fileinfo.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. //go:build windows
  2. // +build windows
  3. package winio
  4. import (
  5. "os"
  6. "runtime"
  7. "unsafe"
  8. "golang.org/x/sys/windows"
  9. )
  10. // FileBasicInfo contains file access time and file attributes information.
  11. type FileBasicInfo struct {
  12. CreationTime, LastAccessTime, LastWriteTime, ChangeTime windows.Filetime
  13. FileAttributes uint32
  14. _ uint32 // padding
  15. }
  16. // GetFileBasicInfo retrieves times and attributes for a file.
  17. func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
  18. bi := &FileBasicInfo{}
  19. if err := windows.GetFileInformationByHandleEx(
  20. windows.Handle(f.Fd()),
  21. windows.FileBasicInfo,
  22. (*byte)(unsafe.Pointer(bi)),
  23. uint32(unsafe.Sizeof(*bi)),
  24. ); 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 := windows.SetFileInformationByHandle(
  33. windows.Handle(f.Fd()),
  34. windows.FileBasicInfo,
  35. (*byte)(unsafe.Pointer(bi)),
  36. uint32(unsafe.Sizeof(*bi)),
  37. ); err != nil {
  38. return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
  39. }
  40. runtime.KeepAlive(f)
  41. return nil
  42. }
  43. // FileStandardInfo contains extended information for the file.
  44. // FILE_STANDARD_INFO in WinBase.h
  45. // https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info
  46. type FileStandardInfo struct {
  47. AllocationSize, EndOfFile int64
  48. NumberOfLinks uint32
  49. DeletePending, Directory bool
  50. }
  51. // GetFileStandardInfo retrieves ended information for the file.
  52. func GetFileStandardInfo(f *os.File) (*FileStandardInfo, error) {
  53. si := &FileStandardInfo{}
  54. if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()),
  55. windows.FileStandardInfo,
  56. (*byte)(unsafe.Pointer(si)),
  57. uint32(unsafe.Sizeof(*si))); err != nil {
  58. return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
  59. }
  60. runtime.KeepAlive(f)
  61. return si, nil
  62. }
  63. // FileIDInfo contains the volume serial number and file ID for a file. This pair should be
  64. // unique on a system.
  65. type FileIDInfo struct {
  66. VolumeSerialNumber uint64
  67. FileID [16]byte
  68. }
  69. // GetFileID retrieves the unique (volume, file ID) pair for a file.
  70. func GetFileID(f *os.File) (*FileIDInfo, error) {
  71. fileID := &FileIDInfo{}
  72. if err := windows.GetFileInformationByHandleEx(
  73. windows.Handle(f.Fd()),
  74. windows.FileIdInfo,
  75. (*byte)(unsafe.Pointer(fileID)),
  76. uint32(unsafe.Sizeof(*fileID)),
  77. ); err != nil {
  78. return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
  79. }
  80. runtime.KeepAlive(f)
  81. return fileID, nil
  82. }