Recent

Author Topic: How to determine Windows version 11? (RtlGetNtVersionNumbers returns Windows 10)  (Read 3677 times)

dculp

  • Full Member
  • ***
  • Posts: 151
I'm trying to determine the Windows version on my Windows 11 computer. I use the following code from BobDog (https://forum.lazarus.freepascal.org/index.php/topic,60982.15.html - page 2, reply 18). However, although my computer is Win11, RtlGetNtVersionNumbers returns -
Major version 10
Minor version 0
build number 26100

Thanks.

Lazarus 3.8 (rev lazarus_3_8) FPC 3.2.2 i386-win32-win32/win64

Code: Pascal  [Select][+][-]
  1. program Windows_version_100a;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. procedure RtlGetNtVersionNumbers(major:pointer;minor:pointer;build:pointer)cdecl external 'ntdll.dll' name 'RtlGetNtVersionNumbers';
  6.  
  7. procedure getversion(var maj,min,bld:dword);
  8. begin
  9. RtlGetNtVersionNumbers(@maj,@min,@bld);
  10. bld:=lo(bld);
  11. end;
  12.  
  13. var
  14. maj,min,bld:dword;
  15. begin
  16. maj:=0;min:=0;bld:=0;
  17. getversion(maj,min,bld);
  18. writeln('Major version ',maj);
  19. writeln('Minor version ',min);
  20. writeln('build number ',bld);
  21. writeln('press return to end . . .');
  22. readln;
  23. end.                
  24.  
« Last Edit: April 06, 2025, 03:58:05 pm by dculp »

TRon

  • Hero Member
  • *****
  • Posts: 4377
Today is tomorrow's yesterday.

dculp

  • Full Member
  • ***
  • Posts: 151
