[FREELDR] Rename the PE loader functions 'PeLdr*' instead of 'WinLdr*'.
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Thu, 19 Sep 2019 00:47:29 +0000 (02:47 +0200)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Thu, 19 Sep 2019 00:53:57 +0000 (02:53 +0200)
boot/freeldr/freeldr/disk/scsiport.c
boot/freeldr/freeldr/include/peloader.h
boot/freeldr/freeldr/lib/peloader.c
boot/freeldr/freeldr/ntldr/winldr.c

index 6cb204d..a42cadc 100644 (file)
@@ -1639,7 +1639,7 @@ LoadBootDeviceDriver(VOID)
     strcat(NtBootDdPath, "\\NTBOOTDD.SYS");
 
     /* Load file */
-    Success = WinLdrLoadImage(NtBootDdPath, LoaderBootDriver, &ImageBase);
+    Success = PeLdrLoadImage(NtBootDdPath, LoaderBootDriver, &ImageBase);
     if (!Success)
     {
         /* That's OK. File simply doesn't exist */
@@ -1647,15 +1647,15 @@ LoadBootDeviceDriver(VOID)
     }
 
     /* Allocate a DTE for ntbootdd */
-    Success = WinLdrAllocateDataTableEntry(&ModuleListHead, "ntbootdd.sys",
-        "NTBOOTDD.SYS", ImageBase, &BootDdDTE);
+    Success = PeLdrAllocateDataTableEntry(&ModuleListHead, "ntbootdd.sys",
+                                          "NTBOOTDD.SYS", ImageBase, &BootDdDTE);
     if (!Success)
         return EIO;
 
     /* Add the PE part of freeldr.sys to the list of loaded executables, it
        contains ScsiPort* exports, imported by ntbootdd.sys */
-    Success = WinLdrAllocateDataTableEntry(&ModuleListHead, "scsiport.sys",
-        "FREELDR.SYS", &__ImageBase, &FreeldrDTE);
+    Success = PeLdrAllocateDataTableEntry(&ModuleListHead, "scsiport.sys",
+                                          "FREELDR.SYS", &__ImageBase, &FreeldrDTE);
     if (!Success)
     {
         RemoveEntryList(&BootDdDTE->InLoadOrderLinks);
@@ -1663,7 +1663,7 @@ LoadBootDeviceDriver(VOID)
     }
 
     /* Fix imports */
-    Success = WinLdrScanImportDescriptorTable(&ModuleListHead, "", BootDdDTE);
+    Success = PeLdrScanImportDescriptorTable(&ModuleListHead, "", BootDdDTE);
 
     /* Now unlinkt the DTEs, they won't be valid later */
     RemoveEntryList(&BootDdDTE->InLoadOrderLinks);
index 9d4b117..a582f76 100644 (file)
 #pragma once
 
 BOOLEAN
-WinLdrLoadImage(IN PCHAR FileName,
-                TYPE_OF_MEMORY MemoryType,
-                OUT PVOID *ImageBasePA);
+PeLdrLoadImage(
+    IN PCHAR FileName,
+    IN TYPE_OF_MEMORY MemoryType,
+    OUT PVOID *ImageBasePA);
 
 BOOLEAN
-WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead,
-                             IN PCCH BaseDllName,
-                             IN PCCH FullDllName,
-                             IN PVOID BasePA,
-                             OUT PLDR_DATA_TABLE_ENTRY *NewEntry);
+PeLdrAllocateDataTableEntry(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PCCH BaseDllName,
+    IN PCCH FullDllName,
+    IN PVOID BasePA,
+    OUT PLDR_DATA_TABLE_ENTRY *NewEntry);
 
 BOOLEAN
-WinLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead,
-                                IN PCCH DirectoryPath,
-                                IN PLDR_DATA_TABLE_ENTRY ScanDTE);
+PeLdrScanImportDescriptorTable(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PCCH DirectoryPath,
+    IN PLDR_DATA_TABLE_ENTRY ScanDTE);
 
 BOOLEAN
-WinLdrCheckForLoadedDll(IN OUT PLIST_ENTRY ModuleListHead,
-                        IN PCH DllName,
-                        OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
+PeLdrCheckForLoadedDll(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PCH DllName,
+    OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
index c306375..53462a5 100644 (file)
  *              http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/
  */
 
-/* INCLUDES ***************************************************************/
+/* INCLUDES ******************************************************************/
 
 #include <freeldr.h>
 #include <debug.h>
 
 DBG_DEFAULT_CHANNEL(PELOADER);
 
-/* FUNCTIONS **************************************************************/
-
-static BOOLEAN
-WinLdrpCompareDllName(IN PCH DllName,
-                      IN PUNICODE_STRING UnicodeName);
-
-static BOOLEAN
-WinLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead,
-                      IN PVOID DllBase,
-                      IN PVOID ImageBase,
-                      IN PIMAGE_THUNK_DATA ThunkData,
-                      IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
-                      IN ULONG ExportSize,
-                      IN BOOLEAN ProcessForwards,
-                      IN PCSTR DirectoryPath);
+/* PRIVATE FUNCTIONS *********************************************************/
 
+/* DllName - physical, UnicodeString->Buffer - virtual */
 static BOOLEAN
-WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead,
-                                PCCH DirectoryPath,
-                                PCH ImportName,
-                                PLDR_DATA_TABLE_ENTRY *DataTableEntry);
+PeLdrpCompareDllName(
+    IN PCH DllName,
+    IN PUNICODE_STRING UnicodeName)
+{
+    PWSTR Buffer;
+    SIZE_T i, Length;
 
-static BOOLEAN
-WinLdrpScanImportAddressTable(IN OUT PLIST_ENTRY ModuleListHead,
-                              IN PVOID DllBase,
-                              IN PVOID ImageBase,
-                              IN PIMAGE_THUNK_DATA ThunkData,
-                              IN PCSTR DirectoryPath);
+    /* First obvious check: for length of two names */
+    Length = strlen(DllName);
 
+#if DBG
+    {
+        UNICODE_STRING UnicodeNamePA;
+        UnicodeNamePA.Length = UnicodeName->Length;
+        UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
+        UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
+        TRACE("PeLdrpCompareDllName: %s and %wZ, Length = %d "
+              "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length);
+    }
+#endif
 
-/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */
-BOOLEAN
-WinLdrCheckForLoadedDll(IN OUT PLIST_ENTRY ModuleListHead,
-                        IN PCH DllName,
-                        OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
-{
-    PLDR_DATA_TABLE_ENTRY DataTableEntry;
-    LIST_ENTRY *ModuleEntry;
+    if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
+        return FALSE;
 
-    TRACE("WinLdrCheckForLoadedDll: DllName %s\n", DllName);
+    /* Store pointer to unicode string's buffer */
+    Buffer = VaToPa(UnicodeName->Buffer);
 
-    /* Just go through each entry in the LoadOrderList and compare loaded module's
-       name with a given name */
-    ModuleEntry = ModuleListHead->Flink;
-    while (ModuleEntry != ModuleListHead)
+    /* Loop character by character */
+    for (i = 0; i < Length; i++)
     {
-        /* Get pointer to the current DTE */
-        DataTableEntry = CONTAINING_RECORD(ModuleEntry,
-            LDR_DATA_TABLE_ENTRY,
-            InLoadOrderLinks);
-
-        TRACE("WinLdrCheckForLoadedDll: DTE %p, EP %p, base %p name '%.*ws'\n",
-              DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
-              DataTableEntry->BaseDllName.Length / 2, VaToPa(DataTableEntry->BaseDllName.Buffer));
+        /* Compare two characters, uppercasing them */
+        if (toupper(*DllName) != toupper((CHAR)*Buffer))
+            return FALSE;
 
-        /* Compare names */
-        if (WinLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
-        {
-            /* Yes, found it, report pointer to the loaded module's DTE
-               to the caller and increase load count for it */
-            *LoadedEntry = DataTableEntry;
-            DataTableEntry->LoadCount++;
-            TRACE("WinLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry);
-            return TRUE;
-        }
+        /* Move to the next character */
+        DllName++;
+        Buffer++;
+    }
 
-        /* Go to the next entry */
-        ModuleEntry = ModuleEntry->Flink;
+    /* Check, if strings either fully match, or match till the "." (w/o extension) */
+    if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
+    {
+        /* Yes they do */
+        return TRUE;
     }
 
-    /* Nothing found */
+    /* Strings don't match, return FALSE */
     return FALSE;
 }
 
-BOOLEAN
-WinLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead,
-                                IN PCCH DirectoryPath,
-                                IN PLDR_DATA_TABLE_ENTRY ScanDTE)
+static BOOLEAN
+PeLdrpLoadAndScanReferencedDll(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PCCH DirectoryPath,
+    IN PCH ImportName,
+    OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry);
+
+static BOOLEAN
+PeLdrpBindImportName(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PVOID DllBase,
+    IN PVOID ImageBase,
+    IN PIMAGE_THUNK_DATA ThunkData,
+    IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
+    IN ULONG ExportSize,
+    IN BOOLEAN ProcessForwards,
+    IN PCSTR DirectoryPath)
 {
-    PLDR_DATA_TABLE_ENTRY DataTableEntry;
-    PIMAGE_IMPORT_DESCRIPTOR ImportTable;
-    ULONG ImportTableSize;
-    PCH ImportName;
+    ULONG Ordinal;
+    PULONG NameTable, FunctionTable;
+    PUSHORT OrdinalTable;
+    LONG High, Low, Middle, Result;
+    ULONG Hint;
+    PIMAGE_IMPORT_BY_NAME ImportData;
+    PCHAR ExportName, ForwarderName;
     BOOLEAN Success;
 
-    /* Get a pointer to the import table of this image */
-    ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
-        TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
+    //TRACE("PeLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X, ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n",
+    //      DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize, ProcessForwards);
 
-#if DBG
+    /* Check passed DllBase param */
+    if(DllBase == NULL)
     {
-        UNICODE_STRING BaseName;
-        BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
-        BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
-        BaseName.Length = ScanDTE->BaseDllName.Length;
-        TRACE("WinLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
-              &BaseName, ImportTable);
+        WARN("DllBase == NULL!\n");
+        return FALSE;
     }
-#endif
 
-    /* If image doesn't have any import directory - just return success */
-    if (ImportTable == NULL)
-        return TRUE;
+    /* Convert all non-critical pointers to PA from VA */
+    ThunkData = VaToPa(ThunkData);
 
-    /* Loop through all entries */
-    for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++)
+    /* Is the reference by ordinal? */
+    if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards)
     {
-        /* Get pointer to the name */
-        ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
-        TRACE("WinLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);
-
-        /* In case we get a reference to ourselves - just skip it */
-        if (WinLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
-            continue;
-
-        /* Load the DLL if it is not already loaded */
-        if (!WinLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
+        /* Yes, calculate the ordinal */
+        Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) - (UINT32)ExportDirectory->Base);
+        //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
+    }
+    else
+    {
+        /* It's reference by name, we have to look it up in the export directory */
+        if (!ProcessForwards)
         {
-            Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead,
-                                                      DirectoryPath,
-                                                      ImportName,
-                                                      &DataTableEntry);
-            if (!Success)
-            {
-                ERR("WinLdrpLoadAndScanReferencedDll() failed\n");
-                return Success;
-            }
+            /* AddressOfData in thunk entry will become a virtual address (from relative) */
+            //TRACE("PeLdrpBindImportName(): ThunkData->u1.AOD was %p\n", ThunkData->u1.AddressOfData);
+            ThunkData->u1.AddressOfData =
+                (ULONG_PTR)RVA(ImageBase, ThunkData->u1.AddressOfData);
+            //TRACE("PeLdrpBindImportName(): ThunkData->u1.AOD became %p\n", ThunkData->u1.AddressOfData);
         }
 
-        /* Scan its import address table */
-        Success = WinLdrpScanImportAddressTable(ModuleListHead,
-                                                DataTableEntry->DllBase,
-                                                ScanDTE->DllBase,
-                                                (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
-                                                DirectoryPath);
+        /* Get the import name */
+        ImportData = VaToPa((PVOID)ThunkData->u1.AddressOfData);
 
-        if (!Success)
+        /* Get pointers to Name and Ordinal tables (RVA -> VA) */
+        NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
+        OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));
+
+        //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n",
+        //      NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals);
+
+        /* Get the hint, convert it to a physical pointer */
+        Hint = ((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint;
+        //TRACE("HintIndex %d\n", Hint);
+
+        /* Get the export name from the hint */
+        ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));
+
+        /* If Hint is less than total number of entries in the export directory,
+           and import name == export name, then we can just get it from the OrdinalTable */
+        if ((Hint < ExportDirectory->NumberOfNames) &&
+            (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
         {
-            ERR("WinLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
-                ImportName, DirectoryPath);
-            return Success;
+            Ordinal = OrdinalTable[Hint];
+            //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
         }
-    }
+        else
+        {
+            /* It's not the easy way, we have to lookup import name in the name table.
+               Let's use a binary search for this task. */
 
-    return TRUE;
-}
+            //TRACE("PeLdrpBindImportName() looking up the import name using binary search...\n");
 
-BOOLEAN
-WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead,
-                             IN PCCH BaseDllName,
-                             IN PCCH FullDllName,
-                             IN PVOID BasePA,
-                             OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
-{
-    PVOID BaseVA = PaToVa(BasePA);
-    PWSTR Buffer;
-    PLDR_DATA_TABLE_ENTRY DataTableEntry;
-    PIMAGE_NT_HEADERS NtHeaders;
-    USHORT Length;
+            /* Low boundary is set to 0, and high boundary to the maximum index */
+            Low = 0;
+            High = ExportDirectory->NumberOfNames - 1;
 
-    TRACE("WinLdrAllocateDataTableEntry(, '%s', '%s', %p)\n",
-          BaseDllName, FullDllName, BasePA);
+            /* Perform a binary-search loop */
+            while (High >= Low)
+            {
+                /* Divide by 2 by shifting to the right once */
+                Middle = (Low + High) / 2;
 
-    /* Allocate memory for a data table entry, zero-initialize it */
-    DataTableEntry = (PLDR_DATA_TABLE_ENTRY)FrLdrHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY),
-                                                           TAG_WLDR_DTE);
-    if (DataTableEntry == NULL)
-        return FALSE;
-    RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
+                /* Get the name from the name table */
+                ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));
 
-    /* Get NT headers from the image */
-    NtHeaders = RtlImageNtHeader(BasePA);
+                /* Compare the names */
+                Result = strcmp(ExportName, (PCHAR)ImportData->Name);
 
-    /* Initialize corresponding fields of DTE based on NT headers value */
-    DataTableEntry->DllBase = BaseVA;
-    DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
-    DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
-    DataTableEntry->SectionPointer = 0;
-    DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
+                // TRACE("Binary search: comparing Import '__', Export '%s'\n",
+                      // VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),
+                      // (PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));
 
-    /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
-       by simple conversion - copying each character */
-    Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
-    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
-    if (Buffer == NULL)
-    {
-        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
-        return FALSE;
-    }
-    RtlZeroMemory(Buffer, Length);
+                // TRACE("TE->u1.AOD %p, fulladdr %p\n",
+                      // ThunkData->u1.AddressOfData,
+                      // ((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name );
 
-    DataTableEntry->BaseDllName.Length = Length;
-    DataTableEntry->BaseDllName.MaximumLength = Length;
-    DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
-    while (*BaseDllName != 0)
-    {
-        *Buffer++ = *BaseDllName++;
+                /* Depending on result of strcmp, perform different actions */
+                if (Result > 0)
+                {
+                    /* Adjust top boundary */
+                    High = Middle - 1;
+                }
+                else if (Result < 0)
+                {
+                    /* Adjust bottom boundary */
+                    Low = Middle + 1;
+                }
+                else
+                {
+                    /* Yay, found it! */
+                    break;
+                }
+            }
+
+            /* If high boundary is less than low boundary, then no result found */
+            if (High < Low)
+            {
+                ERR("Did not find export '%s'!\n", (PCHAR)ImportData->Name);
+                return FALSE;
+            }
+
+            /* Everything alright, get the ordinal */
+            Ordinal = OrdinalTable[Middle];
+
+            //TRACE("PeLdrpBindImportName() found Ordinal %d\n", Ordinal);
+        }
     }
 
