Author: cwittich Date: Wed Mar 25 16:57:58 2009 New Revision: 40226
URL: http://svn.reactos.org/svn/reactos?rev=40226&view=rev Log: sync DDE to wine 1.1.17
Modified: trunk/reactos/dll/win32/user32/include/dde_private.h trunk/reactos/dll/win32/user32/misc/dde.c trunk/reactos/dll/win32/user32/misc/ddeclient.c trunk/reactos/dll/win32/user32/misc/ddeserver.c
Modified: trunk/reactos/dll/win32/user32/include/dde_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/dd... ============================================================================== --- trunk/reactos/dll/win32/user32/include/dde_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/include/dde_private.h [iso-8859-1] Wed Mar 25 16:57:58 2009 @@ -232,9 +232,9 @@ extern BOOL WDML_UnQueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct); extern void WDML_FreeTransaction(WDML_INSTANCE* pInstance, WDML_XACT* pXAct, BOOL doFreePmt); extern WDML_XACT* WDML_FindTransaction(WDML_CONV* pConv, DWORD tid); -extern HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease, - BOOL fDeferUpd, BOOL dAckReq); -extern HDDEDATA WDML_Global2DataHandle(HGLOBAL hMem, WINE_DDEHEAD* da); +extern HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease, + BOOL fDeferUpd, BOOL fAckReq); +extern HDDEDATA WDML_Global2DataHandle(WDML_CONV* pConv, HGLOBAL hMem, WINE_DDEHEAD* p); extern BOOL WDML_IsAppOwned(HDDEDATA hDdeData); extern WDML_INSTANCE* WDML_GetInstance(DWORD InstId); extern WDML_INSTANCE* WDML_GetInstanceFromWnd(HWND hWnd);
Modified: trunk/reactos/dll/win32/user32/misc/dde.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/dde.c... ============================================================================== --- trunk/reactos/dll/win32/user32/misc/dde.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/misc/dde.c [iso-8859-1] Wed Mar 25 16:57:58 2009 @@ -336,8 +336,8 @@ UINT ret; WNDCLASSEXW wndclass;
- TRACE("(%p,%p,0x%x,%d)\n", - pidInst, pfnCallback, afCmd, ulRes); + TRACE("(%p,%p,0x%x,%d,0x%x)\n", + pidInst, pfnCallback, afCmd, ulRes, bUnicode);
if (ulRes) { @@ -503,7 +503,6 @@ ret = DMLERR_INVALIDPARAMETER; goto theError; } - HeapFree(GetProcessHeap(), 0, pInstance); /* finished - release heap space used as work store */ /* can't reinitialise if we have initialised nothing !! */ reference_inst = WDML_InstanceList; /* must first check if we have been given a valid instance to re-initialise !! how do we do that ? */ @@ -559,6 +558,9 @@ reference_inst->CBFflags = pInstance->CBFflags; reference_inst->clientOnly = pInstance->clientOnly; reference_inst->monitorFlags = pInstance->monitorFlags; + + HeapFree(GetProcessHeap(), 0, pInstance); /* finished - release heap space used as work store */ + LeaveCriticalSection(&WDML_CritSect); }
@@ -795,6 +797,25 @@ }
return error_code; +} + +/****************************************************************** + * WDML_SetAllLastError + * + * + */ +static void WDML_SetAllLastError(DWORD lastError) +{ + DWORD threadID; + WDML_INSTANCE* pInstance; + threadID = GetCurrentThreadId(); + pInstance = WDML_InstanceList; + while (pInstance) + { + if (pInstance->threadID == threadID) + pInstance->lastError = lastError; + pInstance = pInstance->next; + } }
/* ================================================================ @@ -979,6 +1000,14 @@ cchMax = MAX_BUFFER_LEN; }
+ /* if there is no input windows returns a NULL string */ + if (hsz == NULL) + { + CHAR *t_ptr = ptr; + *t_ptr = '\0'; + return 1; + } + switch (codepage) { case CP_WINANSI: @@ -1081,7 +1110,9 @@ TRACE("(%d,%s,%d)\n", idInst, debugstr_a(psz), codepage);
pInstance = WDML_GetInstance(idInst); - if (pInstance) + if (pInstance == NULL) + WDML_SetAllLastError(DMLERR_INVALIDPARAMETER); + else { if (codepage == 0) codepage = CP_WINANSI; hsz = WDML_CreateString(pInstance, psz, codepage); @@ -1108,7 +1139,9 @@ HSZ hsz = 0;
pInstance = WDML_GetInstance(idInst); - if (pInstance) + if (pInstance == NULL) + WDML_SetAllLastError(DMLERR_INVALIDPARAMETER); + else { if (codepage == 0) codepage = CP_WINUNICODE; hsz = WDML_CreateString(pInstance, psz, codepage); @@ -1239,15 +1272,24 @@ HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, DWORD cbOff, HSZ hszItem, UINT wFmt, UINT afCmd) { - /* For now, we ignore idInst, hszItem. + + /* Other than check for validity we will ignore for now idInst, hszItem. * The purpose of these arguments still need to be investigated. */
+ WDML_INSTANCE* pInstance; HGLOBAL hMem; LPBYTE pByte; DDE_DATAHANDLE_HEAD* pDdh; WCHAR psz[MAX_BUFFER_LEN];
+ pInstance = WDML_GetInstance(idInst); + if (pInstance == NULL) + { + WDML_SetAllLastError(DMLERR_INVALIDPARAMETER); + return NULL; + } + if (!GetAtomNameW(HSZ2ATOM(hszItem), psz, MAX_BUFFER_LEN)) { psz[0] = HSZ2ATOM(hszItem); @@ -1267,7 +1309,7 @@ return 0; }
- pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hMem); + pDdh = GlobalLock(hMem); if (!pDdh) { GlobalFree(hMem); @@ -1285,7 +1327,7 @@ GlobalUnlock(hMem);
TRACE("=> %p\n", hMem); - return (HDDEDATA)hMem; + return hMem; }
/***************************************************************** @@ -1381,7 +1423,7 @@
TRACE("(%p,%p)\n", hData, pcbDataSize);
- pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hMem); + pDdh = GlobalLock(hMem); if (pDdh == NULL) { ERR("Failed on GlobalLock(%p)\n", hMem); @@ -1429,7 +1471,7 @@ DDE_DATAHANDLE_HEAD* pDdh; BOOL ret = FALSE;
- pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hData); + pDdh = GlobalLock(hData); if (pDdh != NULL) { ret = pDdh->bAppOwned; @@ -1451,7 +1493,7 @@ * 2 16 clipboard format * 4 ? data to be used */ -HDDEDATA WDML_Global2DataHandle(HGLOBAL hMem, WINE_DDEHEAD* p) +HDDEDATA WDML_Global2DataHandle(WDML_CONV* pConv, HGLOBAL hMem, WINE_DDEHEAD* p) { DDEDATA* pDd; HDDEDATA ret = 0; @@ -1472,7 +1514,7 @@ /* fall thru */ case 0: case CF_TEXT: - ret = DdeCreateDataHandle(0, pDd->Value, size, 0, 0, pDd->cfFormat, 0); + ret = DdeCreateDataHandle(pConv->instance->instanceID, pDd->Value, size, 0, 0, pDd->cfFormat, 0); break; case CF_BITMAP: if (size >= sizeof(BITMAP)) @@ -1487,7 +1529,7 @@ bmp->bmPlanes, bmp->bmBitsPixel, pDd->Value + sizeof(BITMAP)))) { - ret = DdeCreateDataHandle(0, (LPBYTE)&hbmp, sizeof(hbmp), + ret = DdeCreateDataHandle(pConv->instance->instanceID, (LPBYTE)&hbmp, sizeof(hbmp), 0, 0, CF_BITMAP, 0); } else ERR("Can't create bmp\n"); @@ -1517,8 +1559,8 @@ DWORD dwSize; HGLOBAL hMem = 0;
- dwSize = GlobalSize((HGLOBAL)hDdeData) - sizeof(DDE_DATAHANDLE_HEAD); - pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock((HGLOBAL)hDdeData); + dwSize = GlobalSize(hDdeData) - sizeof(DDE_DATAHANDLE_HEAD); + pDdh = GlobalLock(hDdeData); if (dwSize && pDdh) { WINE_DDEHEAD* wdh = NULL; @@ -1568,7 +1610,7 @@ wdh->cfFormat = pDdh->cfFormat; GlobalUnlock(hMem); } - GlobalUnlock((HGLOBAL)hDdeData); + GlobalUnlock(hDdeData); }
return hMem; @@ -1638,9 +1680,10 @@ pConvNext = pConv->next; if (DdeCmpStringHandles(pConv->hszService, hszService) == 0) { + HWND client = pConv->hwndClient, server = pConv->hwndServer; WDML_RemoveConv(pConv, WDML_SERVER_SIDE); /* don't care about return code (whether client window is present or not) */ - PostMessageW(pConv->hwndClient, WM_DDE_TERMINATE, (WPARAM)pConv->hwndServer, 0); + PostMessageW(client, WM_DDE_TERMINATE, (WPARAM)server, 0); } } if (pServer == pInstance->servers) @@ -1731,7 +1774,7 @@ pConv->next = pInstance->convs[side]; pInstance->convs[side] = pConv;
- TRACE("pConv->wStatus %04x\n", pConv->wStatus); + TRACE("pConv->wStatus %04x pInstance(%p)\n", pConv->wStatus, pInstance);
return pConv; }
Modified: trunk/reactos/dll/win32/user32/misc/ddeclient.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/ddecl... ============================================================================== --- trunk/reactos/dll/win32/user32/misc/ddeclient.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/misc/ddeclient.c [iso-8859-1] Wed Mar 25 16:57:58 2009 @@ -50,7 +50,7 @@ HCONVLIST WINAPI DdeConnectList(DWORD idInst, HSZ hszService, HSZ hszTopic, HCONVLIST hConvList, PCONVCONTEXT pCC) { - FIXME("(%ld,%p,%p,%p,%p): stub\n", idInst, hszService, hszTopic, hConvList, pCC); + FIXME("(%d,%p,%p,%p,%p): stub\n", idInst, hszService, hszTopic, hConvList, pCC); return (HCONVLIST)1; }
@@ -91,22 +91,18 @@ WDML_CONV* pConv = NULL; ATOM aSrv = 0, aTpc = 0;
- TRACE("(0x%lx,%p,%p,%p)\n", idInst, hszService, hszTopic, pCC); - - EnterCriticalSection(&WDML_CritSect); + TRACE("(0x%x,%p,%p,%p)\n", idInst, hszService, hszTopic, pCC);
pInstance = WDML_GetInstance(idInst); if (!pInstance) - { - goto theEnd; - } + return NULL;
/* make sure this conv is never created */ pConv = WDML_FindConv(pInstance, WDML_CLIENT_SIDE, hszService, hszTopic); if (pConv != NULL) { ERR("This Conv already exists: (%p)\n", pConv); - goto theEnd; + return NULL; }
/* we need to establish a conversation with @@ -114,7 +110,7 @@
if (pInstance->unicode) { - WNDCLASSEXW wndclass; + WNDCLASSEXW wndclass;
wndclass.cbSize = sizeof(wndclass); wndclass.style = 0; @@ -135,7 +131,7 @@ } else { - WNDCLASSEXA wndclass; + WNDCLASSEXA wndclass;
wndclass.cbSize = sizeof(wndclass); wndclass.style = 0; @@ -168,13 +164,9 @@ if (!aTpc) goto theEnd; }
- LeaveCriticalSection(&WDML_CritSect); - /* note: sent messages shall not use packing */ SendMessageTimeoutW( HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwndClient, MAKELPARAM(aSrv, aTpc), SMTO_ABORTIFHUNG, 2000, NULL ); - - EnterCriticalSection(&WDML_CritSect);
pInstance = WDML_GetInstance(idInst); if (!pInstance) @@ -190,6 +182,7 @@ { WARN("Done with INITIATE, but no Server window available\n"); pConv = NULL; + pInstance->lastError = DMLERR_NO_CONV_ESTABLISHED; goto theEnd; } TRACE("Connected to Server window (%p)\n", pConv->hwndServer); @@ -208,7 +201,6 @@ }
theEnd: - LeaveCriticalSection(&WDML_CritSect);
if (aSrv) GlobalDeleteAtom(aSrv); if (aTpc) GlobalDeleteAtom(aTpc); @@ -227,14 +219,13 @@
TRACE("(%p)\n", hConv);
- EnterCriticalSection(&WDML_CritSect); pConv = WDML_GetConv(hConv, FALSE); if (pConv != NULL && (pConv->wStatus & ST_CLIENT)) { BOOL ret;
- /* to reestablist a connection, we have to make sure that: - * 1/ pConv is the converstation attached to the client window (it wouldn't be + /* to reestablish a connection, we have to make sure that: + * 1/ pConv is the conversation attached to the client window (it wouldn't be * if a call to DdeReconnect would have already been done...) * FIXME: is this really an error ??? * 2/ the pConv conversation had really been deconnected @@ -244,7 +235,6 @@ { HWND hwndClient = pConv->hwndClient; HWND hwndServer = pConv->hwndServer; - ATOM aSrv, aTpc;
SetWindowLongPtrW(pConv->hwndClient, GWL_WDML_CONVERSATION, 0);
@@ -252,13 +242,9 @@ aTpc = WDML_MakeAtomFromHsz(pConv->hszTopic); if (!aSrv || !aTpc) goto theEnd;
- LeaveCriticalSection(&WDML_CritSect); - /* note: sent messages shall not use packing */ ret = SendMessageW(hwndServer, WM_DDE_INITIATE, (WPARAM)hwndClient, MAKELPARAM(aSrv, aTpc)); - - EnterCriticalSection(&WDML_CritSect);
pConv = WDML_GetConv(hConv, FALSE); if (pConv == NULL) @@ -291,7 +277,6 @@ }
theEnd: - LeaveCriticalSection(&WDML_CritSect);
if (aSrv) GlobalDeleteAtom(aSrv); if (aTpc) GlobalDeleteAtom(aTpc); @@ -326,7 +311,7 @@ /* FIXME: hMem is unfreed for now... should be deleted in server */
/* pack DdeAdvise */ - pDdeAdvise = (DDEADVISE*)GlobalLock(pXAct->hMem); + pDdeAdvise = GlobalLock(pXAct->hMem); pDdeAdvise->fAckReq = (wType & XTYPF_ACKREQ) ? TRUE : FALSE; pDdeAdvise->fDeferUpd = (wType & XTYPF_NODATA) ? TRUE : FALSE; pDdeAdvise->cfFormat = wFmt; @@ -348,7 +333,7 @@ UINT_PTR uiLo, uiHi; HSZ hsz;
- if (msg->message != WM_DDE_ACK || (HWND)msg->wParam != pConv->hwndServer) + if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { return WDML_QS_PASS; } @@ -434,7 +419,7 @@ UINT_PTR uiLo, uiHi; HSZ hsz;
- if (msg->message != WM_DDE_ACK || (HWND)msg->wParam != pConv->hwndServer) + if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { return WDML_QS_PASS; } @@ -507,7 +492,7 @@ UINT_PTR uiLo, uiHi; HSZ hsz;
- if ((HWND)msg->wParam != pConv->hwndServer) + if (WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) return WDML_QS_PASS;
switch (msg->message) @@ -533,14 +518,14 @@ if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0) return WDML_QS_PASS;
- pXAct->hDdeData = WDML_Global2DataHandle((HGLOBAL)uiLo, &wdh); + pXAct->hDdeData = WDML_Global2DataHandle(pConv, (HGLOBAL)uiLo, &wdh); if (wdh.fRelease) { GlobalFree((HGLOBAL)uiLo); } if (wdh.fAckReq) { - WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi, msg->lParam, WM_DDE_DATA); + pConv->instance->lastError = DMLERR_MEMORY_ERROR; } else { @@ -583,7 +568,7 @@ { if (clientUnicode) { - memSize = WideCharToMultiByte( CP_ACP, 0, pData, cbData, NULL, 0, NULL, NULL); + memSize = WideCharToMultiByte( CP_ACP, 0, pData, cbData / sizeof(WCHAR), NULL, 0, NULL, NULL); } else { @@ -608,7 +593,7 @@ { if (clientUnicode) { - WideCharToMultiByte( CP_ACP, 0, pData, cbData, pDst, memSize, NULL, NULL); + WideCharToMultiByte( CP_ACP, 0, pData, cbData / sizeof(WCHAR), pDst, memSize, NULL, NULL); } else { @@ -632,11 +617,20 @@ * * */ -static WDML_XACT* WDML_ClientQueueExecute(WDML_CONV* pConv, LPCVOID pData, DWORD cbData) +static WDML_XACT* WDML_ClientQueueExecute(WDML_CONV* pConv, LPVOID pData, DWORD cbData) { WDML_XACT* pXAct;
TRACE("XTYP_EXECUTE transaction\n"); + + if (pData == NULL) + { + if (cbData == (DWORD)-1) + pConv->instance->lastError = DMLERR_INVALIDPARAMETER; + else + pConv->instance->lastError = DMLERR_MEMORY_ERROR; + return NULL; + }
pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_EXECUTE, 0, 0); if (!pXAct) @@ -644,7 +638,7 @@
if (cbData == (DWORD)-1) { - HDDEDATA hDdeData = (HDDEDATA)pData; + HDDEDATA hDdeData = pData;
pData = DdeAccessData(hDdeData, &cbData); if (pData) @@ -673,7 +667,7 @@ DDEACK ddeAck; UINT_PTR uiLo, uiHi;
- if (msg->message != WM_DDE_ACK || (HWND)msg->wParam != pConv->hwndServer) + if (msg->message != WM_DDE_ACK || WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { return WDML_QS_PASS; } @@ -701,11 +695,14 @@ * * */ -static WDML_XACT* WDML_ClientQueuePoke(WDML_CONV* pConv, LPCVOID pData, DWORD cbData, +static WDML_XACT* WDML_ClientQueuePoke(WDML_CONV* pConv, LPVOID pData, DWORD cbData, UINT wFmt, HSZ hszItem) { - WDML_XACT* pXAct; - ATOM atom; + DDE_DATAHANDLE_HEAD *dh; + WDML_XACT *pXAct; + DDEPOKE *ddePoke; + HGLOBAL hglobal; + ATOM atom;
TRACE("XTYP_POKE transaction\n");
@@ -715,28 +712,32 @@ pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_POKE, wFmt, hszItem); if (!pXAct) { - GlobalDeleteAtom(atom); - return NULL; + GlobalDeleteAtom(atom); + return NULL; }
if (cbData == (DWORD)-1) { - pXAct->hMem = (HDDEDATA)pData; - } - else - { - DDEPOKE* ddePoke; - - pXAct->hMem = GlobalAlloc(GHND | GMEM_DDESHARE, sizeof(DDEPOKE) + cbData); - ddePoke = GlobalLock(pXAct->hMem); - if (ddePoke) - { - memcpy(ddePoke->Value, pData, cbData); - ddePoke->fRelease = FALSE; /* FIXME: app owned ? */ - ddePoke->cfFormat = wFmt; - GlobalUnlock(pXAct->hMem); - } - } + hglobal = pData; + dh = GlobalLock(hglobal); + cbData = GlobalSize(hglobal) - sizeof(DDE_DATAHANDLE_HEAD); + pData = dh + 1; + GlobalUnlock(hglobal); + } + + pXAct->hMem = GlobalAlloc(GHND | GMEM_DDESHARE, FIELD_OFFSET(DDEPOKE, Value[cbData])); + ddePoke = GlobalLock(pXAct->hMem); + if (!ddePoke) + { + pConv->instance->lastError = DMLERR_MEMORY_ERROR; + return NULL; + } + + ddePoke->unused = 0; + ddePoke->fRelease = TRUE; + ddePoke->cfFormat = wFmt; + memcpy(ddePoke->Value, pData, cbData); + GlobalUnlock(pXAct->hMem);
pXAct->lParam = PackDDElParam(WM_DDE_POKE, (UINT_PTR)pXAct->hMem, atom);
@@ -753,7 +754,7 @@ UINT_PTR uiLo, uiHi; HSZ hsz;
- if (msg->message != WM_DDE_ACK && (HWND)msg->wParam != pConv->hwndServer) + if (msg->message != WM_DDE_ACK && WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { return WDML_QS_PASS; } @@ -798,7 +799,7 @@ * * handles the reply to a terminate request */ -static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg, WDML_XACT* pXAct) +static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg) { if (msg->message != WM_DDE_TERMINATE) { @@ -806,7 +807,7 @@ return WDML_QS_SWALLOWED; }
- if ((HWND)msg->wParam != pConv->hwndServer) + if (WIN_GetFullHandle((HWND)msg->wParam) != pConv->hwndServer) { FIXME("hmmm shouldn't happen\n"); return WDML_QS_PASS; @@ -821,7 +822,7 @@ }
/****************************************************************** - * WDML_HandleReplyData + * WDML_HandleIncomingData * * */ @@ -840,7 +841,7 @@ UnpackDDElParam(WM_DDE_DATA, msg->lParam, &uiLo, &uiHi); hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);
- hDdeDataIn = WDML_Global2DataHandle((HGLOBAL)uiLo, &wdh); + hDdeDataIn = WDML_Global2DataHandle(pConv, (HGLOBAL)uiLo, &wdh);
/* billx: * For hot link, data should be passed to its callback with @@ -890,15 +891,10 @@ */ static WDML_QUEUE_STATE WDML_HandleIncomingTerminate(WDML_CONV* pConv, MSG* msg, HDDEDATA* hdd) { - if (pConv->hwndServer != (HWND)msg->wParam) + if (pConv->hwndServer != WIN_GetFullHandle((HWND)msg->wParam)) return WDML_QS_PASS;
pConv->wStatus |= ST_TERMINATED; - if (!(pConv->instance->CBFflags & CBF_SKIP_DISCONNECTS)) - { - WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv, - 0, 0, 0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0); - } if (pConv->wStatus & ST_CONNECTED) { /* don't care about result code (if server exists or not) */ @@ -921,6 +917,7 @@
if (pConv->transactions) { + if (ack) *ack = DDE_FNOTPROCESSED; /* first check message against a pending transaction, if any */ switch (pXAct->ddeMsg) { @@ -940,7 +937,7 @@ qs = WDML_HandlePokeReply(pConv, msg, pXAct, ack); break; case WM_DDE_TERMINATE: - qs = WDML_HandleTerminateReply(pConv, msg, pXAct); + qs = WDML_HandleTerminateReply(pConv, msg); break; default: qs = WDML_QS_ERROR; @@ -961,9 +958,8 @@ break; case WDML_QS_HANDLED: /* ok, we have resolved a pending transaction - * notify callback if asynchronous, and remove it in any case + * notify callback if asynchronous. */ - WDML_UnQueueTransaction(pConv, pXAct); if (pXAct->dwTimeout == TIMEOUT_ASYNC && pXAct->ddeMsg != WM_DDE_TERMINATE) { WDML_InvokeCallback(pConv->instance, XTYP_XACT_COMPLETE, pXAct->wFmt, @@ -975,7 +971,6 @@ { *hdd = pXAct->hDdeData; } - WDML_FreeTransaction(pConv->instance, pXAct, TRUE); break; case WDML_QS_PASS: /* no pending transaction found, try a warm/hot link or a termination request */ @@ -987,6 +982,14 @@ case WM_DDE_TERMINATE: qs = WDML_HandleIncomingTerminate(pConv, msg, hdd); break; + case WM_DDE_ACK: + /* This happens at end of DdeClientTransaction XTYP_EXECUTE + * Without this assignment, DdeClientTransaction's return value is undefined + */ + *hdd = (HDDEDATA)TRUE; + if (ack) + *ack = DDE_FACK; + break; } break; case WDML_QS_BLOCK: @@ -1003,13 +1006,13 @@ * waits until an answer for a sent request is received * time out is also handled. only used for synchronous transactions */ -static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, WDML_XACT* pXAct, DWORD *ack) +static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, const WDML_XACT* pXAct, DWORD *ack) { DWORD dwTime; DWORD err; WDML_CONV* pConv;
- TRACE("Starting wait for a timeout of %ld ms\n", dwTimeout); + TRACE("Starting wait for a timeout of %d ms\n", dwTimeout);
/* FIXME: time 32 bit wrap around */ dwTimeout += GetCurrentTime(); @@ -1026,15 +1029,11 @@
while (PeekMessageW(&msg, 0, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE)) { - WDML_CONV *pConv; - HDDEDATA hdd; - - EnterCriticalSection(&WDML_CritSect); + HDDEDATA hdd = NULL;
pConv = WDML_GetConv(hConv, FALSE); if (pConv == NULL) { - LeaveCriticalSection(&WDML_CritSect); /* conversation no longer available... return failure */ return 0; } @@ -1053,13 +1052,11 @@ if (ret) { pConv->instance->lastError = hdd ? DMLERR_NO_ERROR : DMLERR_NOTPROCESSED; - LeaveCriticalSection(&WDML_CritSect); return hdd; } } else { - LeaveCriticalSection(&WDML_CritSect); DispatchMessageW(&msg); } } @@ -1067,8 +1064,6 @@ }
TRACE("Timeout !!\n"); - - EnterCriticalSection(&WDML_CritSect);
pConv = WDML_GetConv(hConv, FALSE); if (pConv != NULL) @@ -1088,10 +1083,10 @@ pConv->instance->lastError = err; } } - LeaveCriticalSection(&WDML_CritSect);
return 0; } +
/***************************************************************** * WDML_ClientHandle @@ -1124,6 +1119,7 @@ return hDdeData; }
+ /***************************************************************** * DdeClientTransaction (USER32.@) */ @@ -1134,7 +1130,7 @@ WDML_XACT* pXAct; HDDEDATA hDdeData = 0;
- TRACE("(%p,%ld,%p,%p,%x,%x,%ld,%p)\n", + TRACE("(%p,%d,%p,%p,%x,%x,%d,%p)\n", pData, cbData, hConv, hszItem, wFmt, wType, dwTimeout, pdwResult);
if (hConv == 0) @@ -1143,24 +1139,29 @@ return 0; }
- EnterCriticalSection(&WDML_CritSect); - pConv = WDML_GetConv(hConv, TRUE); if (pConv == NULL) { /* cannot set error... cannot get back to DDE instance */ - goto theError; + return 0; }
switch (wType) { case XTYP_EXECUTE: - /* Windows simply ignores hszItem and wFmt in this case */ + /* Windows simply ignores hszItem and wFmt in this case */ pXAct = WDML_ClientQueueExecute(pConv, pData, cbData); + if (pXAct == NULL) + return 0; break; case XTYP_POKE: - pXAct = WDML_ClientQueuePoke(pConv, pData, cbData, wFmt, hszItem); - break; + if (!hszItem) + { + pConv->instance->lastError = DMLERR_INVALIDPARAMETER; + return 0; + } + pXAct = WDML_ClientQueuePoke(pConv, pData, cbData, wFmt, hszItem); + break; case XTYP_ADVSTART|XTYPF_NODATA: case XTYP_ADVSTART|XTYPF_NODATA|XTYPF_ACKREQ: case XTYP_ADVSTART: @@ -1168,7 +1169,7 @@ if (pData) { pConv->instance->lastError = DMLERR_INVALIDPARAMETER; - goto theError; + return 0; } pXAct = WDML_ClientQueueAdvise(pConv, wType, wFmt, hszItem); break; @@ -1176,70 +1177,49 @@ if (pData) { pConv->instance->lastError = DMLERR_INVALIDPARAMETER; - goto theError; + return 0; } pXAct = WDML_ClientQueueUnadvise(pConv, wFmt, hszItem); break; case XTYP_REQUEST: - if (pData) + if (pData || !hszItem) { pConv->instance->lastError = DMLERR_INVALIDPARAMETER; - goto theError; + return 0; } pXAct = WDML_ClientQueueRequest(pConv, wFmt, hszItem); break; default: - FIXME("Unknown transation\n"); + FIXME("Unknown transaction type %04x\n", wType); /* unknown transaction type */ pConv->instance->lastError = DMLERR_INVALIDPARAMETER; - goto theError; + return 0; }
if (pXAct == NULL) { pConv->instance->lastError = DMLERR_MEMORY_ERROR; - goto theError; + return 0; }
WDML_QueueTransaction(pConv, pXAct);
- if (!PostMessageW(pConv->hwndServer, pXAct->ddeMsg, (WPARAM)pConv->hwndClient, pXAct->lParam)) - { - WARN("Failed posting message %x to %p (error=0x%lx)\n", - pXAct->ddeMsg, pConv->hwndServer, GetLastError()); - pConv->wStatus &= ~ST_CONNECTED; - WDML_UnQueueTransaction(pConv, pXAct); - WDML_FreeTransaction(pConv->instance, pXAct, TRUE); - goto theError; - } - pXAct->dwTimeout = dwTimeout; - /* FIXME: should set the app bits on *pdwResult */ - - if (dwTimeout == TIMEOUT_ASYNC) - { - if (pdwResult) - { - *pdwResult = MAKELONG(0, pXAct->xActID); - } - hDdeData = (HDDEDATA)1; - } - else - { - DWORD count, i; - - count = WDML_CritSect.RecursionCount; - for (i = 0; i < count; i++) - LeaveCriticalSection(&WDML_CritSect); - hDdeData = WDML_SyncWaitTransactionReply((HCONV)pConv, dwTimeout, pXAct, pdwResult); - for (i = 0; i < count; i++) - EnterCriticalSection(&WDML_CritSect); - } - LeaveCriticalSection(&WDML_CritSect); + TRACE("pConv->wStatus %04x\n", pConv->wStatus); + + if (pConv->wStatus & ST_BLOCKED) + { + TRACE("Transactions are blocked, add to the queue and exit\n"); + return (HDDEDATA)1; + } + + hDdeData = WDML_ClientHandle(pConv, pXAct, dwTimeout, pdwResult); + if (dwTimeout != TIMEOUT_ASYNC) + { + WDML_UnQueueTransaction(pConv, pXAct); + WDML_FreeTransaction(pConv->instance, pXAct, TRUE); + }
return hDdeData; - theError: - LeaveCriticalSection(&WDML_CritSect); - return 0; }
/***************************************************************** @@ -1251,9 +1231,6 @@ WDML_CONV* pConv; WDML_XACT* pXAct;
- TRACE("(%08lx,%p,%08lx);\n", idInst, hConv, idTransaction); - - EnterCriticalSection(&WDML_CritSect); if ((pInstance = WDML_GetInstance(idInst))) { if (hConv) @@ -1287,7 +1264,6 @@ } } } - LeaveCriticalSection(&WDML_CritSect);
return TRUE; } @@ -1347,8 +1323,6 @@ pConv->wStatus |= ST_ISLOCAL; }
- WDML_BroadcastDDEWindows(WDML_szEventClass, WM_WDML_CONNECT_CONFIRM, (WPARAM)hwnd, wParam); - GlobalDeleteAtom(uiLo); GlobalDeleteAtom(uiHi);
@@ -1358,8 +1332,6 @@
if (iMsg >= WM_DDE_FIRST && iMsg <= WM_DDE_LAST) { - EnterCriticalSection(&WDML_CritSect); - pConv = WDML_GetConvFromWnd(hwnd);
if (pConv) @@ -1375,7 +1347,6 @@ WDML_HandleReply(pConv, &msg, &hdd, NULL); }
- LeaveCriticalSection(&WDML_CritSect); return 0; }
@@ -1390,7 +1361,6 @@ { WDML_CONV* pConv = NULL; WDML_XACT* pXAct; - DWORD count, i; BOOL ret = FALSE;
TRACE("(%p)\n", hConv); @@ -1401,7 +1371,6 @@ return FALSE; }
- EnterCriticalSection(&WDML_CritSect); pConv = WDML_GetConv(hConv, TRUE); if (pConv != NULL) { @@ -1411,17 +1380,17 @@ pXAct = WDML_ClientQueueTerminate(pConv); if (pXAct != NULL) { - count = WDML_CritSect.RecursionCount; - for (i = 0; i < count; i++) - LeaveCriticalSection(&WDML_CritSect); if (PostMessageW(pConv->hwndServer, pXAct->ddeMsg, (WPARAM)pConv->hwndClient, pXAct->lParam)) + { WDML_SyncWaitTransactionReply(hConv, 10000, pXAct, NULL); - for (i = 0; i < count; i++) - EnterCriticalSection(&WDML_CritSect); - ret = TRUE; + ret = TRUE; + } + else + pConv->instance->lastError = DMLERR_POSTMSG_FAILED; + WDML_FreeTransaction(pConv->instance, pXAct, TRUE); - /* still have to destroy data assosiated with conversation */ + /* still have to destroy data associated with conversation */ WDML_RemoveConv(pConv, WDML_CLIENT_SIDE); } else @@ -1430,7 +1399,6 @@ } } } - LeaveCriticalSection(&WDML_CritSect);
return ret; } @@ -1445,12 +1413,10 @@
TRACE("(%p)\n", hConv);
- EnterCriticalSection(&WDML_CritSect); pConv = WDML_GetConv(hConv, TRUE); if (pConv) { ret = ImpersonateDdeClientWindow(pConv->hwndClient, pConv->hwndServer); } - LeaveCriticalSection(&WDML_CritSect); return ret; }
Modified: trunk/reactos/dll/win32/user32/misc/ddeserver.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/ddese... ============================================================================== --- trunk/reactos/dll/win32/user32/misc/ddeserver.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/misc/ddeserver.c [iso-8859-1] Wed Mar 25 16:57:58 2009 @@ -20,7 +20,7 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
#include <user32.h> @@ -30,7 +30,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
static const WCHAR szServerNameClass[] = {'D','d','e','S','e','r','v','e','r','N','a','m','e',0}; -const char WDML_szServerConvClassA[] = "DdeServerConvAnsi"; +const char WDML_szServerConvClassA[] = "DdeServerConvAnsi"; const WCHAR WDML_szServerConvClassW[] = {'D','d','e','S','e','r','v','e','r','C','o','n','v','U','n','i','c','o','d','e',0};
static LRESULT CALLBACK WDML_ServerNameProc(HWND, UINT, WPARAM, LPARAM); @@ -58,19 +58,15 @@ ATOM atom = 0; UINT count;
- TRACE("(%ld,%p,%p)\n", idInst, hszTopic, hszItem); - - EnterCriticalSection(&WDML_CritSect); + TRACE("(%d,%p,%p)\n", idInst, hszTopic, hszItem);
pInstance = WDML_GetInstance(idInst);
if (pInstance == NULL || pInstance->links == NULL) - { - goto theError; - } + return FALSE;
atom = WDML_MakeAtomFromHsz(hszItem); - if (!atom) goto theError; + if (!atom) return FALSE;
/* first compute the number of links which will trigger a message */ count = 0; @@ -94,7 +90,7 @@ hDdeData = WDML_InvokeCallback(pInstance, XTYP_ADVREQ, pLink->uFmt, pLink->hConv, hszTopic, hszItem, 0, --count, 0);
- if (hDdeData == (HDDEDATA)CBR_BLOCK) + if (hDdeData == CBR_BLOCK) { /* MS doc is not consistent here */ FIXME("CBR_BLOCK returned for ADVREQ\n"); @@ -127,6 +123,7 @@ { ERR("post message failed\n"); pConv->wStatus &= ~ST_CONNECTED; + pConv->instance->lastError = DMLERR_POSTMSG_FAILED; if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData); GlobalFree(hItemData); goto theError; @@ -135,10 +132,9 @@ } } } - LeaveCriticalSection(&WDML_CritSect); return TRUE; + theError: - LeaveCriticalSection(&WDML_CritSect); if (atom) GlobalDeleteAtom(atom); return FALSE; } @@ -161,15 +157,10 @@ { WDML_SERVER* pServer; WDML_INSTANCE* pInstance; - HDDEDATA hDdeData; HWND hwndServer; WNDCLASSEXW wndclass;
- hDdeData = NULL; - - TRACE("(%ld,%p,%p,%x)\n", idInst, hsz1, hsz2, afCmd); - - EnterCriticalSection(&WDML_CritSect); + TRACE("(%d,%p,%p,%x)\n", idInst, hsz1, hsz2, afCmd);
/* First check instance */ @@ -178,7 +169,7 @@ { TRACE("Instance not found as initialised\n"); /* Nothing has been initialised - exit now ! can return TRUE since effect is the same */ - goto theError; + return NULL; }
if (hsz2 != 0L) @@ -187,7 +178,7 @@ */ pInstance->lastError = DMLERR_INVALIDPARAMETER; WARN("Reserved parameter no-zero !!\n"); - goto theError; + return NULL; } if (hsz1 == 0 && !(afCmd & DNS_UNREGISTER)) { @@ -196,7 +187,7 @@ */ TRACE("General unregister unexpected flags\n"); pInstance->lastError = DMLERR_INVALIDPARAMETER; - goto theError; + return NULL; }
switch (afCmd & (DNS_REGISTER | DNS_UNREGISTER)) @@ -207,7 +198,7 @@ { ERR("Trying to register already registered service!\n"); pInstance->lastError = DMLERR_DLL_USAGE; - goto theError; + return NULL; }
TRACE("Adding service name\n"); @@ -234,15 +225,13 @@
RegisterClassExW(&wndclass);
- LeaveCriticalSection(&WDML_CritSect); hwndServer = CreateWindowW(szServerNameClass, NULL, WS_POPUP, 0, 0, 0, 0, 0, 0, 0, 0); - EnterCriticalSection(&WDML_CritSect);
SetWindowLongPtrW(hwndServer, GWL_WDML_INSTANCE, (ULONG_PTR)pInstance); SetWindowLongPtrW(hwndServer, GWL_WDML_SERVER, (ULONG_PTR)pServer); - TRACE("Created nameServer=%p for instance=%08lx\n", hwndServer, idInst); + TRACE("Created nameServer=%p for instance=%08x\n", hwndServer, idInst);
pServer->hwndServer = hwndServer; break; @@ -275,19 +264,14 @@ /* trying to filter where no service names !! */ pInstance->lastError = DMLERR_DLL_USAGE; - goto theError; + return NULL; } else { pServer->filterOn = (afCmd & DNS_FILTERON) != 0; } } - LeaveCriticalSection(&WDML_CritSect); return (HDDEDATA)TRUE; - - theError: - LeaveCriticalSection(&WDML_CritSect); - return FALSE; }
/****************************************************************** @@ -303,53 +287,53 @@
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, + 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); + 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=%08x unicode=%d\n", + hwndServerConv, hwndServerName, pInstance->instanceID, pInstance->unicode);
pConv = WDML_AddConv(pInstance, WDML_SERVER_SIDE, hszApp, hszTopic, hwndClient, hwndServerConv); @@ -400,7 +384,7 @@ hwndClient = (HWND)wParam;
pInstance = WDML_GetInstanceFromWnd(hwndServer); - TRACE("idInst=%ld, threadID=0x%lx\n", pInstance->instanceID, GetCurrentThreadId()); + TRACE("idInst=%d, threadID=0x%x\n", pInstance->instanceID, GetCurrentThreadId()); if (!pInstance) return 0;
/* don't free DDEParams, since this is a broadcast */ @@ -425,9 +409,9 @@ /* 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 ((GetClassNameA(hwndClient, buf, sizeof(buf)) && + if ((GetClassNameA(hwndClient, buf, sizeof(buf)) && lstrcmpiA(buf, WDML_szClientConvClassA) == 0) || - (GetClassNameW(hwndClient, (LPWSTR)buf, sizeof(buf)/sizeof(WCHAR)) && + (GetClassNameW(hwndClient, (LPWSTR)buf, sizeof(buf)/sizeof(WCHAR)) && lstrcmpiW((LPWSTR)buf, WDML_szClientConvClassW) == 0)) { pcc = &cc; @@ -468,7 +452,7 @@ hDdeData = WDML_InvokeCallback(pInstance, XTYP_WILDCONNECT, 0, 0, hszTop, hszApp, 0, (ULONG_PTR)pcc, self);
- if (hDdeData == (HDDEDATA)CBR_BLOCK) + if (hDdeData == CBR_BLOCK) { /* MS doc is not consistent here */ FIXME("CBR_BLOCK returned for WILDCONNECT\n"); @@ -578,6 +562,7 @@ ReuseDDElParam(pXAct->lParam, WM_DDE_REQUEST, WM_DDE_DATA, (UINT_PTR)hMem, (UINT_PTR)pXAct->atom))) { + pConv->instance->lastError = DMLERR_POSTMSG_FAILED; DdeFreeDataHandle(hDdeData); GlobalFree(hMem); fAck = FALSE; @@ -632,7 +617,7 @@ HDDEDATA hDdeData = 0; BOOL fAck = TRUE;
- pDdeAdvise = (DDEADVISE*)GlobalLock(pXAct->hMem); + pDdeAdvise = GlobalLock(pXAct->hMem); uType = XTYP_ADVSTART | (pDdeAdvise->fDeferUpd ? XTYPF_NODATA : 0) | (pDdeAdvise->fAckReq ? XTYPF_ACKREQ : 0); @@ -779,7 +764,7 @@
if (ptr) { - hDdeData = DdeCreateDataHandle(0, ptr, GlobalSize(pXAct->hMem), + hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, ptr, GlobalSize(pXAct->hMem), 0, 0, CF_TEXT, 0); GlobalUnlock(pXAct->hMem); } @@ -804,7 +789,7 @@ case DDE_FNOTPROCESSED: break; } - WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, fBusy, fAck, (UINT)pXAct->hMem, 0, 0); + WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, fBusy, fAck, (UINT_PTR)pXAct->hMem, 0, 0);
return WDML_QS_HANDLED; } @@ -842,7 +827,7 @@ HDDEDATA hDdeData; BOOL fBusy = FALSE, fAck = FALSE;
- pDdePoke = (DDEPOKE*)GlobalLock(pXAct->hMem); + pDdePoke = GlobalLock(pXAct->hMem); if (!pDdePoke) { return WDML_QS_ERROR; @@ -851,7 +836,7 @@ if (!(pConv->instance->CBFflags & CBF_FAIL_POKES)) { hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, pDdePoke->Value, - GlobalSize(pXAct->hMem) - sizeof(DDEPOKE) + 1, + GlobalSize(pXAct->hMem) - FIELD_OFFSET(DDEPOKE, Value), 0, 0, pDdePoke->cfFormat, 0); if (hDdeData) { @@ -983,25 +968,21 @@ WDML_CONV* pConv; WDML_XACT* pXAct = NULL;
- TRACE("%p %04x %08lx %08lx\n", hwndServer, iMsg, wParam , lParam); + TRACE("%p %04x %08lx %08lx\n", hwndServer, iMsg, wParam, lParam);
if (iMsg == WM_DESTROY) { - EnterCriticalSection(&WDML_CritSect); pConv = WDML_GetConvFromWnd(hwndServer); if (pConv && !(pConv->wStatus & ST_TERMINATED)) { WDML_ServerHandleTerminate(pConv, NULL); } - LeaveCriticalSection(&WDML_CritSect); } if (iMsg < WM_DDE_FIRST || iMsg > WM_DDE_LAST) { - return IsWindowUnicode(hwndServer) ? DefWindowProcW(hwndServer, iMsg, wParam, lParam) : + return IsWindowUnicode(hwndServer) ? DefWindowProcW(hwndServer, iMsg, wParam, lParam) : DefWindowProcA(hwndServer, iMsg, wParam, lParam); } - - EnterCriticalSection(&WDML_CritSect);
pInstance = WDML_GetInstanceFromWnd(hwndServer); pConv = WDML_GetConvFromWnd(hwndServer); @@ -1009,17 +990,17 @@ if (!pConv) { ERR("Got a message (%x) on a not known conversation, dropping request\n", iMsg); - goto theError; - } - if (pConv->hwndClient != (HWND)wParam || pConv->hwndServer != hwndServer) - { - ERR("mismatch between C/S windows and converstation\n"); - goto theError; + return 0; + } + if (pConv->hwndClient != WIN_GetFullHandle( (HWND)wParam ) || pConv->hwndServer != hwndServer) + { + ERR("mismatch between C/S windows and conversation\n"); + return 0; } if (pConv->instance != pInstance || pConv->instance == NULL) { ERR("mismatch in instances\n"); - goto theError; + return 0; }
switch (iMsg) @@ -1058,13 +1039,16 @@
default: FIXME("Unsupported message %x\n", iMsg); + break; }
if (pXAct) { pXAct->lParam = lParam; - if (WDML_ServerHandle(pConv, pXAct) == WDML_QS_BLOCK) - { + + if ((pConv->wStatus & ST_BLOCKED) || WDML_ServerHandle(pConv, pXAct) == WDML_QS_BLOCK) + { + TRACE("Transactions are blocked, add to the queue and exit\n"); WDML_QueueTransaction(pConv, pXAct); } else @@ -1072,7 +1056,8 @@ WDML_FreeTransaction(pInstance, pXAct, TRUE); } } - theError: - LeaveCriticalSection(&WDML_CritSect); + else + pConv->instance->lastError = DMLERR_MEMORY_ERROR; + return 0; }