1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS system libraries
3 * PURPOSE: Runtime code
4 * FILE: lib/rtl/version.c
5 * PROGRAMER: Filip Navara
8 /* INCLUDES *****************************************************************/
15 /* GLOBALS ******************************************************************/
20 OUT PRTL_OSVERSIONINFOW lpVersionInformation
23 /* FUNCTIONS ****************************************************************/
25 static inline NTSTATUS
version_compare_values(ULONG left
, ULONG right
, UCHAR condition
)
29 if (left
!= right
) return STATUS_REVISION_MISMATCH
;
32 if (left
<= right
) return STATUS_REVISION_MISMATCH
;
34 case VER_GREATER_EQUAL
:
35 if (left
< right
) return STATUS_REVISION_MISMATCH
;
38 if (left
>= right
) return STATUS_REVISION_MISMATCH
;
41 if (left
> right
) return STATUS_REVISION_MISMATCH
;
44 return STATUS_REVISION_MISMATCH
;
46 return STATUS_SUCCESS
;
55 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 status
= version_compare_values(ver
.wProductType
, VersionInfo
->wProductType
, ConditionMask
>> 7 * VER_NUM_BITS_PER_CONDITION_MASK
& VER_CONDITION_MASK
);
79 if (status
!= STATUS_SUCCESS
)
82 if(TypeMask
& VER_SUITENAME
)
84 switch(ConditionMask
>> 6 * VER_NUM_BITS_PER_CONDITION_MASK
& VER_CONDITION_MASK
)
87 if((VersionInfo
->wSuiteMask
& ver
.wSuiteMask
) != VersionInfo
->wSuiteMask
)
88 return STATUS_REVISION_MISMATCH
;
91 if(!(VersionInfo
->wSuiteMask
& ver
.wSuiteMask
) && VersionInfo
->wSuiteMask
)
92 return STATUS_REVISION_MISMATCH
;
95 return STATUS_INVALID_PARAMETER
;
98 if(TypeMask
& VER_PLATFORMID
)
100 status
= version_compare_values(ver
.dwPlatformId
, VersionInfo
->dwPlatformId
, ConditionMask
>> 3 * VER_NUM_BITS_PER_CONDITION_MASK
& VER_CONDITION_MASK
);
101 if (status
!= STATUS_SUCCESS
)
104 if(TypeMask
& VER_BUILDNUMBER
)
106 status
= version_compare_values(ver
.dwBuildNumber
, VersionInfo
->dwBuildNumber
, ConditionMask
>> 2 * VER_NUM_BITS_PER_CONDITION_MASK
& VER_CONDITION_MASK
);
107 if (status
!= STATUS_SUCCESS
)
110 if(TypeMask
& (VER_MAJORVERSION
|VER_MINORVERSION
|VER_SERVICEPACKMAJOR
|VER_SERVICEPACKMINOR
))
112 unsigned char condition
= 0;
113 BOOLEAN do_next_check
= TRUE
;
115 if(TypeMask
& VER_MAJORVERSION
)
116 condition
= ConditionMask
>> 1 * VER_NUM_BITS_PER_CONDITION_MASK
& VER_CONDITION_MASK
;
117 else if(TypeMask
& VER_MINORVERSION
)
118 condition
= ConditionMask
>> 0 * VER_NUM_BITS_PER_CONDITION_MASK
& VER_CONDITION_MASK
;
119 else if(TypeMask
& VER_SERVICEPACKMAJOR
)
120 condition
= ConditionMask
>> 5 * VER_NUM_BITS_PER_CONDITION_MASK
& VER_CONDITION_MASK
;
121 else if(TypeMask
& VER_SERVICEPACKMINOR
)
122 condition
= ConditionMask
>> 4 * VER_NUM_BITS_PER_CONDITION_MASK
& VER_CONDITION_MASK
;
124 if(TypeMask
& VER_MAJORVERSION
)
126 status
= version_compare_values(ver
.dwMajorVersion
, VersionInfo
->dwMajorVersion
, condition
);
127 do_next_check
= (ver
.dwMajorVersion
== VersionInfo
->dwMajorVersion
) &&
128 ((condition
!= VER_EQUAL
) || (status
== STATUS_SUCCESS
));
130 if((TypeMask
& VER_MINORVERSION
) && do_next_check
)
132 status
= version_compare_values(ver
.dwMinorVersion
, VersionInfo
->dwMinorVersion
, condition
);
133 do_next_check
= (ver
.dwMinorVersion
== VersionInfo
->dwMinorVersion
) &&
134 ((condition
!= VER_EQUAL
) || (status
== STATUS_SUCCESS
));
136 if((TypeMask
& VER_SERVICEPACKMAJOR
) && do_next_check
)
138 status
= version_compare_values(ver
.wServicePackMajor
, VersionInfo
->wServicePackMajor
, condition
);
139 do_next_check
= (ver
.wServicePackMajor
== VersionInfo
->wServicePackMajor
) &&
140 ((condition
!= VER_EQUAL
) || (status
== STATUS_SUCCESS
));
142 if((TypeMask
& VER_SERVICEPACKMINOR
) && do_next_check
)
144 status
= version_compare_values(ver
.wServicePackMinor
, VersionInfo
->wServicePackMinor
, condition
);
147 if (status
!= STATUS_SUCCESS
)
151 return STATUS_SUCCESS
;
158 VerSetConditionMask(IN ULONGLONG dwlConditionMask
,
159 IN DWORD dwTypeBitMask
,
160 IN BYTE dwConditionMask
)
162 if(dwTypeBitMask
== 0)
163 return dwlConditionMask
;
165 dwConditionMask
&= VER_CONDITION_MASK
;
167 if(dwConditionMask
== 0)
168 return dwlConditionMask
;
170 if(dwTypeBitMask
& VER_PRODUCT_TYPE
)
171 dwlConditionMask
|= dwConditionMask
<< 7 * VER_NUM_BITS_PER_CONDITION_MASK
;
172 else if(dwTypeBitMask
& VER_SUITENAME
)
173 dwlConditionMask
|= dwConditionMask
<< 6 * VER_NUM_BITS_PER_CONDITION_MASK
;
174 else if(dwTypeBitMask
& VER_SERVICEPACKMAJOR
)
175 dwlConditionMask
|= dwConditionMask
<< 5 * VER_NUM_BITS_PER_CONDITION_MASK
;
176 else if(dwTypeBitMask
& VER_SERVICEPACKMINOR
)
177 dwlConditionMask
|= dwConditionMask
<< 4 * VER_NUM_BITS_PER_CONDITION_MASK
;
178 else if(dwTypeBitMask
& VER_PLATFORMID
)
179 dwlConditionMask
|= dwConditionMask
<< 3 * VER_NUM_BITS_PER_CONDITION_MASK
;
180 else if(dwTypeBitMask
& VER_BUILDNUMBER
)
181 dwlConditionMask
|= dwConditionMask
<< 2 * VER_NUM_BITS_PER_CONDITION_MASK
;
182 else if(dwTypeBitMask
& VER_MAJORVERSION
)
183 dwlConditionMask
|= dwConditionMask
<< 1 * VER_NUM_BITS_PER_CONDITION_MASK
;
184 else if(dwTypeBitMask
& VER_MINORVERSION
)
185 dwlConditionMask
|= dwConditionMask
<< 0 * VER_NUM_BITS_PER_CONDITION_MASK
;
187 return dwlConditionMask
;