@@ -1645,50 +1645,40 @@ static PyStructSequence_Desc windows_version_desc = {
16451645 via indexing, the rest are name only */
16461646};
16471647
1648- static PyObject *
1649- _sys_getwindowsversion_from_kernel32 (void )
1648+ static PyObject *
1649+ _sys_getwindowsversion_from_RtlGetVersion (void )
16501650{
1651- #ifndef MS_WINDOWS_DESKTOP
1652- PyErr_SetString (PyExc_OSError , "cannot read version info on this platform" );
1653- return NULL ;
1654- #else
1655- HANDLE hKernel32 ;
1656- wchar_t kernel32_path [MAX_PATH ];
1657- LPVOID verblock ;
1658- DWORD verblock_size ;
1659- VS_FIXEDFILEINFO * ffi ;
1660- UINT ffi_len ;
1661- DWORD realMajor , realMinor , realBuild ;
1651+ HMODULE hMod ;
1652+ typedef LONG NTSTATUS , * PNTSTATUS ;
1653+ typedef NTSTATUS (WINAPI * RtlGetVersionPtr )(PRTL_OSVERSIONINFOW );
1654+ RtlGetVersionPtr RtlGetVer ;
1655+
1656+ RTL_OSVERSIONINFOW osVerInfo ;
1657+ ZeroMemory (& osVerInfo , sizeof (osVerInfo ));
1658+ osVerInfo .dwOSVersionInfoSize = sizeof (osVerInfo );
16621659
16631660 Py_BEGIN_ALLOW_THREADS
1664- hKernel32 = GetModuleHandleW (L"kernel32 .dll" );
1661+ hMod = GetModuleHandleW (L"ntdll .dll" );
16651662 Py_END_ALLOW_THREADS
1666- if (!hKernel32 || ! GetModuleFileNameW ( hKernel32 , kernel32_path , MAX_PATH ) ) {
1663+ if (!hMod ) {
16671664 PyErr_SetFromWindowsErr (0 );
16681665 return NULL ;
16691666 }
1670- verblock_size = GetFileVersionInfoSizeW (kernel32_path , NULL );
1671- if (!verblock_size ) {
1667+
1668+ Py_BEGIN_ALLOW_THREADS
1669+ RtlGetVer = (RtlGetVersionPtr )GetProcAddress (hMod , "RtlGetVersion" );
1670+ Py_END_ALLOW_THREADS
1671+ if (!RtlGetVer ) {
16721672 PyErr_SetFromWindowsErr (0 );
16731673 return NULL ;
16741674 }
1675- verblock = PyMem_RawMalloc (verblock_size );
1676- if (!verblock ||
1677- !GetFileVersionInfoW (kernel32_path , 0 , verblock_size , verblock ) ||
1678- !VerQueryValueW (verblock , L"" , (LPVOID )& ffi , & ffi_len )) {
1675+
1676+ if (0 != RtlGetVer (& osVerInfo )) {
16791677 PyErr_SetFromWindowsErr (0 );
1680- if (verblock ) {
1681- PyMem_RawFree (verblock );
1682- }
16831678 return NULL ;
16841679 }
16851680
1686- realMajor = HIWORD (ffi -> dwProductVersionMS );
1687- realMinor = LOWORD (ffi -> dwProductVersionMS );
1688- realBuild = HIWORD (ffi -> dwProductVersionLS );
1689- PyMem_RawFree (verblock );
1690- return Py_BuildValue ("(kkk)" , realMajor , realMinor , realBuild );
1691- #endif /* !MS_WINDOWS_DESKTOP */
1681+ return Py_BuildValue ("(kkk)" , osVerInfo .dwMajorVersion , osVerInfo .dwMinorVersion , osVerInfo .dwBuildNumber );
16921682}
16931683
16941684/* Disable deprecation warnings about GetVersionEx as the result is
@@ -1719,7 +1709,6 @@ sys_getwindowsversion_impl(PyObject *module)
17191709{
17201710 PyObject * version ;
17211711 int pos = 0 ;
1722- OSVERSIONINFOEXW ver ;
17231712
17241713 if (PyObject_GetOptionalAttrString (module , "_cached_windows_version" , & version ) < 0 ) {
17251714 return NULL ;
@@ -1729,6 +1718,8 @@ sys_getwindowsversion_impl(PyObject *module)
17291718 }
17301719 Py_XDECREF (version );
17311720
1721+ OSVERSIONINFOEXW ver ;
1722+ ZeroMemory (& ver , sizeof (ver ));
17321723 ver .dwOSVersionInfoSize = sizeof (ver );
17331724 if (!GetVersionExW ((OSVERSIONINFOW * ) & ver ))
17341725 return PyErr_SetFromWindowsErr (0 );
@@ -1756,11 +1747,13 @@ sys_getwindowsversion_impl(PyObject *module)
17561747 SET_VERSION_INFO (PyLong_FromLong (ver .wSuiteMask ));
17571748 SET_VERSION_INFO (PyLong_FromLong (ver .wProductType ));
17581749
1750+ #ifdef MS_WINDOWS_DESKTOP
17591751 // GetVersion will lie if we are running in a compatibility mode.
1760- // We need to read the version info from a system file resource
1752+ // We need to read the version info from kernel with RtlGetVersion
17611753 // to accurately identify the OS version. If we fail for any reason,
17621754 // just return whatever GetVersion said.
1763- PyObject * realVersion = _sys_getwindowsversion_from_kernel32 ();
1755+ // UWP return correct version from GetVersionExW, this is not necessary.
1756+ PyObject * realVersion = _sys_getwindowsversion_from_RtlGetVersion ();
17641757 if (!realVersion ) {
17651758 if (!PyErr_ExceptionMatches (PyExc_WindowsError )) {
17661759 goto error ;
@@ -1775,6 +1768,7 @@ sys_getwindowsversion_impl(PyObject *module)
17751768 }
17761769
17771770 SET_VERSION_INFO (realVersion );
1771+ #endif
17781772
17791773#undef SET_VERSION_INFO
17801774
0 commit comments