Skip to content

Instantly share code, notes, and snippets.

@hirochachacha
Created April 15, 2017 01:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hirochachacha/9357e505c6d3da0b6baf271258d92652 to your computer and use it in GitHub Desktop.
Save hirochachacha/9357e505c6d3da0b6baf271258d92652 to your computer and use it in GitHub Desktop.
get file name
package main
import (
"fmt"
"os"
"syscall"
"unsafe"
)
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
)
const (
FileNameInfo = 2
)
type FileNameInformation struct {
FileNameLength uint32
FileName [1]uint16
}
func GetFileInformationByHandleEx(handle syscall.Handle, infoClass int32, data *byte, buflen uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(infoClass), uintptr(unsafe.Pointer(data)), uintptr(buflen), 0, 0)
if r1 == 0 {
if e1 != 0 {
err = syscall.Errno(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func Open(path string) (fd syscall.Handle, err error) {
if len(path) == 0 {
return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND
}
pathp, err := syscall.UTF16PtrFromString(path)
if err != nil {
return syscall.InvalidHandle, err
}
return syscall.CreateFile(pathp, syscall.GENERIC_READ, syscall.FILE_SHARE_READ, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
}
func GetFileName(path string) (string, error) {
fd, err := Open(path)
if err != nil {
return "", err
}
defer syscall.CloseHandle(fd)
var buf [syscall.MAX_PATH + 4]byte
err = GetFileInformationByHandleEx(fd, FileNameInfo, &buf[0], uint32(len(buf)))
if err != nil {
return "", err
}
nameInfo := (*FileNameInformation)(unsafe.Pointer(&buf[0]))
p := (*[0xffff]uint16)(unsafe.Pointer(&nameInfo.FileName[0]))
return syscall.UTF16ToString(p[:nameInfo.FileNameLength/2]), nil
}
func main() {
if len(os.Args) != 2 {
fmt.Println("usage: getfilename file")
os.Exit(1)
}
name, err := GetFileName(os.Args[1])
if err != nil {
panic(err)
}
fmt.Println(name)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment