Skip to content

Commit 003af98

Browse files
committed
Simplification 2
1 parent 43d4fc2 commit 003af98

2 files changed

Lines changed: 33 additions & 47 deletions

File tree

Modules/posixmodule.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -829,13 +829,11 @@ PyOS_AfterFork(void)
829829
#ifdef MS_WINDOWS
830830
/* defined in fileutils.c */
831831
void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
832-
void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, ULONG,
833-
FILE_BASIC_INFO *, FILE_ID_INFO *,
832+
void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, FILE_STANDARD_INFO*,
833+
ULONG, FILE_BASIC_INFO *, FILE_ID_INFO *,
834834
struct _Py_stat_struct *);
835835
void _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*);
839837
#endif
840838

841839

@@ -2278,9 +2276,9 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
22782276
}
22792277

22802278
#ifdef MS_WINDOWS_DESKTOP
2281-
_Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, &basicInfo, pIdInfo, result);
2279+
_Py_attribute_data_to_stat(&fileInfo, NULL, tagInfo.ReparseTag, &basicInfo, pIdInfo, result);
22822280
#else
2283-
_Py_attribute_data_to_stat_UWP(&standardInfo, tagInfo.ReparseTag, &basicInfo, result);
2281+
_Py_attribute_data_to_stat(NULL, &standardInfo, tagInfo.ReparseTag, &basicInfo, NULL, result);
22842282
#endif
22852283
update_st_mode_from_path(path, basicInfo.FileAttributes, result);
22862284

@@ -16714,7 +16712,7 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
1671416712
BY_HANDLE_FILE_INFORMATION file_info;
1671516713
ULONG reparse_tag;
1671616714
find_data_to_file_info(dataW, &file_info, &reparse_tag);
16717-
_Py_attribute_data_to_stat(&file_info, reparse_tag, NULL, NULL, &entry->win32_lstat);
16715+
_Py_attribute_data_to_stat(&file_info, NULL, reparse_tag, NULL, NULL, &entry->win32_lstat);
1671816716

1671916717
/* ctime is only deprecated from 3.12, so we copy birthtime across */
1672016718
entry->win32_lstat.st_ctime = entry->win32_lstat.st_birthtime;

