2003-08-11 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / ntoskrnl / ke / main.c
index c00fdb3..e23817a 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.116 2002/03/16 00:00:13 ekohl Exp $
+/* $Id: main.c,v 1.167 2003/08/11 18:50:12 chorns Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/main.c
 
 /* INCLUDES *****************************************************************/
 
-#include <ddk/ntddk.h>
+#define NTOS_MODE_KERNEL
+#include <ntos.h>
 #include <internal/ntoskrnl.h>
 #include <reactos/resource.h>
 #include <internal/mm.h>
+#include <internal/ifs.h>
 #include <internal/module.h>
 #include <internal/ldr.h>
 #include <internal/ex.h>
 #include <internal/po.h>
 #include <internal/cc.h>
 #include <internal/se.h>
-#include <napi/shared_data.h>
 #include <internal/v86m.h>
 #include <internal/kd.h>
 #include <internal/trap.h>
 #include "../dbg/kdb.h"
 #include <internal/registry.h>
+#include <internal/nls.h>
 #include <reactos/bugcodes.h>
+#include <ntos/bootvid.h>
 
 #ifdef HALDBG
 #include <internal/ntosdbg.h>
@@ -64,6 +67,8 @@ ULONG EXPORTED NtBuildNumber = KERNEL_VERSION_BUILD;
 ULONG EXPORTED NtGlobalFlag = 0;
 CHAR  EXPORTED KeNumberProcessors;
 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock;
+ULONG EXPORTED KeDcacheFlushCount = 0;
+ULONG EXPORTED KeIcacheFlushCount = 0;
 static LOADER_MODULE KeLoaderModules[64];
 static UCHAR KeLoaderModuleStrings[64][256];
 static UCHAR KeLoaderCommandLine[256];
@@ -76,334 +81,37 @@ volatile BOOLEAN Initialized = FALSE;
 
 extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
 
-typedef struct
-{
-  LPWSTR ServiceName;
-  LPWSTR DeviceDesc;
-  LPWSTR Group;
-  DWORD Start;
-  DWORD Type;
-} SERVICE, *PSERVICE;
-
-SERVICE Services[] = {
-  {L"pci", L"PCI Bus Driver", L"Boot Bus Extender", 0, 1},
-  {L"keyboard", L"Standard Keyboard Driver", L"Base", 0, 1},
-  {L"blue", L"Bluescreen Driver", L"Base", 0, 1},
-  {L"vidport", L"Video Port Driver", L"Base", 0, 1},
-  {L"vgamp", L"VGA Miniport", L"Base", 0, 1},
-  {L"minixfs", L"Minix File System", L"File system", 0, 1},
-  {L"msfs", L"Mail Slot File System", L"File system", 0, 1},
-  {L"npfs", L"Named Pipe File System", L"File system", 0, 1},
-  {L"psaux", L"PS/2 Auxillary Port Driver", L"", 0, 1},
-  {L"mouclass", L"Mouse Class Driver", L"Pointer Class", 0, 1},
-  {L"ndis", L"NDIS System Driver", L"NDIS Wrapper", 0, 1},
-  {L"ne2000", L"Novell Eagle 2000 Driver", L"NDIS", 0, 1},
-  {L"afd", L"AFD Networking Support Environment", L"TDI", 0, 1},
-  {NULL,}
-};
 
 /* FUNCTIONS ****************************************************************/
 
-#define FULLREG
-
-VOID CreateDefaultRegistryForLegacyDriver(
-  PSERVICE Service)
+static BOOLEAN
+RtlpCheckFileNameExtension(PCHAR FileName,
+                          PCHAR Extension)
 {
-#ifdef FULLREG
-  WCHAR LegacyDriver[] = L"LegacyDriver";
-#endif
-  WCHAR InstancePath[MAX_PATH];
-  WCHAR KeyNameBuffer[MAX_PATH];
-  WCHAR Name[MAX_PATH];
-  UNICODE_STRING KeyName;
-  HANDLE KeyHandle;
-#ifdef FULLREG
-  DWORD DwordData;
-#endif
-  ULONG Length;
-  NTSTATUS Status;
-  WCHAR ImagePath[MAX_PATH];
-  /* Enum section */
-  wcscpy(Name, Service->ServiceName);
-  _wcsupr(Name);
-  wcscpy(InstancePath, L"Root\\LEGACY_");
-  wcscat(InstancePath, Name);
-  wcscat(InstancePath, L"\\0000");
-
-  wcscpy(KeyNameBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
-  wcscat(KeyNameBuffer, InstancePath);
-
-  RtlInitUnicodeString(&KeyName, KeyNameBuffer);
-
-  DPRINT("Key name is %S\n", KeyName.Buffer);
-
-  Status = RtlpCreateRegistryKeyPath(KeyName.Buffer);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlpCreateRegistryKeyPath() failed with status %x\n", Status);
-  return;
-    }
-
-  Status = RtlpGetRegistryHandle(
-    RTL_REGISTRY_ENUM,
-         InstancePath,
-               TRUE,
-               &KeyHandle);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
-  return;
-    }
-#ifdef FULLREG
-  DwordData = 0;
-  Length = sizeof(DWORD);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-    (PWSTR)KeyHandle,
-               L"Capabilities",
-               REG_DWORD,
-               (LPWSTR)&DwordData,
-               Length);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
-
-  Length = (wcslen(LegacyDriver) + 1) * sizeof(WCHAR);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-    (PWSTR)KeyHandle,
-               L"Class",
-               REG_SZ,
-               LegacyDriver,
-               Length);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
-#endif
-  Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-               (PWSTR)KeyHandle,
-               L"DeviceDesc",
-               REG_SZ,
-               Service->DeviceDesc,
-               Length);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
-#ifdef FULLREG
-  DwordData = 0;
-  Length = Length = sizeof(DWORD);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-    (PWSTR)KeyHandle,
-               L"Legacy",
-               REG_DWORD,
-               (LPWSTR)&DwordData,
-               sizeof(DWORD));
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
-#endif
-  Length = (wcslen(Service->ServiceName) + 1) * sizeof(WCHAR);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-               (PWSTR)KeyHandle,
-               L"Service",
-               REG_SZ,
-               Service->ServiceName,
-               Length);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
-
-  NtClose(KeyHandle);
-
-
-  /* Services section */
-
-  Status = RtlpGetRegistryHandle(
-    RTL_REGISTRY_SERVICES,
-         Service->ServiceName,
-               TRUE,
-               &KeyHandle);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
-  return;
-    }
-#ifdef FULLREG
-  Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-               (PWSTR)KeyHandle,
-               L"DisplayName",
-               REG_SZ,
-               Service->DeviceDesc,
-               Length);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
-
-  DwordData = 1;
-  Length = sizeof(DWORD);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-    (PWSTR)KeyHandle,
-               L"ErrorControl",
-               REG_DWORD,
-               (LPWSTR)&DwordData,
-               Length);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
+  PCHAR Ext;
 
