From 3daef8a5fd8268406a4c9d33afd8b464a1f87130 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Wed, 13 Nov 2019 15:56:22 +1100 Subject: [PATCH] roken: Windows version support helpers Add helper functions for determining the version of Windows upon which we are running. --- lib/roken/NTMakefile | 1 + lib/roken/rand.c | 28 +------- lib/roken/versionsupport.h | 139 +++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 27 deletions(-) create mode 100644 lib/roken/versionsupport.h diff --git a/lib/roken/NTMakefile b/lib/roken/NTMakefile index 01f79d165..99a60732c 100644 --- a/lib/roken/NTMakefile +++ b/lib/roken/NTMakefile @@ -177,6 +177,7 @@ INCFILES = \ !ifndef HAVE_STDINT_H $(INCDIR)\stdint.h \ !endif + $(INCDIR)\versionsupport.h \ $(INCDIR)\xdbm.h clean:: diff --git a/lib/roken/rand.c b/lib/roken/rand.c index 8b54c62e5..59ff47add 100644 --- a/lib/roken/rand.c +++ b/lib/roken/rand.c @@ -36,33 +36,7 @@ #ifdef HAVE_WIN32_RAND_S static int hasRand_s = 1; - -// The Following is BackPorted from VersionHelpers.h in the 10.0.15063.0 SDK -static FORCEINLINE BOOL -IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) -{ - OSVERSIONINFOEXW osvi ={ sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; - DWORDLONG const dwlConditionMask = VerSetConditionMask( - VerSetConditionMask( - VerSetConditionMask( - 0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_GREATER_EQUAL), - VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - - osvi.dwMajorVersion = wMajorVersion; - osvi.dwMinorVersion = wMinorVersion; - osvi.wServicePackMajor = wServicePackMajor; - - return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; -} - -static FORCEINLINE BOOL -IsWindowsXPOrGreater() -{ - // Assume that _WIN32_WINNT_WINXP (0x0501) not available so use contants. - return IsWindowsVersionOrGreater(5, 1, 0); -} - +#include "versionsupport.h" #endif void ROKEN_LIB_FUNCTION diff --git a/lib/roken/versionsupport.h b/lib/roken/versionsupport.h new file mode 100644 index 000000000..09adce3bf --- /dev/null +++ b/lib/roken/versionsupport.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2018-2019, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _VERSIONSUPPORT_H_ +#define _VERSIONSUPPORT_H_ 1 + +/* + * IsWindowsVersionOrGreater() is provided by Windows SDK 8.1 or greater. + * As AuriStorFS supports building with SDK 7.0 and greater we must + * provide our own. VerifyVersionInfoW() is present on Windows XP and + * later. + */ + +#ifndef _WIN32_WINNT_WIN7 +#define _WIN32_WINNT_WIN7 0x0601 +#endif + +#ifndef _WIN32_WINNT_WIN8 +#define _WIN32_WINNT_WIN8 0x0602 +#endif + +#ifndef _WIN32_WINNT_WINBLUE +#define _WIN32_WINNT_WINBLUE 0x0603 +#endif + +/* Based upon VersionHelpers.h */ +FORCEINLINE BOOL +IsWindowsVersionOrGreater(WORD wMajorVersion, + WORD wMinorVersion, + WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi; + DWORDLONG dwlConditionMask = 0; + + dwlConditionMask = VerSetConditionMask(dwlConditionMask, + VER_MAJORVERSION, + VER_GREATER_EQUAL); + dwlConditionMask = VerSetConditionMask(dwlConditionMask, + VER_MINORVERSION, + VER_GREATER_EQUAL); + dwlConditionMask = VerSetConditionMask(dwlConditionMask, + VER_SERVICEPACKMAJOR, + VER_GREATER_EQUAL); + + memset(&osvi, 0, sizeof(OSVERSIONINFOEXW)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, + (VER_MAJORVERSION | + VER_MINORVERSION | + VER_SERVICEPACKMAJOR), + dwlConditionMask); +} + +FORCEINLINE BOOL +IsWindowsXPOrGreater(VOID) +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), + LOBYTE(_WIN32_WINNT_WINXP), + 0); +} + +FORCEINLINE BOOL +IsWindows7OrGreater(VOID) +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), + LOBYTE(_WIN32_WINNT_WIN7), + 0); +} + +FORCEINLINE BOOL +IsWindows8OrGreater(VOID) +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), + LOBYTE(_WIN32_WINNT_WIN8), + 0); +} + +FORCEINLINE BOOL +IsWindows8Point1OrGreater(VOID) +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), + LOBYTE(_WIN32_WINNT_WINBLUE), + 0); +} + +#define IS_WINDOWS_VERSION_OR_GREATER_CACHED(fn) \ + \ +FORCEINLINE BOOL \ +fn##Cached(VOID) \ +{ \ + static LONG lIsVersionOrGreater = -1; \ + \ + if (lIsVersionOrGreater == -1) { \ + LONG lResult = fn(); \ + InterlockedCompareExchangeRelease(&lIsVersionOrGreater, \ + lResult, -1); \ + } \ + \ + return lIsVersionOrGreater == 1; \ +} + +IS_WINDOWS_VERSION_OR_GREATER_CACHED(IsWindowsXPOrGreater) +IS_WINDOWS_VERSION_OR_GREATER_CACHED(IsWindows7OrGreater) +IS_WINDOWS_VERSION_OR_GREATER_CACHED(IsWindows8OrGreater) +IS_WINDOWS_VERSION_OR_GREATER_CACHED(IsWindows8Point1OrGreater) + +#endif /* _VERSIONSUPPORT_H_ */