Commit b2de316f authored by Alexandre Julliard's avatar Alexandre Julliard

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

parent f83bc2e5
...@@ -29,9 +29,11 @@ ...@@ -29,9 +29,11 @@
#include "winbase.h" #include "winbase.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winnls.h"
#include "dde.h" #include "dde.h"
#include "ddeml.h" #include "ddeml.h"
#include "win.h" #include "win.h"
#include "wine/unicode.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "dde_private.h" #include "dde_private.h"
...@@ -756,6 +758,54 @@ static WDML_XACT* WDML_ServerQueueExecute(WDML_CONV* pConv, LPARAM lParam) ...@@ -756,6 +758,54 @@ static WDML_XACT* WDML_ServerQueueExecute(WDML_CONV* pConv, LPARAM lParam)
return pXAct; 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 * WDML_ServerHandleExecute
* *
...@@ -769,11 +819,16 @@ static WDML_QUEUE_STATE WDML_ServerHandleExecute(WDML_CONV* pConv, WDML_XACT* pX ...@@ -769,11 +819,16 @@ static WDML_QUEUE_STATE WDML_ServerHandleExecute(WDML_CONV* pConv, WDML_XACT* pX
if (!(pConv->instance->CBFflags & CBF_FAIL_EXECUTES)) if (!(pConv->instance->CBFflags & CBF_FAIL_EXECUTES))
{ {
LPVOID ptr = GlobalLock(pXAct->hMem); LPVOID ptr = GlobalLock(pXAct->hMem);
DWORD size = GlobalSize(pXAct->hMem);
if (ptr) if (ptr)
{ {
hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, ptr, GlobalSize(pXAct->hMem), if (pConv->instance->unicode) /* Unicode server, try to map A->W */
0, 0, CF_TEXT, 0); 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); GlobalUnlock(pXAct->hMem);
} }
hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_EXECUTE, 0, (HCONV)pConv, hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_EXECUTE, 0, (HCONV)pConv,
......
...@@ -2486,11 +2486,9 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV ...@@ -2486,11 +2486,9 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV
case 0: /* ASCII string */ case 0: /* ASCII string */
if (unicode_server) 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(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), 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); "Expected %s, msg_index=%d\n", wine_dbgstr_w(test_cmd_a_to_w), msg_index);
}
} }
else if (unicode_client) else if (unicode_client)
{ {
...@@ -2519,7 +2517,7 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV ...@@ -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", 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); 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", ok(size == size_w_to_a, "Wrong size %d/%d, msg_index=%d\n",
size, size_w_to_a, msg_index); size, size_w_to_a, msg_index);
...@@ -2531,7 +2529,7 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV ...@@ -2531,7 +2529,7 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV
case 2: /* normal Unicode string */ case 2: /* normal Unicode string */
case 3: /* IsTextUnicode false negative */ case 3: /* IsTextUnicode false negative */
case 4: /* Chinese chars */ case 4: /* Chinese chars */
if (unicode_server) todo_wine if (unicode_server)
{ {
/* double A->W mapping */ /* double A->W mapping */
/* NT uses the full size, XP+ only until the first null */ /* NT uses the full size, XP+ only until the first null */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment