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