Fix a couple of problems with FreeLDR portability.
[reactos.git] / reactos / boot / freeldr / freeldr / reactos / reactos.c
index 9cafa6a..87e6414 100644 (file)
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         Freeloader
- * FILE:            boot/freeldr/freeldr/reactos/rosboot.c
- * PURPOSE:         ReactOS Loader
- * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *  FreeLoader
+ *
+ *  Copyright (C) 1998-2003  Brian Palmer  <brianp@sginet.com>
+ *  Copyright (C) 2005       Alex Ionescu  <alex@relsoft.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <freeldr.h>
-#include <internal/i386/ke.h>
-#include <reactos/rossym.h>
-
-#include "registry.h"
-
-#define NDEBUG
 #include <debug.h>
 
-#define IsRecognizedPartition(P)  \
-    ((P) == PARTITION_FAT_12       || \
-     (P) == PARTITION_FAT_16       || \
-     (P) == PARTITION_HUGE         || \
-     (P) == PARTITION_IFS          || \
-     (P) == PARTITION_EXT2         || \
-     (P) == PARTITION_FAT32        || \
-     (P) == PARTITION_FAT32_XINT13 || \
-     (P) == PARTITION_XINT13)
-
-BOOL
-STDCALL
-FrLdrLoadKernel(PCHAR szFileName,
+extern ULONG PageDirectoryStart;
+extern ULONG PageDirectoryEnd;
+
+ROS_LOADER_PARAMETER_BLOCK LoaderBlock;
+char                                   reactos_kernel_cmdline[255];    // Command line passed to kernel
+LOADER_MODULE                  reactos_modules[64];            // Array to hold boot module info loaded for the kernel
+char                                   reactos_module_strings[64][256];        // Array to hold module names
+// Make this a single struct to guarantee that these elements are nearby in
+// memory.  
+reactos_mem_data_t reactos_mem_data;
+ARC_DISK_SIGNATURE      reactos_arc_disk_info[32]; // ARC Disk Information
+char                    reactos_arc_strings[32][256];
+unsigned long           reactos_disk_count = 0;
+char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE] = {0};
+
+CHAR szHalName[255];
+CHAR szBootPath[255];
+CHAR SystemRoot[255];
+static CHAR szLoadingMsg[] = "Loading ReactOS...";
+BOOLEAN FrLdrBootType;
+ULONG_PTR KernelBase;
+ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
+
+BOOLEAN
+FrLdrLoadDriver(PCHAR szFileName,
                 INT nPos)
