diff --git a/reactos/dll/win32/user32/include/dde_private.h b/reactos/dll/win32/user32/include/dde_private.h index bf66d612cd8..42028bf83f2 100644 --- a/reactos/dll/win32/user32/include/dde_private.h +++ b/reactos/dll/win32/user32/include/dde_private.h @@ -232,9 +232,9 @@ extern void WDML_QueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct); 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); diff --git a/reactos/dll/win32/user32/misc/dde.c b/reactos/dll/win32/user32/misc/dde.c index 37d3e99bd56..c5aa3420f92 100644 --- a/reactos/dll/win32/user32/misc/dde.c +++ b/reactos/dll/win32/user32/misc/dde.c @@ -336,8 +336,8 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback, 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 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback, 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 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback, 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); } @@ -797,6 +799,25 @@ UINT WINAPI DdeGetLastError(DWORD idInst) 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; + } +} + /* ================================================================ * * String management @@ -979,6 +1000,14 @@ static int WDML_QueryString(WDML_INSTANCE* pInstance, HSZ hsz, LPVOID ptr, DWORD 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 @@ HSZ WINAPI DdeCreateStringHandleA(DWORD idInst, LPCSTR psz, INT codepage) 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 WINAPI DdeCreateStringHandleW(DWORD idInst, LPCWSTR psz, INT codepage) 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 @@ INT WINAPI DdeCmpStringHandles(HSZ hsz1, HSZ hsz2) 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 @@ HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, DWORD c return 0; } - pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hMem); + pDdh = GlobalLock(hMem); if (!pDdh) { GlobalFree(hMem); @@ -1285,7 +1327,7 @@ HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, DWORD c GlobalUnlock(hMem); TRACE("=> %p\n", hMem); - return (HDDEDATA)hMem; + return hMem; } /***************************************************************** @@ -1381,7 +1423,7 @@ LPBYTE WINAPI DdeAccessData(HDDEDATA hData, LPDWORD pcbDataSize) 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 @@ BOOL WDML_IsAppOwned(HDDEDATA hData) 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 @@ BOOL WDML_IsAppOwned(HDDEDATA hData) * 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 @@ HDDEDATA WDML_Global2DataHandle(HGLOBAL hMem, WINE_DDEHEAD* p) /* 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 @@ HDDEDATA WDML_Global2DataHandle(HGLOBAL hMem, WINE_DDEHEAD* p) 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 @@ HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease, 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 @@ HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease, wdh->cfFormat = pDdh->cfFormat; GlobalUnlock(hMem); } - GlobalUnlock((HGLOBAL)hDdeData); + GlobalUnlock(hDdeData); } return hMem; @@ -1638,9 +1680,10 @@ void WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) 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 @@ WDML_CONV* WDML_AddConv(WDML_INSTANCE* pInstance, WDML_SIDE side, 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; } diff --git a/reactos/dll/win32/user32/misc/ddeclient.c b/reactos/dll/win32/user32/misc/ddeclient.c index 9d8c989e84f..77445ccd8ad 100644 --- a/reactos/dll/win32/user32/misc/ddeclient.c +++ b/reactos/dll/win32/user32/misc/ddeclient.c @@ -50,7 +50,7 @@ const WCHAR WDML_szClientConvClassW[] = {'D','d','e','C','l','i','e','n','t','U' 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 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic, 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 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic, if (pInstance->unicode) { - WNDCLASSEXW wndclass; + WNDCLASSEXW wndclass; wndclass.cbSize = sizeof(wndclass); wndclass.style = 0; @@ -135,7 +131,7 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic, } else { - WNDCLASSEXA wndclass; + WNDCLASSEXA wndclass; wndclass.cbSize = sizeof(wndclass); wndclass.style = 0; @@ -168,14 +164,10 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic, 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 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic, { 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 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic, } theEnd: - LeaveCriticalSection(&WDML_CritSect); if (aSrv) GlobalDeleteAtom(aSrv); if (aTpc) GlobalDeleteAtom(aTpc); @@ -227,14 +219,13 @@ HCONV WINAPI DdeReconnect(HCONV hConv) 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 @@ HCONV WINAPI DdeReconnect(HCONV hConv) { HWND hwndClient = pConv->hwndClient; HWND hwndServer = pConv->hwndServer; - ATOM aSrv, aTpc; SetWindowLongPtrW(pConv->hwndClient, GWL_WDML_CONVERSATION, 0); @@ -252,14 +242,10 @@ HCONV WINAPI DdeReconnect(HCONV hConv) 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 @@ HCONV WINAPI DdeReconnect(HCONV hConv) } theEnd: - LeaveCriticalSection(&WDML_CritSect); if (aSrv) GlobalDeleteAtom(aSrv); if (aTpc) GlobalDeleteAtom(aTpc); @@ -326,7 +311,7 @@ static WDML_XACT* WDML_ClientQueueAdvise(WDML_CONV* pConv, UINT wType, UINT wFmt /* 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 @@ static WDML_QUEUE_STATE WDML_HandleAdviseReply(WDML_CONV* pConv, MSG* msg, WDML_ 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 @@ static WDML_QUEUE_STATE WDML_HandleUnadviseReply(WDML_CONV* pConv, MSG* msg, WDM 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 @@ static WDML_QUEUE_STATE WDML_HandleRequestReply(WDML_CONV* pConv, MSG* msg, WDML 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 @@ static WDML_QUEUE_STATE WDML_HandleRequestReply(WDML_CONV* pConv, MSG* msg, WDML 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 @@ static HGLOBAL WDML_BuildExecuteCommand(WDML_CONV* pConv, LPCVOID pData, DWORD c { 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 @@ static HGLOBAL WDML_BuildExecuteCommand(WDML_CONV* pConv, LPCVOID pData, DWORD c { 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,19 +617,28 @@ static HGLOBAL WDML_BuildExecuteCommand(WDML_CONV* pConv, LPCVOID pData, DWORD c * * */ -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) return NULL; if (cbData == (DWORD)-1) { - HDDEDATA hDdeData = (HDDEDATA)pData; + HDDEDATA hDdeData = pData; pData = DdeAccessData(hDdeData, &cbData); if (pData) @@ -673,7 +667,7 @@ static WDML_QUEUE_STATE WDML_HandleExecuteReply(WDML_CONV* pConv, MSG* msg, WDML 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_QUEUE_STATE WDML_HandleExecuteReply(WDML_CONV* pConv, MSG* msg, WDML * * */ -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,29 +712,33 @@ static WDML_XACT* WDML_ClientQueuePoke(WDML_CONV* pConv, LPCVOID pData, DWORD cb 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; + hglobal = pData; + dh = GlobalLock(hglobal); + cbData = GlobalSize(hglobal) - sizeof(DDE_DATAHANDLE_HEAD); + pData = dh + 1; + GlobalUnlock(hglobal); } - 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); - } + 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); return pXAct; @@ -753,7 +754,7 @@ static WDML_QUEUE_STATE WDML_HandlePokeReply(WDML_CONV* pConv, MSG* msg, WDML_XA 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 @@ static WDML_XACT* WDML_ClientQueueTerminate(WDML_CONV* pConv) * * 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 @@ static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg, WD 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 @@ static WDML_QUEUE_STATE WDML_HandleTerminateReply(WDML_CONV* pConv, MSG* msg, WD } /****************************************************************** - * WDML_HandleReplyData + * WDML_HandleIncomingData * * */ @@ -840,7 +841,7 @@ static WDML_QUEUE_STATE WDML_HandleIncomingData(WDML_CONV* pConv, MSG* msg, HDDE 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_HandleIncomingData(WDML_CONV* pConv, MSG* msg, HDDE */ 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 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h if (pConv->transactions) { + if (ack) *ack = DDE_FNOTPROCESSED; /* first check message against a pending transaction, if any */ switch (pXAct->ddeMsg) { @@ -940,7 +937,7 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h 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 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h 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 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h { *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 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h 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 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h * 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 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, WDML 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 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, WDML if (ret) { pConv->instance->lastError = hdd ? DMLERR_NO_ERROR : DMLERR_NOTPROCESSED; - LeaveCriticalSection(&WDML_CritSect); return hdd; } } else { - LeaveCriticalSection(&WDML_CritSect); DispatchMessageW(&msg); } } @@ -1068,8 +1065,6 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, WDML TRACE("Timeout !!\n"); - EnterCriticalSection(&WDML_CritSect); - pConv = WDML_GetConv(hConv, FALSE); if (pConv != NULL) { @@ -1088,11 +1083,11 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, WDML pConv->instance->lastError = err; } } - LeaveCriticalSection(&WDML_CritSect); return 0; } + /***************************************************************** * WDML_ClientHandle */ @@ -1124,6 +1119,7 @@ HDDEDATA WDML_ClientHandle(WDML_CONV *pConv, WDML_XACT *pXAct, DWORD dwTimeout, return hDdeData; } + /***************************************************************** * DdeClientTransaction (USER32.@) */ @@ -1134,7 +1130,7 @@ HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HS 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 @@ HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HS 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 @@ HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HS if (pData) { pConv->instance->lastError = DMLERR_INVALIDPARAMETER; - goto theError; + return 0; } pXAct = WDML_ClientQueueAdvise(pConv, wType, wFmt, hszItem); break; @@ -1176,70 +1177,49 @@ HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HS 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 */ + TRACE("pConv->wStatus %04x\n", pConv->wStatus); - if (dwTimeout == TIMEOUT_ASYNC) + if (pConv->wStatus & ST_BLOCKED) { - if (pdwResult) - { - *pdwResult = MAKELONG(0, pXAct->xActID); - } - hDdeData = (HDDEDATA)1; + TRACE("Transactions are blocked, add to the queue and exit\n"); + return (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); + hDdeData = WDML_ClientHandle(pConv, pXAct, dwTimeout, pdwResult); + if (dwTimeout != TIMEOUT_ASYNC) + { + WDML_UnQueueTransaction(pConv, pXAct); + WDML_FreeTransaction(pConv->instance, pXAct, TRUE); } - LeaveCriticalSection(&WDML_CritSect); return hDdeData; - theError: - LeaveCriticalSection(&WDML_CritSect); - return 0; } /***************************************************************** @@ -1251,9 +1231,6 @@ BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction 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 @@ BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction } } } - LeaveCriticalSection(&WDML_CritSect); return TRUE; } @@ -1347,8 +1323,6 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA pConv->wStatus |= ST_ISLOCAL; } - WDML_BroadcastDDEWindows(WDML_szEventClass, WM_WDML_CONNECT_CONFIRM, (WPARAM)hwnd, wParam); - GlobalDeleteAtom(uiLo); GlobalDeleteAtom(uiHi); @@ -1358,8 +1332,6 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA if (iMsg >= WM_DDE_FIRST && iMsg <= WM_DDE_LAST) { - EnterCriticalSection(&WDML_CritSect); - pConv = WDML_GetConvFromWnd(hwnd); if (pConv) @@ -1375,7 +1347,6 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA WDML_HandleReply(pConv, &msg, &hdd, NULL); } - LeaveCriticalSection(&WDML_CritSect); return 0; } @@ -1390,7 +1361,6 @@ BOOL WINAPI DdeDisconnect(HCONV hConv) { WDML_CONV* pConv = NULL; WDML_XACT* pXAct; - DWORD count, i; BOOL ret = FALSE; TRACE("(%p)\n", hConv); @@ -1401,7 +1371,6 @@ BOOL WINAPI DdeDisconnect(HCONV hConv) return FALSE; } - EnterCriticalSection(&WDML_CritSect); pConv = WDML_GetConv(hConv, TRUE); if (pConv != NULL) { @@ -1411,17 +1380,17 @@ BOOL WINAPI DdeDisconnect(HCONV hConv) 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 @@ BOOL WINAPI DdeDisconnect(HCONV hConv) } } } - LeaveCriticalSection(&WDML_CritSect); return ret; } @@ -1445,12 +1413,10 @@ BOOL WINAPI DdeImpersonateClient(HCONV hConv) 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; } diff --git a/reactos/dll/win32/user32/misc/ddeserver.c b/reactos/dll/win32/user32/misc/ddeserver.c index 31db147cb45..087431a8931 100644 --- a/reactos/dll/win32/user32/misc/ddeserver.c +++ b/reactos/dll/win32/user32/misc/ddeserver.c @@ -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 @@ -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 @@ BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem) 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 @@ BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem) 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 @@ BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem) { 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 @@ BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem) } } } - LeaveCriticalSection(&WDML_CritSect); return TRUE; + theError: - LeaveCriticalSection(&WDML_CritSect); if (atom) GlobalDeleteAtom(atom); return FALSE; } @@ -161,15 +157,10 @@ HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd) { 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 @@ HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd) { 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 @@ HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd) */ pInstance->lastError = DMLERR_INVALIDPARAMETER; WARN("Reserved parameter no-zero !!\n"); - goto theError; + return NULL; } if (hsz1 == 0 && !(afCmd & DNS_UNREGISTER)) { @@ -196,7 +187,7 @@ HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd) */ TRACE("General unregister unexpected flags\n"); pInstance->lastError = DMLERR_INVALIDPARAMETER; - goto theError; + return NULL; } switch (afCmd & (DNS_REGISTER | DNS_UNREGISTER)) @@ -207,7 +198,7 @@ HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd) { 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 @@ HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd) 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 @@ HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd) /* 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 @@ static WDML_CONV* WDML_CreateServerConv(WDML_INSTANCE* pInstance, HWND hwndClien if (pInstance->unicode) { - WNDCLASSEXW wndclass; + 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; + 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); + RegisterClassExW(&wndclass); - hwndServerConv = CreateWindowW(WDML_szServerConvClassW, 0, + hwndServerConv = CreateWindowW(WDML_szServerConvClassW, 0, WS_CHILD, 0, 0, 0, 0, hwndServerName, 0, 0, 0); } else { - WNDCLASSEXA wndclass; + 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; + 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); + RegisterClassExA(&wndclass); - hwndServerConv = CreateWindowA(WDML_szServerConvClassA, 0, - WS_CHILD, 0, 0, 0, 0, - hwndServerName, 0, 0, 0); + 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); + 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 @@ static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM w 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 @@ 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 ((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 @@ static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM w 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 @@ static WDML_QUEUE_STATE WDML_ServerHandleRequest(WDML_CONV* pConv, WDML_XACT* pX 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 @@ static WDML_QUEUE_STATE WDML_ServerHandleAdvise(WDML_CONV* pConv, WDML_XACT* pXA 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 @@ static WDML_QUEUE_STATE WDML_ServerHandleExecute(WDML_CONV* pConv, WDML_XACT* pX 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 @@ static WDML_QUEUE_STATE WDML_ServerHandleExecute(WDML_CONV* pConv, WDML_XACT* pX 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 @@ static WDML_QUEUE_STATE WDML_ServerHandlePoke(WDML_CONV* pConv, WDML_XACT* pXAct 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 @@ static WDML_QUEUE_STATE WDML_ServerHandlePoke(WDML_CONV* pConv, WDML_XACT* pXAct 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,43 +968,39 @@ static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM w 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); if (!pConv) { ERR("Got a message (%x) on a not known conversation, dropping request\n", iMsg); - goto theError; + return 0; } - if (pConv->hwndClient != (HWND)wParam || pConv->hwndServer != hwndServer) + if (pConv->hwndClient != WIN_GetFullHandle( (HWND)wParam ) || pConv->hwndServer != hwndServer) { - ERR("mismatch between C/S windows and converstation\n"); - goto theError; + 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 @@ static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM w 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 @@ static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM w WDML_FreeTransaction(pInstance, pXAct, TRUE); } } - theError: - LeaveCriticalSection(&WDML_CritSect); + else + pConv->instance->lastError = DMLERR_MEMORY_ERROR; + return 0; }