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