Implement boot logging. Add /BOOTLOG to the command line to enable boot logging.

svn path=/trunk/; revision=10996
This commit is contained in:
Eric Kohl 2004-09-23 11:27:58 +00:00
parent d0135b1184
commit 6e00d9b507
6 changed files with 490 additions and 23 deletions

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.142 2004/09/16 10:25:17 gvg Exp $
# $Id: Makefile,v 1.143 2004/09/23 11:27:58 ekohl Exp $
#
# ReactOS Operating System
#
@ -140,7 +140,7 @@ OBJECTS_KE = \
ke/event.o \
ke/kqueue.o \
ke/kthread.o \
ke/ipi.o \
ke/ipi.o \
ke/main.o \
ke/mutex.o \
ke/process.o \
@ -188,6 +188,7 @@ OBJECTS_MM = \
OBJECTS_IO = \
io/adapter.o \
io/arcname.o \
io/bootlog.o \
io/buildirp.o \
io/cancel.o \
io/cleanup.o \

View file

@ -1993,7 +1993,8 @@ NtInitializeRegistry (IN BOOLEAN SetUpBoot)
if (CmiRegistryInitialized == TRUE)
return STATUS_ACCESS_DENIED;
/* FIXME: save boot log file */
/* Save boot log file */
IopSaveBootLogToFile();
Status = CmiInitHives (SetUpBoot);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: io.h,v 1.43 2004/05/02 19:33:29 ekohl Exp $
/* $Id: io.h,v 1.44 2004/09/23 11:26:09 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -352,11 +352,27 @@ IoCreateDriverList(VOID);
NTSTATUS
IoDestroyDriverList(VOID);
/* bootlog.c */
VOID
IopInitBootLog(VOID);
VOID
IopStartBootLog(VOID);
VOID
IopStopBootLog(VOID);
VOID
IopBootLog(PUNICODE_STRING DriverName, BOOLEAN Success);
VOID
IopSaveBootLogToFile(VOID);
/* errlog.c */
NTSTATUS
IopInitErrorLog (VOID);
IopInitErrorLog(VOID);
/* rawfs.c */

View file