-  Length = (wcslen(Service->Group) + 1) * sizeof(WCHAR);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-               (PWSTR)KeyHandle,
-               L"Group",
-               REG_SZ,
-               Service->Group,
-               Length);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
-#endif
-  wcscpy(ImagePath, L"\\SystemRoot\\System32\\drivers\\");
-  wcscat(ImagePath, Service->ServiceName);
-  wcscat(ImagePath, L".sys");
-
-  Length = (wcslen(ImagePath) + 1) * sizeof(WCHAR);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-               (PWSTR)KeyHandle,
-               L"ImagePath",
-               REG_SZ,
-               ImagePath,
-               Length);
-  if (!NT_SUCCESS(Status))
+  Ext = strrchr(FileName, '.');
+  if (Ext == NULL)
     {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
-#ifdef FULLREG
-  DwordData = Service->Start;
-  Length = sizeof(DWORD);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-    (PWSTR)KeyHandle,
-               L"Start",
-               REG_DWORD,
-               (LPWSTR)&DwordData,
-               Length);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
+      if ((Extension == NULL) || (*Extension == 0))
+       return TRUE;
+      else
+       return FALSE;
     }
 
-  DwordData = Service->Type;
-  Length = sizeof(DWORD);
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_HANDLE,
-    (PWSTR)KeyHandle,
-               L"Type",
-               REG_DWORD,
-               (LPWSTR)&DwordData,
-               Length);
-  if (!NT_SUCCESS(Status))
-    {
-  DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
-       NtClose(KeyHandle);
-       return;
-    }
-#endif
-  NtClose(KeyHandle);
-}
-
-VOID CreateDefaultRegistry()
-{
-  NTSTATUS Status;
-  ULONG i;
+  if (*Extension != '.')
+    Ext++;
 
-  Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
-  if (!NT_SUCCESS(Status))
-  {
-    CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
-    return;
-  }
-
-  Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
-  if (!NT_SUCCESS(Status))
-  {
-    CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
-    return;
-  }
-
-  for (i = 0; Services[i].ServiceName != NULL; i++)
-  {
-    CreateDefaultRegistryForLegacyDriver(&Services[i]);
-  }
-}
-
-
-static BOOLEAN
-RtlpCheckFileNameExtension(PCHAR FileName,
-                          PCHAR Extension)
-{
-   PCHAR Ext;
-
-   Ext = strrchr(FileName, '.');
-   if ((Extension == NULL) || (*Extension == 0))
-     {
-       if (Ext == NULL)
-         return TRUE;
-       else
-         return FALSE;
-     }
-   if (*Extension != '.')
-     Ext++;
-   
-   if (_stricmp(Ext, Extension) == 0)
-     return TRUE;
-   else
-     return FALSE;
+  if (_stricmp(Ext, Extension) == 0)
+    return TRUE;
+  else
+    return FALSE;
 }
 
 
 static VOID
 InitSystemSharedUserPage (PCSZ ParameterLine)
 {
-   PKUSER_SHARED_DATA SharedPage;
-
    UNICODE_STRING ArcDeviceName;
    UNICODE_STRING ArcName;
    UNICODE_STRING BootPath;
@@ -420,13 +128,13 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
    ULONG i;
    BOOLEAN BootDriveFound;
 
-   SharedPage = (PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE;
-   SharedPage->DosDeviceMap = 0;
-   SharedPage->NtProductType = NtProductWinNt;
-   for (i = 0; i < 32; i++)
-     {
-       SharedPage->DosDeviceDriveType[i] = 0;
-     }
+   /*
+    * NOTE:
+    *   The shared user page has been zeroed-out right after creation.
+    *   There is NO need to do this again.
+    */
+
+   SharedUserData->NtProductType = NtProductWinNt;
 
    BootDriveFound = FALSE;
 
@@ -454,17 +162,17 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
    p = strchr (ParamBuffer, '\\');
    if (p)
      {
-       DPRINT("Boot path: %s\n", p);
-       RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
-       *p = 0;
+       DPRINT("Boot path: %s\n", p);
+       RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
+       *p = 0;
      }
    else
      {
-       DPRINT("Boot path: %s\n", "\\");
-       RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
+       DPRINT("Boot path: %s\n", "\\");
+       RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
      }
    DPRINT("Arc name: %s\n", ParamBuffer);
-
+   
    /* Only arc name left - build full arc name */
    ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
    swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
@@ -481,7 +189,7 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
 
    InitializeObjectAttributes (&ObjectAttributes,
                               &ArcName,
-                              0,
+                              OBJ_OPENLINK,
                               NULL,
                               NULL);
 
@@ -496,7 +204,7 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
        CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
                 Status);
 
-       KeBugCheck (0x0);
+       KEBUGCHECK (0x0);
      }
 
    Status = NtQuerySymbolicLinkObject (Handle,
@@ -510,7 +218,7 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
        CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
                 Status);
 
