From bbf56b46d68a6b5983e60e7efc3d8d62e577645e Mon Sep 17 00:00:00 2001 From: thexai <58434170+thexai@users.noreply.github.com> Date: Sat, 27 Jun 2026 12:20:21 +0200 Subject: [PATCH] gh-152433: Windows: Use GetFileSizeEx instead of GetFileSize GetFileSizeEx is available in all supported Windows versions and has the advantage is also present in UWP, then allows build also in UWP with the same common code. It also simplifies error checking and makes handling files larger than 4GB easier. --- ...-06-28-13-03-57.gh-issue-152433.jUXFwC.rst | 1 + Modules/mmapmodule.c | 30 ++++++------------- 2 files changed, 10 insertions(+), 21 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2026-06-28-13-03-57.gh-issue-152433.jUXFwC.rst diff --git a/Misc/NEWS.d/next/Windows/2026-06-28-13-03-57.gh-issue-152433.jUXFwC.rst b/Misc/NEWS.d/next/Windows/2026-06-28-13-03-57.gh-issue-152433.jUXFwC.rst new file mode 100644 index 000000000000000..348bfa4ee9c278c --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2026-06-28-13-03-57.gh-issue-152433.jUXFwC.rst @@ -0,0 +1 @@ +Use the Windows API ``GetFileSizeEx()`` for memory mapped files, rather than the older ``GetFileSize()``. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 6fb04ba7bd47c67..f4f21b45f920a00 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -806,20 +806,12 @@ mmap_mmap_size_impl(mmap_object *self) #ifdef MS_WINDOWS if (self->file_handle != INVALID_HANDLE_VALUE) { - DWORD low,high; - long long size; - low = GetFileSize(self->file_handle, &high); - if (low == INVALID_FILE_SIZE) { - /* It might be that the function appears to have failed, - when indeed its size equals INVALID_FILE_SIZE */ - DWORD error = GetLastError(); - if (error != NO_ERROR) - return PyErr_SetFromWindowsErr(error); + LARGE_INTEGER size; + if (!GetFileSizeEx(self->file_handle, &size)) { + DWORD error = GetLastError(); + return PyErr_SetFromWindowsErr(error); } - if (!high && low < LONG_MAX) - return PyLong_FromLong((long)low); - size = (((long long)high)<<32) + low; - return PyLong_FromLongLong(size); + return PyLong_FromLongLong(size.QuadPart); } #endif /* MS_WINDOWS */ @@ -2127,18 +2119,14 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) m_obj->file_handle = fh; } if (!map_size) { - DWORD low,high; - low = GetFileSize(fh, &high); - /* low might just happen to have the value INVALID_FILE_SIZE; - so we need to check the last error also. */ - if (low == INVALID_FILE_SIZE && - (dwErr = GetLastError()) != NO_ERROR) + LARGE_INTEGER li; + if (!GetFileSizeEx(fh, &li)) { + dwErr = GetLastError(); Py_DECREF(m_obj); return PyErr_SetFromWindowsErr(dwErr); } - - size = (((long long) high) << 32) + low; + size = li.QuadPart; if (size == 0) { PyErr_SetString(PyExc_ValueError, "cannot mmap an empty file");