diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 4efae795e5b..f572b339453 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -62,10 +62,9 @@ NTSTATUS WINAPI LdrGetProcedureAddress(PVOID base, PANSI_STRING name, ULONG ord, WARN("%p %s %ld %p\n",base, debugstr_an(name->Buffer,name->Length), ord, address); if(name) - *address = MODULE_GetProcAddress( (HMODULE) base, name->Buffer, FALSE); + *address = MODULE_GetProcAddress( (HMODULE) base, name->Buffer, -1, FALSE); else - *address = MODULE_GetProcAddress( (HMODULE) base, (LPSTR) ord, FALSE); + *address = MODULE_GetProcAddress( (HMODULE) base, (LPSTR) ord, -1, FALSE); return (*address) ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND; } - diff --git a/include/module.h b/include/module.h index bd7da2d41be..d1d5ccd3fbc 100644 --- a/include/module.h +++ b/include/module.h @@ -134,7 +134,8 @@ typedef struct _wine_modref void *dlhandle; /* handle returned by dlopen() */ int tlsindex; /* TLS index or -1 if none */ - FARPROC (*find_export)( struct _wine_modref *wm, LPCSTR func, BOOL snoop ); + FARPROC (*find_export)( struct _wine_modref *wm, LPCSTR func, + int hint, BOOL snoop ); int nDeps; struct _wine_modref **deps; @@ -201,7 +202,7 @@ enum binary_type /* module.c */ extern WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename ); -extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, BOOL snoop ); +extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, int hint, BOOL snoop ); extern BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved ); extern void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved ); extern void MODULE_DllThreadAttach( LPVOID lpReserved ); diff --git a/loader/elf.c b/loader/elf.c index c861908bd90..e833cd0dddb 100644 --- a/loader/elf.c +++ b/loader/elf.c @@ -61,7 +61,7 @@ typedef struct { sizeof(IMAGE_NT_HEADERS) + \ sizeof(IMAGE_SECTION_HEADER)) -static FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName, BOOL snoop ); +static FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName, int hint, BOOL snoop ); static HMODULE ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname ) { @@ -181,7 +181,7 @@ WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags) return wm; } -static FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName, BOOL snoop ) +static FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName, int hint, BOOL snoop ) { LPVOID fun; int i,nrofargs = 0; diff --git a/loader/module.c b/loader/module.c index 562b1a2a3ba..6cd398e8160 100644 --- a/loader/module.c +++ b/loader/module.c @@ -1624,7 +1624,7 @@ FARPROC16 WINAPI GetProcAddress16( HMODULE16 hModule, LPCSTR name ) */ FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function ) { - return MODULE_GetProcAddress( hModule, function, TRUE ); + return MODULE_GetProcAddress( hModule, function, -1, TRUE ); } /*********************************************************************** @@ -1632,7 +1632,7 @@ FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function ) */ FARPROC WINAPI GetProcAddress32_16( HMODULE hModule, LPCSTR function ) { - return MODULE_GetProcAddress( hModule, function, FALSE ); + return MODULE_GetProcAddress( hModule, function, -1, FALSE ); } /*********************************************************************** @@ -1641,20 +1641,21 @@ FARPROC WINAPI GetProcAddress32_16( HMODULE hModule, LPCSTR function ) FARPROC MODULE_GetProcAddress( HMODULE hModule, /* [in] current module handle */ LPCSTR function, /* [in] function to be looked up */ + int hint, BOOL snoop ) { WINE_MODREF *wm; FARPROC retproc = 0; if (HIWORD(function)) - TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function); + TRACE_(win32)("(%08lx,%s (%d))\n",(DWORD)hModule,function,hint); else TRACE_(win32)("(%08lx,%p)\n",(DWORD)hModule,function); RtlEnterCriticalSection( &loader_section ); if ((wm = MODULE32_LookupHMODULE( hModule ))) { - retproc = wm->find_export( wm, function, snoop ); + retproc = wm->find_export( wm, function, hint, snoop ); if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); } RtlLeaveCriticalSection( &loader_section ); diff --git a/loader/pe_image.c b/loader/pe_image.c index 4c387d55c72..1974ac58ed7 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -134,6 +134,7 @@ void dump_exports( HMODULE hModule ) static FARPROC PE_FindExportedFunction( WINE_MODREF *wm, /* [in] WINE modreference */ LPCSTR funcName, /* [in] function name */ + int hint, BOOL snoop ) { WORD * ordinals; @@ -168,8 +169,20 @@ static FARPROC PE_FindExportedFunction( if (HIWORD(funcName)) { - /* first try a binary search */ int min = 0, max = exports->NumberOfNames - 1; + + /* first check the hint */ + if (hint >= 0 && hint <= max) + { + ename = RVA(name[hint]); + if (!strcmp( ename, funcName )) + { + ordinal = ordinals[hint]; + goto found; + } + } + + /* then do a binary search */ while (min <= max) { int res, pos = (min + max) / 2; @@ -182,17 +195,6 @@ static FARPROC PE_FindExportedFunction( if (res > 0) max = pos - 1; else min = pos + 1; } - /* now try a linear search in case the names aren't sorted properly */ - for (i = 0; i < exports->NumberOfNames; i++) - { - ename = RVA(name[i]); - if (!strcmp( ename, funcName )) - { - ERR( "%s.%s required a linear search\n", wm->modname, funcName ); - ordinal = ordinals[i]; - goto found; - } - } return NULL; } else /* find by ordinal */ @@ -244,7 +246,7 @@ static FARPROC PE_FindExportedFunction( ERR("module not found for forward '%s' used by '%s'\n", forward, wm->modname ); return NULL; } - if (!(proc = MODULE_GetProcAddress( wm_fw->module, end + 1, snoop ))) + if (!(proc = MODULE_GetProcAddress( wm_fw->module, end + 1, -1, snoop ))) ERR("function not found for forward '%s' used by '%s'. If you are using builtin '%s', try using the native one instead.\n", forward, wm->modname, wm->modname ); return proc; } @@ -317,7 +319,7 @@ DWORD PE_fixup_imports( WINE_MODREF *wm ) TRACE("--- Ordinal %s,%d\n", name, ordinal); thunk_list->u1.Function=(PDWORD)MODULE_GetProcAddress( - wmImp->module, (LPCSTR)ordinal, TRUE + wmImp->module, (LPCSTR)ordinal, -1, TRUE ); if (!thunk_list->u1.Function) { ERR("No implementation for %s.%d imported from %s, setting to 0xdeadbeef\n", @@ -328,7 +330,7 @@ DWORD PE_fixup_imports( WINE_MODREF *wm ) pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData); TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint); thunk_list->u1.Function=(PDWORD)MODULE_GetProcAddress( - wmImp->module, pe_name->Name, TRUE + wmImp->module, pe_name->Name, pe_name->Hint, TRUE ); if (!thunk_list->u1.Function) { ERR("No implementation for %s.%d(%s) imported from %s, setting to 0xdeadbeef\n", @@ -349,7 +351,7 @@ DWORD PE_fixup_imports( WINE_MODREF *wm ) TRACE("--- Ordinal %s.%d\n",name,ordinal); thunk_list->u1.Function=(PDWORD)MODULE_GetProcAddress( - wmImp->module, (LPCSTR) ordinal, TRUE + wmImp->module, (LPCSTR) ordinal, -1, TRUE ); if (!thunk_list->u1.Function) { ERR("No implementation for %s.%d imported from %s, setting to 0xdeadbeef\n", @@ -361,7 +363,7 @@ DWORD PE_fixup_imports( WINE_MODREF *wm ) TRACE("--- %s %s.%d\n", pe_name->Name,name,pe_name->Hint); thunk_list->u1.Function=(PDWORD)MODULE_GetProcAddress( - wmImp->module, pe_name->Name, TRUE + wmImp->module, pe_name->Name, pe_name->Hint, TRUE ); if (!thunk_list->u1.Function) { ERR("No implementation for %s.%d(%s) imported from %s, setting to 0xdeadbeef\n",