Mega Code Archive

 
Categories / Delphi / System
 

Ultimate Windows Detection Routines

Title: Ultimate - Windows Detection Routines Question: The follow up to my earlier submitted windows detection routines, this one detects more and more ... Updated !!!!!!! Answer: type TWindowsType = (winUnknown,win31,win95,win95OSR2,winNT,win98,win98se,winME,win2000,winXP,winXPx64,win2003,win2003R2,winVista,winLonghorn); TWindowsProductType = ( wptWorkstation, wptServer ); TWindowsProductKind = record AsString : String; AsType : TWindowsProductType; end; TWindowsProductVersion = record AsString : String; Major : Integer; Minor : Integer; end; TWindowsTypeEx = record Full : String; Product : String; Kind : TWindowsProductKind; OSKind : TWindowsType; OSVersion : TWindowsProductVersion; OSBuild : Integer; ServicePack : String; ServicePackVersion : TWindowsProductVersion; end; function GetWindowsTypeEx : TWindowsTypeEx; const VER_NT_WORKSTATION : integer = $1; VER_NT_DOMAIN_CONTROLLER : integer = $2; // The system is a domain controller. VER_NT_SERVER : integer = $3; // The system is a server. VER_WORKSTATION_NT : integer = $40000000; SM_SERVERR2 : integer = 89; VER_SUITE_SMALLBUSINESS : integer = 0; // Bit 0 { int 1 } = Microsoft Small Business Server was once installed on the system, // but may have been upgraded to another version of Windows. VER_SUITE_SMALLBUSINESS_RESTRICTED : integer = 5; // Bit 5 { int 32 } = Microsoft Small Business Server is installed with the restrictive client license in force. VER_SUITE_ENTERPRISE : integer = 1; // Bit 1 { int 2 } = Windows Server "Longhorn", Enterprise Edition, // Windows Server 2003, Enterprise Edition, // Windows 2000 Advanced Server, // Windows NT Server 4.0 Enterprise Edition is installed. // Refer to the Remarks section for more information about this bit flag. VER_SUITE_BACKOFFICE : integer = 2; // Bit 2 { int 4 } = Microsoft BackOffice components are installed. VER_SUITE_COMMUNICATIONS : integer = 3; // Bit 3 { int 8 } VER_SUITE_TERMINAL : integer = 4; // Bit 4 { int 16 } = Terminal Services is installed. // Refer to the Remarks section for more information about this bit flag. VER_SUITE_EMBEDDEDNT : integer = 6; // Bit 6 { int 64 } = Windows XP Embedded is installed. VER_SUITE_DATACENTER : integer = 7; // Bit 7 { int 128 } = Windows Server "Longhorn", Datacenter Edition // Windows Server 2003, Datacenter Edition // Windows 2000 Datacenter Server is installed. VER_SUITE_SINGLEUSERTS : integer = 8; // Bit 8 { int 256 } = Terminal server in remote admin mode VER_SUITE_PERSONAL : integer = 9; // Bit 9 { int 512 } = Windows XP Home Edition is installed. VER_SUITE_BLADE : integer = 10; // Bit 10 { int 1024 } = Windows Server 2003, Web Edition is installed. VER_SUITE_COMPUTE_SERVER : integer = 14; // Bit 14 { int 16384 } = Windows Server 2003, Compute Cluster Edition is installed. VER_SUITE_STORAGE_SERVER : integer = 13; // Bit 13 { int 8192 } = Windows Storage Server 2003 R2 is installed. PROCESSOR_ARCHITECTURE_AMD64 : integer = 9; // x64 (AMD or Intel) PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 : integer = 10; // WOW64 PROCESSOR_ARCHITECTURE_IA64 : integer = 6; // Intel Itanium Processor Family (IPF) PROCESSOR_ARCHITECTURE_INTEL : integer = 0; // x86 PROCESSOR_ARCHITECTURE_UNKNOWN : integer = $ffff; type OSVERSIONINFOEX = packed record dwOSVersionInfoSize: DWORD; dwMajorVersion: DWORD; dwMinorVersion: DWORD; dwBuildNumber: DWORD; dwPlatformId: DWORD; szCSDVersion: Array [0..127 ] of Char; wServicePackMajor: WORD; wServicePackMinor: WORD; wSuiteMask: WORD; wProductType: BYTE; wReserved: BYTE; End; TOSVersionInfoEx = OSVERSIONINFOEX; POSVersionInfoEx = ^TOSVersionInfoEx; PSystemInfo = ^System_Info; TSIProc = procedure( SI : PSystemInfo ); stdcall; PSIProc = TSIProc; var OSVI : TOSVersionInfoEx; OS : TOSVersionInfo; IsOSVIEx : boolean; SI : SYSTEM_INFO; pSI : PSIProc; pVer : POSVersionInfo; // old version! r : TRegistry; ts : string; begin // Try calling GetVersionEx using the OSVERSIONINFOEX structure. // If that fails, try using the OSVERSIONINFO structure. ZeroMemory(@OSVI,SizeOf(OSVI)); osvi.dwOSVersionInfoSize := sizeof(OSVI); pVer := @OSVI; IsOSVIEx := GetVersionEx ( pVer^ ); if not IsOSVIEx then begin osvi.dwOSVersionInfoSize := sizeof(OS); if not GetVersionEx ( pVer^ ) then exit; end; Result.OSVersion.AsString := format('%d.%d',[OSVI.dwMajorVersion,OSVI.dwMinorVersion]); Result.OSVersion.Major := OSVI.dwMajorVersion; Result.OSVersion.Minor := OSVI.dwMinorVersion; Result.ServicePackVersion.AsString := format('%d.%d',[OSVI.wServicePackMajor,OSVI.wServicePackMinor]); Result.ServicePackVersion.Major := OSVI.wServicePackMajor; Result.ServicePackVersion.Minor := OSVI.wServicePackMinor; Result.Server := False; Result.OSBuild := OSVI.dwBuildNumber; case OSVI.dwPlatformId of // Test for the Windows NT product family. VER_PLATFORM_WIN32_NT: begin // Test for the specific product family. if ( osvi.dwMajorVersion = 6 ) and ( osvi.dwMinorVersion = 0 ) then begin if( osvi.wProductType = VER_NT_WORKSTATION ) then begin Result.Product := 'Microsoft Windows Vista'; Result.OSKind := winVista; end else begin Result.Product := 'Microsoft Windows Server Longhorn'; Result.OSKind := winLonghorn; end; end; if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 2 ) then begin // Use GetProcAddress to avoid load issues on Windows 2000 pSI := GetProcAddress( GetModuleHandle('kernel32.dll'), 'GetNativeSystemInfo'); try pSI(@SI); except end; if ( GetSystemMetrics( SM_SERVERR2 ) 0 ) then begin Result.Product := 'Microsoft Windows Server 2003 R2'; Result.OSKind := win2003R2; end else if ( osvi.wProductType = VER_NT_WORKSTATION ) and ( SI.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64 ) then begin Result.Product := 'Microsoft Windows XP Professional x64 Edition'; Result.OSKind := winXPx64; end else begin Result.Product := 'Microsoft Windows Server 2003 family'; Result.OSKind := win2003; end; end; if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 1 ) then begin Result.Product := 'Microsoft Windows XP'; Result.OSKind := winXP; end; if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 0 ) then begin Result.Product := 'Microsoft Windows 2000'; Result.OSKind := win2000; end; if ( osvi.dwMajorVersion begin Result.Product := 'Microsoft Windows NT'; Result.OSKind := winNT; end; // Test for specific product on Windows NT 4.0 SP6 and later. if( IsOSVIEx ) then begin if ( osvi.wProductType = VER_NT_WORKSTATION ) and ( si.wProcessorArchitecture PROCESSOR_ARCHITECTURE_AMD64) then begin Result.Kind.AsType := wptWorkstation; if( osvi.dwMajorVersion = 4 ) then Result.Kind.AsString := 'Workstation 4.0' else if IsBitSet(osvi.wSuiteMask, VER_SUITE_PERSONAL ) then Result.Kind.AsString := 'Home Edition' else Result.Kind.AsString := 'Professional'; end // Test for the server type. else if ( osvi.wProductType = VER_NT_SERVER ) or ( osvi.wProductType = VER_NT_DOMAIN_CONTROLLER ) then begin Result.Server := True; Result.Kind.AsType := wptServer; // 2003 Server family if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 2 ) then begin if ( si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64 ) then begin if IsBitSet(osvi.wSuiteMask, VER_SUITE_DATACENTER ) then Result.Kind.AsString := 'Datacenter Edition for Itanium-based Systems' else if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then Result.Kind.AsString := 'Enterprise Edition for Itanium-based Systems'; end else if ( si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64 ) then begin if IsBitSet(osvi.wSuiteMask, VER_SUITE_DATACENTER ) then Result.Kind.AsString := 'Datacenter x64 Edition' else if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then Result.Kind.AsString := 'Enterprise x64 Edition' else Result.Kind.AsString := 'Standard x64 Edition' end else begin if IsBitSet(osvi.wSuiteMask, VER_SUITE_DATACENTER ) then Result.Kind.AsString := 'Datacenter Edition' else if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then Result.Kind.AsString := 'Enterprise Edition' else if IsBitSet(osvi.wSuiteMask, VER_SUITE_BLADE ) then Result.Kind.AsString := 'Web Edition' else if IsBitSet(osvi.wSuiteMask, VER_SUITE_SMALLBUSINESS ) then Result.Kind.AsString := 'Small Business Server' else if IsBitSet(osvi.wSuiteMask, VER_SUITE_SMALLBUSINESS_RESTRICTED ) then Result.Kind.AsString := 'Small Business Server ( Restricted )' else Result.Kind.AsString := 'Standard Edition' end; end // 2000 Server family else if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 0 ) then begin Result.Product := 'Microsoft Windows Server 2000 family'; if IsBitSet(osvi.wSuiteMask, VER_SUITE_DATACENTER ) then Result.Kind.AsString := 'Datacenter Server' else if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then Result.Kind.AsString := 'Advanced Server' else Result.Kind.AsString := 'Server'; end // Windows NT 4.0 else begin if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then Result.Kind.AsString := 'Server 4.0 Enterprise Edition' else Result.Kind.AsString := 'Server 4.0'; end; end; end // Test for specific product on Windows NT 4.0 SP5 and earlier else begin r := TRegistry.Create; r.RootKey := HKEY_LOCAL_MACHINE; r.OpenKey('SYSTEM\CurrentControlSet\Control\ProductOptions',False); ts := AnsiUpperCase(R.ReadString('ProductType')); r.Free; if ansisametext(ts,'WINNT') then begin Result.Kind.AsString := 'Workstation'; end else if ansisametext(ts,'LANMANNT') then begin Result.Kind.AsString := 'Server'; end else if ansisametext(ts,'SERVERNT') then begin Result.Kind.AsString := 'Advanced Server'; end; Result.Kind.AsString := Result.Kind.AsString + format(' %d.%d ',[osvi.dwMajorVersion, osvi.dwMinorVersion] ); end; // Display service pack (if any) and build number. if ( osvi.dwMajorVersion = 4 ) and ansisametext( osvi.szCSDVersion, 'Service Pack 6' ) then begin r := TRegistry.Create; r.RootKey := HKEY_LOCAL_MACHINE; // Test for SP6 versus SP6a. if r.OpenKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Hotfix\Q246009',False) then Result.ServicePack := format('Service Pack 6a (Build %d) ' + #13#10, [osvi.dwBuildNumber and $FFFF]) else Result.ServicePack := format('%s (Build %d) ' + #13#10, [osvi.szCSDVersion, osvi.dwBuildNumber and $FFFF]); r.Free; end // Windows NT 3.51 and earlier or Windows 2000 and later else Result.ServicePack := format('%s (Build %d) ' + #13#10, [osvi.szCSDVersion, osvi.dwBuildNumber and $FFFF]); Result.Full := format('%s %s',[Result.Product,Result.Kind.AsString]); end; // Test for the Windows 95 product family. VER_PLATFORM_WIN32_WINDOWS : begin Result.Kind.AsType := wptWorkstation; Result.ServicePack := osvi.szCSDVersion; if (osvi.dwMajorVersion = 4 ) and ( osvi.dwMinorVersion = 0 ) then begin Result.Product := 'Microsoft Windows 95'; Result.OSKind := win95; if ( osvi.szCSDVersion[1] = 'C' ) or ( osvi.szCSDVersion[1] = 'B' ) then begin Result.Kind.AsString := 'OSR2'; Result.OSKind := win95OSR2; end; Result.Full := format('%s %s',[Result.Product,Result.Kind.AsString]); end; if (osvi.dwMajorVersion = 4 ) and ( osvi.dwMinorVersion = 10 ) then begin Result.Product := 'Microsoft Windows 98'; Result.OSKind := win98; if ( osvi.szCSDVersion[1] = 'A' ) then begin Result.Kind.AsString := 'SE'; Result.OSKind := win98se; end; Result.Full := format('%s %s',[Result.Product,Result.Kind.AsString]); end; if (osvi.dwMajorVersion = 4 ) and ( osvi.dwMinorVersion = 90) then begin Result.Product := 'Microsoft Windows Millennium Edition'; Result.Full := format('%s',[Result.Product]); Result.OSKind := winME; end; end; VER_PLATFORM_WIN32s: begin Result.Product := 'Microsoft Win32s'; Result.Kind.AsType := wptWorkstation; Result.Full := format('%s',[Result.Product]); Result.OSKind := win31; end; end; Result.ServicePack := Trim(Result.ServicePack); end;