mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-12-01 01:41:48 +08:00
327 lines
11 KiB
Diff
327 lines
11 KiB
Diff
From e30a560527d17ae81685dd11d3268bc982af2048 Mon Sep 17 00:00:00 2001
|
|
From: Adam Johnson <AdamJohnso@gmail.com>
|
|
Date: Tue, 16 Feb 2021 18:03:07 -0500
|
|
Subject: [PATCH 7/7] restore support for windows 7
|
|
|
|
this backports the windows 7 compatible fix for bpo-39401 from gh-18234,
|
|
originally authored by Steve Dower, and removes explicit dependencies on
|
|
pathcch.
|
|
|
|
The same mechanism is applied to fix posixmodule.c
|
|
---
|
|
index 25ddc82..ff51042 100644
|
|
--- a/Modules/_winapi.c
|
|
+++ b/Modules/_winapi.c
|
|
@@ -44,6 +44,15 @@
|
|
|
|
#include "pycore_runtime.h" // _Py_ID
|
|
|
|
+// The Windws 7 patch lowers the API version such that these constants
|
|
+// are no longer defined by the Windows SDK. Debounce that.
|
|
+#ifndef LCMAP_SORTHANDLE
|
|
+# define LCMAP_SORTHANDLE 0x20000000
|
|
+#endif
|
|
+#ifndef LCMAP_HASH
|
|
+# define LCMAP_HASH 0x00040000
|
|
+#endif
|
|
+
|
|
#if defined(MS_WIN32) && !defined(MS_WIN64)
|
|
#define HANDLE_TO_PYNUM(handle) \
|
|
PyLong_FromUnsignedLong((unsigned long) handle)
|
|
diff --git a/Modules/getpath.c b/Modules/getpath.c
|
|
index bc730fc..7d3d559 100644
|
|
--- a/Modules/getpath.c
|
|
+++ b/Modules/getpath.c
|
|
@@ -11,7 +11,7 @@
|
|
|
|
#ifdef MS_WINDOWS
|
|
# include <windows.h> // GetFullPathNameW(), MAX_PATH
|
|
-# include <pathcch.h>
|
|
+# include <Shlwapi.h>
|
|
#endif
|
|
|
|
#ifdef __APPLE__
|
|
@@ -217,6 +217,11 @@ getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args)
|
|
return r;
|
|
}
|
|
|
|
+#ifdef MS_WINDOWS
|
|
+static int _PathCchFindExtension_Initialized = 0;
|
|
+typedef HRESULT (__stdcall *PPathCchFindExtension) (PCWSTR pszPath, size_t cchPath, PCWSTR *ppszExt);
|
|
+static PPathCchFindExtension _PathCchFindExtension;
|
|
+#endif
|
|
|
|
static PyObject *
|
|
getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args)
|
|
@@ -231,13 +235,51 @@ getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args)
|
|
path = PyUnicode_AsWideCharString(pathobj, &cchPath);
|
|
if (path) {
|
|
#ifdef MS_WINDOWS
|
|
+
|
|
+ if (_PathCchFindExtension_Initialized == 0) {
|
|
+ HMODULE pathapi = LoadLibraryExW(L"api-ms-win-core-path-l1-1-0.dll", NULL,
|
|
+ LOAD_LIBRARY_SEARCH_SYSTEM32);
|
|
+
|
|
+ if (pathapi) {
|
|
+ _PathCchFindExtension = (PPathCchFindExtension)GetProcAddress(pathapi, "PathCchFindExtension");
|
|
+ } else {
|
|
+ _PathCchFindExtension = NULL;
|
|
+ }
|
|
+
|
|
+ _PathCchFindExtension_Initialized = 1;
|
|
+ }
|
|
+
|
|
const wchar_t *ext;
|
|
DWORD attr = GetFileAttributesW(path);
|
|
- r = (attr != INVALID_FILE_ATTRIBUTES) &&
|
|
- !(attr & FILE_ATTRIBUTE_DIRECTORY) &&
|
|
- SUCCEEDED(PathCchFindExtension(path, cchPath + 1, &ext)) &&
|
|
- (CompareStringOrdinal(ext, -1, L".exe", -1, 1 /* ignore case */) == CSTR_EQUAL)
|
|
- ? Py_True : Py_False;
|
|
+ if (attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
+ r = Py_False;
|
|
+ }
|
|
+ else {
|
|
+ HRESULT hr = S_OK;
|
|
+ if (_PathCchFindExtension) {
|
|
+ hr = _PathCchFindExtension(path, cchPath + 1, &ext);
|
|
+ }
|
|
+ else {
|
|
+ if (cchPath > MAX_PATH) {
|
|
+ hr = E_FAIL;
|
|
+ }
|
|
+ else {
|
|
+ ext = PathFindExtensionW(path);
|
|
+ if (*ext == '\0')
|
|
+ hr = E_FAIL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!SUCCEEDED(hr)) {
|
|
+ r = Py_False;
|
|
+ }
|
|
+ else if (CompareStringOrdinal(ext, -1, L".exe", -1, 1 /* ignore case */) != CSTR_EQUAL) {
|
|
+ r = Py_False;
|
|
+ }
|
|
+ else {
|
|
+ r = Py_True;
|
|
+ }
|
|
+ }
|
|
#else
|
|
struct stat st;
|
|
r = (_Py_wstat(path, &st) == 0) &&
|
|
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
|
|
--- a/Modules/posixmodule.c
|
|
+++ b/Modules/posixmodule.c
|
|
@@ -15,7 +15,7 @@
|
|
// whereas pycore_condvar.h defines the WIN32_LEAN_AND_MEAN macro.
|
|
#ifdef MS_WINDOWS
|
|
# include <windows.h>
|
|
-# include <pathcch.h>
|
|
+# include <Shlwapi.h>
|
|
# include <lmcons.h> // UNLEN
|
|
# include "osdefs.h" // SEP
|
|
# define HAVE_SYMLINK
|
|
@@ -4471,6 +4471,11 @@ os__getvolumepathname_impl(PyObject *module, path_t *path)
|
|
return result;
|
|
}
|
|
|
|
+#ifdef MS_WINDOWS
|
|
+static int _PathCchSkipRoot_Initialized = 0;
|
|
+typedef HRESULT (__stdcall *PPathCchSkipRoot) (PCWSTR pszPath, PCWSTR *ppszRootEnd);
|
|
+static PPathCchSkipRoot _PathCchSkipRoot;
|
|
+#endif
|
|
|
|
/*[clinic input]
|
|
os._path_splitroot
|
|
@@ -4489,6 +4493,19 @@ os__path_splitroot_impl(PyObject *module, path_t *path)
|
|
PyObject *result = NULL;
|
|
HRESULT ret;
|
|
|
|
+ if (_PathCchSkipRoot_Initialized == 0) {
|
|
+ HMODULE pathapi = LoadLibraryExW(L"api-ms-win-core-path-l1-1-0.dll", NULL,
|
|
+ LOAD_LIBRARY_SEARCH_SYSTEM32);
|
|
+
|
|
+ if (pathapi) {
|
|
+ _PathCchSkipRoot = (PPathCchSkipRoot)GetProcAddress(pathapi, "PathCchSkipRoot");
|
|
+ } else {
|
|
+ _PathCchSkipRoot = NULL;
|
|
+ }
|
|
+
|
|
+ _PathCchSkipRoot_Initialized = 1;
|
|
+ }
|
|
+
|
|
buffer = (wchar_t*)PyMem_Malloc(sizeof(wchar_t) * (wcslen(path->wide) + 1));
|
|
if (!buffer) {
|
|
return NULL;
|
|
@@ -4499,7 +4516,14 @@ os__path_splitroot_impl(PyObject *module, path_t *path)
|
|
}
|
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
- ret = PathCchSkipRoot(buffer, &end);
|
|
+ if (_PathCchSkipRoot) {
|
|
+ ret = _PathCchSkipRoot(buffer, &end);
|
|
+ } else {
|
|
+ end = PathSkipRootW(buffer);
|
|
+ if (!end) {
|
|
+ ret = E_FAIL;
|
|
+ }
|
|
+ }
|
|
Py_END_ALLOW_THREADS
|
|
if (FAILED(ret)) {
|
|
result = Py_BuildValue("sO", "", path->object);
|
|
diff --git a/PC/pyconfig.h b/PC/pyconfig.h
|
|
index d7d3cf0..6e9c090 100644
|
|
--- a/PC/pyconfig.h
|
|
+++ b/PC/pyconfig.h
|
|
@@ -130,8 +130,8 @@ WIN32 is still required for the locale module.
|
|
|
|
/* set the version macros for the windows headers */
|
|
/* Python 3.9+ requires Windows 8 or greater */
|
|
-#define Py_WINVER 0x0602 /* _WIN32_WINNT_WIN8 */
|
|
-#define Py_NTDDI NTDDI_WIN8
|
|
+#define Py_WINVER 0x0601 /* _WIN32_WINNT_WIN7 */
|
|
+#define Py_NTDDI NTDDI_WIN7
|
|
|
|
/* We only set these values when building Python - we don't want to force
|
|
these values on extensions, as that will affect the prototypes and
|
|
diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj
|
|
index 442e343..ef0a43e 100644
|
|
--- a/PCbuild/_freeze_module.vcxproj
|
|
+++ b/PCbuild/_freeze_module.vcxproj
|
|
@@ -94,7 +94,7 @@
|
|
</ClCompile>
|
|
<Link>
|
|
<SubSystem>Console</SubSystem>
|
|
- <AdditionalDependencies>version.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
+ <AdditionalDependencies>version.lib;ws2_32.lib;shlwapi.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
|
</Link>
|
|
</ItemDefinitionGroup>
|
|
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
|
|
index c39ba3e1a9..0ef3a05fb6 100644
|
|
--- a/PCbuild/pythoncore.vcxproj
|
|
+++ b/PCbuild/pythoncore.vcxproj
|
|
@@ -106,7 +106,7 @@
|
|
<PreprocessorDefinitions Condition="$(IncludeExternals)">_Py_HAVE_ZLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
</ClCompile>
|
|
<Link>
|
|
- <AdditionalDependencies>version.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
+ <AdditionalDependencies>version.lib;ws2_32.lib;shlwapi.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
</Link>
|
|
</ItemDefinitionGroup>
|
|
<ItemGroup>
|
|
diff --git a/Python/fileutils.c b/Python/fileutils.c
|
|
index c86ed40..6b1535d 100644
|
|
--- a/Python/fileutils.c
|
|
+++ b/Python/fileutils.c
|
|
@@ -8,7 +8,7 @@
|
|
#ifdef MS_WINDOWS
|
|
# include <malloc.h>
|
|
# include <windows.h>
|
|
-# include <pathcch.h> // PathCchCombineEx
|
|
+# include <Shlwapi.h>
|
|
extern int winerror_to_errno(int);
|
|
#endif
|
|
|
|
@@ -1999,13 +1999,46 @@ _Py_wrealpath(const wchar_t *path,
|
|
}
|
|
#endif
|
|
|
|
+#ifdef MS_WINDOWS
|
|
+static int _PathCchSkipRoot_Initialized = 0;
|
|
+typedef HRESULT (__stdcall *PPathCchSkipRoot) (PCWSTR pszPath, PCWSTR *ppszRootEnd);
|
|
+static PPathCchSkipRoot _PathCchSkipRoot;
|
|
+
|
|
+#ifndef PATHCCH_ALLOW_LONG_PATHS
|
|
+#define PATHCCH_ALLOW_LONG_PATHS 0x00000001
|
|
+#endif
|
|
+#endif
|
|
|
|
int
|
|
_Py_isabs(const wchar_t *path)
|
|
{
|
|
#ifdef MS_WINDOWS
|
|
+ if (_PathCchSkipRoot_Initialized == 0) {
|
|
+ HMODULE pathapi = LoadLibraryExW(L"api-ms-win-core-path-l1-1-0.dll", NULL,
|
|
+ LOAD_LIBRARY_SEARCH_SYSTEM32);
|
|
+
|
|
+ if (pathapi) {
|
|
+ _PathCchSkipRoot = (PPathCchSkipRoot)GetProcAddress(pathapi, "PathCchSkipRoot");
|
|
+ } else {
|
|
+ _PathCchSkipRoot = NULL;
|
|
+ }
|
|
+
|
|
+ _PathCchSkipRoot_Initialized = 1;
|
|
+ }
|
|
+
|
|
+ HRESULT hr;
|
|
const wchar_t *tail;
|
|
- HRESULT hr = PathCchSkipRoot(path, &tail);
|
|
+ if (_PathCchSkipRoot) {
|
|
+ hr = _PathCchSkipRoot(path, &tail);
|
|
+ } else {
|
|
+ tail = PathSkipRootW(path);
|
|
+ if (!tail) {
|
|
+ hr = E_FAIL;
|
|
+ } else {
|
|
+ hr = S_OK;
|
|
+ }
|
|
+ }
|
|
+
|
|
if (FAILED(hr) || path == tail) {
|
|
return 0;
|
|
}
|
|
@@ -2086,6 +2117,11 @@ _Py_abspath(const wchar_t *path, wchar_t **abspath_p)
|
|
#endif
|
|
}
|
|
|
|
+#ifdef MS_WINDOWS
|
|
+static int _PathCchCombineEx_Initialized = 0;
|
|
+typedef HRESULT (__stdcall *PPathCchCombineEx) (PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore, ULONG dwFlags);
|
|
+static PPathCchCombineEx _PathCchCombineEx;
|
|
+#endif
|
|
|
|
// The caller must ensure "buffer" is big enough.
|
|
static int
|
|
@@ -2093,9 +2127,36 @@ join_relfile(wchar_t *buffer, size_t bufsize,
|
|
const wchar_t *dirname, const wchar_t *relfile)
|
|
{
|
|
#ifdef MS_WINDOWS
|
|
- if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile,
|
|
- PATHCCH_ALLOW_LONG_PATHS))) {
|
|
- return -1;
|
|
+
|
|
+ if (_PathCchCombineEx_Initialized == 0) {
|
|
+ HMODULE pathapi = LoadLibraryExW(L"api-ms-win-core-path-l1-1-0.dll", NULL,
|
|
+ LOAD_LIBRARY_SEARCH_SYSTEM32);
|
|
+
|
|
+ if (pathapi) {
|
|
+ _PathCchCombineEx = (PPathCchCombineEx)GetProcAddress(pathapi, "PathCchCombineEx");
|
|
+ } else {
|
|
+ _PathCchCombineEx = NULL;
|
|
+ }
|
|
+
|
|
+ _PathCchCombineEx_Initialized = 1;
|
|
+ }
|
|
+
|
|
+ if (_PathCchCombineEx) {
|
|
+ if (FAILED(_PathCchCombineEx(buffer, bufsize, dirname, relfile,
|
|
+ PATHCCH_ALLOW_LONG_PATHS))) {
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ size_t dirlen = wcslen(dirname);
|
|
+ size_t rellen = wcslen(relfile);
|
|
+ size_t maxlen = bufsize - 1;
|
|
+ if (maxlen > MAX_PATH || dirlen >= maxlen || rellen >= maxlen - dirlen) {
|
|
+ return -1;
|
|
+ }
|
|
+ wchar_t * r = PathCombineW(buffer, dirname, relfile);
|
|
+ if (!r)
|
|
+ return -1;
|
|
}
|
|
#else
|
|
assert(!_Py_isabs(relfile));
|