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 29 IopInitBootLog(BOOLEAN StartBootLog) 30 { 31 ExInitializeResourceLite(&IopBootLogResource); 32 if (StartBootLog) IopStartBootLog(); 33 } 34 35 36 CODE_SEG("INIT") 37 VOID 38 IopStartBootLog(VOID) 39 { 40 IopBootLogCreate = TRUE; 41 IopBootLogEnabled = TRUE; 42 } 43 44 45 VOID 46 IopStopBootLog(VOID) 47 { 48 IopBootLogEnabled = FALSE; 49 } 50 51 52 VOID 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 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 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 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