Tries to call GetVolumeInformation function from golang. Want to get volume name.
Use spec's of 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
);
Use code:
// 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)
}
... and finally have error :(
unexpected fault address 0xffffffffffffffff
fatal error: fault
[signal 0xc0000005 code=0x0 addr=0xffffffffffffffff pc=0x456b11]
Don't understand and google cant'd help with calling winapi functions and returng string as result.
Thank's.
Package unsafe
Package unsafe contains operations that step around the type safety of Go programs.
type Pointer
type Pointer *ArbitraryType
Pointer represents a pointer to an arbitrary type. There are four special operations available for type Pointer that are not available for other types.
1) A pointer value of any type can be converted to a Pointer.
2) A Pointer can be converted to a pointer value of any type.
3) A uintptr can be converted to a Pointer.
4) A Pointer can be converted to a uintptr.
Pointer therefore allows a program to defeat the type system and read and write arbitrary memory. It should be used with extreme care.
You failed to heed the warning that unsafe.Pointer
"should be used with extreme care."
Try this:
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))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With