Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
remove windows 7 special handling
  • Loading branch information
maxbachmann authored Feb 28, 2023
commit b93dc7ae7fd98bce87118e7374ccf3646c124286
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
47 changes: 7 additions & 40 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 @@ -5336,7 +5331,8 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,

Py_BEGIN_ALLOW_THREADS
fd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO, &info, 0, WSA_FLAG_OVERLAPPED);
FROM_PROTOCOL_INFO, &info, 0,
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
Py_END_ALLOW_THREADS
if (fd == INVALID_SOCKET) {
set_error();
Expand Down Expand Up @@ -5438,33 +5434,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 @@ -6175,15 +6153,10 @@ socket_dup(PyObject *self, PyObject *fdobj)

newfd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
&info, 0, WSA_FLAG_OVERLAPPED);
&info, 0,
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if (newfd == INVALID_SOCKET)
return set_error();

if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) {
closesocket(newfd);
PyErr_SetFromWindowsErr(0);
return NULL;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eryksun are you sure this is the correct change? This seems to break the tests.

Copy link
Contributor

@eryksun eryksun Feb 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. I forgot that the WSASocketW() call in this case isn't responsible for duplicating the handle into the current process. It's implemented the other way around. The API can't assume that the process that calls WSASocketW() is allowed to duplicate a handle from the process that calls WSADuplicateSocketW(). Instead the value of the already duplicated handle is passed in the WSAPROTOCOL_INFOW record. This handle is inheritable, so calling SetHandleInformation() is required in this case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling SetHandleInformation() is thus also required in sock_initobj_impl() for the case where a socket is created with FROM_PROTOCOL_INFO. I'd do the SetHandleInformation() call locally right after calling WSASocketW(), and add a comment that explains why WSA_FLAG_NO_HANDLE_INHERIT doesn't work.

The other WSASocketW() call in sock_initobj_impl() doesn't need SetHandleInformation(). Keeping it separate and adding a comment makes it less likely that we'll mistakenly go down this path again.

#else
/* On UNIX, dup can be used to duplicate the file descriptor of a socket */
newfd = _Py_dup(fd);
Expand Down Expand Up @@ -7340,12 +7313,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
Loading