@ -0,0 +1,426 @@
/* $Id: bootlog.c,v 1.1 2004/09/23 11:26:41 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/bootlog.c
* PURPOSE: Boot log file support
* PROGRAMMER: Eric Kohl
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
static BOOLEAN IopBootLogCreate = FALSE;
static BOOLEAN IopBootLogEnabled = FALSE;
static BOOLEAN IopLogFileEnabled = FALSE;
static ULONG IopLogEntryCount = 0;
static ERESOURCE IopBootLogResource;
/* FUNCTIONS ****************************************************************/
VOID INIT_FUNCTION
IopInitBootLog(VOID)
{
ExInitializeResourceLite(&IopBootLogResource);
}
VOID // INIT_FUNCTION
IopStartBootLog(VOID)
{
IopBootLogCreate = TRUE;
IopBootLogEnabled = TRUE;
}
VOID // INIT_FUNCTION
IopStopBootLog(VOID)
{
IopBootLogEnabled = FALSE;
}
VOID
IopBootLog(PUNICODE_STRING DriverName,
BOOLEAN Success)
{
OBJECT_ATTRIBUTES ObjectAttributes;
WCHAR Buffer[256];
WCHAR ValueNameBuffer[8];
UNICODE_STRING KeyName;
UNICODE_STRING ValueName;
HANDLE ControlSetKey;
HANDLE BootLogKey;
NTSTATUS Status;
if (IopBootLogEnabled == FALSE)
return;
ExAcquireResourceExclusiveLite(&IopBootLogResource, TRUE);
DPRINT("Boot log: %S %wZ\n",
Success ? L"Loaded driver" : L"Did not load driver",
DriverName);
swprintf(Buffer,
L"%s %wZ",
Success ? L"Loaded driver" : L"Did not load driver",
DriverName);
swprintf(ValueNameBuffer,
L"%lu",
IopLogEntryCount);
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\System\\CurrentControlSet");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenKey(&ControlSetKey,
KEY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
ExReleaseResourceLite(&IopBootLogResource);
return;
}
RtlInitUnicodeString(&KeyName, L"BootLog");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
ControlSetKey,
NULL);
Status = NtCreateKey(&BootLogKey,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
NULL,
REG_OPTION_NON_VOLATILE,
NULL);
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
NtClose(ControlSetKey);
ExReleaseResourceLite(&IopBootLogResource);
return;
}
RtlInitUnicodeString(&ValueName, ValueNameBuffer);
Status = NtSetValueKey(BootLogKey,
&ValueName,
0,
REG_SZ,
(PVOID)Buffer,
(wcslen(Buffer) + 1) * sizeof(WCHAR));
NtClose(BootLogKey);
NtClose(ControlSetKey);
if (NT_SUCCESS(Status))
{
IopLogEntryCount++;
}
else
{
CHECKPOINT1;
}
ExReleaseResourceLite(&IopBootLogResource);
}
static NTSTATUS
IopWriteLogFile(PWSTR LogText)
{
FILE_STANDARD_INFORMATION FileInformation;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING FileName;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
LARGE_INTEGER ByteOffset;
PWSTR CrLf = L"\r\n";
NTSTATUS Status;
DPRINT("IopWriteLogFile() called\n");
RtlInitUnicodeString(&FileName,
L"\\SystemRoot\\rosboot.log");
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
NULL,
NULL);
Status = NtCreateFile(&FileHandle,
FILE_WRITE_DATA, /* FILE_APPEND_DATA */
&ObjectAttributes,
&IoStatusBlock,
NULL,
0,
0,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
return Status;
}
Status = NtQueryInformationFile(FileHandle,
&IoStatusBlock,
&FileInformation,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status);
return Status;
}
ByteOffset.QuadPart = FileInformation.EndOfFile.QuadPart;
if (LogText != NULL)
{
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)LogText,
wcslen(LogText) * sizeof(WCHAR),
&ByteOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
NtClose(FileHandle);
return Status;
}
ByteOffset.QuadPart += (wcslen(LogText) * sizeof(WCHAR));
}
/* L"\r\n" */
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)CrLf,
2 * sizeof(WCHAR),
&ByteOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
}
return Status;
}
static NTSTATUS
IopCreateLogFile(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING FileName;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
LARGE_INTEGER ByteOffset;
WCHAR Signature;
NTSTATUS Status;
DPRINT("IopSaveBootLogToFile() called\n");
ExAcquireResourceExclusiveLite(&IopBootLogResource, TRUE);
RtlInitUnicodeString(&FileName,
L"\\SystemRoot\\rosboot.log");
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
NULL,
NULL);
Status = NtCreateFile(&FileHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
NULL,
0,
0,
FILE_SUPERSEDE,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
return Status;
}
ByteOffset.QuadPart = (LONGLONG)0;
Signature = 0xFEFF;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)&Signature,
sizeof(WCHAR),
&ByteOffset,
NULL);
NtClose(FileHandle);
return Status;
}
VOID
IopSaveBootLogToFile(VOID)
{
PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
WCHAR ValueNameBuffer[8];
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
UNICODE_STRING ValueName;
HANDLE KeyHandle;
ULONG BufferSize;
ULONG ResultLength;
ULONG i;
NTSTATUS Status;
if (IopBootLogCreate == FALSE)
return;
DPRINT1("IopSaveBootLogToFile() called\n");
ExAcquireResourceExclusiveLite(&IopBootLogResource, TRUE);
Status = IopCreateLogFile();
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
ExReleaseResourceLite(&IopBootLogResource);
return;
}
Status = IopWriteLogFile(L"ReactOS 0.2.4");
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
ExReleaseResourceLite(&IopBootLogResource);
return;
}
Status = IopWriteLogFile(NULL);
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
ExReleaseResourceLite(&IopBootLogResource);
return;
}
BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256 * sizeof(WCHAR);
KeyInfo = ExAllocatePool(PagedPool,
BufferSize);
if (KeyInfo == NULL)
{
CHECKPOINT1;
ExReleaseResourceLite(&IopBootLogResource);
return;
}
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\System\\CurrentControlSet\\BootLog");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenKey(&KeyHandle,
KEY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
ExFreePool(KeyInfo);
ExReleaseResourceLite(&IopBootLogResource);
return;
}
for (i = 0; ; i++)
{
swprintf(ValueNameBuffer,
L"%lu", i);
RtlInitUnicodeString(&ValueName,
ValueNameBuffer);
Status = NtQueryValueKey(KeyHandle,
&ValueName,
KeyValuePartialInformation,
KeyInfo,
BufferSize,
&ResultLength);
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
break;
}
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
ExFreePool(KeyInfo);
ExReleaseResourceLite(&IopBootLogResource);
return;
}
Status = IopWriteLogFile((PWSTR)&KeyInfo->Data);
if (!NT_SUCCESS(Status))
{
CHECKPOINT1;
ExFreePool(KeyInfo);
ExReleaseResourceLite(&IopBootLogResource);
return;
}
/* Delete keys */
// NtDeleteValueKey(KeyHandle,
// &ValueName);
}
NtClose(KeyHandle);
ExFreePool(KeyInfo);
IopLogFileEnabled = TRUE;
ExReleaseResourceLite(&IopBootLogResource);
DPRINT1("IopSaveBootLogToFile() done\n");
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: driver.c,v 1.52 2004/09/20 19:47:25 hbirr Exp $
/* $Id: driver.c,v 1.53 2004/09/23 11:26:41 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -1183,6 +1183,8 @@ IopInitializeBootDrivers(VOID)
PCHAR Extension;
PLOADER_MODULE KeLoaderModules = (PLOADER_MODULE)KeLoaderBlock.ModsAddr;
ULONG i;
UNICODE_STRING DriverName;
NTSTATUS Status;
DPRINT("IopInitializeBootDrivers()\n");
@ -1209,15 +1211,25 @@ IopInitializeBootDrivers(VOID)
/*
* Load builtin driver
*/
if (!_stricmp(Extension, ".sys"))
if (!_stricmp(Extension, ".exe") || !_stricmp(Extension, ".dll"))
{
RtlCreateUnicodeStringFromAsciiz(&DriverName, ModuleName);
IopBootLog(&DriverName, TRUE);
RtlFreeUnicodeString(&DriverName);
}
else if (!_stricmp(Extension, ".sys"))
{
if (!ModuleLoaded)
{
IopInitializeBuiltinDriver(NULL, (PVOID)ModuleStart, ModuleName,
ModuleSize);
Status = IopInitializeBuiltinDriver(NULL,
(PVOID)ModuleStart,
ModuleName,
ModuleSize);
RtlCreateUnicodeStringFromAsciiz(&DriverName, ModuleName);
IopBootLog(&DriverName, NT_SUCCESS(Status) ? TRUE : FALSE);
RtlFreeUnicodeString(&DriverName);
}
++BootDriverCount;
BootDriverCount++;
}
/*
@ -1251,6 +1263,7 @@ IopLoadDriver(PSERVICE Service)
IopDisplayLoadingMessage(Service->ServiceName.Buffer);
Status = NtLoadDriver(&Service->RegistryPath);
IopBootLog(&Service->ImagePath, NT_SUCCESS(Status) ? TRUE : FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("NtLoadDriver() failed (Status %lx)\n", Status);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: main.c,v 1.194 2004/09/09 20:42:33 hbirr Exp $
/* $Id: main.c,v 1.195 2004/09/23 11:27:08 ekohl Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
@ -356,7 +356,7 @@ ExpInitializeExecutive(VOID)
else
{
MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
}
}
}
}
p1 = p2;
@ -649,6 +649,21 @@ ExpInitializeExecutive(VOID)
/* Initialize Callbacks before drivers */
ExpInitializeCallbacks();
/* Start boot logging */
IopInitBootLog();
p1 = (PCHAR)KeLoaderBlock.CommandLine;
while (*p1 && (p2 = strchr(p1, '/')))
{
p2++;
if (!_strnicmp(p2, "BOOTLOG", 7))
{
p2 += 7;
IopStartBootLog();
}
p1 = p2;
}
/*
* Load boot start drivers
*/
@ -694,6 +709,9 @@ ExpInitializeExecutive(VOID)
IoDestroyDriverList();
/* Stop boot logging */
IopStopBootLog();
/*
* Assign drive letters
*/
@ -744,11 +762,7 @@ ExpInitializeExecutive(VOID)
Handles[1] = ProcessHandle;
/* Wait for the system to be initialized */
#ifdef __GNUC__
Timeout.QuadPart = -1200000000LL; /* 120 second timeout */
#else
Timeout.QuadPart = -1200000000; /* 120 second timeout */
#endif
Timeout.QuadPart = (LONGLONG)-1200000000; /* 120 second timeout */
Status = NtWaitForMultipleObjects(((LONG) sizeof(Handles) / sizeof(HANDLE)),
Handles,
WaitAny,
@ -790,11 +804,7 @@ ExpInitializeExecutive(VOID)
/*
* Crash the system if the initial process terminates within 5 seconds.
*/
#ifdef __GNUC__
Timeout.QuadPart = -50000000LL;
#else
Timeout.QuadPart = -50000000;
#endif
Timeout.QuadPart = (LONGLONG)-50000000; /* 5 second timeout */
Status = NtWaitForSingleObject(ProcessHandle,
FALSE,
&Timeout);