Implement boot logging. Add /BOOTLOG to the command line to enable boot logging.
authorEric Kohl <eric.kohl@reactos.org>
Thu, 23 Sep 2004 11:27:58 +0000 (11:27 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Thu, 23 Sep 2004 11:27:58 +0000 (11:27 +0000)
svn path=/trunk/; revision=10996

reactos/ntoskrnl/Makefile
reactos/ntoskrnl/cm/ntfunc.c
reactos/ntoskrnl/include/internal/io.h
reactos/ntoskrnl/io/bootlog.c [new file with mode: 0644]
reactos/ntoskrnl/io/driver.c
reactos/ntoskrnl/ke/main.c

index 6ecf1ea..1b32407 100644 (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 \
index c9e0435..028a037 100644 (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);
 
index 2dde365..6b73d7c 100644 (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 */
diff --git a/reactos/ntoskrnl/io/bootlog.c b/reactos/ntoskrnl/io/bootlog.c
new file mode 100644 (file)
index 0000000..95c46f6
--- /dev/null
@@ -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 */
index 1040345..1ba9d98 100644 (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);
index 2a968f9..de66854 100644 (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);