-       KeBugCheck (0x0);
+       KEBUGCHECK (0x0);
      }
    DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
 
@@ -528,7 +236,7 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
 
        InitializeObjectAttributes (&ObjectAttributes,
                                    &DriveName,
-                                   0,
+                                   OBJ_OPENLINK,
                                    NULL,
                                    NULL);
 
@@ -557,227 +265,62 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
        if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
          {
             DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
-            swprintf (SharedPage->NtSystemRoot,
-                      L"%C:%wZ", 'A' + i, &BootPath);
-
-               BootDriveFound = TRUE;
+            swprintf(SharedUserData->NtSystemRoot,
+                     L"%C:%wZ", 'A' + i, &BootPath);
+            
+            BootDriveFound = TRUE;
          }
 
        NtClose (Handle);
-
-       /* set bit in dos drives bitmap (drive available) */
-       SharedPage->DosDeviceMap |= (1<<i);
      }
 
    RtlFreeUnicodeString (&BootPath);
    RtlFreeUnicodeString (&DriveDeviceName);
    RtlFreeUnicodeString (&ArcDeviceName);
 
-   DPRINT("DosDeviceMap: 0x%x\n", SharedPage->DosDeviceMap);
+   DPRINT("DosDeviceMap: 0x%x\n", SharedUserData->DosDeviceMap);
 
    if (BootDriveFound == FALSE)
      {
        DbgPrint("No system drive found!\n");
-       KeBugCheck (0x0);
+       KEBUGCHECK (0x0);
      }
 }
 
