-
Notifications
You must be signed in to change notification settings - Fork 84
/
Copy pathrestore-win7-handling-1.patch
185 lines (175 loc) · 6.71 KB
/
restore-win7-handling-1.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
diff --git a/Modules/_winapi.c b/Modules/_winapi.c
index 7727540..8532356 100644
--- a/Modules/_winapi.c
+++ b/Modules/_winapi.c
@@ -2104,6 +2104,8 @@ _winapi_NeedCurrentDirectoryForExePath_impl(PyObject *module,
return result;
}
+typedef HRESULT (WINAPI *CopyFile2Func)(PCWSTR pwszExistingFileName, PCWSTR pwszNewFileName, COPYFILE2_EXTENDED_PARAMETERS *pExtendedParameters);
+CopyFile2Func Py_CopyFile2;
/*[clinic input]
_winapi.CopyFile2
@@ -2146,7 +2148,7 @@ _winapi_CopyFile2_impl(PyObject *module, LPCWSTR existing_file_name,
}
*/
Py_BEGIN_ALLOW_THREADS;
- hr = CopyFile2(existing_file_name, new_file_name, ¶ms);
+ hr = Py_CopyFile2(existing_file_name, new_file_name, ¶ms);
Py_END_ALLOW_THREADS;
/* For future implementation.
if (progress_routine != Py_None) {
@@ -2420,5 +2422,21 @@ static struct PyModuleDef winapi_module = {
PyMODINIT_FUNC
PyInit__winapi(void)
{
+ HMODULE hKernel32 = GetModuleHandleW(L"kernel32");
+ if (!hKernel32) return NULL;
+ if (!(Py_CopyFile2 = (CopyFile2Func)GetProcAddress(hKernel32, "CopyFile2"))) {
+ for (PyMethodDef *method = winapi_functions; method->ml_name; method++) {
+ if (!strcmp(method->ml_name, "CopyFile2")) {
+ PyMethodDef *last = winapi_functions + Py_ARRAY_LENGTH(winapi_functions) - 2;
+ if (method == last) {
+ memset(method, 0, sizeof(*method));
+ } else {
+ *method = *last;
+ memset(last, 0, sizeof(*last));
+ }
+ break;
+ }
+ }
+ }
return PyModuleDef_Init(&winapi_module);
}
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index b9ca286..5711047 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -8759,33 +8759,94 @@ os_setpgrp_impl(PyObject *module)
#ifdef HAVE_GETPPID
#ifdef MS_WINDOWS
+#include <tlhelp32.h>
#include <processsnapshot.h>
+static INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT;
+typedef DWORD (WINAPI *PssCaptureSnapshotFunc)(HANDLE ProcessHandle, PSS_CAPTURE_FLAGS CaptureFlags, DWORD ThreadContextFlags, HPSS* SnapshotHandle);
+typedef DWORD (WINAPI *PssQuerySnapshotFunc)(HPSS SnapshotHandle, PSS_QUERY_INFORMATION_CLASS InformationClass, void* Buffer, DWORD BufferLength);
+typedef DWORD (WINAPI *PssFreeSnapshotFunc)(HANDLE ProcessHandle, HPSS SnapshotHandle);
+static PssCaptureSnapshotFunc Py_PssCaptureSnapshot;
+static PssQuerySnapshotFunc Py_PssQuerySnapshot;
+static PssFreeSnapshotFunc Py_PssFreeSnapshot;
+
+static BOOL CALLBACK Py_ProcessSnapshot_Init(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContext)
+{
+ HMODULE hKernel32 = GetModuleHandleW(L"kernel32");
+ if (hKernel32) {
+ Py_PssCaptureSnapshot = (PssCaptureSnapshotFunc)GetProcAddress(hKernel32, "PssCaptureSnapshot");
+ Py_PssQuerySnapshot = (PssQuerySnapshotFunc)GetProcAddress(hKernel32, "PssQuerySnapshot");
+ Py_PssFreeSnapshot = (PssFreeSnapshotFunc)GetProcAddress(hKernel32, "PssFreeSnapshot");
+ if (!Py_PssCaptureSnapshot || !Py_PssQuerySnapshot || !Py_PssFreeSnapshot) {
+ Py_PssCaptureSnapshot = NULL;
+ Py_PssQuerySnapshot = NULL;
+ Py_PssFreeSnapshot = NULL;
+ }
+ }
+ return TRUE;
+}
+
static PyObject*
win32_getppid(void)
{
- DWORD error;
- PyObject* result = NULL;
- HANDLE process = GetCurrentProcess();
+ InitOnceExecuteOnce(&g_InitOnce, Py_ProcessSnapshot_Init, NULL, NULL);
+ if (Py_PssCaptureSnapshot) {
+ DWORD error;
+ PyObject* result = NULL;
+ HANDLE process = GetCurrentProcess();
- HPSS snapshot = NULL;
- error = PssCaptureSnapshot(process, PSS_CAPTURE_NONE, 0, &snapshot);
- if (error != ERROR_SUCCESS) {
- return PyErr_SetFromWindowsErr(error);
- }
+ HPSS snapshot = NULL;
+ error = Py_PssCaptureSnapshot(process, PSS_CAPTURE_NONE, 0, &snapshot);
+ if (error != ERROR_SUCCESS) {
+ return PyErr_SetFromWindowsErr(error);
+ }
- PSS_PROCESS_INFORMATION info;
- error = PssQuerySnapshot(snapshot, PSS_QUERY_PROCESS_INFORMATION, &info,
- sizeof(info));
- if (error == ERROR_SUCCESS) {
- result = PyLong_FromUnsignedLong(info.ParentProcessId);
- }
- else {
- result = PyErr_SetFromWindowsErr(error);
- }
+ PSS_PROCESS_INFORMATION info;
+ error = Py_PssQuerySnapshot(snapshot, PSS_QUERY_PROCESS_INFORMATION, &info,
+ sizeof(info));
+ if (error == ERROR_SUCCESS) {
+ result = PyLong_FromUnsignedLong(info.ParentProcessId);
+ } else {
+ result = PyErr_SetFromWindowsErr(error);
+ }
- PssFreeSnapshot(process, snapshot);
- return result;
+ Py_PssFreeSnapshot(process, snapshot);
+ return result;
+ } else {
+ HANDLE snapshot;
+ pid_t mypid;
+ PyObject* result = NULL;
+ BOOL have_record;
+ PROCESSENTRY32 pe;
+
+ mypid = getpid(); /* This function never fails */
+
+ snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (snapshot == INVALID_HANDLE_VALUE)
+ return PyErr_SetFromWindowsErr(GetLastError());
+
+ pe.dwSize = sizeof(pe);
+ have_record = Process32First(snapshot, &pe);
+ while (have_record) {
+ if (mypid == (pid_t)pe.th32ProcessID) {
+ /* We could cache the ulong value in a static variable. */
+ result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
+ break;
+ }
+
+ have_record = Process32Next(snapshot, &pe);
+ }
+
+ /* If our loop exits and our pid was not found (result will be NULL)
+ * then GetLastError will return ERROR_NO_MORE_FILES. This is an
+ * error anyway, so let's raise it. */
+ if (!result)
+ result = PyErr_SetFromWindowsErr(GetLastError());
+
+ CloseHandle(snapshot);
+
+ return result;
+ }
}
#endif /*MS_WINDOWS*/
diff --git a/Python/fileutils.c b/Python/fileutils.c
index c752175..36397b3 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -1489,11 +1489,17 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
else
flags = 0;
- if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
+ /* This check can be removed once support for Windows 7 ends. */
+#define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \
+ GetFileType(handle) == FILE_TYPE_CHAR)
+
+ if (!CONSOLE_PSEUDOHANDLE(handle) &&
+ !SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
if (raise)
PyErr_SetFromWindowsErr(0);
return -1;
}
+#undef CONSOLE_PSEUDOHANDLE
return 0;
#else