- Silence (on request of Christoph)
[reactos.git] / reactos / ntoskrnl / io / iomgr / bootlog.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/bootlog.c
5 * PURPOSE: Boot log file support
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 #if defined (ALLOC_PRAGMA)
17 #pragma alloc_text(INIT, IopInitBootLog)
18 #pragma alloc_text(INIT, IopStartBootLog)
19 #endif
20
21 /* GLOBALS ******************************************************************/
22
23 static BOOLEAN IopBootLogCreate = FALSE;
24 static BOOLEAN IopBootLogEnabled = FALSE;
25 static BOOLEAN IopLogFileEnabled = FALSE;
26 static ULONG IopLogEntryCount = 0;
27 static ERESOURCE IopBootLogResource;
28
29
30 /* FUNCTIONS ****************************************************************/
31
32 VOID INIT_FUNCTION
33 IopInitBootLog(BOOLEAN StartBootLog)
34 {
35 ExInitializeResourceLite(&IopBootLogResource);
36 if (StartBootLog) IopStartBootLog();
37 }
38
39
40 VOID INIT_FUNCTION
41 IopStartBootLog(VOID)
42 {
43 IopBootLogCreate = TRUE;
44 IopBootLogEnabled = TRUE;
45 }
46
47
48 VOID
49 IopStopBootLog(VOID)
50 {
51 IopBootLogEnabled = FALSE;
52 }
53
54
55 VOID
56 IopBootLog(PUNICODE_STRING DriverName,
57 BOOLEAN Success)
58 {
59 OBJECT_ATTRIBUTES ObjectAttributes;
60 WCHAR Buffer[256];
61 WCHAR ValueNameBuffer[8];
62 UNICODE_STRING KeyName;
63 UNICODE_STRING ValueName;
64 HANDLE ControlSetKey;
65 HANDLE BootLogKey;
66 NTSTATUS Status;
67
68 if (IopBootLogEnabled == FALSE)
69 return;
70
71 ExAcquireResourceExclusiveLite(&IopBootLogResource, TRUE);
72
73 DPRINT("Boot log: %wS %wZ\n",
74 Success ? L"Loaded driver" : L"Did not load driver",
75 DriverName);
76
77 swprintf(Buffer,
78 L"%ws %wZ",
79 Success ? L"Loaded driver" : L"Did not load driver",
80 DriverName);
81
82 swprintf(ValueNameBuffer,
83 L"%lu",
84 IopLogEntryCount);
85
86 RtlInitUnicodeString(&KeyName,
87 L"\\Registry\\Machine\\System\\CurrentControlSet");
88 InitializeObjectAttributes(&ObjectAttributes,
89 &KeyName,
90 OBJ_CASE_INSENSITIVE,
91 NULL,
92 NULL);
93 Status = ZwOpenKey(&ControlSetKey,
94 KEY_ALL_ACCESS,
95 &ObjectAttributes);
96 if (!NT_SUCCESS(Status))
97 {
98 DPRINT1("ZwOpenKey() failed (Status %lx)\n", Status);
99 ExReleaseResourceLite(&IopBootLogResource);
100 return;
101 }
102
103 RtlInitUnicodeString(&KeyName, L"BootLog");
104 InitializeObjectAttributes(&ObjectAttributes,
105 &KeyName,
106 OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
107 ControlSetKey,
108 NULL);
109 Status = ZwCreateKey(&BootLogKey,
110 KEY_ALL_ACCESS,
111 &ObjectAttributes,
112 0,
113 NULL,
114 REG_OPTION_NON_VOLATILE,
115 NULL);
116 if (!NT_SUCCESS(Status))
117 {
118 DPRINT1("ZwCreateKey() failed (Status %lx)\n", Status);
119 ZwClose(ControlSetKey);
120 ExReleaseResourceLite(&IopBootLogResource);
121 return;
122 }
123
124 RtlInitUnicodeString(&ValueName, ValueNameBuffer);
125 Status = ZwSetValueKey(BootLogKey,
126 &ValueName,
127 0,
128 REG_SZ,
129 (PVOID)Buffer,
130 (wcslen(Buffer) + 1) * sizeof(WCHAR));
131 ZwClose(BootLogKey);
132 ZwClose(ControlSetKey);
133
134 if (!NT_SUCCESS(Status))
135 {
136 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
137 }
138 else
139 {
140 IopLogEntryCount++;
141 }
142
143 ExReleaseResourceLite(&IopBootLogResource);
144 }
145
146
147 static NTSTATUS
148 IopWriteLogFile(PWSTR LogText)
149 {
150 OBJECT_ATTRIBUTES ObjectAttributes;
151 UNICODE_STRING FileName;
152 IO_STATUS_BLOCK IoStatusBlock;
153 HANDLE FileHandle;
154 PWSTR CrLf = L"\r\n";
155 NTSTATUS Status;
156
157 DPRINT("IopWriteLogFile() called\n");
158
159 RtlInitUnicodeString(&FileName,
160 L"\\SystemRoot\\rosboot.log");
161 InitializeObjectAttributes(&ObjectAttributes,
162 &FileName,
163 OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
164 NULL,
165 NULL);
166
167 Status = ZwCreateFile(&FileHandle,
168 FILE_APPEND_DATA,
169 &ObjectAttributes,
170 &IoStatusBlock,
171 NULL,
172 0,
173 0,
174 FILE_OPEN,
175 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
176 NULL,
177 0);
178 if (!NT_SUCCESS(Status))
179 {
180 DPRINT1("ZwCreateFile() failed (Status %lx)\n", Status);
181 return Status;
182 }
183
184 if (LogText != NULL)
185 {
186 Status = ZwWriteFile(FileHandle,
187 NULL,
188 NULL,
189 NULL,
190 &IoStatusBlock,
191 (PVOID)LogText,
192 wcslen(LogText) * sizeof(WCHAR),
193 NULL,
194 NULL);
195 if (!NT_SUCCESS(Status))
196 {
197 DPRINT1("ZwWriteFile() failed (Status %lx)\n", Status);
198 ZwClose(FileHandle);
199 return Status;
200 }
201 }
202
203 /* L"\r\n" */
204 Status = ZwWriteFile(FileHandle,
205 NULL,
206 NULL,
207 NULL,
208 &IoStatusBlock,
209 (PVOID)CrLf,
210 2 * sizeof(WCHAR),
211 NULL,
212 NULL);
213
214 ZwClose(FileHandle);
215
216 if (!NT_SUCCESS(Status))
217 {
218 DPRINT1("ZwWriteFile() failed (Status %lx)\n", Status);
219 }
220
221 return Status;
222 }
223
224
225 static NTSTATUS
226 IopCreateLogFile(VOID)
227 {
228 OBJECT_ATTRIBUTES ObjectAttributes;
229 UNICODE_STRING FileName;
230 IO_STATUS_BLOCK IoStatusBlock;
231 HANDLE FileHandle;
232 LARGE_INTEGER ByteOffset;
233 WCHAR Signature;
234 NTSTATUS Status;
235
236 DPRINT("IopSaveBootLogToFile() called\n");
237
238 ExAcquireResourceExclusiveLite(&IopBootLogResource, TRUE);
239
240 RtlInitUnicodeString(&FileName,
241 L"\\SystemRoot\\rosboot.log");
242 InitializeObjectAttributes(&ObjectAttributes,
243 &FileName,
244 OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
245 NULL,
246 NULL);
247
248 Status = ZwCreateFile(&FileHandle,
249 FILE_ALL_ACCESS,
250 &ObjectAttributes,
251 &IoStatusBlock,
252 NULL,
253 0,
254 0,
255 FILE_SUPERSEDE,
256 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
257 NULL,
258 0);
259 if (!NT_SUCCESS(Status))
260 {
261 DPRINT1("ZwCreateFile() failed (Status %lx)\n", Status);
262 return Status;
263 }
264
265 ByteOffset.QuadPart = (LONGLONG)0;
266
267 Signature = 0xFEFF;
268 Status = ZwWriteFile(FileHandle,
269 NULL,
270 NULL,
271 NULL,
272 &IoStatusBlock,
273 (PVOID)&Signature,
274 sizeof(WCHAR),
275 &ByteOffset,
276 NULL);
277 if (!NT_SUCCESS(Status))
278 {
279 DPRINT1("ZwWriteKey() failed (Status %lx)\n", Status);
280 }
281
282 ZwClose(FileHandle);
283
284 return Status;
285 }
286
287
288 VOID
289 IopSaveBootLogToFile(VOID)
290 {
291 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
292 WCHAR ValueNameBuffer[8];
293 OBJECT_ATTRIBUTES ObjectAttributes;
294 UNICODE_STRING KeyName;
295 UNICODE_STRING ValueName;
296 HANDLE KeyHandle;
297 ULONG BufferSize;
298 ULONG ResultLength;
299 ULONG i;
300 NTSTATUS Status;
301
302 if (IopBootLogCreate == FALSE)
303 return;
304
305 DPRINT("IopSaveBootLogToFile() called\n");
306
307 ExAcquireResourceExclusiveLite(&IopBootLogResource, TRUE);
308
309 Status = IopCreateLogFile();
310 if (!NT_SUCCESS(Status))
311 {
312 DPRINT1("IopCreateLogFile() failed (Status %lx)\n", Status);
313 ExReleaseResourceLite(&IopBootLogResource);
314 return;
315 }
316
317 //Status = IopWriteLogFile(L"ReactOS "KERNEL_VERSION_STR);
318
319 if (!NT_SUCCESS(Status))
320 {
321 DPRINT1("IopWriteLogFile() failed (Status %lx)\n", Status);
322 ExReleaseResourceLite(&IopBootLogResource);
323 return;
324 }
325
326 Status = IopWriteLogFile(NULL);
327 if (!NT_SUCCESS(Status))
328 {
329 DPRINT1("IopWriteLogFile() failed (Status %lx)\n", Status);
330 ExReleaseResourceLite(&IopBootLogResource);
331 return;
332 }
333
334
335 BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256 * sizeof(WCHAR);
336 KeyInfo = ExAllocatePool(PagedPool,
337 BufferSize);
338 if (KeyInfo == NULL)
339 {
340 ExReleaseResourceLite(&IopBootLogResource);
341 return;
342 }
343
344 RtlInitUnicodeString(&KeyName,
345 L"\\Registry\\Machine\\System\\CurrentControlSet\\BootLog");
346 InitializeObjectAttributes(&ObjectAttributes,
347 &KeyName,
348 OBJ_CASE_INSENSITIVE,
349 NULL,
350 NULL);
351 Status = ZwOpenKey(&KeyHandle,
352 KEY_ALL_ACCESS,
353 &ObjectAttributes);
354 if (!NT_SUCCESS(Status))
355 {
356 ExFreePool(KeyInfo);
357 ExReleaseResourceLite(&IopBootLogResource);
358 return;
359 }
360
361 for (i = 0; ; i++)
362 {
363 swprintf(ValueNameBuffer,
364 L"%lu", i);
365
366 RtlInitUnicodeString(&ValueName,
367 ValueNameBuffer);
368
369 Status = ZwQueryValueKey(KeyHandle,
370 &ValueName,
371 KeyValuePartialInformation,
372 KeyInfo,
373 BufferSize,
374 &ResultLength);
375 if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
376 {
377 break;
378 }
379
380 if (!NT_SUCCESS(Status))
381 {
382 ZwClose(KeyHandle);
383 ExFreePool(KeyInfo);
384 ExReleaseResourceLite(&IopBootLogResource);
385 return;
386 }
387
388 Status = IopWriteLogFile((PWSTR)&KeyInfo->Data);
389 if (!NT_SUCCESS(Status))
390 {
391 ZwClose(KeyHandle);
392 ExFreePool(KeyInfo);
393 ExReleaseResourceLite(&IopBootLogResource);
394 return;
395 }
396
397 /* Delete keys */
398 ZwDeleteValueKey(KeyHandle,
399 &ValueName);
400 }
401
402 ZwClose(KeyHandle);
403
404 ExFreePool(KeyInfo);
405
406 IopLogFileEnabled = TRUE;
407 ExReleaseResourceLite(&IopBootLogResource);
408
409 DPRINT("IopSaveBootLogToFile() done\n");
410 }
411
412 /* EOF */