Python/fileutils.c

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,15 +1103,22 @@ typedef union {
11031103

11041104

11051105
void
1106-
_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
1107-
FILE_BASIC_INFO *basic_info, FILE_ID_INFO *id_info,
1106+
_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, FILE_STANDARD_INFO* standard_info,
1107+
ULONG reparse_tag, FILE_BASIC_INFO *basic_info, FILE_ID_INFO *id_info,
11081108
struct _Py_stat_struct *result)
11091109
{
11101110
memset(result, 0, sizeof(*result));
1111-
result->st_mode = attributes_to_mode(info->dwFileAttributes);
1112-
result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1113-
result->st_dev = id_info ? id_info->VolumeSerialNumber : info->dwVolumeSerialNumber;
1114-
result->st_rdev = 0;
1111+
1112+
if (info) {
1113+
result->st_size = (((__int64)info->nFileSizeHigh) << 32) + info->nFileSizeLow;
1114+
result->st_nlink = info->nNumberOfLinks;
1115+
result->st_dev = id_info ? id_info->VolumeSerialNumber : info->dwVolumeSerialNumber;
1116+
}
1117+
if (standard_info && !info) {
1118+
result->st_size = standard_info->EndOfFile.QuadPart;
1119+
result->st_nlink = standard_info->NumberOfLinks;
1120+
}
1121+
11151122
/* st_ctime is deprecated, but we preserve the legacy value in our caller, not here */
11161123
if (basic_info) {
11171124
LARGE_INTEGER_to_time_t_nsec(&basic_info->CreationTime, &result->st_birthtime, &result->st_birthtime_nsec);
@@ -1123,7 +1130,6 @@ _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
11231130
FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
11241131
FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
11251132
}
1126-
result->st_nlink = info->nNumberOfLinks;
11271133

11281134
if (id_info) {
11291135
id_128_to_ino file_id;
@@ -1134,49 +1140,31 @@ _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
11341140
if (!result->st_ino && !result->st_ino_high) {
11351141
/* should only occur for DirEntry_from_find_data, in which case the
11361142
index is likely to be zero anyway. */
1137-
result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow;
1143+
if (info)
1144+
result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow;
11381145
}
11391146

1140-
/* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will
1141-
open other name surrogate reparse points without traversing them. To
1142-
detect/handle these, check st_file_attributes and st_reparse_tag. */
1143-
result->st_reparse_tag = reparse_tag;
1144-
if (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
1145-
reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1146-
/* set the bits that make this a symlink */
1147-
result->st_mode = (result->st_mode & ~S_IFMT) | S_IFLNK;
1148-
}
1149-
result->st_file_attributes = info->dwFileAttributes;
1150-
}
1147+
const DWORD fileAttributes = basic_info ? basic_info->FileAttributes : info->dwFileAttributes;
11511148

1152-
void
1153-
_Py_attribute_data_to_stat_UWP(FILE_STANDARD_INFO* standard_info, ULONG reparse_tag,
1154-
FILE_BASIC_INFO* basic_info, struct _Py_stat_struct* result)
1155-
{
1156-
memset(result, 0, sizeof(*result));
1157-
result->st_mode = attributes_to_mode(basic_info->FileAttributes);
1158-
result->st_size = standard_info->EndOfFile.QuadPart;
1159-
result->st_dev = 1;
1160-
1161-
/* st_ctime is deprecated, but we preserve the legacy value in our caller, not here */
1162-
LARGE_INTEGER_to_time_t_nsec(&basic_info->CreationTime, &result->st_birthtime, &result->st_birthtime_nsec);
1163-
LARGE_INTEGER_to_time_t_nsec(&basic_info->ChangeTime, &result->st_ctime, &result->st_ctime_nsec);
1164-
LARGE_INTEGER_to_time_t_nsec(&basic_info->LastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1165-
LARGE_INTEGER_to_time_t_nsec(&basic_info->LastAccessTime, &result->st_atime, &result->st_atime_nsec);
1166-
1167-
result->st_nlink = standard_info->NumberOfLinks;
1168-
result->st_ino = basic_info->CreationTime.QuadPart;
1149+
result->st_file_attributes = fileAttributes;
1150+
result->st_mode = attributes_to_mode(fileAttributes);
11691151

11701152
/* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will
11711153
open other name surrogate reparse points without traversing them. To
11721154
detect/handle these, check st_file_attributes and st_reparse_tag. */
11731155
result->st_reparse_tag = reparse_tag;
1174-
if (basic_info->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
1156+
if (result->st_file_attributes & FILE_ATTRIBUTE_REPARSE_POINT &&
11751157
reparse_tag == IO_REPARSE_TAG_SYMLINK) {
11761158
/* set the bits that make this a symlink */
11771159
result->st_mode = (result->st_mode & ~S_IFMT) | S_IFLNK;
11781160
}
1179-
result->st_file_attributes = basic_info->FileAttributes;
1161+
1162+
// For UWP compatibility since is not possible obtain the VolumeSerialNumber
1163+
// and FileId due security restriction and App isolation
1164+
#ifndef MS_WINDOWS_DESKTOP
1165+
result->st_dev = 1;
1166+
basic_info->CreationTime.QuadPart;
1167+
#endif
11801168
}
11811169

11821170
void
@@ -1316,9 +1304,9 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status)
13161304
}
13171305

13181306
#ifdef MS_WINDOWS_DESKTOP
1319-
_Py_attribute_data_to_stat(&info, 0, &basicInfo, pIdInfo, status);
1307+
_Py_attribute_data_to_stat(&info, NULL, 0, &basicInfo, pIdInfo, status);
13201308
#else
1321-
_Py_attribute_data_to_stat_UWP(&standardInfo, 0, &basicInfo, status);
1309+
_Py_attribute_data_to_stat(NULL, &standardInfo, 0, &basicInfo, NULL, status);
13221310
#endif
13231311
return 0;
13241312
#else

0 commit comments

Comments
 (0)