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