You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fileinfo.go 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // +build windows
  2. package winio
  3. import (
  4. "os"
  5. "runtime"
  6. "syscall"
  7. "unsafe"
  8. )
  9. //sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx
  10. //sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle
  11. const (
  12. fileBasicInfo = 0
  13. fileIDInfo = 0x12
  14. )
  15. // FileBasicInfo contains file access time and file attributes information.
  16. type FileBasicInfo struct {
  17. CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
  18. FileAttributes uint32
  19. pad uint32 // padding
  20. }
  21. // GetFileBasicInfo retrieves times and attributes for a file.
  22. func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
  23. bi := &FileBasicInfo{}
  24. if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
  25. return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
  26. }
  27. runtime.KeepAlive(f)
  28. return bi, nil
  29. }
  30. // SetFileBasicInfo sets times and attributes for a file.
  31. func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
  32. if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
  33. return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
  34. }
  35. runtime.KeepAlive(f)
  36. return nil
  37. }
  38. // FileIDInfo contains the volume serial number and file ID for a file. This pair should be
  39. // unique on a system.
  40. type FileIDInfo struct {
  41. VolumeSerialNumber uint64
  42. FileID [16]byte
  43. }
  44. // GetFileID retrieves the unique (volume, file ID) pair for a file.
  45. func GetFileID(f *os.File) (*FileIDInfo, error) {
  46. fileID := &FileIDInfo{}
  47. if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
  48. return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
  49. }
  50. runtime.KeepAlive(f)
  51. return fileID, nil
  52. }