6580b4b6716e0a6146e33d8612d1f6be4d5096b1
[reactos.git] / reactos / 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
70 RTL_QUERY_REGISTRY_TABLE QueryTable[3];
71 UNICODE_STRING Identifier;
72 UNICODE_STRING VendorIdentifier;
73 WCHAR Buffer[256];
74
75 UNICODE_STRING EnvironmentKeyName;
76 OBJECT_ATTRIBUTES ObjectAttributes;
77 HANDLE EnvironmentKey;
78 UNICODE_STRING VariableName;
79 PWSTR VariableData;
80
81 NTSTATUS Status;
82
83
84 Status = NtQuerySystemInformation(SystemBasicInformation,
85 &BasicInformation,
86 sizeof(SYSTEM_BASIC_INFORMATION),
87 NULL);
88 if (!NT_SUCCESS(Status))
89 {
90 DPRINT1("SM: Failed to retrieve system basic information (Status %08lx)", Status);
91 return Status;
92 }
93
94 RtlInitUnicodeString(&EnvironmentKeyName,
95 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Environment");
96 InitializeObjectAttributes(&ObjectAttributes,
97 &EnvironmentKeyName,
98 OBJ_CASE_INSENSITIVE,
99 NULL,
100 NULL);
101
102 /* Open the system environment key */
103 Status = NtOpenKey(&EnvironmentKey,
104 GENERIC_WRITE,
105 &ObjectAttributes);
106 if (!NT_SUCCESS(Status))
107 {
108 DPRINT1("SM: Failed to open the environment key (Status %08lx)", Status);
109 return Status;
110 }
111
112 /* Set the 'NUMBER_OF_PROCESSORS' system environment variable */
113 RtlInitUnicodeString(&VariableName,
114 L"NUMBER_OF_PROCESSORS");
115
116 swprintf(Buffer, L"%lu", BasicInformation.NumberOfProcessors);
117
118 Status = NtSetValueKey(EnvironmentKey,
119 &VariableName,
120 0,
121 REG_SZ,
122 Buffer,
123 (wcslen(Buffer) + 1) * sizeof(WCHAR));
124 if (!NT_SUCCESS(Status))
125 {
126 DPRINT1("SM: Failed to set the NUMBER_OF_PROCESSORS environment variable (Status %08lx)", Status);
127 goto done;
128 }
129
130 /* Set the 'OS' system environment variable */
131 RtlInitUnicodeString(&VariableName,
132 L"OS");
133
134 VariableData = L"ReactOS";
135
136 Status = NtSetValueKey(EnvironmentKey,
137 &VariableName,
138 0,
139 REG_SZ,
140 VariableData,
141 (wcslen(VariableData) + 1) * sizeof(WCHAR));
142 if (!NT_SUCCESS(Status))
143 {
144 DPRINT1("SM: Failed to set the OS environment variable (Status %08lx)", Status);
145 goto done;
146 }
147
148 /* Set the 'PROCESSOR_ARCHITECTURE' system environment variable */
149 RtlInitUnicodeString(&VariableName,
150 L"PROCESSOR_ARCHITECTURE");
151
152 #ifdef _M_IX86
153 VariableData = L"x86";
154 #elif _M_MD64
155 VariableData = L"AMD64";
156 #elif _M_ARM
157 VariableData = L"ARM";
158 #elif _M_PPC
159 VariableData = L"PPC";
160 #else
161 #error "Unsupported Architecture!\n"
162 #endif
163
164 Status = NtSetValueKey(EnvironmentKey,
165 &VariableName,
166 0,
167 REG_SZ,
168 VariableData,
169 (wcslen(VariableData) + 1) * sizeof(WCHAR));
170 if (!NT_SUCCESS(Status))
171 {
172 DPRINT1("SM: Failed to set the PROCESSOR_ARCHITECTURE environment variable (Status %08lx)", Status);
173 goto done;
174 }
175
176 done:
177 NtClose(EnvironmentKey);
178
179
180 /* Set the 'PROCESSOR_IDENTIFIER' system environment variable */
181 RtlInitUnicodeString(&Identifier, NULL);
182 RtlInitUnicodeString(&VendorIdentifier, NULL);
183
184 RtlZeroMemory(&QueryTable,
185 sizeof(QueryTable));
186
187 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
188 QueryTable[0].Name = L"Identifier";
189 QueryTable[0].EntryContext = &Identifier;
190
191 QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
192 QueryTable[1].Name = L"VendorIdentifier";
193 QueryTable[1].EntryContext = &VendorIdentifier;
194
195 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
196 L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0",
197 QueryTable,
198 NULL,
199 NULL);
200 if (NT_SUCCESS(Status))
201 {
202 DPRINT("SM: szIdentifier: %wZ\n", &Identifier);
203 DPRINT("SM: szVendorIdentifier: %wZ\n", &VendorIdentifier);
204
205 swprintf(Buffer, L"%wZ, %wZ", &Identifier, &VendorIdentifier);
206
207 RtlWriteRegistryValue(RTL_REGISTRY_CONTROL,
208 L"Session Manager\\Environment",
209 L"PROCESSOR_IDENTIFIER",
210 REG_SZ,
211 Buffer,
212 (wcslen(Buffer) + 1) * sizeof(WCHAR));
213 }
214
215 RtlFreeUnicodeString(&Identifier);
216 RtlFreeUnicodeString(&VendorIdentifier);
217
218 return STATUS_SUCCESS;
219 }
220
221
222 /**********************************************************************
223 * Set environment variables from registry
224 */
225 NTSTATUS
226 SmUpdateEnvironment(VOID)
227 {
228 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
229 WCHAR ValueBuffer[MAX_PATH];
230 NTSTATUS Status;
231
232 /*
233 * The following environment variables must be set prior to reading
234 * other variables from the registry.
235 *
236 * Variables (example):
237 * SystemRoot = "C:\reactos"
238 * SystemDrive = "C:"
239 */
240
241 /* Copy system root into value buffer */
242 wcscpy(ValueBuffer,
243 SharedUserData->NtSystemRoot);
244
245 /* Set SystemRoot = "C:\reactos" */
246 SmpSetEnvironmentVariable(&SmSystemEnvironment, L"SystemRoot", ValueBuffer);
247
248 /* Cut off trailing path */
249 ValueBuffer[2] = 0;
250
251 /* Set SystemDrive = "C:" */
252 SmpSetEnvironmentVariable(&SmSystemEnvironment, L"SystemDrive", ValueBuffer);
253
254 /* Read system environment from the registry. */
255 RtlZeroMemory(&QueryTable,
256 sizeof(QueryTable));
257
258 QueryTable[0].QueryRoutine = SmpEnvironmentQueryRoutine;
259
260 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
261 L"Session Manager\\Environment",
262 QueryTable,
263 &SmSystemEnvironment,
264 SmSystemEnvironment);
265
266 return Status;
267 }
268
269 /* EOF */