尝试从golang调用GetVolumeInformation函数。要获取卷名。
使用api的规范:
BOOL WINAPI GetVolumeInformation( _In_opt_ LPCTSTR lpRootPathName, _Out_opt_ LPTSTR lpVolumeNameBuffer, _In_ DWORD nVolumeNameSize, _Out_opt_ LPDWORD lpVolumeSerialNumber, _Out_opt_ LPDWORD lpMaximumComponentLength, _Out_opt_ LPDWORD lpFileSystemFlags, _Out_opt_ LPTSTR lpFileSystemNameBuffer, _In_ DWORD nFileSystemNameSize );
使用代码:
// test package main import ( "fmt" "syscall" "unsafe" ) func main() { var lpRootPathName = "C:\\" var lpVolumeNameBuffer string var nVolumeNameSize uint64 var lpVolumeSerialNumber uint64 var lpMaximumComponentLength uint64 var lpFileSystemFlags uint64 var lpFileSystemNameBuffer string var nFileSystemNameSize uint32 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(lpRootPathName))), uintptr(unsafe.Pointer(&lpVolumeNameBuffer)), uintptr(unsafe.Pointer(&nVolumeNameSize)), uintptr(unsafe.Pointer(&lpVolumeSerialNumber)), uintptr(unsafe.Pointer(&lpMaximumComponentLength)), uintptr(unsafe.Pointer(&lpFileSystemFlags)), uintptr(unsafe.Pointer(&lpFileSystemNameBuffer)), uintptr(unsafe.Pointer(&nFileSystemNameSize)), 0) fmt.Println(ret, callErr, lpVolumeNameBuffer) }
…最后有错误:(
unexpected fault address 0xffffffffffffffff fatal error: fault [signal 0xc0000005 code=0x0 addr=0xffffffffffffffff pc=0x456b11]
不理解,Google无法帮助调用winapi函数和returng字符串作为结果。
谢谢。
包裹不安全 不安全的软件包包含绕过Go程序的类型安全的操作。 类型指针 type Pointer *ArbitraryType 指针表示指向任意类型的指针。指针类型有四个特殊操作,而其他类型则不可用。 1)任何类型的指针值都可以转换为Pointer。 2)指针可以转换为任何类型的指针值。 3)可以将uintptr转换为Pointer。 4)指针可以转换为uintptr。 因此,指针允许程序击败类型系统并读写任意存储器。使用时应格外小心。
包裹不安全
不安全的软件包包含绕过Go程序的类型安全的操作。
类型指针
type Pointer *ArbitraryType
指针表示指向任意类型的指针。指针类型有四个特殊操作,而其他类型则不可用。
1)任何类型的指针值都可以转换为Pointer。
2)指针可以转换为任何类型的指针值。
3)可以将uintptr转换为Pointer。
4)指针可以转换为uintptr。
因此,指针允许程序击败类型系统并读写任意存储器。使用时应格外小心。
您没有注意unsafe.Pointer“应格外小心” 的警告。
unsafe.Pointer
试试这个:
package main import ( "fmt" "syscall" "unsafe" ) 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)) }