Fixed initialisation messages for raw DDE.
Fixed DdeCreateDataHandle for non NULL or CF_TEXT formats. Various fixes (cosmetics, better error checking).
This commit is contained in:
parent
0faceb05fc
commit
01ff68943d
|
@ -46,8 +46,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, LPCONVCONTEXT pCC)
|
||||
{
|
||||
FIXME("(%ld,%d,%d,%d,%p): stub\n", idInst, hszService, hszTopic,
|
||||
hConvList, pCC);
|
||||
FIXME("(%ld,%d,%d,%d,%p): stub\n", idInst, hszService, hszTopic, hConvList, pCC);
|
||||
return (HCONVLIST)1;
|
||||
}
|
||||
|
||||
|
@ -84,7 +83,6 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic,
|
|||
LPCONVCONTEXT pCC)
|
||||
{
|
||||
HWND hwndClient;
|
||||
LPARAM lParam = 0;
|
||||
WDML_INSTANCE* pInstance;
|
||||
WDML_CONV* pConv = NULL;
|
||||
ATOM aSrv = 0, aTpc = 0;
|
||||
|
@ -168,9 +166,8 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic,
|
|||
|
||||
LeaveCriticalSection(&WDML_CritSect);
|
||||
|
||||
lParam = PackDDElParam(WM_DDE_INITIATE, aSrv, aTpc);
|
||||
SendMessageA(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwndClient, lParam);
|
||||
FreeDDElParam(WM_DDE_INITIATE, lParam);
|
||||
/* note: sent messages shall not use packing */
|
||||
SendMessageA(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwndClient, MAKELPARAM(aSrv, aTpc));
|
||||
|
||||
EnterCriticalSection(&WDML_CritSect);
|
||||
|
||||
|
@ -180,17 +177,17 @@ HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic,
|
|||
goto theEnd;
|
||||
}
|
||||
|
||||
TRACE("WM_DDE_INITIATE was processed\n");
|
||||
/* At this point, Client WM_DDE_ACK should have saved hwndServer
|
||||
for this instance id and hwndClient if server responds.
|
||||
So get HCONV and return it. And add it to conv list */
|
||||
pConv = WDML_GetConvFromWnd(hwndClient);
|
||||
if (pConv == NULL || pConv->hwndServer == 0)
|
||||
{
|
||||
ERR(".. but no Server window available\n");
|
||||
ERR("Done with INITIATE, but no Server window available\n");
|
||||
pConv = NULL;
|
||||
goto theEnd;
|
||||
}
|
||||
TRACE("Connected to Server window (%x)\n", pConv->hwndServer);
|
||||
pConv->wConvst = XST_CONNECTED;
|
||||
|
||||
/* finish init of pConv */
|
||||
|
@ -227,7 +224,6 @@ HCONV WINAPI DdeReconnect(HCONV hConv)
|
|||
pConv = WDML_GetConv(hConv, FALSE);
|
||||
if (pConv != NULL && (pConv->wStatus & ST_CLIENT))
|
||||
{
|
||||
LPARAM lParam;
|
||||
BOOL ret;
|
||||
|
||||
/* to reestablist a connection, we have to make sure that:
|
||||
|
@ -251,9 +247,9 @@ HCONV WINAPI DdeReconnect(HCONV hConv)
|
|||
|
||||
LeaveCriticalSection(&WDML_CritSect);
|
||||
|
||||
lParam = PackDDElParam(WM_DDE_INITIATE, aSrv, aTpc);
|
||||
ret = SendMessageA(hwndServer, WM_DDE_INITIATE, (WPARAM)hwndClient, lParam);
|
||||
FreeDDElParam(WM_DDE_INITIATE, lParam);
|
||||
/* note: sent messages shall not use packing */
|
||||
ret = SendMessageA(hwndServer, WM_DDE_INITIATE, (WPARAM)hwndClient,
|
||||
MAKELPARAM(aSrv, aTpc));
|
||||
|
||||
EnterCriticalSection(&WDML_CritSect);
|
||||
|
||||
|
@ -320,7 +316,8 @@ static WDML_XACT* WDML_ClientQueueAdvise(WDML_CONV* pConv, UINT wType, UINT wFmt
|
|||
|
||||
pXAct->wType = wType & ~0x0F;
|
||||
pXAct->hMem = GlobalAlloc(GHND | GMEM_DDESHARE, sizeof(DDEADVISE));
|
||||
|
||||
/* FIXME: hMem is unfreed for now... should be deleted in server */
|
||||
|
||||
/* pack DdeAdvise */
|
||||
pDdeAdvise = (DDEADVISE*)GlobalLock(pXAct->hMem);
|
||||
pDdeAdvise->fAckReq = (wType & XTYPF_ACKREQ) ? TRUE : FALSE;
|
||||
|
@ -366,7 +363,7 @@ static WDML_QUEUE_STATE WDML_HandleAdviseReply(WDML_CONV* pConv, MSG* msg, WDML_
|
|||
|
||||
/* billx: first to see if the link is already created. */
|
||||
pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE,
|
||||
pXAct->hszItem, pXAct->wFmt);
|
||||
pXAct->hszItem, TRUE, pXAct->wFmt);
|
||||
if (pLink != NULL)
|
||||
{
|
||||
/* we found a link, and only need to modify it in case it changes */
|
||||
|
@ -377,14 +374,15 @@ static WDML_QUEUE_STATE WDML_HandleAdviseReply(WDML_CONV* pConv, MSG* msg, WDML_
|
|||
WDML_AddLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE,
|
||||
pXAct->wType, pXAct->hszItem, pXAct->wFmt);
|
||||
}
|
||||
pXAct->hDdeData = (HDDEDATA)1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Returning TRUE on XTYP_ADVSTART - fAck was FALSE\n");
|
||||
TRACE("Returning FALSE on XTYP_ADVSTART - fAck was FALSE\n");
|
||||
GlobalFree(pXAct->hMem);
|
||||
pXAct->hDdeData = (HDDEDATA)0;
|
||||
}
|
||||
|
||||
pXAct->hDdeData = (HDDEDATA)1;
|
||||
return WDML_QS_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -448,15 +446,16 @@ static WDML_QUEUE_STATE WDML_HandleUnadviseReply(WDML_CONV* pConv, MSG* msg, WDM
|
|||
|
||||
if (!ddeAck.fAck)
|
||||
{
|
||||
TRACE("Returning TRUE on XTYP_ADVSTOP - fAck was FALSE\n");
|
||||
TRACE("Returning FALSE on XTYP_ADVSTOP - fAck was FALSE\n");
|
||||
pXAct->hDdeData = (HDDEDATA)0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* billx: remove the link */
|
||||
WDML_RemoveLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE,
|
||||
pXAct->hszItem, pXAct->wFmt);
|
||||
pXAct->hDdeData = (HDDEDATA)1;
|
||||
}
|
||||
pXAct->hDdeData = (HDDEDATA)1;
|
||||
return WDML_QS_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -501,11 +500,12 @@ static WDML_QUEUE_STATE WDML_HandleRequestReply(WDML_CONV* pConv, MSG* msg, WDML
|
|||
|
||||
if (WIN_GetFullHandle(msg->wParam) != pConv->hwndServer)
|
||||
return WDML_QS_PASS;
|
||||
UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);
|
||||
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_DDE_ACK:
|
||||
UnpackDDElParam(WM_DDE_ACK, msg->lParam, &uiLo, &uiHi);
|
||||
FreeDDElParam(WM_DDE_ACK, msg->lParam);
|
||||
GlobalDeleteAtom(uiHi);
|
||||
WDML_ExtractAck(uiLo, &ddeAck);
|
||||
pXAct->hDdeData = 0;
|
||||
|
@ -515,6 +515,7 @@ static WDML_QUEUE_STATE WDML_HandleRequestReply(WDML_CONV* pConv, MSG* msg, WDML
|
|||
break;
|
||||
|
||||
case WM_DDE_DATA:
|
||||
UnpackDDElParam(WM_DDE_DATA, msg->lParam, &uiLo, &uiHi);
|
||||
TRACE("Got the result (%08lx)\n", (DWORD)uiLo);
|
||||
|
||||
hsz = WDML_MakeHszFromAtom(pConv->instance, uiHi);
|
||||
|
@ -522,7 +523,6 @@ static WDML_QUEUE_STATE WDML_HandleRequestReply(WDML_CONV* pConv, MSG* msg, WDML
|
|||
if (DdeCmpStringHandles(hsz, pXAct->hszItem) != 0)
|
||||
return WDML_QS_PASS;
|
||||
|
||||
/* FIXME: memory clean up ? */
|
||||
pXAct->hDdeData = WDML_Global2DataHandle((HGLOBAL)uiLo, &wdh);
|
||||
if (wdh.fRelease)
|
||||
{
|
||||
|
@ -530,16 +530,17 @@ static WDML_QUEUE_STATE WDML_HandleRequestReply(WDML_CONV* pConv, MSG* msg, WDML
|
|||
}
|
||||
if (wdh.fAckReq)
|
||||
{
|
||||
WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, (HSZ)uiHi, msg->lParam,
|
||||
WM_DDE_DATA);
|
||||
WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi, msg->lParam, WM_DDE_DATA);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalDeleteAtom(uiHi);
|
||||
FreeDDElParam(WM_DDE_ACK, msg->lParam);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FreeDDElParam(msg->message, msg->lParam);
|
||||
return WDML_QS_PASS;
|
||||
}
|
||||
|
||||
|
@ -669,15 +670,12 @@ static WDML_QUEUE_STATE WDML_HandleExecuteReply(WDML_CONV* pConv, MSG* msg, WDML
|
|||
|
||||
if (uiHi != pXAct->hMem)
|
||||
{
|
||||
return WDML_QS_PASS;
|
||||
return WDML_QS_PASS;
|
||||
}
|
||||
|
||||
WDML_ExtractAck(uiLo, &ddeAck);
|
||||
if (!ddeAck.fAck)
|
||||
{
|
||||
GlobalFree(pXAct->hMem);
|
||||
}
|
||||
pXAct->hDdeData = (HDDEDATA)1;
|
||||
pXAct->hDdeData = (HDDEDATA)ddeAck.fAck;
|
||||
|
||||
return WDML_QS_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -832,17 +830,18 @@ static WDML_QUEUE_STATE WDML_HandleIncomingData(WDML_CONV* pConv, MSG* msg, HDDE
|
|||
* For hot link, data should be passed to its callback with
|
||||
* XTYP_ADVDATA and callback should return the proper status.
|
||||
*/
|
||||
pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, hsz, wdh.cfFormat);
|
||||
pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, hsz,
|
||||
uiLo ? TRUE : FALSE, wdh.cfFormat);
|
||||
if (!pLink)
|
||||
{
|
||||
WDML_DecHSZ(pConv->instance, hsz);
|
||||
DdeFreeDataHandle(hDdeDataIn);
|
||||
return WDML_QS_PASS;
|
||||
}
|
||||
|
||||
if (hDdeDataIn != 0 && wdh.fAckReq)
|
||||
{
|
||||
WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi,
|
||||
msg->lParam, WM_DDE_DATA);
|
||||
WDML_PostAck(pConv, WDML_CLIENT_SIDE, 0, FALSE, TRUE, uiHi, msg->lParam, WM_DDE_DATA);
|
||||
if (msg->lParam)
|
||||
msg->lParam = 0;
|
||||
}
|
||||
|
@ -853,14 +852,16 @@ static WDML_QUEUE_STATE WDML_HandleIncomingData(WDML_CONV* pConv, MSG* msg, HDDE
|
|||
|
||||
hDdeDataOut = WDML_InvokeCallback(pConv->instance, XTYP_ADVDATA, pLink->uFmt, pLink->hConv,
|
||||
pConv->hszTopic, pLink->hszItem, hDdeDataIn, 0, 0);
|
||||
if (hDdeDataOut == (HDDEDATA)DDE_FACK)
|
||||
|
||||
if (hDdeDataOut != (HDDEDATA)DDE_FACK || wdh.fRelease)
|
||||
{
|
||||
pLink->hDdeData = hDdeDataIn;
|
||||
}
|
||||
if (wdh.fRelease)
|
||||
{
|
||||
DdeFreeDataHandle(hDdeDataIn);
|
||||
if (uiLo)
|
||||
{
|
||||
GlobalFree(uiLo);
|
||||
}
|
||||
}
|
||||
|
||||
DdeFreeDataHandle(hDdeDataIn);
|
||||
|
||||
WDML_DecHSZ(pConv->instance, hsz);
|
||||
if (msg->lParam)
|
||||
|
@ -961,10 +962,10 @@ static WDML_QUEUE_STATE WDML_HandleReply(WDML_CONV* pConv, MSG* msg, HDDEDATA* h
|
|||
{
|
||||
*hdd = pXAct->hDdeData;
|
||||
}
|
||||
WDML_FreeTransaction(pConv->instance, pXAct, FALSE); /* FIXME: should we free intermediate pmts ? */
|
||||
WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
|
||||
break;
|
||||
case WDML_QS_PASS:
|
||||
/* no pending transaction found, try a warm link or a termination request */
|
||||
/* no pending transaction found, try a warm/hot link or a termination request */
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_DDE_DATA:
|
||||
|
@ -1006,7 +1007,7 @@ static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, WDML
|
|||
* single process they need to share the access to the internal data
|
||||
*/
|
||||
if (MsgWaitForMultipleObjects(0, NULL, FALSE,
|
||||
dwTime - dwTimeout, QS_POSTMESSAGE) == WAIT_OBJECT_0)
|
||||
dwTimeout - dwTime, QS_POSTMESSAGE) == WAIT_OBJECT_0)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
MSG msg;
|
||||
|
@ -1156,7 +1157,6 @@ HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HS
|
|||
WDML_UnQueueTransaction(pConv, pXAct);
|
||||
WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
|
||||
goto theError;
|
||||
|
||||
}
|
||||
pXAct->dwTimeout = dwTimeout;
|
||||
/* FIXME: should set the app bits on *pdwResult */
|
||||
|
@ -1192,6 +1192,56 @@ HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, HCONV hConv, HS
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* DdeAbandonTransaction (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction)
|
||||
{
|
||||
WDML_INSTANCE* pInstance;
|
||||
WDML_CONV* pConv;
|
||||
WDML_XACT* pXAct;
|
||||
|
||||
TRACE("(%08lx,%08lx,%08ld);\n", idInst, (DWORD)hConv, idTransaction);
|
||||
|
||||
EnterCriticalSection(&WDML_CritSect);
|
||||
if ((pInstance = WDML_GetInstance(idInst)))
|
||||
{
|
||||
if (hConv)
|
||||
{
|
||||
if ((pConv = WDML_GetConv(hConv, TRUE)) && pConv->instance == pInstance)
|
||||
{
|
||||
for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
|
||||
{
|
||||
if (pXAct->dwTimeout == TIMEOUT_ASYNC &&
|
||||
(idTransaction == 0 || pXAct->xActID == idTransaction))
|
||||
{
|
||||
WDML_UnQueueTransaction(pConv, pXAct);
|
||||
WDML_FreeTransaction(pInstance, pXAct, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (pConv = pInstance->convs[WDML_CLIENT_SIDE]; pConv; pConv = pConv->next)
|
||||
{
|
||||
if (!pConv->wStatus & ST_CONNECTED) continue;
|
||||
for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
|
||||
{
|
||||
if (pXAct->dwTimeout == TIMEOUT_ASYNC)
|
||||
{
|
||||
WDML_UnQueueTransaction(pConv, pXAct);
|
||||
WDML_FreeTransaction(pInstance, pXAct, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&WDML_CritSect);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* WDML_ClientProc
|
||||
*
|
||||
|
@ -1204,7 +1254,6 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA
|
|||
HSZ hszSrv, hszTpc;
|
||||
|
||||
if (iMsg == WM_DDE_ACK &&
|
||||
UnpackDDElParam(WM_DDE_ACK, lParam, &uiLo, &uiHi) &&
|
||||
/* in the initial WM_INITIATE sendmessage */
|
||||
((pConv = WDML_GetConvFromWnd(hwnd)) == NULL || pConv->wStatus == XST_INIT1))
|
||||
{
|
||||
|
@ -1212,7 +1261,9 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA
|
|||
char buf[256];
|
||||
WDML_INSTANCE* pInstance;
|
||||
|
||||
FreeDDElParam(WM_DDE_ACK, lParam);
|
||||
/* note: sent messages do not need packing */
|
||||
uiLo = LOWORD(lParam);
|
||||
uiHi = HIWORD(lParam);
|
||||
|
||||
/* FIXME: convlist should be handled here */
|
||||
if (pConv)
|
||||
|
@ -1220,6 +1271,7 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA
|
|||
/* we already have started the conv with a server, drop other replies */
|
||||
GlobalDeleteAtom(uiLo);
|
||||
GlobalDeleteAtom(uiHi);
|
||||
PostMessageA((HWND)wParam, WM_DDE_TERMINATE, (WPARAM)hwnd, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1228,8 +1280,7 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA
|
|||
hszSrv = WDML_MakeHszFromAtom(pInstance, uiLo);
|
||||
hszTpc = WDML_MakeHszFromAtom(pInstance, uiHi);
|
||||
|
||||
pConv = WDML_AddConv(pInstance, WDML_CLIENT_SIDE, hszSrv, hszTpc,
|
||||
hwnd, (HWND)wParam);
|
||||
pConv = WDML_AddConv(pInstance, WDML_CLIENT_SIDE, hszSrv, hszTpc, hwnd, (HWND)wParam);
|
||||
|
||||
SetWindowLongA(hwnd, GWL_WDML_CONVERSATION, (DWORD)pConv);
|
||||
pConv->wStatus |= ST_CONNECTED;
|
||||
|
@ -1280,15 +1331,6 @@ static LRESULT CALLBACK WDML_ClientProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPA
|
|||
DefWindowProcA(hwnd, iMsg, wParam, lParam) : DefWindowProcW(hwnd, iMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* DdeAbandonTransaction (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction)
|
||||
{
|
||||
FIXME("empty stub\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* DdeDisconnect (USER32.@)
|
||||
*/
|
||||
|
@ -1308,33 +1350,33 @@ BOOL WINAPI DdeDisconnect(HCONV hConv)
|
|||
}
|
||||
|
||||
EnterCriticalSection(&WDML_CritSect);
|
||||
pConv = WDML_GetConv(hConv, FALSE);
|
||||
pConv = WDML_GetConv(hConv, TRUE);
|
||||
if (pConv != NULL)
|
||||
{
|
||||
if (pConv->wStatus & ST_CONNECTED)
|
||||
{
|
||||
if (pConv->wStatus & ST_CLIENT)
|
||||
{
|
||||
/* FIXME: should abandon all pending transactions */
|
||||
pXAct = WDML_ClientQueueTerminate(pConv);
|
||||
if (pXAct != NULL)
|
||||
{
|
||||
count = WDML_CritSect.RecursionCount;
|
||||
for (i = 0; i < count; i++)
|
||||
LeaveCriticalSection(&WDML_CritSect);
|
||||
WDML_SyncWaitTransactionReply(hConv, 10000, pXAct);
|
||||
for (i = 0; i < count; i++)
|
||||
EnterCriticalSection(&WDML_CritSect);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Not implemented yet for a server side conversation\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* still have to destroy data assosiated with conversation */
|
||||
WDML_RemoveConv(pConv, WDML_CLIENT_SIDE);
|
||||
if (pConv->wStatus & ST_CLIENT)
|
||||
{
|
||||
/* FIXME: should abandon all pending transactions */
|
||||
pXAct = WDML_ClientQueueTerminate(pConv);
|
||||
if (pXAct != NULL)
|
||||
{
|
||||
count = WDML_CritSect.RecursionCount;
|
||||
for (i = 0; i < count; i++)
|
||||
LeaveCriticalSection(&WDML_CritSect);
|
||||
if (PostMessageA(pConv->hwndServer, pXAct->ddeMsg,
|
||||
(WPARAM)pConv->hwndClient, pXAct->lParam))
|
||||
WDML_SyncWaitTransactionReply(hConv, 10000, pXAct);
|
||||
for (i = 0; i < count; i++)
|
||||
EnterCriticalSection(&WDML_CritSect);
|
||||
ret = TRUE;
|
||||
WDML_FreeTransaction(pConv->instance, pXAct, TRUE);
|
||||
/* still have to destroy data assosiated with conversation */
|
||||
WDML_RemoveConv(pConv, WDML_CLIENT_SIDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Not implemented yet for a server side conversation\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&WDML_CritSect);
|
||||
|
||||
|
|
|
@ -132,7 +132,6 @@ typedef struct tagWDML_LINK {
|
|||
UINT transactionType;/* 0 for no link */
|
||||
HSZ hszItem; /* item targetted for (hot/warm) link */
|
||||
UINT uFmt; /* format for data */
|
||||
HDDEDATA hDdeData; /* data them selves */
|
||||
} WDML_LINK;
|
||||
|
||||
typedef struct tagWDML_INSTANCE
|
||||
|
@ -161,6 +160,7 @@ extern CRITICAL_SECTION WDML_CritSect; /* protection for instance list */
|
|||
typedef struct tagDDE_DATAHANDLE_HEAD
|
||||
{
|
||||
short cfFormat;
|
||||
WORD bAppOwned;
|
||||
} DDE_DATAHANDLE_HEAD;
|
||||
|
||||
typedef enum tagWDML_SIDE
|
||||
|
@ -191,12 +191,12 @@ extern WDML_CONV* WDML_GetConv(HCONV hConv, BOOL checkConnected);
|
|||
extern WDML_CONV* WDML_GetConvFromWnd(HWND hWnd);
|
||||
extern WDML_CONV* WDML_FindConv(WDML_INSTANCE* pInstance, WDML_SIDE side,
|
||||
HSZ hszService, HSZ hszTopic);
|
||||
extern LPARAM WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode,
|
||||
BOOL fBusy, BOOL fAck, ATOM atom, LPARAM lParam, UINT oldMsg);
|
||||
extern BOOL WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode,
|
||||
BOOL fBusy, BOOL fAck, UINT pmt, LPARAM lParam, UINT oldMsg);
|
||||
extern void WDML_AddLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
|
||||
UINT wType, HSZ hszItem, UINT wFmt);
|
||||
extern WDML_LINK* WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
|
||||
HSZ hszItem, UINT uFmt);
|
||||
HSZ hszItem, BOOL use_fmt, UINT uFmt);
|
||||
extern void WDML_RemoveLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
|
||||
HSZ hszItem, UINT wFmt);
|
||||
extern void WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE side);
|
||||
|
@ -215,6 +215,7 @@ 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 BOOL WDML_IsAppOwned(HDDEDATA hDdeData);
|
||||
extern WDML_INSTANCE* WDML_GetInstance(DWORD InstId);
|
||||
extern WDML_INSTANCE* WDML_GetInstanceFromWnd(HWND hWnd);
|
||||
/* broadcasting to DDE windows */
|
||||
|
|
|
@ -86,7 +86,7 @@ LPARAM WINAPI PackDDElParam(UINT msg, UINT uiLo, UINT uiHi)
|
|||
params = GlobalLock(hMem);
|
||||
if (params == NULL)
|
||||
{
|
||||
ERR("GlobalLock failed\n");
|
||||
ERR("GlobalLock failed (%x)\n", hMem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ BOOL WINAPI UnpackDDElParam(UINT msg, LPARAM lParam,
|
|||
params = GlobalLock(hMem);
|
||||
if (params == NULL)
|
||||
{
|
||||
ERR("GlobalLock failed\n");
|
||||
ERR("GlobalLock failed (%x)\n", hMem);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -383,9 +383,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
|
|||
|
||||
if (!pInstance->clientOnly)
|
||||
{
|
||||
|
||||
/* Check for other way of setting Client-only !! */
|
||||
|
||||
pInstance->clientOnly =
|
||||
(pInstance->CBFflags & CBF_FAIL_ALLSVRXACTIONS) == CBF_FAIL_ALLSVRXACTIONS;
|
||||
}
|
||||
|
@ -622,7 +620,6 @@ BOOL WINAPI DdeUninitialize(DWORD idInst)
|
|||
/* Stage one - check if we have a handle for this instance
|
||||
*/
|
||||
WDML_INSTANCE* pInstance;
|
||||
WDML_INSTANCE* reference_inst;
|
||||
WDML_CONV* pConv;
|
||||
WDML_CONV* pConvNext;
|
||||
|
||||
|
@ -665,20 +662,16 @@ BOOL WINAPI DdeUninitialize(DWORD idInst)
|
|||
|
||||
if (WDML_InstanceList == pInstance)
|
||||
{
|
||||
/* special case - the first/only entry
|
||||
*/
|
||||
/* special case - the first/only entry */
|
||||
WDML_InstanceList = pInstance->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* general case
|
||||
*/
|
||||
reference_inst = WDML_InstanceList;
|
||||
while (reference_inst->next != pInstance)
|
||||
{
|
||||
reference_inst = pInstance->next;
|
||||
}
|
||||
reference_inst->next = pInstance->next;
|
||||
/* general case, remove entry */
|
||||
WDML_INSTANCE* inst;
|
||||
|
||||
for (inst = WDML_InstanceList; inst->next != pInstance; inst = inst->next);
|
||||
inst->next = pInstance->next;
|
||||
}
|
||||
/* leave crit sect and release the heap entry
|
||||
*/
|
||||
|
@ -849,7 +842,7 @@ ATOM WDML_MakeAtomFromHsz(HSZ hsz)
|
|||
|
||||
if (GetAtomNameW((ATOM)hsz, nameBuffer, MAX_BUFFER_LEN))
|
||||
return GlobalAddAtomW(nameBuffer);
|
||||
WARN("HSZ 0x%xnot found\n", hsz);
|
||||
WARN("HSZ 0x%x not found\n", hsz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -864,8 +857,15 @@ HSZ WDML_MakeHszFromAtom(WDML_INSTANCE* pInstance, ATOM atom)
|
|||
{
|
||||
WCHAR nameBuffer[MAX_BUFFER_LEN];
|
||||
|
||||
GlobalGetAtomNameW(atom, nameBuffer, MAX_BUFFER_LEN);
|
||||
return DdeCreateStringHandleW(pInstance->instanceID, nameBuffer, CP_WINUNICODE);
|
||||
if (!atom) return (HSZ)0;
|
||||
|
||||
if (GlobalGetAtomNameW(atom, nameBuffer, MAX_BUFFER_LEN))
|
||||
{
|
||||
TRACE("%x => %s\n", atom, debugstr_w(nameBuffer));
|
||||
return DdeCreateStringHandleW(pInstance->instanceID, nameBuffer, CP_WINUNICODE);
|
||||
}
|
||||
WARN("ATOM 0x%x not found\n", atom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
@ -914,12 +914,12 @@ BOOL WDML_DecHSZ(WDML_INSTANCE* pInstance, HSZ hsz)
|
|||
pPrev->next = pCurrent->next;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, pCurrent);
|
||||
DeleteAtom(hsz);
|
||||
DeleteAtom((ATOM)hsz);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
WARN("HSZ 0x%xnot found\n", hsz);
|
||||
WARN("HSZ 0x%x not found\n", hsz);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -989,10 +989,10 @@ static int WDML_QueryString(WDML_INSTANCE* pInstance, HSZ hsz, LPVOID ptr, DWORD
|
|||
switch (codepage)
|
||||
{
|
||||
case CP_WINANSI:
|
||||
ret = GetAtomNameA(hsz, ptr, cchMax);
|
||||
ret = GetAtomNameA((ATOM)hsz, ptr, cchMax);
|
||||
break;
|
||||
case CP_WINUNICODE:
|
||||
ret = GetAtomNameW(hsz, ptr, cchMax);
|
||||
ret = GetAtomNameW((ATOM)hsz, ptr, cchMax);
|
||||
default:
|
||||
ERR("Unknown code page %d\n", codepage);
|
||||
ret = 0;
|
||||
|
@ -1035,8 +1035,7 @@ DWORD WINAPI DdeQueryStringW(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, IN
|
|||
DWORD ret = 0;
|
||||
WDML_INSTANCE* pInstance;
|
||||
|
||||
TRACE("(%ld, 0x%x, %p, %ld, %d)\n",
|
||||
idInst, hsz, psz, cchMax, iCodePage);
|
||||
TRACE("(%ld, 0x%x, %p, %ld, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
|
||||
|
||||
EnterCriticalSection(&WDML_CritSect);
|
||||
|
||||
|
@ -1066,11 +1065,11 @@ static HSZ WDML_CreateString(WDML_INSTANCE* pInstance, LPCVOID ptr, int codepage
|
|||
switch (codepage)
|
||||
{
|
||||
case CP_WINANSI:
|
||||
hsz = AddAtomA(ptr);
|
||||
hsz = (HSZ)AddAtomA(ptr);
|
||||
TRACE("added atom %s with HSZ 0x%x, \n", debugstr_a(ptr), hsz);
|
||||
break;
|
||||
case CP_WINUNICODE:
|
||||
hsz = AddAtomW(ptr);
|
||||
hsz = (HSZ)AddAtomW(ptr);
|
||||
TRACE("added atom %s with HSZ 0x%x, \n", debugstr_w(ptr), hsz);
|
||||
break;
|
||||
default:
|
||||
|
@ -1208,8 +1207,8 @@ INT WINAPI DdeCmpStringHandles(HSZ hsz1, HSZ hsz2)
|
|||
int ret = 0;
|
||||
int ret1, ret2;
|
||||
|
||||
ret1 = GetAtomNameW(hsz1, psz1, MAX_BUFFER_LEN);
|
||||
ret2 = GetAtomNameW(hsz2, psz2, MAX_BUFFER_LEN);
|
||||
ret1 = GetAtomNameW((ATOM)hsz1, psz1, MAX_BUFFER_LEN);
|
||||
ret2 = GetAtomNameW((ATOM)hsz2, psz2, MAX_BUFFER_LEN);
|
||||
|
||||
TRACE("(%x<%s> %x<%s>);\n", hsz1, debugstr_w(psz1), hsz2, debugstr_w(psz2));
|
||||
|
||||
|
@ -1260,22 +1259,23 @@ INT WINAPI DdeCmpStringHandles(HSZ hsz1, HSZ hsz2)
|
|||
/*****************************************************************
|
||||
* DdeCreateDataHandle (USER32.@)
|
||||
*/
|
||||
HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb,
|
||||
DWORD cbOff, HSZ hszItem, UINT wFmt,
|
||||
UINT afCmd)
|
||||
HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, DWORD cbOff,
|
||||
HSZ hszItem, UINT wFmt, UINT afCmd)
|
||||
{
|
||||
/*
|
||||
For now, we ignore idInst, hszItem, wFmt, and afCmd.
|
||||
The purpose of these arguments still need to be investigated.
|
||||
*/
|
||||
/* For now, we ignore idInst, hszItem.
|
||||
* The purpose of these arguments still need to be investigated.
|
||||
*/
|
||||
|
||||
HGLOBAL hMem;
|
||||
LPBYTE pByte;
|
||||
DDE_DATAHANDLE_HEAD* pDdh;
|
||||
|
||||
TRACE("(%ld,%p,%ld,%ld,0x%lx,%d,%d): semi-stub\n",
|
||||
idInst,pSrc,cb,cbOff,(DWORD)hszItem,wFmt,afCmd);
|
||||
TRACE("(%ld,%p,%ld,%ld,0x%lx,%d,%d)\n",
|
||||
idInst, pSrc, cb, cbOff, (DWORD)hszItem, wFmt, afCmd);
|
||||
|
||||
if (afCmd != 0 && afCmd != HDATA_APPOWNED)
|
||||
return 0;
|
||||
|
||||
/* we use the first 4 bytes to store the size */
|
||||
if (!(hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cb + sizeof(DDE_DATAHANDLE_HEAD))))
|
||||
{
|
||||
|
@ -1284,8 +1284,15 @@ HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb,
|
|||
}
|
||||
|
||||
pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hMem);
|
||||
if (!pDdh)
|
||||
{
|
||||
GlobalFree(hMem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pDdh->cfFormat = wFmt;
|
||||
|
||||
pDdh->bAppOwned = (afCmd == HDATA_APPOWNED);
|
||||
|
||||
pByte = (LPBYTE)(pDdh + 1);
|
||||
if (pSrc)
|
||||
{
|
||||
|
@ -1420,6 +1427,25 @@ BOOL WINAPI DdeFreeDataHandle(HDDEDATA hData)
|
|||
return GlobalFree((HGLOBAL)hData) == 0;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* WDML_IsAppOwned
|
||||
*
|
||||
*
|
||||
*/
|
||||
BOOL WDML_IsAppOwned(HDDEDATA hData)
|
||||
{
|
||||
DDE_DATAHANDLE_HEAD* pDdh;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock((HGLOBAL)hData);
|
||||
if (pDdh != NULL)
|
||||
{
|
||||
ret = pDdh->bAppOwned;
|
||||
GlobalUnlock((HGLOBAL)hData);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
*
|
||||
* Global <=> Data handle management
|
||||
|
@ -1437,17 +1463,51 @@ HDDEDATA WDML_Global2DataHandle(HGLOBAL hMem, WINE_DDEHEAD* p)
|
|||
{
|
||||
DDEDATA* pDd;
|
||||
HDDEDATA ret = 0;
|
||||
DWORD size;
|
||||
|
||||
if (hMem)
|
||||
{
|
||||
pDd = GlobalLock(hMem);
|
||||
size = GlobalSize(hMem) - sizeof(WINE_DDEHEAD);
|
||||
if (pDd)
|
||||
{
|
||||
if (p) memcpy(p, pDd, sizeof(WINE_DDEHEAD));
|
||||
ret = DdeCreateDataHandle(0, pDd->Value,
|
||||
GlobalSize(hMem) - sizeof(WINE_DDEHEAD),
|
||||
0, 0, pDd->cfFormat, 0);
|
||||
GlobalUnlock(hMem);
|
||||
switch (pDd->cfFormat)
|
||||
{
|
||||
default:
|
||||
FIXME("Unsupported format (%d) for data... assuming raw information\n",
|
||||
pDd->cfFormat);
|
||||
/* fall thru */
|
||||
case 0:
|
||||
case CF_TEXT:
|
||||
ret = DdeCreateDataHandle(0, pDd->Value, size, 0, 0, pDd->cfFormat, 0);
|
||||
break;
|
||||
case CF_BITMAP:
|
||||
if (size >= sizeof(BITMAP))
|
||||
{
|
||||
BITMAP* bmp = (BITMAP*)pDd->Value;
|
||||
int count = bmp->bmWidthBytes * bmp->bmHeight * bmp->bmPlanes;
|
||||
if (size >= sizeof(BITMAP) + count)
|
||||
{
|
||||
HBITMAP hbmp;
|
||||
|
||||
if ((hbmp = CreateBitmap(bmp->bmWidth, bmp->bmHeight,
|
||||
bmp->bmPlanes, bmp->bmBitsPixel,
|
||||
pDd->Value + sizeof(BITMAP))))
|
||||
{
|
||||
ret = DdeCreateDataHandle(0, (LPBYTE)&hbmp, sizeof(hbmp),
|
||||
0, 0, CF_BITMAP, 0);
|
||||
}
|
||||
else ERR("Can't create bmp\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Wrong count: %lu / %d\n", size, sizeof(BITMAP) + count);
|
||||
}
|
||||
} else ERR("No bitmap header\n");
|
||||
break;
|
||||
}
|
||||
GlobalUnlock(hMem);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -1465,28 +1525,56 @@ HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease,
|
|||
DWORD dwSize;
|
||||
HGLOBAL hMem = 0;
|
||||
|
||||
dwSize = GlobalSize(hDdeData) - sizeof(DDE_DATAHANDLE_HEAD);
|
||||
pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hDdeData);
|
||||
dwSize = GlobalSize((HGLOBAL)hDdeData) - sizeof(DDE_DATAHANDLE_HEAD);
|
||||
pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock((HGLOBAL)hDdeData);
|
||||
if (dwSize && pDdh)
|
||||
{
|
||||
hMem = GlobalAlloc(sizeof(WINE_DDEHEAD) + dwSize, GMEM_MOVEABLE | GMEM_DDESHARE);
|
||||
if (hMem)
|
||||
{
|
||||
WINE_DDEHEAD* wdh;
|
||||
WINE_DDEHEAD* wdh = NULL;
|
||||
|
||||
wdh = GlobalLock(hMem);
|
||||
if (wdh)
|
||||
switch (pDdh->cfFormat)
|
||||
{
|
||||
default:
|
||||
FIXME("Unsupported format (%d) for data... passing raw information\n", pDdh->cfFormat);
|
||||
/* fall thru */
|
||||
case 0:
|
||||
case CF_TEXT:
|
||||
hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(WINE_DDEHEAD) + dwSize);
|
||||
if (hMem && (wdh = GlobalLock(hMem)))
|
||||
{
|
||||
wdh->fResponse = fResponse;
|
||||
wdh->fRelease = fRelease;
|
||||
wdh->fDeferUpd = fDeferUpd;
|
||||
wdh->fAckReq = fAckReq;
|
||||
wdh->cfFormat = pDdh->cfFormat;
|
||||
memcpy(wdh + 1, pDdh + 1, dwSize);
|
||||
GlobalUnlock(hMem);
|
||||
}
|
||||
break;
|
||||
case CF_BITMAP:
|
||||
if (dwSize >= sizeof(HBITMAP))
|
||||
{
|
||||
BITMAP bmp;
|
||||
DWORD count;
|
||||
HBITMAP hbmp = *(HBITMAP*)(pDdh + 1);
|
||||
|
||||
if (GetObjectA(hbmp, sizeof(bmp), &bmp))
|
||||
{
|
||||
count = bmp.bmWidthBytes * bmp.bmHeight;
|
||||
hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
|
||||
sizeof(WINE_DDEHEAD) + sizeof(bmp) + count);
|
||||
if (hMem && (wdh = GlobalLock(hMem)))
|
||||
{
|
||||
memcpy(wdh + 1, &bmp, sizeof(bmp));
|
||||
GetBitmapBits(hbmp, count, ((char*)(wdh + 1)) + sizeof(bmp));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
GlobalUnlock(hDdeData);
|
||||
if (wdh)
|
||||
{
|
||||
wdh->fResponse = fResponse;
|
||||
wdh->fRelease = fRelease;
|
||||
wdh->fDeferUpd = fDeferUpd;
|
||||
wdh->fAckReq = fAckReq;
|
||||
wdh->cfFormat = pDdh->cfFormat;
|
||||
GlobalUnlock(hMem);
|
||||
}
|
||||
GlobalUnlock((HGLOBAL)hDdeData);
|
||||
}
|
||||
|
||||
return hMem;
|
||||
|
@ -1779,8 +1867,8 @@ WDML_CONV* WDML_GetConvFromWnd(HWND hWnd)
|
|||
*
|
||||
*
|
||||
*/
|
||||
LPARAM WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode,
|
||||
BOOL fBusy, BOOL fAck, ATOM atom, LPARAM lParam, UINT oldMsg)
|
||||
BOOL WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode,
|
||||
BOOL fBusy, BOOL fAck, UINT pmt, LPARAM lParam, UINT oldMsg)
|
||||
{
|
||||
DDEACK ddeAck;
|
||||
HWND from, to;
|
||||
|
@ -1803,16 +1891,15 @@ LPARAM WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode,
|
|||
|
||||
TRACE("Posting a %s ack\n", ddeAck.fAck ? "positive" : "negative");
|
||||
|
||||
if (lParam) {
|
||||
PostMessageA(to, WM_DDE_ACK, (WPARAM)from,
|
||||
ReuseDDElParam(lParam, oldMsg, WM_DDE_ACK, *(WORD*)&ddeAck, atom));
|
||||
}
|
||||
else
|
||||
lParam = (lParam) ? ReuseDDElParam(lParam, oldMsg, WM_DDE_ACK, *(WORD*)&ddeAck, pmt) :
|
||||
PackDDElParam(WM_DDE_ACK, *(WORD*)&ddeAck, pmt);
|
||||
if (!PostMessageA(to, WM_DDE_ACK, (WPARAM)from, lParam))
|
||||
{
|
||||
lParam = PackDDElParam(WM_DDE_ACK, *(WORD*)&ddeAck, atom);
|
||||
PostMessageA(to, WM_DDE_ACK, (WPARAM)from, lParam);
|
||||
pConv->wStatus &= ~ST_CONNECTED;
|
||||
FreeDDElParam(WM_DDE_ACK, lParam);
|
||||
return FALSE;
|
||||
}
|
||||
return lParam;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
|
@ -1949,9 +2036,9 @@ UINT WINAPI DdeQueryConvInfo(HCONV hConv, DWORD id, LPCONVINFO lpConvInfo)
|
|||
{
|
||||
ret = 0;
|
||||
}
|
||||
else if (hConv & 1)
|
||||
else if ((DWORD)hConv & 1)
|
||||
{
|
||||
pConv = WDML_GetConv(hConv & ~1, FALSE);
|
||||
pConv = WDML_GetConv((DWORD)hConv & ~1, FALSE);
|
||||
if (pConv != NULL)
|
||||
{
|
||||
FIXME("Request on remote conversation information is not implemented yet\n");
|
||||
|
@ -1960,7 +2047,7 @@ UINT WINAPI DdeQueryConvInfo(HCONV hConv, DWORD id, LPCONVINFO lpConvInfo)
|
|||
}
|
||||
LeaveCriticalSection(&WDML_CritSect);
|
||||
if (ret != 0)
|
||||
memcpy(lpConvInfo, &ci, min(lpConvInfo->cb, sizeof(ci)));
|
||||
memcpy(lpConvInfo, &ci, min((size_t)lpConvInfo->cb, sizeof(ci)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1991,7 +2078,6 @@ void WDML_AddLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
|
|||
pLink->transactionType = wType;
|
||||
WDML_IncHSZ(pInstance, pLink->hszItem = hszItem);
|
||||
pLink->uFmt = wFmt;
|
||||
pLink->hDdeData = 0;
|
||||
pLink->next = pInstance->links[side];
|
||||
pInstance->links[side] = pLink;
|
||||
}
|
||||
|
@ -2024,11 +2110,6 @@ void WDML_RemoveLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
|
|||
pPrev->next = pCurrent->next;
|
||||
}
|
||||
|
||||
if (pCurrent->hDdeData)
|
||||
{
|
||||
DdeFreeDataHandle(pCurrent->hDdeData);
|
||||
}
|
||||
|
||||
WDML_DecHSZ(pInstance, pCurrent->hszItem);
|
||||
HeapFree(GetProcessHeap(), 0, pCurrent);
|
||||
break;
|
||||
|
@ -2071,10 +2152,6 @@ void WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE s
|
|||
pNext = pCurrent->next;
|
||||
}
|
||||
|
||||
if (pCurrent->hDdeData)
|
||||
{
|
||||
DdeFreeDataHandle(pCurrent->hDdeData);
|
||||
}
|
||||
WDML_DecHSZ(pInstance, pCurrent->hszItem);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pCurrent);
|
||||
|
@ -2099,7 +2176,7 @@ void WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE s
|
|||
*
|
||||
*/
|
||||
WDML_LINK* WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
|
||||
HSZ hszItem, UINT uFmt)
|
||||
HSZ hszItem, BOOL use_fmt, UINT uFmt)
|
||||
{
|
||||
WDML_LINK* pCurrent = NULL;
|
||||
|
||||
|
@ -2109,7 +2186,7 @@ WDML_LINK* WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
|
|||
|
||||
if (pCurrent->hConv == hConv &&
|
||||
DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 &&
|
||||
pCurrent->uFmt == uFmt)
|
||||
(!use_fmt || pCurrent->uFmt == uFmt))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -2150,7 +2227,7 @@ WDML_XACT* WDML_AllocTransaction(WDML_INSTANCE* pInstance, UINT ddeMsg,
|
|||
pXAct->next = NULL;
|
||||
pXAct->wType = 0;
|
||||
pXAct->wFmt = wFmt;
|
||||
WDML_IncHSZ(pInstance, pXAct->hszItem = hszItem);
|
||||
if ((pXAct->hszItem = hszItem)) WDML_IncHSZ(pInstance, pXAct->hszItem);
|
||||
pXAct->atom = 0;
|
||||
pXAct->hMem = 0;
|
||||
pXAct->lParam = 0;
|
||||
|
@ -2199,10 +2276,12 @@ BOOL WDML_UnQueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct)
|
|||
*/
|
||||
void WDML_FreeTransaction(WDML_INSTANCE* pInstance, WDML_XACT* pXAct, BOOL doFreePmt)
|
||||
{
|
||||
/* free pmt(s) in pXAct too */
|
||||
if (doFreePmt && pXAct->hMem)
|
||||
/* free pmt(s) in pXAct too. check against one for not deleting TRUE return values */
|
||||
if (doFreePmt && (DWORD)pXAct->hMem > 1)
|
||||
{
|
||||
GlobalFree(pXAct->hMem);
|
||||
WDML_DecHSZ(pInstance, pXAct->hszItem);
|
||||
}
|
||||
if (pXAct->hszItem) WDML_DecHSZ(pInstance, pXAct->hszItem);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXAct);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,8 @@ BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem)
|
|||
{
|
||||
WDML_INSTANCE* pInstance = NULL;
|
||||
WDML_LINK* pLink = NULL;
|
||||
HDDEDATA hDdeData = 0, hItemData = 0;
|
||||
HDDEDATA hDdeData = 0;
|
||||
HGLOBAL hItemData = 0;
|
||||
WDML_CONV* pConv = NULL;
|
||||
ATOM atom = 0;
|
||||
UINT count;
|
||||
|
@ -88,7 +89,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 == CBR_BLOCK)
|
||||
if (hDdeData == (HDDEDATA)CBR_BLOCK)
|
||||
{
|
||||
/* MS doc is not consistent here */
|
||||
FIXME("CBR_BLOCK returned for ADVREQ\n");
|
||||
|
@ -112,8 +113,7 @@ BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem)
|
|||
|
||||
if (pConv == NULL)
|
||||
{
|
||||
/* FIXME: wrong if app owned... */
|
||||
DdeFreeDataHandle(hDdeData);
|
||||
if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
|
||||
goto theError;
|
||||
}
|
||||
|
||||
|
@ -121,11 +121,12 @@ BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem)
|
|||
PackDDElParam(WM_DDE_DATA, (UINT)hItemData, atom)))
|
||||
{
|
||||
ERR("post message failed\n");
|
||||
/* FIXME: wrong if app owned... */
|
||||
DdeFreeDataHandle(hDdeData);
|
||||
pConv->wStatus &= ~ST_CONNECTED;
|
||||
if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
|
||||
GlobalFree(hItemData);
|
||||
goto theError;
|
||||
}
|
||||
}
|
||||
if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -352,10 +353,9 @@ static WDML_CONV* WDML_CreateServerConv(WDML_INSTANCE* pInstance, HWND hwndClien
|
|||
SetWindowLongA(hwndServerConv, GWL_WDML_CONVERSATION, (DWORD)pConv);
|
||||
|
||||
/* this should be the only place using SendMessage for WM_DDE_ACK */
|
||||
/* note: sent messages shall not use packing */
|
||||
SendMessageA(hwndClient, WM_DDE_ACK, (WPARAM)hwndServerConv,
|
||||
PackDDElParam(WM_DDE_ACK,
|
||||
WDML_MakeAtomFromHsz(hszApp),
|
||||
WDML_MakeAtomFromHsz(hszTopic)));
|
||||
MAKELPARAM(WDML_MakeAtomFromHsz(hszApp), WDML_MakeAtomFromHsz(hszTopic)));
|
||||
/* we assume we're connected since we've sent an answer...
|
||||
* I'm not sure what we can do... it doesn't look like the return value
|
||||
* of SendMessage is used... sigh...
|
||||
|
@ -457,7 +457,7 @@ static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM w
|
|||
hDdeData = WDML_InvokeCallback(pInstance, XTYP_WILDCONNECT,
|
||||
0, 0, hszTop, hszApp, 0, (DWORD)pcc, self);
|
||||
|
||||
if (hDdeData == CBR_BLOCK)
|
||||
if (hDdeData == (HDDEDATA)CBR_BLOCK)
|
||||
{
|
||||
/* MS doc is not consistent here */
|
||||
FIXME("CBR_BLOCK returned for WILDCONNECT\n");
|
||||
|
@ -478,13 +478,10 @@ static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM w
|
|||
}
|
||||
DdeUnaccessData(hDdeData);
|
||||
}
|
||||
if (!WDML_IsAppOwned(hDdeData)) DdeFreeDataHandle(hDdeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
billx: make a conv and add it to the server list -
|
||||
this can be delayed when link is created for the conv. NO NEED !!!
|
||||
*/
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -548,11 +545,11 @@ static WDML_QUEUE_STATE WDML_ServerHandleRequest(WDML_CONV* pConv, WDML_XACT* pX
|
|||
pConv->hszTopic, pXAct->hszItem, 0, 0, 0);
|
||||
}
|
||||
|
||||
switch (hDdeData)
|
||||
switch ((DWORD)hDdeData)
|
||||
{
|
||||
case 0:
|
||||
WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, FALSE, pXAct->hszItem,
|
||||
pXAct->lParam, WM_DDE_REQUEST);
|
||||
WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, FALSE, pXAct->atom,
|
||||
pXAct->lParam, WM_DDE_REQUEST);
|
||||
break;
|
||||
case CBR_BLOCK:
|
||||
ret = WDML_QS_BLOCK;
|
||||
|
@ -587,7 +584,8 @@ static WDML_XACT* WDML_ServerQueueAdvise(WDML_CONV* pConv, LPARAM lParam)
|
|||
/* XTYP_ADVSTART transaction:
|
||||
establish link and save link info to InstanceInfoTable */
|
||||
|
||||
UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLo, &uiHi);
|
||||
if (!UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLo, &uiHi))
|
||||
return NULL;
|
||||
|
||||
pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_ADVISE,
|
||||
0, WDML_MakeHszFromAtom(pConv->instance, uiHi));
|
||||
|
@ -633,7 +631,7 @@ static WDML_QUEUE_STATE WDML_ServerHandleAdvise(WDML_CONV* pConv, WDML_XACT* pXA
|
|||
|
||||
/* billx: first to see if the link is already created. */
|
||||
pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
|
||||
pXAct->hszItem, pDdeAdvise->cfFormat);
|
||||
pXAct->hszItem, TRUE, pDdeAdvise->cfFormat);
|
||||
|
||||
if (pLink != NULL)
|
||||
{
|
||||
|
@ -643,7 +641,6 @@ static WDML_QUEUE_STATE WDML_ServerHandleAdvise(WDML_CONV* pConv, WDML_XACT* pXA
|
|||
else
|
||||
{
|
||||
TRACE("Adding Link with hConv=0x%lx\n", (DWORD)pConv);
|
||||
|
||||
WDML_AddLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
|
||||
uType, pXAct->hszItem, pDdeAdvise->cfFormat);
|
||||
}
|
||||
|
@ -656,7 +653,10 @@ static WDML_QUEUE_STATE WDML_ServerHandleAdvise(WDML_CONV* pConv, WDML_XACT* pXA
|
|||
|
||||
GlobalUnlock(pXAct->hMem);
|
||||
if (fAck)
|
||||
{
|
||||
GlobalFree(pXAct->hMem);
|
||||
}
|
||||
pXAct->hMem = 0;
|
||||
|
||||
WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, fAck, pXAct->atom, pXAct->lParam, WM_DDE_ADVISE);
|
||||
|
||||
|
@ -699,7 +699,7 @@ static WDML_QUEUE_STATE WDML_ServerHandleUnadvise(WDML_CONV* pConv, WDML_XACT* p
|
|||
}
|
||||
|
||||
pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE,
|
||||
pXAct->hszItem, pXAct->wFmt);
|
||||
pXAct->hszItem, TRUE, pXAct->wFmt);
|
||||
if (pLink == NULL)
|
||||
{
|
||||
ERR("Couln'd find link for %08lx, dropping request\n", (DWORD)pXAct->hszItem);
|
||||
|
@ -718,7 +718,7 @@ static WDML_QUEUE_STATE WDML_ServerHandleUnadvise(WDML_CONV* pConv, WDML_XACT* p
|
|||
|
||||
/* send back ack */
|
||||
WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, TRUE, pXAct->atom,
|
||||
pXAct->lParam, WM_DDE_UNADVISE);
|
||||
pXAct->lParam, WM_DDE_UNADVISE);
|
||||
|
||||
WDML_DecHSZ(pConv->instance, pXAct->hszItem);
|
||||
|
||||
|
@ -856,8 +856,9 @@ static WDML_QUEUE_STATE WDML_ServerHandlePoke(WDML_CONV* pConv, WDML_XACT* pXAct
|
|||
GlobalUnlock(pXAct->hMem);
|
||||
|
||||
if (!fAck)
|
||||
{
|
||||
GlobalFree(pXAct->hMem);
|
||||
|
||||
}
|
||||
WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, fBusy, fAck, pXAct->atom, pXAct->lParam, WM_DDE_POKE);
|
||||
|
||||
WDML_DecHSZ(pConv->instance, pXAct->hszItem);
|
||||
|
@ -893,7 +894,6 @@ static WDML_QUEUE_STATE WDML_ServerHandleTerminate(WDML_CONV* pConv, WDML_XACT*
|
|||
WDML_InvokeCallback(pConv->instance, XTYP_DISCONNECT, 0, (HCONV)pConv, 0, 0,
|
||||
0, 0, (pConv->wStatus & ST_ISSELF) ? 1 : 0);
|
||||
}
|
||||
|
||||
PostMessageA(pConv->hwndClient, WM_DDE_TERMINATE, (WPARAM)pConv->hwndServer, 0);
|
||||
WDML_RemoveConv(pConv, WDML_SERVER_SIDE);
|
||||
|
||||
|
|
Loading…
Reference in New Issue