Unicode version of DdeCreateStringHandle should ignore codepage parameter

Dmitry Timoshkov dmitry at baikal.ru
Fri Apr 23 02:24:16 CDT 2004


Hello,

an actual fault was caused by a recent ShellExecute unicodification,
DDE code was (almost) correct.

Here is a more correct fix for the problem with a test case.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Fix a bug in ShellExecute which called DdeCreateStringHandleW
    with a wrong parameter. Revert previous erroneous fix.

diff -u cvs/hq/wine/dlls/shell32/shlexec.c wine/dlls/shell32/shlexec.c
--- cvs/hq/wine/dlls/shell32/shlexec.c	2004-04-23 16:07:38.000000000 +0900
+++ wine/dlls/shell32/shlexec.c	2004-04-23 16:09:06.000000000 +0900
@@ -766,8 +766,8 @@ static unsigned dde_connect(WCHAR* key, 
         return 2;
     }
 
-    hszApp = DdeCreateStringHandleW(ddeInst, app, CP_WINANSI);
-    hszTopic = DdeCreateStringHandleW(ddeInst, topic, CP_WINANSI);
+    hszApp = DdeCreateStringHandleW(ddeInst, app, CP_WINUNICODE);
+    hszTopic = DdeCreateStringHandleW(ddeInst, topic, CP_WINUNICODE);
 
     hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
     exec = ddeexec;
diff -u cvs/hq/wine/dlls/user/dde/misc.c wine/dlls/user/dde/misc.c
--- cvs/hq/wine/dlls/user/dde/misc.c	2004-04-23 16:07:38.000000000 +0900
+++ wine/dlls/user/dde/misc.c	2004-04-23 16:09:06.000000000 +0900
@@ -511,7 +511,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PF
 
 	if (WDML_InstanceList == NULL)
 	{
-	    ret = DMLERR_DLL_USAGE;
+	    ret = DMLERR_INVALIDPARAMETER;
 	    goto theError;
 	}
 	HeapFree(GetProcessHeap(), 0, pInstance); /* finished - release heap space used as work store */
@@ -536,7 +536,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PF
 
 			if (!(afCmd & APPCMD_CLIENTONLY))
 			{
-			    ret = DMLERR_DLL_USAGE;
+			    ret = DMLERR_INVALIDPARAMETER;
 			    goto theError;
 			}
 		    }
@@ -545,7 +545,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PF
 
 		if (pInstance->monitor != reference_inst->monitor)
 		{
-		    ret = DMLERR_DLL_USAGE;
+		    ret = DMLERR_INVALIDPARAMETER;
 		    goto theError;
 		}
 
@@ -553,7 +553,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PF
 
 		if ((afCmd&APPCMD_CLIENTONLY) && !reference_inst->clientOnly)
 		{
-		    ret = DMLERR_DLL_USAGE;
+		    ret = DMLERR_INVALIDPARAMETER;
 		    goto theError;
 		}
 		break;
@@ -562,10 +562,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PF
 	}
 	if (reference_inst->next == NULL)
 	{
-	    /* Crazy situation - trying to re-initialize something that has not beeen initialized !!
-	     *
-	     *	Manual does not say what we do, cannot return DMLERR_NOT_INITIALIZED so what ?
-	     */
 	    ret = DMLERR_INVALIDPARAMETER;
 	    goto theError;
 	}
