Reactos
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 */
20DWORD
21WINAPI
22GetVersion(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 */
35BOOL
36WINAPI
37GetVersionExW(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 */
67BOOL
68WINAPI
69GetVersionExA(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 */
116BOOL
117WINAPI
118VerifyVersionInfoW(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}