quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

version_win32.c (8114B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Steve Holme, <steve_holme@hotmail.com>.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 
     25 #include "../curl_setup.h"
     26 
     27 #ifdef _WIN32
     28 
     29 #include <curl/curl.h>
     30 #include "version_win32.h"
     31 #include "warnless.h"
     32 
     33 /* The last 2 #include files should be in this order */
     34 #include "../curl_memory.h"
     35 #include "../memdebug.h"
     36 
     37 /* This Unicode version struct works for VerifyVersionInfoW (OSVERSIONINFOEXW)
     38    and RtlVerifyVersionInfo (RTLOSVERSIONINFOEXW) */
     39 struct OUR_OSVERSIONINFOEXW {
     40   ULONG  dwOSVersionInfoSize;
     41   ULONG  dwMajorVersion;
     42   ULONG  dwMinorVersion;
     43   ULONG  dwBuildNumber;
     44   ULONG  dwPlatformId;
     45   WCHAR  szCSDVersion[128];
     46   USHORT wServicePackMajor;
     47   USHORT wServicePackMinor;
     48   USHORT wSuiteMask;
     49   UCHAR  wProductType;
     50   UCHAR  wReserved;
     51 };
     52 
     53 /*
     54  * curlx_verify_windows_version()
     55  *
     56  * This is used to verify if we are running on a specific Windows version.
     57  *
     58  * Parameters:
     59  *
     60  * majorVersion [in] - The major version number.
     61  * minorVersion [in] - The minor version number.
     62  * buildVersion [in] - The build version number. If 0, this parameter is
     63  *                     ignored.
     64  * platform     [in] - The optional platform identifier.
     65  * condition    [in] - The test condition used to specifier whether we are
     66  *                     checking a version less than, equal to or greater than
     67  *                     what is specified in the major and minor version
     68  *                     numbers.
     69  *
     70  * Returns TRUE if matched; otherwise FALSE.
     71  */
     72 bool curlx_verify_windows_version(const unsigned int majorVersion,
     73                                   const unsigned int minorVersion,
     74                                   const unsigned int buildVersion,
     75                                   const PlatformIdentifier platform,
     76                                   const VersionCondition condition)
     77 {
     78   bool matched = FALSE;
     79 
     80 #ifdef CURL_WINDOWS_UWP
     81   /* We have no way to determine the Windows version from Windows apps,
     82      so let's assume we are running on the target Windows version. */
     83   const WORD fullVersion = MAKEWORD(minorVersion, majorVersion);
     84   const WORD targetVersion = (WORD)_WIN32_WINNT;
     85 
     86   (void)buildVersion;
     87 
     88   switch(condition) {
     89   case VERSION_LESS_THAN:
     90     matched = targetVersion < fullVersion;
     91     break;
     92 
     93   case VERSION_LESS_THAN_EQUAL:
     94     matched = targetVersion <= fullVersion;
     95     break;
     96 
     97   case VERSION_EQUAL:
     98     matched = targetVersion == fullVersion;
     99     break;
    100 
    101   case VERSION_GREATER_THAN_EQUAL:
    102     matched = targetVersion >= fullVersion;
    103     break;
    104 
    105   case VERSION_GREATER_THAN:
    106     matched = targetVersion > fullVersion;
    107     break;
    108   }
    109 
    110   if(matched && (platform == PLATFORM_WINDOWS)) {
    111     /* we are always running on PLATFORM_WINNT */
    112     matched = FALSE;
    113   }
    114 #elif defined(UNDER_CE)
    115   (void)majorVersion;
    116   (void)minorVersion;
    117   (void)buildVersion;
    118   (void)platform;
    119   (void)condition;
    120 #else
    121   ULONGLONG cm = 0;
    122   struct OUR_OSVERSIONINFOEXW osver;
    123   BYTE majorCondition;
    124   BYTE minorCondition;
    125   BYTE buildCondition;
    126   BYTE spMajorCondition;
    127   BYTE spMinorCondition;
    128   DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION |
    129                      VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;
    130 
    131   typedef LONG (APIENTRY *RTLVERIFYVERSIONINFO_FN)
    132     (struct OUR_OSVERSIONINFOEXW *, ULONG, ULONGLONG);
    133   static RTLVERIFYVERSIONINFO_FN pRtlVerifyVersionInfo;
    134   static bool onetime = TRUE; /* safe because first call is during init */
    135 
    136   if(onetime) {
    137     pRtlVerifyVersionInfo = CURLX_FUNCTION_CAST(RTLVERIFYVERSIONINFO_FN,
    138       (GetProcAddress(GetModuleHandleA("ntdll"), "RtlVerifyVersionInfo")));
    139     onetime = FALSE;
    140   }
    141 
    142   switch(condition) {
    143   case VERSION_LESS_THAN:
    144     majorCondition = VER_LESS;
    145     minorCondition = VER_LESS;
    146     buildCondition = VER_LESS;
    147     spMajorCondition = VER_LESS_EQUAL;
    148     spMinorCondition = VER_LESS_EQUAL;
    149     break;
    150 
    151   case VERSION_LESS_THAN_EQUAL:
    152     majorCondition = VER_LESS_EQUAL;
    153     minorCondition = VER_LESS_EQUAL;
    154     buildCondition = VER_LESS_EQUAL;
    155     spMajorCondition = VER_LESS_EQUAL;
    156     spMinorCondition = VER_LESS_EQUAL;
    157     break;
    158 
    159   case VERSION_EQUAL:
    160     majorCondition = VER_EQUAL;
    161     minorCondition = VER_EQUAL;
    162     buildCondition = VER_EQUAL;
    163     spMajorCondition = VER_GREATER_EQUAL;
    164     spMinorCondition = VER_GREATER_EQUAL;
    165     break;
    166 
    167   case VERSION_GREATER_THAN_EQUAL:
    168     majorCondition = VER_GREATER_EQUAL;
    169     minorCondition = VER_GREATER_EQUAL;
    170     buildCondition = VER_GREATER_EQUAL;
    171     spMajorCondition = VER_GREATER_EQUAL;
    172     spMinorCondition = VER_GREATER_EQUAL;
    173     break;
    174 
    175   case VERSION_GREATER_THAN:
    176     majorCondition = VER_GREATER;
    177     minorCondition = VER_GREATER;
    178     buildCondition = VER_GREATER;
    179     spMajorCondition = VER_GREATER_EQUAL;
    180     spMinorCondition = VER_GREATER_EQUAL;
    181     break;
    182 
    183   default:
    184     return FALSE;
    185   }
    186 
    187   memset(&osver, 0, sizeof(osver));
    188   osver.dwOSVersionInfoSize = sizeof(osver);
    189   osver.dwMajorVersion = majorVersion;
    190   osver.dwMinorVersion = minorVersion;
    191   osver.dwBuildNumber = buildVersion;
    192   if(platform == PLATFORM_WINDOWS)
    193     osver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
    194   else if(platform == PLATFORM_WINNT)
    195     osver.dwPlatformId = VER_PLATFORM_WIN32_NT;
    196 
    197   cm = VerSetConditionMask(cm, VER_MAJORVERSION, majorCondition);
    198   cm = VerSetConditionMask(cm, VER_MINORVERSION, minorCondition);
    199   cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, spMajorCondition);
    200   cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, spMinorCondition);
    201 
    202   if(platform != PLATFORM_DONT_CARE) {
    203     cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
    204     dwTypeMask |= VER_PLATFORMID;
    205   }
    206 
    207   /* Later versions of Windows have version functions that may not return the
    208      real version of Windows unless the application is so manifested. We prefer
    209      the real version always, so we use the Rtl variant of the function when
    210      possible. Note though the function signatures have underlying fundamental
    211      types that are the same, the return values are different. */
    212   if(pRtlVerifyVersionInfo)
    213     matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
    214   else
    215     matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver, dwTypeMask, cm);
    216 
    217   /* Compare the build number separately. VerifyVersionInfo normally compares
    218      major.minor in hierarchical order (eg 1.9 is less than 2.0) but does not
    219      do the same for build (eg 1.9 build 222 is not less than 2.0 build 111).
    220      Build comparison is only needed when build numbers are equal (eg 1.9 is
    221      always less than 2.0 so build comparison is not needed). */
    222   if(matched && buildVersion &&
    223      (condition == VERSION_EQUAL ||
    224       ((condition == VERSION_GREATER_THAN_EQUAL ||
    225         condition == VERSION_LESS_THAN_EQUAL) &&
    226         curlx_verify_windows_version(majorVersion, minorVersion, 0,
    227                                      platform, VERSION_EQUAL)))) {
    228 
    229     cm = VerSetConditionMask(0, VER_BUILDNUMBER, buildCondition);
    230     dwTypeMask = VER_BUILDNUMBER;
    231     if(pRtlVerifyVersionInfo)
    232       matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
    233     else
    234       matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
    235                                       dwTypeMask, cm);
    236   }
    237 
    238 #endif
    239 
    240   return matched;
    241 }
    242 
    243 #endif /* _WIN32 */