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