xref: /reactos/ntoskrnl/io/iomgr/bootlog.c (revision 5c7ce447)
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 /* GLOBALS ******************************************************************/
17 
18 static BOOLEAN IopBootLogCreate = FALSE;
19 static BOOLEAN IopBootLogEnabled = FALSE;
20 static BOOLEAN IopLogFileEnabled = FALSE;
21 static ULONG IopLogEntryCount = 0;
22 static ERESOURCE IopBootLogResource;
23 
24 
25 /* FUNCTIONS ****************************************************************/
26 
27 CODE_SEG("INIT")
28 VOID
IopInitBootLog(BOOLEAN StartBootLog)29 IopInitBootLog(BOOLEAN StartBootLog)
30 {
31     ExInitializeResourceLite(&IopBootLogResource);
32     if (StartBootLog) IopStartBootLog();
33 }
34 
35 
36 CODE_SEG("INIT")
37 VOID
IopStartBootLog(VOID)38 IopStartBootLog(VOID)
39 {
40     IopBootLogCreate = TRUE;
41     IopBootLogEnabled = TRUE;
42 }
43 
44 
45 VOID
IopStopBootLog(VOID)46 IopStopBootLog(VOID)
47 {
48     IopBootLogEnabled = FALSE;
49 }
50 
51 
52 VOID
IopBootLog(PUNICODE_STRING DriverName,BOOLEAN Success)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                            (ULONG)(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
145 NTSTATUS
IopWriteLogFile(PWSTR LogText)146 IopWriteLogFile(PWSTR LogText)
147 {
148     OBJECT_ATTRIBUTES ObjectAttributes;
149     UNICODE_STRING FileName;
150     IO_STATUS_BLOCK IoStatusBlock;
151     HANDLE FileHandle;
152     PWSTR CrLf = L"\r\n";
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 = ZwCreateFile(&FileHandle,
166                           FILE_APPEND_DATA | SYNCHRONIZE,
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("ZwCreateFile() failed (Status %lx)\n", Status);
179         return Status;
180     }
181 
182     if (LogText != NULL)
183     {
184         Status = ZwWriteFile(FileHandle,
185                              NULL,
186                              NULL,
187                              NULL,
188                              &IoStatusBlock,
189                              LogText,
190                              (ULONG)wcslen(LogText) * sizeof(WCHAR),
191                              NULL,
192                              NULL);
193         if (!NT_SUCCESS(Status))
194         {
195             DPRINT1("ZwWriteFile() failed (Status %lx)\n", Status);
196             ZwClose(FileHandle);
197             return Status;
198         }
199     }
200 
201     /* L"\r\n" */
202     Status = ZwWriteFile(FileHandle,
203                          NULL,
204                          NULL,
205                          NULL,
206                          &IoStatusBlock,
207                          (PVOID)CrLf,
208                          2 * sizeof(WCHAR),
209                          NULL,
210                          NULL);
211 
212     ZwClose(FileHandle);
213 
214     if (!NT_SUCCESS(Status))
215     {
216         DPRINT1("ZwWriteFile() failed (Status %lx)\n", Status);
217     }
218 
219     return Status;
220 }
221 
222 
223 static
224 NTSTATUS
IopCreateLogFile(VOID)225 IopCreateLogFile(VOID)
226 {
227     OBJECT_ATTRIBUTES ObjectAttributes;
228     UNICODE_STRING FileName;
229     IO_STATUS_BLOCK IoStatusBlock;
230     HANDLE FileHandle;
231     LARGE_INTEGER ByteOffset;
232     WCHAR Signature;
233     NTSTATUS Status;
234 
235     DPRINT("IopSaveBootLogToFile() called\n");
236 
237     ExAcquireResourceExclusiveLite(&IopBootLogResource, TRUE);
238 
239     RtlInitUnicodeString(&FileName,
240                          L"\\SystemRoot\\rosboot.log");
241     InitializeObjectAttributes(&ObjectAttributes,
242                                &FileName,
243                                OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
244                                NULL,
245                                NULL);
246 
247     Status = ZwCreateFile(&FileHandle,
248                           FILE_ALL_ACCESS,
249                           &ObjectAttributes,
250                           &IoStatusBlock,
251                           NULL,
252                           0,
253                           0,
254                           FILE_SUPERSEDE,
255                           FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
256                           NULL,
257                           0);
258     if (!NT_SUCCESS(Status))
259     {
260         DPRINT1("ZwCreateFile() failed (Status %lx)\n", Status);
261         return Status;
262     }
263 
264     ByteOffset.QuadPart = (LONGLONG)0;
265 
266     Signature = 0xFEFF;
267     Status = ZwWriteFile(FileHandle,
268                          NULL,
269                          NULL,
270                          NULL,
271                          &IoStatusBlock,
272                          (PVOID)&Signature,
273                          sizeof(WCHAR),
274                          &ByteOffset,
275                          NULL);
276     if (!NT_SUCCESS(Status))
277     {
278         DPRINT1("ZwWriteKey() failed (Status %lx)\n", Status);
279     }
280 
281     ZwClose(FileHandle);
282 
283     return Status;
284 }
285 
286 
287 VOID
IopSaveBootLogToFile(VOID)288 IopSaveBootLogToFile(VOID)
289 {
290     PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
291     WCHAR ValueNameBuffer[8];
292     OBJECT_ATTRIBUTES ObjectAttributes;
293     UNICODE_STRING KeyName;
294     UNICODE_STRING ValueName;
295     HANDLE KeyHandle;
296     ULONG BufferSize;
297     ULONG ResultLength;
298     ULONG i;
299     NTSTATUS Status;
300 
301     if (IopBootLogCreate == FALSE)
302         return;
303 
304     DPRINT("IopSaveBootLogToFile() called\n");
305 
306     ExAcquireResourceExclusiveLite(&IopBootLogResource, TRUE);
307 
308     Status = IopCreateLogFile();
309     if (!NT_SUCCESS(Status))
310     {
311         DPRINT1("IopCreateLogFile() failed (Status %lx)\n", Status);
312         ExReleaseResourceLite(&IopBootLogResource);
313         return;
314     }
315 
316     //Status = IopWriteLogFile(L"ReactOS "KERNEL_VERSION_STR);
317 
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         ExReleaseResourceLite(&IopBootLogResource);
340         return;
341     }
342 
343     RtlInitUnicodeString(&KeyName,
344                          L"\\Registry\\Machine\\System\\CurrentControlSet\\BootLog");
345     InitializeObjectAttributes(&ObjectAttributes,
346                                &KeyName,
347                                OBJ_CASE_INSENSITIVE,
348                                NULL,
349                                NULL);
350     Status = ZwOpenKey(&KeyHandle,
351                        KEY_ALL_ACCESS,
352                        &ObjectAttributes);
353     if (!NT_SUCCESS(Status))
354     {
355         ExFreePool(KeyInfo);
356         ExReleaseResourceLite(&IopBootLogResource);
357         return;
358     }
359 
360     for (i = 0; ; i++)
361     {
362         swprintf(ValueNameBuffer,
363                  L"%lu", i);
364 
365         RtlInitUnicodeString(&ValueName,
366                              ValueNameBuffer);
367 
368         Status = ZwQueryValueKey(KeyHandle,
369                                  &ValueName,
370                                  KeyValuePartialInformation,
371                                  KeyInfo,
372                                  BufferSize,
373                                  &ResultLength);
374         if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
375         {
376             break;
377         }
378 
379         if (!NT_SUCCESS(Status))
380         {
381             ZwClose(KeyHandle);
382             ExFreePool(KeyInfo);
383             ExReleaseResourceLite(&IopBootLogResource);
384             return;
385         }
386 
387         Status = IopWriteLogFile((PWSTR)&KeyInfo->Data);
388         if (!NT_SUCCESS(Status))
389         {
390             ZwClose(KeyHandle);
391             ExFreePool(KeyInfo);
392             ExReleaseResourceLite(&IopBootLogResource);
393             return;
394         }
395 
396         /* Delete keys */
397         ZwDeleteValueKey(KeyHandle,
398                          &ValueName);
399     }
400 
401     ZwClose(KeyHandle);
402 
403     ExFreePool(KeyInfo);
404 
405     IopLogFileEnabled = TRUE;
406     ExReleaseResourceLite(&IopBootLogResource);
407 
408     DPRINT("IopSaveBootLogToFile() done\n");
409 }
410 
411 /* EOF */
412