Commit 87458a5c authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

Add DDE transaction test, make it pass under Wine.

parent 0e8e5c30
......@@ -341,7 +341,7 @@ static LRESULT CALLBACK WDML_EventProc(HWND hwndEvent, UINT uMsg, WPARAM wParam,
*
*/
UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes, BOOL b16)
DWORD afCmd, DWORD ulRes, BOOL bUnicode, BOOL b16)
{
WDML_INSTANCE* pInstance;
WDML_INSTANCE* reference_inst;
......@@ -376,6 +376,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
pInstance->instanceID = *pidInst; /* May need to add calling proc Id */
pInstance->threadID = GetCurrentThreadId();
pInstance->callback = *pfnCallback;
pInstance->unicode = bUnicode;
pInstance->win16 = b16;
pInstance->nodeList = NULL; /* node will be added later */
pInstance->monitorFlags = afCmd & MF_MASK;
......@@ -585,7 +586,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
UINT WINAPI DdeInitializeA(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes)
{
return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, FALSE);
return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, FALSE, FALSE);
}
/******************************************************************************
......@@ -605,7 +606,7 @@ UINT WINAPI DdeInitializeA(LPDWORD pidInst, PFNCALLBACK pfnCallback,
UINT WINAPI DdeInitializeW(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes)
{
return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, FALSE);
return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, TRUE, FALSE);
}
/*****************************************************************
......@@ -1919,7 +1920,7 @@ WDML_CONV* WDML_GetConv(HCONV hConv, BOOL checkConnected)
FIXME("found conv but ain't connected\n");
return NULL;
}
if (GetCurrentThreadId() != pConv->instance->threadID)
if (!pConv->instance || GetCurrentThreadId() != pConv->instance->threadID)
{
FIXME("wrong thread ID\n");
return NULL;
......@@ -2100,6 +2101,7 @@ static BOOL WDML_GetLocalConvInfo(WDML_CONV* pConv, CONVINFO* ci, DWORD id)
/******************************************************************
* DdeQueryConvInfo (USER32.@)
*
* FIXME: Set last DDE error on failure.
*/
UINT WINAPI DdeQueryConvInfo(HCONV hConv, DWORD id, PCONVINFO lpConvInfo)
{
......@@ -2118,18 +2120,20 @@ UINT WINAPI DdeQueryConvInfo(HCONV hConv, DWORD id, PCONVINFO lpConvInfo)
EnterCriticalSection(&WDML_CritSect);
pConv = WDML_GetConv(hConv, FALSE);
if (pConv != NULL && !WDML_GetLocalConvInfo(pConv, &ci, id))
if (pConv != NULL)
{
ret = 0;
if (!WDML_GetLocalConvInfo(pConv, &ci, id))
ret = 0;
}
else if ((ULONG_PTR)hConv & 1)
else
{
pConv = WDML_GetConv((HCONV)((ULONG_PTR)hConv & ~1), FALSE);
if (pConv != NULL)
{
FIXME("Request on remote conversation information is not implemented yet\n");
ret = 0;
}
if ((ULONG_PTR)hConv & 1)
{
pConv = WDML_GetConv((HCONV)((ULONG_PTR)hConv & ~1), FALSE);
if (pConv != NULL)
FIXME("Request on remote conversation information is not implemented yet\n");
}
ret = 0;
}
LeaveCriticalSection(&WDML_CritSect);
if (ret != 0)
......
......@@ -153,6 +153,7 @@ typedef struct tagWDML_INSTANCE
DWORD threadID; /* needed to keep instance linked to a unique thread */
BOOL monitor; /* have these two as full Booleans cos they'll be tested frequently */
BOOL clientOnly; /* bit wasteful of space but it will be faster */
BOOL unicode; /* Flag to indicate Win32 API used to initialise */
BOOL win16; /* flag to indicate Win16 API used to initialize */
HSZNode* nodeList; /* for cleaning upon exit */
PFNCALLBACK callback;
......@@ -196,7 +197,7 @@ extern WDML_SERVER* WDML_FindServer(WDML_INSTANCE* pInstance, HSZ hszService, HS
extern WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV* pConv, WDML_XACT* pXAct);
/* called both in DdeClientTransaction and server side. */
extern UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes, BOOL b16);
DWORD afCmd, DWORD ulRes, BOOL bUnicode, BOOL b16);
extern WDML_CONV* WDML_AddConv(WDML_INSTANCE* pInstance, WDML_SIDE side,
HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer);
extern void WDML_RemoveConv(WDML_CONV* pConv, WDML_SIDE side);
......@@ -242,8 +243,10 @@ static inline void WDML_ExtractAck(WORD status, DDEACK* da)
}
extern const WCHAR WDML_szEventClass[]; /* class of window for events (aka instance) */
extern const WCHAR WDML_szServerConvClass[]; /* class of window for server side conv */
extern const WCHAR WDML_szClientConvClass[]; /* class of window for client side conv */
extern const char WDML_szServerConvClassA[]; /* ANSI class of window for server side conv */
extern const WCHAR WDML_szServerConvClassW[]; /* unicode class of window for server side conv */
extern const char WDML_szClientConvClassA[]; /* ANSI class of window for client side conv */
extern const WCHAR WDML_szClientConvClassW[]; /* unicode class of window for client side conv */
#define WM_WDML_REGISTER (WM_USER + 0x200)
#define WM_WDML_UNREGISTER (WM_USER + 0x201)
......
......@@ -39,7 +39,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
static const WCHAR szServerNameClass[] = {'W','i','n','e','D','d','e','S','e','r','v','e','r','N','a','m','e',0};
const WCHAR WDML_szServerConvClass[] = {'W','i','n','e','D','d','e','S','e','r','v','e','r','C','o','n','v',0};
const char WDML_szServerConvClassA[] = "WineDdeServerConvA";
const WCHAR WDML_szServerConvClassW[] = {'W','i','n','e','D','d','e','S','e','r','v','e','r','C','o','n','v','W',0};
static LRESULT CALLBACK WDML_ServerNameProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK WDML_ServerConvProc(HWND, UINT, WPARAM, LPARAM);
......@@ -308,26 +309,53 @@ static WDML_CONV* WDML_CreateServerConv(WDML_INSTANCE* pInstance, HWND hwndClien
{
HWND hwndServerConv;
WDML_CONV* pConv;
WNDCLASSEXW wndclass;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = 0;
wndclass.lpfnWndProc = WDML_ServerConvProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 2 * sizeof(ULONG_PTR);
wndclass.hInstance = 0;
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = WDML_szServerConvClass;
wndclass.hIconSm = 0;
RegisterClassExW(&wndclass);
hwndServerConv = CreateWindowW(WDML_szServerConvClass, 0,
if (pInstance->unicode)
{
WNDCLASSEXW wndclass;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = 0;
wndclass.lpfnWndProc = WDML_ServerConvProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 2 * sizeof(ULONG_PTR);
wndclass.hInstance = 0;
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = WDML_szServerConvClassW;
wndclass.hIconSm = 0;
RegisterClassExW(&wndclass);
hwndServerConv = CreateWindowW(WDML_szServerConvClassW, 0,
WS_CHILD, 0, 0, 0, 0,
hwndServerName, 0, 0, 0);
}
else
{
WNDCLASSEXA wndclass;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = 0;
wndclass.lpfnWndProc = WDML_ServerConvProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 2 * sizeof(ULONG_PTR);
wndclass.hInstance = 0;
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = WDML_szServerConvClassA;
wndclass.hIconSm = 0;
RegisterClassExA(&wndclass);
hwndServerConv = CreateWindowA(WDML_szServerConvClassA, 0,
WS_CHILD, 0, 0, 0, 0,
hwndServerName, 0, 0, 0);
}
TRACE("Created convServer=%p (nameServer=%p) for instance=%08lx\n",
hwndServerConv, hwndServerName, pInstance->instanceID);
......@@ -396,7 +424,7 @@ static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM w
CONVCONTEXT cc;
CONVCONTEXT* pcc = NULL;
WDML_CONV* pConv;
WCHAR buf[256];
char buf[256];
if (GetWindowThreadProcessId(hwndClient, NULL) == GetWindowThreadProcessId(hwndServer, NULL) &&
WDML_GetInstanceFromWnd(hwndClient) == WDML_GetInstanceFromWnd(hwndServer))
......@@ -406,13 +434,15 @@ static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM w
/* FIXME: so far, we don't grab distant convcontext, so only check if remote is
* handled under DDEML, and if so build a default context
*/
if (GetClassNameW(hwndClient, buf, sizeof(buf)/sizeof(WCHAR)) &&
lstrcmpiW(buf, WDML_szClientConvClass) == 0)
if ((GetClassNameA(hwndClient, buf, sizeof(buf)) &&
lstrcmpiA(buf, WDML_szClientConvClassA) == 0) ||
(GetClassNameW(hwndClient, (LPWSTR)buf, sizeof(buf)/sizeof(WCHAR)) &&
lstrcmpiW((LPWSTR)buf, WDML_szClientConvClassW) == 0))
{
pcc = &cc;
memset(pcc, 0, sizeof(*pcc));
pcc->cb = sizeof(*pcc);
pcc->iCodePage = CP_WINUNICODE;
pcc->iCodePage = IsWindowUnicode(hwndClient) ? CP_WINUNICODE : CP_WINANSI;
}
if ((pInstance->CBFflags & CBF_FAIL_SELFCONNECTIONS) && self)
{
......@@ -976,7 +1006,8 @@ static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM w
}
if (iMsg < WM_DDE_FIRST || iMsg > WM_DDE_LAST)
{
return DefWindowProcW(hwndServer, iMsg, wParam, lParam);
return IsWindowUnicode(hwndServer) ? DefWindowProcW(hwndServer, iMsg, wParam, lParam) :
DefWindowProcA(hwndServer, iMsg, wParam, lParam);
}
EnterCriticalSection(&WDML_CritSect);
......
......@@ -151,7 +151,8 @@ HDDEDATA WDML_InvokeCallback16(PFNCALLBACK pfn, UINT uType, UINT uFmt,
UINT16 WINAPI DdeInitialize16(LPDWORD pidInst, PFNCALLBACK16 pfnCallback,
DWORD afCmd, DWORD ulRes)
{
return WDML_Initialize(pidInst, (PFNCALLBACK)pfnCallback, afCmd, ulRes, TRUE);
return WDML_Initialize(pidInst, (PFNCALLBACK)pfnCallback, afCmd, ulRes,
FALSE, TRUE);
}
/*****************************************************************
......
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