-#ifndef NDEBUG
-
-VOID DumpBIOSMemoryMap(VOID)
+VOID STATIC
+MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length)
 {
+  PHYSICAL_ADDRESS Page;
   ULONG i;
 
-  DbgPrint("Dumping BIOS memory map:\n");
-  DbgPrint("Memory map base: %d\n", KeLoaderBlock.MmapAddr);
-  DbgPrint("Memory map size: %d\n", KeLoaderBlock.MmapLength);
-  DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount);
-  for (i = 0; i < KeMemoryMapRangeCount; i++)
-    {
-      DbgPrint("Range: Base (%08X)  Length (%08X)  Type (%02X)\n",
-        KeMemoryMap[i].BaseAddrLow,
-        KeMemoryMap[i].LengthLow,
-        KeMemoryMap[i].Type);
-    }
-  for (;;);
-}
-
-#endif /* !NDEBUG */
-
-#if 1
-// SEH Test
-
-static ULONG Scratch;
-
-EXCEPTION_DISPOSITION
-ExpUnhandledException1(
-  PEXCEPTION_RECORD ExceptionRecord,
-  PEXCEPTION_REGISTRATION ExceptionRegistration,
-  PCONTEXT Context,
-  PVOID DispatcherContext)
-{
-  DbgPrint("ExpUnhandledException1() called\n");
-  DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
-  DbgPrint("  Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
-  DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
-  DbgPrint("Context 0x%X\n", Context);
-  DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
-
-  Context->Eax = (ULONG)&Scratch;
-
-  return ExceptionContinueExecution;
-}
-
-
-EXCEPTION_DISPOSITION
-ExpUnhandledException2(
-  PEXCEPTION_RECORD ExceptionRecord,
-  PEXCEPTION_REGISTRATION ExceptionRegistration,
-  PCONTEXT Context,
-  PVOID DispatcherContext)
-{
-  DbgPrint("ExpUnhandledException2() called\n");
-  DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
-  DbgPrint("  Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
-  DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
-  DbgPrint("Context 0x%X\n", Context);
-  DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
-
-#if 1
-  Context->Eax = (ULONG)&Scratch;
-
-  return ExceptionContinueExecution;
-
-#else
-
-  return ExceptionContinueSearch;
-
-#endif
-}
-
-
-#if 1
-// Put in mingw headers
-extern VOID
-CDECL
-_local_unwind2(
-  PEXCEPTION_REGISTRATION RegistrationFrame,
-  DWORD TryLevel);
-
-extern VOID
-CDECL
-_global_unwind2(
-  PVOID RegistrationFrame);
-
-extern EXCEPTION_DISPOSITION
-CDECL
-_except_handler2(
-  PEXCEPTION_RECORD ExceptionRecord,
-  PEXCEPTION_REGISTRATION RegistrationFrame,
-  PCONTEXT Context,
-  PVOID DispatcherContext);
-
-extern EXCEPTION_DISPOSITION
-CDECL
-_except_handler3(
-  PEXCEPTION_RECORD ExceptionRecord,
-  PEXCEPTION_REGISTRATION RegistrationFrame,
-  PCONTEXT Context,
-  PVOID DispatcherContext);
-
-#endif
-
-PRTL_EXCEPTION_REGISTRATION
-CurrentRER(VOID)
-{
-   ULONG Value;
-   
-   __asm__("movl %%ebp, %0\n\t" : "=a" (Value));
-
-   return((PRTL_EXCEPTION_REGISTRATION)Value) - 1;
-}
-
-PULONG x;
-PRTL_EXCEPTION_REGISTRATION TestER;
-SCOPETABLE_ENTRY ScopeTable;
-PEXCEPTION_REGISTRATION OSPtr;
-
-
-DWORD CDECL SEHFilterRoutine(VOID)
-{
-  DbgPrint("Within filter routine.\n");
-  return EXCEPTION_EXECUTE_HANDLER;
-  //return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-VOID CDECL SEHHandlerRoutine(VOID)
-{
-  DbgPrint("Within exception handler.\n");
-  DbgPrint("System halted.\n");
-  for (;;);
-}
-
-
-VOID SEHTest()
-{
-  RTL_EXCEPTION_REGISTRATION ER;
-  LPEXCEPTION_POINTERS ExceptionPointers;
-  PVOID StandardESPInFrame;
-
-  __asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame));
-  DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame);
-
-  ExceptionPointers = NULL;
-
-  ER.OS.handler = _except_handler3;
-  __asm__ ("movl %%fs:0,%%eax;" : "=a" (ER.OS.prev));
-  DbgPrint("ER.OS.prev: 0x%X\n", ER.OS.prev);
-
-  ER.ScopeTable = &ScopeTable;
-  DbgPrint("ER.ScopeTable: 0x%X\n", ER.ScopeTable);
-  ER.TryLevel = -1;
-  __asm__ ("movl %%ebp,%%eax;" : "=a" (ER.Ebp));
-  DbgPrint("ER.Ebp: 0x%X\n", ER.Ebp);
-
-  ScopeTable.PreviousTryLevel = -1;
-  ScopeTable.FilterRoutine = SEHFilterRoutine;
-  DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable.FilterRoutine);
-  ScopeTable.HandlerRoutine = SEHHandlerRoutine;
-  DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable.HandlerRoutine);
-
-
-  OSPtr = &ER.OS;
-  DbgPrint("OSPtr: 0x%X\n", OSPtr);
-
-  __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr));
-
-  /*__try1(__except_handler3)*/ if(1) {
-    ER.TryLevel = 0; // Entered first try... block
-
-    DbgPrint("Within guarded section.\n");
-    x = (PULONG)0xf2000000; *x = 0;
-    DbgPrint("After exception.\n");
-  } /* __except1 */ if(0) {
+  for (i = 0; i < PAGE_ROUND_UP(Length)/PAGE_SIZE; i++)
+  {
+     Page = MmGetPhysicalAddressForProcess(NULL, StartAddress + i * PAGE_SIZE);
+     MmDeleteVirtualMapping(NULL, StartAddress + i * PAGE_SIZE, FALSE, NULL, NULL);
+     MmDereferencePage(Page);
   }
-
-  DbgPrint("After exception2.\n");
-
-  __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER.OS.prev));
-  //KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
-
-  DbgPrint("Exiting.\n");
 }
 
