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