@@ -834,6 +834,9 @@ void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, ULONG,
834834 struct _Py_stat_struct *);
835835void _Py_stat_basic_info_to_stat(FILE_STAT_BASIC_INFORMATION *,
836836 struct _Py_stat_struct *);
837+ void _Py_attribute_data_to_stat_UWP(FILE_STANDARD_INFO*, ULONG,
838+ FILE_BASIC_INFO*, struct _Py_stat_struct*);
839+ void _Py_find_data_to_stat(WIN32_FIND_DATAW* find_data, struct _Py_stat_struct* result);
837840#endif
838841
839842
@@ -2023,27 +2026,8 @@ win32_wchdir(LPCWSTR path)
20232026#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
20242027#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
20252028
2026- static void
2027- find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
2028- BY_HANDLE_FILE_INFORMATION *info,
2029- ULONG *reparse_tag)
2030- {
2031- memset(info, 0, sizeof(*info));
2032- info->dwFileAttributes = pFileData->dwFileAttributes;
2033- info->ftCreationTime = pFileData->ftCreationTime;
2034- info->ftLastAccessTime = pFileData->ftLastAccessTime;
2035- info->ftLastWriteTime = pFileData->ftLastWriteTime;
2036- info->nFileSizeHigh = pFileData->nFileSizeHigh;
2037- info->nFileSizeLow = pFileData->nFileSizeLow;
2038- /* info->nNumberOfLinks = 1; */
2039- if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
2040- *reparse_tag = pFileData->dwReserved0;
2041- else
2042- *reparse_tag = 0;
2043- }
2044-
20452029static BOOL
2046- attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info , ULONG *reparse_tag)
2030+ attributes_from_dir(LPCWSTR pszFile, struct _Py_stat_struct* result , ULONG *reparse_tag)
20472031{
20482032 HANDLE hFindFile;
20492033 WIN32_FIND_DATAW FileData;
@@ -2074,7 +2058,7 @@ attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *re
20742058 return FALSE;
20752059 }
20762060 FindClose(hFindFile);
2077- find_data_to_file_info (&FileData, info, reparse_tag );
2061+ _Py_find_data_to_stat (&FileData, result );
20782062 return TRUE;
20792063}
20802064
@@ -2108,10 +2092,11 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
21082092 BOOL traverse)
21092093{
21102094 HANDLE hFile;
2111- BY_HANDLE_FILE_INFORMATION fileInfo;
2112- FILE_BASIC_INFO basicInfo;
2113- FILE_BASIC_INFO *pBasicInfo = NULL;
2114- FILE_ID_INFO idInfo;
2095+ BY_HANDLE_FILE_INFORMATION fileInfo = {0};
2096+ BY_HANDLE_FILE_INFORMATION* pFileInfo = NULL;
2097+ FILE_STANDARD_INFO standardInfo = {0};
2098+ FILE_BASIC_INFO basicInfo = {0};
2099+ FILE_ID_INFO idInfo = {0};
21152100 FILE_ID_INFO *pIdInfo = NULL;
21162101 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
21172102 DWORD fileType, error;
@@ -2132,7 +2117,7 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
21322117 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
21332118 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
21342119 /* Try reading the parent directory. */
2135- if (!attributes_from_dir(path, &fileInfo , &tagInfo.ReparseTag)) {
2120+ if (!attributes_from_dir(path, result , &tagInfo.ReparseTag)) {
21362121 /* Cannot read the parent directory. */
21372122 switch (GetLastError()) {
21382123 case ERROR_FILE_NOT_FOUND: /* File cannot be found */
@@ -2147,7 +2132,7 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
21472132
21482133 return -1;
21492134 }
2150- if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
2135+ if (result->st_file_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
21512136 if (traverse ||
21522137 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
21532138 /* The stat call has to traverse but cannot, so fail. */
@@ -2247,9 +2232,15 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
22472232 }
22482233 }
22492234
2250- if (!GetFileInformationByHandle(hFile, &fileInfo) ||
2251- !GetFileInformationByHandleEx(hFile, FileBasicInfo,
2252- &basicInfo, sizeof(basicInfo))) {
2235+ #ifdef MS_WINDOWS_DESKTOP
2236+ if (GetFileInformationByHandle(hFile, &fileInfo)) {
2237+ /* Successfully got fileInfo, so pass it along */
2238+ pFileInfo = &fileInfo;
2239+ }
2240+ #endif
2241+
2242+ if (!GetFileInformationByHandleEx(hFile, FileStandardInfo, &standardInfo, sizeof(standardInfo)) ||
2243+ !GetFileInformationByHandleEx(hFile, FileBasicInfo, &basicInfo, sizeof(basicInfo))) {
22532244 switch (GetLastError()) {
22542245 case ERROR_INVALID_PARAMETER:
22552246 case ERROR_INVALID_FUNCTION:
@@ -2264,17 +2255,18 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
22642255 goto cleanup;
22652256 }
22662257
2267- /* Successfully got FileBasicInfo, so we'll pass it along */
2268- pBasicInfo = &basicInfo;
2269-
22702258 if (GetFileInformationByHandleEx(hFile, FileIdInfo, &idInfo, sizeof(idInfo))) {
22712259 /* Successfully got FileIdInfo, so pass it along */
22722260 pIdInfo = &idInfo;
22732261 }
22742262 }
22752263
2276- _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, pBasicInfo, pIdInfo, result);
2277- update_st_mode_from_path(path, fileInfo.dwFileAttributes, result);
2264+ #ifdef MS_WINDOWS_DESKTOP
2265+ _Py_attribute_data_to_stat(pFileInfo, tagInfo.ReparseTag, &basicInfo, pIdInfo, result);
2266+ #else
2267+ _Py_attribute_data_to_stat_UWP(&standardInfo, tagInfo.ReparseTag, &basicInfo, result);
2268+ #endif
2269+ update_st_mode_from_path(path, basicInfo.FileAttributes, result);
22782270
22792271cleanup:
22802272 if (hFile != INVALID_HANDLE_VALUE) {
@@ -16670,8 +16662,6 @@ static PyObject *
1667016662DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
1667116663{
1667216664 DirEntry *entry;
16673- BY_HANDLE_FILE_INFORMATION file_info;
16674- ULONG reparse_tag;
1667516665 wchar_t *joined_path;
1667616666
1667716667 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
@@ -16708,8 +16698,7 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
1670816698 goto error;
1670916699 }
1671016700
16711- find_data_to_file_info(dataW, &file_info, &reparse_tag);
16712- _Py_attribute_data_to_stat(&file_info, reparse_tag, NULL, NULL, &entry->win32_lstat);
16701+ _Py_find_data_to_stat(dataW, &entry->win32_lstat);
1671316702
1671416703 /* ctime is only deprecated from 3.12, so we copy birthtime across */
1671516704 entry->win32_lstat.st_ctime = entry->win32_lstat.st_birthtime;
0 commit comments