+{
+    PFILE FilePointer;
+    CHAR value[256], *FinalSlash;
+    LPSTR p;
+
+    if (!_stricmp(szFileName, "hal.dll"))
+    {
+        /* Use the boot.ini name instead */
+        szFileName = szHalName;
+    }
+
+    FinalSlash = strrchr(szFileName, '\\');
+    if(FinalSlash)
+       szFileName = FinalSlash + 1;
+
+    /* Open the Driver */
+    FilePointer = FsOpenFile(szFileName);
+
+    /* Try under the system root in the main dir and drivers */
+    if (FilePointer == NULL)
+    {
+       strcpy(value, SystemRoot);
+       if(value[strlen(value)-1] != '\\')
+           strcat(value, "\\");
+       strcat(value, szFileName);
+       FilePointer = FsOpenFile(value);
+    }
+
+    if (FilePointer == NULL)
+    {
+       strcpy(value, SystemRoot);
+       if(value[strlen(value)-1] != '\\')
+           strcat(value, "\\");
+       strcat(value, "SYSTEM32\\");
+       strcat(value, szFileName);
+       FilePointer = FsOpenFile(value);
+    }
+
+    if (FilePointer == NULL)
+    {
+       strcpy(value, SystemRoot);
+       if(value[strlen(value)-1] != '\\')
+           strcat(value, "\\");
+       strcat(value, "SYSTEM32\\DRIVERS\\");
+       strcat(value, szFileName);
+       FilePointer = FsOpenFile(value);
+    }
+
+    /* Make sure we did */
+    if (FilePointer == NULL) {
+
+        /* Fail if file wasn't opened */
+        strcpy(value, szFileName);
+        strcat(value, " not found.");
+        return(FALSE);
+    }
+
+    /* Update the status bar with the current file */
+    strcpy(value, "Reading ");
+    p = strrchr(szFileName, '\\');
+    if (p == NULL) {
+
+        strcat(value, szFileName);
+
+    } else {
+
+        strcat(value, p + 1);
+
+    }
+    UiDrawStatusText(value);
+
+    /* Load the driver */
+    FrLdrMapImage(FilePointer, szFileName, 0);
+
+    /* Update status and return */
+    UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
+    return(TRUE);
+}
+
+PVOID
+NTAPI
+FrLdrLoadImage(IN PCHAR szFileName,
+               IN INT nPos,
+               IN ULONG ImageType)
 {
     PFILE FilePointer;
     PCHAR szShortName;
-    CHAR szBuffer[256];
+    CHAR szBuffer[256], szFullPath[256];
+    PVOID LoadBase;
 
-    /* Extract Kernel filename without path */
+    /* Extract filename without path */
     szShortName = strrchr(szFileName, '\\');
-    if (szShortName == NULL) {
-        
+    if (!szShortName)
+    {
         /* No path, leave it alone */
         szShortName = szFileName;
-        
-    } else {
-        
+
+        /* Which means we need to build a path now */
+        strcpy(szBuffer, szFileName);
+        strcpy(szFullPath, szBootPath);
+        if (!FrLdrBootType)
+        {
+            strcat(szFullPath, "SYSTEM32\\DRIVERS\\");
+        }
+        else
+        {
+            strcat(szFullPath, "\\");
+        }
+        strcat(szFullPath, szBuffer);
+        szFileName = szFullPath;
+    }
+    else
+    {
         /* Skip the path */
         szShortName = szShortName + 1;
     }
 
-    /* Open the Kernel */
+    /* Open the image */
     FilePointer = FsOpenFile(szFileName);
-    
-    /* Make sure it worked */
-    if (FilePointer == NULL) {
-        
+    if (!FilePointer)
+    {
         /* Return failure on the short name */
         strcpy(szBuffer, szShortName);
         strcat(szBuffer, " not found.");
         UiMessageBox(szBuffer);
-        return(FALSE);
+        return FALSE;
     }
 
     /* Update the status bar with the current file */
@@ -66,78 +182,16 @@ FrLdrLoadKernel(PCHAR szFileName,
     UiDrawStatusText(szBuffer);
 
     /* Do the actual loading */
-    FrLdrMapKernel(FilePointer);
+    LoadBase = FrLdrMapImage(FilePointer, szShortName, ImageType);
 
     /* Update Processbar and return success */
-    UiDrawProgressBarCenter(nPos, 100, "Loading ReactOS...");
-    return(TRUE);
-}
-
-static VOID
-FreeldrFreeMem(PVOID Area)
-{
-  MmFreeMemory(Area);
-}
-
-static PVOID
-FreeldrAllocMem(ULONG_PTR Size)
-{
-  return MmAllocateMemory((ULONG) Size);
-}
-
-static BOOLEAN
-FreeldrReadFile(PVOID FileContext, PVOID Buffer, ULONG Size)
-{
-  ULONG BytesRead;
-  
-  return FsReadFile((PFILE) FileContext, (ULONG) Size, &BytesRead, Buffer)
-         && Size == BytesRead;
+    if (!FrLdrBootType) UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
+    return LoadBase;
 }
 
 static BOOLEAN
-FreeldrSeekFile(PVOID FileContext, ULONG_PTR Position)
-{
-  FsSetFilePointer((PFILE) FileContext, (ULONG) Position);
-    return TRUE;
-}
-
-static BOOL
-LoadKernelSymbols(PCHAR szKernelName, int nPos)
-{
-  static ROSSYM_CALLBACKS FreeldrCallbacks =
-    {
-      FreeldrAllocMem,
-      FreeldrFreeMem,
-      FreeldrReadFile,
-      FreeldrSeekFile
-    };
-  PFILE FilePointer;
-  PROSSYM_INFO RosSymInfo;
-  ULONG Size;
-  ULONG_PTR Base;
-
-  RosSymInit(&FreeldrCallbacks);
-
-  FilePointer = FsOpenFile(szKernelName);
-  if (FilePointer == NULL)
-    {
-      return FALSE;
-    }
-  if (! RosSymCreateFromFile(FilePointer, &RosSymInfo))
-    {
-      return FALSE;
-    }
-  Base = FrLdrCreateModule("NTOSKRNL.SYM");
-  Size = RosSymGetRawDataLength(RosSymInfo);
-  RosSymGetRawData(RosSymInfo, (PVOID)Base);
-  FrLdrCloseModule(Base, Size);
-  RosSymDelete(RosSymInfo);
-  return TRUE;
-}
-  
-BOOL
-FrLdrLoadNlsFile(PCHAR szFileName, 
-                 PCHAR szModuleName)
+FrLdrLoadNlsFile(PCSTR szFileName,
+                 PCSTR szModuleName)
 {
     PFILE FilePointer;
     CHAR value[256];
@@ -145,10 +199,10 @@ FrLdrLoadNlsFile(PCHAR szFileName,
 
     /* Open the Driver */
     FilePointer = FsOpenFile(szFileName);
-    
+
     /* Make sure we did */
     if (FilePointer == NULL) {
-        
+
         /* Fail if file wasn't opened */
         strcpy(value, szFileName);
         strcat(value, " not found.");
@@ -160,11 +214,11 @@ FrLdrLoadNlsFile(PCHAR szFileName,
     strcpy(value, "Reading ");
     p = strrchr(szFileName, '\\');
     if (p == NULL) {
-        
+
         strcat(value, szFileName);
-        
+
     } else {
-        
+
         strcat(value, p + 1);
     }
     UiDrawStatusText(value);
@@ -174,414 +228,355 @@ FrLdrLoadNlsFile(PCHAR szFileName,
     return(TRUE);
 }
 
-BOOL
-FrLdrLoadNlsFiles(PCHAR szSystemRoot, 
+static BOOLEAN
+FrLdrLoadNlsFiles(PCHAR szSystemRoot,
                   PCHAR szErrorOut)
 {
     LONG rc = ERROR_SUCCESS;
     FRLDRHKEY hKey;
-    CHAR szIdBuffer[80];
-    CHAR szNameBuffer[80];
+    WCHAR szIdBuffer[80];
+    WCHAR szNameBuffer[80];
     CHAR szFileName[256];
     ULONG BufferSize;
 
     /* open the codepage key */
     rc = RegOpenKey(NULL,
-                    "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
+                    L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
                     &hKey);
     if (rc != ERROR_SUCCESS) {
-        
+
         strcpy(szErrorOut, "Couldn't open CodePage registry key");
         return(FALSE);
     }
-    
+
     /* get ANSI codepage */
-    BufferSize = 80;
-    rc = RegQueryValue(hKey, "ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
+    BufferSize = sizeof(szIdBuffer);
+    rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
     if (rc != ERROR_SUCCESS) {
-        
+
         strcpy(szErrorOut, "Couldn't get ACP NLS setting");
         return(FALSE);
     }
 
-    BufferSize = 80;
+    BufferSize = sizeof(szNameBuffer);
     rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
     if (rc != ERROR_SUCCESS) {
-        
+
         strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
         return(FALSE);
     }
 
     /* load ANSI codepage table */
-    strcpy(szFileName, szSystemRoot);
-    strcat(szFileName, "system32\\");
-    strcat(szFileName, szNameBuffer);
+    sprintf(szFileName,"%ssystem32\\%S", szSystemRoot, szNameBuffer);
     DbgPrint((DPRINT_REACTOS, "ANSI file: %s\n", szFileName));
     if (!FrLdrLoadNlsFile(szFileName, "ansi.nls")) {
-        
+
         strcpy(szErrorOut, "Couldn't load ansi.nls");
         return(FALSE);
     }
 
     /* get OEM codepage */
-    BufferSize = 80;
-    rc = RegQueryValue(hKey, "OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
+    BufferSize = sizeof(szIdBuffer);
+    rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
     if (rc != ERROR_SUCCESS) {
-        
+
         strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
         return(FALSE);
     }
 
-    BufferSize = 80;
+    BufferSize = sizeof(szNameBuffer);
     rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
     if (rc != ERROR_SUCCESS) {
-        
+
         strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
         return(FALSE);
     }
 
     /* load OEM codepage table */
-    strcpy(szFileName, szSystemRoot);
-    strcat(szFileName, "system32\\");
-    strcat(szFileName, szNameBuffer);
+    sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
     DbgPrint((DPRINT_REACTOS, "Oem file: %s\n", szFileName));
     if (!FrLdrLoadNlsFile(szFileName, "oem.nls")) {
-        
+
         strcpy(szErrorOut, "Couldn't load oem.nls");
         return(FALSE);
     }
 
     /* open the language key */
     rc = RegOpenKey(NULL,
-                    "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
+                    L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
                     &hKey);
     if (rc != ERROR_SUCCESS) {
-        
+
         strcpy(szErrorOut, "Couldn't open Language registry key");
         return(FALSE);
     }
 
     /* get the Unicode case table */
-    BufferSize = 80;
-    rc = RegQueryValue(hKey, "Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
+    BufferSize = sizeof(szIdBuffer);
+    rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
     if (rc != ERROR_SUCCESS) {
-        
+
         strcpy(szErrorOut, "Couldn't get Language Default setting");
         return(FALSE);
     }
 
-    BufferSize = 80;
+    BufferSize = sizeof(szNameBuffer);
     rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
     if (rc != ERROR_SUCCESS) {
-        
+
         strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
         return(FALSE);
     }
 
     /* load Unicode case table */
-    strcpy(szFileName, szSystemRoot);
-    strcat(szFileName, "system32\\");
-    strcat(szFileName, szNameBuffer);
+    sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
     DbgPrint((DPRINT_REACTOS, "Casemap file: %s\n", szFileName));
     if (!FrLdrLoadNlsFile(szFileName, "casemap.nls")) {
-        
-        strcpy(szErrorOut, "casemap.nls");
-        return(FALSE);
-    }
-
-    return(TRUE);
-}
-
-BOOL
-FrLdrLoadDriver(PCHAR szFileName, 
-                INT nPos)
-{
-    PFILE FilePointer;
-    CHAR value[256];
-    LPSTR p;
 
-    /* Open the Driver */
-    FilePointer = FsOpenFile(szFileName);
-    
-    /* Make sure we did */
-    if (FilePointer == NULL) {
-        
-        /* Fail if file wasn't opened */
-        strcpy(value, szFileName);
-        strcat(value, " not found.");
-        UiMessageBox(value);
+        strcpy(szErrorOut, "casemap.nls");
         return(FALSE);
     }
 
-    /* Update the status bar with the current file */
-    strcpy(value, "Reading ");
-    p = strrchr(szFileName, '\\');
-    if (p == NULL) {
-      
-        strcat(value, szFileName);
-  
-    } else {
-        
-        strcat(value, p + 1);
-        
-    }
-    UiDrawStatusText(value);
-
-    /* Load the driver */
-    FrLdrLoadModule(FilePointer, szFileName, NULL);
-
-    /* Update status and return */
-    UiDrawProgressBarCenter(nPos, 100, "Loading ReactOS...");
     return(TRUE);
 }
 
-VOID
-FrLdrLoadBootDrivers(PCHAR szSystemRoot, 
+static VOID
+FrLdrLoadBootDrivers(PCHAR szSystemRoot,
                      INT nPos)
 {
     LONG rc = 0;
     FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey;
-    CHAR GroupNameBuffer[512];
-    CHAR ServiceName[256];
+    WCHAR GroupNameBuffer[512];
+    WCHAR ServiceName[256];
     ULONG OrderList[128];
     ULONG BufferSize;
     ULONG Index;
     ULONG TagIndex;
-    LPSTR GroupName;
+    LPWSTR GroupName;
 
     ULONG ValueSize;
     ULONG ValueType;
     ULONG StartValue;
     ULONG TagValue;
-    UCHAR DriverGroup[256];
+    WCHAR DriverGroup[256];
     ULONG DriverGroupSize;
 
-    UCHAR ImagePath[256];
-    UCHAR TempImagePath[256];
+    CHAR ImagePath[256];
+    WCHAR TempImagePath[256];
 
     /* get 'service group order' key */
     rc = RegOpenKey(NULL,
-                    "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
+                    L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
                     &hGroupKey);
     if (rc != ERROR_SUCCESS) {
-        
+
         DbgPrint((DPRINT_REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc));
         return;
     }
-  
+
     /* get 'group order list' key */
     rc = RegOpenKey(NULL,
-                    "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
+                    L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
                     &hOrderKey);
     if (rc != ERROR_SUCCESS) {
-        
+
         DbgPrint((DPRINT_REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc));
         return;
     }
 
     /* enumerate drivers */
     rc = RegOpenKey(NULL,
-                    "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
+                    L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
                     &hServiceKey);
     if (rc != ERROR_SUCCESS)  {
-        
+
         DbgPrint((DPRINT_REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc));
         return;
     }
 
     /* Get the Name Group */
     BufferSize = sizeof(GroupNameBuffer);
-    rc = RegQueryValue(hGroupKey, "List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
+    rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
     DbgPrint((DPRINT_REACTOS, "RegQueryValue(): rc %d\n", (int)rc));
     if (rc != ERROR_SUCCESS) return;
     DbgPrint((DPRINT_REACTOS, "BufferSize: %d \n", (int)BufferSize));
-    DbgPrint((DPRINT_REACTOS, "GroupNameBuffer: '%s' \n", GroupNameBuffer));
+    DbgPrint((DPRINT_REACTOS, "GroupNameBuffer: '%S' \n", GroupNameBuffer));
 
     /* Loop through each group */
     GroupName = GroupNameBuffer;
     while (*GroupName) {
-        DbgPrint((DPRINT_REACTOS, "Driver group: '%s'\n", GroupName));
+        DbgPrint((DPRINT_REACTOS, "Driver group: '%S'\n", GroupName));
 
         /* Query the Order */
         BufferSize = sizeof(OrderList);
         rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
         if (rc != ERROR_SUCCESS) OrderList[0] = 0;
-      
+
         /* enumerate all drivers */
-        for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
-    
+        for (TagIndex = 1; TagIndex <= SWAPD(OrderList[0]); TagIndex++) {
+
             Index = 0;
-        
+
             while (TRUE) {
-            
+
                 /* Get the Driver's Name */
                 ValueSize = sizeof(ServiceName);
                 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
                 DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
-            
+
                 /* Makre sure it's valid, and check if we're done */
                 if (rc == ERROR_NO_MORE_ITEMS) break;
                 if (rc != ERROR_SUCCESS) return;
-                DbgPrint((DPRINT_REACTOS, "Service %d: '%s'\n", (int)Index, ServiceName));
+                DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName));
 
                 /* open driver Key */
                 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
+                if (rc == ERROR_SUCCESS)
+                               {
+                    /* Read the Start Value */
+                    ValueSize = sizeof(ULONG);
+                    rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
+                    if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
+                    DbgPrint((DPRINT_REACTOS, "  Start: %x  \n", (int)StartValue));
+
+                    /* Read the Tag */
+                    ValueSize = sizeof(ULONG);
+                    rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
+                    if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
+                    DbgPrint((DPRINT_REACTOS, "  Tag:   %x  \n", (int)TagValue));
+
+                    /* Read the driver's group */
+                    DriverGroupSize = sizeof(DriverGroup);
+                    rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
+                    DbgPrint((DPRINT_REACTOS, "  Group: '%S'  \n", DriverGroup));
+
+                    /* Make sure it should be started */
+                    if ((StartValue == 0) &&
+                        (TagValue == OrderList[TagIndex]) &&
+                        (_wcsicmp(DriverGroup, GroupName) == 0)) {
+
+                        /* Get the Driver's Location */
+                        ValueSize = sizeof(TempImagePath);
+                        rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
+
+                        /* Write the whole path if it suceeded, else prepare to fail */
+                        if (rc != ERROR_SUCCESS) {
+                            DbgPrint((DPRINT_REACTOS, "  ImagePath: not found\n"));
+                            sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", szSystemRoot, ServiceName);
+                        } else if (TempImagePath[0] != L'\\') {
+                            sprintf(ImagePath, "%s%S", szSystemRoot, TempImagePath);
+                        } else {
+                            sprintf(ImagePath, "%S", TempImagePath);
+                            DbgPrint((DPRINT_REACTOS, "  ImagePath: '%s'\n", ImagePath));
+                        }
+
+                        DbgPrint((DPRINT_REACTOS, "  Loading driver: '%s'\n", ImagePath));
+
+                        /* Update the position if needed */
+                        if (nPos < 100) nPos += 5;
+
+                        FrLdrLoadImage(ImagePath, nPos, 2);
 
-                /* Read the Start Value */
-                ValueSize = sizeof(ULONG);
-                rc = RegQueryValue(hDriverKey, "Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
-                DbgPrint((DPRINT_REACTOS, "  Start: %x  \n", (int)StartValue));
-
-                /* Read the Tag */
-                ValueSize = sizeof(ULONG);
-                rc = RegQueryValue(hDriverKey, "Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
-                if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
-                DbgPrint((DPRINT_REACTOS, "  Tag:   %x  \n", (int)TagValue));
-
-                /* Read the driver's group */
-                DriverGroupSize = 256;
-                rc = RegQueryValue(hDriverKey, "Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
-                DbgPrint((DPRINT_REACTOS, "  Group: '%s'  \n", DriverGroup));
-
-                /* Make sure it should be started */
-                if ((StartValue == 0) && 
-                    (TagValue == OrderList[TagIndex]) && 
-                    (stricmp(DriverGroup, GroupName) == 0)) {
-
-                    /* Get the Driver's Location */
-                    ValueSize = 256;
-                    rc = RegQueryValue(hDriverKey, "ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
-                    
-                    /* Write the whole path if it suceeded, else prepare to fail */
-                    if (rc != ERROR_SUCCESS) {
-                        DbgPrint((DPRINT_REACTOS, "  ImagePath: not found\n"));
-                        strcpy(ImagePath, szSystemRoot);
-                        strcat(ImagePath, "system32\\drivers\\");
-                        strcat(ImagePath, ServiceName);
-                        strcat(ImagePath, ".sys");
-                    } else if (TempImagePath[0] != '\\') {
-                        strcpy(ImagePath, szSystemRoot);
-                        strcat(ImagePath, TempImagePath);
                     } else {
-                        strcpy(ImagePath, TempImagePath);
-                        DbgPrint((DPRINT_REACTOS, "  ImagePath: '%s'\n", ImagePath));
+
+                        DbgPrint((DPRINT_REACTOS, "  Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
+                                 ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName));
                     }
-                    
-                    DbgPrint((DPRINT_REACTOS, "  Loading driver: '%s'\n", ImagePath));
-    
-                    /* Update the position if needed */
-                    if (nPos < 100) nPos += 5;
-                    
-                    FrLdrLoadDriver(ImagePath, nPos);
-                    
-                } else {
-                        
-                    DbgPrint((DPRINT_REACTOS, "  Skipping driver '%s' with Start %d, Tag %d and Group '%s' (Current Tag %d, current group '%s')\n",
-                    ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName));
                 }
-            
+
                 Index++;
             }
-        }  
+        }
 
         Index = 0;
         while (TRUE) {
-        
+
             /* Get the Driver's Name */
             ValueSize = sizeof(ServiceName);
             rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
-        
+
             DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
             if (rc == ERROR_NO_MORE_ITEMS) break;
             if (rc != ERROR_SUCCESS) return;
-            DbgPrint((DPRINT_REACTOS, "Service %d: '%s'\n", (int)Index, ServiceName));
+            DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName));
 
             /* open driver Key */
             rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
+            if (rc == ERROR_SUCCESS)
+            {
+                /* Read the Start Value */
+                ValueSize = sizeof(ULONG);
+                rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
+                if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
+                DbgPrint((DPRINT_REACTOS, "  Start: %x  \n", (int)StartValue));
 
-            /* Read the Start Value */
-            ValueSize = sizeof(ULONG);
-            rc = RegQueryValue(hDriverKey, "Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
-            DbgPrint((DPRINT_REACTOS, "  Start: %x  \n", (int)StartValue));
+                /* Read the Tag */
+                ValueSize = sizeof(ULONG);
+                rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
+                if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
+                DbgPrint((DPRINT_REACTOS, "  Tag:   %x  \n", (int)TagValue));
 
-            /* Read the Tag */
-            ValueSize = sizeof(ULONG);
-            rc = RegQueryValue(hDriverKey, "Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
-            if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
-            DbgPrint((DPRINT_REACTOS, "  Tag:   %x  \n", (int)TagValue));
+                /* Read the driver's group */
+                DriverGroupSize = sizeof(DriverGroup);
+                rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
+                DbgPrint((DPRINT_REACTOS, "  Group: '%S'  \n", DriverGroup));
 
-            /* Read the driver's group */
-            DriverGroupSize = 256;
-            rc = RegQueryValue(hDriverKey, "Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
-            DbgPrint((DPRINT_REACTOS, "  Group: '%s'  \n", DriverGroup));
+                for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
+                    if (TagValue == OrderList[TagIndex]) break;
+                }
 
-            for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
-                if (TagValue == OrderList[TagIndex]) break;
-            }
-    
-            if ((StartValue == 0) && 
-                (TagIndex > OrderList[0]) && 
-                (stricmp(DriverGroup, GroupName) == 0)) {
-                
-                    ValueSize = 256;
-                    rc = RegQueryValue(hDriverKey, "ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
-                    if (rc != ERROR_SUCCESS) {
-                        DbgPrint((DPRINT_REACTOS, "  ImagePath: not found\n"));
-                        strcpy(ImagePath, szSystemRoot);
-                        strcat(ImagePath, "system32\\drivers\\");
-                        strcat(ImagePath, ServiceName);
-                        strcat(ImagePath, ".sys");
-                    } else if (TempImagePath[0] != '\\') {
-                        strcpy(ImagePath, szSystemRoot);
-                        strcat(ImagePath, TempImagePath);
-                    } else {
-                        strcpy(ImagePath, TempImagePath);
-                        DbgPrint((DPRINT_REACTOS, "  ImagePath: '%s'\n", ImagePath));
-                    }
-                DbgPrint((DPRINT_REACTOS, "  Loading driver: '%s'\n", ImagePath));
-    
-                if (nPos < 100) nPos += 5;
-    
-                FrLdrLoadDriver(ImagePath, nPos);                
-                
-            } else {
-                
-                DbgPrint((DPRINT_REACTOS, "  Skipping driver '%s' with Start %d, Tag %d and Group '%s' (Current group '%s')\n",
-                ServiceName, StartValue, TagValue, DriverGroup, GroupName));
+                if ((StartValue == 0) &&
+                    (TagIndex > OrderList[0]) &&
+                    (_wcsicmp(DriverGroup, GroupName) == 0)) {
+
+                        ValueSize = sizeof(TempImagePath);
+                        rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
+                        if (rc != ERROR_SUCCESS) {
+                            DbgPrint((DPRINT_REACTOS, "  ImagePath: not found\n"));
+                            sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", szSystemRoot, ServiceName);
+                        } else if (TempImagePath[0] != L'\\') {
+                            sprintf(ImagePath, "%s%S", szSystemRoot, TempImagePath);
+                        } else {
+                            sprintf(ImagePath, "%S", TempImagePath);
+                            DbgPrint((DPRINT_REACTOS, "  ImagePath: '%s'\n", ImagePath));
+                        }
+                    DbgPrint((DPRINT_REACTOS, "  Loading driver: '%s'\n", ImagePath));
+
+                    if (nPos < 100) nPos += 5;
+
+                    FrLdrLoadImage(ImagePath, nPos, 2);
+
+                } else {
+
+                    DbgPrint((DPRINT_REACTOS, "  Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
+                    ServiceName, StartValue, TagValue, DriverGroup, GroupName));
+                }
             }
-        
+
             Index++;
         }
 
         /* Move to the next group name */
-        GroupName = GroupName + strlen(GroupName) + 1;
+        GroupName = GroupName + wcslen(GroupName) + 1;
     }
 }
 
 VOID
-LoadAndBootReactOS(PUCHAR OperatingSystemName)
+LoadAndBootReactOS(PCSTR OperatingSystemName)
 {
        PFILE FilePointer;
-       CHAR  name[1024];
-       CHAR  value[1024];
-       CHAR  szKernelName[1024];
-       CHAR  szHalName[1024];
-       CHAR  szFileName[1024];
-       CHAR  szBootPath[256];
-       INT   i;
+       CHAR name[255];
+       CHAR value[255];
+       CHAR SystemPath[255];
+       CHAR szKernelName[255];
+       CHAR szFileName[255];
        CHAR  MsgBuffer[256];
        ULONG SectionId;
-
+    PIMAGE_NT_HEADERS NtHeader;
+    PVOID LoadBase;
        ULONG_PTR Base;
        ULONG Size;
 
-       PARTITION_TABLE_ENTRY PartitionTableEntry;
-       ULONG rosPartition;
-       extern ULONG PageDirectoryStart;
-       extern ULONG PageDirectoryEnd;
-       extern BOOLEAN AcpiPresent;
-
        //
        // Open the operating system section
        // specified in the .ini file
@@ -593,49 +588,64 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
                return;
        }
 
+       UiDrawBackdrop();
+       UiDrawStatusText("Detecting Hardware...");
+    UiDrawProgressBarCenter(1, 100, szLoadingMsg);
+
        /*
         * Setup multiboot information structure
         */
-       LoaderBlock.Flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
+       LoaderBlock.CommandLine = reactos_kernel_cmdline;
        LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart;
        LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd;
-       LoaderBlock.BootDevice = 0xffffffff;
-       LoaderBlock.CommandLine = (unsigned long)multiboot_kernel_cmdline;
        LoaderBlock.ModsCount = 0;
-       LoaderBlock.ModsAddr = (unsigned long)multiboot_modules;
-       LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)(PVOID)&multiboot_memory_map, 32) * sizeof(memory_map_t);
-       if (LoaderBlock.MmapLength)
-       {
-               LoaderBlock.MmapAddr = (unsigned long)&multiboot_memory_map;
-               LoaderBlock.Flags |= MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_MEMORY_MAP;
-               multiboot_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
-               DbgPrint((DPRINT_REACTOS, "memory map length: %d\n", LoaderBlock.MmapLength));
-               DbgPrint((DPRINT_REACTOS, "dumping memory map:\n"));
-               for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
-               {
-                       if (MEMTYPE_USABLE == multiboot_memory_map[i].type &&
-                           0 == multiboot_memory_map[i].base_addr_low)
-                       {
-                               LoaderBlock.MemLower = (multiboot_memory_map[i].base_addr_low + multiboot_memory_map[i].length_low) / 1024;
-                               if (640 < LoaderBlock.MemLower)
-                               {
-                                       LoaderBlock.MemLower = 640;
-                               }
-                       }
-                       if (MEMTYPE_USABLE == multiboot_memory_map[i].type &&
-                           multiboot_memory_map[i].base_addr_low <= 1024 * 1024 &&
-                           1024 * 1024 <= multiboot_memory_map[i].base_addr_low + multiboot_memory_map[i].length_low)
-                       {
-                               LoaderBlock.MemHigher = (multiboot_memory_map[i].base_addr_low + multiboot_memory_map[i].length_low) / 1024 - 1024;
-                       }
-                       DbgPrint((DPRINT_REACTOS, "start: %x\t size: %x\t type %d\n", 
-                                 multiboot_memory_map[i].base_addr_low, 
-                                 multiboot_memory_map[i].length_low,
-                                 multiboot_memory_map[i].type));
-               }
-       }
-       DbgPrint((DPRINT_REACTOS, "low_mem = %d\n", LoaderBlock.MemLower));
-       DbgPrint((DPRINT_REACTOS, "high_mem = %d\n", LoaderBlock.MemHigher));
+       LoaderBlock.ModsAddr = reactos_modules;
+    LoaderBlock.DrivesAddr = reactos_arc_disk_info;
+    LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
+    if (LoaderBlock.MmapLength)
+    {
+        ULONG i;
+        LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
+        LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map;
+        reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
+        for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
+        {
+#ifdef _M_PPC
+            ULONG tmp;
+            /* Also swap from long long to high/low
+             * We also have unusable memory that will be available to kernel
+             * land.  Mark it here.
+             */
+            if (BiosMemoryAcpiReclaim == reactos_memory_map[i].type)
+            {
+                reactos_memory_map[i].type = BiosMemoryUsable;
+            }
+
+            tmp = reactos_memory_map[i].base_addr_low;
+            reactos_memory_map[i].base_addr_low = reactos_memory_map[i].base_addr_high;
+            reactos_memory_map[i].base_addr_high = tmp;
+            tmp = reactos_memory_map[i].length_low;
+            reactos_memory_map[i].length_low = reactos_memory_map[i].length_high;
+            reactos_memory_map[i].length_high = tmp;
+#endif
+
+            if (BiosMemoryUsable == reactos_memory_map[i].type &&
+                0 == reactos_memory_map[i].base_addr_low)
+            {
+                LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
+                if (640 < LoaderBlock.MemLower)
+                {
+                    LoaderBlock.MemLower = 640;
+                }
+            }
+            if (BiosMemoryUsable == reactos_memory_map[i].type &&
+                reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
+                1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
+            {
+                LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
+            }
+        }
+    }
 
        /*
         * Initialize the registry
@@ -645,7 +655,7 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
        /*
         * Make sure the system path is set in the .ini file
         */
-       if (!IniReadSettingByName(SectionId, "SystemPath", value, 1024))
+       if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
        {
                UiMessageBox("System path not specified for selected operating system.");
                return;
@@ -654,106 +664,76 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
        /*
         * Special case for Live CD.
         */
-       if (!stricmp(value, "LiveCD"))
+       if (!_stricmp(SystemPath, "LiveCD"))
        {
-               strcpy(szBootPath, "\\reactos");
-
-               /* Set kernel command line */
-               sprintf(multiboot_kernel_cmdline,
-                       "multi(0)disk(0)cdrom(%u)\\reactos /MININT",
-                       (unsigned int)BootDrive);
+               /* Normalize */
+               MachDiskGetBootPath(SystemPath, sizeof(SystemPath));
+               strcat(SystemPath, "\\reactos");
+               strcat(strcpy(reactos_kernel_cmdline, SystemPath),
+                      " /MININT");
        }
        else
        {
-               /*
-                * Verify system path
-                */
-               if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
-               {
-                       sprintf(MsgBuffer,"Invalid system path: '%s'", value);
-                       UiMessageBox(MsgBuffer);
-                       return;
-               }
-
-               /* recalculate the boot partition for freeldr */
-               i = 0;
-               rosPartition = 0;
-               while (1)
-               {
-                  if (!MachDiskGetPartitionEntry(BootDrive, ++i, &PartitionTableEntry))
-                  {
-                     BootPartition = 0;
-                     break;
-                  }
-                  if (IsRecognizedPartition(PartitionTableEntry.SystemIndicator))
-                  {
-                     if (++rosPartition == BootPartition)
-                     {
-                        BootPartition = i;
-                        break;
-                     }
-                  }
-               }
-
-               if (BootPartition == 0)
+               if (! MachDiskNormalizeSystemPath(SystemPath,
+                                                 sizeof(SystemPath)))
                {
-                       sprintf(MsgBuffer,"Invalid system path: '%s'", value);
-                       UiMessageBox(MsgBuffer);
+                       UiMessageBox("Invalid system path");
                        return;
                }
-
-               /* copy ARC path into kernel command line */
-               strcpy(multiboot_kernel_cmdline, value);
+               /* copy system path into kernel command line */
+               strcpy(reactos_kernel_cmdline, SystemPath);
        }
 
-       /* Set boot drive and partition */
-       ((LPSTR )(&LoaderBlock.BootDevice))[0] = (CHAR)BootDrive;
-       ((LPSTR )(&LoaderBlock.BootDevice))[1] = (CHAR)BootPartition;
-
        /*
         * Read the optional kernel parameters (if any)
         */
-       if (IniReadSettingByName(SectionId, "Options", value, 1024))
+       if (IniReadSettingByName(SectionId, "Options", value, sizeof(value)))
        {
-               strcat(multiboot_kernel_cmdline, " ");
-               strcat(multiboot_kernel_cmdline, value);
+               strcat(reactos_kernel_cmdline, " ");
+               strcat(reactos_kernel_cmdline, value);
        }
 
-       /* append a backslash */
-       if ((strlen(szBootPath)==0) ||
-           szBootPath[strlen(szBootPath)] != '\\')
-               strcat(szBootPath, "\\");
-
-       DbgPrint((DPRINT_REACTOS,"SystemRoot: '%s'\n", szBootPath));
-
-
-       UiDrawBackdrop();
-       UiDrawStatusText("Detecting Hardware...");
-
        /*
         * Detect hardware
         */
-       MachHwDetect();
+       LoaderBlock.ArchExtra = (ULONG)MachHwDetect();
+    UiDrawProgressBarCenter(5, 100, szLoadingMsg);
 
-       if (AcpiPresent) LoaderBlock.Flags |= MB_INFO_FLAG_ACPI_TABLE;
+    LoaderBlock.DrivesCount = reactos_disk_count;
 
        UiDrawStatusText("Loading...");
-       UiDrawProgressBarCenter(0, 100, "Loading ReactOS...");
+
+       //
+       // If we have a ramdisk, this will switch to the ramdisk disk routines
+       // which read from memory instead of using the firmware. This has to be done
+       // after hardware detection, since hardware detection will require using the
+       // real routines in order to perform disk-detection (just because we're on a
+       // ram-boot doesn't mean the user doesn't have actual disks installed too!)
+       //
+       RamDiskSwitchFromBios();
 
        /*
-        * Try to open boot drive
+        * Try to open system drive
         */
-       if (!FsOpenVolume(BootDrive, BootPartition))
+       if (!FsOpenSystemVolume(SystemPath, szBootPath, &LoaderBlock.BootDevice))
        {
                UiMessageBox("Failed to open boot drive.");
                return;
        }
 
+       /* append a backslash */
+       if ((strlen(szBootPath)==0) ||
+           szBootPath[strlen(szBootPath)] != '\\')
+               strcat(szBootPath, "\\");
+
+       DbgPrint((DPRINT_REACTOS,"SystemRoot: '%s'\n", szBootPath));
+       strcpy(SystemRoot, szBootPath);
+
        /*
         * Find the kernel image name
         * and try to load the kernel off the disk
         */
-       if(IniReadSettingByName(SectionId, "Kernel", value, 1024))
+       if(IniReadSettingByName(SectionId, "Kernel", value, sizeof(value)))
        {
                /*
                 * Set the name and
@@ -777,13 +757,11 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
                strcat(szKernelName, value);
        }
 
-    if (!FrLdrLoadKernel(szKernelName, 5)) return;
-    
        /*
         * Find the HAL image name
         * and try to load the kernel off the disk
         */
-       if(IniReadSettingByName(SectionId, "Hal", value, 1024))
+       if(IniReadSettingByName(SectionId, "Hal", value, sizeof(value)))
        {
                /*
                 * Set the name and
@@ -807,8 +785,15 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
                strcat(szHalName, value);
        }
 
-       if (!FrLdrLoadDriver(szHalName, 10))
-               return;
+       /* Load the kernel */
+       LoadBase = FrLdrLoadImage(szKernelName, 5, 1);
+       if (!LoadBase) return;
+
+       /* Get the NT header, kernel base and kernel entry */
+       NtHeader = RtlImageNtHeader(LoadBase);
+       KernelBase = SWAPD(NtHeader->OptionalHeader.ImageBase);
+       KernelEntryPoint = (ROS_KERNEL_ENTRY_POINT)(KernelBase + SWAPD(NtHeader->OptionalHeader.AddressOfEntryPoint));
+       LoaderBlock.KernelBase = KernelBase;
 
        /*
         * Load the System hive from disk
@@ -855,53 +840,66 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
         */
        RegInitCurrentControlSet(FALSE);
 
-       UiDrawProgressBarCenter(15, 100, "Loading ReactOS...");
-
-       /*
-        * Export the hardware hive
-        */
-       Base = FrLdrCreateModule ("HARDWARE");
-       RegExportBinaryHive ("\\Registry\\Machine\\HARDWARE", (PCHAR)Base, &Size);
-       FrLdrCloseModule (Base, Size);
+       UiDrawProgressBarCenter(15, 100, szLoadingMsg);
 
-       UiDrawProgressBarCenter(20, 100, "Loading ReactOS...");
+       UiDrawProgressBarCenter(20, 100, szLoadingMsg);
 
        /*
         * Load NLS files
         */
        if (!FrLdrLoadNlsFiles(szBootPath, MsgBuffer))
        {
-               UiMessageBox(MsgBuffer);
+               UiMessageBox(MsgBuffer);
                return;
        }
-       UiDrawProgressBarCenter(30, 100, "Loading ReactOS...");
-
-       /*
-        * Load kernel symbols
-        */
-       LoadKernelSymbols(szKernelName, 30);
-       UiDrawProgressBarCenter(40, 100, "Loading ReactOS...");
+       UiDrawProgressBarCenter(30, 100, szLoadingMsg);
 
        /*
         * Load boot drivers
         */
        FrLdrLoadBootDrivers(szBootPath, 40);
-       UiUnInitialize("Booting ReactOS...");
+       //UiUnInitialize("Booting ReactOS...");
 
-       /*
-        * Now boot the kernel
-        */
-       DiskStopFloppyMotor();
-    MachVideoPrepareForReactOS();
-    FrLdrStartup(0x2badb002);
+    //
+    // Perform architecture-specific pre-boot configuration
+    //
+    MachPrepareForReactOS(FALSE);
+
+    //
+    // Setup paging and jump to kernel
+    //
+       FrLdrStartup(0x2badb002);
 }
 
 #undef DbgPrint
 ULONG
-DbgPrint(char *Fmt, ...)
+DbgPrint(const char *Format, ...)
 {
-  UiMessageBox(Fmt);
-  return 0;
+       va_list ap;
+       CHAR Buffer[512];
+       ULONG Length;
+
+       va_start(ap, Format);
+
+       /* Construct a string */
+       Length = _vsnprintf(Buffer, 512, Format, ap);
+
+       /* Check if we went past the buffer */
+       if (Length == -1)
+       {
+               /* Terminate it if we went over-board */
+               Buffer[sizeof(Buffer) - 1] = '\n';
+
+               /* Put maximum */
+               Length = sizeof(Buffer);
+       }
+
+       /* Show it as a message box */
+       UiMessageBox(Buffer);
+
+       /* Cleanup and exit */
+       va_end(ap);
+       return 0;
 }
 
 /* EOF */