diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index 5bb79af99c1..4de17a9b234 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -540,8 +540,8 @@ @ stdcall GetModuleFileNameA(long ptr long) @ stdcall GetModuleFileNameW(long ptr long) @ stdcall GetModuleHandleA(str) -# @ stub GetModuleHandleExA -# @ stub GetModuleHandleExW +@ stdcall GetModuleHandleExA(long ptr ptr) +@ stdcall GetModuleHandleExW(long ptr ptr) @ stdcall GetModuleHandleW(wstr) @ stdcall GetNamedPipeHandleStateA(long ptr ptr ptr ptr str long) @ stdcall GetNamedPipeHandleStateW(long ptr ptr ptr ptr wstr long) diff --git a/dlls/kernel/module.c b/dlls/kernel/module.c index a909bbfb77a..291e817bfa8 100644 --- a/dlls/kernel/module.c +++ b/dlls/kernel/module.c @@ -480,6 +480,57 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType ) return FALSE; } +/*********************************************************************** + * GetModuleHandleExA (KERNEL32.@) + */ +BOOL WINAPI GetModuleHandleExA( DWORD flags, LPCSTR name, HMODULE *module ) +{ + WCHAR *nameW; + + if (!name || (flags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)) + return GetModuleHandleExW( flags, (LPCWSTR)name, module ); + + if (!(nameW = FILE_name_AtoW( name, FALSE ))) return FALSE; + return GetModuleHandleExW( flags, nameW, module ); +} + +/*********************************************************************** + * GetModuleHandleExW (KERNEL32.@) + */ +BOOL WINAPI GetModuleHandleExW( DWORD flags, LPCWSTR name, HMODULE *module ) +{ + NTSTATUS status = STATUS_SUCCESS; + HMODULE ret; + + if (!name) + { + ret = NtCurrentTeb()->Peb->ImageBaseAddress; + } + else if (flags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) + { + void *dummy; + if (!(ret = RtlPcToFileHeader( (void *)name, &dummy ))) status = STATUS_DLL_NOT_FOUND; + } + else + { + UNICODE_STRING wstr; + RtlInitUnicodeString( &wstr, name ); + status = LdrGetDllHandle( 0, 0, &wstr, &ret ); + } + + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError( status ) ); + return FALSE; + } + + if ((flags & GET_MODULE_HANDLE_EX_FLAG_PIN) || + !(flags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)) + FIXME( "should update refcount, flags %lx\n", flags ); + + if (module) *module = ret; + return TRUE; +} /*********************************************************************** * GetModuleHandleA (KERNEL32.@) @@ -496,11 +547,10 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType ) */ HMODULE WINAPI GetModuleHandleA(LPCSTR module) { - WCHAR *moduleW; + HMODULE ret; - if (!module) return NtCurrentTeb()->Peb->ImageBaseAddress; - if (!(moduleW = FILE_name_AtoW( module, FALSE ))) return 0; - return GetModuleHandleW( moduleW ); + if (!GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, module, &ret )) ret = 0; + return ret; } /*********************************************************************** @@ -510,19 +560,9 @@ HMODULE WINAPI GetModuleHandleA(LPCSTR module) */ HMODULE WINAPI GetModuleHandleW(LPCWSTR module) { - NTSTATUS nts; - HMODULE ret; - UNICODE_STRING wstr; + HMODULE ret; - if (!module) return NtCurrentTeb()->Peb->ImageBaseAddress; - - RtlInitUnicodeString( &wstr, module ); - nts = LdrGetDllHandle( 0, 0, &wstr, &ret); - if (nts != STATUS_SUCCESS) - { - SetLastError( RtlNtStatusToDosError( nts ) ); - ret = 0; - } + if (!GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, module, &ret )) ret = 0; return ret; } diff --git a/include/winbase.h b/include/winbase.h index 39db999416f..549e36eda14 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -750,6 +750,10 @@ DECL_WINELIB_TYPE_AW(ENUMRESLANGPROC) #define LOAD_LIBRARY_AS_DATAFILE 0x00000002 #define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 +#define GET_MODULE_HANDLE_EX_FLAG_PIN 1 +#define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2 +#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4 + typedef PLDT_ENTRY LPLDT_ENTRY; typedef enum _GET_FILEEX_INFO_LEVELS { @@ -1568,6 +1572,9 @@ DWORD WINAPI GetModuleFileNameW(HMODULE,LPWSTR,DWORD); HMODULE WINAPI GetModuleHandleA(LPCSTR); HMODULE WINAPI GetModuleHandleW(LPCWSTR); #define GetModuleHandle WINELIB_NAME_AW(GetModuleHandle) +BOOL WINAPI GetModuleHandleExA(DWORD,LPCSTR,HMODULE*); +BOOL WINAPI GetModuleHandleExW(DWORD,LPCWSTR,HMODULE*); +#define GetModuleHandleEx WINELIB_NAME_AW(GetModuleHandleEx) BOOL WINAPI GetNamedPipeHandleStateA(HANDLE,LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPSTR,DWORD); BOOL WINAPI GetNamedPipeHandleStateW(HANDLE,LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR,DWORD); #define GetNamedPipeHandleState WINELIB_NAME_AW(GetNamedPipeHandleState)