Skip to content

gh-102336: remove windows 7 special handling #102337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Cleanup Windows 7 specific special handling. Patch by Max Bachmann.
31 changes: 6 additions & 25 deletions Modules/_winapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,23 +63,6 @@

#define T_HANDLE T_POINTER

/* Grab CancelIoEx dynamically from kernel32 */
static int has_CancelIoEx = -1;
static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED);

static int
check_CancelIoEx()
{
if (has_CancelIoEx == -1)
{
HINSTANCE hKernel32 = GetModuleHandle("KERNEL32");
* (FARPROC *) &Py_CancelIoEx = GetProcAddress(hKernel32,
"CancelIoEx");
has_CancelIoEx = (Py_CancelIoEx != NULL);
}
return has_CancelIoEx;
}

typedef struct {
PyTypeObject *overlapped_type;
} WinApiState;
Expand Down Expand Up @@ -134,8 +117,7 @@ overlapped_dealloc(OverlappedObject *self)

PyObject_GC_UnTrack(self);
if (self->pending) {
if (check_CancelIoEx() &&
Py_CancelIoEx(self->handle, &self->overlapped) &&
if (CancelIoEx(self->handle, &self->overlapped) &&
GetOverlappedResult(self->handle, &self->overlapped, &bytes, TRUE))
{
/* The operation is no longer pending -- nothing to do. */
Expand Down Expand Up @@ -306,10 +288,7 @@ _winapi_Overlapped_cancel_impl(OverlappedObject *self)

if (self->pending) {
Py_BEGIN_ALLOW_THREADS
if (check_CancelIoEx())
res = Py_CancelIoEx(self->handle, &self->overlapped);
else
res = CancelIo(self->handle);
CancelIoEx(self->handle, &self->overlapped);
Py_END_ALLOW_THREADS
}

Expand Down Expand Up @@ -655,8 +634,10 @@ _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path,
cleanup:
ret = GetLastError();

CloseHandle(token);
CloseHandle(junction);
if (token != NULL)
CloseHandle(token);
if (junction != NULL)
CloseHandle(junction);
PyMem_RawFree(rdb);

if (ret != 0)
Expand Down
5 changes: 2 additions & 3 deletions Modules/getpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,11 @@ getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args)
path = PyUnicode_AsWideCharString(pathobj, &cchPath);
if (path) {
#ifdef MS_WINDOWS
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)
(cchPath >= 4) &&
(CompareStringOrdinal(path + cchPath - 4, -1, L".exe", -1, 1 /* ignore case */) == CSTR_EQUAL)
? Py_True : Py_False;
#else
struct stat st;
Expand Down
16 changes: 8 additions & 8 deletions Modules/mmapmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ mmap_resize_method(mmap_object *self,
CloseHandle(self->map_handle);
/* if the file mapping still exists, it cannot be resized. */
if (self->tagname) {
self->map_handle = OpenFileMapping(FILE_MAP_WRITE, FALSE,
self->map_handle = OpenFileMappingA(FILE_MAP_WRITE, FALSE,
self->tagname);
if (self->map_handle) {
PyErr_SetFromWindowsErr(ERROR_USER_MAPPED_FILE);
Expand Down Expand Up @@ -531,7 +531,7 @@ mmap_resize_method(mmap_object *self,

/* create a new file mapping and map a new view */
/* FIXME: call CreateFileMappingW with wchar_t tagname */
self->map_handle = CreateFileMapping(
self->map_handle = CreateFileMappingA(
self->file_handle,
NULL,
PAGE_READWRITE,
Expand Down Expand Up @@ -1514,12 +1514,12 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
off_lo = (DWORD)(offset & 0xFFFFFFFF);
/* For files, it would be sufficient to pass 0 as size.
For anonymous maps, we have to pass the size explicitly. */
m_obj->map_handle = CreateFileMapping(m_obj->file_handle,
NULL,
flProtect,
size_hi,
size_lo,
m_obj->tagname);
m_obj->map_handle = CreateFileMappingA(m_obj->file_handle,
NULL,
flProtect,
size_hi,
size_lo,
m_obj->tagname);
if (m_obj->map_handle != NULL) {
m_obj->data = (char *) MapViewOfFile(m_obj->map_handle,
dwDesiredAccess,
Expand Down
112 changes: 28 additions & 84 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@
#define PY_SSIZE_T_CLEAN

#include "Python.h"
// Include <windows.h> before pycore internal headers. FSCTL_GET_REPARSE_POINT
// is not exported by <windows.h> if the WIN32_LEAN_AND_MEAN macro is defined,
// whereas pycore_condvar.h defines the WIN32_LEAN_AND_MEAN macro.
#ifdef MS_WINDOWS
# include <windows.h>
# include <pathcch.h>
# include <lmcons.h> // UNLEN
# include "osdefs.h" // SEP
# define HAVE_SYMLINK
#endif

#ifdef __VXWORKS__
# include "pycore_bitutils.h" // _Py_popcount32()
Expand All @@ -34,6 +24,15 @@
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_signal.h" // Py_NSIG

#ifdef MS_WINDOWS
# include <windows.h>
# include <pathcch.h>
# include <winioctl.h>
# include <lmcons.h> // UNLEN
# include "osdefs.h" // SEP
# define HAVE_SYMLINK
#endif

#include "structmember.h" // PyMemberDef
#ifndef MS_WINDOWS
# include "posixmodule.h"
Expand Down Expand Up @@ -1507,32 +1506,6 @@ _Py_Sigset_Converter(PyObject *obj, void *addr)
}
#endif /* HAVE_SIGSET_T */

#ifdef MS_WINDOWS

static int
win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
{
char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
_Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
DWORD n_bytes_returned;

if (0 == DeviceIoControl(
reparse_point_handle,
FSCTL_GET_REPARSE_POINT,
NULL, 0, /* in buffer */
target_buffer, sizeof(target_buffer),
&n_bytes_returned,
NULL)) /* we're not using OVERLAPPED_IO */
return FALSE;

if (reparse_tag)
*reparse_tag = rdb->ReparseTag;

return TRUE;
}

#endif /* MS_WINDOWS */

/* Return a dictionary corresponding to the POSIX environment table */
#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
/* On Darwin/MacOSX a shared library or framework has no access to
Expand Down Expand Up @@ -8263,42 +8236,32 @@ os_setpgrp_impl(PyObject *module)
#ifdef HAVE_GETPPID

#ifdef MS_WINDOWS
#include <tlhelp32.h>
#include <processsnapshot.h>

static PyObject*
win32_getppid()
{
HANDLE snapshot;
DWORD error;
PyObject* result = NULL;
BOOL have_record;
PROCESSENTRY32 pe;

DWORD mypid = GetCurrentProcessId(); /* This function never fails */

snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE)
return PyErr_SetFromWindowsErr(GetLastError());
HANDLE process = GetCurrentProcess();

pe.dwSize = sizeof(pe);
have_record = Process32First(snapshot, &pe);
while (have_record) {
if (mypid == pe.th32ProcessID) {
/* We could cache the ulong value in a static variable. */
result = PyLong_FromUnsignedLong(pe.th32ParentProcessID);
break;
}

have_record = Process32Next(snapshot, &pe);
HPSS snapshot = NULL;
error = PssCaptureSnapshot(process, PSS_CAPTURE_NONE, 0, &snapshot);
if (error != ERROR_SUCCESS) {
return PyErr_SetFromWindowsErr(error);
}

/* 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);
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);
}

PssFreeSnapshot(process, snapshot);
return result;
}
#endif /*MS_WINDOWS*/
Expand Down Expand Up @@ -15067,9 +15030,6 @@ os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
* on win32
*/

typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);

/*[clinic input]
os._add_dll_directory

Expand All @@ -15089,23 +15049,15 @@ static PyObject *
os__add_dll_directory_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
{
HMODULE hKernel32;
PAddDllDirectory AddDllDirectory;
DLL_DIRECTORY_COOKIE cookie = 0;
DWORD err = 0;

if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
return NULL;
}

/* For Windows 7, we have to load this. As this will be a fairly
infrequent operation, just do it each time. Kernel32 is always
loaded. */
Py_BEGIN_ALLOW_THREADS
if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
!(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
hKernel32, "AddDllDirectory")) ||
!(cookie = (*AddDllDirectory)(path->wide))) {
if (!(cookie = AddDllDirectory(path->wide))) {
err = GetLastError();
}
Py_END_ALLOW_THREADS
Expand Down Expand Up @@ -15134,8 +15086,6 @@ static PyObject *
os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
{
HMODULE hKernel32;
PRemoveDllDirectory RemoveDllDirectory;
DLL_DIRECTORY_COOKIE cookieValue;
DWORD err = 0;

Expand All @@ -15148,14 +15098,8 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
cookie, "DLL directory cookie");

/* For Windows 7, we have to load this. As this will be a fairly
infrequent operation, just do it each time. Kernel32 is always
loaded. */
Py_BEGIN_ALLOW_THREADS
if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
!(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
hKernel32, "RemoveDllDirectory")) ||
!(*RemoveDllDirectory)(cookieValue)) {
if (!RemoveDllDirectory(cookieValue)) {
err = GetLastError();
}
Py_END_ALLOW_THREADS
Expand Down
42 changes: 10 additions & 32 deletions Modules/socketmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,11 +606,6 @@ select_error(void)
# define SUPPRESS_DEPRECATED_CALL
#endif

#ifdef MS_WINDOWS
/* Does WSASocket() support the WSA_FLAG_NO_HANDLE_INHERIT flag? */
static int support_wsa_no_inherit = -1;
#endif

/* Convenience function to raise an error according to errno
and return a NULL pointer from a function. */

Expand Down Expand Up @@ -5342,6 +5337,13 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,
set_error();
return -1;
}

if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0)) {
closesocket(fd);
PyErr_SetFromWindowsErr(0);
return -1;
}

family = info.iAddressFamily;
type = info.iSocketType;
proto = info.iProtocol;
Expand Down Expand Up @@ -5438,33 +5440,15 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,
#endif

Py_BEGIN_ALLOW_THREADS
if (support_wsa_no_inherit) {
fd = WSASocketW(family, type, proto,
NULL, 0,
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if (fd == INVALID_SOCKET) {
/* Windows 7 or Windows 2008 R2 without SP1 or the hotfix */
support_wsa_no_inherit = 0;
fd = socket(family, type, proto);
}
}
else {
fd = socket(family, type, proto);
}
fd = WSASocketW(family, type, proto,
NULL, 0,
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
Py_END_ALLOW_THREADS

if (fd == INVALID_SOCKET) {
set_error();
return -1;
}

if (!support_wsa_no_inherit) {
if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0)) {
closesocket(fd);
PyErr_SetFromWindowsErr(0);
return -1;
}
}
#else
/* UNIX */
Py_BEGIN_ALLOW_THREADS
Expand Down Expand Up @@ -7340,12 +7324,6 @@ PyInit__socket(void)
if (!os_init())
return NULL;

#ifdef MS_WINDOWS
if (support_wsa_no_inherit == -1) {
support_wsa_no_inherit = IsWindows7SP1OrGreater();
}
#endif

Py_SET_TYPE(&sock_type, &PyType_Type);
m = PyModule_Create(&socketmodule);
if (m == NULL)
Expand Down
8 changes: 1 addition & 7 deletions Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1362,17 +1362,11 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
else
flags = 0;

/* 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 (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
if (raise)
PyErr_SetFromWindowsErr(0);
return -1;
}
#undef CONSOLE_PSEUDOHANDLE
return 0;

#else
Expand Down