-#endif
-
 VOID
 ExpInitializeExecutive(VOID)
 {
+  LARGE_INTEGER Timeout;
+  HANDLE ProcessHandle;
+  HANDLE ThreadHandle;
+  ULONG BootDriverCount;
   ULONG i;
   ULONG start;
   ULONG length;
   PCHAR name;
   CHAR str[50];
+  NTSTATUS Status;
+  BOOLEAN SetupBoot;
+  PCHAR p1, p2;
+  ULONG MaxMem;
+  BOOLEAN NoBootScreen = FALSE;
+  UNICODE_STRING Name;
+  HANDLE InitDoneEventHandle;
+  OBJECT_ATTRIBUTES ObjectAttributes;
 
   /*
    * Fail at runtime if someone has changed various structures without
@@ -786,6 +329,7 @@ ExpInitializeExecutive(VOID)
   assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
   assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
   assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
+  assert(FIELD_OFFSET(KTHREAD, ServiceTable) == KTHREAD_SERVICE_TABLE);
   assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
   assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
   assert(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
@@ -795,26 +339,128 @@ ExpInitializeExecutive(VOID)
   assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
   assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
   assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
-  
-  assert(FIELD_OFFSET(KPCR, ExceptionList) == KPCR_EXCEPTION_LIST);
+
+  assert(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
   assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
-  assert(FIELD_OFFSET(KPCR, CurrentThread) == KPCR_CURRENT_THREAD);
+  assert(FIELD_OFFSET(IKPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
+  assert(FIELD_OFFSET(IKPCR, Self) == KPCR_SELF);
+  assert(FIELD_OFFSET(IKPCR, CurrentThread) == KPCR_CURRENT_THREAD);
 
   LdrInit1();
 
   KeLowerIrql(DISPATCH_LEVEL);
   
   NtEarlyInitVdm();
-  
+
+  p1 = (PCHAR)KeLoaderBlock.CommandLine;
+
+  MaxMem = 0;
+  while(*p1 && (p2 = strchr(p1, '/')))
+  {
+     p2++;
+     if (!_strnicmp(p2, "MAXMEM", 6))
+     {
+        p2 += 6;
+        while (isspace(*p2)) p2++;
+       if (*p2 == '=')
+       {
+          p2++;
+          while(isspace(*p2)) p2++;
+          if (isdigit(*p2))
+          {
+             while (isdigit(*p2))
+             {
+                MaxMem = MaxMem * 10 + *p2 - '0';
+                p2++;
+             }
+             break;
+          }
+       }
+     }
+    else if (!_strnicmp(p2, "NOBOOTSCREEN", 12))
+      {
+        p2 += 12;
+        NoBootScreen = TRUE;
+      }
+     p1 = p2;
+  }
+
   MmInit1(FirstKrnlPhysAddr,
-    LastKrnlPhysAddr,
-    LastKernelAddress,
-    (PADDRESS_RANGE)&KeMemoryMap,
-    KeMemoryMapRangeCount);
-  
-  /* create default nls tables */
-  RtlpInitNlsTables();
-  
+         LastKrnlPhysAddr,
+         LastKernelAddress,
+         (PADDRESS_RANGE)&KeMemoryMap,
+         KeMemoryMapRangeCount,
+         MaxMem > 8 ? MaxMem : 4096);
+
+  /* Import ANSI code page table */
+  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+    {
+      start = KeLoaderModules[i].ModStart;
+      length = KeLoaderModules[i].ModEnd - start;
+
+      name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
+      if (name == NULL)
+       {
+         name = (PCHAR)KeLoaderModules[i].String;
+       }
+      else
+       {
+         name++;
+       }
+
+      if (!_stricmp (name, "ansi.nls"))
+       {
+         RtlpImportAnsiCodePage((PUSHORT)start, length);
+       }
+    }
+
+  /* Import OEM code page table */
+  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+    {
+      start = KeLoaderModules[i].ModStart;
+      length = KeLoaderModules[i].ModEnd - start;
+
+      name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
+      if (name == NULL)
+       {
+         name = (PCHAR)KeLoaderModules[i].String;
+       }
+      else
+       {
+         name++;
+       }
+
+      if (!_stricmp (name, "oem.nls"))
+       {
+         RtlpImportOemCodePage((PUSHORT)start, length);
+       }
+    }
+
+  /* Import Unicode casemap table */
+  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+    {
+      start = KeLoaderModules[i].ModStart;
+      length = KeLoaderModules[i].ModEnd - start;
+
+      name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
+      if (name == NULL)
+       {
+         name = (PCHAR)KeLoaderModules[i].String;
+       }
+      else
+       {
+         name++;
+       }
+
+      if (!_stricmp (name, "casemap.nls"))
+       {
+         RtlpImportUnicodeCasemap((PUSHORT)start, length);
+       }
+    }
+
+  /* Create initial NLS tables */
+  RtlpCreateInitialNlsTables();
+
   /*
    * Initialize the kernel debugger
    */
@@ -826,9 +472,13 @@ ExpInitializeExecutive(VOID)
   KeLowerIrql(PASSIVE_LEVEL);
 
   if (!SeInit1())
-    KeBugCheck(SECURITY_INITIALIZATION_FAILED);
+    KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
 
   ObInit();
+
+  if (!SeInit2())
+    KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
+
   PiInitProcessManager();
 
   KdInit1();
@@ -838,19 +488,6 @@ ExpInitializeExecutive(VOID)
       DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
     }
 
-  /*
-   * Display version number and copyright/warranty message
-   */
-  HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
-                  KERNEL_VERSION_BUILD_STR")\n");
-  HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
-  HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
-                  "Public License, and you\n");
-  HalDisplayString("are welcome to change it and/or distribute copies of it "
-                  "under certain\n"); 
-  HalDisplayString("conditions. There is absolutely no warranty for "
-                  "ReactOS.\n\n");
-
   /* Initialize all processors */
   KeNumberProcessors = 0;
 
@@ -873,21 +510,6 @@ ExpInitializeExecutive(VOID)
       KeNumberProcessors++;
     }
 
-  if (KeNumberProcessors > 1)
-    {
-      sprintf(str,
-             "Found %d system processors. [%lu MB Memory]\n",
-             KeNumberProcessors,
-             (KeLoaderBlock.MemHigher + 1088)/ 1024);
-    }
-  else
-    {
-      sprintf(str,
-             "Found 1 system processor. [%lu MB Memory]\n",
-             (KeLoaderBlock.MemHigher + 1088)/ 1024);
-    }
-  HalDisplayString(str);
-
   /*
    * Initialize various critical subsystems
    */
@@ -902,10 +524,56 @@ ExpInitializeExecutive(VOID)
   MmInit3();
   CcInit();
   KdInit2();
-  
+  FsRtlpInitFileLockingImplementation();
+
   /* Report all resources used by hal */
   HalReportResourceUsage();
-  
+
+  /* Display the boot screen image if not disabled */
+  if (!NoBootScreen)
+    {
+      InbvEnableBootDriver(TRUE);
+    }
+
+  /*
+   * Clear the screen to blue
+   */
+  HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+  /*
+   * Display version number and copyright/warranty message
+   */
+  HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
+                  KERNEL_VERSION_BUILD_STR")\n");
+  HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
+  HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
+                  "Public License, and you\n");
+  HalDisplayString("are welcome to change it and/or distribute copies of it "
+                  "under certain\n"); 
+  HalDisplayString("conditions. There is absolutely no warranty for "
+                  "ReactOS.\n\n");
+
+  if (KeNumberProcessors > 1)
+    {
+      sprintf(str,
+             "Found %d system processors. [%lu MB Memory]\n",
+             KeNumberProcessors,
+             (KeLoaderBlock.MemHigher + 1088)/ 1024);
+    }
+  else
+    {
+      sprintf(str,
+             "Found 1 system processor. [%lu MB Memory]\n",
+             (KeLoaderBlock.MemHigher + 1088)/ 1024);
+    }
+  HalDisplayString(str);
+
+  KdInit3();
+
+
+  /* Create the NLS section */
+  RtlpCreateNlsSection();
+
   /*
    * Initalize services loaded at boot time
    */
@@ -918,56 +586,56 @@ ExpInitializeExecutive(VOID)
        KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
     }
 
