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