Heim >Backend-Entwicklung >Golang >Wie kann ich den Datenträgernamen mithilfe der WinAPI-GetVolumeInformation-Funktion von Go sicher abrufen?

Wie kann ich den Datenträgernamen mithilfe der WinAPI-GetVolumeInformation-Funktion von Go sicher abrufen?

Barbara Streisand
Barbara StreisandOriginal
2024-10-25 04:46:02319Durchsuche

How to Safely Retrieve Disk Volume Name Using Go's WinAPI GetVolumeInformation Function?

Aufrufen der WinAPI-Funktion „GetVolumeInformation“ von „Go To Retrieve Disk Volume Name“

In diesem Artikel befassen wir uns mit dem Problem, das beim Versuch auftritt Rufen Sie die GetVolumeInformation-Funktion von Go aus auf. Das Ziel besteht darin, den Volume-Namen eines bestimmten Laufwerks zu ermitteln.

Lassen Sie uns zunächst das Problem verstehen. Der Codeausschnitt basiert auf den Spezifikationen der GetVolumeInformation-Funktion, wie sie in der Windows-API definiert sind. Die Absicht bestand darin, den Volume-Namen über den Parameter lpVolumeNameBuffer abzurufen. Die Ausführung dieses Codes führte jedoch zu einem unerwarteten Fehler, der auf einen Fehler beim Zugriff auf den Speicher hinweist.

Um dieses Problem zu beheben, müssen wir die problematischen Aspekte des Codes analysieren. Ein wichtiger Punkt ist der unsafe.Pointer-Typ, der beim Deklarieren der Variablen für den lpVolumeNameBuffer und andere stringbezogene Parameter verwendet wird.

Unsichere Vorgänge in Go

Das unsichere Paket von Go bietet Low-Level-Zugriff auf den zugrunde liegenden Systemspeicher unter Umgehung der Typensicherheit, um beliebige Lese- und Schreibvorgänge auszuführen. Diese Funktion ist zwar leistungsstark, birgt jedoch den Nachteil einer möglichen Speicherbeschädigung, wenn sie unachtsam verwendet wird.

In diesem Fall verstößt die Verwendung von „unsafe.Pointer“ zur Darstellung der Zeichenfolgenpuffer gegen die Prinzipien der Typsicherheit. Um solche Probleme zu vermeiden, können wir Gos eigene String-Verarbeitungsfunktionen nutzen.

Lösung

Der geänderte Code unten verfolgt einen sichereren Ansatz:

<code class="go">package main

import (
    "fmt"
    "syscall"
)

func main() {
    var RootPathName = `C:\`
    var VolumeNameBuffer = make([]uint16, syscall.MAX_PATH+1)
    var nVolumeNameSize = uint32(len(VolumeNameBuffer))
    var VolumeSerialNumber uint32
    var MaximumComponentLength uint32
    var FileSystemFlags uint32
    var FileSystemNameBuffer = make([]uint16, 255)
    var nFileSystemNameSize uint32 = syscall.MAX_PATH + 1

    kernel32, _ := syscall.LoadLibrary("kernel32.dll")
    getVolume, _ := syscall.GetProcAddress(kernel32, "GetVolumeInformationW")

    var nargs uintptr = 8
    ret, _, callErr := syscall.Syscall9(uintptr(getVolume),
        nargs,
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(RootPathName))),
        uintptr(unsafe.Pointer(&VolumeNameBuffer[0])),
        uintptr(nVolumeNameSize),
        uintptr(unsafe.Pointer(&VolumeSerialNumber)),
        uintptr(unsafe.Pointer(&MaximumComponentLength)),
        uintptr(unsafe.Pointer(&FileSystemFlags)),
        uintptr(unsafe.Pointer(&FileSystemNameBuffer[0])),
        uintptr(nFileSystemNameSize),
        0)
    fmt.Println(ret, callErr, syscall.UTF16ToString(VolumeNameBuffer))
}</code>

In dieser Version:

  • VolumeNameBuffer und FileSystemNameBuffer werden als Slices von uint16 statt als unsichere Zeiger deklariert. Dadurch kann Go die Speicherverwaltung und die automatische Konvertierung in und von UTF-16-Strings übernehmen.
  • Wir verwenden syscall.StringToUTF16Ptr, um den RootPathName-String in einen UTF-16-Zeiger zu konvertieren und so eine ordnungsgemäße String-Verarbeitung gemäß Windows-Konventionen sicherzustellen .

Durch die Einhaltung von Typsicherheitspraktiken und die Nutzung der Go-eigenen String-Verarbeitung können wir den Volume-Namen effektiv abrufen, ohne auf Probleme beim Speicherzugriff zu stoßen.

Das obige ist der detaillierte Inhalt vonWie kann ich den Datenträgernamen mithilfe der WinAPI-GetVolumeInformation-Funktion von Go sicher abrufen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn