[freeldr] Never suppose that buffer in UNICODE_STRING is null terminated. Fixes some...
[reactos.git] / reactos / boot / freeldr / freeldr / windows / winldr.c
index 622d258..f3f7cd1 100644 (file)
@@ -14,9 +14,9 @@
  *  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.
+ *  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.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include <freeldr.h>
 #include <ndk/ldrtypes.h>
 #include <debug.h>
 
+// TODO: Move to .h
+void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
+                      PVOID *GdtIdt,
+                      ULONG *PcrBasePage,
+                      ULONG *TssBasePage);
+
 //FIXME: Do a better way to retrieve Arc disk information
 extern ULONG reactos_disk_count;
 extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
@@ -31,6 +37,7 @@ extern char reactos_arc_strings[32][256];
 
 extern BOOLEAN UseRealHeap;
 extern ULONG LoaderPagesSpanned;
+extern BOOLEAN AcpiPresent;
 
 BOOLEAN
 WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
@@ -75,9 +82,9 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
 VOID
 WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
                        PCHAR Options,
-                       PCHAR SystemPath,
+                       PCHAR SystemRoot,
                        PCHAR BootPath,
-                       WORD VersionToBoot)
+                       USHORT VersionToBoot)
 {
        /* Examples of correct options and paths */
        //CHAR  Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
@@ -86,24 +93,19 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
        //CHAR  ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
 
        CHAR    HalPath[] = "\\";
-       CHAR    SystemRoot[256];
        CHAR    ArcBoot[256];
        CHAR    MiscFiles[256];
        ULONG i, PathSeparator;
        PLOADER_PARAMETER_EXTENSION Extension;
 
-       LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
-
        /* Construct SystemRoot and ArcBoot from SystemPath */
-       PathSeparator = strstr(SystemPath, "\\") - SystemPath;
-       strncpy(ArcBoot, SystemPath, PathSeparator);
+       PathSeparator = strstr(BootPath, "\\") - BootPath;
+       strncpy(ArcBoot, BootPath, PathSeparator);
        ArcBoot[PathSeparator] = 0;
-       strcpy(SystemRoot, &SystemPath[PathSeparator]);
-       strcat(SystemRoot, "\\");
 
-       DbgPrint((DPRINT_WINDOWS, "ArcBoot: %s\n", ArcBoot));
-       DbgPrint((DPRINT_WINDOWS, "SystemRoot: %s\n", SystemRoot));
-       DbgPrint((DPRINT_WINDOWS, "Options: %s\n", Options));
+       DPRINTM(DPRINT_WINDOWS, "ArcBoot: %s\n", ArcBoot);
+       DPRINTM(DPRINT_WINDOWS, "SystemRoot: %s\n", SystemRoot);
+       DPRINTM(DPRINT_WINDOWS, "Options: %s\n", Options);
 
        /* Fill Arc BootDevice */
        LoaderBlock->ArcBootDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
@@ -195,61 +197,24 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
        Extension->MinorVersion = VersionToBoot & 0xFF;
        Extension->Profile.Status = 2;
 
+       /* Check if ACPI is present */
+       if (AcpiPresent)
+       {
+               /* See KiRosFrldrLpbToNtLpb for details */
+               Extension->AcpiTable = (PVOID)1;
+       }
+
        /* Load drivers database */
        strcpy(MiscFiles, BootPath);
        strcat(MiscFiles, "AppPatch\\drvmain.sdb");
        Extension->DrvDBImage = PaToVa(WinLdrLoadModule(MiscFiles,
                &Extension->DrvDBSize, LoaderRegistryData));
 
+       /* Convert extension and setup block pointers */
        LoaderBlock->Extension = PaToVa(Extension);
-}
 
-// Last step before going virtual
-void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
-                      PVOID *GdtIdt,
-                      ULONG *PcrBasePage,
-                      ULONG *TssBasePage)
-{
-       ULONG TssSize;
-       ULONG TssPages;
-       ULONG_PTR Pcr = 0;
-       ULONG_PTR Tss = 0;
-       ULONG BlockSize, NumPages;
-
-       LoaderBlock->u.I386.CommonDataArea = NULL; //CommonDataArea;
-       LoaderBlock->u.I386.MachineType = 0; // ntldr sets this to 0
-
-       /* Allocate 2 pages for PCR */
-       Pcr = (ULONG_PTR)MmAllocateMemoryWithType(2 * MM_PAGE_SIZE, LoaderStartupPcrPage);
-       *PcrBasePage = Pcr >> MM_PAGE_SHIFT;
-
-       if (Pcr == 0)
-       {
-               UiMessageBox("Can't allocate PCR\n");
-               return;
-       }
-
-       /* Allocate TSS */
-       TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
-       TssPages = TssSize / MM_PAGE_SIZE;
-
-       Tss = (ULONG_PTR)MmAllocateMemoryWithType(TssSize, LoaderMemoryData);
-
-       *TssBasePage = Tss >> MM_PAGE_SHIFT;
-
-       /* Allocate space for new GDT + IDT */
-       BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here?
-       NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
-       *GdtIdt = (PKGDTENTRY)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);
-
-       if (*GdtIdt == NULL)
-       {
-               UiMessageBox("Can't allocate pages for GDT+IDT!\n");
-               return;
-       }
-
-       /* Zero newly prepared GDT+IDT */
-       RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT);
+       if (LoaderBlock->SetupLdrBlock)
+               LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock);
 }
 
 BOOLEAN
@@ -267,7 +232,7 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
        PVOID DriverBase;
 
        // Separate the path to file name and directory path
-       sprintf(DriverPath, "%S", FilePath->Buffer);
+       snprintf(DriverPath, sizeof(DriverPath), "%wZ", FilePath);
        DriverNamePos = strrchr(DriverPath, '\\');
        if (DriverNamePos != NULL)
        {
@@ -277,8 +242,14 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
                // Cut out the name from the path
                *(DriverNamePos+1) = 0;
        }
+       else
+       {
+               // There is no directory in the path
+               strcpy(DllName, DriverPath);
+               DriverPath[0] = 0;
+       }
 
-       DbgPrint((DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath, DllName, LoaderBlock));
+       DPRINTM(DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath, DllName, LoaderBlock);
 
 
        // Check if driver is already loaded
@@ -290,7 +261,7 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
        }
 
        // It's not loaded, we have to load it
-       sprintf(FullPath,"%s%S", BootPath, FilePath->Buffer);
+       snprintf(FullPath, sizeof(FullPath), "%s%wZ", BootPath, FilePath);
        Status = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
        if (!Status)
                return FALSE;
@@ -299,7 +270,7 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
        Status = WinLdrAllocateDataTableEntry(LoaderBlock, DllName, DllName, DriverBase, DriverDTE);
        if (!Status)
        {
-               DbgPrint((DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n"));
+               DPRINTM(DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n");
                return FALSE;
        }
 
@@ -311,8 +282,8 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
        Status = WinLdrScanImportDescriptorTable(LoaderBlock, FullPath, *DriverDTE);
        if (!Status)
        {
-               DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for %s\n",
-                       FullPath));
+               DPRINTM(DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for %s\n",
+                       FullPath);
                return FALSE;
        }
 
@@ -332,16 +303,16 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
 
        while (NextBd != &LoaderBlock->BootDriverListHead)
        {
-               BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
+               BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
 
-               DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
-                       BootDriver->DataTableEntry, &BootDriver->RegistryPath));
+               DPRINTM(DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
+                       BootDriver->LdrEntry, &BootDriver->RegistryPath);
 
                // Paths are relative (FIXME: Are they always relative?)
 
                // Load it
                Status = WinLdrLoadDeviceDriver(LoaderBlock, BootPath, &BootDriver->FilePath,
-                       0, &BootDriver->DataTableEntry);
+                       0, &BootDriver->LdrEntry);
 
                // If loading failed - cry loudly
                //FIXME: Maybe remove it from the list and try to continue?
@@ -353,9 +324,10 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
 
                // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore
                BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);
-               BootDriver->DataTableEntry = PaToVa(BootDriver->DataTableEntry);
+               BootDriver->FilePath.Buffer = PaToVa(BootDriver->FilePath.Buffer);
+               BootDriver->LdrEntry = PaToVa(BootDriver->LdrEntry);
 
-               NextBd = BootDriver->ListEntry.Flink;
+               NextBd = BootDriver->Link.Flink;
        }
 
        return TRUE;
@@ -364,70 +336,97 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
 PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size,
                                           TYPE_OF_MEMORY MemoryType)
 {
-       PFILE FileHandle;\r
-       PVOID PhysicalBase;\r
-       ULONG FileSize;\r
-       BOOLEAN Status;\r
-\r
-       //CHAR ProgressString[256];\r
-\r
-       /* Inform user we are loading files */\r
-       //sprintf(ProgressString, "Loading %s...", FileName);\r
-       //UiDrawProgressBarCenter(1, 100, ProgressString);\r
-\r
-       DbgPrint((DPRINT_WINDOWS, "Loading module %s\n", ModuleName));\r
-       *Size = 0;\r
-\r
-       /* Open the image file */\r
-       FileHandle = FsOpenFile(ModuleName);\r
-\r
-       if (FileHandle == NULL)\r
-       {\r
-               /* In case of errors, we just return, without complaining to the user */\r
-               return NULL;\r
-       }\r
-\r
-       /* Get this file's size */\r
-       FileSize = FsGetFileSize(FileHandle);\r
-       *Size = FileSize;\r
-\r
-       /* Allocate memory */\r
-       PhysicalBase = MmAllocateMemoryWithType(FileSize, MemoryType);\r
-       if (PhysicalBase == NULL)\r
-       {\r
-               FsCloseFile(FileHandle);\r
-               return NULL;\r
-       }\r
-\r
-       /* Load whole file */\r
-       Status = FsReadFile(FileHandle, FileSize, NULL, PhysicalBase);\r
-       if (!Status)\r
-       {\r
-               FsCloseFile(FileHandle);\r
-               return NULL;\r
-       }\r
-\r
-       DbgPrint((DPRINT_WINDOWS, "Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize));\r
-\r
-       /* We are done with the file - close it */\r
-       FsCloseFile(FileHandle);\r
-\r
-       return PhysicalBase;\r
+       ULONG FileId;
+       PVOID PhysicalBase;
+       FILEINFORMATION FileInfo;
+       ULONG FileSize;
+       ULONG Status;
+       ULONG BytesRead;
+
+       //CHAR ProgressString[256];
+
+       /* Inform user we are loading files */
+       //sprintf(ProgressString, "Loading %s...", FileName);
+       //UiDrawProgressBarCenter(1, 100, ProgressString);
+
+       DPRINTM(DPRINT_WINDOWS, "Loading module %s\n", ModuleName);
+       *Size = 0;
+
+       /* Open the image file */
+       Status = ArcOpen((PCHAR)ModuleName, OpenReadOnly, &FileId);
+       if (Status != ESUCCESS)
+       {
+               /* In case of errors, we just return, without complaining to the user */
+               return NULL;
+       }
+
+       /* Get this file's size */
+       Status = ArcGetFileInformation(FileId, &FileInfo);
+       if (Status != ESUCCESS)
+       {
+               ArcClose(FileId);
+               return NULL;
+       }
+       FileSize = FileInfo.EndingAddress.LowPart;
+       *Size = FileSize;
+
+       /* Allocate memory */
+       PhysicalBase = MmAllocateMemoryWithType(FileSize, MemoryType);
+       if (PhysicalBase == NULL)
+       {
+               ArcClose(FileId);
+               return NULL;
+       }
+
+       /* Load whole file */
+       Status = ArcRead(FileId, PhysicalBase, FileSize, &BytesRead);
+       ArcClose(FileId);
+       if (Status != ESUCCESS)
+       {
+               return NULL;
+       }
+
+       DPRINTM(DPRINT_WINDOWS, "Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize);
+
+       return PhysicalBase;
+}
+
+
+USHORT
+WinLdrDetectVersion()
+{
+       LONG rc;
+       FRLDRHKEY hKey;
+
+       rc = RegOpenKey(
+               NULL,
+               L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
+               &hKey);
+       if (rc != ERROR_SUCCESS)
+       {
+               // Key doesn't exist; assume NT 4.0
+               return _WIN32_WINNT_NT4;
+       }
+
+       // We may here want to read the value of ProductVersion
+       return _WIN32_WINNT_WS03;
 }
 
 
 VOID
-LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
+LoadAndBootWindows(PCSTR OperatingSystemName,
+                   PSTR SettingsValue,
+                   USHORT OperatingSystemVersion)
 {
-       CHAR  MsgBuffer[256];
-       CHAR  SystemPath[512], SearchPath[512];
-       CHAR  FileName[512];
-       CHAR  BootPath[512];
+       BOOLEAN HasSection;
+       char  FullPath[MAX_PATH], SystemRoot[MAX_PATH], BootPath[MAX_PATH];
+       CHAR  FileName[MAX_PATH];
        CHAR  BootOptions[256];
+       PCHAR File;
+       PCHAR PathSeparator;
        PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
        BOOLEAN Status;
-       ULONG SectionId;
-       ULONG BootDevice;
+       ULONG_PTR SectionId;
        PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA;
        KERNEL_ENTRY_POINT KiSystemStartup;
        PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL;
@@ -436,60 +435,78 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
        ULONG PcrBasePage=0;
        ULONG TssBasePage=0;
 
-       //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion);
-       //UiMessageBox(MsgBuffer);
-
        // Open the operating system section
        // specified in the .ini file
-       if (!IniOpenSection(OperatingSystemName, &SectionId))
-       {
-               sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
-               UiMessageBox(MsgBuffer);
-               return;
-       }
+       HasSection = IniOpenSection(OperatingSystemName, &SectionId);
 
        UiDrawBackdrop();
        UiDrawStatusText("Detecting Hardware...");
-       UiDrawProgressBarCenter(1, 100, "Loading Windows...");
+       UiDrawProgressBarCenter(1, 100, "Loading NT...");
 
-       /* Make sure the system path is set in the .ini file */
-       if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
+       /* Read the system path is set in the .ini file */
+       if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", FullPath, sizeof(FullPath)))
        {
-               UiMessageBox("System path not specified for selected operating system.");
-               return;
+               strcpy(FullPath, OperatingSystemName);
        }
 
+       /* Special case for LiveCD */
+       if (!_strnicmp(FullPath, "LiveCD", strlen("LiveCD")))
+       {
+               strcpy(BootPath, FullPath + strlen("LiveCD"));
+               MachDiskGetBootPath(FullPath, sizeof(FullPath));
+               strcat(FullPath, BootPath);
+       }
+
+       /* Convert FullPath to SystemRoot */
+       PathSeparator = strstr(FullPath, "\\");
+       strcpy(SystemRoot, PathSeparator);
+       strcat(SystemRoot, "\\");
+
        /* Read booting options */
-       if (!IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))
+       if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))
        {
-               /* Nothing read, make the string empty */
-               strcpy(BootOptions, "");
+               /* Get options after the title */
+               const CHAR*p = SettingsValue;
+               while (*p == ' ' || *p == '"')
+                       p++;
+               while (*p != '\0' && *p != '"')
+                       p++;
+               strcpy(BootOptions, p);
+               DPRINTM(DPRINT_WINDOWS,"BootOptions: '%s'\n", BootOptions);
        }
 
-       /* Normalize system path */
-       if (!MachDiskNormalizeSystemPath(SystemPath, sizeof(SystemPath)))
+       //
+       // Check if a ramdisk file was given
+       //
+       File = strstr(BootOptions, "/RDPATH=");
+       if (File)
        {
-               UiMessageBox("Invalid system path");
-               return;
+               //
+               // Copy the file name and everything else after it
+               //
+               strcpy(FileName, File + 8);
+
+               //
+               // Null-terminate
+               //
+               *strstr(FileName, " ") = ANSI_NULL;
+
+               //
+               // Load the ramdisk
+               //
+               RamDiskLoadVirtualFile(FileName);
        }
 
        /* Let user know we started loading */
        UiDrawStatusText("Loading...");
 
-       /* Try to open system drive */
-       BootDevice = 0xffffffff;
-       if (!FsOpenSystemVolume(SystemPath, BootPath, &BootDevice))
-       {
-               UiMessageBox("Failed to open boot drive.");
-               return;
-       }
-
        /* append a backslash */
+       strcpy(BootPath, FullPath);
        if ((strlen(BootPath)==0) ||
            BootPath[strlen(BootPath)] != '\\')
                strcat(BootPath, "\\");
 
-       DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath));
+       DPRINTM(DPRINT_WINDOWS,"BootPath: '%s'\n", BootPath);
 
        /* Allocate and minimalistic-initialize LPB */
        AllocateAndInitLPB(&LoaderBlock);
@@ -498,17 +515,24 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
        UseRealHeap = TRUE;
        LoaderBlock->ConfigurationRoot = MachHwDetect();
 
+       /* Load Hive */
+       Status = WinLdrInitSystemHive(LoaderBlock, BootPath);
+       DPRINTM(DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status);
+
+       if (OperatingSystemVersion == 0)
+               OperatingSystemVersion = WinLdrDetectVersion();
+
        /* Load kernel */
        strcpy(FileName, BootPath);
        strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");
        Status = WinLdrLoadImage(FileName, LoaderSystemCode, &NtosBase);
-       DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase));
+       DPRINTM(DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase);
 
        /* Load HAL */
        strcpy(FileName, BootPath);
        strcat(FileName, "SYSTEM32\\HAL.DLL");
        Status = WinLdrLoadImage(FileName, LoaderHalCode, &HalBase);
-       DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase));
+       DPRINTM(DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase);
 
        /* Load kernel-debugger support dll */
        if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
@@ -516,7 +540,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
                strcpy(FileName, BootPath);
                strcat(FileName, "SYSTEM32\\KDCOM.DLL");
                Status = WinLdrLoadImage(FileName, LoaderBootDriver, &KdComBase);
-               DbgPrint((DPRINT_WINDOWS, "KdCom loaded with status %d at %p\n", Status, KdComBase));
+               DPRINTM(DPRINT_WINDOWS, "KdCom loaded with status %d at %p\n", Status, KdComBase);
        }
 
        /* Allocate data table entries for above-loaded modules */