@TRon - Your link gives a list of the Windows versions. I need the Pascal code (or code that I can modify to Pascal) that will return the Windows 11 version (rather than returning Win10 when I'm actually running Win11).

TRon

  • Hero Member
  • *****
  • Posts: 4377
Code: Pascal  [Select][+][-]
  1. if bld >= 22000 then writeln('windows 11');
  2.  
Today is tomorrow's yesterday.

AlexTP

  • Hero Member
  • *****
  • Posts: 2574
    • UVviewsoft
I just added some info to the wiki, https://wiki.freepascal.org/Windows_version .

440bx

  • Hero Member
  • *****
  • Posts: 5478
It used to be that RtlGetNtVersionNumbers returned the true Windows version but, no longer :(

Somewhere along Win 10, the implementation changed and now the function returns values that are stored "somewhere" (likely the PEB), telling the calling program the version is whatever Windows wants the program to think it is.

I don't run Windows 11 (and never will) but, if I were running it and needed some way of finding out the version number, I'd check the product version of csrss.exe, that exe is a critical component of Windows and usually accurate information about Windows can be had by "inspecting" that file.

Try this, use Explorer to go to system32, find csrss.exe, right click on it and select properties.  The properties window has a "version" tab.  Look in that tab.  If the product version says "10.xx.xx" then, it's quite likely cumbersome and possibly difficult to tell Win11 from Win10 (but, there is probably a way, fortunately, I don't have to find out and, won't have to find out either :) )

HTH.
 
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

dculp

  • Full Member
  • ***
  • Posts: 151
@AlexTP - I tried the code from your link but I get numerous compiler errors linked the closing "end." statement. It seems to think this is a Windows program but I want to run it as a console. (I've added LCL package as a required package for Win32Proc.) It makes no difference whether WindowsVersionName is actually called (can comment out).

Code: Pascal  [Select][+][-]
  1. program windows_version_200a;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses    Win32Proc;
  6.  
  7. var VersionName: string;
  8.  
  9. function WindowsVersionName: string;
  10. begin
  11.   Result:= '?';
  12.  
  13.   case WindowsVersion of
  14.     wv95:     Result:= 'Windows 95';
  15.     wvNT4:    Result:= 'Windows NT v.4';
  16.     wv98:     Result:= 'Windows 98';
  17.     wvMe:     Result:= 'Windows Me';
  18.     wv2000:   Result:= 'Windows 2000';
  19.     wvXP:     Result:= 'Windows XP';
  20.     wvServer2003: Result:= 'Windows Server 2003';
  21.     wvVista:  Result:= 'Windows Vista';
  22.     wv7:      Result:= 'Windows 7';
  23.     wv8:      Result:= 'Windows 8';
  24.     wv8_1:    Result:= 'Windows 8.1';
  25.     wv10:     Result:= 'Windows 10';
  26.     wv11:     Result:= 'Windows 11';
  27.     //etc.
  28.     //see possible values in the unit "win32proc" in "lcl/interfaces/win32/win32proc.pp"
  29.   end;
  30. end;
  31.  
  32. begin
  33.   VersionName:= WindowsVersionName;
  34. end.                          
  35.  


« Last Edit: April 06, 2025, 07:24:17 pm by dculp »

dculp

  • Full Member
  • ***
  • Posts: 151
@440bx - There is no csrss.exe in my Windows\System32 folder. It is only in the following folder (doesn't look promising) and the Properties doesn't have a Version tab.
C:\Windows\WinSxS\amd64_microsoft-windows-csrss_31bf3856ad364e35_10.0.26100.1_none_55d78c384ca248d1\

440bx

  • Hero Member
  • *****
  • Posts: 5478
@dculp

if not under system32 then maybe syswow64.  There should definitely be a copy of csrss.exe somewhere in a Windows subdirectory. 

I am amazed that csrss.exe would not have version information.  That would be quite a departure.

Would you please check again for a copy of csrss.exe in some Windows subdirectory ? and then try getting the version from that file.

Just in case, if you use Process Hacker, System Informer or Process Explorer, you can find the running copy of csrss.exe and get information about it by right clicking on it and selecting properties.  In the worst case, check out the "Strings" tab, one of the listed strings should reveal the csrss.exe version.

The Windows little system utilities often fall very short of providing relevant information, that's why I don't even mention them.

HTH.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

dculp

  • Full Member
  • ***
  • Posts: 151
@440bx -
I searched my entire C: drive for csrss*. (I use FreeCommander with "Show hidden files".) Only 2 files were found -
csrss.exe.mui in C:\Windows\WinSxS\amd64_microsoft-windows-csrss.resources_31bf3856ad364e35_10.0.26100.1_en-us_d784b37749fd398a\
csrss.exe in C:\Windows\WinSxS\amd64_microsoft-windows-csrss_31bf3856ad364e35_10.0.26100.1_none_55d78c384ca248d1\

In the Properties\Details tab for the latter file, the version is 10.0.26100.1, date modified 4/1/2024. Per my original post, 26100 is the build number returned by RtlGetNtVersionNumbers; however, RtlGetNtVersionNumbers also indicates that the Major Version is 10.

« Last Edit: April 06, 2025, 11:37:50 pm by dculp »

440bx

  • Hero Member
  • *****
  • Posts: 5478
@dculp,

Thank you for checking.

I have to say, I am very surprised that no csrss.exe is found in a subdirectory of Windows. 

Another question for you: when you ask for system information from the Control Panel, does it say you're running Win 10 or Win 11 ?   

The reason I ask is because if it says Win 11, a disassembly of the .cpl file might show where it's getting that value from.  Who knows, maybe it checks that the build number is greater than some value and if it is, it shows Win 11.  I wouldn't put it past MS to do something like that.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

dculp

  • Full Member
  • ***
  • Posts: 151
Actually csrss.exe was found in Windows subdirectory WinSxS\amd64_microsoft-windows-csrss_31bf3856ad364e35_10.0.26100.1_none_55d78c384ca248d1\
Note that the subdirectory name contains the Windows version number 10.0.26100.1.

My Win11 System Information shows -
   OS Name   Microsoft Windows 11 Pro
   Version      10.0.26100 Build 26100

440bx

  • Hero Member
  • *****
  • Posts: 5478
Actually csrss.exe was found in Windows subdirectory WinSxS\amd64_microsoft-windows-csrss_31bf3856ad364e35_10.0.26100.1_none_55d78c384ca248d1\
Note that the subdirectory name contains the Windows version number 10.0.26100.1.
I expected a copy in Windows\system32 because that's where it resides in the original installation.  Strange that it isn't there.

My Win11 System Information shows -
   OS Name   Microsoft Windows 11 Pro
   Version      10.0.26100 Build 26100
That makes sense.  The "OS Name" is _not_ the same thing as the OS Version.  Notice that the OS Version still says 10.  The OS Name is probably in the registry.

Maybe regedit can find a string "Microsoft Windows 11 Pro" somewhere in there. Might be worth a try.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

Khrys

  • Full Member
  • ***
  • Posts: 243
I've been successfully using the following function to check for specific build numbers. Not exactly what you asked for, but maybe it helps:

Code: Pascal  [Select][+][-]
  1. {$push}{$packrecords C}
  2.  
  3. function VerSetConditionMask(ConditionMask: ULONGLONG; TypeMask: DWORD; Condition: BYTE): ULONGLONG; stdcall;
  4.          external kernel32 name 'VerSetConditionMask';
  5. function VerifyVersionInfo(lpVersionInformation: LPVOID; dwTypeMask: DWORD; dwlConditionMask: DWORDLONG): BOOL; stdcall;
  6.          external kernel32 name 'VerifyVersionInfoA';
  7.  
  8. /// Returns True if the build number of the currently running Windows version is greater than or equal to [BuildNumber].
  9. function WindowsBuildNewerThan(BuildNumber: DWORD): Boolean;
  10. const
  11.   VER_BUILDNUMBER = $00000004;
  12.   VER_GREATER_EQUAL = $03;
  13. type
  14.   OSVERSIONINFOEX = record
  15.     dwOSVersionInfoSize, dwMajorVersion, dwMinorVersion: DWORD;
  16.     dwBuildNumber, dwPlatformId: DWORD;
  17.     szCSDVersion: array[0..127] of CHAR;
  18.     wServicePackMajor, wServicePackMinor: WORD;
  19.     wSuiteMask: WORD;
  20.     wProductType: BYTE;
  21.     wReserved: BYTE;
  22.   end;
  23. var
  24.   Version: OSVERSIONINFOEX;
  25. begin
  26.   Version := Default(OSVERSIONINFOEX);
  27.   Version.dwOSVersionInfoSize := SizeOf(Version);
  28.   Version.dwBuildNumber := BuildNumber;
  29.   Result := VerifyVersionInfo(@Version, VER_BUILDNUMBER, // Make sure the .exe has a manifest (i.e. at .rsrc/MANIFEST/1)
  30.                               VerSetConditionMask(0, VER_BUILDNUMBER, VER_GREATER_EQUAL));
  31. end;
  32.  
  33. {$pop}

Zvoni

  • Hero Member
  • *****
  • Posts: 2982
Errr..... Look it up in the Registry?
Code: [Select]
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

 

TinyPortal © 2005-2018