-    /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
-       using the same method */
-    Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
-    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
-    if (Buffer == NULL)
+    /* Check ordinal number for validity! */
+    if (Ordinal >= ExportDirectory->NumberOfFunctions)
     {
-        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
+        ERR("Ordinal number is invalid!\n");
         return FALSE;
     }
-    RtlZeroMemory(Buffer, Length);
 
-    DataTableEntry->FullDllName.Length = Length;
-    DataTableEntry->FullDllName.MaximumLength = Length;
-    DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
-    while (*FullDllName != 0)
+    /* Get a pointer to the function table */
+    FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions));
+
+    /* Save a pointer to the function */
+    ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);
+
+    /* Is it a forwarder? (function pointer is within the export directory) */
+    ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
+    if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
+        ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
     {
-        *Buffer++ = *FullDllName++;
-    }
+        PLDR_DATA_TABLE_ENTRY DataTableEntry;
+        CHAR ForwardDllName[255];
+        PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
+        ULONG RefExportSize;
 
-    /* Initialize what's left - LoadCount which is 1, and set Flags so that
-       we know this entry is processed */
-    DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
-    DataTableEntry->LoadCount = 1;
+        TRACE("PeLdrpBindImportName(): ForwarderName %s\n", ForwarderName);
 
-    /* Insert this DTE to a list in the LPB */
-    InsertTailList(ModuleListHead, &DataTableEntry->InLoadOrderLinks);
-    TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n", DataTableEntry,
-          DataTableEntry->BaseDllName.Length / 2,
-          VaToPa(DataTableEntry->BaseDllName.Buffer),
-          DataTableEntry->DllBase);
+        /* Save the name of the forward dll */
+        RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));
 
-    /* Save pointer to a newly allocated and initialized entry */
-    *NewEntry = DataTableEntry;
+        /* Strip out the symbol name */
+        *strrchr(ForwardDllName,'.') = '\0';
 
-    /* Return success */
+        /* Check if the target image is already loaded */
+        if (!PeLdrCheckForLoadedDll(ModuleListHead, ForwardDllName, &DataTableEntry))
+        {
+            /* Check if the forward dll name has an extension */
+            if (strchr(ForwardDllName, '.') == NULL)
+            {
+                /* Name does not have an extension, append '.dll' */
+                strcat(ForwardDllName, ".dll");
+            }
+
+            /* Now let's try to load it! */
+            Success = PeLdrpLoadAndScanReferencedDll(ModuleListHead,
+                                                     DirectoryPath,
+                                                     ForwardDllName,
+                                                     &DataTableEntry);
+            if (!Success)
+            {
+                ERR("PeLdrpLoadAndScanReferencedDll() failed to load forwarder dll.\n");
+                return Success;
+            }
+        }
+
+        /* Get pointer to the export directory of loaded DLL */
+        RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
+            RtlImageDirectoryEntryToData(VaToPa(DataTableEntry->DllBase),
+            TRUE,
+            IMAGE_DIRECTORY_ENTRY_EXPORT,
+            &RefExportSize);
+
+        /* Fail if it's NULL */
+        if (RefExportDirectory)
+        {
+            UCHAR Buffer[128];
+            IMAGE_THUNK_DATA RefThunkData;
+            PIMAGE_IMPORT_BY_NAME ImportByName;
+            PCHAR ImportName;
+
+            /* Get pointer to the import name */
+            ImportName = strrchr(ForwarderName, '.') + 1;
+
+            /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
+            ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;
+
+            /* Fill the name with the import name */
+            RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);
+
+            /* Set Hint to 0 */
+            ImportByName->Hint = 0;
+
+            /* And finally point ThunkData's AddressOfData to that structure */
+            RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;
+
+            /* And recursively call ourselves */
+            Success = PeLdrpBindImportName(ModuleListHead,
+                                           DataTableEntry->DllBase,
+                                           ImageBase,
+                                           &RefThunkData,
+                                           RefExportDirectory,
+                                           RefExportSize,
+                                           TRUE,
+                                           DirectoryPath);
+
+            /* Fill out the ThunkData with data from RefThunkData */
+            ThunkData->u1 = RefThunkData.u1;
+
+            /* Return what we got from the recursive call */
+            return Success;
+        }
+        else
+        {
+            /* Fail if ExportDirectory is NULL */
+            return FALSE;
+        }
+    }
+
+    /* Success! */
     return TRUE;
 }
 
-/*
- * WinLdrLoadImage loads the specified image from the file (it doesn't
- * perform any additional operations on the filename, just directly
- * calls the file I/O routines), and relocates it so that it's ready
- * to be used when paging is enabled.
- * Addressing mode: physical
- */
-BOOLEAN
-WinLdrLoadImage(IN PCHAR FileName,
-                TYPE_OF_MEMORY MemoryType,
-                OUT PVOID *ImageBasePA)
+static BOOLEAN
+PeLdrpLoadAndScanReferencedDll(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PCCH DirectoryPath,
+    IN PCH ImportName,
+    OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
 {
-    ULONG FileId;
-    PVOID PhysicalBase;
-    PVOID VirtualBase = NULL;
-    UCHAR HeadersBuffer[SECTOR_SIZE * 2];
-    PIMAGE_NT_HEADERS NtHeaders;
-    PIMAGE_SECTION_HEADER SectionHeader;
-    ULONG VirtualSize, SizeOfRawData, NumberOfSections;
-    ARC_STATUS Status;
-    LARGE_INTEGER Position;
-    ULONG i, BytesRead;
+    CHAR FullDllName[256];
+    BOOLEAN Success;
+    PVOID BasePA = NULL;
 
-    TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);
+    /* Prepare the full path to the file to be loaded */
+    strcpy(FullDllName, DirectoryPath);
+    strcat(FullDllName, ImportName);
 
-    /* Open the image file */
-    Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
-    if (Status != ESUCCESS)
-    {
-        WARN("ArcOpen(FileName: '%s') failed. Status: %u\n", FileName, Status);
-        return FALSE;
-    }
+    TRACE("Loading referenced DLL: %s\n", FullDllName);
 
-    /* Load the first 2 sectors of the image so we can read the PE header */
-    Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
-    if (Status != ESUCCESS)
+    /* Load the image */
+    Success = PeLdrLoadImage(FullDllName, LoaderBootDriver, &BasePA);
+    if (!Success)
     {
-        ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
-        UiMessageBox("Error reading from file.");
-        ArcClose(FileId);
-        return FALSE;
+        ERR("PeLdrLoadImage() failed\n");
+        return Success;
     }
 
-    /* Now read the MZ header to get the offset to the PE Header */
-    NtHeaders = RtlImageNtHeader(HeadersBuffer);
-    if (!NtHeaders)
+    /* Allocate DTE for newly loaded DLL */
+    Success = PeLdrAllocateDataTableEntry(ModuleListHead,
+                                          ImportName,
+                                          FullDllName,
+                                          BasePA,
+                                          DataTableEntry);
+    if (!Success)
     {
-        ERR("No NT header found in \"%s\"\n", FileName);
-        UiMessageBox("Error - no NT header found.");
-        ArcClose(FileId);
-        return FALSE;
+        ERR("PeLdrAllocateDataTableEntry() failed\n");
+        return Success;
     }
 
-    /* Ensure this is executable image */
-    if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0))
+    /* Scan its dependencies too */
+    TRACE("PeLdrScanImportDescriptorTable() calling ourselves for %S\n",
+          VaToPa((*DataTableEntry)->BaseDllName.Buffer));
+    Success = PeLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
+    if (!Success)
     {
-        ERR("Not an executable image \"%s\"\n", FileName);
-        UiMessageBox("Not an executable image.");
-        ArcClose(FileId);
-        return FALSE;
+        ERR("PeLdrScanImportDescriptorTable() failed\n");
+        return Success;
     }
 
-    /* Store number of sections to read and a pointer to the first section */
-    NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
-    SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
+    return TRUE;
+}
 
-    /* Try to allocate this memory, if fails - allocate somewhere else */
-    PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
-                       (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
-                       MemoryType);
+static BOOLEAN
+PeLdrpScanImportAddressTable(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PVOID DllBase,
+    IN PVOID ImageBase,
+    IN PIMAGE_THUNK_DATA ThunkData,
+    IN PCSTR DirectoryPath)
+{
+    PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
+    BOOLEAN Success;
+    ULONG ExportSize;
 
-    if (PhysicalBase == NULL)
-    {
-        /* It's ok, we don't panic - let's allocate again at any other "low" place */
-        PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);
+    TRACE("PeLdrpScanImportAddressTable(): DllBase 0x%X, "
+          "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);
 
-        if (PhysicalBase == NULL)
-        {
-            ERR("Failed to alloc %lu bytes for image %s\n", NtHeaders->OptionalHeader.SizeOfImage, FileName);
-            UiMessageBox("Failed to alloc pages for image.");
-            ArcClose(FileId);
-            return FALSE;
-        }
+    /* Obtain the export table from the DLL's base */
+    if (DllBase == NULL)
+    {
+        ERR("Error, DllBase == NULL!\n");
+        return FALSE;
+    }
+    else
+    {
+        ExportDirectory =
+            (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(VaToPa(DllBase),
+                TRUE,
+                IMAGE_DIRECTORY_ENTRY_EXPORT,
+                &ExportSize);
     }
 
-    /* This is the real image base - in form of a virtual address */
-    VirtualBase = PaToVa(PhysicalBase);
-
-    TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
+    TRACE("PeLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory);
 
-    /* Set to 0 position and fully load the file image */
-    Position.QuadPart = 0;
-    Status = ArcSeek(FileId, &Position, SeekAbsolute);
-    if (Status != ESUCCESS)
+    /* If pointer to Export Directory is */
+    if (ExportDirectory == NULL)
     {
-        ERR("ArcSeek(File: '%s') failed. Status: 0x%lx\n", FileName, Status);
-        UiMessageBox("Error seeking the start of a file.");
-        ArcClose(FileId);
+        ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
         return FALSE;
     }
 
-    Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead);
-    if (Status != ESUCCESS)
+    /* Go through each entry in the thunk table and bind it */
+    while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
     {
-        ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
-        UiMessageBox("Error reading headers.");
-        ArcClose(FileId);
-        return FALSE;
+        /* Bind it */
+        Success = PeLdrpBindImportName(ModuleListHead,
+                                       DllBase,
+                                       ImageBase,
+                                       ThunkData,
+                                       ExportDirectory,
+                                       ExportSize,
+                                       FALSE,
+                                       DirectoryPath);
+
+        /* Move to the next entry */
+        ThunkData++;
+
+        /* Return error if binding was unsuccessful */
+        if (!Success)
+            return Success;
     }
 
-    /* Reload the NT Header */
-    NtHeaders = RtlImageNtHeader(PhysicalBase);
+    /* Return success */
+    return TRUE;
+}
 
-    /* Load the first section */
-    SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
 
-    /* Fill output parameters */
-    *ImageBasePA = PhysicalBase;
+/* FUNCTIONS *****************************************************************/
 
-    /* Walk through each section and read it (check/fix any possible
-       bad situations, if they arise) */
-    for (i = 0; i < NumberOfSections; i++)
-    {
-        VirtualSize = SectionHeader->Misc.VirtualSize;
-        SizeOfRawData = SectionHeader->SizeOfRawData;
+/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */
+BOOLEAN
+PeLdrCheckForLoadedDll(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PCH DllName,
+    OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
+{
+    PLDR_DATA_TABLE_ENTRY DataTableEntry;
+    LIST_ENTRY *ModuleEntry;
 
-        /* Handle a case when VirtualSize equals 0 */
-        if (VirtualSize == 0)
-            VirtualSize = SizeOfRawData;
+    TRACE("PeLdrCheckForLoadedDll: DllName %s\n", DllName);
 
-        /* If PointerToRawData is 0, then force its size to be also 0 */
-        if (SectionHeader->PointerToRawData == 0)
-        {
-            SizeOfRawData = 0;
-        }
-        else
-        {
-            /* Cut the loaded size to the VirtualSize extents */
-            if (SizeOfRawData > VirtualSize)
-                SizeOfRawData = VirtualSize;
-        }
-
-        /* Actually read the section (if its size is not 0) */
-        if (SizeOfRawData != 0)
-        {
-            /* Seek to the correct position */
-            Position.LowPart = SectionHeader->PointerToRawData;
-            Status = ArcSeek(FileId, &Position, SeekAbsolute);
-
-            TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
+    /* Just go through each entry in the LoadOrderList and compare loaded module's
+       name with a given name */
+    ModuleEntry = ModuleListHead->Flink;
+    while (ModuleEntry != ModuleListHead)
+    {
+        /* Get pointer to the current DTE */
+        DataTableEntry = CONTAINING_RECORD(ModuleEntry,
+            LDR_DATA_TABLE_ENTRY,
+            InLoadOrderLinks);
 
-            /* Read this section from the file, size = SizeOfRawData */
-            Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
-            if (Status != ESUCCESS)
-            {
-                ERR("WinLdrLoadImage(): Error reading section from file!\n");
-                break;
-            }
-        }
+        TRACE("PeLdrCheckForLoadedDll: DTE %p, EP %p, base %p name '%.*ws'\n",
+              DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
+              DataTableEntry->BaseDllName.Length / 2, VaToPa(DataTableEntry->BaseDllName.Buffer));
 
-        /* Size of data is less than the virtual size - fill up the remainder with zeroes */
-        if (SizeOfRawData < VirtualSize)
+        /* Compare names */
+        if (PeLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
         {
-            TRACE("WinLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize);
-            RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
+            /* Yes, found it, report pointer to the loaded module's DTE
+               to the caller and increase load count for it */
+            *LoadedEntry = DataTableEntry;
+            DataTableEntry->LoadCount++;
+            TRACE("PeLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry);
+            return TRUE;
         }
 
-        SectionHeader++;
-    }
-
-    /* We are done with the file - close it */
-    ArcClose(FileId);
-
-    /* If loading failed - return right now */
-    if (Status != ESUCCESS)
-        return FALSE;
-
-    /* Relocate the image, if it needs it */
-    if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
-    {
-        WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase,
-             VirtualBase);
-        return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
-                                                 (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
-                                                 "FreeLdr",
-                                                 TRUE,
-                                                 TRUE, /* in case of conflict still return success */
-                                                 FALSE);
+        /* Go to the next entry */
+        ModuleEntry = ModuleEntry->Flink;
     }
 
-    TRACE("WinLdrLoadImage() done, PA = %p\n", *ImageBasePA);
-    return TRUE;
+    /* Nothing found */
+    return FALSE;
 }
 
-/* PRIVATE FUNCTIONS *******************************************************/
-
-/* DllName - physical, UnicodeString->Buffer - virtual */
-static BOOLEAN
-WinLdrpCompareDllName(IN PCH DllName,
-                      IN PUNICODE_STRING UnicodeName)
+BOOLEAN
+PeLdrScanImportDescriptorTable(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PCCH DirectoryPath,
+    IN PLDR_DATA_TABLE_ENTRY ScanDTE)
 {
-    PWSTR Buffer;
-    SIZE_T i, Length;
+    PLDR_DATA_TABLE_ENTRY DataTableEntry;
+    PIMAGE_IMPORT_DESCRIPTOR ImportTable;
+    ULONG ImportTableSize;
+    PCH ImportName;
+    BOOLEAN Success;
 
-    /* First obvious check: for length of two names */
-    Length = strlen(DllName);
+    /* Get a pointer to the import table of this image */
+    ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
+        TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
 
 #if DBG
     {
-        UNICODE_STRING UnicodeNamePA;
-        UnicodeNamePA.Length = UnicodeName->Length;
-        UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
-        UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
-        TRACE("WinLdrpCompareDllName: %s and %wZ, Length = %d "
-              "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length);
+        UNICODE_STRING BaseName;
+        BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
+        BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
+        BaseName.Length = ScanDTE->BaseDllName.Length;
+        TRACE("PeLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
+              &BaseName, ImportTable);
     }
 #endif
 
-    if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
-        return FALSE;
-
-    /* Store pointer to unicode string's buffer */
-    Buffer = VaToPa(UnicodeName->Buffer);
+    /* If image doesn't have any import directory - just return success */
+    if (ImportTable == NULL)
+        return TRUE;
 
-    /* Loop character by character */
-    for (i = 0; i < Length; i++)
+    /* Loop through all entries */
+    for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++)
     {
-        /* Compare two characters, uppercasing them */
-        if (toupper(*DllName) != toupper((CHAR)*Buffer))
-            return FALSE;
+        /* Get pointer to the name */
+        ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
+        TRACE("PeLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);
 
-        /* Move to the next character */
-        DllName++;
-        Buffer++;
-    }
+        /* In case we get a reference to ourselves - just skip it */
+        if (PeLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
+            continue;
 
-    /* Check, if strings either fully match, or match till the "." (w/o extension) */
-    if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
-    {
-        /* Yes they do */
-        return TRUE;
+        /* Load the DLL if it is not already loaded */
+        if (!PeLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
+        {
+            Success = PeLdrpLoadAndScanReferencedDll(ModuleListHead,
+                                                     DirectoryPath,
+                                                     ImportName,
+                                                     &DataTableEntry);
+            if (!Success)
+            {
+                ERR("PeLdrpLoadAndScanReferencedDll() failed\n");
+                return Success;
+            }
+        }
+
+        /* Scan its import address table */
+        Success = PeLdrpScanImportAddressTable(ModuleListHead,
+                                               DataTableEntry->DllBase,
+                                               ScanDTE->DllBase,
+                                               (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
+                                               DirectoryPath);
+
+        if (!Success)
+        {
+            ERR("PeLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
+                ImportName, DirectoryPath);
+            return Success;
+        }
     }
 
-    /* Strings don't match, return FALSE */
-    return FALSE;
+    return TRUE;
 }
 
-static BOOLEAN
-WinLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead,
-                      IN PVOID DllBase,
-                      IN PVOID ImageBase,
-                      IN PIMAGE_THUNK_DATA ThunkData,
-                      IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
-                      IN ULONG ExportSize,
-                      IN BOOLEAN ProcessForwards,
-                      IN PCSTR DirectoryPath)
+BOOLEAN
+PeLdrAllocateDataTableEntry(
+    IN OUT PLIST_ENTRY ModuleListHead,
+    IN PCCH BaseDllName,
+    IN PCCH FullDllName,
+    IN PVOID BasePA,
+    OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
 {
-    ULONG Ordinal;
-    PULONG NameTable, FunctionTable;
-    PUSHORT OrdinalTable;
-    LONG High, Low, Middle, Result;
-    ULONG Hint;
-    PIMAGE_IMPORT_BY_NAME ImportData;
-    PCHAR ExportName, ForwarderName;
-    BOOLEAN Success;
+    PVOID BaseVA = PaToVa(BasePA);
+    PWSTR Buffer;
+    PLDR_DATA_TABLE_ENTRY DataTableEntry;
+    PIMAGE_NT_HEADERS NtHeaders;
+    USHORT Length;
 
-    //TRACE("WinLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X, ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n",
-    //      DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize, ProcessForwards);
+    TRACE("PeLdrAllocateDataTableEntry(, '%s', '%s', %p)\n",
+          BaseDllName, FullDllName, BasePA);
 
-    /* Check passed DllBase param */
-    if(DllBase == NULL)
-    {
-        WARN("DllBase == NULL!\n");
+    /* Allocate memory for a data table entry, zero-initialize it */
+    DataTableEntry = (PLDR_DATA_TABLE_ENTRY)FrLdrHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY),
+                                                           TAG_WLDR_DTE);
+    if (DataTableEntry == NULL)
         return FALSE;
-    }
+    RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
 
-    /* Convert all non-critical pointers to PA from VA */
-    ThunkData = VaToPa(ThunkData);
+    /* Get NT headers from the image */
+    NtHeaders = RtlImageNtHeader(BasePA);
 
-    /* Is the reference by ordinal? */
-    if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards)
+    /* Initialize corresponding fields of DTE based on NT headers value */
+    DataTableEntry->DllBase = BaseVA;
+    DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
+    DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
+    DataTableEntry->SectionPointer = 0;
+    DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
+
+    /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
+       by simple conversion - copying each character */
+    Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
+    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
+    if (Buffer == NULL)
     {
-        /* Yes, calculate the ordinal */
-        Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) - (UINT32)ExportDirectory->Base);
-        //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal);
+        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
+        return FALSE;
     }
-    else
-    {
-        /* It's reference by name, we have to look it up in the export directory */
-        if (!ProcessForwards)
-        {
-            /* AddressOfData in thunk entry will become a virtual address (from relative) */
-            //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD was %p\n", ThunkData->u1.AddressOfData);
-            ThunkData->u1.AddressOfData =
-                (ULONG_PTR)RVA(ImageBase, ThunkData->u1.AddressOfData);
-            //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD became %p\n", ThunkData->u1.AddressOfData);
-        }
-
-        /* Get the import name */
-        ImportData = VaToPa((PVOID)ThunkData->u1.AddressOfData);
-
-        /* Get pointers to Name and Ordinal tables (RVA -> VA) */
-        NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
-        OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));
-
-        //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n",
-        //      NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals);
-
-        /* Get the hint, convert it to a physical pointer */
-        Hint = ((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint;
-        //TRACE("HintIndex %d\n", Hint);
-
-        /* Get the export name from the hint */
-        ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));
-
-        /* If Hint is less than total number of entries in the export directory,
-           and import name == export name, then we can just get it from the OrdinalTable */
-        if ((Hint < ExportDirectory->NumberOfNames) &&
-            (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
-        {
-            Ordinal = OrdinalTable[Hint];
-            //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal);
-        }
-        else
-        {
-            /* It's not the easy way, we have to lookup import name in the name table.
-               Let's use a binary search for this task. */
-
-            //TRACE("WinLdrpBindImportName() looking up the import name using binary search...\n");
-
-            /* Low boundary is set to 0, and high boundary to the maximum index */
-            Low = 0;
-            High = ExportDirectory->NumberOfNames - 1;
+    RtlZeroMemory(Buffer, Length);
 
-            /* Perform a binary-search loop */
-            while (High >= Low)
-            {
-                /* Divide by 2 by shifting to the right once */
-                Middle = (Low + High) / 2;
+    DataTableEntry->BaseDllName.Length = Length;
+    DataTableEntry->BaseDllName.MaximumLength = Length;
+    DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
+    while (*BaseDllName != 0)
+    {
+        *Buffer++ = *BaseDllName++;
+    }
 
-                /* Get the name from the name table */
-                ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));
+    /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
+       using the same method */
+    Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
+    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
+    if (Buffer == NULL)
+    {
+        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
+        return FALSE;
+    }
+    RtlZeroMemory(Buffer, Length);
 
-                /* Compare the names */
-                Result = strcmp(ExportName, (PCHAR)ImportData->Name);
+    DataTableEntry->FullDllName.Length = Length;
+    DataTableEntry->FullDllName.MaximumLength = Length;
+    DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
+    while (*FullDllName != 0)
+    {
+        *Buffer++ = *FullDllName++;
+    }
 
-                // TRACE("Binary search: comparing Import '__', Export '%s'\n",
-                      // VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),
-                      // (PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));
+    /* Initialize what's left - LoadCount which is 1, and set Flags so that
+       we know this entry is processed */
+    DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
+    DataTableEntry->LoadCount = 1;
 
-                // TRACE("TE->u1.AOD %p, fulladdr %p\n",
-                      // ThunkData->u1.AddressOfData,
-                      // ((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name );
+    /* Insert this DTE to a list in the LPB */
+    InsertTailList(ModuleListHead, &DataTableEntry->InLoadOrderLinks);
+    TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n", DataTableEntry,
+          DataTableEntry->BaseDllName.Length / 2,
+          VaToPa(DataTableEntry->BaseDllName.Buffer),
+          DataTableEntry->DllBase);
 
-                /* Depending on result of strcmp, perform different actions */
-                if (Result > 0)
-                {
-                    /* Adjust top boundary */
-                    High = Middle - 1;
-                }
-                else if (Result < 0)
-                {
-                    /* Adjust bottom boundary */
-                    Low = Middle + 1;
-                }
-                else
-                {
-                    /* Yay, found it! */
-                    break;
-                }
-            }
+    /* Save pointer to a newly allocated and initialized entry */
+    *NewEntry = DataTableEntry;
 
-            /* If high boundary is less than low boundary, then no result found */
-            if (High < Low)
-            {
-                ERR("Did not find export '%s'!\n", (PCHAR)ImportData->Name);
-                return FALSE;
-            }
+    /* Return success */
+    return TRUE;
+}
 
-            /* Everything alright, get the ordinal */
-            Ordinal = OrdinalTable[Middle];
+/*
+ * PeLdrLoadImage loads the specified image from the file (it doesn't
+ * perform any additional operations on the filename, just directly
+ * calls the file I/O routines), and relocates it so that it's ready
+ * to be used when paging is enabled.
+ * Addressing mode: physical
+ */
+BOOLEAN
+PeLdrLoadImage(
+    IN PCHAR FileName,
+    IN TYPE_OF_MEMORY MemoryType,
+    OUT PVOID *ImageBasePA)
+{
+    ULONG FileId;
+    PVOID PhysicalBase;
+    PVOID VirtualBase = NULL;
+    UCHAR HeadersBuffer[SECTOR_SIZE * 2];
+    PIMAGE_NT_HEADERS NtHeaders;
+    PIMAGE_SECTION_HEADER SectionHeader;
+    ULONG VirtualSize, SizeOfRawData, NumberOfSections;
+    ARC_STATUS Status;
+    LARGE_INTEGER Position;
+    ULONG i, BytesRead;
 
-            //TRACE("WinLdrpBindImportName() found Ordinal %d\n", Ordinal);
-        }
-    }
+    TRACE("PeLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);
 
-    /* Check ordinal number for validity! */
-    if (Ordinal >= ExportDirectory->NumberOfFunctions)
+    /* Open the image file */
+    Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
+    if (Status != ESUCCESS)
     {
-        ERR("Ordinal number is invalid!\n");
+        WARN("ArcOpen(FileName: '%s') failed. Status: %u\n", FileName, Status);
         return FALSE;
     }
 
-    /* Get a pointer to the function table */
-    FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions));
+    /* Load the first 2 sectors of the image so we can read the PE header */
+    Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
+    if (Status != ESUCCESS)
+    {
+        ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
+        UiMessageBox("Error reading from file.");
+        ArcClose(FileId);
+        return FALSE;
+    }
 
-    /* Save a pointer to the function */
-    ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);
+    /* Now read the MZ header to get the offset to the PE Header */
+    NtHeaders = RtlImageNtHeader(HeadersBuffer);
+    if (!NtHeaders)
+    {
+        ERR("No NT header found in \"%s\"\n", FileName);
+        UiMessageBox("Error: No NT header found.");
+        ArcClose(FileId);
+        return FALSE;
+    }
 
-    /* Is it a forwarder? (function pointer is within the export directory) */
-    ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
-    if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
-        ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
+    /* Ensure this is executable image */
+    if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0))
     {
-        PLDR_DATA_TABLE_ENTRY DataTableEntry;
-        CHAR ForwardDllName[255];
-        PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
-        ULONG RefExportSize;
+        ERR("Not an executable image \"%s\"\n", FileName);
+        UiMessageBox("Not an executable image.");
+        ArcClose(FileId);
+        return FALSE;
+    }
 
-        TRACE("WinLdrpBindImportName(): ForwarderName %s\n", ForwarderName);
+    /* Store number of sections to read and a pointer to the first section */
+    NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
+    SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
 
-        /* Save the name of the forward dll */
-        RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));
+    /* Try to allocate this memory, if fails - allocate somewhere else */
+    PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
+                       (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
+                       MemoryType);
 
-        /* Strip out the symbol name */
-        *strrchr(ForwardDllName,'.') = '\0';
+    if (PhysicalBase == NULL)
+    {
+        /* It's ok, we don't panic - let's allocate again at any other "low" place */
+        PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);
 
-        /* Check if the target image is already loaded */
-        if (!WinLdrCheckForLoadedDll(ModuleListHead, ForwardDllName, &DataTableEntry))
+        if (PhysicalBase == NULL)
         {
-            /* Check if the forward dll name has an extension */
-            if (strchr(ForwardDllName, '.') == NULL)
-            {
-                /* Name does not have an extension, append '.dll' */
-                strcat(ForwardDllName, ".dll");
-            }
-
-            /* Now let's try to load it! */
-            Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead,
-                                                      DirectoryPath,
-                                                      ForwardDllName,
-                                                      &DataTableEntry);
-            if (!Success)
-            {
-                ERR("WinLdrpLoadAndScanReferencedDll() failed to load forwarder dll.\n");
-                return Success;
-            }
+            ERR("Failed to alloc %lu bytes for image %s\n", NtHeaders->OptionalHeader.SizeOfImage, FileName);
+            UiMessageBox("Failed to alloc pages for image.");
+            ArcClose(FileId);
+            return FALSE;
         }
+    }
 
-        /* Get pointer to the export directory of loaded DLL */
-        RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
-            RtlImageDirectoryEntryToData(VaToPa(DataTableEntry->DllBase),
-            TRUE,
-            IMAGE_DIRECTORY_ENTRY_EXPORT,
-            &RefExportSize);
+    /* This is the real image base - in form of a virtual address */
+    VirtualBase = PaToVa(PhysicalBase);
 
-        /* Fail if it's NULL */
-        if (RefExportDirectory)
-        {
-            UCHAR Buffer[128];
-            IMAGE_THUNK_DATA RefThunkData;
-            PIMAGE_IMPORT_BY_NAME ImportByName;
-            PCHAR ImportName;
+    TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
 
-            /* Get pointer to the import name */
-            ImportName = strrchr(ForwarderName, '.') + 1;
+    /* Set to 0 position and fully load the file image */
+    Position.QuadPart = 0;
+    Status = ArcSeek(FileId, &Position, SeekAbsolute);
+    if (Status != ESUCCESS)
+    {
+        ERR("ArcSeek(File: '%s') failed. Status: 0x%lx\n", FileName, Status);
+        UiMessageBox("Error seeking the start of a file.");
+        ArcClose(FileId);
+        return FALSE;
+    }
 
-            /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
-            ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;
+    Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead);
+    if (Status != ESUCCESS)
+    {
+        ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
+        UiMessageBox("Error reading headers.");
+        ArcClose(FileId);
+        return FALSE;
+    }
 
-            /* Fill the name with the import name */
-            RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);
+    /* Reload the NT Header */
+    NtHeaders = RtlImageNtHeader(PhysicalBase);
 
-            /* Set Hint to 0 */
-            ImportByName->Hint = 0;
+    /* Load the first section */
+    SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
 
-            /* And finally point ThunkData's AddressOfData to that structure */
-            RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;
+    /* Fill output parameters */
+    *ImageBasePA = PhysicalBase;
 
-            /* And recursively call ourselves */
-            Success = WinLdrpBindImportName(ModuleListHead,
-                                            DataTableEntry->DllBase,
-                                            ImageBase,
-                                            &RefThunkData,
-                                            RefExportDirectory,
-                                            RefExportSize,
-                                            TRUE,
-                                            DirectoryPath);
+    /* Walk through each section and read it (check/fix any possible
+       bad situations, if they arise) */
+    for (i = 0; i < NumberOfSections; i++)
+    {
+        VirtualSize = SectionHeader->Misc.VirtualSize;
+        SizeOfRawData = SectionHeader->SizeOfRawData;
 
-            /* Fill out the ThunkData with data from RefThunkData */
-            ThunkData->u1 = RefThunkData.u1;
+        /* Handle a case when VirtualSize equals 0 */
+        if (VirtualSize == 0)
+            VirtualSize = SizeOfRawData;
 
-            /* Return what we got from the recursive call */
-            return Success;
+        /* If PointerToRawData is 0, then force its size to be also 0 */
+        if (SectionHeader->PointerToRawData == 0)
+        {
+            SizeOfRawData = 0;
         }
         else
         {
-            /* Fail if ExportDirectory is NULL */
-            return FALSE;
+            /* Cut the loaded size to the VirtualSize extents */
+            if (SizeOfRawData > VirtualSize)
+                SizeOfRawData = VirtualSize;
         }
-    }
-
-    /* Success! */
-    return TRUE;
-}
-
-static BOOLEAN
-WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead,
-                                PCCH DirectoryPath,
-                                PCH ImportName,
-                                PLDR_DATA_TABLE_ENTRY *DataTableEntry)
-{
-    CHAR FullDllName[256];
-    BOOLEAN Success;
-    PVOID BasePA = NULL;
-
-    /* Prepare the full path to the file to be loaded */
-    strcpy(FullDllName, DirectoryPath);
-    strcat(FullDllName, ImportName);
-
-    TRACE("Loading referenced DLL: %s\n", FullDllName);
-
-    /* Load the image */
-    Success = WinLdrLoadImage(FullDllName, LoaderBootDriver, &BasePA);
-    if (!Success)
-    {
-        ERR("WinLdrLoadImage() failed\n");
-        return Success;
-    }
-
-    /* Allocate DTE for newly loaded DLL */
-    Success = WinLdrAllocateDataTableEntry(ModuleListHead,
-                                           ImportName,
-                                           FullDllName,
-                                           BasePA,
-                                           DataTableEntry);
-    if (!Success)
-    {
-        ERR("WinLdrAllocateDataTableEntry() failed\n");
-        return Success;
-    }
 
-    /* Scan its dependencies too */
-    TRACE("WinLdrScanImportDescriptorTable() calling ourselves for %S\n",
-          VaToPa((*DataTableEntry)->BaseDllName.Buffer));
-    Success = WinLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
-    if (!Success)
-    {
-        ERR("WinLdrScanImportDescriptorTable() failed\n");
-        return Success;
-    }
+        /* Actually read the section (if its size is not 0) */
+        if (SizeOfRawData != 0)
+        {
+            /* Seek to the correct position */
+            Position.LowPart = SectionHeader->PointerToRawData;
+            Status = ArcSeek(FileId, &Position, SeekAbsolute);
 
-    return TRUE;
-}
+            TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
 
-static BOOLEAN
-WinLdrpScanImportAddressTable(IN OUT PLIST_ENTRY ModuleListHead,
-                              IN PVOID DllBase,
-                              IN PVOID ImageBase,
-                              IN PIMAGE_THUNK_DATA ThunkData,
-                              IN PCSTR DirectoryPath)
-{
-    PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
-    BOOLEAN Success;
-    ULONG ExportSize;
+            /* Read this section from the file, size = SizeOfRawData */
+            Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
+            if (Status != ESUCCESS)
+            {
+                ERR("PeLdrLoadImage(): Error reading section from file!\n");
+                break;
+            }
+        }
 
-    TRACE("WinLdrpScanImportAddressTable(): DllBase 0x%X, "
-          "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);
+        /* Size of data is less than the virtual size - fill up the remainder with zeroes */
+        if (SizeOfRawData < VirtualSize)
+        {
+            TRACE("PeLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize);
+            RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
+        }
 
-    /* Obtain the export table from the DLL's base */
-    if (DllBase == NULL)
-    {
-        ERR("Error, DllBase == NULL!\n");
-        return FALSE;
-    }
-    else
-    {
-        ExportDirectory =
-            (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(VaToPa(DllBase),
-                TRUE,
-                IMAGE_DIRECTORY_ENTRY_EXPORT,
-                &ExportSize);
+        SectionHeader++;
     }
 
-    TRACE("WinLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory);
+    /* We are done with the file - close it */
+    ArcClose(FileId);
 
-    /* If pointer to Export Directory is */
-    if (ExportDirectory == NULL)
-    {
-        ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
+    /* If loading failed - return right now */
+    if (Status != ESUCCESS)
         return FALSE;
-    }
 
-    /* Go through each entry in the thunk table and bind it */
-    while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
+    /* Relocate the image, if it needs it */
+    if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
     {
-        /* Bind it */
-        Success = WinLdrpBindImportName(ModuleListHead,
-                                        DllBase,
-                                        ImageBase,
-                                        ThunkData,
-                                        ExportDirectory,
-                                        ExportSize,
-                                        FALSE,
-                                        DirectoryPath);
-
-        /* Move to the next entry */
-        ThunkData++;
-
-        /* Return error if binding was unsuccessful */
-        if (!Success)
-            return Success;
+        WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, VirtualBase);
+        return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
+                                                 (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
+                                                 "FreeLdr",
+                                                 TRUE,
+                                                 TRUE, /* in case of conflict still return success */
+                                                 FALSE);
     }
 
-    /* Return success */
+    TRACE("PeLdrLoadImage() done, PA = %p\n", *ImageBasePA);
     return TRUE;
 }
index fd31040..4ad35a2 100644 (file)
@@ -258,7 +258,7 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
     TRACE("DriverPath: '%s', DllName: '%s', LPB\n", DriverPath, DllName);
 
     // Check if driver is already loaded
-    Success = WinLdrCheckForLoadedDll(LoadOrderListHead, DllName, DriverDTE);
+    Success = PeLdrCheckForLoadedDll(LoadOrderListHead, DllName, DriverDTE);
     if (Success)
     {
         // We've got the pointer to its DTE, just return success
@@ -267,15 +267,15 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
 
     // It's not loaded, we have to load it
     RtlStringCbPrintfA(FullPath, sizeof(FullPath), "%s%wZ", BootPath, FilePath);
-    Success = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
+    Success = PeLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
     if (!Success)
         return FALSE;
 
     // Allocate a DTE for it
-    Success = WinLdrAllocateDataTableEntry(LoadOrderListHead, DllName, DllName, DriverBase, DriverDTE);
+    Success = PeLdrAllocateDataTableEntry(LoadOrderListHead, DllName, DllName, DriverBase, DriverDTE);
     if (!Success)
     {
-        ERR("WinLdrAllocateDataTableEntry() failed\n");
+        ERR("PeLdrAllocateDataTableEntry() failed\n");
         return FALSE;
     }
 
@@ -284,10 +284,10 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
 
     // Look for any dependencies it may have, and load them too
     RtlStringCbPrintfA(FullPath, sizeof(FullPath), "%s%s", BootPath, DriverPath);
-    Success = WinLdrScanImportDescriptorTable(LoadOrderListHead, FullPath, *DriverDTE);
+    Success = PeLdrScanImportDescriptorTable(LoadOrderListHead, FullPath, *DriverDTE);
     if (!Success)
     {
-        ERR("WinLdrScanImportDescriptorTable() failed for %s\n", FullPath);
+        ERR("PeLdrScanImportDescriptorTable() failed for %s\n", FullPath);
         return FALSE;
     }
 
@@ -451,7 +451,7 @@ LoadModule(
     RtlStringCbCopyA(FullFileName, sizeof(FullFileName), Path);
     RtlStringCbCatA(FullFileName, sizeof(FullFileName), File);
 
-    Success = WinLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
+    Success = PeLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
     if (!Success)
     {
         TRACE("Loading %s failed\n", File);
@@ -464,11 +464,11 @@ LoadModule(
      * the Kernel Debugger Transport DLL, to make the
      * PE loader happy.
      */
-    Success = WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
-                                           ImportName,
-                                           FullFileName,
-                                           BaseAddress,
-                                           Dte);
+    Success = PeLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
+                                          ImportName,
+                                          FullFileName,
+                                          BaseAddress,
+                                          Dte);
 
     return Success;
 }
@@ -640,11 +640,11 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
     }
 
     /* Load all referenced DLLs for Kernel, HAL and Kernel Debugger Transport DLL */
-    Success  = WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, *KernelDTE);
-    Success &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
+    Success  = PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, *KernelDTE);
+    Success &= PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
     if (KdComDTE)
     {
-        Success &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, KdComDTE);
+        Success &= PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, KdComDTE);
     }
 
     return Success;