• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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