From f3a73ef7afdab3408a15ccab68a20ca4b9c7c207 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Thu, 6 Mar 2003 23:41:37 +0000 Subject: [PATCH] - implemented LdrGetProcedureAddress and made use of it for GetProcAddress - implemented LdrGetDllHandle and made use of it in GetModuleHandle - removed MODULE_DllThreadDetach from loader/module.c (should have been removed in a previous patch) --- dlls/ntdll/loader.c | 111 +++++++++++++++++++++++++++----- dlls/ntdll/ntdll_misc.h | 3 + include/module.h | 4 +- loader/module.c | 164 +++++++++++++++++------------------------------- loader/pe_image.c | 1 + 5 files changed, 159 insertions(+), 124 deletions(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index c1bcfc35580..d72db1d0bf6 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -21,6 +21,7 @@ #include "winternl.h" #include "module.h" +#include "file.h" #include "wine/exception.h" #include "excpt.h" #include "wine/debug.h" @@ -58,36 +59,118 @@ NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE hModule) return ret; } -/* FIXME : MODULE_FindModule should depend on LdrGetDllHandle, not vice-versa */ +/********************************************************************** + * MODULE_FindModule + * + * Find a (loaded) win32 module depending on path + * LPCSTR path: [in] pathname of module/library to be found + * + * The loader_section must be locked while calling this function + * RETURNS + * the module handle if found + * 0 if not + */ +WINE_MODREF *MODULE_FindModule(LPCSTR path) +{ + WINE_MODREF *wm; + char dllname[260], *p; + + /* Append .DLL to name if no extension present */ + strcpy( dllname, path ); + if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\')) + strcat( dllname, ".DLL" ); + + for ( wm = MODULE_modref_list; wm; wm = wm->next ) + { + if ( !FILE_strcasecmp( dllname, wm->modname ) ) + break; + if ( !FILE_strcasecmp( dllname, wm->filename ) ) + break; + if ( !FILE_strcasecmp( dllname, wm->short_modname ) ) + break; + if ( !FILE_strcasecmp( dllname, wm->short_filename ) ) + break; + } + + return wm; +} +/****************************************************************** + * LdrGetDllHandle (NTDLL.@) + * + * + */ NTSTATUS WINAPI LdrGetDllHandle(ULONG x, ULONG y, PUNICODE_STRING name, HMODULE *base) { - STRING str; WINE_MODREF *wm; - FIXME("%08lx %08lx %s %p : partial stub\n",x,y,debugstr_wn(name->Buffer,name->Length),base); + TRACE("%08lx %08lx %s %p\n", + x, y, name ? debugstr_wn(name->Buffer, name->Length) : NULL, base); - *base = 0; + if (x != 0 || y != 0) + FIXME("Unknown behavior, please report\n"); + + /* FIXME: we should store module name information as unicode */ + if (name) + { + STRING str; + + RtlUnicodeStringToAnsiString( &str, name, TRUE ); + + wm = MODULE_FindModule( str.Buffer ); + RtlFreeAnsiString( &str ); + } + else + wm = exe_modref; - RtlUnicodeStringToAnsiString(&str, name, TRUE); - wm = MODULE_FindModule(str.Buffer); - if(!wm) + if (!wm) + { + *base = 0; return STATUS_DLL_NOT_FOUND; - *base = (PVOID) wm->module; + } + *base = wm->module; return STATUS_SUCCESS; } -/* FIXME : MODULE_GetProcAddress should depend on LdrGetProcedureAddress, not vice-versa */ +/*********************************************************************** + * MODULE_GetProcAddress (internal) + */ +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("(%p,%s (%d))\n",hModule,function,hint); + else + TRACE("(%p,%p)\n",hModule,function); + + RtlEnterCriticalSection( &loader_section ); + if ((wm = MODULE32_LookupHMODULE( hModule ))) + { + retproc = wm->find_export( wm, function, hint, snoop ); + if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); + } + RtlLeaveCriticalSection( &loader_section ); + return retproc; +} + +/****************************************************************** + * LdrGetProcedureAddress (NTDLL.@) + * + * + */ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE base, PANSI_STRING name, ULONG ord, PVOID *address) { - WARN("%p %s %ld %p\n", base, debugstr_an(name->Buffer,name->Length), ord, address); + WARN("%p %s %ld %p\n", base, name ? debugstr_an(name->Buffer, name->Length) : NULL, ord, address); - if(name) - *address = MODULE_GetProcAddress( base, name->Buffer, -1, FALSE); - else - *address = MODULE_GetProcAddress( base, (LPSTR) ord, -1, FALSE); + *address = MODULE_GetProcAddress( base, name ? name->Buffer : (LPSTR)ord, -1, TRUE ); return (*address) ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND; } diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index ae37e6fe987..618001ecad4 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -26,4 +26,7 @@ extern LPCSTR debugstr_us( const UNICODE_STRING *str ); extern void dump_ObjectAttributes (const OBJECT_ATTRIBUTES *ObjectAttributes); +/* module handling */ +extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, int hint, BOOL snoop ); + #endif diff --git a/include/module.h b/include/module.h index ef3cdba469a..b8688fe8b20 100644 --- a/include/module.h +++ b/include/module.h @@ -209,6 +209,7 @@ extern void MODULE_WalkModref( DWORD id ); /* the following parts of module.c are temporary exported during move of code * from loader/module.c to dlls/ntdll/loader.c */ +extern WINE_MODREF *exe_modref; extern CRITICAL_SECTION loader_section; extern int process_detaching; extern BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ); @@ -268,9 +269,6 @@ extern BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *f extern void MODULE_GetLoadOrder( enum loadorder_type plo[], const char *path, BOOL win32 ); extern void MODULE_AddLoadOrderOption( const char *option ); -/* loader/elf.c */ -extern WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags); - /* relay32/builtin.c */ extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags); extern HMODULE BUILTIN32_LoadExeModule( HMODULE main ); diff --git a/loader/module.c b/loader/module.c index a74bfb86fa8..a27d5cc31f8 100644 --- a/loader/module.c +++ b/loader/module.c @@ -47,7 +47,7 @@ WINE_DECLARE_DEBUG_CHANNEL(loaddll); WINE_MODREF *MODULE_modref_list = NULL; -static WINE_MODREF *exe_modref; +WINE_MODREF *exe_modref; static int free_lib_count; /* recursion depth of FreeLibrary calls */ int process_detaching = 0; /* set on process detach to avoid deadlocks with thread detach */ @@ -325,36 +325,6 @@ void MODULE_DllThreadAttach( LPVOID lpReserved ) RtlLeaveCriticalSection( &loader_section ); } -/************************************************************************* - * MODULE_DllThreadDetach - * - * Send DLL thread detach notifications. These are sent in the - * same sequence as process detach notification. - * - */ -void MODULE_DllThreadDetach( LPVOID lpReserved ) -{ - WINE_MODREF *wm; - - /* don't do any detach calls if process is exiting */ - if (process_detaching) return; - /* FIXME: there is still a race here */ - - RtlEnterCriticalSection( &loader_section ); - - for ( wm = MODULE_modref_list; wm; wm = wm->next ) - { - if ( !(wm->flags & WINE_MODREF_PROCESS_ATTACHED) ) - continue; - if ( wm->flags & WINE_MODREF_NO_DLL_CALLS ) - continue; - - MODULE_InitDLL( wm, DLL_THREAD_DETACH, lpReserved ); - } - - RtlLeaveCriticalSection( &loader_section ); -} - /**************************************************************************** * DisableThreadLibraryCalls (KERNEL32.@) * @@ -475,42 +445,6 @@ HMODULE16 MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 ) } -/********************************************************************** - * MODULE_FindModule - * - * Find a (loaded) win32 module depending on path - * - * RETURNS - * the module handle if found - * 0 if not - */ -WINE_MODREF *MODULE_FindModule( - LPCSTR path /* [in] pathname of module/library to be found */ -) { - WINE_MODREF *wm; - char dllname[260], *p; - - /* Append .DLL to name if no extension present */ - strcpy( dllname, path ); - if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\')) - strcat( dllname, ".DLL" ); - - for ( wm = MODULE_modref_list; wm; wm = wm->next ) - { - if ( !FILE_strcasecmp( dllname, wm->modname ) ) - break; - if ( !FILE_strcasecmp( dllname, wm->filename ) ) - break; - if ( !FILE_strcasecmp( dllname, wm->short_modname ) ) - break; - if ( !FILE_strcasecmp( dllname, wm->short_filename ) ) - break; - } - - return wm; -} - - /* Check whether a file is an OS/2 or a very old Windows executable * by testing on import of KERNEL. * @@ -993,14 +927,26 @@ HINSTANCE WINAPI LoadModule( LPCSTR name, LPVOID paramBlock ) */ HMODULE WINAPI GetModuleHandleA(LPCSTR module) { - WINE_MODREF *wm; + NTSTATUS nts; + HMODULE ret; - if ( module == NULL ) - wm = exe_modref; + if (module) + { + UNICODE_STRING wstr; + + RtlCreateUnicodeStringFromAsciiz(&wstr, module); + nts = LdrGetDllHandle(0, 0, &wstr, &ret); + RtlFreeUnicodeString( &wstr ); + } else - wm = MODULE_FindModule( module ); + nts = LdrGetDllHandle(0, 0, NULL, &ret); + if (nts != STATUS_SUCCESS) + { + ret = 0; + SetLastError( RtlNtStatusToDosError( nts ) ); + } - return wm? wm->module : 0; + return ret; } /*********************************************************************** @@ -1008,11 +954,25 @@ HMODULE WINAPI GetModuleHandleA(LPCSTR module) */ HMODULE WINAPI GetModuleHandleW(LPCWSTR module) { - HMODULE hModule; - LPSTR modulea = HEAP_strdupWtoA( GetProcessHeap(), 0, module ); - hModule = GetModuleHandleA( modulea ); - HeapFree( GetProcessHeap(), 0, modulea ); - return hModule; + NTSTATUS nts; + HMODULE ret; + + if (module) + { + UNICODE_STRING wstr; + + RtlInitUnicodeString( &wstr, module ); + nts = LdrGetDllHandle( 0, 0, &wstr, &ret); + } + else + nts = LdrGetDllHandle( 0, 0, NULL, &ret); + + if (nts != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError( nts ) ); + ret = 0; + } + return ret; } @@ -1601,7 +1561,24 @@ FARPROC16 WINAPI GetProcAddress16( HMODULE16 hModule, LPCSTR name ) */ FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function ) { - return MODULE_GetProcAddress( hModule, function, -1, TRUE ); + NTSTATUS nts; + FARPROC fp; + + if (HIWORD(function)) + { + ANSI_STRING str; + + RtlInitAnsiString( &str, function ); + nts = LdrGetProcedureAddress( hModule, &str, 0, (void**)&fp ); + } + else + nts = LdrGetProcedureAddress( hModule, NULL, (DWORD)function, (void**)&fp ); + if (nts != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError( nts ) ); + fp = NULL; + } + return fp; } /*********************************************************************** @@ -1609,37 +1586,10 @@ FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function ) */ FARPROC WINAPI GetProcAddress32_16( HMODULE hModule, LPCSTR function ) { - return MODULE_GetProcAddress( hModule, function, -1, FALSE ); + /* FIXME: we used to disable snoop when returning proc for Win16 subsystem */ + return GetProcAddress( hModule, function ); } -/*********************************************************************** - * MODULE_GetProcAddress (internal) - */ -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 (%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, hint, snoop ); - if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); - } - RtlLeaveCriticalSection( &loader_section ); - return retproc; -} - - /*************************************************************************** * HasGPHandler (KERNEL.338) */ diff --git a/loader/pe_image.c b/loader/pe_image.c index f6908ecc9ad..5ae6dc846c0 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -46,6 +46,7 @@ #include "snoop.h" #include "wine/server.h" #include "wine/debug.h" +#include "ntdll_misc.h" WINE_DEFAULT_DEBUG_CHANNEL(win32); WINE_DECLARE_DEBUG_CHANNEL(module); -- 2.11.4.GIT