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