Skip to content

Instantly share code, notes, and snippets.

@PolarNick239
Last active December 15, 2020 02:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PolarNick239/5168c2bbf2731171bc190a465cc4d052 to your computer and use it in GitHub Desktop.
Save PolarNick239/5168c2bbf2731171bc190a465cc4d052 to your computer and use it in GitHub Desktop.
--- a/PC/python.manifest
+++ b/PC/python.manifest
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
- <trustInfo>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -1445,6 +1445,31 @@
return TRUE;
}
+/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
+static int has_GetFinalPathNameByHandle = -1;
+static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
+ DWORD);
+static int
+check_GetFinalPathNameByHandle()
+{
+ HINSTANCE hKernel32;
+ DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
+ DWORD);
+
+ /* only recheck */
+ if (-1 == has_GetFinalPathNameByHandle)
+ {
+ hKernel32 = GetModuleHandleW(L"KERNEL32");
+ *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
+ "GetFinalPathNameByHandleA");
+ *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
+ "GetFinalPathNameByHandleW");
+ has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
+ Py_GetFinalPathNameByHandleW;
+ }
+ return has_GetFinalPathNameByHandle;
+}
+
static BOOL
get_target_path(HANDLE hdl, wchar_t **target_path)
{
@@ -1453,7 +1479,7 @@
/* We have a good handle to the target, use it to determine
the target path name (then we'll call lstat on it). */
- buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
+ buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
VOLUME_NAME_DOS);
if(!buf_size)
return FALSE;
@@ -1464,7 +1490,7 @@
return FALSE;
}
- result_length = GetFinalPathNameByHandleW(hdl,
+ result_length = Py_GetFinalPathNameByHandleW(hdl,
buf, buf_size, VOLUME_NAME_DOS);
if(!result_length) {
@@ -1497,6 +1523,12 @@
wchar_t *target_path;
const char *dot;
+ if(!check_GetFinalPathNameByHandle()) {
+ /* If the OS doesn't have GetFinalPathNameByHandle, don't
+ traverse reparse point. */
+ traverse = FALSE;
+ }
+
hFile = CreateFileA(
path,
FILE_READ_ATTRIBUTES, /* desired access */
@@ -1587,6 +1619,12 @@
wchar_t *target_path;
const wchar_t *dot;
+ if(!check_GetFinalPathNameByHandle()) {
+ /* If the OS doesn't have GetFinalPathNameByHandle, don't
+ traverse reparse point. */
+ traverse = FALSE;
+ }
+
hFile = CreateFileW(
path,
FILE_READ_ATTRIBUTES, /* desired access */
@@ -3824,6 +3862,13 @@
if (path_wchar == NULL)
return NULL;
+ if(!check_GetFinalPathNameByHandle()) {
+ /* If the OS doesn't have GetFinalPathNameByHandle, return a
+ NotImplementedError. */
+ return PyErr_Format(PyExc_NotImplementedError,
+ "GetFinalPathNameByHandle not available on this platform");
+ }
+
hFile = CreateFileW(
path_wchar,
0, /* desired access */
@@ -3839,7 +3884,7 @@
/* We have a good handle to the target, use it to determine the
target path name. */
- buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
+ buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
if(!buf_size)
return win32_error_object("GetFinalPathNameByHandle", path);
@@ -3848,7 +3893,7 @@
if(!target_path)
return PyErr_NoMemory();
- result_length = GetFinalPathNameByHandleW(hFile, target_path,
+ result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
buf_size, VOLUME_NAME_DOS);
if(!result_length)
return win32_error_object("GetFinalPathNamyByHandle", path);
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -463,7 +463,7 @@
/* 11,644,473,600,000,000,000: number of nanoseconds between
the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
days). */
- *tp = large.QuadPart * 100 - 11644473600000000000;
+ *tp = large.QuadPart * 100 - 11644473600000000000ULL;
if (info) {
DWORD timeAdjustment, timeIncrement;
BOOL isTimeAdjustmentDisabled, ok;
@@ -557,6 +557,32 @@
return pygettimeofday(t, info, 1);
}
+/* GetTickCount64() is not available on XP. */
+ULONGLONG GetTickCount64_Alternative ()
+{
+ static ULONGLONG (CALLBACK *Py_GetTickCount64)() = (ULONGLONG (CALLBACK *)(void))-1;
+ static DWORD last_ticks = 0;
+ static DWORD n_overflow = 0;
+ DWORD ticks = 0;
+ HINSTANCE hKernel32;
+
+ if (Py_GetTickCount64 == (void*)-1)
+ {
+ hKernel32 = GetModuleHandleW(L"KERNEL32");
+ Py_GetTickCount64 = *(ULONGLONG (CALLBACK *)(void))(GetProcAddress(hKernel32,
+ "GetTickCount64"));
+ }
+ if (Py_GetTickCount64 != (void*) NULL)
+ {
+ return Py_GetTickCount64();
+ }
+
+ ticks = GetTickCount();
+ if (ticks < last_ticks)
+ n_overflow++;
+ last_ticks = ticks;
+ return ((ULONGLONG)n_overflow << 32LL) + (ULONGLONG)GetTickCount();
+}
static int
pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
@@ -566,7 +592,7 @@
assert(info == NULL || raise);
- result = GetTickCount64();
+ result = GetTickCount64_Alternative();
*tp = result * MS_TO_NS;
if (*tp / MS_TO_NS != result) {
@AureliusMarcusHu
Copy link

Dear PolarNick,
I don't understand the meaning of this patch. I have an old laptop with Windows Xp 32 bit Service pack 3 and want to run python 3.5+ version on this laptop with scrapy. Is it possible with installing this patch ? And how do I install this patch ?
Thanks in advance
Marcus

@PolarNick239
Copy link
Author

You need to compile python from source code (with changes from this patch). This is not easy - https://devguide.python.org/setup/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment