- Get rid of LdrGetModuleObject, since MmLoadSystemImage will now return the existing...
authorAlex Ionescu <aionescu@gmail.com>
Fri, 23 Feb 2007 07:56:01 +0000 (07:56 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Fri, 23 Feb 2007 07:56:01 +0000 (07:56 +0000)
- Remove /ldr ntoskrnl directory, since this module is finally gone.
- Make PsInit code search for ntdll lookups using LookupEntryPoint internal function, instead of LdrGetProcedureAddress. Same code but done with recursion instead, and internal to this module (remove ANSI_STRINGs since we don't need them anymore).

svn path=/trunk/; revision=25886

reactos/ntoskrnl/include/internal/ldr.h
reactos/ntoskrnl/io/iomgr/driver.c
reactos/ntoskrnl/kdbg/kdb_symbols.c
reactos/ntoskrnl/ldr/loader.c [deleted file]
reactos/ntoskrnl/ldr/rtl.c [deleted file]
reactos/ntoskrnl/mm/mm.c
reactos/ntoskrnl/mm/pagefile.c
reactos/ntoskrnl/mm/sysldr.c
reactos/ntoskrnl/ntoskrnl.rbuild
reactos/ntoskrnl/ps/psmgr.c

index 882bc2d..9898813 100644 (file)
@@ -6,8 +6,4 @@
 #define DRIVER_ROOT_NAME        L"\\Driver\\"
 #define FILESYSTEM_ROOT_NAME    L"\\FileSystem\\"
 
-PLDR_DATA_TABLE_ENTRY
-NTAPI
-LdrGetModuleObject(PUNICODE_STRING ModuleName);
-
 #endif /* __INCLUDE_INTERNAL_LDR_H */
index 74c3c6a..055a7cf 100644 (file)
@@ -435,34 +435,20 @@ IopLoadServiceModule(
       return Status;
    }
 
-   /*
-    * Load the module.
-    */
-
-   *ModuleObject = LdrGetModuleObject(&ServiceImagePath);
-
-   if (*ModuleObject == NULL)
-   {
       /*
        * Case for disabled drivers
        */
 
-      if (ServiceStart >= 4)
-      {
-         /* FIXME: Check if it is the right status code */
-         Status = STATUS_PLUGPLAY_NO_DEVICE;
-      }
-      else
-      {
-         DPRINT("Loading module\n");
-         Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, NULL);
-      }
-   }
-   else
-   {
-      DPRINT("Module already loaded\n");
-      Status = STATUS_IMAGE_ALREADY_LOADED;
-   }
+  if (ServiceStart >= 4)
+  {
+     /* FIXME: Check if it is the right status code */
+     Status = STATUS_PLUGPLAY_NO_DEVICE;
+  }
+  else
+  {
+     DPRINT("Loading module\n");
+     Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, NULL);
+  }
 
    ExFreePool(ServiceImagePath.Buffer);
 
@@ -1062,7 +1048,6 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
    UNICODE_STRING ServiceName;
    UNICODE_STRING ObjectName;
    PDRIVER_OBJECT DriverObject;
-   PLDR_DATA_TABLE_ENTRY ModuleObject;
    NTSTATUS Status;
    LPWSTR Start;
 
@@ -1145,16 +1130,6 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
       return Status;
    }
 
-   /*
-    * ... and check if it's loaded
-    */
-
-   ModuleObject = LdrGetModuleObject(&ImagePath);
-   if (ModuleObject == NULL)
-   {
-      return STATUS_UNSUCCESSFUL;
-   }
-
    /*
     * Free the service path
     */
@@ -1169,7 +1144,7 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
       (*DriverObject->DriverUnload)(DriverObject);
    ObDereferenceObject(DriverObject);
    ObDereferenceObject(DriverObject);
-   MmUnloadSystemImage(ModuleObject);
+   MmUnloadSystemImage(DriverObject->DriverSection);
 
    return STATUS_SUCCESS;
 }
@@ -1692,18 +1667,6 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
    DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
    DPRINT("Type: %lx\n", Type);
 
-   /*
-    * See, if the driver module isn't already loaded
-    */
-
-   ModuleObject = LdrGetModuleObject(&ImagePath);
-   if (ModuleObject != NULL)
-   {
-      DPRINT("Image already loaded\n");
-      Status = STATUS_IMAGE_ALREADY_LOADED;
-      goto ReleaseCapturedString;
-   }
-
    /*
     * Create device node
     */
index 3b96b96..b57fed0 100644 (file)
@@ -608,7 +608,7 @@ KdbSymProcessBootSymbols(IN PUNICODE_STRING FileName)
       IsRaw = FALSE;
     }
 
-  ModuleObject = LdrGetModuleObject(ModuleName);
+  ModuleObject = NULL;
 
   if (ModuleObject != NULL)
   {
diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c
deleted file mode 100644 (file)
index 8eb33e4..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ldr/loader.c
- * PURPOSE:         Loaders for PE executables
- *
- * PROGRAMMERS:     Jean Michault
- *                  Rex Jolliff (rex@lvcablemodem.com)
- *                  Jason Filby (jasonfilby@yahoo.com)
- *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
- */
-
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-static LONG
-LdrpCompareModuleNames (
-                        IN PUNICODE_STRING String1,
-                        IN PUNICODE_STRING String2 )
-{
-    ULONG len1, len2, i;
-    PWCHAR s1, s2, p;
-    WCHAR  c1, c2;
-
-    if (String1 && String2)
-    {
-        /* Search String1 for last path component */
-        len1 = String1->Length / sizeof(WCHAR);
-        s1 = String1->Buffer;
-        for (i = 0, p = String1->Buffer; i < String1->Length; i = i + sizeof(WCHAR), p++)
-        {
-            if (*p == L'\\')
-            {
-                if (i == String1->Length - sizeof(WCHAR))
-                {
-                    s1 = NULL;
-                    len1 = 0;
-                }
-                else
-                {
-                    s1 = p + 1;
-                    len1 = (String1->Length - i) / sizeof(WCHAR);
-                }
-            }
-        }
-
-        /* Search String2 for last path component */
-        len2 = String2->Length / sizeof(WCHAR);
-        s2 = String2->Buffer;
-        for (i = 0, p = String2->Buffer; i < String2->Length; i = i + sizeof(WCHAR), p++)
-        {
-            if (*p == L'\\')
-            {
-                if (i == String2->Length - sizeof(WCHAR))
-                {
-                    s2 = NULL;
-                    len2 = 0;
-                }
-                else
-                {
-                    s2 = p + 1;
-                    len2 = (String2->Length - i) / sizeof(WCHAR);
-                }
-            }
-        }
-
-        /* Compare last path components */
-        if (s1 && s2)
-        {
-            while (1)
-            {
-                c1 = len1-- ? RtlUpcaseUnicodeChar (*s1++) : 0;
-                c2 = len2-- ? RtlUpcaseUnicodeChar (*s2++) : 0;
-                if ((c1 == 0 && c2 == L'.') || (c1 == L'.' && c2 == 0))
-                    return(0);
-                if (!c1 || !c2 || c1 != c2)
-                    return(c1 - c2);
-            }
-        }
-    }
-
-    return(0);
-}
-
-extern KSPIN_LOCK PsLoadedModuleSpinLock;
-
-//
-// Used for checking if a module is already in the module list.
-// Used during loading/unloading drivers.
-//
-PLDR_DATA_TABLE_ENTRY
-NTAPI
-LdrGetModuleObject ( PUNICODE_STRING ModuleName )
-{
-    PLDR_DATA_TABLE_ENTRY Module;
-    PLIST_ENTRY Entry;
-    KIRQL Irql;
-
-    DPRINT("LdrGetModuleObject(%wZ) called\n", ModuleName);
-
-    KeAcquireSpinLock(&PsLoadedModuleSpinLock,&Irql);
-
-    Entry = PsLoadedModuleList.Flink;
-    while (Entry != &PsLoadedModuleList)
-    {
-        Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
-
-        DPRINT("Comparing %wZ and %wZ\n",
-            &Module->BaseDllName,
-            ModuleName);
-
-        if (!LdrpCompareModuleNames(&Module->BaseDllName, ModuleName))
-        {
-            DPRINT("Module %wZ\n", &Module->BaseDllName);
-            KeReleaseSpinLock(&PsLoadedModuleSpinLock, Irql);
-            return(Module);
-        }
-
-        Entry = Entry->Flink;
-    }
-
-    KeReleaseSpinLock(&PsLoadedModuleSpinLock, Irql);
-
-    DPRINT("Could not find module '%wZ'\n", ModuleName);
-
-    return(NULL);
-}
-
-/* EOF */
diff --git a/reactos/ntoskrnl/ldr/rtl.c b/reactos/ntoskrnl/ldr/rtl.c
deleted file mode 100644 (file)
index 8e8ff37..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ldr/rtl.c
- * PURPOSE:         Loader utilities
- *
- * PROGRAMMERS:     Jean Michault
- *                  Rex Jolliff (rex@lvcablemodem.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS ****************************************************************/
-
-NTSTATUS STDCALL
-LdrGetProcedureAddress (IN PVOID BaseAddress,
-                        IN PANSI_STRING Name,
-                        IN ULONG Ordinal,
-                        OUT PVOID *ProcedureAddress)
-{
-   PIMAGE_EXPORT_DIRECTORY ExportDir;
-   ULONG ExportDirSize = 0;
-   PUSHORT OrdinalPtr;
-   PULONG NamePtr;
-   PCHAR CurrentNamePtr;
-   PULONG AddressPtr;
-
-   if (ProcedureAddress == NULL)
-      return STATUS_INVALID_PARAMETER;
-
-   /* get the pointer to the export directory */
-   ExportDir = RtlImageDirectoryEntryToData(BaseAddress, TRUE,
-                                           IMAGE_DIRECTORY_ENTRY_EXPORT,
-                                           &ExportDirSize);
-
-   if (ExportDir == NULL || ExportDirSize == 0)
-      return STATUS_INVALID_PARAMETER;
-
-   AddressPtr = (PULONG)RVA(BaseAddress, ExportDir->AddressOfFunctions);
-
-   if (Name && Name->Length)
-   {
-      LONG minn, maxn, mid, res;
-
-      /* Search for export by name */
-
-      /*
-       * NOTE: Exports are always sorted and so we can apply binary search.
-       * Also the function names are _case sensitive_, so respect that.
-       * -- Filip Navara, August 1st, 2005
-       */
-
-      /*
-       * I don't know who wrote this code but it's not working.
-       * Test case: KiFastSystemCall and KiFastSystemCallRet in ntdll.
-       * Former can't be found even though it's exported.
-       */
-
-      OrdinalPtr = (PUSHORT)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
-      NamePtr = (PULONG)RVA(BaseAddress, ExportDir->AddressOfNames);
-
-      minn = 0; maxn = ExportDir->NumberOfNames - 1;
-      while (minn <= maxn)
-      {
-         mid = (minn + maxn) / 2;
-         CurrentNamePtr = (PCHAR)RVA(BaseAddress, NamePtr[mid]);
-         res = strcmp(CurrentNamePtr, Name->Buffer);
-         if (res == 0)
-         {
-            /*
-             * Check if the beginning of the name matched, but it's still
-             * not the whole name.
-             */
-             *ProcedureAddress = (PVOID)RVA(BaseAddress, AddressPtr[OrdinalPtr[mid]]);
-             return STATUS_SUCCESS;
-         }
-         if (res > 0)
-            maxn = mid - 1;
-         else
-            minn = mid + 1;
-      }
-
-      CPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
-   }
-   else
-   {
-      /* Search for export by ordinal */
-
-      Ordinal &= 0x0000FFFF;
-      if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions)
-      {
-         *ProcedureAddress = (PVOID)RVA(BaseAddress, AddressPtr[Ordinal - ExportDir->Base]);
-         return STATUS_SUCCESS;
-      }
-
-      CPRINT("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal);
-   }
-
-   return STATUS_PROCEDURE_NOT_FOUND;
-}
-
-/* EOF */
index cd33300..0711646 100644 (file)
@@ -398,70 +398,6 @@ MmSetAddressRangeModified (
    return (FALSE);
 }
 
-/*
- * @implemented
- */
-PVOID
-NTAPI
-MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
-{
-    PVOID ProcAddress;
-    ANSI_STRING AnsiRoutineName;
-    NTSTATUS Status;
-    PLIST_ENTRY NextEntry;
-    extern LIST_ENTRY PsLoadedModuleList;
-    PLDR_DATA_TABLE_ENTRY LdrEntry;
-    BOOLEAN Found = FALSE;
-    UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
-    UNICODE_STRING HalName = RTL_CONSTANT_STRING(L"hal.dll");
-
-    /* Convert routine to ansi name */
-    Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
-                                          SystemRoutineName,
-                                          TRUE);
-    if (!NT_SUCCESS(Status)) return NULL;
-
-    /* Loop the loaded module list */
-    NextEntry = PsLoadedModuleList.Flink;
-    while (NextEntry != &PsLoadedModuleList)
-    {
-        /* Get the entry */
-        LdrEntry = CONTAINING_RECORD(NextEntry,
-                                     LDR_DATA_TABLE_ENTRY,
-                                     InLoadOrderLinks);
-
-        /* Check if it's the kernel or HAL */
-        if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
-        {
-            /* Found it */
-            Found = TRUE;
-        }
-        else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
-        {
-            /* Found it */
-            Found = TRUE;
-        }
-
-        /* Check if we found a valid binary */
-        if (Found)
-        {
-            /* Find the procedure name */
-            Status = LdrGetProcedureAddress(LdrEntry->DllBase,
-                                            &AnsiRoutineName,
-                                            0,
-                                            &ProcAddress);
-            break;
-        }
-
-        /* Keep looping */
-        NextEntry = NextEntry->Flink;
-    }
-
-    /* Free the string and return */
-    RtlFreeAnsiString(&AnsiRoutineName);
-    return (NT_SUCCESS(Status) ? ProcAddress : NULL);
-}
-
 NTSTATUS
 NTAPI
 NtGetWriteWatch(IN HANDLE ProcessHandle,
index 3b5fed1..15c60ed 100644 (file)
 #pragma alloc_text(INIT, MmInitPagingFile)
 #endif
 
+PVOID
+NTAPI
+MiFindExportedRoutineByName(IN PVOID DllBase,
+                            IN PANSI_STRING ExportName);
 
 /* TYPES *********************************************************************/
 
@@ -694,7 +698,7 @@ MmInitializeCrashDump(HANDLE PageFileHandle, ULONG PageFileNum)
    UNICODE_STRING DiskDumpName = RTL_CONSTANT_STRING(L"DiskDump");
    ANSI_STRING ProcName;
    PIO_STACK_LOCATION StackPtr;
-   PLDR_DATA_TABLE_ENTRY ModuleObject;
+   PLDR_DATA_TABLE_ENTRY ModuleObject = NULL;
 
    Status = ZwFsControlFile(PageFileHandle,
                             0,
@@ -767,16 +771,14 @@ MmInitializeCrashDump(HANDLE PageFileHandle, ULONG PageFileNum)
    }
 
    /* Load the diskdump driver. */
-   ModuleObject = LdrGetModuleObject(&DiskDumpName);
+   Status = MmLoadSystemImage(&DiskDumpName, NULL, NULL, 0, (PVOID)&ModuleObject, NULL);
    if (ModuleObject == NULL)
    {
       return(STATUS_OBJECT_NAME_NOT_FOUND);
    }
    RtlInitAnsiString(&ProcName, "DiskDumpFunctions");
-   Status = LdrGetProcedureAddress(ModuleObject->DllBase,
-                                   &ProcName,
-                                   0,
-                                   (PVOID*)&MmCoreDumpFunctions);
+   MmCoreDumpFunctions = MiFindExportedRoutineByName(ModuleObject->DllBase,
+                                                     &ProcName);
    if (!NT_SUCCESS(Status))
    {
       ObDereferenceObject(PageFile);
index d6c2de7..cb4660e 100644 (file)
@@ -56,6 +56,77 @@ MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
     ExFreePool(LdrEntry->LoadedImports);\r
 }\r
 \r
+PVOID\r
+NTAPI\r
+MiFindExportedRoutineByName(IN PVOID DllBase,\r
+                            IN PANSI_STRING ExportName)\r
+{\r
+    PULONG NameTable;\r
+    PUSHORT OrdinalTable;\r
+    PIMAGE_EXPORT_DIRECTORY ExportDirectory;\r
+    LONG Low = 0, Mid = 0, High, Ret;\r
+    USHORT Ordinal;\r
+    PVOID Function;\r
+    ULONG ExportSize;\r
+    PULONG ExportTable;\r
+    PAGED_CODE();\r
+\r
+    /* Get the export directory */\r
+    ExportDirectory = RtlImageDirectoryEntryToData(DllBase,\r
+                                                   TRUE,\r
+                                                   IMAGE_DIRECTORY_ENTRY_EXPORT,\r
+                                                   &ExportSize);\r
+    if (!ExportDirectory) return NULL;\r
+\r
+    /* Setup name tables */\r
+    NameTable = (PULONG)((ULONG_PTR)DllBase +\r
+                         ExportDirectory->AddressOfNames);\r
+    OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +\r
+                             ExportDirectory->AddressOfNameOrdinals);\r
+\r
+    /* Do a binary search */\r
+    High = ExportDirectory->NumberOfNames - 1;\r
+    while (High >= Low)\r
+    {\r
+        /* Get new middle value */\r
+        Mid = (Low + High) >> 1;\r
+\r
+        /* Compare name */\r
+        Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);\r
+        if (Ret < 0)\r
+        {\r
+            /* Update high */\r
+            High = Mid - 1;\r
+        }\r
+        else if (Ret > 0)\r
+        {\r
+            /* Update low */\r
+            Low = Mid + 1;\r
+        }\r
+        else\r
+        {\r
+            /* We got it */\r
+            break;\r
+        }\r
+    }\r
+\r
+    /* Check if we couldn't find it */\r
+    if (High < Low) return NULL;\r
+\r
+    /* Otherwise, this is the ordinal */\r
+    Ordinal = OrdinalTable[Mid];\r
+\r
+    /* Resolve the address and write it */\r
+    ExportTable = (PULONG)((ULONG_PTR)DllBase +\r
+                           ExportDirectory->AddressOfFunctions);\r
+    Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);\r
+\r
+    /* We found it! */\r
+    ASSERT((Function > (PVOID)ExportDirectory) &&\r
+           (Function < (PVOID)((ULONG_PTR)ExportDirectory + ExportSize)));\r
+    return Function;\r
+}\r
+\r
 PVOID\r
 NTAPI\r
 MiLocateExportName(IN PVOID DllBase,\r
@@ -1712,3 +1783,77 @@ Quickie:
     return Status;\r
 }\r
 \r
+/*\r
+ * @implemented\r
+ */\r
+PVOID\r
+NTAPI\r
+MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)\r
+{\r
+    PVOID ProcAddress = NULL;\r
+    ANSI_STRING AnsiRoutineName;\r
+    NTSTATUS Status;\r
+    PLIST_ENTRY NextEntry;\r
+    extern LIST_ENTRY PsLoadedModuleList;\r
+    PLDR_DATA_TABLE_ENTRY LdrEntry;\r
+    BOOLEAN Found = FALSE;\r
+    UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");\r
+    UNICODE_STRING HalName = RTL_CONSTANT_STRING(L"hal.dll");\r
+    ULONG Modules = 0;\r
+\r
+    /* Convert routine to ansi name */\r
+    Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,\r
+                                          SystemRoutineName,\r
+                                          TRUE);\r
+    if (!NT_SUCCESS(Status)) return NULL;\r
+\r
+    /* Lock the list */\r
+    KeEnterCriticalRegion();\r
+\r
+    /* Loop the loaded module list */\r
+    NextEntry = PsLoadedModuleList.Flink;\r
+    while (NextEntry != &PsLoadedModuleList)\r
+    {\r
+        /* Get the entry */\r
+        LdrEntry = CONTAINING_RECORD(NextEntry,\r
+                                     LDR_DATA_TABLE_ENTRY,\r
+                                     InLoadOrderLinks);\r
+\r
+        /* Check if it's the kernel or HAL */\r
+        if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))\r
+        {\r
+            /* Found it */\r
+            Found = TRUE;\r
+            Modules++;\r
+        }\r
+        else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))\r
+        {\r
+            /* Found it */\r
+            Found = TRUE;\r
+            Modules++;\r
+        }\r
+\r
+        /* Check if we found a valid binary */\r
+        if (Found)\r
+        {\r
+            /* Find the procedure name */\r
+            ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,\r
+                                                      &AnsiRoutineName);\r
+\r
+            /* Break out if we found it or if we already tried both modules */\r
+            if (ProcAddress) break;\r
+            if (Modules == 2) break;\r
+        }\r
+\r
+        /* Keep looping */\r
+        NextEntry = NextEntry->Flink;\r
+    }\r
+\r
+    /* Release the lock */\r
+    KeLeaveCriticalRegion();\r
+\r
+    /* Free the string and return */\r
+    RtlFreeAnsiString(&AnsiRoutineName);\r
+    return ProcAddress;\r
+}\r
+\r
index 6089107..fa8309a 100644 (file)
             <file>kdio.c</file>
             <file>kdmain.c</file>
     </directory>