-  /*  Pass 1: load nls files  */
+  /* Pass 1: import system hive registry chunk */
+  SetupBoot = TRUE;
   for (i = 1; i < KeLoaderBlock.ModsCount; i++)
     {
-      name = (PCHAR)KeLoaderModules[i].String;
-      if (RtlpCheckFileNameExtension(name, ".nls"))
-       {
-         ULONG Mod2Start = 0;
-         ULONG Mod2End = 0;
-         ULONG Mod3Start = 0;
-         ULONG Mod3End = 0;
+      start = KeLoaderModules[i].ModStart;
+      length = KeLoaderModules[i].ModEnd - start;
 
-         name = (PCHAR)KeLoaderModules[i+1].String;
-         if (RtlpCheckFileNameExtension(name, ".nls"))
-           {
-             Mod2Start = (ULONG)KeLoaderModules[i+1].ModStart;
-             Mod2End = (ULONG)KeLoaderModules[i+1].ModEnd;
-
-             name = (PCHAR)KeLoaderModules[i+2].String;
-             if (RtlpCheckFileNameExtension(name, ".nls"))
-               {
-                 Mod3Start = (ULONG)KeLoaderModules[i+2].ModStart;
-                 Mod3End = (ULONG)KeLoaderModules[i+2].ModEnd;
-               }
-           }
+      DPRINT("Module: '%s'\n", (PCHAR)KeLoaderModules[i].String);
+      name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
+      if (name == NULL)
+       {
+         name = (PCHAR)KeLoaderModules[i].String;
+       }
+      else
+       {
+         name++;
+       }
 
-         /* Initialize nls sections */
-         RtlpInitNlsSections((ULONG)KeLoaderModules[i].ModStart,
-                             (ULONG)KeLoaderModules[i].ModEnd,
-                             Mod2Start,
-                             Mod2End,
-                             Mod3Start,
-                             Mod3End);
-         break;
+      if (!_stricmp (name, "system") ||
+         !_stricmp (name, "system.hiv"))
+       {
+         CPRINT("Process system hive registry chunk at %08lx\n", start);
+         SetupBoot = FALSE;
+         CmImportSystemHive((PCHAR)start, length);
        }
     }
 
-  /*  Pass 2: load registry chunks passed in  */
+  /* Pass 2: import hardware hive registry chunk */
   for (i = 1; i < KeLoaderBlock.ModsCount; i++)
     {
       start = KeLoaderModules[i].ModStart;
       length = KeLoaderModules[i].ModEnd - start;
       name = (PCHAR)KeLoaderModules[i].String;
-      if (RtlpCheckFileNameExtension(name, "") ||
-         RtlpCheckFileNameExtension(name, ".hiv"))
+      if (!_stricmp (name, "hardware") ||
+         !_stricmp (name, "hardware.hiv"))
        {
-         CPRINT("Process registry chunk at %08lx\n", start);
-         CmImportHive((PCHAR)start, length);
+         CPRINT("Process hardware hive registry chunk at %08lx\n", start);
+         CmImportHardwareHive((PCHAR)start, length);
        }
     }
 
+  /* Create dummy keys if no hardware hive was found */
+  CmImportHardwareHive (NULL, 0);
+
+  /* Initialize volatile registry settings */
+  if (SetupBoot == FALSE)
+    {
+      CmInit2((PCHAR)KeLoaderBlock.CommandLine);
+    }
+
   /*
    * Enter the kernel debugger before starting up the boot drivers
    */
@@ -975,7 +643,12 @@ ExpInitializeExecutive(VOID)
   KdbEnter();
 #endif /* KDBG */
 
-  /*  Pass 3: process boot loaded drivers  */
+  IoCreateDriverList();
+
+  IoInit2();
+
+  /* Pass 3: process boot loaded drivers */
+  BootDriverCount = 0;
   for (i=1; i < KeLoaderBlock.ModsCount; i++)
     {
       start = KeLoaderModules[i].ModStart;
@@ -984,10 +657,31 @@ ExpInitializeExecutive(VOID)
       if (RtlpCheckFileNameExtension(name, ".sys") ||
          RtlpCheckFileNameExtension(name, ".sym"))
        {
-         CPRINT("Processing module '%s' at %08lx, length 0x%08lx\n",
+         CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n",
                 name, start, length);
-         LdrProcessDriver((PVOID)start, name, length);
+         LdrInitializeBootStartDriver((PVOID)start, name, length);
        }
+      if (RtlpCheckFileNameExtension(name, ".sys"))
+       BootDriverCount++;
+    }
+
+  /* Pass 4: free memory for all boot files, except ntoskrnl.exe and hal.dll */
+  for (i = 2; i < KeLoaderBlock.ModsCount; i++)
+    {
+#ifdef KDBG
+       /* Do not free the memory from symbol files, if the kernel debugger is activ */
+       if (!RtlpCheckFileNameExtension(name, ".sym"))
+#endif
+         {
+           MiFreeBootDriverMemory((PVOID)KeLoaderModules[i].ModStart,
+                                 KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
+        }
+    }
+
+  if (BootDriverCount == 0)
+    {
+      DbgPrint("No boot drivers available.\n");
+      KEBUGCHECK(0);
     }
 
   /* Create ARC names for boot devices */
@@ -995,25 +689,23 @@ ExpInitializeExecutive(VOID)
 
   /* Create the SystemRoot symbolic link */
   CPRINT("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
-  IoCreateSystemRootLink((PUCHAR)KeLoaderBlock.CommandLine);
+  Status = IoCreateSystemRootLink((PUCHAR)KeLoaderBlock.CommandLine);
+  if (!NT_SUCCESS(Status))
+    KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
 
 #ifdef DBGPRINT_FILE_LOG
-  /* On the assumption that we can now access disks start up the debug 
+  /* On the assumption that we can now access disks start up the debug
      logger thread */
   DebugLogInit2();
 #endif /* DBGPRINT_FILE_LOG */
-  
 
-#if 0
-  CreateDefaultRegistry();
-#endif
+#ifdef KDBG
+  KdbInitProfiling2();
+#endif /* KDBG */
+
 
   PiInitDefaultLocale();
 
-  /*
-   * Start the motherboard enumerator (the HAL)
-   */
-  HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
 #if 0
   /*
    * Load boot start drivers
@@ -1025,6 +717,9 @@ ExpInitializeExecutive(VOID)
    */
   LdrLoadAutoConfigDrivers();
 #endif
+
+  IoDestroyDriverList();
+
   /*
    * Assign drive letters
    */
@@ -1039,13 +734,96 @@ ExpInitializeExecutive(VOID)
    */
   InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
 
-  if (!SeInit2())
-    KeBugCheck(SECURITY1_INITIALIZATION_FAILED);
+  /* Create 'ReactOSInitDone' event */
+  RtlInitUnicodeString(&Name, L"\\ReactOSInitDone");
+  InitializeObjectAttributes(&ObjectAttributes,
+    &Name,
+    0,
+    NULL,
+    NULL);
+  Status = NtCreateEvent(&InitDoneEventHandle,
+    EVENT_ALL_ACCESS,
+    &ObjectAttributes,
+    FALSE,              /* Synchronization event */
+    FALSE);             /* Not signalled */
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status);
+      InitDoneEventHandle = INVALID_HANDLE_VALUE;
+    }
 
   /*
    *  Launch initial process
    */
-  LdrLoadInitialProcess();
+  Status = LdrLoadInitialProcess(&ProcessHandle,
+                                &ThreadHandle);
+  if (!NT_SUCCESS(Status))
+    {
+      KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+  if (InitDoneEventHandle != INVALID_HANDLE_VALUE)
+    {
+      HANDLE Handles[2]; /* Init event, Initial process */
+
+      Handles[0] = InitDoneEventHandle;
+      Handles[1] = ProcessHandle;
+
+      /* Wait for the system to be initialized */
+      Timeout.QuadPart = -1200000000LL;  /* 120 second timeout */
+      Status = NtWaitForMultipleObjects(((LONG) sizeof(Handles) / sizeof(HANDLE)),
+        Handles,
+        WaitAny,
+        FALSE,    /* Non-alertable */
+        &Timeout);
+      if (!NT_SUCCESS(Status))
+        {
+          DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status);
+        }
+      else if (Status == STATUS_TIMEOUT)
+        {
+          DPRINT1("WARNING: System not initialized after 120 seconds.\n");
+        }
+      else if (Status == STATUS_WAIT_0 + 1)
+        {
+          /*
+           * Crash the system if the initial process was terminated.
+           */
+          KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        }
+
+      if (!NoBootScreen)
+        {
+          InbvEnableBootDriver(FALSE);
+        }
+
+      NtSetEvent(InitDoneEventHandle, NULL);
+
+      NtClose(InitDoneEventHandle);
+    }
+  else
+    {
+      /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
+      if (!NoBootScreen)
+        {
+          InbvEnableBootDriver(FALSE);
+        }
+
+      /*
+       * Crash the system if the initial process terminates within 5 seconds.
+       */
+      Timeout.QuadPart = -50000000LL;
+      Status = NtWaitForSingleObject(ProcessHandle,
+                                FALSE,
+                                &Timeout);
+      if (Status != STATUS_TIMEOUT)
+        {
+          KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        }
+    }
+
+  NtClose(ThreadHandle);
+  NtClose(ProcessHandle);
 
   PsTerminateSystemThread(STATUS_SUCCESS);
 }
