Skip to content

Commit 6031727

Browse files
authored
gh-104820: Fixes os.stat on Windows to better handle file systems that do not support FileIdInformation (GH-104892)
1 parent 087c1a6 commit 6031727

File tree

3 files changed

+12
-5
lines changed

3 files changed

+12
-5
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixes :func:`~os.stat` and related functions on file systems that do not
2+
support file ID requests. This includes FAT32 and exFAT.

Modules/posixmodule.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,7 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
18641864
BY_HANDLE_FILE_INFORMATION fileInfo;
18651865
FILE_BASIC_INFO basicInfo;
18661866
FILE_ID_INFO idInfo;
1867+
FILE_ID_INFO *pIdInfo = &idInfo;
18671868
FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
18681869
DWORD fileType, error;
18691870
BOOL isUnhandledTag = FALSE;
@@ -2000,9 +2001,7 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
20002001

20012002
if (!GetFileInformationByHandle(hFile, &fileInfo) ||
20022003
!GetFileInformationByHandleEx(hFile, FileBasicInfo,
2003-
&basicInfo, sizeof(basicInfo)) ||
2004-
!GetFileInformationByHandleEx(hFile, FileIdInfo,
2005-
&idInfo, sizeof(idInfo))) {
2004+
&basicInfo, sizeof(basicInfo))) {
20062005
switch (GetLastError()) {
20072006
case ERROR_INVALID_PARAMETER:
20082007
case ERROR_INVALID_FUNCTION:
@@ -2018,7 +2017,12 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
20182017
}
20192018
}
20202019

2021-
_Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, &basicInfo, &idInfo, result);
2020+
if (!GetFileInformationByHandleEx(hFile, FileIdInfo, &idInfo, sizeof(idInfo))) {
2021+
/* Failed to get FileIdInfo, so do not pass it along */
2022+
pIdInfo = NULL;
2023+
}
2024+
2025+
_Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, &basicInfo, pIdInfo, result);
20222026
update_st_mode_from_path(path, fileInfo.dwFileAttributes, result);
20232027

20242028
cleanup:

Python/fileutils.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,8 @@ _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
11321132
file_id.id = id_info->FileId;
11331133
result->st_ino = file_id.st_ino;
11341134
result->st_ino_high = file_id.st_ino_high;
1135-
} else {
1135+
}
1136+
if (!result->st_ino && !result->st_ino_high) {
11361137
/* should only occur for DirEntry_from_find_data, in which case the
11371138
index is likely to be zero anyway. */
11381139
result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow;

0 commit comments

Comments
 (0)