diff --git a/reactos/ntoskrnl/include/internal/ldr.h b/reactos/ntoskrnl/include/internal/ldr.h index 882bc2dea22..98988135237 100644 --- a/reactos/ntoskrnl/include/internal/ldr.h +++ b/reactos/ntoskrnl/include/internal/ldr.h @@ -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 */ diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index 74c3c6a413a..055a7cf0f1c 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -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 */ diff --git a/reactos/ntoskrnl/kdbg/kdb_symbols.c b/reactos/ntoskrnl/kdbg/kdb_symbols.c index 3b96b9630d7..b57fed0a405 100644 --- a/reactos/ntoskrnl/kdbg/kdb_symbols.c +++ b/reactos/ntoskrnl/kdbg/kdb_symbols.c @@ -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 index 8eb33e45da5..00000000000 --- a/reactos/ntoskrnl/ldr/loader.c +++ /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 -#define NDEBUG -#include - -/* 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 index 8e8ff37d5db..00000000000 --- a/reactos/ntoskrnl/ldr/rtl.c +++ /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 -#define NDEBUG -#include - -/* 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 */ diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index cd333002731..0711646f4fd 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -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, diff --git a/reactos/ntoskrnl/mm/pagefile.c b/reactos/ntoskrnl/mm/pagefile.c index 3b5fed1dc03..15c60ed000c 100644 --- a/reactos/ntoskrnl/mm/pagefile.c +++ b/reactos/ntoskrnl/mm/pagefile.c @@ -35,6 +35,10 @@ #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); diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/sysldr.c index d6c2de723f0..cb4660e4bad 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/sysldr.c @@ -56,6 +56,77 @@ MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry) ExFreePool(LdrEntry->LoadedImports); } +PVOID +NTAPI +MiFindExportedRoutineByName(IN PVOID DllBase, + IN PANSI_STRING ExportName) +{ + PULONG NameTable; + PUSHORT OrdinalTable; + PIMAGE_EXPORT_DIRECTORY ExportDirectory; + LONG Low = 0, Mid = 0, High, Ret; + USHORT Ordinal; + PVOID Function; + ULONG ExportSize; + PULONG ExportTable; + PAGED_CODE(); + + /* Get the export directory */ + ExportDirectory = RtlImageDirectoryEntryToData(DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ExportSize); + if (!ExportDirectory) return NULL; + + /* Setup name tables */ + NameTable = (PULONG)((ULONG_PTR)DllBase + + ExportDirectory->AddressOfNames); + OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase + + ExportDirectory->AddressOfNameOrdinals); + + /* Do a binary search */ + High = ExportDirectory->NumberOfNames - 1; + while (High >= Low) + { + /* Get new middle value */ + Mid = (Low + High) >> 1; + + /* Compare name */ + Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]); + if (Ret < 0) + { + /* Update high */ + High = Mid - 1; + } + else if (Ret > 0) + { + /* Update low */ + Low = Mid + 1; + } + else + { + /* We got it */ + break; + } + } + + /* Check if we couldn't find it */ + if (High < Low) return NULL; + + /* Otherwise, this is the ordinal */ + Ordinal = OrdinalTable[Mid]; + + /* Resolve the address and write it */ + ExportTable = (PULONG)((ULONG_PTR)DllBase + + ExportDirectory->AddressOfFunctions); + Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]); + + /* We found it! */ + ASSERT((Function > (PVOID)ExportDirectory) && + (Function < (PVOID)((ULONG_PTR)ExportDirectory + ExportSize))); + return Function; +} + PVOID NTAPI MiLocateExportName(IN PVOID DllBase, @@ -1712,3 +1783,77 @@ Quickie: return Status; } +/* + * @implemented + */ +PVOID +NTAPI +MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName) +{ + PVOID ProcAddress = NULL; + 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"); + ULONG Modules = 0; + + /* Convert routine to ansi name */ + Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName, + SystemRoutineName, + TRUE); + if (!NT_SUCCESS(Status)) return NULL; + + /* Lock the list */ + KeEnterCriticalRegion(); + + /* 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; + Modules++; + } + else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE)) + { + /* Found it */ + Found = TRUE; + Modules++; + } + + /* Check if we found a valid binary */ + if (Found) + { + /* Find the procedure name */ + ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase, + &AnsiRoutineName); + + /* Break out if we found it or if we already tried both modules */ + if (ProcAddress) break; + if (Modules == 2) break; + } + + /* Keep looping */ + NextEntry = NextEntry->Flink; + } + + /* Release the lock */ + KeLeaveCriticalRegion(); + + /* Free the string and return */ + RtlFreeAnsiString(&AnsiRoutineName); + return ProcAddress; +} + diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 60891077471..fa8309aca10 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -227,10 +227,6 @@ kdio.c kdmain.c - - loader.c - rtl.c - close.c complete.c diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index 7567844784a..50c8ac6ef81 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -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 -PspLookupSystemDllEntryPoint(IN PANSI_STRING Name, +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 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 */