Hello, This is a follow up of http://www.winehq.org/pipermail/wine-devel/2013-July/100459.html ( [PATCH] imm32: Fixed crashing in ImmGetIMCCSize. )
I believe the attached patchset is the correct fix for the Office crashing bug, how ever, I'm looking for a more graceful way to improve ImmCreateContext and other IMC functions, I appreciate to any feedback on the patches especially Patch 6/6. My tests show that Windows return a HGLOBAL hmem for ImmCreateIMCC() as the returned HIMCC, so it is easy to re-implement ImmCreateIMCC in a graceful way. However, Windows return a magic number for ImmCreateContext, (for instance, have a look at 000B01D9 in the test show in https://testbot.winehq.org/JobDetails.pl?Key=26619&log_207=1#k207) I have no idea how that magic number comes, while I understand there is no need to re-implement ImmCreateContext in the same way as Windows does, I'm still interesting in a more beautiful implementation like my ImmCreateIMCC reached, get rid of casting InputContextData to HIMC if possible. Thanks in advance for any suggestions! If there is no better way, I'll send this series to wine-patches. -- Regards, Qian Hong - http://www.winehq.org
From 8ef24f0fc1c962aa69ac2a1baec197abe3523068 Mon Sep 17 00:00:00 2001 From: Qian Hong <qh...@codeweavers.com> Date: Mon, 5 Aug 2013 23:17:38 +0800 Subject: [PATCH 1/6] imm32/tests: Added more IMCC lock count tests. To: wine-patches <wine-patc...@winehq.org> Reply-To: wine-devel <wine-devel@winehq.org> Cc: Qian Hong<qh...@codeweavers.com> --- dlls/imm32/tests/imm32.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 26101a4..2cdc662 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -715,7 +715,8 @@ static void test_ImmGetIMCLockCount(void) static void test_ImmGetIMCCLockCount(void) { HIMCC imcc; - DWORD count, ret; + DWORD count, g_count, ret, i; + VOID *p; imcc = ImmCreateIMCC(sizeof(CANDIDATEINFO)); count = ImmGetIMCCLockCount(imcc); @@ -731,6 +732,28 @@ static void test_ImmGetIMCCLockCount(void) ok(ret == FALSE, "expect FALSE, ret %d\n", ret); count = ImmGetIMCCLockCount(imcc); ok(count == 0, "expect 0, returned %d\n", count); + + p = ImmLockIMCC(imcc); + todo_wine ok(GlobalHandle(p) == imcc, "expect %p, returned %p\n", imcc, GlobalHandle(p)); + + for (i = 0; i < GMEM_LOCKCOUNT * 2; i++) + { + ImmLockIMCC(imcc); + count = ImmGetIMCCLockCount(imcc); + g_count = GlobalFlags(imcc) & GMEM_LOCKCOUNT; + todo_wine ok(count == g_count, "count %d, g_count %d\n", count, g_count); + } + count = ImmGetIMCCLockCount(imcc); + todo_wine ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count); + + for (i = 0; i < GMEM_LOCKCOUNT - 1; i++) + GlobalUnlock(imcc); + count = ImmGetIMCCLockCount(imcc); + todo_wine ok(count == 1, "expect 1, returned %d\n", count); + GlobalUnlock(imcc); + count = ImmGetIMCCLockCount(imcc); + todo_wine ok(count == 0, "expect 0, returned %d\n", count); + ImmDestroyIMCC(imcc); } -- 1.7.9.5
From 45a80c8cd1d0cb2dfa3d5afaadbfd22f41ee5cef Mon Sep 17 00:00:00 2001 From: Qian Hong <qh...@codeweavers.com> Date: Mon, 5 Aug 2013 23:56:37 +0800 Subject: [PATCH 2/6] imm32/tests: Added tests for ImmDestroyIMCC. To: wine-patches <wine-patc...@winehq.org> Reply-To: wine-devel <wine-devel@winehq.org> Cc: Qian Hong<qh...@codeweavers.com> --- dlls/imm32/tests/imm32.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 2cdc662..6965d5f 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -757,6 +757,38 @@ static void test_ImmGetIMCCLockCount(void) ImmDestroyIMCC(imcc); } +static void test_ImmDestroyIMCC(void) +{ + HIMCC imcc; + DWORD ret, count, size; + VOID *p; + + imcc = ImmCreateIMCC(sizeof(CANDIDATEINFO)); + count = ImmGetIMCCLockCount(imcc); + ok(count == 0, "expect 0, returned %d\n", count); + p = ImmLockIMCC(imcc); + ok(p != NULL, "ImmLockIMCC failed!\n"); + count = ImmGetIMCCLockCount(imcc); + ok(count == 1, "expect 1, returned %d\n", count); + size = ImmGetIMCCSize(imcc); + ok(size == sizeof(CANDIDATEINFO), "expect %d, returned %d\n", sizeof(CANDIDATEINFO), size); + p = ImmDestroyIMCC(imcc); + ok(p == NULL, "Destroy an locked IMCC should success!\n"); + p = ImmLockIMCC(imcc); + todo_wine ok(p == NULL, "Lock a destroyed IMCC should fail!\n"); + ret = ImmUnlockIMCC(imcc); + todo_wine ok(ret == FALSE, "Unlock a destroyed IMCC should return FALSE!\n"); + count = ImmGetIMCCLockCount(imcc); + todo_wine ok(count == 0, "Get lock count of a destroyed IMCC should return 0!\n"); + size = ImmGetIMCCSize(imcc); + todo_wine ok(size == 0, "Get size of a destroyed IMCC should return 0!\n"); + SetLastError(0xdeadbeef); + p = ImmDestroyIMCC(imcc); + todo_wine ok(p != NULL, "returned NULL\n"); + ret = GetLastError(); + todo_wine ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret); +} + static void test_ImmMessages(void) { CANDIDATEFORM cf; @@ -918,6 +950,7 @@ START_TEST(imm32) { test_ImmDefaultHwnd(); test_ImmGetIMCLockCount(); test_ImmGetIMCCLockCount(); + test_ImmDestroyIMCC(); msg_spy_cleanup(); /* Reinitialize the hooks to capture all windows */ msg_spy_init(NULL); -- 1.7.9.5
From 5343cc57be7ea86ee0efc238d6609a60a98c4621 Mon Sep 17 00:00:00 2001 From: Qian Hong <qh...@codeweavers.com> Date: Tue, 6 Aug 2013 00:08:36 +0800 Subject: [PATCH 3/6] imm32: Fixed IMCC implementation. To: wine-patches <wine-patc...@winehq.org> Reply-To: wine-devel <wine-devel@winehq.org> Cc: Qian Hong<qh...@codeweavers.com> --- dlls/imm32/imm.c | 52 +++++++--------------------------------------- dlls/imm32/tests/imm32.c | 22 ++++++++++---------- 2 files changed, 18 insertions(+), 56 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 5aee6ea..bc7caba 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -37,12 +37,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm); -typedef struct tagIMCCInternal -{ - DWORD dwLock; - DWORD dwSize; -} IMCCInternal; - #define MAKE_FUNCPTR(f) typeof(f) * p##f typedef struct _tagImmHkl{ struct list entry; @@ -2625,15 +2619,7 @@ DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC) */ HIMCC WINAPI ImmCreateIMCC(DWORD size) { - IMCCInternal *internal; - int real_size = size + sizeof(IMCCInternal); - - internal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, real_size); - if (internal == NULL) - return NULL; - - internal->dwSize = size; - return internal; + return GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE, size); } /*********************************************************************** @@ -2641,8 +2627,7 @@ HIMCC WINAPI ImmCreateIMCC(DWORD size) */ HIMCC WINAPI ImmDestroyIMCC(HIMCC block) { - HeapFree(GetProcessHeap(),0,block); - return NULL; + return GlobalFree(block); } /*********************************************************************** @@ -2650,11 +2635,7 @@ HIMCC WINAPI ImmDestroyIMCC(HIMCC block) */ LPVOID WINAPI ImmLockIMCC(HIMCC imcc) { - IMCCInternal *internal; - internal = imcc; - - internal->dwLock ++; - return internal + 1; + return GlobalLock(imcc); } /*********************************************************************** @@ -2662,12 +2643,7 @@ LPVOID WINAPI ImmLockIMCC(HIMCC imcc) */ BOOL WINAPI ImmUnlockIMCC(HIMCC imcc) { - IMCCInternal *internal; - internal = imcc; - - if (internal->dwLock) - internal->dwLock --; - return (internal->dwLock!=0); + return GlobalUnlock(imcc); } /*********************************************************************** @@ -2675,10 +2651,7 @@ BOOL WINAPI ImmUnlockIMCC(HIMCC imcc) */ DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc) { - IMCCInternal *internal; - internal = imcc; - - return internal->dwLock; + return GlobalFlags(imcc) & GMEM_LOCKCOUNT; } /*********************************************************************** @@ -2686,15 +2659,7 @@ DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc) */ HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size) { - IMCCInternal *internal,*newone; - int real_size = size + sizeof(IMCCInternal); - - internal = imcc; - - newone = HeapReAlloc(GetProcessHeap(), 0, internal, real_size); - newone->dwSize = size; - - return newone; + return GlobalReAlloc(imcc, size, GMEM_ZEROINIT | GMEM_MOVEABLE); } /*********************************************************************** @@ -2702,10 +2667,7 @@ HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size) */ DWORD WINAPI ImmGetIMCCSize(HIMCC imcc) { - IMCCInternal *internal; - internal = imcc; - - return internal->dwSize; + return GlobalSize(imcc); } /*********************************************************************** diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 6965d5f..e6bb68a 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -734,25 +734,25 @@ static void test_ImmGetIMCCLockCount(void) ok(count == 0, "expect 0, returned %d\n", count); p = ImmLockIMCC(imcc); - todo_wine ok(GlobalHandle(p) == imcc, "expect %p, returned %p\n", imcc, GlobalHandle(p)); + ok(GlobalHandle(p) == imcc, "expect %p, returned %p\n", imcc, GlobalHandle(p)); for (i = 0; i < GMEM_LOCKCOUNT * 2; i++) { ImmLockIMCC(imcc); count = ImmGetIMCCLockCount(imcc); g_count = GlobalFlags(imcc) & GMEM_LOCKCOUNT; - todo_wine ok(count == g_count, "count %d, g_count %d\n", count, g_count); + ok(count == g_count, "count %d, g_count %d\n", count, g_count); } count = ImmGetIMCCLockCount(imcc); - todo_wine ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count); + ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count); for (i = 0; i < GMEM_LOCKCOUNT - 1; i++) GlobalUnlock(imcc); count = ImmGetIMCCLockCount(imcc); - todo_wine ok(count == 1, "expect 1, returned %d\n", count); + ok(count == 1, "expect 1, returned %d\n", count); GlobalUnlock(imcc); count = ImmGetIMCCLockCount(imcc); - todo_wine ok(count == 0, "expect 0, returned %d\n", count); + ok(count == 0, "expect 0, returned %d\n", count); ImmDestroyIMCC(imcc); } @@ -775,18 +775,18 @@ static void test_ImmDestroyIMCC(void) p = ImmDestroyIMCC(imcc); ok(p == NULL, "Destroy an locked IMCC should success!\n"); p = ImmLockIMCC(imcc); - todo_wine ok(p == NULL, "Lock a destroyed IMCC should fail!\n"); + ok(p == NULL, "Lock a destroyed IMCC should fail!\n"); ret = ImmUnlockIMCC(imcc); - todo_wine ok(ret == FALSE, "Unlock a destroyed IMCC should return FALSE!\n"); + ok(ret == FALSE, "Unlock a destroyed IMCC should return FALSE!\n"); count = ImmGetIMCCLockCount(imcc); - todo_wine ok(count == 0, "Get lock count of a destroyed IMCC should return 0!\n"); + ok(count == 0, "Get lock count of a destroyed IMCC should return 0!\n"); size = ImmGetIMCCSize(imcc); - todo_wine ok(size == 0, "Get size of a destroyed IMCC should return 0!\n"); + ok(size == 0, "Get size of a destroyed IMCC should return 0!\n"); SetLastError(0xdeadbeef); p = ImmDestroyIMCC(imcc); - todo_wine ok(p != NULL, "returned NULL\n"); + ok(p != NULL, "returned NULL\n"); ret = GetLastError(); - todo_wine ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret); + ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret); } static void test_ImmMessages(void) -- 1.7.9.5
From 2d2e2d7387816145c7d1ef30a6ac18ea713fcc90 Mon Sep 17 00:00:00 2001 From: Qian Hong <qh...@codeweavers.com> Date: Mon, 5 Aug 2013 23:21:44 +0800 Subject: [PATCH 4/6] imm32/tests: Added more IMC lock count tests. To: wine-patches <wine-patc...@winehq.org> Reply-To: wine-devel <wine-devel@winehq.org> Cc: Qian Hong<qh...@codeweavers.com> --- dlls/imm32/tests/imm32.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index e6bb68a..2d446d8 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -691,7 +691,7 @@ static void test_ImmDefaultHwnd(void) static void test_ImmGetIMCLockCount(void) { HIMC imc; - DWORD count, ret; + DWORD count, ret, i; INPUTCONTEXT *ic; imc = ImmCreateContext(); @@ -709,6 +709,23 @@ static void test_ImmGetIMCLockCount(void) ok(ret == TRUE, "expect TRUE, ret %d\n", ret); count = ImmGetIMCLockCount(imc); ok(count == 0, "expect 0, returned %d\n", count); + + for (i = 0; i < GMEM_LOCKCOUNT * 2; i++) + { + ic = ImmLockIMC(imc); + ok(ic != NULL, "ImmLockIMC failed!\n"); + } + count = ImmGetIMCLockCount(imc); + todo_wine ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count); + + for (i = 0; i < GMEM_LOCKCOUNT - 1; i++) + ImmUnlockIMC(imc); + count = ImmGetIMCLockCount(imc); + todo_wine ok(count == 1, "expect 1, returned %d\n", count); + ImmUnlockIMC(imc); + count = ImmGetIMCLockCount(imc); + todo_wine ok(count == 0, "expect 0, returned %d\n", count); + ImmDestroyContext(imc); } -- 1.7.9.5
From f26c1a6c5609519cce532758d8d7e524395fe224 Mon Sep 17 00:00:00 2001 From: Qian Hong <qh...@codeweavers.com> Date: Tue, 6 Aug 2013 00:34:56 +0800 Subject: [PATCH 5/6] imm32/tests: Added tests for ImmDestroyContext. To: wine-patches <wine-patc...@winehq.org> Reply-To: wine-devel <wine-devel@winehq.org> Cc: Qian Hong<qh...@codeweavers.com> --- dlls/imm32/tests/imm32.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 2d446d8..9b2aede 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -774,6 +774,34 @@ static void test_ImmGetIMCCLockCount(void) ImmDestroyIMCC(imcc); } +static void test_ImmDestroyContext(void) +{ + HIMC imc; + DWORD ret, count; + INPUTCONTEXT *ic; + + imc = ImmCreateContext(); + count = ImmGetIMCLockCount(imc); + ok(count == 0, "expect 0, returned %d\n", count); + ic = ImmLockIMC(imc); + ok(ic != NULL, "ImmLockIMC failed!\n"); + count = ImmGetIMCLockCount(imc); + ok(count == 1, "expect 1, returned %d\n", count); + ret = ImmDestroyContext(imc); + ok(ret == TRUE, "Destroy an locked IMC should success!\n"); + ic = ImmLockIMC(imc); + todo_wine ok(ic == NULL, "Lock a destroyed IMC should fail!\n"); + ret = ImmUnlockIMC(imc); + todo_wine ok(ret == FALSE, "Unlock a destroyed IMC should fail!\n"); + count = ImmGetIMCLockCount(imc); + todo_wine ok(count == 0, "Get lock count of a destroyed IMC should return 0!\n"); + SetLastError(0xdeadbeef); + ret = ImmDestroyContext(imc); + todo_wine ok(ret == FALSE, "Destroy a destroyed IMC should fail!\n"); + ret = GetLastError(); + todo_wine ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret); +} + static void test_ImmDestroyIMCC(void) { HIMCC imcc; @@ -967,6 +995,7 @@ START_TEST(imm32) { test_ImmDefaultHwnd(); test_ImmGetIMCLockCount(); test_ImmGetIMCCLockCount(); + test_ImmDestroyContext(); test_ImmDestroyIMCC(); msg_spy_cleanup(); /* Reinitialize the hooks to capture all windows */ -- 1.7.9.5
From 0ffa7576938bcc6adf6674f46d6bf3174fff0745 Mon Sep 17 00:00:00 2001 From: Qian Hong <qh...@codeweavers.com> Date: Tue, 6 Aug 2013 01:39:27 +0800 Subject: [PATCH 6/6] imm32: Improved IMC implementation. To: wine-patches <wine-patc...@winehq.org> Reply-To: wine-devel <wine-devel@winehq.org> Cc: Qian Hong<qh...@codeweavers.com> --- dlls/imm32/imm.c | 46 ++++++++++++++++++++++++---------------------- dlls/imm32/tests/imm32.c | 16 ++++++++-------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index bc7caba..d3f2167 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -69,7 +69,6 @@ typedef struct _tagImmHkl{ typedef struct tagInputContextData { - DWORD dwLock; INPUTCONTEXT IMC; ImmHkl *immKbd; @@ -615,8 +614,11 @@ HIMC WINAPI ImmCreateContext(void) InputContextData *new_context; LPGUIDELINE gl; LPCANDIDATEINFO ci; + HGLOBAL hmem; - new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData)); + hmem = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE, sizeof(InputContextData)); + new_context = GlobalLock(hmem); + GlobalUnlock(hmem); /* Load the IME */ new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0)); @@ -662,24 +664,24 @@ HIMC WINAPI ImmCreateContext(void) static BOOL IMM_DestroyContext(HIMC hIMC) { InputContextData *data = hIMC; + HGLOBAL hmem = GlobalHandle(data); - TRACE("Destroying %p\n",hIMC); + TRACE("Destroying %p\n", hIMC); - if (hIMC) - { - data->immKbd->uSelected --; - data->immKbd->pImeSelect(hIMC, FALSE); - SendMessageW(data->IMC.hWnd, WM_IME_SELECT, FALSE, (LPARAM)GetKeyboardLayout(0)); + if (!hmem) + return FALSE; - ImmDestroyIMCC(data->IMC.hCompStr); - ImmDestroyIMCC(data->IMC.hCandInfo); - ImmDestroyIMCC(data->IMC.hGuideLine); - ImmDestroyIMCC(data->IMC.hPrivate); - ImmDestroyIMCC(data->IMC.hMsgBuf); + data->immKbd->uSelected --; + data->immKbd->pImeSelect(hIMC, FALSE); + SendMessageW(data->IMC.hWnd, WM_IME_SELECT, FALSE, (LPARAM)GetKeyboardLayout(0)); - HeapFree(GetProcessHeap(),0,data); - } - return TRUE; + ImmDestroyIMCC(data->IMC.hCompStr); + ImmDestroyIMCC(data->IMC.hCandInfo); + ImmDestroyIMCC(data->IMC.hGuideLine); + ImmDestroyIMCC(data->IMC.hPrivate); + ImmDestroyIMCC(data->IMC.hMsgBuf); + + return (GlobalFree(hmem) == NULL); } /*********************************************************************** @@ -2587,10 +2589,8 @@ DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType, LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC) { InputContextData *data = hIMC; - - if (!data) + if (!GlobalLock(GlobalHandle(data))) return NULL; - data->dwLock++; return &data->IMC; } @@ -2600,8 +2600,10 @@ LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC) BOOL WINAPI ImmUnlockIMC(HIMC hIMC) { InputContextData *data = hIMC; - if (data->dwLock) - data->dwLock--; + HGLOBAL hmem = GlobalHandle(data); + if (!hmem) + return FALSE; + GlobalUnlock(hmem); return TRUE; } @@ -2611,7 +2613,7 @@ BOOL WINAPI ImmUnlockIMC(HIMC hIMC) DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC) { InputContextData *data = hIMC; - return data->dwLock; + return GlobalFlags(GlobalHandle(data)) & GMEM_LOCKCOUNT; } /*********************************************************************** diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 9b2aede..f82632b 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -716,15 +716,15 @@ static void test_ImmGetIMCLockCount(void) ok(ic != NULL, "ImmLockIMC failed!\n"); } count = ImmGetIMCLockCount(imc); - todo_wine ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count); + ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count); for (i = 0; i < GMEM_LOCKCOUNT - 1; i++) ImmUnlockIMC(imc); count = ImmGetIMCLockCount(imc); - todo_wine ok(count == 1, "expect 1, returned %d\n", count); + ok(count == 1, "expect 1, returned %d\n", count); ImmUnlockIMC(imc); count = ImmGetIMCLockCount(imc); - todo_wine ok(count == 0, "expect 0, returned %d\n", count); + ok(count == 0, "expect 0, returned %d\n", count); ImmDestroyContext(imc); } @@ -790,16 +790,16 @@ static void test_ImmDestroyContext(void) ret = ImmDestroyContext(imc); ok(ret == TRUE, "Destroy an locked IMC should success!\n"); ic = ImmLockIMC(imc); - todo_wine ok(ic == NULL, "Lock a destroyed IMC should fail!\n"); + ok(ic == NULL, "Lock a destroyed IMC should fail!\n"); ret = ImmUnlockIMC(imc); - todo_wine ok(ret == FALSE, "Unlock a destroyed IMC should fail!\n"); + ok(ret == FALSE, "Unlock a destroyed IMC should fail!\n"); count = ImmGetIMCLockCount(imc); - todo_wine ok(count == 0, "Get lock count of a destroyed IMC should return 0!\n"); + ok(count == 0, "Get lock count of a destroyed IMC should return 0!\n"); SetLastError(0xdeadbeef); ret = ImmDestroyContext(imc); - todo_wine ok(ret == FALSE, "Destroy a destroyed IMC should fail!\n"); + ok(ret == FALSE, "Destroy a destroyed IMC should fail!\n"); ret = GetLastError(); - todo_wine ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret); + ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret); } static void test_ImmDestroyIMCC(void) -- 1.7.9.5