Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * PURPOSE: Runtime code * FILE: lib/rtl/version.c * PROGRAMERS: Filip Navara * Hermes Belusca-Maito (hermes.belusca@sfr.fr) */
/* INCLUDES *****************************************************************/
#include <rtl.h>
#define NDEBUG#include <debug.h>
/* GLOBALS ******************************************************************/
NTSTATUSNTAPIRtlGetVersion(OUT PRTL_OSVERSIONINFOW lpVersionInformation);
/* FUNCTIONS ****************************************************************/
static UCHARRtlpVerGetCondition(IN ULONGLONG ConditionMask, IN ULONG TypeMask);
static BOOLEANRtlpVerCompare(ULONG left, ULONG right, UCHAR Condition){ switch (Condition) { case VER_EQUAL: return (left == right); case VER_GREATER: return (left > right); case VER_GREATER_EQUAL: return (left >= right); case VER_LESS: return (left < right); case VER_LESS_EQUAL: return (left <= right); default: break; } return FALSE;}
/** @implemented*/NTSTATUSNTAPIRtlVerifyVersionInfo(IN PRTL_OSVERSIONINFOEXW VersionInfo, IN ULONG TypeMask, IN ULONGLONG ConditionMask){ RTL_OSVERSIONINFOEXW Version; BOOLEAN Comparison; BOOLEAN DoNextCheck; NTSTATUS Status; UCHAR Condition;
/* FIXME: - Check the following special case on Windows (various versions): o lp->wSuiteMask == 0 and ver.wSuiteMask != 0 and VER_AND/VER_OR o lp->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW) - MSDN talks about some tests being impossible. Check what really happens. */
Version.dwOSVersionInfoSize = sizeof(Version);
Status = RtlGetVersion((PRTL_OSVERSIONINFOW)&Version); if (Status != STATUS_SUCCESS) { return Status; }
if (!TypeMask || !ConditionMask) { return STATUS_INVALID_PARAMETER; }
if (TypeMask & VER_PRODUCT_TYPE) { Comparison = RtlpVerCompare(Version.wProductType, VersionInfo->wProductType, RtlpVerGetCondition(ConditionMask, VER_PRODUCT_TYPE)); if (!Comparison) { return STATUS_REVISION_MISMATCH; } }
if (TypeMask & VER_SUITENAME) { switch (RtlpVerGetCondition(ConditionMask, VER_SUITENAME)) { case VER_AND: { if ((VersionInfo->wSuiteMask & Version.wSuiteMask) != VersionInfo->wSuiteMask) { return STATUS_REVISION_MISMATCH; } } break;
case VER_OR: { if (!(VersionInfo->wSuiteMask & Version.wSuiteMask) && VersionInfo->wSuiteMask) { return STATUS_REVISION_MISMATCH; } break; }
default: { return STATUS_INVALID_PARAMETER; } } }
if (TypeMask & VER_PLATFORMID) { Comparison = RtlpVerCompare(Version.dwPlatformId, VersionInfo->dwPlatformId, RtlpVerGetCondition(ConditionMask, VER_PLATFORMID)); if (!Comparison) { return STATUS_REVISION_MISMATCH; } }
if (TypeMask & VER_BUILDNUMBER) { Comparison = RtlpVerCompare(Version.dwBuildNumber, VersionInfo->dwBuildNumber, RtlpVerGetCondition(ConditionMask, VER_BUILDNUMBER)); if (!Comparison) { return STATUS_REVISION_MISMATCH; } }
DoNextCheck = TRUE; Condition = VER_EQUAL;
if (TypeMask & VER_MAJORVERSION) { Condition = RtlpVerGetCondition(ConditionMask, VER_MAJORVERSION); DoNextCheck = (VersionInfo->dwMajorVersion == Version.dwMajorVersion); Comparison = RtlpVerCompare(Version.dwMajorVersion, VersionInfo->dwMajorVersion, Condition);
if (!Comparison && !DoNextCheck) { return STATUS_REVISION_MISMATCH; } }
if (DoNextCheck) { if (TypeMask & VER_MINORVERSION) { if (Condition == VER_EQUAL) { Condition = RtlpVerGetCondition(ConditionMask, VER_MINORVERSION); }
DoNextCheck = (VersionInfo->dwMinorVersion == Version.dwMinorVersion); Comparison = RtlpVerCompare(Version.dwMinorVersion, VersionInfo->dwMinorVersion, Condition);
if (!Comparison && !DoNextCheck) { return STATUS_REVISION_MISMATCH; } }
if (DoNextCheck && (TypeMask & VER_SERVICEPACKMAJOR)) { if (Condition == VER_EQUAL) { Condition = RtlpVerGetCondition(ConditionMask, VER_SERVICEPACKMAJOR); }
DoNextCheck = (VersionInfo->wServicePackMajor == Version.wServicePackMajor); Comparison = RtlpVerCompare(Version.wServicePackMajor, VersionInfo->wServicePackMajor, Condition);
if (!Comparison && !DoNextCheck) { return STATUS_REVISION_MISMATCH; }
if (DoNextCheck && (TypeMask & VER_SERVICEPACKMINOR)) { if (Condition == VER_EQUAL) { Condition = RtlpVerGetCondition(ConditionMask, VER_SERVICEPACKMINOR); }
Comparison = RtlpVerCompare(Version.wServicePackMinor, VersionInfo->wServicePackMinor, Condition);
if (!Comparison) { return STATUS_REVISION_MISMATCH; } } } }
return STATUS_SUCCESS;}
static UCHARRtlpVerGetCondition(IN ULONGLONG ConditionMask, IN ULONG TypeMask){ UCHAR Condition = 0;
if (TypeMask & VER_PRODUCT_TYPE) Condition |= ConditionMask >> (7 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_SUITENAME) Condition |= ConditionMask >> (6 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_PLATFORMID) Condition |= ConditionMask >> (3 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_BUILDNUMBER) Condition |= ConditionMask >> (2 * VER_NUM_BITS_PER_CONDITION_MASK); /* * We choose here the lexicographical order on the 4D space * {(Major ; Minor ; SP Major ; SP Minor)} to select the * appropriate comparison operator. * Therefore the following 'else if' instructions must be in this order. */ else if (TypeMask & VER_MAJORVERSION) Condition |= ConditionMask >> (1 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_MINORVERSION) Condition |= ConditionMask >> (0 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_SERVICEPACKMAJOR) Condition |= ConditionMask >> (5 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_SERVICEPACKMINOR) Condition |= ConditionMask >> (4 * VER_NUM_BITS_PER_CONDITION_MASK);
Condition &= VER_CONDITION_MASK;
return Condition;}
/* * @implemented */ULONGLONGNTAPIVerSetConditionMask(IN ULONGLONG ConditionMask, IN ULONG TypeMask, IN UCHAR Condition){ ULONGLONG ullCondMask;
if (TypeMask == 0) return ConditionMask;
Condition &= VER_CONDITION_MASK;
if (Condition == 0) return ConditionMask;
ullCondMask = Condition; if (TypeMask & VER_PRODUCT_TYPE) ConditionMask |= ullCondMask << (7 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_SUITENAME) ConditionMask |= ullCondMask << (6 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_SERVICEPACKMAJOR) ConditionMask |= ullCondMask << (5 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_SERVICEPACKMINOR) ConditionMask |= ullCondMask << (4 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_PLATFORMID) ConditionMask |= ullCondMask << (3 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_BUILDNUMBER) ConditionMask |= ullCondMask << (2 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_MAJORVERSION) ConditionMask |= ullCondMask << (1 * VER_NUM_BITS_PER_CONDITION_MASK); else if (TypeMask & VER_MINORVERSION) ConditionMask |= ullCondMask << (0 * VER_NUM_BITS_PER_CONDITION_MASK);
return ConditionMask;}
/* EOF */