ホームページ >バックエンド開発 >Golang >Go の WinAPI GetVolumeInformation 関数を使用してディスク ボリューム名を安全に取得する方法

Go の WinAPI GetVolumeInformation 関数を使用してディスク ボリューム名を安全に取得する方法

Barbara Streisand
Barbara Streisandオリジナル
2024-10-25 04:46:02326ブラウズ

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

Go To Retrieve Disk Volume Name から Get VolumeInformation WinAPI 関数を呼び出す

この記事では、 Go から GetVolumeInformation 関数を呼び出します。目標は、指定されたドライブのボリューム名を取得することです。

まず、問題を理解しましょう。このコード スニペットは、Windows API で定義されている GetVolumeInformation 関数の仕様に基づいています。その目的は、lpVolumeNameBuffer パラメーターを通じてボリューム名を取得することでした。ただし、このコードを実行すると、メモリへのアクセス障害を示す予期しないエラーが発生しました。

この問題を解決するには、コードの問題のある側面を分析する必要があります。重要なポイントの 1 つは、lpVolumeNameBuffer およびその他の文字列関連パラメーターの変数を宣言するときに使用される unsafe.Pointer 型です。

Go の安全でない操作

Go の unsafe パッケージは次のことを提供します。基礎となるシステム メモリへの低レベル アクセス。任意の読み取りおよび書き込み操作を実行するためにタイプ セーフティをバイパスします。この機能は強力ですが、不注意に使用するとメモリ破損の可能性があるという注意事項があります。

この場合、文字列バッファを表すために unsafe.Pointer を使用すると、型安全性の原則に違反します。このような問題を回避するには、Go 独自の文字列処理機能を利用できます。

解決策

以下の変更されたコードは、より安全なアプローチを採用しています。

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

このバージョンでは:

  • VolumeNameBuffer と FileSystemNameBuffer は、安全でないポインターではなく uint16 のスライスとして宣言されます。これにより、Go がメモリ管理と UTF-16 文字列との自動変換を処理できるようになります。
  • syscall.StringToUTF16Ptr を使用して RootPathName 文字列を UTF-16 ポインターに変換し、Windows の規則に従って適切な文字列処理を保証します。 .

タイプ セーフティの実践を遵守し、Go 独自の文字列処理を利用することにより、メモリ アクセスの問題が発生することなくボリューム名を効果的に取得できます。

以上がGo の WinAPI GetVolumeInformation 関数を使用してディスク ボリューム名を安全に取得する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。