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 ...@@ -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_named_export
* *
* Find an exported function by name. * Find an exported function by name.
...@@ -734,10 +757,10 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY * ...@@ -734,10 +757,10 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *
{ {
const WORD *ordinals = get_rva( module, exports->AddressOfNameOrdinals ); const WORD *ordinals = get_rva( module, exports->AddressOfNameOrdinals );
const DWORD *names = get_rva( module, exports->AddressOfNames ); const DWORD *names = get_rva( module, exports->AddressOfNames );
int min = 0, max = exports->NumberOfNames - 1; int ordinal;
/* first check the hint */ /* first check the hint */
if (hint >= 0 && hint <= max) if (hint >= 0 && hint < exports->NumberOfNames)
{ {
char *ename = get_rva( module, names[hint] ); char *ename = get_rva( module, names[hint] );
if (!strcmp( ename, name )) if (!strcmp( ename, name ))
...@@ -745,17 +768,30 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY * ...@@ -745,17 +768,30 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *
} }
/* then do a binary search */ /* then do a binary search */
while (min <= max) if ((ordinal = find_name_in_exports( module, exports, name )) == -1) return NULL;
{ return find_ordinal_export( module, exports, exp_size, ordinal, load_path );
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; * RtlFindExportedRoutineByName
} */
return NULL; 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 ) ...@@ -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 ) static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void **entry )
{ {
IMAGE_EXPORT_DIRECTORY *exports;
DWORD exp_size;
NTSTATUS status; NTSTATUS status;
void *proc = NULL; void *proc;
const char *name;
WINE_MODREF *prev, *imp; WINE_MODREF *prev, *imp;
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */ 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 * ...@@ -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) ); TRACE( "loaded mscoree for %s\n", debugstr_w(wm->ldr.FullDllName.Buffer) );
if ((exports = RtlImageDirectoryEntryToData( imp->ldr.DllBase, TRUE, name = (wm->ldr.Flags & LDR_IMAGE_IS_DLL) ? "_CorDllMain" : "_CorExeMain";
IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size ))) if (!(proc = RtlFindExportedRoutineByName( imp->ldr.DllBase, name ))) return STATUS_PROCEDURE_NOT_FOUND;
{
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;
*entry = proc; *entry = proc;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
......
...@@ -653,6 +653,7 @@ ...@@ -653,6 +653,7 @@
@ stdcall RtlFindClearBits(ptr long long) @ stdcall RtlFindClearBits(ptr long long)
@ stdcall RtlFindClearBitsAndSet(ptr long long) @ stdcall RtlFindClearBitsAndSet(ptr long long)
@ stdcall RtlFindClearRuns(ptr ptr long long) @ stdcall RtlFindClearRuns(ptr ptr long long)
@ stdcall RtlFindExportedRoutineByName(ptr str)
@ stdcall RtlFindLastBackwardRunClear(ptr long ptr) @ stdcall RtlFindLastBackwardRunClear(ptr long ptr)
@ stdcall RtlFindLastBackwardRunSet(ptr long ptr) @ stdcall RtlFindLastBackwardRunSet(ptr long ptr)
@ stdcall RtlFindLeastSignificantBit(int64) @ stdcall RtlFindLeastSignificantBit(int64)
......
...@@ -33,6 +33,7 @@ static DWORD64 (WINAPI *pGetEnabledXStateFeatures)(void); ...@@ -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 NTSTATUS (WINAPI *pRtlCreateUserStack)(SIZE_T, SIZE_T, ULONG, SIZE_T, SIZE_T, INITIAL_TEB *);
static ULONG64 (WINAPI *pRtlGetEnabledExtendedFeatures)(ULONG64); static ULONG64 (WINAPI *pRtlGetEnabledExtendedFeatures)(ULONG64);
static NTSTATUS (WINAPI *pRtlFreeUserStack)(void *); static NTSTATUS (WINAPI *pRtlFreeUserStack)(void *);
static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char*);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static NTSTATUS (WINAPI *pNtAllocateVirtualMemoryEx)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG, static NTSTATUS (WINAPI *pNtAllocateVirtualMemoryEx)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG,
MEM_EXTENDED_PARAMETER *, ULONG); MEM_EXTENDED_PARAMETER *, ULONG);
...@@ -996,6 +997,16 @@ static void test_syscalls(void) ...@@ -996,6 +997,16 @@ static void test_syscalls(void)
} }
perform_relocations( ptr, delta ); perform_relocations( ptr, delta );
pNtClose = (void *)GetProcAddress( module, "NtClose" ); 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 )) if (!memcmp( pNtClose, (char *)pNtClose + delta, 32 ))
{ {
pNtClose = (void *)((char *)pNtClose + delta); pNtClose = (void *)((char *)pNtClose + delta);
...@@ -1041,6 +1052,7 @@ START_TEST(virtual) ...@@ -1041,6 +1052,7 @@ START_TEST(virtual)
mod = GetModuleHandleA("ntdll.dll"); mod = GetModuleHandleA("ntdll.dll");
pRtlCreateUserStack = (void *)GetProcAddress(mod, "RtlCreateUserStack"); pRtlCreateUserStack = (void *)GetProcAddress(mod, "RtlCreateUserStack");
pRtlFreeUserStack = (void *)GetProcAddress(mod, "RtlFreeUserStack"); pRtlFreeUserStack = (void *)GetProcAddress(mod, "RtlFreeUserStack");
pRtlFindExportedRoutineByName = (void *)GetProcAddress(mod, "RtlFindExportedRoutineByName");
pRtlGetEnabledExtendedFeatures = (void *)GetProcAddress(mod, "RtlGetEnabledExtendedFeatures"); pRtlGetEnabledExtendedFeatures = (void *)GetProcAddress(mod, "RtlGetEnabledExtendedFeatures");
pNtAllocateVirtualMemoryEx = (void *)GetProcAddress(mod, "NtAllocateVirtualMemoryEx"); pNtAllocateVirtualMemoryEx = (void *)GetProcAddress(mod, "NtAllocateVirtualMemoryEx");
......
...@@ -4013,6 +4013,7 @@ NTSYSAPI NTSTATUS WINAPI RtlFindCharInUnicodeString(int,const UNICODE_STRING*,c ...@@ -4013,6 +4013,7 @@ NTSYSAPI NTSTATUS WINAPI RtlFindCharInUnicodeString(int,const UNICODE_STRING*,c
NTSYSAPI ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP,ULONG,ULONG); NTSYSAPI ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP,ULONG,ULONG);
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP,ULONG,ULONG); NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP,ULONG,ULONG);
NTSYSAPI ULONG WINAPI RtlFindClearRuns(PCRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN); 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 RtlFindLastBackwardRunSet(PCRTL_BITMAP,ULONG,PULONG);
NTSYSAPI ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP,ULONG,PULONG); NTSYSAPI ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP,ULONG,PULONG);
NTSYSAPI CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG); 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