796 lines
28 KiB
Plaintext
796 lines
28 KiB
Plaintext
//---------------------------------------------------------------------
|
|
// Windows Version Pascal Source
|
|
//
|
|
// Create by: Kang Sin-young (2004.01.25 Last Modify)
|
|
//---------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------
|
|
// GetWindowsVersion Pascal Source
|
|
// From https://github.com/yypbd/yypbd-Delphi-Libs/blob/master/lib/WindowsVersion.pas
|
|
// Create by: Young-pil Yang (2014.05.28 Last Modify)
|
|
//---------------------------------------------------------------------
|
|
|
|
unit EM.WinOSVersion;
|
|
|
|
interface
|
|
|
|
uses
|
|
WinApi.Windows, WinApi.Messages, SysUtils, Variants, StrUtils, System.Win.Registry;
|
|
|
|
type
|
|
TGetProductInfo = function (dwOsMajorVer, dwOSMinorVerion, dwSpMajorVer, dwSpMinorVer : DWORD; pdwReturnProductType : PDWORD):Boolean; stdcall;
|
|
|
|
WKSTA_INFO_100 = record
|
|
wki100_platform_id: DWORD;
|
|
wki100_computername: LPWSTR;
|
|
wki100_langroup: LPWSTR;
|
|
wki100_ver_major: DWORD;
|
|
wki100_ver_minor: DWORD;
|
|
end;
|
|
|
|
LPWKSTA_INFO_100 = ^WKSTA_INFO_100;
|
|
|
|
_USER_INFO_0 = record
|
|
usri0_name: LPWSTR;
|
|
end;
|
|
|
|
|
|
TWinVerSub = record
|
|
Major,
|
|
Minor,
|
|
Build: DWORD;
|
|
end;
|
|
|
|
TWinVerInfo = record
|
|
WinID,
|
|
WinVer,
|
|
WinName,
|
|
ServicePack: String;
|
|
Version: TWinVerSub;
|
|
end;
|
|
|
|
_OSVERSIONINFOEXA = record
|
|
dwOSVersionInfoSize: DWORD;
|
|
dwMajorVersion: DWORD;
|
|
dwMinorVersion: DWORD;
|
|
dwBuildNumber: DWORD;
|
|
dwPlatformId: DWORD;
|
|
szCSDVersion: array[0..127] of AnsiChar; { Maintenance string for PSS usage }
|
|
wServicePackMajor: WORD;
|
|
wServicePackMinor: WORD;
|
|
wSuiteMask: WORD;
|
|
wProductType: BYTE;
|
|
wReserved: BYTE;
|
|
end;
|
|
{$EXTERNALSYM _OSVERSIONINFOEXA}
|
|
_OSVERSIONINFOEXW = record
|
|
dwOSVersionInfoSize: DWORD;
|
|
dwMajorVersion: DWORD;
|
|
dwMinorVersion: DWORD;
|
|
dwBuildNumber: DWORD;
|
|
dwPlatformId: DWORD;
|
|
szCSDVersion: array[0..127] of WideChar; { Maintenance string for PSS usage }
|
|
wServicePackMajor: WORD;
|
|
wServicePackMinor: WORD;
|
|
wSuiteMask: WORD;
|
|
wProductType: BYTE;
|
|
wReserved: BYTE;
|
|
end;
|
|
{$EXTERNALSYM _OSVERSIONINFOEXW}
|
|
OSVERSIONINFOEXA = _OSVERSIONINFOEXA;
|
|
OSVERSIONINFOEXW = _OSVERSIONINFOEXW;
|
|
{$EXTERNALSYM OSVERSIONINFOEXA}
|
|
{$EXTERNALSYM OSVERSIONINFOEXW}
|
|
OSVERSIONINFOEX = OSVERSIONINFOEXA;
|
|
{$EXTERNALSYM OSVERSIONINFOEX}
|
|
TOSVersionInfoExA = OSVERSIONINFOEXA;
|
|
TOSVersionInfoExW = OSVERSIONINFOEXW;
|
|
|
|
const
|
|
NERR_Success = 0;
|
|
SERVICE_MAX_COUNT = 10;
|
|
VER_EQUAL = 1;
|
|
|
|
VER_SERVER_NT = $80000000;
|
|
{$EXTERNALSYM VER_SERVER_NT}
|
|
VER_WORKSTATION_NT = $40000000;
|
|
{$EXTERNALSYM VER_WORKSTATION_NT}
|
|
|
|
VER_SUITE_SMALLBUSINESS = $00000001;
|
|
{$EXTERNALSYM VER_SUITE_SMALLBUSINESS}
|
|
VER_SUITE_ENTERPRISE = $00000002;
|
|
{$EXTERNALSYM VER_SUITE_ENTERPRISE}
|
|
VER_SUITE_BACKOFFICE = $00000004;
|
|
{$EXTERNALSYM VER_SUITE_BACKOFFICE}
|
|
VER_SUITE_COMMUNICATIONS = $00000008;
|
|
{$EXTERNALSYM VER_SUITE_COMMUNICATIONS}
|
|
VER_SUITE_TERMINAL = $00000010;
|
|
{$EXTERNALSYM VER_SUITE_TERMINAL}
|
|
VER_SUITE_SMALLBUSINESS_RESTRICTED = $00000020;
|
|
{$EXTERNALSYM VER_SUITE_SMALLBUSINESS_RESTRICTED}
|
|
VER_SUITE_EMBEDDEDNT = $00000040;
|
|
{$EXTERNALSYM VER_SUITE_EMBEDDEDNT}
|
|
VER_SUITE_DATACENTER = $00000080;
|
|
{$EXTERNALSYM VER_SUITE_DATACENTER}
|
|
VER_SUITE_SINGLEUSERTS = $00000100;
|
|
{$EXTERNALSYM VER_SUITE_SINGLEUSERTS}
|
|
VER_SUITE_PERSONAL = $00000200;
|
|
{$EXTERNALSYM VER_SUITE_PERSONAL}
|
|
VER_SUITE_BLADE = $00000400;
|
|
{$EXTERNALSYM VER_SUITE_BLADE}
|
|
VER_SUITE_EMBEDDED_RESTRICTED = $00000800;
|
|
{$EXTERNALSYM VER_SUITE_EMBEDDED_RESTRICTED}
|
|
VER_SUITE_SECURITY_APPLIANCE = $00001000;
|
|
{$EXTERNALSYM VER_SUITE_SECURITY_APPLIANCE}
|
|
|
|
VER_NT_WORKSTATION = $0000001;
|
|
{$EXTERNALSYM VER_NT_WORKSTATION}
|
|
VER_NT_DOMAIN_CONTROLLER = $0000002;
|
|
{$EXTERNALSYM VER_NT_DOMAIN_CONTROLLER}
|
|
VER_NT_SERVER = $0000003;
|
|
{$EXTERNALSYM VER_NT_SERVER}
|
|
|
|
//GetProductInfo vista 이상에서만 사용
|
|
PRODUCT_BUSINESS = $00000006;
|
|
PRODUCT_BUSINESS_N = $00000010;
|
|
PRODUCT_CLUSTER_SERVER = $00000012;
|
|
PRODUCT_DATACENTER_SERVER = $00000008;
|
|
PRODUCT_DATACENTER_SERVER_CORE = $0000000C;
|
|
PRODUCT_DATACENTER_SERVER_CORE_V = $00000027;
|
|
PRODUCT_DATACENTER_SERVER_V = $00000025;
|
|
PRODUCT_ENTERPRISE = $00000004;
|
|
PRODUCT_ENTERPRISE_E = $00000046;
|
|
PRODUCT_ENTERPRISE_N = $0000001B;
|
|
PRODUCT_ENTERPRISE_SERVER = $0000000A;
|
|
PRODUCT_ENTERPRISE_SERVER_CORE = $0000000E;
|
|
PRODUCT_ENTERPRISE_SERVER_CORE_V = $00000029;
|
|
PRODUCT_ENTERPRISE_SERVER_IA64 = $0000000F;
|
|
PRODUCT_ENTERPRISE_SERVER_V = $00000026;
|
|
PRODUCT_HOME_BASIC = $00000002;
|
|
PRODUCT_HOME_BASIC_E = $00000043;
|
|
PRODUCT_HOME_BASIC_N = $00000005;
|
|
PRODUCT_HOME_PREMIUM = $00000003;
|
|
PRODUCT_ULTIMATE = $00000001;
|
|
PRODUCT_PROFESSIONAL = $00000030;
|
|
PRODUCT_PROFESSIONAL_N = $00000031;
|
|
PRODUCT_STARTER = $0000000B;
|
|
PRODUCT_SMALLBUSINESS_SERVER = $00000009;
|
|
PRODUCT_SMALLBUSINESS_SERVER_PREMIUM = $00000019;
|
|
PRODUCT_STANDARD_SERVER = $00000007;
|
|
PRODUCT_STANDARD_SERVER_CORE = $0000000D;
|
|
PRODUCT_WEB_SERVER = $00000011;
|
|
|
|
var
|
|
MajorCache: DWORD;
|
|
MinorCache: DWORD;
|
|
ServicePackCache: DWORD;
|
|
IsServerCache: Boolean;
|
|
|
|
function NetWkstaGetInfo(ServerName: LPWSTR; Level: DWORD; BufPtr: Pointer)
|
|
: Longint; stdcall; external 'netapi32.dll' Name 'NetWkstaGetInfo';
|
|
function NetApiBufferFree(Buffer: Pointer): Longint; stdcall;
|
|
external 'netapi32.dll' Name 'NetApiBufferFree';
|
|
{$IFDEF UNICODE}
|
|
function VerifyVersionInfo(var LPOSVERSIONINFOEX: OSVERSIONINFOEX;
|
|
dwTypeMask: DWORD; dwlConditionMask: int64): BOOL; stdcall;
|
|
external kernel32 name 'VerifyVersionInfoW';
|
|
{$ELSE}
|
|
function VerifyVersionInfo(var LPOSVERSIONINFOEX: OSVERSIONINFOEX;
|
|
dwTypeMask: DWORD; dwlConditionMask: int64): BOOL; stdcall;
|
|
external kernel32 name 'VerifyVersionInfoA';
|
|
{$ENDIF}
|
|
function VerSetConditionMask(dwlConditionMask: int64; dwTypeBitMask: DWORD;
|
|
dwConditionMask: Byte): int64; stdcall; external kernel32;
|
|
|
|
function GetVersionEx2(var lpVersionInformation: TOSVersionInfoExA): BOOL; stdcall;
|
|
{$EXTERNALSYM GetVersionEx2}
|
|
function GetVersionEx2A(var lpVersionInformation: TOSVersionInfoExA): BOOL; stdcall;
|
|
{$EXTERNALSYM GetVersionEx2A}
|
|
function GetVersionEx2W(var lpVersionInformation: TOSVersionInfoExW): BOOL; stdcall;
|
|
{$EXTERNALSYM GetVersionEx2W}
|
|
|
|
function GetWindowsVersion(var AMajor, AMinor: DWORD): Boolean; overload;
|
|
function GetWindowsVersion(var AMajor, AMinor, AServicePack, ABuildNumber: DWORD;
|
|
var AIsServer: Boolean): Boolean; overload;
|
|
|
|
function GetWinVersion: TWinVerInfo;
|
|
|
|
function ParseWinNT(p: TOSVersionInfoExW; IsEx: Boolean): TWinVerInfo; overload;
|
|
function ParseWinNT(p: TOSVersionInfoExA; IsEx: Boolean): TWinVerInfo; overload;
|
|
function ParseWin9x(p: TOSVersionInfo): TWinVerInfo;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.Classes, Tocsg.Safe, Tocsg.Path, Tocsg.Strings, Tocsg.Registry,
|
|
Tocsg.FileInfo;
|
|
|
|
function GetVersionEx2; external kernel32 name 'GetVersionExA';
|
|
function GetVersionEx2A; external kernel32 name 'GetVersionExA';
|
|
function GetVersionEx2W; external kernel32 name 'GetVersionExW';
|
|
|
|
function GetWinVersion: TWinVerInfo;
|
|
var
|
|
rtnVerEx: TOSVersionInfoExA;
|
|
rtnVer: TOSVersionInfo;
|
|
rtnParse: TWinVerInfo;
|
|
begin
|
|
rtnVer.dwOSVersionInfoSize := sizeof(OSVERSIONINFO); //Get 1st OS Info
|
|
GetVersionEx(rtnVer);
|
|
|
|
if rtnVer.dwPlatformId = VER_PLATFORM_WIN32_NT then
|
|
begin
|
|
if rtnVer.dwMajorVersion < 5 then
|
|
rtnParse := ParseWinNT(rtnVerEx, False)
|
|
else begin
|
|
rtnVerEx.dwOSVersionInfoSize := sizeof(TOSVersionInfoExA); //*WinNT/2000/XP/2003
|
|
GetVersionEx2(rtnVerEx);
|
|
rtnParse := ParseWinNT(rtnVerEx, True);
|
|
end;
|
|
end else
|
|
rtnParse := ParseWin9x(rtnVer);
|
|
|
|
Result := rtnParse;
|
|
end;
|
|
|
|
function ParseWinNT(p: TOSVersionInfoExA; IsEx: Boolean): TWinVerInfo;
|
|
|
|
function IsWin11: Boolean;
|
|
var
|
|
fi: TTgFileInfo;
|
|
StrList: TStringList;
|
|
begin
|
|
Result := false;
|
|
Guard(fi, TTgFileInfo.Create(GetSystemDir + 'kernel32.dll'));
|
|
Guard(StrList, TStringList.Create);
|
|
if SplitString(fi.Version, '.', StrList) > 3 then
|
|
begin
|
|
if StrToIntDef(StrList[2], -1) >= 22000 then
|
|
Result := true;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
rtn: TWinVerInfo;
|
|
|
|
resVer: TRegistry;
|
|
szProduct: String;
|
|
procGetProductInfo : TGetProductInfo;
|
|
hModule : THandle;
|
|
ProdType : DWORD;
|
|
dwMajor, dwMinor, dwService, dwBuildNum : DWORD;
|
|
bIsServer : Boolean;
|
|
begin
|
|
GetWindowsVersion(dwMajor, dwMinor, dwService, dwBuildNum, bIsServer);
|
|
|
|
p.dwMajorVersion := dwMajor;
|
|
p.dwMinorVersion := dwMinor;
|
|
p.dwBuildNumber := dwBuildNum;
|
|
if not bIsServer then
|
|
begin
|
|
p.wProductType := VER_NT_WORKSTATION
|
|
end;
|
|
|
|
// 윈도우 8.0이 추가 되면서 다시 개선함
|
|
rtn.WinVer := 'Unknown';
|
|
|
|
case p.dwMajorVersion of
|
|
5 :
|
|
case p.dwMinorVersion of
|
|
0 : rtn.WinName := '2000';
|
|
1 : rtn.WinName := 'XP';
|
|
2 : rtn.WinName := '2003 Server Family';
|
|
end;
|
|
6 :
|
|
case p.dwMinorVersion of
|
|
0 :
|
|
if p.wProductType = VER_NT_WORKSTATION then
|
|
rtn.WinVer := 'Vista'
|
|
else
|
|
rtn.WinVer := 'Server 2008';
|
|
1 :
|
|
if p.wProductType = VER_NT_WORKSTATION then
|
|
rtn.WinVer := '7'
|
|
else
|
|
rtn.WinVer := 'Server 2008 R2';
|
|
2 : // 윈 8 정보 추가
|
|
if p.wProductType = VER_NT_WORKSTATION then
|
|
rtn.WinVer := '8'
|
|
else
|
|
rtn.WinVer := 'Server 2012';
|
|
3 : // 윈 8 정보 추가
|
|
if p.wProductType = VER_NT_WORKSTATION then
|
|
rtn.WinVer := '8.1'
|
|
else
|
|
rtn.WinVer := 'Server 2012 R2';
|
|
end;
|
|
10 :
|
|
begin
|
|
// 윈도우 10
|
|
rtn.WinVer := '10';
|
|
case p.dwMinorVersion of
|
|
0 : ; // .. 하위 정보 확인 필요
|
|
end;
|
|
|
|
// windows 11의 공식 메이저 버전은 10이다..
|
|
// 11인걸 판단하기 위해 'kernel32.dll'의 빌드번호가 22000 이상인지 확인한다. 22_0517 10:05:21 kku
|
|
if IsWin11 then
|
|
rtn.WinVer := '11';
|
|
end;
|
|
0 :
|
|
begin
|
|
// 안전모드에서는 실패한다. 22_1116 13:11:54 kku
|
|
rtn.WinVer := ExtrNumStr(GetRegValueAsString(HKEY_LOCAL_MACHINE,
|
|
'SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'ProductName'));
|
|
if rtn.WinVer = '10' then
|
|
begin
|
|
if IsWin11 then
|
|
rtn.WinVer := '11';
|
|
end else
|
|
if rtn.WinVer = '' then
|
|
rtn.WinVer := '?';
|
|
end;
|
|
end;
|
|
rtn.WinName := 'Windows ' + rtn.WinVer;
|
|
|
|
//Get Product Substring
|
|
if (IsEX) then begin
|
|
case p.wProductType of
|
|
VER_NT_WORKSTATION:
|
|
begin
|
|
if (p.dwMajorVersion = 4) then
|
|
rtn.WinName := rtn.WinName + ' Workstation 4.0'
|
|
else if (p.wSuiteMask and VER_SUITE_PERSONAL) = VER_SUITE_PERSONAL then
|
|
rtn.WinName := rtn.WinName + ' Home Edition'
|
|
else if p.dwMajorVersion = 6 then
|
|
begin
|
|
// 비스타의 경우.. 버전정보를 모르겠다.. 아직은..
|
|
|
|
|
|
|
|
end
|
|
else
|
|
rtn.WinName := rtn.WinName + ' Professional';
|
|
end;
|
|
VER_NT_SERVER:
|
|
begin
|
|
if ((p.dwMajorVersion = 5) and (p.dwMinorVersion = 2)) then begin
|
|
if (p.wSuiteMask and VER_SUITE_DATACENTER) = VER_SUITE_DATACENTER then
|
|
rtn.WinName := rtn.WinName + ' Datacenter Edition'
|
|
else if (p.wSuiteMask and VER_SUITE_ENTERPRISE) = VER_SUITE_ENTERPRISE then
|
|
rtn.WinName := rtn.WinName + ' Enterprise Edition'
|
|
else if (p.wSuiteMask and VER_SUITE_BLADE) = VER_SUITE_BLADE then
|
|
rtn.WinName := rtn.WinName + ' Web Edition'
|
|
else
|
|
rtn.WinName := rtn.WinName + ' Standard Edition';
|
|
end
|
|
else if ((p.dwMajorVersion = 5) and (p.dwMinorVersion = 0)) then begin
|
|
if (p.wSuiteMask and VER_SUITE_DATACENTER) = VER_SUITE_DATACENTER then
|
|
rtn.WinName := rtn.WinName + ' Datacenter Server'
|
|
else if (p.wSuiteMask and VER_SUITE_ENTERPRISE) = VER_SUITE_ENTERPRISE then
|
|
rtn.WinName := rtn.WinName + ' Advanced Server'
|
|
else
|
|
rtn.WinName := rtn.WinName + ' Server';
|
|
end
|
|
else if (p.dwMajorVersion = 6) then
|
|
|
|
else begin
|
|
if (p.wSuiteMask and VER_SUITE_ENTERPRISE) = VER_SUITE_ENTERPRISE then
|
|
rtn.WinName := rtn.WinName + ' Server 4.0 Enterprise Edition'
|
|
else
|
|
rtn.WinName := rtn.WinName + ' Server 4.0';
|
|
end;
|
|
end;
|
|
end; {case of}
|
|
|
|
if p.dwMajorVersion = 6 then
|
|
begin
|
|
hModule := GetModuleHandle('kernel32.dll');
|
|
procGetProductInfo := GetProcAddress( hModule ,'GetProductInfo');
|
|
if Assigned(procGetProductInfo) then
|
|
begin
|
|
procGetProductInfo(p.dwMajorVersion, p.dwMinorVersion, 0, 0, @ProdType);
|
|
|
|
case ProdType of
|
|
PRODUCT_ULTIMATE : rtn.WinName := rtn.WinName + ' Ultimate';
|
|
PRODUCT_PROFESSIONAL : rtn.WinName := rtn.WinName + ' Professional';
|
|
PRODUCT_HOME_PREMIUM : rtn.WinName := rtn.WinName + ' Home Premium Edition';
|
|
PRODUCT_HOME_BASIC : rtn.WinName := rtn.WinName + ' Home Basic Edition';
|
|
PRODUCT_ENTERPRISE : rtn.WinName := rtn.WinName + ' Enterprise Edition';
|
|
PRODUCT_BUSINESS : rtn.WinName := rtn.WinName + ' Business Edition';
|
|
PRODUCT_STARTER : rtn.WinName := rtn.WinName + ' Starter Edition';
|
|
PRODUCT_CLUSTER_SERVER : rtn.WinName := rtn.WinName + ' Cluster Server Edition';
|
|
PRODUCT_DATACENTER_SERVER : rtn.WinName := rtn.WinName + ' Datacenter Edition';
|
|
PRODUCT_DATACENTER_SERVER_CORE : rtn.WinName := rtn.WinName + ' Datacenter Edition (core installation)';
|
|
PRODUCT_ENTERPRISE_SERVER : rtn.WinName := rtn.WinName + ' Enterprise Edition';
|
|
PRODUCT_ENTERPRISE_SERVER_CORE : rtn.WinName := rtn.WinName + ' Enterprise Edition (core installation)';
|
|
PRODUCT_ENTERPRISE_SERVER_IA64 : rtn.WinName := rtn.WinName + ' Enterprise Edition for Itanium-based Systems)';
|
|
PRODUCT_SMALLBUSINESS_SERVER : rtn.WinName := rtn.WinName + ' Small Business Server';
|
|
PRODUCT_SMALLBUSINESS_SERVER_PREMIUM : rtn.WinName := rtn.WinName + ' Small Business Server Premium Edition';
|
|
PRODUCT_STANDARD_SERVER : rtn.WinName := rtn.WinName + ' Standard Edition';
|
|
PRODUCT_STANDARD_SERVER_CORE : rtn.WinName := rtn.WinName + ' Standard Edition (core installation)';
|
|
PRODUCT_WEB_SERVER : rtn.WinName := rtn.WinName + ' Web Server Edition';
|
|
end;
|
|
|
|
FreeModule(hModule);
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
end {If IsEx}
|
|
else begin
|
|
// Test for specific product on Windows NT 4.0 SP5 and earlier
|
|
resVer := TRegistry.Create(KEY_READ);
|
|
try
|
|
resVer.RootKey := HKEY_LOCAL_MACHINE;
|
|
resver.OpenKeyReadOnly('SYSTEM\\CurrentControlSet\\Control\\ProductOptions');
|
|
|
|
szProduct := resVer.ReadString('ProductType');
|
|
|
|
if (Strcomp('WINNT', PChar(szProduct)) = 0) then
|
|
rtn.WinName := rtn.WinName + ' Workstation '
|
|
else if (Strcomp('LANMANNT', PChar(szProduct)) = 0) then
|
|
rtn.WinName := rtn.WinName + ' Server '
|
|
else if (Strcomp('SERVERNT', PChar(szProduct)) = 0) then
|
|
rtn.WinName := rtn.WinName + ' Advanced Server ';
|
|
|
|
rtn.WinName := rtn.WinName + IntToStr(p.dwMajorVersion) + '.' + IntToStr(p.dwMinorVersion);
|
|
finally
|
|
resVer.Free;
|
|
end;
|
|
end;{else IsEx}
|
|
|
|
//Get Version
|
|
rtn.Version.Major := p.dwMajorVersion;
|
|
rtn.Version.Minor := p.dwMinorVersion;
|
|
rtn.Version.Build := p.dwBuildNumber;
|
|
|
|
//Get Service Pack
|
|
if ((p.dwMajorVersion = 4) and (lstrcmpiA(p.szCSDVersion, 'Service Pack 6' ) = 0)) then begin
|
|
// Test for SP6 versus SP6a.
|
|
resVer := TRegistry.Create(KEY_READ);
|
|
try
|
|
resVer.RootKey := HKEY_LOCAL_MACHINE;
|
|
if resVer.OpenKeyReadOnly('SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009') then
|
|
rtn.ServicePack := 'Service Pack 6a'
|
|
else
|
|
rtn.ServicePack := String(p.szCSDVersion); //warring 제거
|
|
finally
|
|
resVer.Free;
|
|
end;
|
|
end
|
|
else
|
|
//Else Other All Version
|
|
if Boolean(p.wServicePackMajor) or Boolean(p.wServicePackMinor) then begin
|
|
rtn.ServicePack := 'Service Pack ' + intToStr(p.wServicePackMajor);
|
|
if Boolean(p.wServicePackMinor) then
|
|
rtn.ServicePack := rtn.ServicePack + '.' + IntToStr(p.wServicePackMinor);
|
|
end
|
|
else
|
|
rtn.ServicePack := String(p.szCSDVersion);
|
|
|
|
//Create ID String and Return
|
|
rtn.WinID := 'Microsoft ' + rtn.WinName + '(Version ' + IntToStr(rtn.Version.Major) + '.' + IntToStr(rtn.Version.Minor)
|
|
+ ' Build ' + IntToStr(rtn.Version.Build) + ') ' + rtn.ServicePack;
|
|
|
|
Result := rtn;
|
|
end;
|
|
|
|
function ParseWinNT(p: TOSVersionInfoExW; IsEx: Boolean): TWinVerInfo;
|
|
var
|
|
rtn: TWinVerInfo;
|
|
|
|
resVer: TRegistry;
|
|
szProduct: String;
|
|
procGetProductInfo : TGetProductInfo;
|
|
hModule : THandle;
|
|
ProdType : DWORD;
|
|
dwMajor, dwMinor, dwService, dwBuildNum : DWORD;
|
|
bIsServer : Boolean;
|
|
begin
|
|
GetWindowsVersion(dwMajor, dwMinor, dwService, dwBuildNum, bIsServer);
|
|
|
|
p.dwMajorVersion := dwMajor;
|
|
p.dwMinorVersion := dwMinor;
|
|
p.dwBuildNumber := dwBuildNum;
|
|
if not bIsServer then
|
|
begin
|
|
p.wProductType := VER_NT_WORKSTATION
|
|
end;
|
|
|
|
//Get Windows Product
|
|
if p.dwMajorVersion = 5 then begin
|
|
if p.dwMinorVersion = 2 then
|
|
rtn.WinName := 'Windows 2003 Server Family'
|
|
else if p.dwMinorVersion = 1 then
|
|
rtn.WinName := 'Windows XP'
|
|
else if p.dwMinorVersion = 0 then
|
|
rtn.WinName := 'Windows 2000';
|
|
end
|
|
|
|
else if p.dwMajorVersion = 6 then
|
|
if p.dwMinorVersion = 1 then
|
|
begin
|
|
if p.wProductType = VER_NT_WORKSTATION then
|
|
rtn.WinName := 'Windows 7'
|
|
else rtn.WinName := 'Windows Server 2008 R2';
|
|
end else if p.dwMinorVersion = 0 then
|
|
begin
|
|
if p.wProductType = VER_NT_WORKSTATION then
|
|
rtn.WinName := 'Windows Vista'
|
|
else rtn.WinName := 'Windows Server 2008';
|
|
end
|
|
else
|
|
rtn.WinName := 'Windows NT';
|
|
|
|
//Get Product Substring
|
|
if (IsEX) then begin
|
|
case p.wProductType of
|
|
VER_NT_WORKSTATION:
|
|
begin
|
|
if (p.dwMajorVersion = 4) then
|
|
rtn.WinName := rtn.WinName + ' Workstation 4.0'
|
|
else if (p.wSuiteMask and VER_SUITE_PERSONAL) = VER_SUITE_PERSONAL then
|
|
rtn.WinName := rtn.WinName + ' Home Edition'
|
|
else if p.dwMajorVersion = 6 then
|
|
begin
|
|
// 비스타의 경우.. 버전정보를 모르겠다.. 아직은..
|
|
end else
|
|
rtn.WinName := rtn.WinName + ' Professional';
|
|
end;
|
|
VER_NT_SERVER:
|
|
begin
|
|
if ((p.dwMajorVersion = 5) and (p.dwMinorVersion = 2)) then begin
|
|
if (p.wSuiteMask and VER_SUITE_DATACENTER) = VER_SUITE_DATACENTER then
|
|
rtn.WinName := rtn.WinName + ' Datacenter Edition'
|
|
else if (p.wSuiteMask and VER_SUITE_ENTERPRISE) = VER_SUITE_ENTERPRISE then
|
|
rtn.WinName := rtn.WinName + ' Enterprise Edition'
|
|
else if (p.wSuiteMask and VER_SUITE_BLADE) = VER_SUITE_BLADE then
|
|
rtn.WinName := rtn.WinName + ' Web Edition'
|
|
else
|
|
rtn.WinName := rtn.WinName + ' Standard Edition';
|
|
end
|
|
else if ((p.dwMajorVersion = 5) and (p.dwMinorVersion = 0)) then begin
|
|
if (p.wSuiteMask and VER_SUITE_DATACENTER) = VER_SUITE_DATACENTER then
|
|
rtn.WinName := rtn.WinName + ' Datacenter Server'
|
|
else if (p.wSuiteMask and VER_SUITE_ENTERPRISE) = VER_SUITE_ENTERPRISE then
|
|
rtn.WinName := rtn.WinName + ' Advanced Server'
|
|
else
|
|
rtn.WinName := rtn.WinName + ' Server';
|
|
end
|
|
else if (p.dwMajorVersion = 6) then
|
|
|
|
else begin
|
|
if (p.wSuiteMask and VER_SUITE_ENTERPRISE) = VER_SUITE_ENTERPRISE then
|
|
rtn.WinName := rtn.WinName + ' Server 4.0 Enterprise Edition'
|
|
else
|
|
rtn.WinName := rtn.WinName + ' Server 4.0';
|
|
end;
|
|
end;
|
|
end; {case of}
|
|
|
|
if p.dwMajorVersion = 6 then
|
|
begin
|
|
hModule := GetModuleHandle('kernel32.dll');
|
|
procGetProductInfo := GetProcAddress( hModule ,'GetProductInfo');
|
|
if Assigned(procGetProductInfo) then
|
|
begin
|
|
procGetProductInfo(p.dwMajorVersion, p.dwMinorVersion, 0, 0, @ProdType);
|
|
|
|
case ProdType of
|
|
PRODUCT_ULTIMATE : rtn.WinName := rtn.WinName + ' Ultimate';
|
|
PRODUCT_PROFESSIONAL : rtn.WinName := rtn.WinName + ' Professional';
|
|
PRODUCT_HOME_PREMIUM : rtn.WinName := rtn.WinName + ' Home Premium Edition';
|
|
PRODUCT_HOME_BASIC : rtn.WinName := rtn.WinName + ' Home Basic Edition';
|
|
PRODUCT_ENTERPRISE : rtn.WinName := rtn.WinName + ' Enterprise Edition';
|
|
PRODUCT_BUSINESS : rtn.WinName := rtn.WinName + ' Business Edition';
|
|
PRODUCT_STARTER : rtn.WinName := rtn.WinName + ' Starter Edition';
|
|
PRODUCT_CLUSTER_SERVER : rtn.WinName := rtn.WinName + ' Cluster Server Edition';
|
|
PRODUCT_DATACENTER_SERVER : rtn.WinName := rtn.WinName + ' Datacenter Edition';
|
|
PRODUCT_DATACENTER_SERVER_CORE : rtn.WinName := rtn.WinName + ' Datacenter Edition (core installation)';
|
|
PRODUCT_ENTERPRISE_SERVER : rtn.WinName := rtn.WinName + ' Enterprise Edition';
|
|
PRODUCT_ENTERPRISE_SERVER_CORE : rtn.WinName := rtn.WinName + ' Enterprise Edition (core installation)';
|
|
PRODUCT_ENTERPRISE_SERVER_IA64 : rtn.WinName := rtn.WinName + ' Enterprise Edition for Itanium-based Systems)';
|
|
PRODUCT_SMALLBUSINESS_SERVER : rtn.WinName := rtn.WinName + ' Small Business Server';
|
|
PRODUCT_SMALLBUSINESS_SERVER_PREMIUM : rtn.WinName := rtn.WinName + ' Small Business Server Premium Edition';
|
|
PRODUCT_STANDARD_SERVER : rtn.WinName := rtn.WinName + ' Standard Edition';
|
|
PRODUCT_STANDARD_SERVER_CORE : rtn.WinName := rtn.WinName + ' Standard Edition (core installation)';
|
|
PRODUCT_WEB_SERVER : rtn.WinName := rtn.WinName + ' Web Server Edition';
|
|
|
|
end;
|
|
|
|
FreeModule(hModule);
|
|
end;
|
|
end;
|
|
|
|
|
|
end {If IsEx}
|
|
else begin
|
|
// Test for specific product on Windows NT 4.0 SP5 and earlier
|
|
resVer := TRegistry.Create(KEY_READ);
|
|
try
|
|
resVer.RootKey := HKEY_LOCAL_MACHINE;
|
|
resver.OpenKeyReadOnly('SYSTEM\\CurrentControlSet\\Control\\ProductOptions');
|
|
|
|
szProduct := resVer.ReadString('ProductType');
|
|
|
|
if (Strcomp('WINNT', PChar(szProduct)) = 0) then
|
|
rtn.WinName := rtn.WinName + ' Workstation '
|
|
else if (Strcomp('LANMANNT', PChar(szProduct)) = 0) then
|
|
rtn.WinName := rtn.WinName + ' Server '
|
|
else if (Strcomp('SERVERNT', PChar(szProduct)) = 0) then
|
|
rtn.WinName := rtn.WinName + ' Advanced Server ';
|
|
|
|
rtn.WinName := rtn.WinName + IntToStr(p.dwMajorVersion) + '.' + IntToStr(p.dwMinorVersion);
|
|
finally
|
|
resVer.Free;
|
|
end;
|
|
end;{else IsEx}
|
|
|
|
//Get Version
|
|
rtn.Version.Major := p.dwMajorVersion;
|
|
rtn.Version.Minor := p.dwMinorVersion;
|
|
rtn.Version.Build := (p.dwBuildNumber and $FFFF);
|
|
|
|
//Get Service Pack
|
|
if ((p.dwMajorVersion = 4) and (lstrcmpW(p.szCSDVersion, 'Service Pack 6' ) = 0)) then begin
|
|
// Test for SP6 versus SP6a.
|
|
resVer := TRegistry.Create(KEY_READ);
|
|
try
|
|
resVer.RootKey := HKEY_LOCAL_MACHINE;
|
|
if resVer.OpenKeyReadOnly('SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009') then
|
|
rtn.ServicePack := 'Service Pack 6a'
|
|
else
|
|
rtn.ServicePack := p.szCSDVersion;
|
|
finally
|
|
resVer.Free;
|
|
end;
|
|
end
|
|
else
|
|
//Else Other All Version
|
|
if Boolean(p.wServicePackMajor) or Boolean(p.wServicePackMinor) then begin
|
|
rtn.ServicePack := 'Service Pack ' + intToStr(p.wServicePackMajor);
|
|
if Boolean(p.wServicePackMinor) then
|
|
rtn.ServicePack := rtn.ServicePack + '.' + IntToStr(p.wServicePackMinor);
|
|
end
|
|
else
|
|
rtn.ServicePack := p.szCSDVersion;
|
|
|
|
//Create ID String and Return
|
|
rtn.WinID := 'Microsoft ' + rtn.WinName + #10#13'(Version ' + IntToStr(rtn.Version.Major) + '.' + IntToStr(rtn.Version.Minor)
|
|
+ ' Build ' + IntToStr(rtn.Version.Build) + ') ' + rtn.ServicePack;
|
|
|
|
Result := rtn;
|
|
end;
|
|
|
|
function ParseWin9x(p: TOSVersionInfo): TWinVerInfo;
|
|
var
|
|
rtn: TWinVerInfo;
|
|
begin
|
|
if ((p.dwMajorVersion = 4) and (p.dwMinorVersion = 0)) then begin
|
|
rtn.WinName := 'Windows 95';
|
|
if ((p.szCSDVersion[1] = 'C') or (p.szCSDVersion[1] = 'B')) then
|
|
rtn.WinName := rtn.WinName + ' OSR2';
|
|
end
|
|
else if ((p.dwMajorVersion = 4) and (p.dwMinorVersion = 10)) then begin
|
|
rtn.WinName := 'Windows 98';
|
|
if (p.szCSDVersion[1] = 'A') then
|
|
rtn.WinName := rtn.WinName + ' SE';
|
|
end
|
|
else if ((p.dwMajorVersion = 4) and (p.dwMinorVersion = 90)) then
|
|
rtn.WinName := 'Windows Millennium Edition';
|
|
|
|
rtn.Version.Major := p.dwMajorVersion;
|
|
rtn.Version.Minor := p.dwMinorVersion;
|
|
rtn.Version.Build := (p.dwBuildNumber and $FFFF);
|
|
|
|
rtn.ServicePack := p.szCSDVersion;
|
|
if ((p.szCSDVersion[1] = 'C') or (p.szCSDVersion[1] = 'B') or (p.szCSDVersion[1] = 'A')) then
|
|
rtn.ServicePack := RightStr(rtn.ServicePack, Length(rtn.ServicePack) - 2);
|
|
|
|
//Create ID String and Return
|
|
rtn.WinID := 'Microsoft ' + rtn.WinName + #10#13'(Version ' + IntToStr(rtn.Version.Major) + '.' + IntToStr(rtn.Version.Minor)
|
|
+ ' Build ' + IntToStr(rtn.Version.Build) + ') ' + rtn.ServicePack;
|
|
|
|
Result := rtn;
|
|
end;
|
|
|
|
function GetWindowsVersion(var AMajor, AMinor: DWORD): Boolean;
|
|
var
|
|
Buf: LPWKSTA_INFO_100;
|
|
begin
|
|
Result := False;
|
|
if MajorCache <> 0 then
|
|
begin
|
|
AMajor := MajorCache;
|
|
AMinor := MinorCache;
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
if NetWkstaGetInfo(nil, 100, @Buf) = NERR_Success then
|
|
begin
|
|
MajorCache := Buf.wki100_ver_major;
|
|
AMajor := MajorCache;
|
|
MinorCache := Buf.wki100_ver_minor;
|
|
AMinor := MinorCache;
|
|
NetApiBufferFree(Buf);
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
function GetWindowsVersion(var AMajor, AMinor, AServicePack, ABuildNumber: DWORD;
|
|
var AIsServer: Boolean): Boolean; overload;
|
|
var
|
|
I: Integer;
|
|
osvi: OSVERSIONINFOEX;
|
|
ConditionMask: LONGLONG;
|
|
begin
|
|
Result := False;
|
|
AMajor := 0;
|
|
AMinor := 0;
|
|
AServicePack := 0;
|
|
ABuildNumber := 0;
|
|
|
|
if not GetWindowsVersion(AMajor, AMinor) then
|
|
exit;
|
|
|
|
if ServicePackCache <> MAXDWORD then
|
|
begin
|
|
AServicePack := ServicePackCache;
|
|
AIsServer := IsServerCache;
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
ZeroMemory(@osvi, SizeOf(OSVERSIONINFOEX));
|
|
osvi.dwOSVersionInfoSize := SizeOf(OSVERSIONINFOEX);
|
|
ConditionMask := 0;
|
|
ConditionMask := VerSetConditionMask(ConditionMask, VER_SERVICEPACKMAJOR, VER_EQUAL);
|
|
for I := 0 to SERVICE_MAX_COUNT - 1 do
|
|
begin
|
|
osvi.wServicePackMajor := I;
|
|
if VerifyVersionInfo(osvi, VER_SERVICEPACKMAJOR, ConditionMask) then
|
|
begin
|
|
ServicePackCache := I;
|
|
AServicePack := ServicePackCache;
|
|
ZeroMemory(@osvi, SizeOf(OSVERSIONINFOEX));
|
|
osvi.dwOSVersionInfoSize := SizeOf(OSVERSIONINFOEX);
|
|
osvi.wProductType := VER_NT_SERVER;
|
|
ConditionMask := 0;
|
|
ConditionMask := VerSetConditionMask(ConditionMask, VER_PRODUCT_TYPE,
|
|
VER_EQUAL);
|
|
IsServerCache := VerifyVersionInfo(osvi, VER_PRODUCT_TYPE, ConditionMask);
|
|
AIsServer := IsServerCache;
|
|
Result := True;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
ConditionMask := 0;
|
|
ConditionMask := VerSetConditionMask(ConditionMask, VER_BUILDNUMBER,
|
|
VER_EQUAL);
|
|
for I := 0 to 10000 do
|
|
begin
|
|
osvi.dwBuildNumber := I;
|
|
if VerifyVersionInfo(osvi, VER_BUILDNUMBER, ConditionMask) then
|
|
begin
|
|
ABuildNumber := I;
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
initialization
|
|
MajorCache := 0;
|
|
MinorCache := 0;
|
|
ServicePackCache := MAXDWORD;
|
|
IsServerCache := False;
|
|
|
|
end.
|
|
|
|
|
|
|
|
|
|
|