-    <directory name="ldr">
-            <file>loader.c</file>
-            <file>rtl.c</file>
-    </directory>
     <directory name="lpc">
             <file>close.c</file>
             <file>complete.c</file>
index 7567844..50c8ac6 100644 (file)
@@ -38,15 +38,6 @@ PVOID PspSystemDllBase;
 PVOID PspSystemDllSection;
 PVOID PspSystemDllEntryPoint;
 
-ANSI_STRING ThunkName = RTL_CONSTANT_STRING("LdrInitializeThunk");
-ANSI_STRING ApcName = RTL_CONSTANT_STRING("KiUserApcDispatcher");
-ANSI_STRING ExceptName = RTL_CONSTANT_STRING("KiUserExceptionDispatcher");
-ANSI_STRING CallbackName = RTL_CONSTANT_STRING("KiUserCallbackDispatcher");
-ANSI_STRING RaiseName = RTL_CONSTANT_STRING("KiRaiseUserExceptionDispatcher");
-ANSI_STRING FastName = RTL_CONSTANT_STRING("KiFastSystemCall");
-ANSI_STRING FastReturnName = RTL_CONSTANT_STRING("KiFastSystemCallRet");
-ANSI_STRING InterruptName = RTL_CONSTANT_STRING("KiIntSystemCall");
-
 UNICODE_STRING PsNtDllPathName =
     RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll");
 
@@ -67,13 +58,106 @@ BOOLEAN PspDoingGiveBacks;
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
+ULONG
+NTAPI
+NameToOrdinal(IN PCHAR Name,
+              IN PVOID DllBase,
+              IN ULONG NumberOfNames,
+              IN PULONG NameTable,
+              IN PUSHORT OrdinalTable)
+{
+    ULONG Mid;
+    LONG Ret;
+
+    /* Fail if no names */
+    if (!NumberOfNames) return -1;
+
+    /* Do binary search */
+    Mid = NumberOfNames >> 1;
+    Ret = strcmp(Name, (PCHAR)((ULONG_PTR)DllBase + NameTable[Mid]));
+
+    /* Check if we found it */
+    if (!Ret) return OrdinalTable[Mid];
+
+    /* We didn't. Check if we only had one name to check */
+    if (NumberOfNames == 1) return -1;
+
+    /* Check if we should look up or down */
+    if (Ret < 0)
+    {
+        /* Loop down */
+        NumberOfNames = Mid;
+    }
+    else
+    {
+        /* Look up, update tables */
+        NameTable = &NameTable[Mid + 1];
+        OrdinalTable = &OrdinalTable[Mid + 1];
+        NumberOfNames -= (Mid - 1);
+    }
+
+    /* Call us recursively */
+    return NameToOrdinal(Name, DllBase, NumberOfNames, NameTable, OrdinalTable);
+}
+
+NTSTATUS
+NTAPI
+LookupEntryPoint(IN PVOID DllBase,
+                 IN PCHAR Name,
+                 OUT PVOID *EntryPoint)
+{
+    PULONG NameTable;
+    PUSHORT OrdinalTable;
+    PIMAGE_EXPORT_DIRECTORY ExportDirectory;
+    ULONG ExportSize;
+    CHAR Buffer[64];
+    USHORT Ordinal;
+    PULONG ExportTable;
+
+    /* Get the export directory */
+    ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
+                                                   TRUE,
+                                                   IMAGE_DIRECTORY_ENTRY_EXPORT,
+                                                   &ExportSize);
+
+    /* Validate the name and copy it */
+    if (strlen(Name) > sizeof(Buffer) - 2) return STATUS_INVALID_PARAMETER;
+    strcpy(Buffer, Name);
+
+    /* Setup name tables */
+    NameTable = (PULONG)((ULONG_PTR)DllBase +
+                         ExportDirectory->AddressOfNames);
+    OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
+                             ExportDirectory->AddressOfNameOrdinals);
+
+    /* Get the ordinal */
+    Ordinal = NameToOrdinal(Buffer,
+                            DllBase,
+                            ExportDirectory->NumberOfNames,
+                            NameTable,
+                            OrdinalTable);
+
+    /* Make sure the ordinal is valid */
+    if (Ordinal >= ExportDirectory->NumberOfFunctions)
+    {
+        /* It's not, fail */
+        return STATUS_PROCEDURE_NOT_FOUND;
+    }
+
+    /* Resolve the address and write it */
+    ExportTable = (PULONG)((ULONG_PTR)DllBase +
+                           ExportDirectory->AddressOfFunctions);
+    *EntryPoint = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 NTAPI
-PspLookupSystemDllEntryPoint(IN PANSI_STRING Name,
+PspLookupSystemDllEntryPoint(IN PCHAR Name,
                              IN PVOID *EntryPoint)
 {
     /* Call the LDR Routine */
-    return LdrGetProcedureAddress(PspSystemDllBase, Name, 0, EntryPoint);
+    return LookupEntryPoint(PspSystemDllBase, Name, EntryPoint);
 }
 
 NTSTATUS
@@ -83,22 +167,22 @@ PspLookupKernelUserEntryPoints(VOID)
     NTSTATUS Status;
 
     /* Get user-mode APC trampoline */
-    Status = PspLookupSystemDllEntryPoint(&ApcName,
+    Status = PspLookupSystemDllEntryPoint("KiUserApcDispatcher",
                                           &KeUserApcDispatcher);
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Get user-mode exception dispatcher */
-    Status = PspLookupSystemDllEntryPoint(&ExceptName,
+    Status = PspLookupSystemDllEntryPoint("KiUserExceptionDispatcher",
                                           &KeUserExceptionDispatcher);
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Get user-mode callback dispatcher */
-    Status = PspLookupSystemDllEntryPoint(&CallbackName,
+    Status = PspLookupSystemDllEntryPoint("KiUserCallbackDispatcher",
                                           &KeUserCallbackDispatcher);
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Get user-mode exception raise trampoline */
-    Status = PspLookupSystemDllEntryPoint(&RaiseName,
+    Status = PspLookupSystemDllEntryPoint("KiRaiseUserExceptionDispatcher",
                                           &KeRaiseUserExceptionDispatcher);
     if (!NT_SUCCESS(Status)) return Status;
 
@@ -106,20 +190,20 @@ PspLookupKernelUserEntryPoints(VOID)
     if (KeFeatureBits & KF_FAST_SYSCALL)
     {
         /* Get user-mode sysenter stub */
-        Status = PspLookupSystemDllEntryPoint(&FastName,
+        Status = PspLookupSystemDllEntryPoint("KiFastSystemCall",
                                               (PVOID)&SharedUserData->
                                               SystemCall);
         if (!NT_SUCCESS(Status)) return Status;
 
         /* Get user-mode sysenter return stub */
-        Status = PspLookupSystemDllEntryPoint(&FastReturnName,
+        Status = PspLookupSystemDllEntryPoint("KiFastSystemCallRet",
                                               (PVOID)&SharedUserData->
                                               SystemCallReturn);
     }
     else
     {
         /* Get the user-mode interrupt stub */
-        Status = PspLookupSystemDllEntryPoint(&InterruptName,
+        Status = PspLookupSystemDllEntryPoint("KiIntSystemCall",
                                               (PVOID)&SharedUserData->
                                               SystemCall);
     }
@@ -250,7 +334,8 @@ PspInitializeSystemDll(VOID)
     NTSTATUS Status;
 
     /* Get user-mode startup thunk */
-    Status = PspLookupSystemDllEntryPoint(&ThunkName, &PspSystemDllEntryPoint);
+    Status = PspLookupSystemDllEntryPoint("LdrInitializeThunk",
+                                          &PspSystemDllEntryPoint);
     if (!NT_SUCCESS(Status))
     {
         /* Failed, bugcheck */