diff --git a/src/dutil/inc/osutil.h b/src/dutil/inc/osutil.h index 01f8d9c..2cce6f6 100644 --- a/src/dutil/inc/osutil.h +++ b/src/dutil/inc/osutil.h @@ -33,6 +33,9 @@ HRESULT DAPI OsIsRunningPrivileged( HRESULT DAPI OsIsUacEnabled( __out BOOL* pfUacEnabled ); +HRESULT DAPI OsRtlGetVersion( + __inout RTL_OSVERSIONINFOEXW* pOvix + ); #ifdef __cplusplus } diff --git a/src/dutil/osutil.cpp b/src/dutil/osutil.cpp index d1a4dd9..38b32eb 100644 --- a/src/dutil/osutil.cpp +++ b/src/dutil/osutil.cpp @@ -2,8 +2,11 @@ #include "precomp.h" +typedef NTSTATUS(NTAPI* PFN_RTL_GET_VERSION)(_Out_ PRTL_OSVERSIONINFOEXW lpVersionInformation); + OS_VERSION vOsVersion = OS_VERSION_UNKNOWN; DWORD vdwOsServicePack = 0; +RTL_OSVERSIONINFOEXW vovix = { }; /******************************************************************** OsGetVersion @@ -186,3 +189,41 @@ LExit: return hr; } + +HRESULT DAPI OsRtlGetVersion( + __inout RTL_OSVERSIONINFOEXW* pOvix + ) +{ + HRESULT hr = S_OK; + HMODULE hNtdll = NULL; + PFN_RTL_GET_VERSION pfnRtlGetVersion = NULL; + + if (vovix.dwOSVersionInfoSize) + { + ExitFunction(); + } + + vovix.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); + + hr = LoadSystemLibrary(L"ntdll.dll", &hNtdll); + if (E_MODNOTFOUND == hr) + { + ExitOnRootFailure(hr = E_NOTIMPL, "Failed to load ntdll.dll"); + } + ExitOnFailure(hr, "Failed to load ntdll.dll."); + + pfnRtlGetVersion = reinterpret_cast(::GetProcAddress(hNtdll, "RtlGetVersion")); + ExitOnNullWithLastError(pfnRtlGetVersion, hr, "Failed to locate RtlGetVersion."); + + hr = static_cast(pfnRtlGetVersion(&vovix)); + +LExit: + memcpy(pOvix, &vovix, sizeof(RTL_OSVERSIONINFOEXW)); + + if (hNtdll) + { + ::FreeLibrary(hNtdll); + } + + return hr; +}