@@ -51,6 +51,7 @@ Data members:
5151# ifndef WIN32_LEAN_AND_MEAN
5252# define WIN32_LEAN_AND_MEAN
5353# endif
54+ # define REG_CURRENT_VERSION L"Software\\Microsoft\\Windows NT\\CurrentVersion"
5455# include <windows.h>
5556#endif /* MS_WINDOWS */
5657
@@ -1645,13 +1646,10 @@ static PyStructSequence_Desc windows_version_desc = {
16451646 via indexing, the rest are name only */
16461647};
16471648
1649+ #ifdef MS_WINDOWS_DESKTOP
16481650static PyObject *
16491651_sys_getwindowsversion_from_kernel32 (void )
16501652{
1651- #ifndef MS_WINDOWS_DESKTOP
1652- PyErr_SetString (PyExc_OSError , "cannot read version info on this platform" );
1653- return NULL ;
1654- #else
16551653 HANDLE hKernel32 ;
16561654 wchar_t kernel32_path [MAX_PATH ];
16571655 LPVOID verblock ;
@@ -1687,9 +1685,21 @@ _sys_getwindowsversion_from_kernel32(void)
16871685 realMinor = LOWORD (ffi -> dwProductVersionMS );
16881686 realBuild = HIWORD (ffi -> dwProductVersionLS );
16891687 PyMem_RawFree (verblock );
1688+
1689+ // Obtain the build number from Windows registry in case of Windows 10/11
1690+ if (realMajor == 10 && realMinor == 0 ) {
1691+ wchar_t currentBuild [32 ] = {0 };
1692+ DWORD len = sizeof (currentBuild );
1693+ if (ERROR_SUCCESS == RegGetValueW (HKEY_LOCAL_MACHINE , REG_CURRENT_VERSION , L"CurrentBuild" ,
1694+ RRF_RT_REG_SZ , NULL , & currentBuild , & len ))
1695+ {
1696+ realBuild = _wtol (currentBuild );
1697+ }
1698+ }
1699+
16901700 return Py_BuildValue ("(kkk)" , realMajor , realMinor , realBuild );
1691- #endif /* !MS_WINDOWS_DESKTOP */
16921701}
1702+ #endif /* MS_WINDOWS_DESKTOP */
16931703
16941704/* Disable deprecation warnings about GetVersionEx as the result is
16951705 being passed straight through to the caller, who is responsible for
@@ -1719,7 +1729,6 @@ sys_getwindowsversion_impl(PyObject *module)
17191729{
17201730 PyObject * version ;
17211731 int pos = 0 ;
1722- OSVERSIONINFOEXW ver ;
17231732
17241733 if (PyObject_GetOptionalAttrString (module , "_cached_windows_version" , & version ) < 0 ) {
17251734 return NULL ;
@@ -1729,6 +1738,8 @@ sys_getwindowsversion_impl(PyObject *module)
17291738 }
17301739 Py_XDECREF (version );
17311740
1741+ OSVERSIONINFOEXW ver ;
1742+ ZeroMemory (& ver , sizeof (ver ));
17321743 ver .dwOSVersionInfoSize = sizeof (ver );
17331744 if (!GetVersionExW ((OSVERSIONINFOW * ) & ver ))
17341745 return PyErr_SetFromWindowsErr (0 );
@@ -1756,10 +1767,12 @@ sys_getwindowsversion_impl(PyObject *module)
17561767 SET_VERSION_INFO (PyLong_FromLong (ver .wSuiteMask ));
17571768 SET_VERSION_INFO (PyLong_FromLong (ver .wProductType ));
17581769
1770+ #ifdef MS_WINDOWS_DESKTOP
17591771 // GetVersion will lie if we are running in a compatibility mode.
17601772 // We need to read the version info from a system file resource
17611773 // to accurately identify the OS version. If we fail for any reason,
17621774 // just return whatever GetVersion said.
1775+ // UWP return correct version from GetVersionExW, this is not necessary.
17631776 PyObject * realVersion = _sys_getwindowsversion_from_kernel32 ();
17641777 if (!realVersion ) {
17651778 if (!PyErr_ExceptionMatches (PyExc_WindowsError )) {
@@ -1775,6 +1788,7 @@ sys_getwindowsversion_impl(PyObject *module)
17751788 }
17761789
17771790 SET_VERSION_INFO (realVersion );
1791+ #endif
17781792
17791793#undef SET_VERSION_INFO
17801794
0 commit comments