1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/version.c
5 * PURPOSE: Version functions
6 * PROGRAMMER: Ariadne (ariadne@xs4all.nl)
7 Ged Murphy (gedmurphy@reactos.org)
8 */
9
10 #include <k32.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /* FUNCTIONS ******************************************************************/
16
17 /*
18 * @implemented
19 */
20 DWORD
21 WINAPI
GetVersion(VOID)22 GetVersion(VOID)
23 {
24 PPEB Peb = NtCurrentPeb();
25
26 return (DWORD)( ((Peb->OSPlatformId ^ 2) << 30) |
27 (Peb->OSBuildNumber << 16) |
28 (Peb->OSMinorVersion << 8 ) |
29 Peb->OSMajorVersion );
30 }
31
32 /*
33 * @implemented
34 */
35 BOOL
36 WINAPI
GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)37 GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
38 {
39 NTSTATUS Status;
40 LPOSVERSIONINFOEXW lpVersionInformationEx;
41
42 if ((lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOW)) &&
43 (lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW)))
44 {
45 SetLastError(ERROR_INSUFFICIENT_BUFFER);
46 return FALSE;
47 }
48
49 Status = RtlGetVersion((PRTL_OSVERSIONINFOW)lpVersionInformation);
50 if (Status == STATUS_SUCCESS)
51 {
52 if (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXW))
53 {
54 lpVersionInformationEx = (PVOID)lpVersionInformation;
55 lpVersionInformationEx->wReserved = 0;
56 }
57
58 return TRUE;
59 }
60
61 return FALSE;
62 }
63
64 /*
65 * @implemented
66 */
67 BOOL
68 WINAPI
GetVersionExA(IN LPOSVERSIONINFOA lpVersionInformation)69 GetVersionExA(IN LPOSVERSIONINFOA lpVersionInformation)
70 {
71 OSVERSIONINFOEXW VersionInformation;
72 LPOSVERSIONINFOEXA lpVersionInformationEx;
73 UNICODE_STRING CsdVersionW;
74 NTSTATUS Status;
75 ANSI_STRING CsdVersionA;
76
77 if ((lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOA)) &&
78 (lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXA)))
79 {
80 SetLastError(ERROR_INSUFFICIENT_BUFFER);
81 return FALSE;
82 }
83
84 VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
85
86 if (!GetVersionExW((LPOSVERSIONINFOW)&VersionInformation)) return FALSE;
87
88 /* Copy back fields that match both supported structures */
89 lpVersionInformation->dwMajorVersion = VersionInformation.dwMajorVersion;
90 lpVersionInformation->dwMinorVersion = VersionInformation.dwMinorVersion;
91 lpVersionInformation->dwBuildNumber = VersionInformation.dwBuildNumber;
92 lpVersionInformation->dwPlatformId = VersionInformation.dwPlatformId;
93
94 if (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA))
95 {
96 lpVersionInformationEx = (PVOID)lpVersionInformation;
97 lpVersionInformationEx->wServicePackMajor = VersionInformation.wServicePackMajor;
98 lpVersionInformationEx->wServicePackMinor = VersionInformation.wServicePackMinor;
99 lpVersionInformationEx->wSuiteMask = VersionInformation.wSuiteMask;
100 lpVersionInformationEx->wProductType = VersionInformation.wProductType;
101 lpVersionInformationEx->wReserved = VersionInformation.wReserved;
102 }
103
104 /* Convert the CSD string */
105 RtlInitEmptyAnsiString(&CsdVersionA,
106 lpVersionInformation->szCSDVersion,
107 sizeof(lpVersionInformation->szCSDVersion));
108 RtlInitUnicodeString(&CsdVersionW, VersionInformation.szCSDVersion);
109 Status = RtlUnicodeStringToAnsiString(&CsdVersionA, &CsdVersionW, FALSE);
110 return (NT_SUCCESS(Status));
111 }
112
113 /*
114 * @implemented
115 */
116 BOOL
117 WINAPI
VerifyVersionInfoW(IN LPOSVERSIONINFOEXW lpVersionInformation,IN DWORD dwTypeMask,IN DWORDLONG dwlConditionMask)118 VerifyVersionInfoW(IN LPOSVERSIONINFOEXW lpVersionInformation,
119 IN DWORD dwTypeMask,
120 IN DWORDLONG dwlConditionMask)
121 {
122 NTSTATUS Status;
123
124 Status = RtlVerifyVersionInfo((PRTL_OSVERSIONINFOEXW)lpVersionInformation,
125 dwTypeMask,
126 dwlConditionMask);
127 switch (Status)
128 {
129 case STATUS_INVALID_PARAMETER:
130 SetLastError(ERROR_BAD_ARGUMENTS);
131 return FALSE;
132
133 case STATUS_REVISION_MISMATCH:
134 if (lpVersionInformation)
135 {
136 DPRINT1("VerifyVersionInfo -- Version mismatch(%d.%d.%d:%d)\n",
137 (dwTypeMask & VER_MAJORVERSION) ? lpVersionInformation->dwMajorVersion : -1,
138 (dwTypeMask & VER_MINORVERSION) ? lpVersionInformation->dwMinorVersion : -1,
139 (dwTypeMask & VER_BUILDNUMBER) ? lpVersionInformation->dwBuildNumber : -1,
140 (dwTypeMask & VER_PLATFORMID) ? lpVersionInformation->dwPlatformId : -1);
141 }
142 else
143 {
144 DPRINT1("VerifyVersionInfo -- Version mismatch(NULL)\n");
145 }
146 SetLastError(ERROR_OLD_WIN_VERSION);
147 return FALSE;
148
149 default:
150 /* RtlVerifyVersionInfo shouldn't report any other failure code! */
151 ASSERT(NT_SUCCESS(Status));
152 return TRUE;
153 }
154 }
155
156 /*
157 * @implemented
158 */
159 BOOL
160 WINAPI
VerifyVersionInfoA(IN LPOSVERSIONINFOEXA lpVersionInformation,IN DWORD dwTypeMask,IN DWORDLONG dwlConditionMask)161 VerifyVersionInfoA(IN LPOSVERSIONINFOEXA lpVersionInformation,
162 IN DWORD dwTypeMask,
163 IN DWORDLONG dwlConditionMask)
164 {
165 OSVERSIONINFOEXW viex;
166
167 /* NOTE: szCSDVersion is ignored, we don't need to convert it to Unicode */
168 viex.dwOSVersionInfoSize = sizeof(viex);
169 viex.dwMajorVersion = lpVersionInformation->dwMajorVersion;
170 viex.dwMinorVersion = lpVersionInformation->dwMinorVersion;
171 viex.dwBuildNumber = lpVersionInformation->dwBuildNumber;
172 viex.dwPlatformId = lpVersionInformation->dwPlatformId;
173 viex.wServicePackMajor = lpVersionInformation->wServicePackMajor;
174 viex.wServicePackMinor = lpVersionInformation->wServicePackMinor;
175 viex.wSuiteMask = lpVersionInformation->wSuiteMask;
176 viex.wProductType = lpVersionInformation->wProductType;
177 viex.wReserved = lpVersionInformation->wReserved;
178 return VerifyVersionInfoW(&viex, dwTypeMask, dwlConditionMask);
179 }
180