Redirecting its calls to the test executable for easier testing and to wokaround some Windows IME caching mechanism that prevent the IME module from reloading.
-- v4: imm32/tests: Test ImmGetIMEFileName with the installed IME. imm32/tests: Test ImmGetDescription with the installed IME. imm32/tests: Redirect IME function to the main module. imm32/tests: Test ImmInstallIMEW with an actual IME. makedep: Support resource files for embedded TESTDLL. imm32/tests: Add broken test results for w10v22H2.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index a97457320ce..00e192cb180 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -2285,7 +2285,9 @@ static DWORD WINAPI com_initialization_thread(void *arg)
static void test_com_initialization(void) { + APTTYPEQUALIFIER qualifier; HANDLE thread; + APTTYPE type; HRESULT hr; HWND wnd; BOOL r; @@ -2340,13 +2342,17 @@ static void test_com_initialization(void) ok(hr == S_OK, "CoInitialize returned %lx\n", hr); test_apttype(APTTYPE_MTA); DestroyWindow(wnd); - test_apttype(-1); + + hr = CoGetApartmentType(&type, &qualifier); + ok(hr == CO_E_NOTINITIALIZED || broken(hr == S_OK) /* w10v22H2 */, + "CoGetApartmentType returned %#lx\n", hr); + test_apttype(hr == S_OK ? APTTYPE_MTA : -1);
wnd = CreateWindowA("static", "static", WS_POPUP, 0, 0, 100, 100, 0, 0, 0, 0); ok(wnd != NULL, "CreateWindow failed\n"); - test_apttype(-1); + test_apttype(hr == S_OK ? APTTYPE_MTA : -1); ShowWindow(wnd, SW_SHOW); - test_apttype(APTTYPE_MAINSTA); + test_apttype(hr == S_OK ? APTTYPE_MTA : APTTYPE_MAINSTA); DestroyWindow(wnd); test_apttype(-1); }
From: Rémi Bernon rbernon@codeweavers.com
--- tools/makedep.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/tools/makedep.c b/tools/makedep.c index 8fa539026ca..ddb091e2dc2 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -97,9 +97,10 @@ struct incl_file #define FLAG_IDL_HEADER 0x008000 /* generates a header (.h) file */ #define FLAG_RC_PO 0x010000 /* rc file contains translations */ #define FLAG_RC_HEADER 0x020000 /* rc file is a header */ -#define FLAG_C_IMPLIB 0x040000 /* file is part of an import library */ -#define FLAG_C_UNIX 0x080000 /* file is part of a Unix library */ -#define FLAG_SFD_FONTS 0x100000 /* sfd file generated bitmap fonts */ +#define FLAG_RC_TESTDLL 0x040000 /* rc file is for a test dll */ +#define FLAG_C_IMPLIB 0x080000 /* file is part of an import library */ +#define FLAG_C_UNIX 0x100000 /* file is part of a Unix library */ +#define FLAG_SFD_FONTS 0x200000 /* sfd file generated bitmap fonts */
static const struct { @@ -938,6 +939,7 @@ static void parse_pragma_directive( struct file *source, char *str ) { if (!strcmp( flag, "header" )) source->flags |= FLAG_RC_HEADER; else if (!strcmp( flag, "po" )) source->flags |= FLAG_RC_PO; + else if (!strcmp( flag, "testdll" )) source->flags |= FLAG_RC_TESTDLL; } else if (strendswith( source->name, ".sfd" )) { @@ -2710,8 +2712,14 @@ static void output_source_rc( struct makefile *make, struct incl_file *source, c if (source->file->flags & FLAG_RC_HEADER) return; if (source->file->flags & FLAG_GENERATED) strarray_add( &make->clean_files, source->name ); if (linguas.count && (source->file->flags & FLAG_RC_PO)) po_dir = "po"; - for (arch = 0; arch < archs.count; arch++) - if (!make->disabled[arch]) strarray_add( &make->res_files[arch], res_file ); + if (!(source->file->flags & FLAG_RC_TESTDLL)) + { + for (arch = 0; arch < archs.count; arch++) + { + if (make->disabled[arch]) continue; + strarray_add( &make->res_files[arch], res_file ); + } + } if (source->file->flags & FLAG_RC_PO) { strarray_add( &make->pot_files, strmake( "%s.pot", obj )); @@ -3036,11 +3044,11 @@ static void output_source_in( struct makefile *make, struct incl_file *source, c */ static void output_source_spec( struct makefile *make, struct incl_file *source, const char *obj ) { + const char *dll_name, *obj_name, *res_name, *output_file, *debug_file, *output_rsrc; struct strarray imports = get_expanded_file_local_var( make, obj, "IMPORTS" ); struct strarray dll_flags = empty_strarray; struct strarray default_imports = empty_strarray; struct strarray all_libs, dep_libs; - const char *dll_name, *obj_name, *res_name, *output_file, *debug_file; unsigned int arch;
if (!imports.count) imports = make->imports; @@ -3057,12 +3065,15 @@ static void output_source_spec( struct makefile *make, struct incl_file *source, if (!arch) strarray_addall( &all_libs, libs ); dll_name = arch_module_name( strmake( "%s.dll", obj ), arch ); obj_name = obj_dir_path( make, strmake( "%s%s.o", arch_dirs[arch], obj )); - res_name = strmake( "%s%s.res", arch_dirs[arch], obj ); output_file = obj_dir_path( make, dll_name ); + output_rsrc = strmake( "%s.res", dll_name ); + + if (!find_src_file( make, strmake( "%s.rc", obj ))) res_name = NULL; + else res_name = obj_dir_path( make, strmake( "%s.res", obj ));
strarray_add( &make->clean_files, dll_name ); - strarray_add( &make->res_files[arch], res_name ); - output( "%s:", obj_dir_path( make, res_name )); + strarray_add( &make->res_files[arch], output_rsrc ); + output( "%s:", obj_dir_path( make, output_rsrc )); output_filename( output_file ); output_filename( tools_path( make, "wrc" )); output( "\n" ); @@ -3072,6 +3083,7 @@ static void output_source_spec( struct makefile *make, struct incl_file *source, output( "%s:", output_file ); output_filename( source->filename ); output_filename( obj_name ); + if (res_name) output_filename( res_name ); output_filenames( dep_libs ); output_filename( tools_path( make, "winebuild" )); output_filename( tools_path( make, "winegcc" )); @@ -3083,6 +3095,7 @@ static void output_source_spec( struct makefile *make, struct incl_file *source, output_filename( "-shared" ); output_filename( source->filename ); output_filename( obj_name ); + if (res_name) output_filename( res_name ); if ((debug_file = get_debug_file( make, dll_name, arch ))) output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file ))); output_filenames( all_libs );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/Makefile.in | 9 +- dlls/imm32/tests/ime_test.h | 35 ++++++++ dlls/imm32/tests/ime_wrapper.c | 107 +++++++++++++++++++++++ dlls/imm32/tests/ime_wrapper.rc | 28 ++++++ dlls/imm32/tests/ime_wrapper.spec | 16 ++++ dlls/imm32/tests/imm32.c | 138 +++++++++++++++++++++++++++++- 6 files changed, 328 insertions(+), 5 deletions(-) create mode 100644 dlls/imm32/tests/ime_test.h create mode 100644 dlls/imm32/tests/ime_wrapper.c create mode 100644 dlls/imm32/tests/ime_wrapper.rc create mode 100644 dlls/imm32/tests/ime_wrapper.spec
diff --git a/dlls/imm32/tests/Makefile.in b/dlls/imm32/tests/Makefile.in index d0881429e34..141b1fd8a97 100644 --- a/dlls/imm32/tests/Makefile.in +++ b/dlls/imm32/tests/Makefile.in @@ -1,5 +1,8 @@ TESTDLL = imm32.dll -IMPORTS = imm32 ole32 user32 +IMPORTS = imm32 ole32 user32 advapi32
-C_SRCS = \ - imm32.c +SOURCES = \ + imm32.c \ + ime_wrapper.c \ + ime_wrapper.rc \ + ime_wrapper.spec diff --git a/dlls/imm32/tests/ime_test.h b/dlls/imm32/tests/ime_test.h new file mode 100644 index 00000000000..bdfb899b504 --- /dev/null +++ b/dlls/imm32/tests/ime_test.h @@ -0,0 +1,35 @@ +/* + * Copyright 2023 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_IME_TEST_H +#define __WINE_IME_TEST_H + +#include <stdarg.h> +#include <stddef.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "wingdi.h" + +#include "imm.h" +#include "immdev.h" + +#endif /* __WINE_IME_TEST_H */ diff --git a/dlls/imm32/tests/ime_wrapper.c b/dlls/imm32/tests/ime_wrapper.c new file mode 100644 index 00000000000..5bdd9afa336 --- /dev/null +++ b/dlls/imm32/tests/ime_wrapper.c @@ -0,0 +1,107 @@ +/* + * Copyright 2023 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "ime_test.h" + +BOOL WINAPI ImeConfigure( HKL hkl, HWND hwnd, DWORD mode, void *data ) +{ + return FALSE; +} + +DWORD WINAPI ImeConversionList( HIMC himc, const WCHAR *source, CANDIDATELIST *dest, DWORD dest_len, UINT flag ) +{ + return 0; +} + +BOOL WINAPI ImeDestroy( UINT force ) +{ + return FALSE; +} + +UINT WINAPI ImeEnumRegisterWord( REGISTERWORDENUMPROCW proc, const WCHAR *reading, DWORD style, + const WCHAR *string, void *data ) +{ + return 0; +} + +LRESULT WINAPI ImeEscape( HIMC himc, UINT escape, void *data ) +{ + return 0; +} + +DWORD WINAPI ImeGetImeMenuItems( HIMC himc, DWORD flags, DWORD type, IMEMENUITEMINFOW *parent, + IMEMENUITEMINFOW *menu, DWORD size ) +{ + return 0; +} + +UINT WINAPI ImeGetRegisterWordStyle( UINT item, STYLEBUFW *style_buf ) +{ + return 0; +} + +BOOL WINAPI ImeInquire( IMEINFO *info, WCHAR *ui_class, DWORD flags ) +{ + return FALSE; +} + +BOOL WINAPI ImeProcessKey( HIMC himc, UINT vkey, LPARAM key_data, BYTE *key_state ) +{ + return FALSE; +} + +BOOL WINAPI ImeRegisterWord( const WCHAR *reading, DWORD style, const WCHAR *string ) +{ + return FALSE; +} + +BOOL WINAPI ImeSelect( HIMC himc, BOOL select ) +{ + return FALSE; +} + +BOOL WINAPI ImeSetActiveContext( HIMC himc, BOOL flag ) +{ + return FALSE; +} + +BOOL WINAPI ImeSetCompositionString( HIMC himc, DWORD index, const void *comp, DWORD comp_len, + const void *read, DWORD read_len ) +{ + return FALSE; +} + +UINT WINAPI ImeToAsciiEx( UINT vkey, UINT scan_code, BYTE *key_state, TRANSMSGLIST *msgs, UINT state, HIMC himc ) +{ + return 0; +} + +BOOL WINAPI ImeUnregisterWord( const WCHAR *reading, DWORD style, const WCHAR *string ) +{ + return FALSE; +} + +BOOL WINAPI NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value ) +{ + return FALSE; +} + +BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, LPVOID reserved ) +{ + return TRUE; +} diff --git a/dlls/imm32/tests/ime_wrapper.rc b/dlls/imm32/tests/ime_wrapper.rc new file mode 100644 index 00000000000..6844b62195b --- /dev/null +++ b/dlls/imm32/tests/ime_wrapper.rc @@ -0,0 +1,28 @@ +/* + * Copyright 2023 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep testdll + +#define WINE_LANGID 0400 +#define WINE_FILETYPE VFT_DRV +#define WINE_FILESUBTYPE VFT2_DRV_INPUTMETHOD +#define WINE_FILENAME "ime_wrapper" +#define WINE_FILENAME_STR "ime_wrapper.dll" +#define WINE_FILEDESCRIPTION_STR "WineTest IME" + +#include "wine/wine_common_ver.rc" diff --git a/dlls/imm32/tests/ime_wrapper.spec b/dlls/imm32/tests/ime_wrapper.spec new file mode 100644 index 00000000000..937fdba922a --- /dev/null +++ b/dlls/imm32/tests/ime_wrapper.spec @@ -0,0 +1,16 @@ +@ stdcall ImeConfigure(long long long ptr) +@ stdcall ImeConversionList(long wstr ptr long long) +@ stdcall ImeDestroy(long) +@ stdcall ImeEnumRegisterWord(ptr wstr long wstr ptr) +@ stdcall ImeEscape(long long ptr) +@ stdcall ImeGetImeMenuItems(long long long ptr ptr long) +@ stdcall ImeGetRegisterWordStyle(long ptr) +@ stdcall ImeInquire(ptr wstr wstr) +@ stdcall ImeProcessKey(long long long ptr) +@ stdcall ImeRegisterWord(wstr long wstr) +@ stdcall ImeSelect(long long) +@ stdcall ImeSetActiveContext(long long) +@ stdcall ImeSetCompositionString(long long ptr long ptr long) +@ stdcall ImeToAsciiEx(long long ptr ptr long long) +@ stdcall ImeUnregisterWord(wstr long wstr) +@ stdcall NotifyIME(long long long long) diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 00e192cb180..3f71c00622b 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -18,7 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include <stdio.h> +#include <stdarg.h> +#include <stddef.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h"
#include "wine/test.h" #include "objbase.h" @@ -27,6 +33,8 @@ #include "imm.h" #include "immdev.h"
+#include "ime_test.h" + BOOL WINAPI ImmSetActiveContext(HWND, HIMC, BOOL);
static BOOL (WINAPI *pImmAssociateContextEx)(HWND,HIMC,DWORD); @@ -206,6 +214,28 @@ static HWND hwnd, child;
static HWND get_ime_window(void);
+static void load_resource( const WCHAR *name, WCHAR *filename ) +{ + static WCHAR path[MAX_PATH]; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempPathW( ARRAY_SIZE(path), path ); + GetTempFileNameW( path, name, 0, filename ); + + file = CreateFileW( filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); + ok( file != INVALID_HANDLE_VALUE, "failed to create %s, error %lu\n", debugstr_w(filename), GetLastError() ); + + res = FindResourceW( NULL, name, L"TESTDLL" ); + ok( res != 0, "couldn't find resource\n" ); + ptr = LockResource( LoadResource( GetModuleHandleW( NULL ), res ) ); + WriteFile( file, ptr, SizeofResource( GetModuleHandleW( NULL ), res ), &written, NULL ); + ok( written == SizeofResource( GetModuleHandleW( NULL ), res ), "couldn't write resource\n" ); + CloseHandle( file ); +} + static LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HWND default_ime_wnd; @@ -2453,7 +2483,109 @@ static void test_ImmDisableIME(void) ok(!def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def); }
-START_TEST(imm32) { +static UINT ime_count; +static WCHAR ime_path[MAX_PATH]; + +static HKL ime_install(void) +{ + WCHAR buffer[MAX_PATH]; + DWORD len, ret; + HKEY hkey; + HKL hkl; + + /* install the actual IME module, it will lookup the functions from the DLL */ + load_resource( L"ime_wrapper.dll", buffer ); + + SetLastError( 0xdeadbeef ); + swprintf( ime_path, ARRAY_SIZE(ime_path), L"c:\windows\system32\wine%04x.ime", ime_count++ ); + ret = MoveFileW( buffer, ime_path ); + todo_wine_if( GetLastError() == ERROR_ALREADY_EXISTS ) + ok( ret || broken( !ret ) /* sometimes still in use */, + "MoveFileW failed, error %lu\n", GetLastError() ); + + hkl = ImmInstallIMEW( ime_path, L"WineTest IME" ); + todo_wine + ok( hkl == (HKL)(int)0xe0200400, "ImmInstallIMEW returned %p, error %lu\n", hkl, GetLastError() ); + + swprintf( buffer, ARRAY_SIZE(buffer), L"System\CurrentControlSet\Control\Keyboard Layouts\%08x", hkl ); + ret = RegOpenKeyW( HKEY_LOCAL_MACHINE, buffer, &hkey ); + ok( !ret, "RegOpenKeyW returned %#lx, error %lu\n", ret, GetLastError() ); + + len = sizeof(buffer); + memset( buffer, 0xcd, sizeof(buffer) ); + ret = RegQueryValueExW( hkey, L"Ime File", NULL, NULL, (BYTE *)buffer, &len ); + ok( !ret, "RegQueryValueExW returned %#lx, error %lu\n", ret, GetLastError() ); + todo_wine + ok( !wcsicmp( buffer, wcsrchr( ime_path, '\' ) + 1 ), "got Ime File %s\n", debugstr_w(buffer) ); + + len = sizeof(buffer); + memset( buffer, 0xcd, sizeof(buffer) ); + ret = RegQueryValueExW( hkey, L"Layout Text", NULL, NULL, (BYTE *)buffer, &len ); + ok( !ret, "RegQueryValueExW returned %#lx, error %lu\n", ret, GetLastError() ); + ok( !wcscmp( buffer, L"WineTest IME" ), "got Layout Text %s\n", debugstr_w(buffer) ); + + len = sizeof(buffer); + memset( buffer, 0xcd, sizeof(buffer) ); + ret = RegQueryValueExW( hkey, L"Layout File", NULL, NULL, (BYTE *)buffer, &len ); + todo_wine + ok( !ret, "RegQueryValueExW returned %#lx, error %lu\n", ret, GetLastError() ); + todo_wine + ok( !wcscmp( buffer, L"kbdus.dll" ), "got Layout File %s\n", debugstr_w(buffer) ); + + ret = RegCloseKey( hkey ); + ok( !ret, "RegCloseKey returned %#lx, error %lu\n", ret, GetLastError() ); + + return hkl; +} + +static void ime_cleanup( HKL hkl ) +{ + WCHAR buffer[MAX_PATH], value[MAX_PATH]; + DWORD i, buffer_len, value_len, ret; + HKEY hkey; + + ret = UnloadKeyboardLayout( hkl ); + todo_wine + ok( ret, "UnloadKeyboardLayout failed, error %lu\n", GetLastError() ); + + swprintf( buffer, ARRAY_SIZE(buffer), L"System\CurrentControlSet\Control\Keyboard Layouts\%08x", hkl ); + ret = RegDeleteKeyW( HKEY_LOCAL_MACHINE, buffer ); + ok( !ret, "RegDeleteKeyW returned %#lx, error %lu\n", ret, GetLastError() ); + + ret = RegOpenKeyW( HKEY_CURRENT_USER, L"Keyboard Layout\Preload", &hkey ); + ok( !ret, "RegOpenKeyW returned %#lx, error %lu\n", ret, GetLastError() ); + + value_len = ARRAY_SIZE(value); + buffer_len = sizeof(buffer); + for (i = 0; !RegEnumValueW( hkey, i, value, &value_len, NULL, NULL, (void *)buffer, &buffer_len ); i++) + { + value_len = ARRAY_SIZE(value); + buffer_len = sizeof(buffer); + if (hkl != UlongToHandle( wcstoul( buffer, NULL, 16 ) )) continue; + ret = RegDeleteValueW( hkey, value ); + ok( !ret, "RegDeleteValueW returned %#lx, error %lu\n", ret, GetLastError() ); + } + + ret = RegCloseKey( hkey ); + ok( !ret, "RegCloseKey returned %#lx, error %lu\n", ret, GetLastError() ); + + ret = DeleteFileW( ime_path ); + todo_wine_if( GetLastError() == ERROR_ACCESS_DENIED ) + ok( ret || broken( !ret ) /* sometimes still in use */, + "DeleteFileW failed, error %lu\n", GetLastError() ); +} + +static void test_ImmInstallIME(void) +{ + HKL hkl; + + if (!(hkl = ime_install())) return; + + ime_cleanup( hkl ); +} + +START_TEST(imm32) +{ if (!is_ime_enabled()) { win_skip("IME support not implemented\n"); @@ -2462,6 +2594,8 @@ START_TEST(imm32) {
test_com_initialization();
+ test_ImmInstallIME(); + if (init()) { test_ImmNotifyIME();
From: Rémi Bernon rbernon@codeweavers.com
For easier testing and to wokaround some Windows IME caching mechanism that prevent the IME module from reloading. --- dlls/imm32/tests/ime_test.h | 21 +++ dlls/imm32/tests/ime_wrapper.c | 67 +++++++--- dlls/imm32/tests/ime_wrapper.spec | 1 + dlls/imm32/tests/imm32.c | 210 ++++++++++++++++++++++++++++++ 4 files changed, 283 insertions(+), 16 deletions(-)
diff --git a/dlls/imm32/tests/ime_test.h b/dlls/imm32/tests/ime_test.h index bdfb899b504..fda8065276d 100644 --- a/dlls/imm32/tests/ime_test.h +++ b/dlls/imm32/tests/ime_test.h @@ -32,4 +32,25 @@ #include "imm.h" #include "immdev.h"
+struct ime_functions +{ + BOOL (*WINAPI pImeConfigure)(HKL,HWND,DWORD,void *); + DWORD (*WINAPI pImeConversionList)(HIMC,const WCHAR *,CANDIDATELIST *,DWORD,UINT); + BOOL (*WINAPI pImeDestroy)(UINT); + UINT (*WINAPI pImeEnumRegisterWord)(REGISTERWORDENUMPROCW,const WCHAR *,DWORD,const WCHAR *,void *); + LRESULT (*WINAPI pImeEscape)(HIMC,UINT,void *); + DWORD (*WINAPI pImeGetImeMenuItems)(HIMC,DWORD,DWORD,IMEMENUITEMINFOW *,IMEMENUITEMINFOW *,DWORD); + UINT (*WINAPI pImeGetRegisterWordStyle)(UINT,STYLEBUFW *); + BOOL (*WINAPI pImeInquire)(IMEINFO *,WCHAR *,DWORD); + BOOL (*WINAPI pImeProcessKey)(HIMC,UINT,LPARAM,BYTE *); + BOOL (*WINAPI pImeRegisterWord)(const WCHAR *,DWORD,const WCHAR *); + BOOL (*WINAPI pImeSelect)(HIMC,BOOL); + BOOL (*WINAPI pImeSetActiveContext)(HIMC,BOOL); + BOOL (*WINAPI pImeSetCompositionString)(HIMC,DWORD,const void *,DWORD,const void *,DWORD); + UINT (*WINAPI pImeToAsciiEx)(UINT,UINT,BYTE *,TRANSMSGLIST *,UINT,HIMC); + BOOL (*WINAPI pImeUnregisterWord)(const WCHAR *,DWORD,const WCHAR *); + BOOL (*WINAPI pNotifyIME)(HIMC,DWORD,DWORD,DWORD); + BOOL (*WINAPI pDllMain)(HINSTANCE,DWORD,void *); +}; + #endif /* __WINE_IME_TEST_H */ diff --git a/dlls/imm32/tests/ime_wrapper.c b/dlls/imm32/tests/ime_wrapper.c index 5bdd9afa336..d8a03499549 100644 --- a/dlls/imm32/tests/ime_wrapper.c +++ b/dlls/imm32/tests/ime_wrapper.c @@ -18,90 +18,125 @@
#include "ime_test.h"
+struct ime_functions ime_functions = {0}; + BOOL WINAPI ImeConfigure( HKL hkl, HWND hwnd, DWORD mode, void *data ) { - return FALSE; + if (!ime_functions.pImeConfigure) return FALSE; + return ime_functions.pImeConfigure( hkl, hwnd, mode, data ); }
DWORD WINAPI ImeConversionList( HIMC himc, const WCHAR *source, CANDIDATELIST *dest, DWORD dest_len, UINT flag ) { - return 0; + if (!ime_functions.pImeConversionList) return 0; + return ime_functions.pImeConversionList( himc, source, dest, dest_len, flag ); }
BOOL WINAPI ImeDestroy( UINT force ) { - return FALSE; + if (!ime_functions.pImeDestroy) return FALSE; + return ime_functions.pImeDestroy( force ); }
UINT WINAPI ImeEnumRegisterWord( REGISTERWORDENUMPROCW proc, const WCHAR *reading, DWORD style, const WCHAR *string, void *data ) { - return 0; + if (!ime_functions.pImeEnumRegisterWord) return 0; + return ime_functions.pImeEnumRegisterWord( proc, reading, style, string, data ); }
LRESULT WINAPI ImeEscape( HIMC himc, UINT escape, void *data ) { - return 0; + if (!ime_functions.pImeEscape) return 0; + return ime_functions.pImeEscape( himc, escape, data ); }
DWORD WINAPI ImeGetImeMenuItems( HIMC himc, DWORD flags, DWORD type, IMEMENUITEMINFOW *parent, IMEMENUITEMINFOW *menu, DWORD size ) { - return 0; + if (!ime_functions.pImeGetImeMenuItems) return 0; + return ime_functions.pImeGetImeMenuItems( himc, flags, type, parent, menu, size ); }
UINT WINAPI ImeGetRegisterWordStyle( UINT item, STYLEBUFW *style_buf ) { - return 0; + if (!ime_functions.pImeGetRegisterWordStyle) return 0; + return ime_functions.pImeGetRegisterWordStyle( item, style_buf ); }
BOOL WINAPI ImeInquire( IMEINFO *info, WCHAR *ui_class, DWORD flags ) { - return FALSE; + if (!ime_functions.pImeInquire) return FALSE; + return ime_functions.pImeInquire( info, ui_class, flags ); }
BOOL WINAPI ImeProcessKey( HIMC himc, UINT vkey, LPARAM key_data, BYTE *key_state ) { - return FALSE; + if (!ime_functions.pImeProcessKey) return FALSE; + return ime_functions.pImeProcessKey( himc, vkey, key_data, key_state ); }
BOOL WINAPI ImeRegisterWord( const WCHAR *reading, DWORD style, const WCHAR *string ) { - return FALSE; + if (!ime_functions.pImeRegisterWord) return FALSE; + return ime_functions.pImeRegisterWord( reading, style, string ); }
BOOL WINAPI ImeSelect( HIMC himc, BOOL select ) { - return FALSE; + if (!ime_functions.pImeSelect) return FALSE; + return ime_functions.pImeSelect( himc, select ); }
BOOL WINAPI ImeSetActiveContext( HIMC himc, BOOL flag ) { - return FALSE; + if (!ime_functions.pImeSetActiveContext) return FALSE; + return ime_functions.pImeSetActiveContext( himc, flag ); }
BOOL WINAPI ImeSetCompositionString( HIMC himc, DWORD index, const void *comp, DWORD comp_len, const void *read, DWORD read_len ) { - return FALSE; + if (!ime_functions.pImeSetCompositionString) return FALSE; + return ime_functions.pImeSetCompositionString( himc, index, comp, comp_len, read, read_len ); }
UINT WINAPI ImeToAsciiEx( UINT vkey, UINT scan_code, BYTE *key_state, TRANSMSGLIST *msgs, UINT state, HIMC himc ) { - return 0; + if (!ime_functions.pImeToAsciiEx) return 0; + return ime_functions.pImeToAsciiEx( vkey, scan_code, key_state, msgs, state, himc ); }
BOOL WINAPI ImeUnregisterWord( const WCHAR *reading, DWORD style, const WCHAR *string ) { - return FALSE; + if (!ime_functions.pImeUnregisterWord) return FALSE; + return ime_functions.pImeUnregisterWord( reading, style, string ); }
BOOL WINAPI NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value ) { - return FALSE; + if (!ime_functions.pNotifyIME) return FALSE; + return ime_functions.pNotifyIME( himc, action, index, value ); }
BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, LPVOID reserved ) { + static HMODULE module; + + switch (reason) + { + case DLL_PROCESS_ATTACH: + if (!(module = GetModuleHandleW( L"winetest_ime.dll" ))) return TRUE; + ime_functions = *(struct ime_functions *)GetProcAddress( module, "ime_functions" ); + if (!ime_functions.pDllMain) return TRUE; + return ime_functions.pDllMain( instance, reason, reserved ); + + case DLL_PROCESS_DETACH: + if (module == instance) return TRUE; + if (!ime_functions.pDllMain) return TRUE; + ime_functions.pDllMain( instance, reason, reserved ); + memset( &ime_functions, 0, sizeof(ime_functions) ); + } + return TRUE; } diff --git a/dlls/imm32/tests/ime_wrapper.spec b/dlls/imm32/tests/ime_wrapper.spec index 937fdba922a..05a60e84a5d 100644 --- a/dlls/imm32/tests/ime_wrapper.spec +++ b/dlls/imm32/tests/ime_wrapper.spec @@ -14,3 +14,4 @@ @ stdcall ImeToAsciiEx(long long ptr ptr long long) @ stdcall ImeUnregisterWord(wstr long wstr) @ stdcall NotifyIME(long long long long) +@ extern -private ime_functions diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 3f71c00622b..91f5a61065f 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -2483,16 +2483,219 @@ static void test_ImmDisableIME(void) ok(!def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def); }
+#define ime_trace( msg, ... ) if (winetest_debug > 1) trace( "%04lx:%s " msg, GetCurrentThreadId(), __func__, ## __VA_ARGS__ ) + +static LRESULT CALLBACK ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + ime_trace( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); + ok( 0, "unexpected call\n" ); + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +static WNDCLASSEXW ime_ui_class = +{ + .cbSize = sizeof(WNDCLASSEXW), + .style = CS_IME, + .lpfnWndProc = ime_ui_window_proc, + .cbWndExtra = 2 * sizeof(LONG_PTR), + .lpszClassName = L"WineTestIME", +}; + +static BOOL WINAPI ime_ImeConfigure( HKL hkl, HWND hwnd, DWORD mode, void *data ) +{ + ime_trace( "hkl %p, hwnd %p, mode %lu, data %p\n", hkl, hwnd, mode, data ); + ok( 0, "unexpected call\n" ); + return FALSE; +} + +static DWORD WINAPI ime_ImeConversionList( HIMC himc, const WCHAR *source, CANDIDATELIST *dest, + DWORD dest_len, UINT flag ) +{ + ime_trace( "himc %p, source %s, dest %p, dest_len %lu, flag %#x\n", + himc, debugstr_w(source), dest, dest_len, flag ); + ok( 0, "unexpected call\n" ); + return 0; +} + +static BOOL WINAPI ime_ImeDestroy( UINT force ) +{ + ime_trace( "force %u\n", force ); + ok( 0, "unexpected call\n" ); + return TRUE; +} + +static UINT WINAPI ime_ImeEnumRegisterWord( REGISTERWORDENUMPROCW proc, const WCHAR *reading, DWORD style, + const WCHAR *string, void *data ) +{ + ime_trace( "proc %p, reading %s, style %lu, string %s, data %p\n", + proc, debugstr_w(reading), style, debugstr_w(string), data ); + ok( 0, "unexpected call\n" ); + return 0; +} + +static LRESULT WINAPI ime_ImeEscape( HIMC himc, UINT escape, void *data ) +{ + ime_trace( "himc %p, escape %#x, data %p\n", himc, escape, data ); + ok( 0, "unexpected call\n" ); + return TRUE; +} + +static DWORD WINAPI ime_ImeGetImeMenuItems( HIMC himc, DWORD flags, DWORD type, IMEMENUITEMINFOW *parent, + IMEMENUITEMINFOW *menu, DWORD size ) +{ + ime_trace( "himc %p, flags %#lx, type %lu, parent %p, menu %p, size %#lx\n", + himc, flags, type, parent, menu, size ); + ok( 0, "unexpected call\n" ); + return 0; +} + +static UINT WINAPI ime_ImeGetRegisterWordStyle( UINT item, STYLEBUFW *style ) +{ + ime_trace( "item %u, style %p\n", item, style ); + ok( 0, "unexpected call\n" ); + return 0; +} + +static BOOL WINAPI ime_ImeInquire( IMEINFO *info, WCHAR *ui_class, DWORD flags ) +{ + ime_trace( "info %p, ui_class %p, flags %#lx\n", info, ui_class, flags ); + ok( 0, "unexpected call\n" ); + return TRUE; +} + +static BOOL WINAPI ime_ImeProcessKey( HIMC himc, UINT vkey, LPARAM key_data, BYTE *key_state ) +{ + ime_trace( "himc %p, vkey %u, key_data %#Ix, key_state %p\n", + himc, vkey, key_data, key_state ); + ok( 0, "unexpected call\n" ); + return FALSE; +} + +static BOOL WINAPI ime_ImeRegisterWord( const WCHAR *reading, DWORD style, const WCHAR *string ) +{ + ime_trace( "reading %s, style %lu, string %s\n", debugstr_w(reading), style, debugstr_w(string) ); + ok( 0, "unexpected call\n" ); + return FALSE; +} + +static BOOL WINAPI ime_ImeSelect( HIMC himc, BOOL select ) +{ + ime_trace( "himc %p, select %d\n", himc, select ); + ok( 0, "unexpected call\n" ); + return FALSE; +} + +static BOOL WINAPI ime_ImeSetActiveContext( HIMC himc, BOOL flag ) +{ + ime_trace( "himc %p, flag %#x\n", himc, flag ); + ok( 0, "unexpected call\n" ); + return FALSE; +} + +static BOOL WINAPI ime_ImeSetCompositionString( HIMC himc, DWORD index, const void *comp, DWORD comp_len, + const void *read, DWORD read_len ) +{ + ime_trace( "himc %p, index %lu, comp %p, comp_len %lu, read %p, read_len %lu\n", + himc, index, comp, comp_len, read, read_len ); + ok( 0, "unexpected call\n" ); + return FALSE; +} + +static UINT WINAPI ime_ImeToAsciiEx( UINT vkey, UINT scan_code, BYTE *key_state, TRANSMSGLIST *msgs, UINT state, HIMC himc ) +{ + ime_trace( "vkey %u, scan_code %u, key_state %p, msgs %p, state %u, himc %p\n", + vkey, scan_code, key_state, msgs, state, himc ); + ok( 0, "unexpected call\n" ); + return 0; +} + +static BOOL WINAPI ime_ImeUnregisterWord( const WCHAR *reading, DWORD style, const WCHAR *string ) +{ + ime_trace( "reading %s, style %lu, string %s\n", debugstr_w(reading), style, debugstr_w(string) ); + ok( 0, "unexpected call\n" ); + return FALSE; +} + +static BOOL WINAPI ime_NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value ) +{ + ime_trace( "himc %p, action %lu, index %lu, value %lu\n", himc, action, index, value ); + ok( 0, "unexpected call\n" ); + return FALSE; +} + +static BOOL WINAPI ime_DllMain( HINSTANCE instance, DWORD reason, LPVOID reserved ) +{ + ime_trace( "instance %p, reason %lu, reserved %p.\n", instance, reason, reserved ); + + switch (reason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls( instance ); + ime_ui_class.hInstance = instance; + RegisterClassExW( &ime_ui_class ); + break; + + case DLL_PROCESS_DETACH: + UnregisterClassW( ime_ui_class.lpszClassName, instance ); + break; + } + + return TRUE; +} + +static struct ime_functions ime_functions = +{ + ime_ImeConfigure, + ime_ImeConversionList, + ime_ImeDestroy, + ime_ImeEnumRegisterWord, + ime_ImeEscape, + ime_ImeGetImeMenuItems, + ime_ImeGetRegisterWordStyle, + ime_ImeInquire, + ime_ImeProcessKey, + ime_ImeRegisterWord, + ime_ImeSelect, + ime_ImeSetActiveContext, + ime_ImeSetCompositionString, + ime_ImeToAsciiEx, + ime_ImeUnregisterWord, + ime_NotifyIME, + ime_DllMain, +}; + static UINT ime_count; static WCHAR ime_path[MAX_PATH];
static HKL ime_install(void) { WCHAR buffer[MAX_PATH]; + HMODULE module; DWORD len, ret; HKEY hkey; HKL hkl;
+ /* IME module gets cached and won't reload from disk as soon as a window has + * loaded it. To workaround the issue we load the module first as a DLL, + * set its function pointers from the test, and later when the cached IME + * gets loaded, read the function pointers from the separately loaded DLL. + */ + + load_resource( L"ime_wrapper.dll", buffer ); + + SetLastError( 0xdeadbeef ); + ret = MoveFileW( buffer, L"c:\windows\system32\winetest_ime.dll" ); + if (!ret) + { + ok( GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError() ); + win_skip( "Failed to copy DLL to system directory\n" ); + return 0; + } + + module = LoadLibraryW( L"c:\windows\system32\winetest_ime.dll" ); + ok( !!module, "LoadLibraryW failed, error %lu\n", GetLastError() ); + *(struct ime_functions *)GetProcAddress( module, "ime_functions" ) = ime_functions; + /* install the actual IME module, it will lookup the functions from the DLL */ load_resource( L"ime_wrapper.dll", buffer );
@@ -2540,6 +2743,7 @@ static HKL ime_install(void)
static void ime_cleanup( HKL hkl ) { + HMODULE module = GetModuleHandleW( L"winetest_ime.dll" ); WCHAR buffer[MAX_PATH], value[MAX_PATH]; DWORD i, buffer_len, value_len, ret; HKEY hkey; @@ -2573,6 +2777,12 @@ static void ime_cleanup( HKL hkl ) todo_wine_if( GetLastError() == ERROR_ACCESS_DENIED ) ok( ret || broken( !ret ) /* sometimes still in use */, "DeleteFileW failed, error %lu\n", GetLastError() ); + + ret = FreeLibrary( module ); + ok( ret, "FreeLibrary failed, error %lu\n", GetLastError() ); + + ret = DeleteFileW( L"c:\windows\system32\winetest_ime.dll" ); + ok( ret, "DeleteFileW failed, error %lu\n", GetLastError() ); }
static void test_ImmInstallIME(void)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 136 +++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 56 deletions(-)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 91f5a61065f..e259c8b2e22 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -1194,61 +1194,6 @@ static void test_ImmGetContext(void) ok(ImmReleaseContext(hwnd, himc), "ImmReleaseContext failed\n"); }
-static void test_ImmGetDescription(void) -{ - HKL hkl; - WCHAR descW[100]; - CHAR descA[100]; - UINT ret, lret; - - /* FIXME: invalid keyboard layouts should not pass */ - ret = ImmGetDescriptionW(NULL, NULL, 0); - ok(!ret, "ImmGetDescriptionW failed, expected 0 received %d.\n", ret); - ret = ImmGetDescriptionA(NULL, NULL, 0); - ok(!ret, "ImmGetDescriptionA failed, expected 0 received %d.\n", ret); - - /* load a language with valid IMM descriptions */ - hkl = GetKeyboardLayout(0); - ok(hkl != 0, "GetKeyboardLayout failed, expected != 0.\n"); - - ret = ImmGetDescriptionW(hkl, NULL, 0); - if(!ret) - { - win_skip("ImmGetDescriptionW is not working for current loaded keyboard.\n"); - return; - } - - SetLastError(0xdeadcafe); - ret = ImmGetDescriptionW(0, NULL, 100); - ok (ret == 0, "ImmGetDescriptionW with 0 hkl should return 0\n"); - ret = GetLastError(); - ok (ret == 0xdeadcafe, "Last Error should remain unchanged\n"); - - ret = ImmGetDescriptionW(hkl, descW, 0); - ok(ret, "ImmGetDescriptionW failed, expected != 0 received 0.\n"); - - lret = ImmGetDescriptionW(hkl, descW, ret + 1); - ok(lret, "ImmGetDescriptionW failed, expected != 0 received 0.\n"); - ok(lret == ret, "ImmGetDescriptionW failed to return the correct amount of data. Expected %d, got %d.\n", ret, lret); - - lret = ImmGetDescriptionA(hkl, descA, ret + 1); - ok(lret, "ImmGetDescriptionA failed, expected != 0 received 0.\n"); - ok(lret == ret, "ImmGetDescriptionA failed to return the correct amount of data. Expected %d, got %d.\n", ret, lret); - - ret /= 2; /* try to copy partially */ - lret = ImmGetDescriptionW(hkl, descW, ret + 1); - ok(lret, "ImmGetDescriptionW failed, expected != 0 received 0.\n"); - ok(lret == ret, "ImmGetDescriptionW failed to return the correct amount of data. Expected %d, got %d.\n", ret, lret); - - lret = ImmGetDescriptionA(hkl, descA, ret + 1); - ok(!lret, "ImmGetDescriptionA should fail\n"); - - ret = ImmGetDescriptionW(hkl, descW, 1); - ok(!ret, "ImmGetDescriptionW failed, expected 0 received %d.\n", ret); - - UnloadKeyboardLayout(hkl); -} - static LRESULT (WINAPI *old_imm_wnd_proc)(HWND, UINT, WPARAM, LPARAM); static LRESULT WINAPI imm_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { @@ -2794,6 +2739,85 @@ static void test_ImmInstallIME(void) ime_cleanup( hkl ); }
+static void test_ImmGetDescription(void) +{ + HKL hkl = GetKeyboardLayout( 0 ); + WCHAR bufferW[MAX_PATH]; + char bufferA[MAX_PATH]; + DWORD ret; + + SetLastError( 0xdeadbeef ); + ret = ImmGetDescriptionW( NULL, NULL, 0 ); + ok( !ret, "ImmGetDescriptionW returned %lu\n", ret ); + ret = ImmGetDescriptionA( NULL, NULL, 0 ); + ok( !ret, "ImmGetDescriptionA returned %lu\n", ret ); + ret = ImmGetDescriptionW( NULL, NULL, 100 ); + ok( !ret, "ImmGetDescriptionW returned %lu\n", ret ); + ret = ImmGetDescriptionA( NULL, NULL, 100 ); + ok( !ret, "ImmGetDescriptionA returned %lu\n", ret ); + ret = ImmGetDescriptionW( hkl, bufferW, 100 ); + todo_wine + ok( !ret, "ImmGetDescriptionW returned %lu\n", ret ); + ret = ImmGetDescriptionA( hkl, bufferA, 100 ); + todo_wine + ok( !ret, "ImmGetDescriptionA returned %lu\n", ret ); + ret = GetLastError(); + ok( ret == 0xdeadbeef, "got error %lu\n", ret ); + + if (!(hkl = ime_install())) return; + + memset( bufferW, 0xcd, sizeof(bufferW) ); + ret = ImmGetDescriptionW( hkl, bufferW, 2 ); + ok( ret == 1, "ImmGetDescriptionW returned %lu\n", ret ); + ok( !wcscmp( bufferW, L"W" ), "got bufferW %s\n", debugstr_w(bufferW) ); + memset( bufferA, 0xcd, sizeof(bufferA) ); + ret = ImmGetDescriptionA( hkl, bufferA, 2 ); + ok( ret == 0, "ImmGetDescriptionA returned %lu\n", ret ); + todo_wine + ok( !strcmp( bufferA, "" ), "got bufferA %s\n", debugstr_a(bufferA) ); + + memset( bufferW, 0xcd, sizeof(bufferW) ); + ret = ImmGetDescriptionW( hkl, bufferW, 11 ); + todo_wine + ok( ret == 10, "ImmGetDescriptionW returned %lu\n", ret ); + todo_wine + ok( !wcscmp( bufferW, L"WineTest I" ), "got bufferW %s\n", debugstr_w(bufferW) ); + memset( bufferA, 0xcd, sizeof(bufferA) ); + ret = ImmGetDescriptionA( hkl, bufferA, 11 ); + todo_wine + ok( ret == 0, "ImmGetDescriptionA returned %lu\n", ret ); + todo_wine + ok( !strcmp( bufferA, "" ), "got bufferA %s\n", debugstr_a(bufferA) ); + + memset( bufferW, 0xcd, sizeof(bufferW) ); + ret = ImmGetDescriptionW( hkl, bufferW, 12 ); + todo_wine + ok( ret == 11, "ImmGetDescriptionW returned %lu\n", ret ); + todo_wine + ok( !wcscmp( bufferW, L"WineTest IM" ), "got bufferW %s\n", debugstr_w(bufferW) ); + memset( bufferA, 0xcd, sizeof(bufferA) ); + ret = ImmGetDescriptionA( hkl, bufferA, 12 ); + todo_wine + ok( ret == 12, "ImmGetDescriptionA returned %lu\n", ret ); + todo_wine + ok( !strcmp( bufferA, "WineTest IME" ), "got bufferA %s\n", debugstr_a(bufferA) ); + + memset( bufferW, 0xcd, sizeof(bufferW) ); + ret = ImmGetDescriptionW( hkl, bufferW, 13 ); + todo_wine + ok( ret == 12, "ImmGetDescriptionW returned %lu\n", ret ); + todo_wine + ok( !wcscmp( bufferW, L"WineTest IME" ), "got bufferW %s\n", debugstr_w(bufferW) ); + memset( bufferA, 0xcd, sizeof(bufferA) ); + ret = ImmGetDescriptionA( hkl, bufferA, 13 ); + todo_wine + ok( ret == 12, "ImmGetDescriptionA returned %lu\n", ret ); + todo_wine + ok( !strcmp( bufferA, "WineTest IME" ), "got bufferA %s\n", debugstr_a(bufferA) ); + + ime_cleanup( hkl ); +} + START_TEST(imm32) { if (!is_ime_enabled()) @@ -2805,6 +2829,7 @@ START_TEST(imm32) test_com_initialization();
test_ImmInstallIME(); + test_ImmGetDescription();
if (init()) { @@ -2817,7 +2842,6 @@ START_TEST(imm32) test_ImmThreads(); test_ImmIsUIMessage(); test_ImmGetContext(); - test_ImmGetDescription(); test_ImmDefaultHwnd(); test_default_ime_window_creation(); test_ImmGetIMCLockCount();
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 84 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index e259c8b2e22..b617283e922 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -2818,6 +2818,89 @@ static void test_ImmGetDescription(void) ime_cleanup( hkl ); }
+static void test_ImmGetIMEFileName(void) +{ + HKL hkl = GetKeyboardLayout( 0 ); + WCHAR bufferW[MAX_PATH], expectW[16]; + char bufferA[MAX_PATH], expectA[16]; + DWORD ret; + + SetLastError( 0xdeadbeef ); + ret = ImmGetIMEFileNameW( NULL, NULL, 0 ); + ok( !ret, "ImmGetIMEFileNameW returned %lu\n", ret ); + ret = ImmGetIMEFileNameA( NULL, NULL, 0 ); + ok( !ret, "ImmGetIMEFileNameA returned %lu\n", ret ); + ret = ImmGetIMEFileNameW( NULL, NULL, 100 ); + ok( !ret, "ImmGetIMEFileNameW returned %lu\n", ret ); + ret = ImmGetIMEFileNameA( NULL, NULL, 100 ); + ok( !ret, "ImmGetIMEFileNameA returned %lu\n", ret ); + ret = ImmGetIMEFileNameW( hkl, bufferW, 100 ); + ok( !ret, "ImmGetIMEFileNameW returned %lu\n", ret ); + ret = ImmGetIMEFileNameA( hkl, bufferA, 100 ); + ok( !ret, "ImmGetIMEFileNameA returned %lu\n", ret ); + ret = GetLastError(); + todo_wine + ok( ret == 0xdeadbeef, "got error %lu\n", ret ); + + if (!(hkl = ime_install())) return; + + memset( bufferW, 0xcd, sizeof(bufferW) ); + ret = ImmGetIMEFileNameW( hkl, bufferW, 2 ); + todo_wine + ok( ret == 1, "ImmGetIMEFileNameW returned %lu\n", ret ); + todo_wine + ok( !wcscmp( bufferW, L"W" ), "got bufferW %s\n", debugstr_w(bufferW) ); + memset( bufferA, 0xcd, sizeof(bufferA) ); + ret = ImmGetIMEFileNameA( hkl, bufferA, 2 ); + ok( ret == 0, "ImmGetIMEFileNameA returned %lu\n", ret ); + todo_wine + ok( !strcmp( bufferA, "" ), "got bufferA %s\n", debugstr_a(bufferA) ); + + swprintf( expectW, ARRAY_SIZE(expectW), L"WINE%04X.I", ime_count - 1 ); + memset( bufferW, 0xcd, sizeof(bufferW) ); + ret = ImmGetIMEFileNameW( hkl, bufferW, 11 ); + todo_wine + ok( ret == 10, "ImmGetIMEFileNameW returned %lu\n", ret ); + todo_wine + ok( !wcscmp( bufferW, expectW ), "got bufferW %s\n", debugstr_w(bufferW) ); + memset( bufferA, 0xcd, sizeof(bufferA) ); + ret = ImmGetIMEFileNameA( hkl, bufferA, 11 ); + ok( ret == 0, "ImmGetIMEFileNameA returned %lu\n", ret ); + todo_wine + ok( !strcmp( bufferA, "" ), "got bufferA %s\n", debugstr_a(bufferA) ); + + swprintf( expectW, ARRAY_SIZE(expectW), L"WINE%04X.IM", ime_count - 1 ); + memset( bufferW, 0xcd, sizeof(bufferW) ); + ret = ImmGetIMEFileNameW( hkl, bufferW, 12 ); + todo_wine + ok( ret == 11, "ImmGetIMEFileNameW returned %lu\n", ret ); + todo_wine + ok( !wcscmp( bufferW, expectW ), "got bufferW %s\n", debugstr_w(bufferW) ); + snprintf( expectA, ARRAY_SIZE(expectA), "WINE%04X.IME", ime_count - 1 ); + memset( bufferA, 0xcd, sizeof(bufferA) ); + ret = ImmGetIMEFileNameA( hkl, bufferA, 12 ); + todo_wine + ok( ret == 12, "ImmGetIMEFileNameA returned %lu\n", ret ); + todo_wine + ok( !strcmp( bufferA, expectA ), "got bufferA %s\n", debugstr_a(bufferA) ); + + swprintf( expectW, ARRAY_SIZE(expectW), L"WINE%04X.IME", ime_count - 1 ); + memset( bufferW, 0xcd, sizeof(bufferW) ); + ret = ImmGetIMEFileNameW( hkl, bufferW, 13 ); + todo_wine + ok( ret == 12, "ImmGetIMEFileNameW returned %lu\n", ret ); + todo_wine + ok( !wcscmp( bufferW, expectW ), "got bufferW %s\n", debugstr_w(bufferW) ); + memset( bufferA, 0xcd, sizeof(bufferA) ); + ret = ImmGetIMEFileNameA( hkl, bufferA, 13 ); + todo_wine + ok( ret == 12, "ImmGetIMEFileNameA returned %lu\n", ret ); + todo_wine + ok( !strcmp( bufferA, expectA ), "got bufferA %s\n", debugstr_a(bufferA) ); + + ime_cleanup( hkl ); +} + START_TEST(imm32) { if (!is_ime_enabled()) @@ -2830,6 +2913,7 @@ START_TEST(imm32)
test_ImmInstallIME(); test_ImmGetDescription(); + test_ImmGetIMEFileName();
if (init()) {
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=130368
Your paranoid android.
=== debian11 (32 bit report) ===
user32: win.c:10980: Test failed: GetForegroundWindow() = 00570144