Skip to content

Commit 6ad73ca

Browse files
committed
gh-152433: Windows: use CreateFile2 on Windows UWP build
UWP does not support ``CreateFileW`` because it is only compatible with the Win32 desktop API.
1 parent cfe3e07 commit 6ad73ca

6 files changed

Lines changed: 50 additions & 16 deletions

File tree

Include/internal/pycore_fileutils_windows.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,33 @@ static inline BOOL _Py_GetFileInformationByName_ErrorIsTrustworthy(int error)
9393
return FALSE;
9494
}
9595

96+
static inline HANDLE _Py_WinCreateFile(
97+
_In_ LPCWSTR lpFileName,
98+
_In_ DWORD dwDesiredAccess,
99+
_In_ DWORD dwShareMode,
100+
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
101+
_In_ DWORD dwCreationDisposition,
102+
_In_ DWORD dwFlagsAndAttributes,
103+
_In_opt_ HANDLE hTemplateFile
104+
)
105+
{
106+
#ifndef MS_WINDOWS_DESKTOP
107+
if (dwShareMode == 0)
108+
dwShareMode = FILE_SHARE_READ;
109+
110+
CREATEFILE2_EXTENDED_PARAMETERS ext;
111+
ZeroMemory(&ext, sizeof(CREATEFILE2_EXTENDED_PARAMETERS));
112+
ext.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
113+
ext.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
114+
ext.dwFileFlags = dwFlagsAndAttributes & 0xFFFF0000;
115+
116+
return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, &ext);
117+
#else
118+
return CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
119+
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
120+
#endif
121+
}
122+
96123
#endif
97124

98125
#endif
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use ``CreateFile2`` on Windows UWP build.

Modules/_winapi.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <winioctl.h>
4949
#include <crtdbg.h>
5050
#include "winreparse.h"
51+
#include "internal/pycore_fileutils_windows.h"
5152

5253
// PSAPI_VERSION=2 redirects GetProcessMemoryInfo() to
5354
// K32GetProcessMemoryInfo() in kernel32.dll, so we don't need to link
@@ -546,7 +547,7 @@ _winapi_CreateFile_impl(PyObject *module, LPCWSTR file_name,
546547
}
547548