@@ -794,8 +790,6 @@ UINT WINAPI DdeGetLastError(DWORD idInst
     DWORD		error_code;
     WDML_INSTANCE*	pInstance;
 
-    FIXME("(%ld): error reporting is weakly implemented\n", idInst);
-
     EnterCriticalSection(&WDML_CritSect);
 
     /*  First check instance
@@ -803,7 +797,7 @@ UINT WINAPI DdeGetLastError(DWORD idInst
     pInstance = WDML_GetInstance(idInst);
     if  (pInstance == NULL)
     {
-	error_code = DMLERR_DLL_NOT_INITIALIZED;
+	error_code = DMLERR_INVALIDPARAMETER;
     }
     else
     {
@@ -1004,6 +998,7 @@ static int	WDML_QueryString(WDML_INSTANC
 	break;
     case CP_WINUNICODE:
 	ret = GetAtomNameW(HSZ2ATOM(hsz), ptr, cchMax);
+        break;
     default:
 	ERR("Unknown code page %d\n", codepage);
 	ret = 0;
@@ -1141,8 +1136,10 @@ HSZ WINAPI DdeCreateStringHandleW(DWORD 
 
     pInstance = WDML_GetInstance(idInst);
     if (pInstance)
-        hsz = WDML_CreateString(pInstance, psz, CP_WINUNICODE);
-
+    {
+	if (codepage == 0) codepage = CP_WINUNICODE;
+	hsz = WDML_CreateString(pInstance, psz, codepage);
+    }
     LeaveCriticalSection(&WDML_CritSect);
 
     return hsz;
diff -u /dev/null wine/dlls/user/tests/dde.c
--- /dev/null	2003-01-30 18:24:37.000000000 +0800
+++ wine/dlls/user/tests/dde.c	2004-04-23 16:09:06.000000000 +0900
@@ -0,0 +1,119 @@
+/*
+ * Unit tests for DDE functions
+ *
+ * Copyright (c) 2004 Dmitry Timoshkov
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+
+#include "wine/test.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "ddeml.h"
+#include "winerror.h"
+
+static HDDEDATA CALLBACK DdeCallback(UINT uType, UINT uFmt, HCONV hconv,
+                                     HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
+                                     ULONG_PTR dwData1, ULONG_PTR dwData2)
+{
+    return 0;
+}
+
+static void test_DdeCreateStringHandleW(DWORD dde_inst, int codepage)
+{
+    static const WCHAR dde_string[] = {'D','D','E',' ','S','t','r','i','n','g',0};
+    HSZ str_handle;
+    WCHAR bufW[256];
+    char buf[256];
+    int ret;
+
+    str_handle = DdeCreateStringHandleW(dde_inst, dde_string, codepage);
+    ok(str_handle != 0, "DdeCreateStringHandleW failed with error %08x\n",
+       DdeGetLastError(dde_inst));
+
+    ret = DdeQueryStringW(dde_inst, str_handle, NULL, 0, codepage);
+    if (codepage == CP_WINANSI)
+        ok(ret == 1, "DdeQueryStringW returned wrong length %d\n", ret);
+    else
+        ok(ret == lstrlenW(dde_string), "DdeQueryStringW returned wrong length %d\n", ret);
+
+    ret = DdeQueryStringW(dde_inst, str_handle, bufW, 256, codepage);
+    if (codepage == CP_WINANSI)
+    {
+        ok(ret == 1, "DdeQueryStringW returned wrong length %d\n", ret);
+        ok(!lstrcmpA("D", (LPCSTR)bufW), "DdeQueryStringW returned wrong string\n");
+    }
+    else
+    {
+        ok(ret == lstrlenW(dde_string), "DdeQueryStringW returned wrong length %d\n", ret);
+        ok(!lstrcmpW(dde_string, bufW), "DdeQueryStringW returned wrong string\n");
+    }
+
+    ret = DdeQueryStringA(dde_inst, str_handle, buf, 256, CP_WINANSI);
+    if (codepage == CP_WINANSI)
+    {
+        ok(ret == 1, "DdeQueryStringA returned wrong length %d\n", ret);
+        ok(!lstrcmpA("D", buf), "DdeQueryStringW returned wrong string\n");
+    }
+    else
+    {
+        ok(ret == lstrlenA("DDE String"), "DdeQueryStringA returned wrong length %d\n", ret);
+        ok(!lstrcmpA("DDE String", buf), "DdeQueryStringA returned wrong string %s\n", buf);
+    }
+
+    ret = DdeQueryStringA(dde_inst, str_handle, buf, 256, CP_WINUNICODE);
+    if (codepage == CP_WINANSI)
+    {
+        ok(ret == 1, "DdeQueryStringA returned wrong length %d\n", ret);
+        ok(!lstrcmpA("D", buf), "DdeQueryStringA returned wrong string %s\n", buf);
+    }
+    else
+    {
+        ok(ret == lstrlenA("DDE String"), "DdeQueryStringA returned wrong length %d\n", ret);
+        ok(!lstrcmpW(dde_string, (LPCWSTR)buf), "DdeQueryStringW returned wrong string\n");
+    }
+
+    ok(DdeFreeStringHandle(dde_inst, str_handle), "DdeFreeStringHandle failed\n");
+}
+
+START_TEST(dde)
+{
+    DWORD dde_inst, ret;
+
+    dde_inst = 0xdeadbeef;
+    SetLastError(0xdeadbeef);
+    ret = DdeInitializeW(&dde_inst, DdeCallback, APPCMD_CLIENTONLY, 0);
+    if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+    {
+        trace("Skipping the DDE test on a Win9x platform\n");
+        return;
+    }
+
+    ok(ret == DMLERR_INVALIDPARAMETER, "DdeInitializeW should fail, but got %04lx instead\n", ret);
+    ok(DdeGetLastError(dde_inst) == DMLERR_INVALIDPARAMETER, "expected DMLERR_INVALIDPARAMETER\n");
+
+    dde_inst = 0;
+    ret = DdeInitializeW(&dde_inst, DdeCallback, APPCMD_CLIENTONLY, 0);
+    ok(ret == DMLERR_NO_ERROR, "DdeInitializeW failed with error %04lx (%08x)\n",
+       ret, DdeGetLastError(dde_inst));
+
+    test_DdeCreateStringHandleW(dde_inst, 0);
+    test_DdeCreateStringHandleW(dde_inst, CP_WINUNICODE);
+    test_DdeCreateStringHandleW(dde_inst, CP_WINANSI);
+
+    ok(DdeUninitialize(dde_inst), "DdeUninitialize failed\n");
+}
diff -u cvs/hq/wine/dlls/user/tests/Makefile.in wine/dlls/user/tests/Makefile.in
--- cvs/hq/wine/dlls/user/tests/Makefile.in	2004-02-12 15:35:47.000000000 +0800
+++ wine/dlls/user/tests/Makefile.in	2004-04-23 16:09:59.000000000 +0900
@@ -7,6 +7,7 @@ IMPORTS   = user32 gdi32 advapi32
 
 CTESTS = \
 	class.c \
+	dde.c \
 	dialog.c \
 	generated.c \
 	input.c \






More information about the wine-patches mailing list