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