Commit 87b7132b authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Implement RtlFindExportedRoutineByName().

parent 12f3e27b
......@@ -724,6 +724,29 @@ static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY
/*************************************************************************
* find_name_in_exports
*
* Helper for find_named_export.
*/
static int find_name_in_exports( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports, const char *name )
{
const WORD *ordinals = get_rva( module, exports->AddressOfNameOrdinals );
const DWORD *names = get_rva( module, exports->AddressOfNames );
int min = 0, max = exports->NumberOfNames - 1;
while (min <= max)
{
int res, pos = (min + max) / 2;
char *ename = get_rva( module, names[pos] );
if (!(res = strcmp( ename, name ))) return ordinals[pos];
if (res > 0) max = pos - 1;
else min = pos + 1;
}
return -1;
}
/*************************************************************************
* find_named_export
*
* Find an exported function by name.
......@@ -734,10 +757,10 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *
{
const WORD *ordinals = get_rva( module, exports->AddressOfNameOrdinals );
const DWORD *names = get_rva( module, exports->AddressOfNames );
int min = 0, max = exports->NumberOfNames - 1;
int ordinal;
/* first check the hint */
if (hint >= 0 && hint <= max)
if (hint >= 0 && hint < exports->NumberOfNames)
{
char *ename = get_rva( module, names[hint] );
if (!strcmp( ename, name ))
......@@ -745,17 +768,30 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *
}
/* then do a binary search */
while (min <= max)
{
int res, pos = (min + max) / 2;
char *ename = get_rva( module, names[pos] );
if (!(res = strcmp( ename, name )))
return find_ordinal_export( module, exports, exp_size, ordinals[pos], load_path );
if (res > 0) max = pos - 1;
else min = pos + 1;
}
return NULL;
if ((ordinal = find_name_in_exports( module, exports, name )) == -1) return NULL;
return find_ordinal_export( module, exports, exp_size, ordinal, load_path );
}
/*************************************************************************
* RtlFindExportedRoutineByName
*/
void * WINAPI RtlFindExportedRoutineByName( HMODULE module, const char *name )
{
const IMAGE_EXPORT_DIRECTORY *exports;
const DWORD *functions;
DWORD exp_size;
int ordinal;
exports = RtlImageDirectoryEntryToData( module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size );
if (!exports || exp_size < sizeof(*exports)) return NULL;
if ((ordinal = find_name_in_exports( module, exports, name )) == -1) return NULL;
if (ordinal >= exports->NumberOfFunctions) return NULL;
functions = get_rva( module, exports->AddressOfFunctions );
if (!functions[ordinal]) return NULL;
return get_rva( module, functions[ordinal] );
}
......@@ -1076,10 +1112,9 @@ static void free_tls_slot( LDR_DATA_TABLE_ENTRY *mod )
*/
static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void **entry )
{
IMAGE_EXPORT_DIRECTORY *exports;
DWORD exp_size;
NTSTATUS status;
void *proc = NULL;
void *proc;
const char *name;
WINE_MODREF *prev, *imp;
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */
......@@ -1101,13 +1136,8 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void *
TRACE( "loaded mscoree for %s\n", debugstr_w(wm->ldr.FullDllName.Buffer) );
if ((exports = RtlImageDirectoryEntryToData( imp->ldr.DllBase, TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size )))
{
const char *name = (wm->ldr.Flags & LDR_IMAGE_IS_DLL) ? "_CorDllMain" : "_CorExeMain";
proc = find_named_export( imp->ldr.DllBase, exports, exp_size, name, -1, load_path );
}
if (!proc) return STATUS_PROCEDURE_NOT_FOUND;
name = (wm->ldr.Flags & LDR_IMAGE_IS_DLL) ? "_CorDllMain" : "_CorExeMain";
if (!(proc = RtlFindExportedRoutineByName( imp->ldr.DllBase, name ))) return STATUS_PROCEDURE_NOT_FOUND;
*entry = proc;
return STATUS_SUCCESS;
}
......
......@@ -653,6 +653,7 @@
@ stdcall RtlFindClearBits(ptr long long)
@ stdcall RtlFindClearBitsAndSet(ptr long long)
@ stdcall RtlFindClearRuns(ptr ptr long long)
@ stdcall RtlFindExportedRoutineByName(ptr str)
@ stdcall RtlFindLastBackwardRunClear(ptr long ptr)
@ stdcall RtlFindLastBackwardRunSet(ptr long ptr)
@ stdcall RtlFindLeastSignificantBit(int64)
......
......@@ -33,6 +33,7 @@ static DWORD64 (WINAPI *pGetEnabledXStateFeatures)(void);
static NTSTATUS (WINAPI *pRtlCreateUserStack)(SIZE_T, SIZE_T, ULONG, SIZE_T, SIZE_T, INITIAL_TEB *);
static ULONG64 (WINAPI *pRtlGetEnabledExtendedFeatures)(ULONG64);
static NTSTATUS (WINAPI *pRtlFreeUserStack)(void *);
static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char*);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static NTSTATUS (WINAPI *pNtAllocateVirtualMemoryEx)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG,
MEM_EXTENDED_PARAMETER *, ULONG);
......@@ -996,6 +997,16 @@ static void test_syscalls(void)
}
perform_relocations( ptr, delta );
pNtClose = (void *)GetProcAddress( module, "NtClose" );
if (pRtlFindExportedRoutineByName)
{
void *func = pRtlFindExportedRoutineByName( module, "NtClose" );
ok( func == (void *)pNtClose, "wrong ptr %p / %p\n", func, pNtClose );
func = pRtlFindExportedRoutineByName( ptr, "NtClose" );
ok( (char *)func - (char *)pNtClose == delta, "wrong ptr %p / %p\n", func, pNtClose );
}
else win_skip( "RtlFindExportedRoutineByName not supported\n" );
if (!memcmp( pNtClose, (char *)pNtClose + delta, 32 ))
{
pNtClose = (void *)((char *)pNtClose + delta);
......@@ -1041,6 +1052,7 @@ START_TEST(virtual)
mod = GetModuleHandleA("ntdll.dll");
pRtlCreateUserStack = (void *)GetProcAddress(mod, "RtlCreateUserStack");
pRtlFreeUserStack = (void *)GetProcAddress(mod, "RtlFreeUserStack");
pRtlFindExportedRoutineByName = (void *)GetProcAddress(mod, "RtlFindExportedRoutineByName");
pRtlGetEnabledExtendedFeatures = (void *)GetProcAddress(mod, "RtlGetEnabledExtendedFeatures");
pNtAllocateVirtualMemoryEx = (void *)GetProcAddress(mod, "NtAllocateVirtualMemoryEx");
......
......@@ -4013,6 +4013,7 @@ NTSYSAPI NTSTATUS WINAPI RtlFindCharInUnicodeString(int,const UNICODE_STRING*,c
NTSYSAPI ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP,ULONG,ULONG);
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP,ULONG,ULONG);
NTSYSAPI ULONG WINAPI RtlFindClearRuns(PCRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN);
NTSYSAPI void * WINAPI RtlFindExportedRoutineByName(HMODULE,const char*);
NTSYSAPI ULONG WINAPI RtlFindLastBackwardRunSet(PCRTL_BITMAP,ULONG,PULONG);
NTSYSAPI ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP,ULONG,PULONG);
NTSYSAPI CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment