ReactOS  0.4.15-dev-321-g2d9b385
version.c
Go to the documentation of this file.
1 /*
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)
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include <rtl.h>
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* GLOBALS ******************************************************************/
18 
20 NTAPI
21 RtlGetVersion(OUT PRTL_OSVERSIONINFOW lpVersionInformation);
22 
23 /* FUNCTIONS ****************************************************************/
24 
25 static UCHAR
27  IN ULONG TypeMask);
28 
29 static BOOLEAN
31 {
32  switch (Condition)
33  {
34  case VER_EQUAL:
35  return (left == right);
36  case VER_GREATER:
37  return (left > right);
38  case VER_GREATER_EQUAL:
39  return (left >= right);
40  case VER_LESS:
41  return (left < right);
42  case VER_LESS_EQUAL:
43  return (left <= right);
44  default:
45  break;
46  }
47  return FALSE;
48 }
49 
50 /*
51 * @implemented
52 */
54 NTAPI
58 {
60  BOOLEAN Comparison;
61  BOOLEAN DoNextCheck;
64 
65  /* FIXME:
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.
70  */
71 
72  Version.dwOSVersionInfoSize = sizeof(Version);
73 
75  if (Status != STATUS_SUCCESS)
76  {
77  return Status;
78  }
79 
80  if (!TypeMask || !ConditionMask)
81  {
83  }
84 
86  {
87  Comparison = RtlpVerCompare(Version.wProductType,
88  VersionInfo->wProductType,
90  if (!Comparison)
91  {
93  }
94  }
95 
96  if (TypeMask & VER_SUITENAME)
97  {
99  {
100  case VER_AND:
101  {
102  if ((VersionInfo->wSuiteMask & Version.wSuiteMask) != VersionInfo->wSuiteMask)
103  {
105  }
106  }
107  break;
108 
109  case VER_OR:
110  {
111  if (!(VersionInfo->wSuiteMask & Version.wSuiteMask) && VersionInfo->wSuiteMask)
112  {
114  }
115  break;
116  }
117 
118  default:
119  {
121  }
122  }
123  }
124 
125  if (TypeMask & VER_PLATFORMID)
126  {
127  Comparison = RtlpVerCompare(Version.dwPlatformId,
128  VersionInfo->dwPlatformId,
130  if (!Comparison)
131  {
133  }
134  }
135 
137  {
138  Comparison = RtlpVerCompare(Version.dwBuildNumber,
139  VersionInfo->dwBuildNumber,
141  if (!Comparison)
142  {
144  }
145  }
146 
147  DoNextCheck = TRUE;
149 
151  {
153  DoNextCheck = (VersionInfo->dwMajorVersion == Version.dwMajorVersion);
154  Comparison = RtlpVerCompare(Version.dwMajorVersion,
155  VersionInfo->dwMajorVersion,
156  Condition);
157 
158  if (!Comparison && !DoNextCheck)
159  {
161  }
162  }
163 
164  if (DoNextCheck)
165  {
167  {
168  if (Condition == VER_EQUAL)
169  {
171  }
172 
173  DoNextCheck = (VersionInfo->dwMinorVersion == Version.dwMinorVersion);
174  Comparison = RtlpVerCompare(Version.dwMinorVersion,
175  VersionInfo->dwMinorVersion,
176  Condition);
177 
178  if (!Comparison && !DoNextCheck)
179  {
181  }
182  }
183 
184  if (DoNextCheck && (TypeMask & VER_SERVICEPACKMAJOR))
185  {
186  if (Condition == VER_EQUAL)
187  {
189  }
190 
191  DoNextCheck = (VersionInfo->wServicePackMajor == Version.wServicePackMajor);
192  Comparison = RtlpVerCompare(Version.wServicePackMajor,
193  VersionInfo->wServicePackMajor,
194  Condition);
195 
196  if (!Comparison && !DoNextCheck)
197  {
199  }
200 
201  if (DoNextCheck && (TypeMask & VER_SERVICEPACKMINOR))
202  {
203  if (Condition == VER_EQUAL)
204  {
206  }
207 
208  Comparison = RtlpVerCompare(Version.wServicePackMinor,
209  VersionInfo->wServicePackMinor,
210  Condition);
211 
212  if (!Comparison)
213  {
215  }
216  }
217  }
218  }
219 
220  return STATUS_SUCCESS;
221 }
222 
223 static UCHAR
225  IN ULONG TypeMask)
226 {
227  UCHAR Condition = 0;
228 
231  else if (TypeMask & VER_SUITENAME)
233  else if (TypeMask & VER_PLATFORMID)
235  else if (TypeMask & VER_BUILDNUMBER)
237  /*
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.
242  */
243  else if (TypeMask & VER_MAJORVERSION)
245  else if (TypeMask & VER_MINORVERSION)
247  else if (TypeMask & VER_SERVICEPACKMAJOR)
249  else if (TypeMask & VER_SERVICEPACKMINOR)
251 
253 
254  return Condition;
255 }
256 
257 /*
258  * @implemented
259  */
260 ULONGLONG
261 NTAPI
263  IN ULONG TypeMask,
265 {
266  ULONGLONG ullCondMask;
267 
268  if (TypeMask == 0)
269  return ConditionMask;
270 
272 
273  if (Condition == 0)
274  return ConditionMask;
275 
276  ullCondMask = Condition;
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);
293 
294  return ConditionMask;
295 }
296 
297 /* EOF */
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:311
#define VER_MINORVERSION
Definition: rtltypes.h:226
_In_ ULONG TypeMask
Definition: rtlfuncs.h:4510
#define IN
Definition: typedefs.h:39
#define VER_SUITENAME
Definition: rtltypes.h:232
#define VER_AND
Definition: rtltypes.h:242
#define TRUE
Definition: types.h:120
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:361
ULONGLONG NTAPI VerSetConditionMask(IN ULONGLONG ConditionMask, IN ULONG TypeMask, IN UCHAR Condition)
Definition: version.c:262
#define VER_BUILDNUMBER
Definition: rtltypes.h:228
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:158
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define VER_CONDITION_MASK
Definition: rtltypes.h:244
LONG NTSTATUS
Definition: precomp.h:26
#define VER_PRODUCT_TYPE
Definition: rtltypes.h:233
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
unsigned char BOOLEAN
#define VER_LESS_EQUAL
Definition: rtltypes.h:241
IN ULONG IN UCHAR Condition
#define VER_OR
Definition: rtltypes.h:243
#define VER_EQUAL
Definition: rtltypes.h:237
uint64_t ULONGLONG
Definition: typedefs.h:66
#define VER_PLATFORMID
Definition: rtltypes.h:229
#define VER_MAJORVERSION
Definition: rtltypes.h:227
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
static BOOLEAN RtlpVerCompare(ULONG left, ULONG right, UCHAR Condition)
Definition: version.c:30
static UCHAR RtlpVerGetCondition(IN ULONGLONG ConditionMask, IN ULONG TypeMask)
Definition: version.c:224
unsigned char UCHAR
Definition: xmlstorage.h:181
#define VER_SERVICEPACKMAJOR
Definition: rtltypes.h:231
#define VER_GREATER
Definition: rtltypes.h:238
Status
Definition: gdiplustypes.h:24
#define VER_GREATER_EQUAL
Definition: rtltypes.h:239
#define VER_NUM_BITS_PER_CONDITION_MASK
Definition: rtltypes.h:245
_In_ ULONG _In_ ULONGLONG ConditionMask
Definition: rtlfuncs.h:4510
#define VER_SERVICEPACKMINOR
Definition: rtltypes.h:230
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSTATUS NTAPI RtlVerifyVersionInfo(IN PRTL_OSVERSIONINFOEXW VersionInfo, IN ULONG TypeMask, IN ULONGLONG ConditionMask)
Definition: version.c:55
#define VER_LESS
Definition: rtltypes.h:240