Implemented handling of forwarded exports

svn path=/trunk/; revision=1610
This commit is contained in:
Eric Kohl 2001-02-10 10:04:39 +00:00
parent c87bd2d365
commit 41280eeeb5

View file

@ -1,4 +1,4 @@
/* $Id: utils.c,v 1.38 2001/02/06 05:50:50 dwelch Exp $ /* $Id: utils.c,v 1.39 2001/02/10 10:04:39 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -45,9 +45,9 @@ STDCALL
LPVOID lpReserved LPVOID lpReserved
); );
static static NTSTATUS LdrFindDll(PLDR_MODULE *Dll,PUNICODE_STRING Name);
NTSTATUS static PVOID LdrFixupForward(PCHAR ForwardName);
LdrFindDll (PLDR_MODULE *Dll,PUNICODE_STRING Name); static PVOID LdrGetExportByName(PVOID BaseAddress, PUCHAR SymbolName, USHORT Hint);
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -571,6 +571,66 @@ NTSTATUS LdrMapSections(HANDLE ProcessHandle,
} }
/**********************************************************************
* NAME LOCAL
* LdrFixupForward
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
* NOTE
*
*/
static PVOID
LdrFixupForward(PCHAR ForwardName)
{
CHAR NameBuffer[128];
UNICODE_STRING DllName;
UNICODE_STRING FunctionName;
NTSTATUS Status;
PCHAR p;
PVOID BaseAddress;
strcpy(NameBuffer, ForwardName);
p = strchr(NameBuffer, '.');
if (p != NULL)
{
*p = 0;
DPRINT("Dll: %s Function: %s\n", NameBuffer, p+1);
RtlCreateUnicodeStringFromAsciiz (&DllName,
NameBuffer);
Status = LdrGetDllHandle (0, 0, &DllName, &BaseAddress);
if (!NT_SUCCESS(Status))
{
Status = LdrLoadDll(NULL,
0,
&DllName,
&BaseAddress);
RtlFreeUnicodeString (&DllName);
if (!NT_SUCCESS(Status))
{
DbgPrint("LdrFixupForward: failed to load %wZ\n", &DllName);
return NULL;
}
}
RtlFreeUnicodeString (&DllName);
DPRINT("BaseAddress: %p\n", BaseAddress);
return LdrGetExportByName(BaseAddress, p+1, -1);
}
return NULL;
}
/********************************************************************** /**********************************************************************
* NAME LOCAL * NAME LOCAL
* LdrGetExportByOrdinal * LdrGetExportByOrdinal
@ -638,89 +698,119 @@ LdrGetExportByOrdinal (
* *
*/ */
static PVOID static PVOID
LdrGetExportByName (PVOID BaseAddress, PUCHAR SymbolName, WORD Hint) LdrGetExportByName(PVOID BaseAddress,
PUCHAR SymbolName,
WORD Hint)
{ {
PIMAGE_EXPORT_DIRECTORY ExportDir; PIMAGE_EXPORT_DIRECTORY ExportDir;
PDWORD * ExFunctions; PDWORD * ExFunctions;
PDWORD * ExNames; PDWORD * ExNames;
USHORT * ExOrdinals; USHORT * ExOrdinals;
ULONG i; ULONG i;
PVOID ExName; PVOID ExName;
ULONG Ordinal; ULONG Ordinal;
ULONG minn, maxn; PVOID Function;
ULONG minn, maxn;
ULONG ExportDirSize;
ExportDir = (PIMAGE_EXPORT_DIRECTORY) DPRINT("LdrGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
RtlImageDirectoryEntryToData (BaseAddress,
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(BaseAddress,
TRUE, TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT, IMAGE_DIRECTORY_ENTRY_EXPORT,
NULL); &ExportDirSize);
/* /*
* Get header pointers * Get header pointers
*/ */
ExNames = (PDWORD *)RVA(BaseAddress, ExNames = (PDWORD *)RVA(BaseAddress,
ExportDir->AddressOfNames); ExportDir->AddressOfNames);
ExOrdinals = (USHORT *)RVA(BaseAddress, ExOrdinals = (USHORT *)RVA(BaseAddress,
ExportDir->AddressOfNameOrdinals); ExportDir->AddressOfNameOrdinals);
ExFunctions = (PDWORD *)RVA(BaseAddress, ExFunctions = (PDWORD *)RVA(BaseAddress,
ExportDir->AddressOfFunctions); ExportDir->AddressOfFunctions);
/* /*
* Check the hint first * Check the hint first
*/ */
if (Hint < ExportDir->NumberOfFunctions) if (Hint < ExportDir->NumberOfFunctions)
{ {
ExName = RVA(BaseAddress, ExNames[Hint]); ExName = RVA(BaseAddress, ExNames[Hint]);
if (strcmp(ExName, SymbolName) == 0) if (strcmp(ExName, SymbolName) == 0)
{ {
Ordinal = ExOrdinals[Hint]; Ordinal = ExOrdinals[Hint];
return(RVA(BaseAddress, ExFunctions[Ordinal])); Function = RVA(BaseAddress, ExFunctions[Ordinal]);
} if (((ULONG)Function >= (ULONG)ExportDir) &&
} ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
}
if (Function != NULL)
return Function;
}
}
/* /*
* Try a binary search first * Try a binary search first
*/ */
minn = 0, maxn = ExportDir->NumberOfFunctions; minn = 0, maxn = ExportDir->NumberOfFunctions;
while (minn <= maxn) while (minn <= maxn)
{ {
ULONG mid; ULONG mid;
LONG res; LONG res;
mid = (minn + maxn) / 2; mid = (minn + maxn) / 2;
ExName = RVA(BaseAddress, ExNames[mid]); ExName = RVA(BaseAddress, ExNames[mid]);
res = strcmp(ExName, SymbolName); res = strcmp(ExName, SymbolName);
if (res == 0) if (res == 0)
{ {
Ordinal = ExOrdinals[mid]; Ordinal = ExOrdinals[mid];
return(RVA(BaseAddress, ExFunctions[Ordinal])); Function = RVA(BaseAddress, ExFunctions[Ordinal]);
} if (((ULONG)Function >= (ULONG)ExportDir) &&
else if (res > 0) ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
{ {
maxn = mid - 1; DPRINT("Forward: %s\n", (PCHAR)Function);
} Function = LdrFixupForward((PCHAR)Function);
else }
{ if (Function != NULL)
minn = mid + 1; return Function;
} }
} else if (res > 0)
/* {
* Fall back on a linear search maxn = mid - 1;
*/ }
else
{
minn = mid + 1;
}
}
/*
* Fall back on a linear search
*/
DbgPrint("LDR: Falling back on a linear search of export table\n"); DbgPrint("LDR: Falling back on a linear search of export table\n");
for (i = 0; i < ExportDir->NumberOfFunctions; i++) for (i = 0; i < ExportDir->NumberOfFunctions; i++)
{ {
ExName = RVA(BaseAddress, ExNames[i]); ExName = RVA(BaseAddress, ExNames[i]);
if (strcmp(ExName,SymbolName) == 0) if (strcmp(ExName,SymbolName) == 0)
{ {
Ordinal = ExOrdinals[i]; Ordinal = ExOrdinals[i];
return(RVA(BaseAddress, ExFunctions[Ordinal])); Function = RVA(BaseAddress, ExFunctions[Ordinal]);
} DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize);
} if (((ULONG)Function >= (ULONG)ExportDir) &&
DbgPrint("LdrGetExportByName() = failed to find %s\n",SymbolName); ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
return NULL; {
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
}
return Function;
}
}
DbgPrint("LdrGetExportByName() = failed to find %s\n",SymbolName);
return NULL;
} }
@ -1474,9 +1564,8 @@ LdrGetDllHandle (IN ULONG Unknown1,
{ {
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
DPRINT("EntryPoint %lu\n", Module->EntryPoint); DPRINT("EntryPoint %x\n", Module->EntryPoint);
DPRINT("Comparing %wZ and %wZ\n",
DPRINT("Scanning %wZ %wZ\n",
&Module->BaseDllName, &Module->BaseDllName,
&FullDllName); &FullDllName);