Source file
src/os/stat_windows.go
Documentation: os
1
2
3
4
5 package os
6
7 import (
8 "internal/syscall/windows"
9 "syscall"
10 "unsafe"
11 )
12
13
14
15 func (file *File) Stat() (FileInfo, error) {
16 if file == nil {
17 return nil, ErrInvalid
18 }
19
20 if file.isdir() {
21
22 return Stat(file.dirinfo.path)
23 }
24 if isWindowsNulName(file.name) {
25 return &devNullStat, nil
26 }
27
28 ft, err := file.pfd.GetFileType()
29 if err != nil {
30 return nil, &PathError{Op: "GetFileType", Path: file.name, Err: err}
31 }
32 switch ft {
33 case syscall.FILE_TYPE_PIPE, syscall.FILE_TYPE_CHAR:
34 return &fileStat{name: basename(file.name), filetype: ft}, nil
35 }
36
37 fs, err := newFileStatFromGetFileInformationByHandle(file.name, file.pfd.Sysfd)
38 if err != nil {
39 return nil, err
40 }
41 fs.filetype = ft
42 return fs, err
43 }
44
45
46 func stat(funcname, name string, createFileAttrs uint32) (FileInfo, error) {
47 if len(name) == 0 {
48 return nil, &PathError{Op: funcname, Path: name, Err: syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
49 }
50 if isWindowsNulName(name) {
51 return &devNullStat, nil
52 }
53 namep, err := syscall.UTF16PtrFromString(fixLongPath(name))
54 if err != nil {
55 return nil, &PathError{Op: funcname, Path: name, Err: err}
56 }
57
58
59
60 var fa syscall.Win32FileAttributeData
61 err = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
62 if err == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
63
64 fs := &fileStat{
65 FileAttributes: fa.FileAttributes,
66 CreationTime: fa.CreationTime,
67 LastAccessTime: fa.LastAccessTime,
68 LastWriteTime: fa.LastWriteTime,
69 FileSizeHigh: fa.FileSizeHigh,
70 FileSizeLow: fa.FileSizeLow,
71 }
72 if err := fs.saveInfoFromPath(name); err != nil {
73 return nil, err
74 }
75 return fs, nil
76 }
77
78
79 if err == windows.ERROR_SHARING_VIOLATION {
80 var fd syscall.Win32finddata
81 sh, err := syscall.FindFirstFile(namep, &fd)
82 if err != nil {
83 return nil, &PathError{Op: "FindFirstFile", Path: name, Err: err}
84 }
85 syscall.FindClose(sh)
86 fs := newFileStatFromWin32finddata(&fd)
87 if err := fs.saveInfoFromPath(name); err != nil {
88 return nil, err
89 }
90 return fs, nil
91 }
92
93
94 h, err := syscall.CreateFile(namep, 0, 0, nil,
95 syscall.OPEN_EXISTING, createFileAttrs, 0)
96 if err != nil {
97 return nil, &PathError{Op: "CreateFile", Path: name, Err: err}
98 }
99 defer syscall.CloseHandle(h)
100
101 return newFileStatFromGetFileInformationByHandle(name, h)
102 }
103
104
105 func statNolog(name string) (FileInfo, error) {
106 return stat("Stat", name, syscall.FILE_FLAG_BACKUP_SEMANTICS)
107 }
108
109
110 func lstatNolog(name string) (FileInfo, error) {
111 attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
112
113
114 attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT
115 return stat("Lstat", name, attrs)
116 }
117
View as plain text