[FREELDR]
[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 done:
231 NtClose(EnvironmentKey);
232
233
234 /* Set the 'PROCESSOR_IDENTIFIER' system environment variable */
235 RtlInitUnicodeString(&Identifier, NULL);
236 RtlInitUnicodeString(&VendorIdentifier, NULL);
237
238 RtlZeroMemory(&QueryTable,
239 sizeof(QueryTable));
240
241 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
242 QueryTable[0].Name = L"Identifier";
243 QueryTable[0].EntryContext = &Identifier;
244
245 QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
246 QueryTable[1].Name = L"VendorIdentifier";
247 QueryTable[1].EntryContext = &VendorIdentifier;
248
249 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
250 L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0",
251 QueryTable,
252 NULL,
253 NULL);
254 if (NT_SUCCESS(Status))
255 {
256 DPRINT("SM: szIdentifier: %wZ\n", &Identifier);
257 DPRINT("SM: szVendorIdentifier: %wZ\n", &VendorIdentifier);
258
259 swprintf(Buffer, L"%wZ, %wZ", &Identifier, &VendorIdentifier);
260
261 RtlWriteRegistryValue(RTL_REGISTRY_CONTROL,
262 L"Session Manager\\Environment",
263 L"PROCESSOR_IDENTIFIER",
264 REG_SZ,
265 Buffer,
266 (wcslen(Buffer) + 1) * sizeof(WCHAR));
267 }
268
269 RtlFreeUnicodeString(&Identifier);
270 RtlFreeUnicodeString(&VendorIdentifier);
271
272 return STATUS_SUCCESS;
273 }
274
275
276 /**********************************************************************
277 * Set environment variables from registry
278 */
279 NTSTATUS
280 SmUpdateEnvironment(VOID)
281 {
282 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
283 WCHAR ValueBuffer[MAX_PATH];
284 NTSTATUS Status;
285
286 /*
287 * The following environment variables must be set prior to reading
288 * other variables from the registry.
289 *
290 * Variables (example):
291 * SystemRoot = "C:\reactos"
292 * SystemDrive = "C:"
293 */
294
295 /* Copy system root into value buffer */
296 wcscpy(ValueBuffer,
297 SharedUserData->NtSystemRoot);
298
299 /* Set SystemRoot = "C:\reactos" */
300 SmpSetEnvironmentVariable(&SmSystemEnvironment, L"SystemRoot", ValueBuffer);
301
302 /* Cut off trailing path */
303 ValueBuffer[2] = 0;
304
305 /* Set SystemDrive = "C:" */
306 SmpSetEnvironmentVariable(&SmSystemEnvironment, L"SystemDrive", ValueBuffer);
307
308 /* Read system environment from the registry. */
309 RtlZeroMemory(&QueryTable,
310 sizeof(QueryTable));
311
312 QueryTable[0].QueryRoutine = SmpEnvironmentQueryRoutine;
313
314 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
315 L"Session Manager\\Environment",
316 QueryTable,
317 &SmSystemEnvironment,
318 SmSystemEnvironment);
319
320 return Status;
321 }
322
323 /* EOF */