xref: /reactos/dll/win32/kernel32/client/version.c (revision 50cf16b3)
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
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
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
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
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
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