xref: /reactos/dll/win32/kernel32/client/version.c (revision 527f2f90)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS system libraries
4  * FILE:            dll/win32/kernel32/misc/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             DPRINT1("ReactOS returning version mismatch. Investigate!\n");
135             SetLastError(ERROR_OLD_WIN_VERSION);
136             return FALSE;
137 
138         default:
139             /* RtlVerifyVersionInfo shouldn't report any other failure code! */
140             ASSERT(NT_SUCCESS(Status));
141             return TRUE;
142     }
143 }
144 
145 /*
146  * @implemented
147  */
148 BOOL
149 WINAPI
150 VerifyVersionInfoA(IN LPOSVERSIONINFOEXA lpVersionInformation,
151                    IN DWORD dwTypeMask,
152                    IN DWORDLONG dwlConditionMask)
153 {
154     OSVERSIONINFOEXW viex;
155 
156     /* NOTE: szCSDVersion is ignored, we don't need to convert it to Unicode */
157     viex.dwOSVersionInfoSize = sizeof(viex);
158     viex.dwMajorVersion = lpVersionInformation->dwMajorVersion;
159     viex.dwMinorVersion = lpVersionInformation->dwMinorVersion;
160     viex.dwBuildNumber = lpVersionInformation->dwBuildNumber;
161     viex.dwPlatformId = lpVersionInformation->dwPlatformId;
162     viex.wServicePackMajor = lpVersionInformation->wServicePackMajor;
163     viex.wServicePackMinor = lpVersionInformation->wServicePackMinor;
164     viex.wSuiteMask = lpVersionInformation->wSuiteMask;
165     viex.wProductType = lpVersionInformation->wProductType;
166     viex.wReserved = lpVersionInformation->wReserved;
167     return VerifyVersionInfoW(&viex, dwTypeMask, dwlConditionMask);
168 }
169