返回 DeepSeek-Reasonix
native_windows.go
根目录 / internal / fileops / native_windows.go
1 //go:build windows
2
3 package fileops
4
5 import (
6 "fmt"
7 "os"
8 "unsafe"
9
10 "golang.org/x/sys/windows"
11 )
12
13 type windowsFileBasicInfo struct {
14 CreationTime int64
15 LastAccessTime int64
16 LastWriteTime int64
17 ChangeTime int64
18 Attributes uint32
19 Reserved uint32
20 }
21
22 func diskNativeSnapshot(path string) (string, []string) {
23 name, err := windows.UTF16PtrFromString(path)
24 if err != nil {
25 return "", nil
26 }
27 h, err := windows.CreateFile(name, windows.FILE_READ_ATTRIBUTES,
28 windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE,
29 nil, windows.OPEN_EXISTING, windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
30 if err != nil {
31 return "", nil
32 }
33 defer windows.CloseHandle(h)
34 return windowsSnapshot(h)
35 }
36
37 func diskNativeHandleSnapshot(file *os.File) (string, []string) {
38 if file == nil {
39 return "", nil
40 }
41 return windowsSnapshot(windows.Handle(file.Fd()))
42 }
43
44 func windowsSnapshot(h windows.Handle) (string, []string) {
45 var byHandle windows.ByHandleFileInformation
46 if err := windows.GetFileInformationByHandle(h, &byHandle); err != nil {
47 return "", nil
48 }
49 identity := fmt.Sprintf("volume=%d,fileindex=%08x%08x", byHandle.VolumeSerialNumber, byHandle.FileIndexHigh, byHandle.FileIndexLow)
50 meta := []string{
51 fmt.Sprintf("win.volume=%d", byHandle.VolumeSerialNumber),
52 fmt.Sprintf("win.fileindex=%08x%08x", byHandle.FileIndexHigh, byHandle.FileIndexLow),
53 fmt.Sprintf("win.links=%d", byHandle.NumberOfLinks),
54 fmt.Sprintf("win.attributes=%d", byHandle.FileAttributes),
55 }
56 var basic windowsFileBasicInfo
57 if err := windows.GetFileInformationByHandleEx(h, windows.FileBasicInfo, (*byte)(unsafe.Pointer(&basic)), uint32(unsafe.Sizeof(basic))); err == nil {
58 meta = append(meta,
59 fmt.Sprintf("win.creation=%d", basic.CreationTime),
60 fmt.Sprintf("win.lastwrite=%d", basic.LastWriteTime),
61 fmt.Sprintf("win.change=%d", basic.ChangeTime),
62 fmt.Sprintf("win.basic_attributes=%d", basic.Attributes),
63 )
64 }
65 return identity, meta
66 }
67
67 lines GO