Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Mendapatkan Nama Kelantangan Cakera dengan Selamat Menggunakan Fungsi WinAPI GetVolumeInformation Go?

Bagaimana untuk Mendapatkan Nama Kelantangan Cakera dengan Selamat Menggunakan Fungsi WinAPI GetVolumeInformation Go?

Barbara Streisand
Barbara Streisandasal
2024-10-25 04:46:02216semak imbas

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

Memanggil GetVolumeInformation WinAPI Function from Go To Retrieve Disk Volume Name

Dalam artikel ini, kami akan menangani isu yang dihadapi semasa cuba untuk panggil fungsi GetVolumeInformation daripada Go. Matlamatnya ialah untuk mendapatkan nama volum pemacu yang ditentukan.

Untuk bermula, mari kita fahami masalahnya. Coretan kod adalah berdasarkan spesifikasi fungsi GetVolumeInformation seperti yang ditakrifkan dalam API Windows. Niatnya adalah untuk mendapatkan semula nama volum melalui parameter lpVolumeNameBuffer. Walau bagaimanapun, pelaksanaan kod ini mengakibatkan ralat yang tidak dijangka, menunjukkan kesilapan dalam mengakses memori.

Untuk menyelesaikan isu ini, kita perlu menganalisis aspek kod yang bermasalah. Satu perkara utama ialah jenis tidak selamat.Penunjuk yang digunakan semasa mengisytiharkan pembolehubah untuk lpVolumeNameBuffer dan parameter berkaitan rentetan lain.

Operasi Tidak Selamat dalam Go

Pakej tidak selamat Go menyediakan akses peringkat rendah kepada memori sistem asas, memintas keselamatan jenis untuk melaksanakan operasi baca dan tulis sewenang-wenangnya. Walaupun berkuasa, keupayaan ini disertakan dengan kaveat kemungkinan kerosakan memori jika digunakan secara cuai.

Dalam kes ini, penggunaan tidak selamat.Penunjuk untuk mewakili penimbal rentetan melanggar prinsip keselamatan jenis. Untuk mengelakkan isu sedemikian, kami boleh menggunakan keupayaan pengendalian rentetan Go sendiri.

Penyelesaian

Kod yang diubah suai di bawah mengambil pendekatan yang lebih selamat:

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

Dalam versi ini:

  • VolumeNameBuffer dan FileSystemNameBuffer diisytiharkan sebagai kepingan uint16 dan bukannya penunjuk tidak selamat. Ini membolehkan Go mengendalikan pengurusan memori dan penukaran automatik kepada dan dari rentetan UTF-16.
  • Kami menggunakan syscall.StringToUTF16Ptr untuk menukar rentetan RootPathName kepada penuding UTF-16, memastikan pengendalian rentetan yang betul mengikut konvensyen Windows .

Dengan mematuhi amalan keselamatan menaip dan menggunakan pengendalian rentetan Go sendiri, kami boleh mendapatkan semula nama volum dengan berkesan tanpa menghadapi masalah akses memori.

Atas ialah kandungan terperinci Bagaimana untuk Mendapatkan Nama Kelantangan Cakera dengan Selamat Menggunakan Fungsi WinAPI GetVolumeInformation Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn