Skip to content

Commit

Permalink
gh-104820: Fixes os.stat on Windows to better handle file systems tha…
Browse files Browse the repository at this point in the history
…t do not support FileIdInformation (GH-104892)
  • Loading branch information
zooba committed May 24, 2023
1 parent 087c1a6 commit 6031727
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixes :func:`~os.stat` and related functions on file systems that do not
support file ID requests. This includes FAT32 and exFAT.
12 changes: 8 additions & 4 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1864,6 +1864,7 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
BY_HANDLE_FILE_INFORMATION fileInfo;
FILE_BASIC_INFO basicInfo;
FILE_ID_INFO idInfo;
FILE_ID_INFO *pIdInfo = &idInfo;
FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
DWORD fileType, error;
BOOL isUnhandledTag = FALSE;
Expand Down Expand Up @@ -2000,9 +2001,7 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,

if (!GetFileInformationByHandle(hFile, &fileInfo) ||
!GetFileInformationByHandleEx(hFile, FileBasicInfo,
&basicInfo, sizeof(basicInfo)) ||
!GetFileInformationByHandleEx(hFile, FileIdInfo,
&idInfo, sizeof(idInfo))) {
&basicInfo, sizeof(basicInfo))) {
switch (GetLastError()) {
case ERROR_INVALID_PARAMETER:
case ERROR_INVALID_FUNCTION:
Expand All @@ -2018,7 +2017,12 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
}
}

_Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, &basicInfo, &idInfo, result);
if (!GetFileInformationByHandleEx(hFile, FileIdInfo, &idInfo, sizeof(idInfo))) {
/* Failed to get FileIdInfo, so do not pass it along */
pIdInfo = NULL;
}

_Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, &basicInfo, pIdInfo, result);
update_st_mode_from_path(path, fileInfo.dwFileAttributes, result);

cleanup:
Expand Down
3 changes: 2 additions & 1 deletion Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,8 @@ _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
file_id.id = id_info->FileId;
result->st_ino = file_id.st_ino;
result->st_ino_high = file_id.st_ino_high;
} else {
}
if (!result->st_ino && !result->st_ino_high) {
/* should only occur for DirEntry_from_find_data, in which case the
index is likely to be zero anyway. */
result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow;
Expand Down

0 comments on commit 6031727

Please sign in to comment.