$theTitle=wp_title(" - ", false); if($theTitle != "") { ?>
About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like
17 May // php the_time('Y') ?>
If you want to check if you are running on a Server Core edition of Windows you can use the GetProductInfo API.
GetProductInfo takes 4 input parameters that can be obtained using GetVersionEx and the OSVERSIONINFOEX structure:
1 2 3 4 5 6 | var osvi: OSVERSIONINFOEX; begin ZeroMemory(@osvi, SizeOf(osvi)); osvi.dwOSVersionInfoSize := SizeOf(osvi); Win32Check(GetVersionEx(osvi)); |
No we call GetProductInfo:
1 2 3 4 5 | var dwProdType: DWORD; begin Win32Check(GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.wServicePackMajor, osvi.wServicePackMinor, dwProdType)); |
The value returned in dwProdType can be checked against one of the constants for the Server Core editions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | PRODUCT_DATACENTER_SERVER_CORE, PRODUCT_STANDARD_SERVER_CORE, PRODUCT_ENTERPRISE_SERVER_CORE, PRODUCT_WEB_SERVER_CORE, PRODUCT_DATACENTER_SERVER_CORE_V, PRODUCT_STANDARD_SERVER_CORE_V, PRODUCT_ENTERPRISE_SERVER_CORE_V, PRODUCT_STORAGE_EXPRESS_SERVER_CORE, PRODUCT_STORAGE_STANDARD_SERVER_CORE, PRODUCT_STORAGE_WORKGROUP_SERVER_CORE, PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE, PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE, PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE, PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE |
So if put this all together we can write a function for it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | function IsServerCore: Boolean; var osvi: OSVERSIONINFOEX; dwProdType: DWORD; begin ZeroMemory(@osvi, SizeOf(osvi)); osvi.dwOSVersionInfoSize := SizeOf(osvi); Win32Check(GetVersionEx(osvi)); Win32Check(GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.wServicePackMajor, osvi.wServicePackMinor, dwProdType)); case dwProdType of PRODUCT_DATACENTER_SERVER_CORE, PRODUCT_STANDARD_SERVER_CORE, PRODUCT_ENTERPRISE_SERVER_CORE, PRODUCT_WEB_SERVER_CORE, PRODUCT_DATACENTER_SERVER_CORE_V, PRODUCT_STANDARD_SERVER_CORE_V, PRODUCT_ENTERPRISE_SERVER_CORE_V, PRODUCT_STORAGE_EXPRESS_SERVER_CORE, PRODUCT_STORAGE_STANDARD_SERVER_CORE, PRODUCT_STORAGE_WORKGROUP_SERVER_CORE, PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE, PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE, PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE, PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE: Result := True else Result := False; end; end; |
But where do these values come from?
GetProductInfo is exported by Kernel32.dll, this function is a stub to RtlGetProductInfo which is exported by ntdll.dll
RtlGetProductInfo performs a few checks on the input parameters and then calls the undocumented NtQueryLicenseValue API which has this signature:
1 2 | function NtQueryLicenseValue(Name: PUNICODE_STRING; ulType: ULONG; Buffer: Pointer; Length: ULONG; var DataLength: ULONG): NTSTATUS; stdcall; |
The value of the Name parameter on my Windows 7 machine is Kernel-ProductInfo, the ulType parameter is SL_DATA_DWORD (4), the buffer is a PDWORD with Length being SizeOf(DWORD).
If the call to NtQueryLicenseValue fails, a special value of 0xABCDABCDu is returned which equals PRODUCT_UNLICENSED.
You can directly check this value with the Licensing Demo from my Having fun with Windows Licensing article:
Leave a reply