1 #ifndef Py_INTERNAL_FILEUTILS_WINDOWS_H
2 #define Py_INTERNAL_FILEUTILS_WINDOWS_H
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6
7 #ifndef Py_BUILD_CORE
8 # error "this header requires Py_BUILD_CORE define"
9 #endif
10
11 #ifdef MS_WINDOWS
12
13 #if !defined(NTDDI_WIN10_NI) || !(NTDDI_VERSION >= NTDDI_WIN10_NI)
14 typedef struct _FILE_STAT_BASIC_INFORMATION {
15 LARGE_INTEGER FileId;
16 LARGE_INTEGER CreationTime;
17 LARGE_INTEGER LastAccessTime;
18 LARGE_INTEGER LastWriteTime;
19 LARGE_INTEGER ChangeTime;
20 LARGE_INTEGER AllocationSize;
21 LARGE_INTEGER EndOfFile;
22 ULONG FileAttributes;
23 ULONG ReparseTag;
24 ULONG NumberOfLinks;
25 ULONG DeviceType;
26 ULONG DeviceCharacteristics;
27 ULONG Reserved;
28 LARGE_INTEGER VolumeSerialNumber;
29 FILE_ID_128 FileId128;
30 } FILE_STAT_BASIC_INFORMATION;
31
32 typedef enum _FILE_INFO_BY_NAME_CLASS {
33 FileStatByNameInfo,
34 FileStatLxByNameInfo,
35 FileCaseSensitiveByNameInfo,
36 FileStatBasicByNameInfo,
37 MaximumFileInfoByNameClass
38 } FILE_INFO_BY_NAME_CLASS;
39 #endif
40
41 typedef BOOL (WINAPI *PGetFileInformationByName)(
42 PCWSTR FileName,
43 FILE_INFO_BY_NAME_CLASS FileInformationClass,
44 PVOID FileInfoBuffer,
45 ULONG FileInfoBufferSize
46 );
47
_Py_GetFileInformationByName(PCWSTR FileName,FILE_INFO_BY_NAME_CLASS FileInformationClass,PVOID FileInfoBuffer,ULONG FileInfoBufferSize)48 static inline BOOL _Py_GetFileInformationByName(
49 PCWSTR FileName,
50 FILE_INFO_BY_NAME_CLASS FileInformationClass,
51 PVOID FileInfoBuffer,
52 ULONG FileInfoBufferSize
53 ) {
54 static PGetFileInformationByName GetFileInformationByName = NULL;
55 static int GetFileInformationByName_init = -1;
56
57 if (GetFileInformationByName_init < 0) {
58 HMODULE hMod = LoadLibraryW(L"api-ms-win-core-file-l2-1-4");
59 GetFileInformationByName_init = 0;
60 if (hMod) {
61 GetFileInformationByName = (PGetFileInformationByName)GetProcAddress(
62 hMod, "GetFileInformationByName");
63 if (GetFileInformationByName) {
64 GetFileInformationByName_init = 1;
65 } else {
66 FreeLibrary(hMod);
67 }
68 }
69 }
70
71 if (GetFileInformationByName_init <= 0) {
72 SetLastError(ERROR_NOT_SUPPORTED);
73 return FALSE;
74 }
75 return GetFileInformationByName(FileName, FileInformationClass, FileInfoBuffer, FileInfoBufferSize);
76 }
77
_Py_GetFileInformationByName_ErrorIsTrustworthy(int error)78 static inline BOOL _Py_GetFileInformationByName_ErrorIsTrustworthy(int error)
79 {
80 switch(error) {
81 case ERROR_FILE_NOT_FOUND:
82 case ERROR_PATH_NOT_FOUND:
83 case ERROR_NOT_READY:
84 case ERROR_BAD_NET_NAME:
85 case ERROR_BAD_NETPATH:
86 case ERROR_BAD_PATHNAME:
87 case ERROR_INVALID_NAME:
88 case ERROR_FILENAME_EXCED_RANGE:
89 return TRUE;
90 case ERROR_NOT_SUPPORTED:
91 return FALSE;
92 }
93 return FALSE;
94 }
95
96 #endif
97
98 #endif
99