[CMAKE]
[reactos.git] / base / system / smss / initenv.c
1 /*
2 * PROJECT: ReactOS Session Manager
3 * LICENSE: GPL v2 or later - See COPYING in the top level directory
4 * FILE: base/system/smss/initenv.c
5 * PURPOSE: Environment initialization.
6 * PROGRAMMERS: ReactOS Development Team
7 */
8
9 /* INCLUDES ******************************************************************/
10 #include "smss.h"
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS */
16
17 PWSTR SmSystemEnvironment = NULL;
18
19
20 /* FUNCTIONS */
21
22 NTSTATUS
23 SmCreateEnvironment(VOID)
24 {
25 return RtlCreateEnvironment(FALSE, &SmSystemEnvironment);
26 }
27
28
29 static NTSTATUS
30 SmpSetEnvironmentVariable(IN PVOID Context,
31 IN PWSTR ValueName,
32 IN PWSTR ValueData)
33 {
34 UNICODE_STRING EnvVariable;
35 UNICODE_STRING EnvValue;
36
37 RtlInitUnicodeString(&EnvVariable,
38 ValueName);
39 RtlInitUnicodeString(&EnvValue,
40 ValueData);
41 return RtlSetEnvironmentVariable(Context,
42 &EnvVariable,
43 &EnvValue);
44 }
45
46
47 static NTSTATUS NTAPI
48 SmpEnvironmentQueryRoutine(IN PWSTR ValueName,
49 IN ULONG ValueType,
50 IN PVOID ValueData,
51 IN ULONG ValueLength,
52 IN PVOID Context,
53 IN PVOID EntryContext)
54 {
55 DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
56
57 if (ValueType != REG_SZ && ValueType != REG_EXPAND_SZ)
58 return STATUS_SUCCESS;
59
60 DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
61 return SmpSetEnvironmentVariable(Context,ValueName,(PWSTR)ValueData);
62 }
63
64
65 NTSTATUS
66 SmSetEnvironmentVariables(VOID)
67 {
68 SYSTEM_BASIC_INFORMATION BasicInformation;
69 SYSTEM_PROCESSOR_INFORMATION ProcessorInformation;
70 RTL_QUERY_REGISTRY_TABLE QueryTable[3];
71 UNICODE_STRING Identifier;
72 UNICODE_STRING VendorIdentifier;
73 WCHAR Buffer[256];
74 UNICODE_STRING EnvironmentKeyName;
75 OBJECT_ATTRIBUTES ObjectAttributes;
76 HANDLE EnvironmentKey;
77 UNICODE_STRING VariableName;
78 PWSTR VariableData;
79 NTSTATUS Status;
80
81 Status = NtQuerySystemInformation(SystemProcessorInformation,
82 &ProcessorInformation,
83 sizeof(SYSTEM_PROCESSOR_INFORMATION),
84 NULL);
85 if (!NT_SUCCESS(Status))
86 {
87 DPRINT1("SM: Failed to retrieve system processor information (Status %08lx)", Status);
88 return Status;
89 }
90
91 Status = NtQuerySystemInformation(SystemBasicInformation,
92 &BasicInformation,
93 sizeof(SYSTEM_BASIC_INFORMATION),
94 NULL);
95 if (!NT_SUCCESS(Status))
96 {
97 DPRINT1("SM: Failed to retrieve system basic information (Status %08lx)", Status);
98 return Status;
99 }
100
101 RtlInitUnicodeString(&EnvironmentKeyName,
102 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Environment");
103 InitializeObjectAttributes(&ObjectAttributes,
104 &EnvironmentKeyName,
105 OBJ_CASE_INSENSITIVE,
106 NULL,
107 NULL);
108
109 /* Open the system environment key */
110 Status = NtOpenKey(&EnvironmentKey,
111 GENERIC_WRITE,
112 &ObjectAttributes);
113 if (!NT_SUCCESS(Status))
114 {
115 DPRINT1("SM: Failed to open the environment key (Status %08lx)", Status);
116 return Status;
117 }
118
119 /* Set the 'NUMBER_OF_PROCESSORS' system environment variable */
120 RtlInitUnicodeString(&VariableName,
121 L"NUMBER_OF_PROCESSORS");
122
123 swprintf(Buffer, L"%lu", BasicInformation.NumberOfProcessors);
124
125 Status = NtSetValueKey(EnvironmentKey,
126 &VariableName,
127 0,
128 REG_SZ,
129 Buffer,
130 (wcslen(Buffer) + 1) * sizeof(WCHAR));
131 if (!NT_SUCCESS(Status))
132 {
133 DPRINT1("SM: Failed to set the NUMBER_OF_PROCESSORS environment variable (Status %08lx)", Status);
134 goto done;
135 }
136
137 /* Set the 'OS' system environment variable */
138 RtlInitUnicodeString(&VariableName,
139 L"OS");
140
141 VariableData = L"ReactOS";
142
143 Status = NtSetValueKey(EnvironmentKey,
144 &VariableName,
145 0,
146 REG_SZ,
147 VariableData,
148 (wcslen(VariableData) + 1) * sizeof(WCHAR));
149 if (!NT_SUCCESS(Status))
150 {
151 DPRINT1("SM: Failed to set the OS environment variable (Status %08lx)", Status);
152 goto done;
153 }
154
155 /* Set the 'PROCESSOR_ARCHITECTURE' system environment variable */
156 RtlInitUnicodeString(&VariableName,
157 L"PROCESSOR_ARCHITECTURE");
158
159 switch (ProcessorInformation.ProcessorArchitecture)
160 {
161 case PROCESSOR_ARCHITECTURE_INTEL:
162 VariableData = L"x86";
163 break;
164
165 case PROCESSOR_ARCHITECTURE_PPC:
166 VariableData = L"PPC";
167 break;
168
169 case PROCESSOR_ARCHITECTURE_ARM:
170 VariableData = L"ARM";
171 break;
172
173 case PROCESSOR_ARCHITECTURE_AMD64:
174 VariableData = L"AMD64";
175 break;
176
177 default:
178 VariableData = L"Unknown";
179 break;
180 }
181
182 Status = NtSetValueKey(EnvironmentKey,
183 &VariableName,
184 0,
185 REG_SZ,
186 VariableData,
187 (wcslen(VariableData) + 1) * sizeof(WCHAR));
188 if (!NT_SUCCESS(Status))
189 {
190 DPRINT1("SM: Failed to set the PROCESSOR_ARCHITECTURE environment variable (Status %08lx)", Status);
191 goto done;
192 }
193
194 /* Set the 'PROCESSOR_LEVEL' system environment variable */
195 RtlInitUnicodeString(&VariableName,
196 L"PROCESSOR_LEVEL");
197
198 swprintf(Buffer, L"%lu", ProcessorInformation.ProcessorLevel);
199
200 Status = NtSetValueKey(EnvironmentKey,
201 &VariableName,
202 0,
203 REG_SZ,
204 Buffer,
205 (wcslen(Buffer) + 1) * sizeof(WCHAR));
206 if (!NT_SUCCESS(Status))
207 {
208 DPRINT1("SM: Failed to set the PROCESSOR_LEVEL environment variable (Status %08lx)", Status);
209 goto done;
210 }
211
212 /* Set the 'PROCESSOR_REVISION' system environment variable */
213 RtlInitUnicodeString(&VariableName,
214 L"PROCESSOR_REVISION");
215
216 swprintf(Buffer, L"%04x", ProcessorInformation.ProcessorRevision);
217
218 Status = NtSetValueKey(EnvironmentKey,
219 &VariableName,
220 0,
221 REG_SZ,
222 Buffer,
223 (wcslen(Buffer) + 1) * sizeof(WCHAR));
224 if (!NT_SUCCESS(Status))
225 {
226 DPRINT1("SM: Failed to set the PROCESSOR_REVISION environment variable (Status %08lx)", Status);
227 goto done;
228 }
229
230 /* Set the 'PROCESSOR_IDENTIFIER' system environment variable */
231 RtlInitUnicodeString(&Identifier, NULL);
232 RtlInitUnicodeString(&VendorIdentifier, NULL);
233
234 RtlZeroMemory(&QueryTable,
235 sizeof(QueryTable));
236
237 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
238 QueryTable[0].Name = L"Identifier";
239 QueryTable[0].EntryContext = &Identifier;
240
241 QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
242 QueryTable[1].Name = L"VendorIdentifier";
243 QueryTable[1].EntryContext = &VendorIdentifier;
244
245 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
246 L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0",
247 QueryTable,
248 NULL,
249 NULL);
250 if (!NT_SUCCESS(Status))
251 {
252 DPRINT1("SM: Failed to retrieve processor Identifier and/or VendorIdentifier (Status %08lx)", Status);
253 goto done;
254 }
255
256 DPRINT("SM: szIdentifier: %wZ\n" , &Identifier);
257 DPRINT("SM: szVendorIdentifier: %wZ\n", &VendorIdentifier);
258
259 RtlInitUnicodeString(&VariableName, L"PROCESSOR_IDENTIFIER");
260 swprintf(Buffer, L"%wZ, %wZ", &Identifier, &VendorIdentifier);
261 RtlFreeUnicodeString(&VendorIdentifier);
262 RtlFreeUnicodeString(&Identifier);
263
264 Status = NtSetValueKey(EnvironmentKey,
265 &VariableName,
266 0,
267 REG_SZ,
268 Buffer,
269 (wcslen(Buffer) + 1) * sizeof(WCHAR));
270 if (!NT_SUCCESS(Status))
271 {
272 DPRINT1("SM: Failed to set the PROCESSOR_IDENTIFIER environment variable (Status %08lx)", Status);
273 goto done;
274 }
275
276 done:
277 /* Close the handle */
278 NtClose(EnvironmentKey);
279
280 return Status;
281 }
282
283
284 /**********************************************************************
285 * Set environment variables from registry
286 */
287 NTSTATUS
288 SmUpdateEnvironment(VOID)
289 {
290 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
291 WCHAR ValueBuffer[MAX_PATH];
292 NTSTATUS Status;
293 #ifndef NDEBUG
294 ULONG ii;
295 PWSTR envp;
296 #endif
297
298 /*
299 * The following environment variables must be set prior to reading
300 * other variables from the registry.
301 *
302 * Variables (example):
303 * SystemRoot = "C:\reactos"
304 * SystemDrive = "C:"
305 */
306
307 /* Copy system root into value buffer */
308 wcscpy(ValueBuffer,
309 SharedUserData->NtSystemRoot);
310
311 /* Set SystemRoot = "C:\reactos" */
312 SmpSetEnvironmentVariable(&SmSystemEnvironment, L"SystemRoot", ValueBuffer);
313
314 /* Cut off trailing path */
315 ValueBuffer[2] = 0;
316
317 /* Set SystemDrive = "C:" */
318 SmpSetEnvironmentVariable(&SmSystemEnvironment, L"SystemDrive", ValueBuffer);
319
320 /* Read system environment from the registry. */
321 RtlZeroMemory(&QueryTable,
322 sizeof(QueryTable));
323
324 QueryTable[0].QueryRoutine = SmpEnvironmentQueryRoutine;
325
326 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
327 L"Session Manager\\Environment",
328 QueryTable,
329 &SmSystemEnvironment,
330 SmSystemEnvironment);
331
332 #ifndef NDEBUG
333 /* Print all environment varaibles */
334 ii = 0;
335 envp = SmSystemEnvironment;
336 DbgPrint("SmUpdateEnvironment:\n");
337 while (*envp)
338 {
339 DbgPrint(" %u: %S\n", ii++, envp);
340 envp += wcslen(envp) + 1;
341 }
342 #endif
343
344 return Status;
345 }
346
347 /* EOF */