Maison >développement back-end >Golang >Comment récupérer en toute sécurité le nom du volume de disque à l'aide de la fonction WinAPI GetVolumeInformation de Go ?

Comment récupérer en toute sécurité le nom du volume de disque à l'aide de la fonction WinAPI GetVolumeInformation de Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-10-25 04:46:02321parcourir

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

Appel de la fonction WinAPI GetVolumeInformation à partir de Go pour récupérer le nom du volume de disque

Dans cet article, nous aborderons le problème rencontré lors de la tentative de appelez la fonction GetVolumeInformation depuis Go. Le but est d'obtenir le nom du volume d'un lecteur spécifié.

Pour commencer, comprenons le problème. L'extrait de code est basé sur les spécifications de la fonction GetVolumeInformation telle que définie dans l'API Windows. L'intention était de récupérer le nom du volume via le paramètre lpVolumeNameBuffer. Cependant, l'exécution de ce code a entraîné une erreur inattendue, indiquant un défaut d'accès à la mémoire.

Pour résoudre ce problème, nous devons analyser les aspects problématiques du code. Un point clé est le type unsafe.Pointer utilisé lors de la déclaration des variables pour lpVolumeNameBuffer et d'autres paramètres liés aux chaînes.

Opérations non sécurisées dans Go

Le package unsafe de Go fournit accès de bas niveau à la mémoire système sous-jacente, contournant la sécurité de type afin d'effectuer des opérations de lecture et d'écriture arbitraires. Bien que puissante, cette fonctionnalité s'accompagne d'une mise en garde concernant une corruption potentielle de la mémoire si elle est utilisée avec négligence.

Dans ce cas, l'utilisation d'unsafe.Pointer pour représenter les tampons de chaîne viole les principes de sécurité des types. Pour éviter de tels problèmes, nous pouvons utiliser les propres capacités de gestion des chaînes de Go.

Solution

Le code modifié ci-dessous adopte une approche plus sûre :

<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>

Dans cette version :

  • VolumeNameBuffer et FileSystemNameBuffer sont déclarés comme des tranches de uint16 au lieu de pointeurs non sécurisés. Cela permet à Go de gérer la gestion de la mémoire et la conversion automatique vers et depuis les chaînes UTF-16.
  • Nous utilisons syscall.StringToUTF16Ptr pour convertir la chaîne RootPathName en pointeur UTF-16, garantissant ainsi une gestion correcte des chaînes conformément aux conventions Windows. .

En adhérant aux pratiques de sécurité de type et en utilisant la propre gestion des chaînes de Go, nous pouvons récupérer efficacement le nom du volume sans rencontrer de problèmes d'accès à la mémoire.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn