unit LibOSVersion;
interface
uses
Windows, SysUtils;
{$IF CompilerVersion < 21}
// Delphi 2010 - 21
// Delphi 2009 - 20
// Delphi 2007 - 18.5
// Delphi 2006 - 18
// Delphi 2005 - 17
// Delphi 8 - 16
// Delphi 7 - 15
// Delphi 6 - 14
type
POSVersionInfoExA = ^TOSVersionInfoExA;
POSVersionInfoEx = POSVersionInfoExA;
_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}
_OSVERSIONINFOEX = _OSVERSIONINFOEXA;
TOSVersionInfoExA = _OSVERSIONINFOEXA;
TOSVersionInfoEx = TOSVersionInfoExA;
OSVERSIONINFOEXA = _OSVERSIONINFOEXA;
{$EXTERNALSYM OSVERSIONINFOEXA}
{$EXTERNALSYM OSVERSIONINFOEX}
OSVERSIONINFOEX = OSVERSIONINFOEXA;
function GetVersionEx(var VersionInformation: TOSVersionInfoEx): BOOL; stdcall;
{$EXTERNALSYM GetVersionEx}
{$IFEND}
function OS_GetVersionEx(var OSVI : OSVERSIONINFOEX) : BOOL; stdcall;
function OS_GetNativeSystemInfo(var SI : SYSTEM_INFO) : BOOL; stdcall;
function OS_VersionText : String;
{===============================================================
VER_PLATFORM_WIN32_NT = 2
VER_PLATFORM_WIN32_WINDOWS = 1
================================================================}
function OS_PlatformID : DWORD; stdcall;
{===============================================================
4, 0 = Windows NT 4.0, or Windows 95.
4, 10 = Windows 98.
4, 90 = Windows Me.
5, 0 = Windows 2000.
5, 1 = Windows XP.
5, 2 = Windows Server 2003 R2, ## GetSystemMetrics(SM_SERVERR2) != 0
= Windows Server 2003, ## GetSystemMetrics(SM_SERVERR2) == 0
= Windows Home Server, ## OSVERSIONINFOEX.wSuiteMask == VER_SUITE_WH_SERVER
= Windows XP Professional x64 Edition. ## (OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
6, 0 = Windows Vista, ## OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
= Windows Server 2008. ## OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
6, 1 = Windows Server 2008 R2, ## OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
= Windows 7 ## OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
6, 2 = Windows Server 2012 ## OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
= Windows 8 ## OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
*6, 3 = Windows Server 2012 R2 ## OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
= Windows 8.1 ## OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
*10, 0 = Windows Server 2016 ## OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
= Windows 10 ## OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
================================================================
* For applications that have been manifested for Windows 8.1 or Windows 10.
Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2).
To manifest your applications for Windows 8.1 or Windows 10, refer to Targeting your application for Windows.
================================================================}
// 프로그램 등록 정보에서 호환성 체크를 찍고 들어오는 경우
// 호환 OS의 정보가 들어오니 주의하도록...
function OS_Version(var Major, Minor, Build : DWORD) : BOOL; stdcall;
{===============================================================
"Service Pack 6a"
"Service Pack 6"
"Service Pack 5"
"Service Pack 4"
"Service Pack 3"
"Service Pack 2"
"Service Pack 1"
"A" : Window 98 SE
"B" : Window 98 SE
"C" : Windows 95 OSR 2
================================================================}
function OS_CSDVersion : String; stdcall;
{===============================================================
6, 0 = Service Pack 6
================================================================}
function OS_ServicePackVersion(var Major, Minor : DWORD) : BOOL; stdcall;
{===============================================================
// WinNT SP xx 이상인가?
================================================================}
function OS_isNTsp(ServicePackMajor : WORD) : BOOL; stdcall;
{===============================================================
// 이 버전이상인가?
================================================================}
function OS_isVersion(Major, Minor: DWORD) : BOOL; stdcall;
const
{$EXTERNALSYM PROCESSOR_INTEL_386}
PROCESSOR_INTEL_386 = 386;
{$EXTERNALSYM PROCESSOR_INTEL_486}
PROCESSOR_INTEL_486 = 486;
{$EXTERNALSYM PROCESSOR_INTEL_PENTIUM}
PROCESSOR_INTEL_PENTIUM = 586;
{$EXTERNALSYM PROCESSOR_INTEL_IA64}
PROCESSOR_INTEL_IA64 = 2200;
{$EXTERNALSYM PROCESSOR_AMD_X8664}
PROCESSOR_AMD_X8664 = 8664;
{$EXTERNALSYM PROCESSOR_UNKNOWN}
PROCESSOR_UNKNOWN = 0;
{===============================================================
386 = PROCESSOR_INTEL_386
486 = PROCESSOR_INTEL_486
586 = PROCESSOR_INTEL_PENTIUM
2200 = PROCESSOR_INTEL_IA64
8664 = PROCESSOR_AMD_X8664
0 = Unknown type
================================================================}
function OS_GetProcessorType : DWORD; stdcall;
const
{$EXTERNALSYM PROCESSOR_ARCHITECTURE_AMD64}
PROCESSOR_ARCHITECTURE_AMD64 = 9;
{$EXTERNALSYM PROCESSOR_ARCHITECTURE_IA64}
PROCESSOR_ARCHITECTURE_IA64 = 6;
{$EXTERNALSYM PROCESSOR_ARCHITECTURE_INTEL}
PROCESSOR_ARCHITECTURE_INTEL = 0;
{$EXTERNALSYM PROCESSOR_ARCHITECTURE_UNKNOWN}
PROCESSOR_ARCHITECTURE_UNKNOWN = $FFFF;
{===============================================================
9 = PROCESSOR_ARCHITECTURE_AMD64 ## x64 (AMD or Intel)
6 = PROCESSOR_ARCHITECTURE_IA64 ## Intel Itanium Processor Family (IPF)
0 = PROCESSOR_ARCHITECTURE_INTEL ## x86
0xFFFF = PROCESSOR_ARCHITECTURE_UNKNOWN ## Unknown architecture.
================================================================}
function OS_GetProcessorArch : WORD; stdcall;
{$IF CompilerVersion < 21}
function GetVersionEx; external kernel32 name 'GetVersionExA';
{$IFEND}
function OS_GetNativeSystemInfo(var SI : SYSTEM_INFO) : BOOL; stdcall;
type
TSIFUNC = procedure(SI : Pointer); stdcall;
var
SIFUNC : TSIFUNC;
begin
// WindowXP 이상에서만 지원
SIFUNC := GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetNativeSystemInfo');
RESULT := Assigned(SIFUNC);
if RESULT then SIFUNC(@SI);
end;
function OS_GetProcessorType : DWORD; stdcall;
var
SI : SYSTEM_INFO;
begin
// WindowXP 이상에서만 지원
if (not OS_isVersion(5, 1)) or (not OS_GetNativeSystemInfo(SI)) then begin
RESULT := 0;
Exit;
end;
RESULT := SI.dwProcessorType;
end;
function OS_GetProcessorArch : WORD; stdcall;
var
SI : SYSTEM_INFO;
begin
// WindowXP 이상에서만 지원
if (not OS_isVersion(5, 1)) or (not OS_GetNativeSystemInfo(SI)) then begin
RESULT := $FFFF;
Exit;
end;
RESULT := SI.wProcessorArchitecture;
end;
function OS_GetVersionEx(var OSVI : OSVERSIONINFOEX) : BOOL; stdcall;
begin
FillMemory(@osvi, sizeof(OSVERSIONINFOEX), $FF);
osvi.dwOSVersionInfoSize := sizeof(OSVERSIONINFOEX);
RESULT := GetVersionEx(OSVI);
if not RESULT then begin
osvi.dwOSVersionInfoSize := sizeof(OSVERSIONINFO);
RESULT := GetVersionEx(OSVI);
end;
end;
function OS_PlatformID : DWORD; stdcall;
var
OSVI : OSVERSIONINFOEX;
begin
if OS_GetVersionEx(OSVI)
then RESULT := OSVI.dwPlatformId
else RESULT := DWORD(-1);
end;
// 프로그램 등록 정보에서 호환성 체크를 찍고 들어오는 경우
// 호환 OS의 정보가 들어오니 주의하도록...
function OS_Version(var Major, Minor, Build : DWORD) : BOOL; stdcall;
var
OSVI : OSVERSIONINFOEX;
begin
RESULT := OS_GetVersionEx(OSVI);
if RESULT then begin
Major := OSVI.dwMajorVersion;
Minor := OSVI.dwMinorVersion;
Build := OSVI.dwBuildNumber;
end;
end;
function OS_isVersion(Major, Minor: DWORD) : BOOL; stdcall;
var
OSVI : OSVERSIONINFOEX;
begin
RESULT := OS_GetVersionEx(OSVI);
if RESULT then begin
RESULT := (OSVI.dwMajorVersion > Major) or
((OSVI.dwMajorVersion = Major) and (OSVI.dwMinorVersion >= Minor));
end;
end;
function OS_CSDVersion : String; stdcall;
var
OSVI : OSVERSIONINFOEX;
begin
if OS_GetVersionEx(OSVI)
then RESULT := Trim(OSVI.szCSDVersion)
else RESULT := '';
end;
function OS_ServicePackVersion(var Major, Minor : DWORD) : BOOL; stdcall;
var
OSVI : OSVERSIONINFOEX;
Buf : String;
begin
RESULT := OS_GetVersionEx(OSVI);
if RESULT then begin
if (OSVI.wServicePackMajor = $FFFF) and (OSVI.wServicePackMinor = $FFFF) then begin
// CSDVersion 으로부터 추출 해야한다.
Buf := UpperCase(Trim(OSVI.szCSDVersion));
if Pos('SERVICE PACK ', Buf) = 1 then begin
Delete(Buf, 1, 13);
if (Length(Buf) > 0) and (Buf[1] >= '1') and (Buf[1] <= '9') then begin
Major := Ord(Buf[1]) - Ord('0');
Minor := 0;
Delete(Buf, 1, 1);
if (Length(Buf) > 0) and (Buf[1] >= 'A') and (Buf[1] <= 'Z') then Minor := Ord(Buf[1]) - Ord('A') + 1;
end
else begin
Major := 0;
Minor := 0;
end;
end
else if (Length(Buf) = 1) and (Buf[1] >= 'A') and (Buf[1] <= 'C') then begin
Minor := Ord(Buf[1]) - Ord('A') + 1;
Major := 0;
end
else begin
Minor := 0;
Major := 0;
end;
end
else begin
Major := OSVI.wServicePackMajor;
Minor := OSVI.wServicePackMinor;
end;
end;
end;
function OS_isNTsp(ServicePackMajor : WORD) : BOOL; stdcall;
var
Major, Minor, Build : DWORD;
begin
RESULT := OS_PlatformID = VER_PLATFORM_WIN32_NT; // NT, 2000, XP, 2003, ...
if not RESULT then Exit;
RESULT := OS_Version(Major, Minor, Build);
if not RESULT then Exit;
if Major >= 5 then Exit; // 2000, XP, 2003, ...
// 모두 걸러지고 NT 4.0 만 남았다.
RESULT := OS_ServicePackVersion(Major, Minor);
if not RESULT then Exit;
RESULT := (Major >= ServicePackMajor);
end;
function OS_VersionText : String;
var
OSVI : OSVERSIONINFOEX;
TEMP : String;
begin
RESULT := '';
if not OS_GetVersionEx(OSVI) then Exit;
RESULT := IntToStr(OSVI.dwMajorVersion) + '.' + IntToStr(OSVI.dwMinorVersion) + '.' + IntToStr(OSVI.dwBuildNumber);
TEMP := OSVI.szCSDVersion;
if TEMP <> '' then begin
if Length(TEMP) = 1 then case TEMP[1] of
'A' : TEMP := 'Windows 98 SE (A)';
'B' : TEMP := 'Windows 98 SE (B)';
'C' : TEMP := 'Windows 95 OSR 2';
end;
RESULT := RESULT + ' ' + TEMP;
end;
end;