sync DDE to wine 1.1.17

svn path=/trunk/; revision=40226
This commit is contained in:
Christoph von Wittich
2009-03-25 13:57:58 +00:00
parent 034b4711be
commit 49aa71cfbc
4 changed files with 248 additions and 254 deletions
@@ -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);
+61 -18
View File
@@ -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;
}
+111 -145
View File
@@ -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;
}
+73 -88
View File
@@ -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 @@ 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;
}