kernel32: Partial implementation of GetModuleHandleExA/W.
diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec
index 5bb79af..4de17a9 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 a909bbf..291e817 100644
--- a/dlls/kernel/module.c
+++ b/dlls/kernel/module.c
@@ -480,6 +480,57 @@
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 @@
*/
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 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 39db999..549e36e 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -750,6 +750,10 @@
#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 @@
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)