A+
--
Eric Pouech
Name: ntkrnl_3 ChangeLog: - 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) License: X11 GenDate: 2003/03/06 20:05:27 UTC ModifiedFiles: dlls/ntdll/loader.c dlls/ntdll/ntdll_misc.h include/module.h include/winternl.h loader/module.c loader/pe_image.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/loader.c,v retrieving revision 1.9 diff -u -u -r1.9 loader.c --- dlls/ntdll/loader.c 4 Mar 2003 04:36:56 -0000 1.9 +++ dlls/ntdll/loader.c 6 Mar 2003 06:25:24 -0000 @@ -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 @@ 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"); - RtlUnicodeStringToAnsiString(&str, name, TRUE); - wm = MODULE_FindModule(str.Buffer); - if(!wm) + /* 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; + + 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; } Index: dlls/ntdll/ntdll_misc.h =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/ntdll_misc.h,v retrieving revision 1.7 diff -u -u -r1.7 ntdll_misc.h --- dlls/ntdll/ntdll_misc.h 12 Sep 2002 22:07:03 -0000 1.7 +++ dlls/ntdll/ntdll_misc.h 4 Mar 2003 20:40:53 -0000 @@ -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 Index: include/module.h =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/include/module.h,v retrieving revision 1.71 diff -u -u -r1.71 module.h --- include/module.h 5 Mar 2003 02:50:25 -0000 1.71 +++ include/module.h 6 Mar 2003 06:25:55 -0000 @@ -209,6 +209,7 @@ /* 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 ); @@ -267,9 +268,6 @@ extern BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *filename, UINT size ); 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); Index: loader/module.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/loader/module.c,v retrieving revision 1.173 diff -u -u -r1.173 module.c --- loader/module.c 5 Mar 2003 02:50:25 -0000 1.173 +++ loader/module.c 6 Mar 2003 07:24:21 -0000 @@ -47,7 +47,7 @@ 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 @@ 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 @@ } -/********************************************************************** - * 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 @@ */ 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 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 @@ */ 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,36 +1586,9 @@ */ 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) Index: loader/pe_image.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/loader/pe_image.c,v retrieving revision 1.120 diff -u -u -r1.120 pe_image.c --- loader/pe_image.c 18 Feb 2003 23:29:47 -0000 1.120 +++ loader/pe_image.c 4 Mar 2003 21:15:50 -0000 @@ -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);