2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Runtime code
5 * FILE: lib/rtl/version.c
6 * PROGRAMERS: Filip Navara
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
10 /* INCLUDES *****************************************************************/
17 /* GLOBALS ******************************************************************/
21 RtlGetVersion(OUT PRTL_OSVERSIONINFOW lpVersionInformation
);
23 /* FUNCTIONS ****************************************************************/
26 RtlpVerGetCondition(IN ULONGLONG ConditionMask
,
30 RtlpVerCompare(ULONG left
, ULONG right
, UCHAR Condition
)
35 return (left
== right
);
37 return (left
> right
);
38 case VER_GREATER_EQUAL
:
39 return (left
>= right
);
41 return (left
< right
);
43 return (left
<= right
);
55 RtlVerifyVersionInfo(IN PRTL_OSVERSIONINFOEXW VersionInfo
,
57 IN ULONGLONG ConditionMask
)
59 RTL_OSVERSIONINFOEXW Version
;
66 - Check the following special case on Windows (various versions):
67 o lp->wSuiteMask == 0 and ver.wSuiteMask != 0 and VER_AND/VER_OR
68 o lp->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW)
69 - MSDN talks about some tests being impossible. Check what really happens.
72 Version
.dwOSVersionInfoSize
= sizeof(Version
);
74 Status
= RtlGetVersion((PRTL_OSVERSIONINFOW
)&Version
);
75 if (Status
!= STATUS_SUCCESS
)
80 if (!TypeMask
|| !ConditionMask
)
82 return STATUS_INVALID_PARAMETER
;
85 if (TypeMask
& VER_PRODUCT_TYPE
)
87 Comparison
= RtlpVerCompare(Version
.wProductType
,
88 VersionInfo
->wProductType
,
89 RtlpVerGetCondition(ConditionMask
, VER_PRODUCT_TYPE
));
92 return STATUS_REVISION_MISMATCH
;
96 if (TypeMask
& VER_SUITENAME
)
98 switch (RtlpVerGetCondition(ConditionMask
, VER_SUITENAME
))
102 if ((VersionInfo
->wSuiteMask
& Version
.wSuiteMask
) != VersionInfo
->wSuiteMask
)
104 return STATUS_REVISION_MISMATCH
;
111 if (!(VersionInfo
->wSuiteMask
& Version
.wSuiteMask
) && VersionInfo
->wSuiteMask
)
113 return STATUS_REVISION_MISMATCH
;
120 return STATUS_INVALID_PARAMETER
;
125 if (TypeMask
& VER_PLATFORMID
)
127 Comparison
= RtlpVerCompare(Version
.dwPlatformId
,
128 VersionInfo
->dwPlatformId
,
129 RtlpVerGetCondition(ConditionMask
, VER_PLATFORMID
));
132 return STATUS_REVISION_MISMATCH
;
136 if (TypeMask
& VER_BUILDNUMBER
)
138 Comparison
= RtlpVerCompare(Version
.dwBuildNumber
,
139 VersionInfo
->dwBuildNumber
,
140 RtlpVerGetCondition(ConditionMask
, VER_BUILDNUMBER
));
143 return STATUS_REVISION_MISMATCH
;
148 Condition
= VER_EQUAL
;
150 if (TypeMask
& VER_MAJORVERSION
)
152 Condition
= RtlpVerGetCondition(ConditionMask
, VER_MAJORVERSION
);
153 DoNextCheck
= (VersionInfo
->dwMajorVersion
== Version
.dwMajorVersion
);
154 Comparison
= RtlpVerCompare(Version
.dwMajorVersion
,
155 VersionInfo
->dwMajorVersion
,
158 if (!Comparison
&& !DoNextCheck
)
160 return STATUS_REVISION_MISMATCH
;
166 if (TypeMask
& VER_MINORVERSION
)
168 if (Condition
== VER_EQUAL
)
170 Condition
= RtlpVerGetCondition(ConditionMask
, VER_MINORVERSION
);
173 DoNextCheck
= (VersionInfo
->dwMinorVersion
== Version
.dwMinorVersion
);
174 Comparison
= RtlpVerCompare(Version
.dwMinorVersion
,
175 VersionInfo
->dwMinorVersion
,
178 if (!Comparison
&& !DoNextCheck
)
180 return STATUS_REVISION_MISMATCH
;
184 if (DoNextCheck
&& (TypeMask
& VER_SERVICEPACKMAJOR
))
186 if (Condition
== VER_EQUAL
)
188 Condition
= RtlpVerGetCondition(ConditionMask
, VER_SERVICEPACKMAJOR
);
191 DoNextCheck
= (VersionInfo
->wServicePackMajor
== Version
.wServicePackMajor
);
192 Comparison
= RtlpVerCompare(Version
.wServicePackMajor
,
193 VersionInfo
->wServicePackMajor
,
196 if (!Comparison
&& !DoNextCheck
)
198 return STATUS_REVISION_MISMATCH
;
201 if (DoNextCheck
&& (TypeMask
& VER_SERVICEPACKMINOR
))
203 if (Condition
== VER_EQUAL
)
205 Condition
= RtlpVerGetCondition(ConditionMask
, VER_SERVICEPACKMINOR
);
208 Comparison
= RtlpVerCompare((ULONG
)Version
.wServicePackMinor
,
209 (ULONG
)VersionInfo
->wServicePackMinor
,
214 return STATUS_REVISION_MISMATCH
;
220 return STATUS_SUCCESS
;
224 RtlpVerGetCondition(IN ULONGLONG ConditionMask
,
229 if (TypeMask
& VER_PRODUCT_TYPE
)
230 Condition
|= ConditionMask
>> (7 * VER_NUM_BITS_PER_CONDITION_MASK
);
231 else if (TypeMask
& VER_SUITENAME
)
232 Condition
|= ConditionMask
>> (6 * VER_NUM_BITS_PER_CONDITION_MASK
);
233 else if (TypeMask
& VER_PLATFORMID
)
234 Condition
|= ConditionMask
>> (3 * VER_NUM_BITS_PER_CONDITION_MASK
);
235 else if (TypeMask
& VER_BUILDNUMBER
)
236 Condition
|= ConditionMask
>> (2 * VER_NUM_BITS_PER_CONDITION_MASK
);
238 * We choose here the lexicographical order on the 4D space
239 * {(Major ; Minor ; SP Major ; SP Minor)} to select the
240 * appropriate comparison operator.
241 * Therefore the following 'else if' instructions must be in this order.
243 else if (TypeMask
& VER_MAJORVERSION
)
244 Condition
|= ConditionMask
>> (1 * VER_NUM_BITS_PER_CONDITION_MASK
);
245 else if (TypeMask
& VER_MINORVERSION
)
246 Condition
|= ConditionMask
>> (0 * VER_NUM_BITS_PER_CONDITION_MASK
);
247 else if (TypeMask
& VER_SERVICEPACKMAJOR
)
248 Condition
|= ConditionMask
>> (5 * VER_NUM_BITS_PER_CONDITION_MASK
);
249 else if (TypeMask
& VER_SERVICEPACKMINOR
)
250 Condition
|= ConditionMask
>> (4 * VER_NUM_BITS_PER_CONDITION_MASK
);
252 Condition
&= VER_CONDITION_MASK
;
262 VerSetConditionMask(IN ULONGLONG ConditionMask
,
266 ULONGLONG ullCondMask
;
269 return ConditionMask
;
271 Condition
&= VER_CONDITION_MASK
;
274 return ConditionMask
;
276 ullCondMask
= Condition
;
277 if (TypeMask
& VER_PRODUCT_TYPE
)
278 ConditionMask
|= ullCondMask
<< (7 * VER_NUM_BITS_PER_CONDITION_MASK
);
279 else if (TypeMask
& VER_SUITENAME
)
280 ConditionMask
|= ullCondMask
<< (6 * VER_NUM_BITS_PER_CONDITION_MASK
);
281 else if (TypeMask
& VER_SERVICEPACKMAJOR
)
282 ConditionMask
|= ullCondMask
<< (5 * VER_NUM_BITS_PER_CONDITION_MASK
);
283 else if (TypeMask
& VER_SERVICEPACKMINOR
)
284 ConditionMask
|= ullCondMask
<< (4 * VER_NUM_BITS_PER_CONDITION_MASK
);
285 else if (TypeMask
& VER_PLATFORMID
)
286 ConditionMask
|= ullCondMask
<< (3 * VER_NUM_BITS_PER_CONDITION_MASK
);
287 else if (TypeMask
& VER_BUILDNUMBER
)
288 ConditionMask
|= ullCondMask
<< (2 * VER_NUM_BITS_PER_CONDITION_MASK
);
289 else if (TypeMask
& VER_MAJORVERSION
)
290 ConditionMask
|= ullCondMask
<< (1 * VER_NUM_BITS_PER_CONDITION_MASK
);
291 else if (TypeMask
& VER_MINORVERSION
)
292 ConditionMask
|= ullCondMask
<< (0 * VER_NUM_BITS_PER_CONDITION_MASK
);
294 return ConditionMask
;