@@ -1060,14 +838,14 @@ KiSystemStartup(BOOLEAN BootProcessor)
     {
       /* Never returns */
       ExpInitializeExecutive();
-      KeBugCheck(0);
+      KEBUGCHECK(0);
     }
   /* Do application processor initialization */
   KeApplicationProcessorInit();
   PsApplicationProcessorInit();
   KeLowerIrql(PASSIVE_LEVEL);
   PsIdleThreadMain(NULL);
-  KeBugCheck(0);
+  KEBUGCHECK(0);
   for(;;);
 }
 
@@ -1096,28 +874,84 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
   /*
    * Copy the parameters to a local buffer because lowmem will go away
    */
-  memcpy (&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
-  memcpy (&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
-         sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
+  memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+  memcpy(&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
+        sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
   KeLoaderBlock.ModsCount++;
   KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
-  
+
   /*
-   * FIXME: Preliminary hack!!!! Add boot device to beginning of command line.
-   * This should be done by the boot loader.
+   * Convert a path specification in the grub format to one understood by the
+   * rest of the kernel.
    */
-  strcpy (KeLoaderCommandLine,
-         "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN");
-/*  strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine); */
-  
+  if (((PUCHAR)_LoaderBlock->CommandLine)[0] == '(')
+    {
+      ULONG DiskNumber = 0, PartNumber = 0;
+      PCH p;
+      CHAR Temp[256];
+      PCH options;
+      PCH s1;
+
+      if (((PUCHAR)_LoaderBlock->CommandLine)[1] == 'h' &&
+         ((PUCHAR)_LoaderBlock->CommandLine)[2] == 'd')
+       {
+         DiskNumber = ((PUCHAR)_LoaderBlock->CommandLine)[3] - '0';
+         PartNumber = ((PUCHAR)_LoaderBlock->CommandLine)[5] - '0';
+       }
+      strcpy(Temp, &((PUCHAR)_LoaderBlock->CommandLine)[7]);
+      if ((options = strchr(Temp, ' ')) != NULL)
+       {
+         *options = 0;
+         options++;
+       }
+      else
+       {
+         options = "";
+       }
+      if ((s1 = strrchr(Temp, '/')) != NULL)
+       {
+         *s1 = 0;
+         if ((s1 = strrchr(Temp, '/')) != NULL)
+           {
+             *s1 = 0;
+           }
+       }
+      sprintf(KeLoaderCommandLine, 
+             "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s",
+             DiskNumber, PartNumber + 1, Temp, options);
+
+      p = KeLoaderCommandLine;
+      while (*p != 0 && *p != ' ')
+       {
+         if ((*p) == '/')
+           {
+             (*p) = '\\';
+           }
+         p++;
+       }
+      DPRINT1("Command Line: %s\n", KeLoaderCommandLine);
+    }
+  else
+    {
+      strcpy(KeLoaderCommandLine, (PUCHAR)_LoaderBlock->CommandLine);
+    }
   KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
+  
   strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
   KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
   KeLoaderModules[0].ModStart = 0xC0000000;
   KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
   for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {
-      strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
+    {      
+      CHAR* s;
+      if ((s = strrchr((PUCHAR)KeLoaderModules[i].String, '/')) != 0)
+       {
+         strcpy(KeLoaderModuleStrings[i], s + 1);
+       }
+      else
+       {
+         strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
+       }
       KeLoaderModules[i].ModStart -= 0x200000;
       KeLoaderModules[i].ModStart += 0xc0000000;
       KeLoaderModules[i].ModEnd -= 0x200000;
@@ -1130,7 +964,8 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
 #endif
 
   HalBase = KeLoaderModules[1].ModStart;
-  DriverBase = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;
+  DriverBase = 
+    PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
 
   /*
    * Process hal.dll