@@ -531,26 +555,26 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
        }
 
        /* Load all referenced DLLs for kernel, HAL and kdcom.dll */
-       strcpy(SearchPath, BootPath);
-       strcat(SearchPath, "SYSTEM32\\");
-       WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KernelDTE);
-       WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE);
+       strcpy(FileName, BootPath);
+       strcat(FileName, "SYSTEM32\\");
+       WinLdrScanImportDescriptorTable(LoaderBlock, FileName, KernelDTE);
+       WinLdrScanImportDescriptorTable(LoaderBlock, FileName, HalDTE);
        if (KdComDTE)
-               WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KdComDTE);
+               WinLdrScanImportDescriptorTable(LoaderBlock, FileName, KdComDTE);
 
-       /* Load Hive, and then NLS data, OEM font, and prepare boot drivers list */
-       Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath);
-       DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status));
+       /* Load NLS data, OEM font, and prepare boot drivers list */
+       Status = WinLdrScanSystemHive(LoaderBlock, BootPath);
+       DPRINTM(DPRINT_WINDOWS, "SYSTEM hive scanned with status %d\n", Status);
 
        /* Load boot drivers */
        Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
-       DbgPrint((DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status));
+       DPRINTM(DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status);
 
        /* Alloc PCR, TSS, do magic things with the GDT/IDT */
        WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
 
        /* Initialize Phase 1 - no drivers loading anymore */
-       WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemPath, BootPath, OperatingSystemVersion);
+       WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemRoot, BootPath, OperatingSystemVersion);
 
        /* Save entry-point pointer and Loader block VAs */
        KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
@@ -569,10 +593,10 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
        WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt);
 
        /* Save final value of LoaderPagesSpanned */
-       LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
+       LoaderBlockVA->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
 
-       DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
-               KiSystemStartup, LoaderBlockVA));
+       DPRINTM(DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
+               KiSystemStartup, LoaderBlockVA);
 
        WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
        WinLdrpDumpBootDriver(LoaderBlockVA);
@@ -603,8 +627,8 @@ WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
        {
                MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
 
-               DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
-                       MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType));
+               DPRINTM(DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
+                       MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType);
 
                NextMd = MemoryDescriptor->ListEntry.Flink;
        }
@@ -620,12 +644,12 @@ WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)
 
        while (NextBd != &LoaderBlock->BootDriverListHead)
        {
-               BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
+               BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
 
-               DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
-                       BootDriver->DataTableEntry, &BootDriver->RegistryPath));
+               DPRINTM(DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
+                       BootDriver->LdrEntry, &BootDriver->RegistryPath);
 
-               NextBd = BootDriver->ListEntry.Flink;
+               NextBd = BootDriver->Link.Flink;
        }
 }
 
@@ -641,8 +665,8 @@ WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
        {
                ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
 
-               DbgPrint((DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
-                       ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature));
+               DPRINTM(DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
+                       ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature);
 
                NextBd = ArcDisk->ListEntry.Flink;
        }