Sync with trunk r63743.
[reactos.git] / dll / ntdll / rtl / version.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/ntdll/rtl/process.c
5 * PURPOSE: Process functions
6 * PROGRAMMER: Ariadne (ariadne@xs4all.nl)
7 * UPDATE HISTORY:
8 * Created 01/11/98
9 */
10
11 /* INCLUDES *******************************************************************/
12
13 #include <ntdll.h>
14
15 #define NDEBUG
16 #include <debug.h>
17
18 /* FUNCTIONS ******************************************************************/
19
20 /* HACK: ReactOS specific changes, see bug-reports CORE-6611 and CORE-4620 (aka. #5003) */
21 static VOID NTAPI
22 SetRosSpecificInfo(IN OUT PRTL_OSVERSIONINFOEXW VersionInformation)
23 {
24 CHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
25 PKEY_VALUE_PARTIAL_INFORMATION kvpInfo = (PVOID)Buffer;
26 OBJECT_ATTRIBUTES ObjectAttributes;
27 ULONG ReportAsWorkstation = 0;
28 HANDLE hKey;
29 ULONG Length;
30 NTSTATUS Status;
31 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version");
32 UNICODE_STRING ValName = RTL_CONSTANT_STRING(L"ReportAsWorkstation");
33
34 InitializeObjectAttributes(&ObjectAttributes,
35 &KeyName,
36 OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
37 NULL,
38 NULL);
39
40 /* Don't change anything if the key doesn't exist */
41 Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
42 if (NT_SUCCESS(Status))
43 {
44 /* Get the value from the registry and make sure it's a 32-bit value */
45 Status = NtQueryValueKey(hKey,
46 &ValName,
47 KeyValuePartialInformation,
48 kvpInfo,
49 sizeof(Buffer),
50 &Length);
51 if (NT_SUCCESS(Status) &&
52 (kvpInfo->Type == REG_DWORD) &&
53 (kvpInfo->DataLength == sizeof(ULONG)))
54 {
55 /* Is the value set? */
56 ReportAsWorkstation = *(PULONG)kvpInfo->Data;
57 if ((VersionInformation->wProductType == VER_NT_SERVER) &&
58 (ReportAsWorkstation != 0))
59 {
60 /* It is, modify the product type to report a workstation */
61 VersionInformation->wProductType = VER_NT_WORKSTATION;
62 DPRINT1("We modified the reported OS from NtProductServer to NtProductWinNt\n");
63 }
64 }
65
66 /* Close the handle */
67 NtClose(hKey);
68 }
69 }
70
71 /**********************************************************************
72 * NAME EXPORTED
73 * RtlGetNtProductType
74 *
75 * DESCRIPTION
76 * Retrieves the OS product type.
77 *
78 * ARGUMENTS
79 * ProductType Pointer to the product type variable.
80 *
81 * RETURN VALUE
82 * TRUE if successful, otherwise FALSE
83 *
84 * NOTE
85 * ProductType can be one of the following values:
86 * 1 Workstation (WinNT)
87 * 2 Server (LanmanNT)
88 * 3 Advanced Server (ServerNT)
89 *
90 * REVISIONS
91 * 2000-08-10 ekohl
92 *
93 * @implemented
94 */
95 BOOLEAN NTAPI
96 RtlGetNtProductType(PNT_PRODUCT_TYPE ProductType)
97 {
98 *ProductType = SharedUserData->NtProductType;
99 return TRUE;
100 }
101
102 /**********************************************************************
103 * NAME EXPORTED
104 * RtlGetNtVersionNumbers
105 *
106 * DESCRIPTION
107 * Get the version numbers of the run time library.
108 *
109 * ARGUMENTS
110 * pdwMajorVersion [OUT] Destination for the Major version
111 * pdwMinorVersion [OUT] Destination for the Minor version
112 * pdwBuildNumber [OUT] Destination for the Build version
113 *
114 * RETURN VALUE
115 * Nothing.
116 *
117 * NOTES
118 * - Introduced in Windows XP (NT 5.1)
119 * - Since this call didn't exist before XP, we report at least the version
120 * 5.1. This fixes the loading of msvcrt.dll as released with XP Home,
121 * which fails in DLLMain() if the major version isn't 5.
122 *
123 * @implemented
124 */
125 VOID NTAPI
126 RtlGetNtVersionNumbers(OUT LPDWORD pdwMajorVersion,
127 OUT LPDWORD pdwMinorVersion,
128 OUT LPDWORD pdwBuildNumber)
129 {
130 PPEB pPeb = NtCurrentPeb();
131
132 if (pdwMajorVersion)
133 {
134 *pdwMajorVersion = pPeb->OSMajorVersion < 5 ? 5 : pPeb->OSMajorVersion;
135 }
136
137 if (pdwMinorVersion)
138 {
139 if ( (pPeb->OSMajorVersion < 5) ||
140 ((pPeb->OSMajorVersion == 5) && (pPeb->OSMinorVersion < 1)) )
141 *pdwMinorVersion = 1;
142 else
143 *pdwMinorVersion = pPeb->OSMinorVersion;
144 }
145
146 if (pdwBuildNumber)
147 {
148 /* Windows really does this! */
149 *pdwBuildNumber = (0xF0000000 | pPeb->OSBuildNumber);
150 }
151 }
152
153 /*
154 * @implemented
155 * @note User-mode version of RtlGetVersion in ntoskrnl/rtl/misc.c
156 */
157 NTSTATUS NTAPI
158 RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
159 {
160 LONG i, MaxLength;
161
162 if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOW) ||
163 lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
164 {
165 PPEB Peb = NtCurrentPeb();
166
167 lpVersionInformation->dwMajorVersion = Peb->OSMajorVersion;
168 lpVersionInformation->dwMinorVersion = Peb->OSMinorVersion;
169 lpVersionInformation->dwBuildNumber = Peb->OSBuildNumber;
170 lpVersionInformation->dwPlatformId = Peb->OSPlatformId;
171 RtlZeroMemory(lpVersionInformation->szCSDVersion, sizeof(lpVersionInformation->szCSDVersion));
172
173 if(((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
174 {
175 MaxLength = (sizeof(lpVersionInformation->szCSDVersion) / sizeof(lpVersionInformation->szCSDVersion[0])) - 1;
176 i = _snwprintf(lpVersionInformation->szCSDVersion,
177 MaxLength,
178 L"Service Pack %d",
179 ((Peb->OSCSDVersion >> 8) & 0xFF));
180 if (i < 0)
181 {
182 /* Null-terminate if it was overflowed */
183 lpVersionInformation->szCSDVersion[MaxLength] = L'\0';
184 }
185 }
186
187 if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
188 {
189 PRTL_OSVERSIONINFOEXW InfoEx = (PRTL_OSVERSIONINFOEXW)lpVersionInformation;
190 InfoEx->wServicePackMajor = (Peb->OSCSDVersion >> 8) & 0xFF;
191 InfoEx->wServicePackMinor = Peb->OSCSDVersion & 0xFF;
192 InfoEx->wSuiteMask = SharedUserData->SuiteMask & 0xFFFF;
193 InfoEx->wProductType = SharedUserData->NtProductType;
194 InfoEx->wReserved = 0;
195
196 /* HACK: ReactOS specific changes, see bug-reports CORE-6611 and CORE-4620 (aka. #5003) */
197 SetRosSpecificInfo(InfoEx);
198 }
199
200 return STATUS_SUCCESS;
201 }
202
203 return STATUS_INVALID_PARAMETER;
204 }
205
206 /* EOF */