00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include <stdio.h>
00027
#include <ntrtlp.h>
00028
#if !defined(NTOS_KERNEL_RUNTIME)
00029
#include <winerror.h>
00030
#endif
00031
00032
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
00033
#pragma alloc_text(PAGE, RtlGetVersion)
00034
#endif
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #define NEW_STYLE_BIT_MASK 0x8000000000000000
00061
00062
00063
00064
00065
00066 #define OLD_CONDITION(_m_,_t_) (ULONG)((_m_&(0xff<<(1<<_t_)))>>(1<<_t_))
00067
00068
00069
00070
00071 #define OLD_STYLE_CONDITION_MASK(_m_) (((_m_) & NEW_STYLE_BIT_MASK) == 0)
00072
00073 #define RTL_GET_CONDITION(_m_, _t_) \
00074
(OLD_STYLE_CONDITION_MASK(_m_) ? (OLD_CONDITION(_m_,_t_)) : \
00075
RtlpVerGetConditionMask((_m_), (_t_)))
00076
00077 #define LEXICAL_COMPARISON 1
00078 #define MAX_STRING_LENGTH 20
00079
00080 ULONG
00081
RtlpVerGetConditionMask(
00082 ULONGLONG ConditionMask,
00083 ULONG TypeMask
00084 );
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
#if defined(NTOS_KERNEL_RUNTIME)
00106
NTSTATUS
00107
RtlGetVersion (
00108 OUT PRTL_OSVERSIONINFOW lpVersionInformation
00109 )
00110 {
00111 NT_PRODUCT_TYPE NtProductType;
00112
RTL_PAGED_CODE();
00113
00114 lpVersionInformation->dwMajorVersion =
NtMajorVersion;
00115 lpVersionInformation->dwMinorVersion =
NtMinorVersion;
00116 lpVersionInformation->dwBuildNumber = (
USHORT)(
NtBuildNumber & 0x3FFF);
00117 lpVersionInformation->dwPlatformId = 2;
00118
if (lpVersionInformation->dwOSVersionInfoSize ==
sizeof( RTL_OSVERSIONINFOEXW )) {
00119 ((PRTL_OSVERSIONINFOEXW)lpVersionInformation)->wServicePackMajor = ((
USHORT)
CmNtCSDVersion >> 8) & (0xFF);
00120 ((PRTL_OSVERSIONINFOEXW)lpVersionInformation)->wServicePackMinor = (
USHORT)
CmNtCSDVersion & 0xFF;
00121 ((PRTL_OSVERSIONINFOEXW)lpVersionInformation)->wSuiteMask = (
USHORT)(USER_SHARED_DATA->SuiteMask&0xffff);
00122 ((PRTL_OSVERSIONINFOEXW)lpVersionInformation)->wProductType = (
RtlGetNtProductType(&NtProductType) ? NtProductType :0);
00123
00124
00125 ((PRTL_OSVERSIONINFOEXW)lpVersionInformation)->wReserved = (UCHAR)0;
00126 }
00127
00128
return STATUS_SUCCESS;
00129 }
00130
#else
00131
NTSTATUS
00132 RtlGetVersion(
00133 OUT PRTL_OSVERSIONINFOW lpVersionInformation
00134 )
00135 {
00136 PPEB Peb;
00137 NT_PRODUCT_TYPE NtProductType;
00138
00139 Peb = NtCurrentPeb();
00140 lpVersionInformation->dwMajorVersion = Peb->OSMajorVersion;
00141 lpVersionInformation->dwMinorVersion = Peb->OSMinorVersion;
00142 lpVersionInformation->dwBuildNumber = Peb->OSBuildNumber;
00143 lpVersionInformation->dwPlatformId = Peb->OSPlatformId;
00144
if (lpVersionInformation->dwOSVersionInfoSize ==
sizeof( OSVERSIONINFOEXW ))
00145 {
00146 ((POSVERSIONINFOEXW)lpVersionInformation)->wServicePackMajor = (Peb->OSCSDVersion >> 8) & 0xFF;
00147 ((POSVERSIONINFOEXW)lpVersionInformation)->wServicePackMinor = Peb->OSCSDVersion & 0xFF;
00148 ((POSVERSIONINFOEXW)lpVersionInformation)->wSuiteMask = (
USHORT)(USER_SHARED_DATA->SuiteMask&0xffff);
00149 ((POSVERSIONINFOEXW)lpVersionInformation)->wProductType = 0;
00150
if (
RtlGetNtProductType( &NtProductType )) {
00151 ((POSVERSIONINFOEXW)lpVersionInformation)->wProductType = (UCHAR)NtProductType;
00152 }
00153 }
00154
00155
return STATUS_SUCCESS;
00156 }
00157
#endif
00158
00159
00160 BOOLEAN
00161 RtlpVerCompare(
00162 LONG Condition,
00163 LONG Value1,
00164 LONG Value2,
00165 BOOLEAN *Equal,
00166
int Flags
00167 )
00168 {
00169
char String1[
MAX_STRING_LENGTH];
00170
char String2[
MAX_STRING_LENGTH];
00171 LONG Comparison;
00172
00173
if (Flags &
LEXICAL_COMPARISON) {
00174
sprintf(
String1,
"%d", Value1);
00175
sprintf(
String2,
"%d", Value2);
00176 Comparison = strcmp(
String2,
String1);
00177 Value1 = 0;
00178 Value2 = Comparison;
00179 }
00180 *Equal = (Value1 == Value2);
00181
switch (Condition) {
00182
case VER_EQUAL:
00183
return (Value2 == Value1);
00184
00185
case VER_GREATER:
00186
return (Value2 > Value1);
00187
00188
case VER_LESS:
00189
return (Value2 < Value1);
00190
00191
case VER_GREATER_EQUAL:
00192
return (Value2 >= Value1);
00193
00194
case VER_LESS_EQUAL:
00195
return (Value2 <= Value1);
00196
00197
default:
00198
break;
00199 }
00200
00201
return FALSE;
00202 }
00203
00204
00205
00206
NTSTATUS
00207 RtlVerifyVersionInfo(
00208 IN PRTL_OSVERSIONINFOEXW VersionInfo,
00209 IN ULONG TypeMask,
00210 IN ULONGLONG ConditionMask
00211 )
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 {
00235 ULONG i;
00236 OSVERSIONINFOEXW CurrVersion;
00237 BOOLEAN SuiteFound =
FALSE;
00238 BOOLEAN Equal;
00239
NTSTATUS Status;
00240 ULONG Condition;
00241
00242
00243
if (TypeMask == 0) {
00244
return STATUS_INVALID_PARAMETER;
00245 }
00246
00247 RtlZeroMemory( &CurrVersion,
sizeof(OSVERSIONINFOEXW) );
00248 CurrVersion.dwOSVersionInfoSize =
sizeof(OSVERSIONINFOEXW);
00249
00250
Status =
RtlGetVersion((PRTL_OSVERSIONINFOW)&CurrVersion);
00251
if (
Status != STATUS_SUCCESS)
00252
return Status;
00253
00254
if (VersionInfo->wSuiteMask != 0) {
00255
for (i=0; i<16; i++) {
00256
if (VersionInfo->wSuiteMask&(1<<i)) {
00257
switch (
RTL_GET_CONDITION(ConditionMask,VER_SUITENAME)) {
00258
case VER_AND:
00259
if (!(CurrVersion.wSuiteMask&(1<<i))) {
00260
return STATUS_REVISION_MISMATCH;
00261 }
00262
break;
00263
00264
case VER_OR:
00265
if (CurrVersion.wSuiteMask&(1<<i)) {
00266 SuiteFound =
TRUE;
00267 }
00268
break;
00269
00270
default:
00271
return STATUS_INVALID_PARAMETER;
00272 }
00273 }
00274 }
00275
if ((
RtlpVerGetConditionMask(ConditionMask,VER_SUITENAME) == VER_OR) && (SuiteFound ==
FALSE)) {
00276
return STATUS_REVISION_MISMATCH;
00277 }
00278 }
00279
00280 Equal =
TRUE;
00281 Condition = VER_EQUAL;
00282
if (TypeMask & VER_MAJORVERSION) {
00283 Condition =
RTL_GET_CONDITION( ConditionMask, VER_MAJORVERSION);
00284
if (
RtlpVerCompare(
00285 Condition,
00286 VersionInfo->dwMajorVersion,
00287 CurrVersion.dwMajorVersion,
00288 &Equal,
00289 0
00290 ) ==
FALSE)
00291 {
00292
if (!Equal) {
00293
return STATUS_REVISION_MISMATCH;
00294 }
00295 }
00296 }
00297
00298
if (Equal) {
00299
ASSERT(Condition);
00300
if (TypeMask & VER_MINORVERSION) {
00301
if (Condition == VER_EQUAL) {
00302 Condition =
RTL_GET_CONDITION(ConditionMask, VER_MINORVERSION);
00303 }
00304
if (
RtlpVerCompare(
00305 Condition,
00306 VersionInfo->dwMinorVersion,
00307 CurrVersion.dwMinorVersion,
00308 &Equal,
00309
LEXICAL_COMPARISON
00310 ) ==
FALSE)
00311 {
00312
if (!Equal) {
00313
return STATUS_REVISION_MISMATCH;
00314 }
00315 }
00316 }
00317
00318
if (Equal) {
00319
if (TypeMask & VER_SERVICEPACKMAJOR) {
00320
if (Condition == VER_EQUAL) {
00321 Condition =
RTL_GET_CONDITION(ConditionMask, VER_SERVICEPACKMAJOR);
00322 }
00323
if (
RtlpVerCompare(
00324 Condition,
00325 VersionInfo->wServicePackMajor,
00326 CurrVersion.wServicePackMajor,
00327 &Equal,
00328 0
00329 ) ==
FALSE)
00330 {
00331
if (!Equal) {
00332
return STATUS_REVISION_MISMATCH;
00333 }
00334 }
00335 }
00336
if (Equal) {
00337
if (TypeMask & VER_SERVICEPACKMINOR) {
00338
if (Condition == VER_EQUAL) {
00339 Condition =
RTL_GET_CONDITION(ConditionMask, VER_SERVICEPACKMINOR);
00340 }
00341
if (
RtlpVerCompare(
00342 Condition,
00343 (ULONG)VersionInfo->wServicePackMinor,
00344 (ULONG)CurrVersion.wServicePackMinor,
00345 &Equal,
00346
LEXICAL_COMPARISON
00347 ) ==
FALSE)
00348 {
00349
return STATUS_REVISION_MISMATCH;
00350 }
00351 }
00352 }
00353 }
00354 }
00355
00356
if ((TypeMask & VER_BUILDNUMBER) &&
00357
RtlpVerCompare(
00358
RTL_GET_CONDITION( ConditionMask, VER_BUILDNUMBER),
00359 VersionInfo->dwBuildNumber,
00360 CurrVersion.dwBuildNumber,
00361 &Equal,
00362 0
00363 ) ==
FALSE)
00364 {
00365
return STATUS_REVISION_MISMATCH;
00366 }
00367
00368
if ((TypeMask & VER_PLATFORMID) &&
00369
RtlpVerCompare(
00370
RTL_GET_CONDITION( ConditionMask, VER_PLATFORMID),
00371 VersionInfo->dwPlatformId,
00372 CurrVersion.dwPlatformId,
00373 &Equal,
00374 0
00375 ) ==
FALSE)
00376 {
00377
return STATUS_REVISION_MISMATCH;
00378 }
00379
00380
00381
if ((TypeMask & VER_PRODUCT_TYPE) &&
00382
RtlpVerCompare(
00383
RTL_GET_CONDITION( ConditionMask, VER_PRODUCT_TYPE),
00384 VersionInfo->wProductType,
00385 CurrVersion.wProductType,
00386 &Equal,
00387 0
00388 ) ==
FALSE)
00389 {
00390
return STATUS_REVISION_MISMATCH;
00391 }
00392
00393
return STATUS_SUCCESS;
00394 }
00395
00396 ULONG
00397 RtlpVerGetConditionMask(
00398 ULONGLONG ConditionMask,
00399 ULONG TypeMask
00400 )
00401 {
00402 ULONG NumBitsToShift;
00403 ULONG Condition = 0;
00404
00405
if (!TypeMask) {
00406
return 0;
00407 }
00408
00409
for (NumBitsToShift = 0; TypeMask; NumBitsToShift++) {
00410 TypeMask >>= 1;
00411 }
00412
00413 Condition |= (ConditionMask) >> ((NumBitsToShift - 1)
00414 * VER_NUM_BITS_PER_CONDITION_MASK);
00415 Condition &= VER_CONDITION_MASK;
00416
return Condition;
00417 }
00418
00419
00420 ULONGLONG
00421 VerSetConditionMask(
00422 ULONGLONG ConditionMask,
00423 ULONG TypeMask,
00424 UCHAR Condition
00425 )
00426 {
00427
int NumBitsToShift;
00428
00429 Condition &= VER_CONDITION_MASK;
00430
00431
if (!TypeMask) {
00432
return 0;
00433 }
00434
00435
for (NumBitsToShift = 0; TypeMask; NumBitsToShift++) {
00436 TypeMask >>= 1;
00437 }
00438
00439
00440
00441
00442 ConditionMask |=
NEW_STYLE_BIT_MASK;
00443 ConditionMask |= (Condition) << ((NumBitsToShift - 1)
00444 * VER_NUM_BITS_PER_CONDITION_MASK);
00445
00446
return ConditionMask;
00447 }