548549
Py_BEGIN_ALLOW_THREADS
549-
handle = CreateFileW(file_name, desired_access,
550+
handle = _Py_WinCreateFile(file_name, desired_access,
550551
share_mode, security_attributes,
551552
creation_disposition,
552553
flags_and_attributes, template_file);
@@ -721,7 +722,7 @@ _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path,
721722
if (!CreateDirectoryW(dst_path, NULL))
722723
goto cleanup;
723724

724-
junction = CreateFileW(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
725+
junction = _Py_WinCreateFile(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
725726
OPEN_EXISTING,
726727
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
727728
if (junction == INVALID_HANDLE_VALUE)

Modules/getpath.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifdef MS_WINDOWS
1515
# include <windows.h> // GetFullPathNameW(), MAX_PATH
1616
# include <pathcch.h>
17+
# include "internal/pycore_fileutils_windows.h"
1718
#endif
1819

1920
#ifdef __APPLE__
@@ -527,7 +528,7 @@ getpath_realpath(PyObject *Py_UNUSED(self) , PyObject *args)
527528
}
528529

529530
Py_BEGIN_ALLOW_THREADS
530-
hFile = CreateFileW(path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
531+
hFile = _Py_WinCreateFile(path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
531532
if (hFile != INVALID_HANDLE_VALUE) {
532533
len = GetFinalPathNameByHandleW(hFile, resolved, MAXPATHLEN, VOLUME_NAME_DOS);
533534
err = len ? 0 : GetLastError();

Modules/overlapped.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
#include "Python.h"
1515
#include "pycore_tuple.h" // _PyTuple_FromPairSteal
1616

17-
#define WINDOWS_LEAN_AND_MEAN
17+
#ifdef MS_WINDOWS
18+
# define WINDOWS_LEAN_AND_MEAN
19+
# include "internal/pycore_fileutils_windows.h"
20+
#endif
21+
1822
#include <winsock2.h>
1923
#include <ws2tcpip.h>
2024
#include <mswsock.h>
@@ -1635,7 +1639,7 @@ _overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self,
16351639
HANDLE PipeHandle;
16361640

16371641
Py_BEGIN_ALLOW_THREADS
1638-
PipeHandle = CreateFileW(Address,
1642+
PipeHandle = _Py_WinCreateFile(Address,
16391643
GENERIC_READ | GENERIC_WRITE,
16401644
0, NULL, OPEN_EXISTING,
16411645
FILE_FLAG_OVERLAPPED, NULL);

Modules/posixmodule.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,7 +2124,7 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
21242124
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
21252125
}
21262126

2127-
hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
2127+
hFile = _Py_WinCreateFile(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
21282128
if (hFile == INVALID_HANDLE_VALUE) {
21292129
/* Either the path doesn't exist, or the caller lacks access. */
21302130
error = GetLastError();
@@ -2159,7 +2159,7 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
21592159

21602160
case ERROR_INVALID_PARAMETER:
21612161
/* \\.\con requires read or write access. */
2162-
hFile = CreateFileW(path, access | GENERIC_READ,
2162+
hFile = _Py_WinCreateFile(path, access | GENERIC_READ,
21632163
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
21642164
OPEN_EXISTING, flags, NULL);
21652165
if (hFile == INVALID_HANDLE_VALUE) {
@@ -2173,7 +2173,7 @@ win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result,
21732173
if (traverse) {
21742174
traverse = FALSE;
21752175
isUnhandledTag = TRUE;
2176-
hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
2176+
hFile = _Py_WinCreateFile(path, access, 0, NULL, OPEN_EXISTING,
21772177
flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
21782178
}
21792179
if (hFile == INVALID_HANDLE_VALUE) {
@@ -4107,7 +4107,7 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
41074107
result = win32_fchmod(path->fd, mode);
41084108
}
41094109
else if (follow_symlinks) {
4110-
HANDLE hfile = CreateFileW(path->wide,
4110+
HANDLE hfile = _Py_WinCreateFile(path->wide,
41114111
FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES,
41124112
0, NULL,
41134113
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
@@ -5384,7 +5384,7 @@ os__path_isdevdrive_impl(PyObject *module, path_t *path)
53845384
/* only care about local dev drives */
53855385
r = Py_False;
53865386
} else {
5387-
HANDLE hVolume = CreateFileW(
5387+
HANDLE hVolume = _Py_WinCreateFile(
53885388
volume,
53895389
FILE_READ_ATTRIBUTES,
53905390
FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -5532,7 +5532,7 @@ os__getfinalpathname_impl(PyObject *module, path_t *path)
55325532
PyObject *result;
55335533

55345534
Py_BEGIN_ALLOW_THREADS
5535-
hFile = CreateFileW(
5535+
hFile = _Py_WinCreateFile(
55365536
path->wide,
55375537
0, /* desired access */
55385538
0, /* share mode */
@@ -5807,7 +5807,7 @@ _testFileTypeByName(LPCWSTR path, int testedType)
58075807
if (testedType != PY_IFREG && testedType != PY_IFDIR) {
58085808
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
58095809
}
5810-
HANDLE hfile = CreateFileW(path, FILE_READ_ATTRIBUTES, 0, NULL,
5810+
HANDLE hfile = _Py_WinCreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
58115811
OPEN_EXISTING, flags, NULL);
58125812
if (hfile != INVALID_HANDLE_VALUE) {
58135813
BOOL result = _testFileTypeByHandle(hfile, testedType, FALSE);
@@ -5863,7 +5863,7 @@ _testFileExistsByName(LPCWSTR path, BOOL followLinks)
58635863
if (!followLinks) {
58645864
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
58655865
}
5866-
HANDLE hfile = CreateFileW(path, FILE_READ_ATTRIBUTES, 0, NULL,
5866+
HANDLE hfile = _Py_WinCreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
58675867
OPEN_EXISTING, flags, NULL);
58685868
if (hfile != INVALID_HANDLE_VALUE) {
58695869
if (followLinks) {
@@ -5876,7 +5876,7 @@ _testFileExistsByName(LPCWSTR path, BOOL followLinks)
58765876
if (!result) {
58775877
return TRUE;
58785878
}
5879-
hfile = CreateFileW(path, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
5879+
hfile = _Py_WinCreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
58805880
FILE_FLAG_BACKUP_SEMANTICS, NULL);
58815881
if (hfile != INVALID_HANDLE_VALUE) {
58825882
CloseHandle(hfile);
@@ -7172,7 +7172,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
71727172

71737173
#ifdef MS_WINDOWS
71747174
Py_BEGIN_ALLOW_THREADS
7175-
hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
7175+
hFile = _Py_WinCreateFile(path->wide, FILE_WRITE_ATTRIBUTES, 0,
71767176
NULL, OPEN_EXISTING,
71777177
FILE_FLAG_BACKUP_SEMANTICS, NULL);
71787178
Py_END_ALLOW_THREADS
@@ -10954,7 +10954,7 @@ os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
1095410954

1095510955
/* First get a handle to the reparse point */
1095610956
Py_BEGIN_ALLOW_THREADS
10957-
reparse_point_handle = CreateFileW(
10957+
reparse_point_handle = _Py_WinCreateFile(
1095810958
path->wide,
1095910959
0,
1096010960
0,

0 commit comments

Comments
 (0)