From 899cd5595ddc145672e1697fca9b6cf0e7c84b22 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 1 Jun 2020 23:11:33 -0700 Subject: [PATCH] sys: FspIsNtDdiVersionAvailable --- src/sys/driver.c | 6 ++-- src/sys/driver.h | 1 + src/sys/util.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/sys/driver.c b/src/sys/driver.c index 66eb90b6..f430deb8 100644 --- a/src/sys/driver.c +++ b/src/sys/driver.c @@ -237,7 +237,7 @@ static VOID FspDriverMultiVersionInitialize(VOID) #pragma prefast(suppress:30035, "FspDriverMultiVersionInitialize is called from DriverEntry") ExInitializeDriverRuntime(DrvRtPoolNxOptIn); - if (RtlIsNtDdiVersionAvailable(NTDDI_WIN7)) + if (FspIsNtDdiVersionAvailable(NTDDI_WIN7)) { UNICODE_STRING Name; @@ -246,10 +246,10 @@ static VOID FspDriverMultiVersionInitialize(VOID) (FSP_MV_CcCoherencyFlushAndPurgeCache *)(UINT_PTR)MmGetSystemRoutineAddress(&Name); } - if (RtlIsNtDdiVersionAvailable(NTDDI_WIN8)) + if (FspIsNtDdiVersionAvailable(NTDDI_WIN8)) FspMvMdlMappingNoWrite = MdlMappingNoWrite; - if (RtlIsNtDdiVersionAvailable(0x0A000005/*NTDDI_WIN10_RS4*/)) + if (FspIsNtDdiVersionAvailable(NTDDI_WIN10_RS4)) FspHasReparsePointCaseSensitivityFix = TRUE; } diff --git a/src/sys/driver.h b/src/sys/driver.h index f87f1bb9..2eaee33f 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -503,6 +503,7 @@ NTSTATUS FspUuid5Make(const UUID *Namespace, const VOID *Buffer, ULONG Size, UUI /* utility */ PVOID FspAllocatePoolMustSucceed(POOL_TYPE PoolType, SIZE_T Size, ULONG Tag); PVOID FspAllocateIrpMustSucceed(CCHAR StackSize); +BOOLEAN FspIsNtDdiVersionAvailable(ULONG RequestedVersion); NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); diff --git a/src/sys/util.c b/src/sys/util.c index cf85c517..0ba7db1d 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -21,6 +21,7 @@ #include +BOOLEAN FspIsNtDdiVersionAvailable(ULONG Version); NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); @@ -132,6 +133,7 @@ PVOID FspIrpHookContext(PVOID Context); NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); #ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, FspIsNtDdiVersionAvailable) #pragma alloc_text(PAGE, FspCreateGuid) #pragma alloc_text(PAGE, FspGetDeviceObjectPointer) #pragma alloc_text(PAGE, FspRegistryGetValue) @@ -223,6 +225,75 @@ PVOID FspAllocateIrpMustSucceed(CCHAR StackSize) } } +BOOLEAN FspIsNtDdiVersionAvailable(ULONG RequestedVersion) +{ + PAGED_CODE(); + + static ULONG Version; + + if (0 == Version) + { + RTL_OSVERSIONINFOEXW VersionInfo; + ULONG TempVersion; + + RtlZeroMemory(&VersionInfo, sizeof VersionInfo); + VersionInfo.dwOSVersionInfoSize = sizeof VersionInfo; + RtlGetVersion((PVOID)&VersionInfo); + + TempVersion = + ((UINT8)VersionInfo.dwMajorVersion << 24) | + ((UINT8)VersionInfo.dwMinorVersion << 16) | + ((UINT8)VersionInfo.wServicePackMajor << 8); + + if (10 <= VersionInfo.dwMajorVersion) + { + /* see https://docs.microsoft.com/en-us/windows/release-information/ */ + static struct + { + ULONG BuildNumber; + ULONG Subver; + } Builds[] = + { + { 10240, SUBVER(NTDDI_WIN10) }, + { 10586, SUBVER(NTDDI_WIN10_TH2) }, + { 14393, SUBVER(NTDDI_WIN10_RS1) }, + { 15063, SUBVER(NTDDI_WIN10_RS2) }, + { 16299, SUBVER(NTDDI_WIN10_RS3) }, + { 17134, SUBVER(NTDDI_WIN10_RS4) }, + { 17763, SUBVER(NTDDI_WIN10_RS5) }, + { 18362, SUBVER(NTDDI_WIN10_19H1) }, + { 18363, SUBVER(NTDDI_WIN10_19H1) }, + { 19041, 9 }, + { (ULONG)-1, 10 }, + }; + int Lo = 0, Hi = sizeof Builds / sizeof Builds[0] - 1, Mi; + + while (Lo <= Hi) + { + Mi = (unsigned)(Lo + Hi) >> 1; + + if (Builds[Mi].BuildNumber < VersionInfo.dwBuildNumber) + Lo = Mi + 1; + else if (Builds[Mi].BuildNumber > VersionInfo.dwBuildNumber) + Hi = Mi - 1; + else + { + Lo = Mi; + break; + } + } + Mi = Lo; + + TempVersion |= (UINT8)Builds[Mi].Subver; + } + + /* thread-safe because multiple threads will compute same value */ + InterlockedExchange((PVOID)&Version, TempVersion); + } + + return RequestedVersion <= Version; +} + NTSTATUS FspCreateGuid(GUID *Guid) { PAGED_CODE();