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
)
60 RTL_OSVERSIONINFOEXW ver
;
64 - Check the following special case on Windows (various versions):
65 o lp->wSuiteMask == 0 and ver.wSuiteMask != 0 and VER_AND/VER_OR
66 o lp->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW)
67 - MSDN talks about some tests being impossible. Check what really happens.
70 ver
.dwOSVersionInfoSize
= sizeof(ver
);
71 Status
= RtlGetVersion((PRTL_OSVERSIONINFOW
)&ver
);
72 if (Status
!= STATUS_SUCCESS
) return Status
;
74 if (!TypeMask
|| !ConditionMask
) return STATUS_INVALID_PARAMETER
;
76 if (TypeMask
& VER_PRODUCT_TYPE
)
78 Comparison
= RtlpVerCompare(ver
.wProductType
,
79 VersionInfo
->wProductType
,
80 RtlpVerGetCondition(ConditionMask
, VER_PRODUCT_TYPE
));
82 return STATUS_REVISION_MISMATCH
;
85 if (TypeMask
& VER_SUITENAME
)
87 switch (RtlpVerGetCondition(ConditionMask
, VER_SUITENAME
))
90 if ((VersionInfo
->wSuiteMask
& ver
.wSuiteMask
) != VersionInfo
->wSuiteMask
)
92 return STATUS_REVISION_MISMATCH
;
96 if (!(VersionInfo
->wSuiteMask
& ver
.wSuiteMask
) && VersionInfo
->wSuiteMask
)
98 return STATUS_REVISION_MISMATCH
;
102 return STATUS_INVALID_PARAMETER
;
106 if (TypeMask
& VER_PLATFORMID
)
108 Comparison
= RtlpVerCompare(ver
.dwPlatformId
,
109 VersionInfo
->dwPlatformId
,
110 RtlpVerGetCondition(ConditionMask
, VER_PLATFORMID
));
112 return STATUS_REVISION_MISMATCH
;
115 if (TypeMask
& VER_BUILDNUMBER
)
117 Comparison
= RtlpVerCompare(ver
.dwBuildNumber
,
118 VersionInfo
->dwBuildNumber
,
119 RtlpVerGetCondition(ConditionMask
, VER_BUILDNUMBER
));
121 return STATUS_REVISION_MISMATCH
;
124 TypeMask
&= VER_MAJORVERSION
|VER_MINORVERSION
|VER_SERVICEPACKMAJOR
|VER_SERVICEPACKMINOR
;
127 BOOLEAN do_next_check
= TRUE
;
129 * Select the leading comparison operator (for example, the comparison
130 * operator for VER_MAJORVERSION supersedes the others for VER_MINORVERSION,
131 * VER_SERVICEPACKMAJOR and VER_SERVICEPACKMINOR).
133 UCHAR Condition
= RtlpVerGetCondition(ConditionMask
, TypeMask
);
136 if (TypeMask
& VER_MAJORVERSION
)
138 Comparison
= RtlpVerCompare(ver
.dwMajorVersion
,
139 VersionInfo
->dwMajorVersion
,
141 do_next_check
= (ver
.dwMajorVersion
== VersionInfo
->dwMajorVersion
) &&
142 ((Condition
!= VER_EQUAL
) || Comparison
);
144 if ((TypeMask
& VER_MINORVERSION
) && do_next_check
)
146 Comparison
= RtlpVerCompare(ver
.dwMinorVersion
,
147 VersionInfo
->dwMinorVersion
,
149 do_next_check
= (ver
.dwMinorVersion
== VersionInfo
->dwMinorVersion
) &&
150 ((Condition
!= VER_EQUAL
) || Comparison
);
152 if ((TypeMask
& VER_SERVICEPACKMAJOR
) && do_next_check
)
154 Comparison
= RtlpVerCompare(ver
.wServicePackMajor
,
155 VersionInfo
->wServicePackMajor
,
157 do_next_check
= (ver
.wServicePackMajor
== VersionInfo
->wServicePackMajor
) &&
158 ((Condition
!= VER_EQUAL
) || Comparison
);
160 if ((TypeMask
& VER_SERVICEPACKMINOR
) && do_next_check
)
162 Comparison
= RtlpVerCompare(ver
.wServicePackMinor
,
163 VersionInfo
->wServicePackMinor
,
168 return STATUS_REVISION_MISMATCH
;
171 return STATUS_SUCCESS
;
175 RtlpVerGetCondition(IN ULONGLONG ConditionMask
,
180 if (TypeMask
& VER_PRODUCT_TYPE
)
181 Condition
|= ConditionMask
>> (7 * VER_NUM_BITS_PER_CONDITION_MASK
);
182 else if (TypeMask
& VER_SUITENAME
)
183 Condition
|= ConditionMask
>> (6 * VER_NUM_BITS_PER_CONDITION_MASK
);
184 else if (TypeMask
& VER_PLATFORMID
)
185 Condition
|= ConditionMask
>> (3 * VER_NUM_BITS_PER_CONDITION_MASK
);
186 else if (TypeMask
& VER_BUILDNUMBER
)
187 Condition
|= ConditionMask
>> (2 * VER_NUM_BITS_PER_CONDITION_MASK
);
189 * We choose here the lexicographical order on the 4D space
190 * {(Major ; Minor ; SP Major ; SP Minor)} to select the
191 * appropriate comparison operator.
192 * Therefore the following 'else if' instructions must be in this order.
194 else if (TypeMask
& VER_MAJORVERSION
)
195 Condition
|= ConditionMask
>> (1 * VER_NUM_BITS_PER_CONDITION_MASK
);
196 else if (TypeMask
& VER_MINORVERSION
)
197 Condition
|= ConditionMask
>> (0 * VER_NUM_BITS_PER_CONDITION_MASK
);
198 else if (TypeMask
& VER_SERVICEPACKMAJOR
)
199 Condition
|= ConditionMask
>> (5 * VER_NUM_BITS_PER_CONDITION_MASK
);
200 else if (TypeMask
& VER_SERVICEPACKMINOR
)
201 Condition
|= ConditionMask
>> (4 * VER_NUM_BITS_PER_CONDITION_MASK
);
203 Condition
&= VER_CONDITION_MASK
;
213 VerSetConditionMask(IN ULONGLONG ConditionMask
,
217 ULONGLONG ullCondMask
;
220 return ConditionMask
;
222 Condition
&= VER_CONDITION_MASK
;
225 return ConditionMask
;
227 ullCondMask
= Condition
;
228 if (TypeMask
& VER_PRODUCT_TYPE
)
229 ConditionMask
|= ullCondMask
<< (7 * VER_NUM_BITS_PER_CONDITION_MASK
);
230 else if (TypeMask
& VER_SUITENAME
)
231 ConditionMask
|= ullCondMask
<< (6 * VER_NUM_BITS_PER_CONDITION_MASK
);
232 else if (TypeMask
& VER_SERVICEPACKMAJOR
)
233 ConditionMask
|= ullCondMask
<< (5 * VER_NUM_BITS_PER_CONDITION_MASK
);
234 else if (TypeMask
& VER_SERVICEPACKMINOR
)
235 ConditionMask
|= ullCondMask
<< (4 * VER_NUM_BITS_PER_CONDITION_MASK
);
236 else if (TypeMask
& VER_PLATFORMID
)
237 ConditionMask
|= ullCondMask
<< (3 * VER_NUM_BITS_PER_CONDITION_MASK
);
238 else if (TypeMask
& VER_BUILDNUMBER
)
239 ConditionMask
|= ullCondMask
<< (2 * VER_NUM_BITS_PER_CONDITION_MASK
);
240 else if (TypeMask
& VER_MAJORVERSION
)
241 ConditionMask
|= ullCondMask
<< (1 * VER_NUM_BITS_PER_CONDITION_MASK
);
242 else if (TypeMask
& VER_MINORVERSION
)
243 ConditionMask
|= ullCondMask
<< (0 * VER_NUM_BITS_PER_CONDITION_MASK
);
245 return ConditionMask
;