Release 8.2.
[wine.git] / dlls / kernel32 / version.c
blobf64a393e4a3654158cc9deb78a3edcbf825dc48f
1 /*
2 * Windows and DOS version functions
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Patrik Stridvall
6 * Copyright 1998, 2003 Andreas Mohr
7 * Copyright 1997, 2003 Alexandre Julliard
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <string.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include "ntstatus.h"
29 #define WIN32_NO_STATUS
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "winuser.h"
34 #include "winternl.h"
35 #include "winerror.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ver);
41 static inline UCHAR version_update_condition(UCHAR *last_condition, UCHAR condition)
43 switch (*last_condition)
45 case 0:
46 *last_condition = condition;
47 break;
48 case VER_EQUAL:
49 if (condition >= VER_EQUAL && condition <= VER_LESS_EQUAL)
51 *last_condition = condition;
52 return condition;
54 break;
55 case VER_GREATER:
56 case VER_GREATER_EQUAL:
57 if (condition >= VER_EQUAL && condition <= VER_GREATER_EQUAL)
58 return condition;
59 break;
60 case VER_LESS:
61 case VER_LESS_EQUAL:
62 if (condition == VER_EQUAL || (condition >= VER_LESS && condition <= VER_LESS_EQUAL))
63 return condition;
64 break;
66 if (!condition) *last_condition |= 0x10;
67 return *last_condition & 0xf;
70 static inline BOOL version_compare_values(ULONG left, ULONG right, UCHAR condition)
72 switch (condition)
74 case VER_EQUAL:
75 if (left != right) return FALSE;
76 break;
77 case VER_GREATER:
78 if (left <= right) return FALSE;
79 break;
80 case VER_GREATER_EQUAL:
81 if (left < right) return FALSE;
82 break;
83 case VER_LESS:
84 if (left >= right) return FALSE;
85 break;
86 case VER_LESS_EQUAL:
87 if (left > right) return FALSE;
88 break;
89 default:
90 return FALSE;
92 return TRUE;
96 /******************************************************************************
97 * VerifyVersionInfoA (KERNEL32.@)
99 BOOL WINAPI VerifyVersionInfoA( LPOSVERSIONINFOEXA lpVersionInfo, DWORD dwTypeMask,
100 DWORDLONG dwlConditionMask)
102 OSVERSIONINFOEXW verW;
104 verW.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
105 verW.dwMajorVersion = lpVersionInfo->dwMajorVersion;
106 verW.dwMinorVersion = lpVersionInfo->dwMinorVersion;
107 verW.dwBuildNumber = lpVersionInfo->dwBuildNumber;
108 verW.dwPlatformId = lpVersionInfo->dwPlatformId;
109 verW.wServicePackMajor = lpVersionInfo->wServicePackMajor;
110 verW.wServicePackMinor = lpVersionInfo->wServicePackMinor;
111 verW.wSuiteMask = lpVersionInfo->wSuiteMask;
112 verW.wProductType = lpVersionInfo->wProductType;
113 verW.wReserved = lpVersionInfo->wReserved;
115 return VerifyVersionInfoW(&verW, dwTypeMask, dwlConditionMask);
119 /******************************************************************************
120 * VerifyVersionInfoW (KERNEL32.@)
122 BOOL WINAPI VerifyVersionInfoW( LPOSVERSIONINFOEXW info, DWORD dwTypeMask,
123 DWORDLONG dwlConditionMask)
125 OSVERSIONINFOEXW ver;
127 TRACE("(%p 0x%lx 0x%s)\n", info, dwTypeMask, wine_dbgstr_longlong(dwlConditionMask));
129 ver.dwOSVersionInfoSize = sizeof(ver);
130 if (!GetVersionExW((OSVERSIONINFOW*)&ver)) return FALSE;
132 if (!dwTypeMask || !dwlConditionMask)
134 SetLastError(ERROR_BAD_ARGUMENTS);
135 return FALSE;
138 if (dwTypeMask & VER_PRODUCT_TYPE)
140 if (!version_compare_values(ver.wProductType, info->wProductType, dwlConditionMask >> 7*3 & 0x07))
141 goto mismatch;
143 if (dwTypeMask & VER_SUITENAME)
144 switch (dwlConditionMask >> 6*3 & 0x07)
146 case VER_AND:
147 if ((info->wSuiteMask & ver.wSuiteMask) != info->wSuiteMask)
148 goto mismatch;
149 break;
150 case VER_OR:
151 if (!(info->wSuiteMask & ver.wSuiteMask) && info->wSuiteMask)
152 goto mismatch;
153 break;
154 default:
155 SetLastError(ERROR_BAD_ARGUMENTS);
156 return FALSE;
158 if (dwTypeMask & VER_PLATFORMID)
160 if (!version_compare_values(ver.dwPlatformId, info->dwPlatformId, dwlConditionMask >> 3*3 & 0x07))
161 goto mismatch;
163 if (dwTypeMask & VER_BUILDNUMBER)
165 if (!version_compare_values(ver.dwBuildNumber, info->dwBuildNumber, dwlConditionMask >> 2*3 & 0x07))
166 goto mismatch;
169 if (dwTypeMask & (VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR))
171 unsigned char condition, last_condition = 0;
172 BOOL succeeded = TRUE, do_next_check = TRUE;
174 if (dwTypeMask & VER_MAJORVERSION)
176 condition = version_update_condition(&last_condition, dwlConditionMask >> 1*3 & 0x07);
177 succeeded = version_compare_values(ver.dwMajorVersion, info->dwMajorVersion, condition);
178 do_next_check = (ver.dwMajorVersion == info->dwMajorVersion) &&
179 ((condition >= VER_EQUAL) && (condition <= VER_LESS_EQUAL));
181 if ((dwTypeMask & VER_MINORVERSION) && do_next_check)
183 condition = version_update_condition(&last_condition, dwlConditionMask >> 0*3 & 0x07);
184 succeeded = version_compare_values(ver.dwMinorVersion, info->dwMinorVersion, condition);
185 do_next_check = (ver.dwMinorVersion == info->dwMinorVersion) &&
186 ((condition >= VER_EQUAL) && (condition <= VER_LESS_EQUAL));
188 if ((dwTypeMask & VER_SERVICEPACKMAJOR) && do_next_check)
190 condition = version_update_condition(&last_condition, dwlConditionMask >> 5*3 & 0x07);
191 succeeded = version_compare_values(ver.wServicePackMajor, info->wServicePackMajor, condition);
192 do_next_check = (ver.wServicePackMajor == info->wServicePackMajor) &&
193 ((condition >= VER_EQUAL) && (condition <= VER_LESS_EQUAL));
195 if ((dwTypeMask & VER_SERVICEPACKMINOR) && do_next_check)
197 condition = version_update_condition(&last_condition, dwlConditionMask >> 4*3 & 0x07);
198 succeeded = version_compare_values(ver.wServicePackMinor, info->wServicePackMinor, condition);
201 if (!succeeded) goto mismatch;
204 return TRUE;
206 mismatch:
207 SetLastError(ERROR_OLD_WIN_VERSION);
208 return FALSE;
211 /***********************************************************************
212 * TermsrvAppInstallMode (KERNEL32.@)
214 * Find out whether the terminal server is in INSTALL or EXECUTE mode.
216 BOOL WINAPI TermsrvAppInstallMode(void)
218 FIXME("stub\n");
219 return FALSE;
222 /***********************************************************************
223 * SetTermsrvAppInstallMode (KERNEL32.@)
225 * This function is said to switch between the INSTALL (TRUE) or
226 * EXECUTE (FALSE) terminal server modes.
228 * This function always returns zero on WinXP Home so it's probably
229 * safe to return that value in most cases. However, if a terminal
230 * server is running it will probably return something else.
232 DWORD WINAPI SetTermsrvAppInstallMode(BOOL bInstallMode)
234 FIXME("(%d): stub\n", bInstallMode);
235 return 0;