Alexandre Julliard : user32: Add a heuristic for Unicode mappings of DDE data on the server side.

Alexandre Julliard julliard at winehq.org
Fri Jun 25 09:40:51 CDT 2010


Module: wine
Branch: master
Commit: b2de316fc59875a810cbe60e94e05e6c96836e95
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b2de316fc59875a810cbe60e94e05e6c96836e95

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jun 24 23:43:08 2010 +0200

user32: Add a heuristic for Unicode mappings of DDE data on the server side.

---

 dlls/user32/dde_server.c |   59 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/user32/tests/dde.c  |    6 +---
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/dlls/user32/dde_server.c b/dlls/user32/dde_server.c
index 2dc8ae8..0d62c49 100644
--- a/dlls/user32/dde_server.c
+++ b/dlls/user32/dde_server.c
@@ -29,9 +29,11 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
+#include "winnls.h"
 #include "dde.h"
 #include "ddeml.h"
 #include "win.h"
+#include "wine/unicode.h"
 #include "wine/debug.h"
 #include "dde_private.h"
 
@@ -756,6 +758,54 @@ static	WDML_XACT* WDML_ServerQueueExecute(WDML_CONV* pConv, LPARAM lParam)
     return pXAct;
 }
 
+static BOOL data_looks_unicode( const WCHAR *data, DWORD size )
+{
+    DWORD i;
+
+    if (size % sizeof(WCHAR)) return FALSE;
+    for (i = 0; i < size / sizeof(WCHAR); i++) if (data[i] > 255) return FALSE;
+    return TRUE;
+}
+
+/* convert data to Unicode, unless it looks like it's already Unicode */
+static HDDEDATA map_A_to_W( DWORD instance, void *ptr, DWORD size )
+{
+    HDDEDATA ret;
+    DWORD len;
+    const char *end;
+
+    if (!data_looks_unicode( ptr, size ))
+    {
+        if ((end = memchr( ptr, 0, size ))) size = end + 1 - (const char *)ptr;
+        len = MultiByteToWideChar( CP_ACP, 0, ptr, size, NULL, 0 );
+        ret = DdeCreateDataHandle( instance, NULL, len * sizeof(WCHAR), 0, 0, CF_TEXT, 0);
+        MultiByteToWideChar( CP_ACP, 0, ptr, size, (WCHAR *)DdeAccessData(ret, NULL), len );
+    }
+    else ret = DdeCreateDataHandle( instance, ptr, size, 0, 0, CF_TEXT, 0 );
+
+    return ret;
+}
+
+/* convert data to ASCII, unless it looks like it's not in Unicode format */
+static HDDEDATA map_W_to_A( DWORD instance, void *ptr, DWORD size )
+{
+    HDDEDATA ret;
+    DWORD len;
+    const WCHAR *end;
+
+    if (data_looks_unicode( ptr, size ))
+    {
+        size /= sizeof(WCHAR);
+        if ((end = memchrW( ptr, 0, size ))) size = end + 1 - (const WCHAR *)ptr;
+        len = WideCharToMultiByte( CP_ACP, 0, ptr, size, NULL, 0, NULL, NULL );
+        ret = DdeCreateDataHandle( instance, NULL, len, 0, 0, CF_TEXT, 0);
+        WideCharToMultiByte( CP_ACP, 0, ptr, size, (char *)DdeAccessData(ret, NULL), len, NULL, NULL );
+    }
+    else ret = DdeCreateDataHandle( instance, ptr, size, 0, 0, CF_TEXT, 0 );
+
+    return ret;
+}
+
  /******************************************************************
  *		WDML_ServerHandleExecute
  *
@@ -769,11 +819,16 @@ static	WDML_QUEUE_STATE WDML_ServerHandleExecute(WDML_CONV* pConv, WDML_XACT* pX
     if (!(pConv->instance->CBFflags & CBF_FAIL_EXECUTES))
     {
 	LPVOID	ptr = GlobalLock(pXAct->hMem);
+        DWORD size = GlobalSize(pXAct->hMem);
 
 	if (ptr)
 	{
-	    hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, ptr, GlobalSize(pXAct->hMem),
-					   0, 0, CF_TEXT, 0);
+            if (pConv->instance->unicode)  /* Unicode server, try to map A->W */
+                hDdeData = map_A_to_W( pConv->instance->instanceID, ptr, size );
+            else if (!IsWindowUnicode( pConv->hwndClient )) /* ASCII server and client, try to map W->A */
+                hDdeData = map_W_to_A( pConv->instance->instanceID, ptr, size );
+            else
+                hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, ptr, size, 0, 0, CF_TEXT, 0);
 	    GlobalUnlock(pXAct->hMem);
 	}
 	hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_EXECUTE, 0, (HCONV)pConv,
diff --git a/dlls/user32/tests/dde.c b/dlls/user32/tests/dde.c
index ce6d964..529c527 100644
--- a/dlls/user32/tests/dde.c
+++ b/dlls/user32/tests/dde.c
@@ -2486,11 +2486,9 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV
         case 0:  /* ASCII string */
             if (unicode_server)
             {
-                todo_wine {
                 ok(size == size_a_to_w, "Wrong size %d/%d, msg_index=%d\n", size, size_a_to_w, msg_index);
                 ok(!lstrcmpW((WCHAR*)buffer, test_cmd_a_to_w),
                    "Expected %s, msg_index=%d\n", wine_dbgstr_w(test_cmd_a_to_w), msg_index);
-                }
             }
             else if (unicode_client)
             {
@@ -2519,7 +2517,7 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV
                 ok(!lstrcmpA((CHAR*)buffer, test_cmd_w_to_a), "Expected %s, got %s, msg_index=%d\n",
                    test_cmd_w_to_a, buffer, msg_index);
             }
-            else todo_wine
+            else
             {
                 ok(size == size_w_to_a, "Wrong size %d/%d, msg_index=%d\n",
                    size, size_w_to_a, msg_index);
@@ -2531,7 +2529,7 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV
         case 2:  /* normal Unicode string */
         case 3:  /* IsTextUnicode false negative */
         case 4:  /* Chinese chars */
-            if (unicode_server) todo_wine
+            if (unicode_server)
             {
                 /* double A->W mapping */
                 /* NT uses the full size, XP+ only until the first null */




More information about the wine-cvs mailing list