📄 server.c
字号:
* WDML_ServerQueueRequest * * */static WDML_XACT* WDML_ServerQueueRequest(WDML_CONV* pConv, LPARAM lParam){ UINT_PTR uiLo, uiHi; WDML_XACT* pXAct; UnpackDDElParam(WM_DDE_REQUEST, lParam, &uiLo, &uiHi); pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_REQUEST, uiLo, WDML_MakeHszFromAtom(pConv->instance, uiHi)); if (pXAct) pXAct->atom = uiHi; return pXAct;}/****************************************************************** * WDML_ServerHandleRequest * * */static WDML_QUEUE_STATE WDML_ServerHandleRequest(WDML_CONV* pConv, WDML_XACT* pXAct){ HDDEDATA hDdeData = 0; WDML_QUEUE_STATE ret = WDML_QS_HANDLED; if (!(pConv->instance->CBFflags & CBF_FAIL_REQUESTS)) { hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_REQUEST, pXAct->wFmt, (HCONV)pConv, pConv->hszTopic, pXAct->hszItem, 0, 0, 0); } switch ((ULONG_PTR)hDdeData) { case 0: WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, FALSE, pXAct->atom, pXAct->lParam, WM_DDE_REQUEST); break; case CBR_BLOCK: ret = WDML_QS_BLOCK; break; default: { HGLOBAL hMem = WDML_DataHandle2Global(hDdeData, TRUE, FALSE, FALSE, FALSE); if (!PostMessageA(pConv->hwndClient, WM_DDE_DATA, (WPARAM)pConv->hwndServer, ReuseDDElParam(pXAct->lParam, WM_DDE_REQUEST, WM_DDE_DATA, (UINT_PTR)hMem, (UINT_PTR)pXAct->atom))) { DdeFreeDataHandle(hDdeData); GlobalFree(hMem); } } break; } WDML_DecHSZ(pConv->instance, pXAct->hszItem); return ret;}/****************************************************************** * WDML_ServerQueueAdvise * * */static WDML_XACT* WDML_ServerQueueAdvise(WDML_CONV* pConv, LPARAM lParam){ UINT_PTR uiLo, uiHi; WDML_XACT* pXAct; /* XTYP_ADVSTART transaction: establish link and save link info to InstanceInfoTable */ if (!UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLo, &uiHi)) return NULL; pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_ADVISE, 0, WDML_MakeHszFromAtom(pConv->instance, uiHi)); if (pXAct) { pXAct->hMem = (HGLOBAL)uiLo; pXAct->atom = uiHi; } return pXAct;}/****************************************************************** * WDML_ServerHandleAdvise * * */static WDML_QUEUE_STATE WDML_ServerHandleAdvise(WDML_CONV* pConv, WDML_XACT* pXAct){ UINT uType; WDML_LINK* pLink; DDEADVISE* pDdeAdvise; HDDEDATA hDdeData; BOOL fAck; pDdeAdvise = (DDEADVISE*)GlobalLock(pXAct->hMem); uType = XTYP_ADVSTART | (pDdeAdvise->fDeferUpd ? XTYPF_NODATA : 0) | (pDdeAdvise->fAckReq ? XTYPF_ACKREQ : 0); if (!(pConv->instance->CBFflags & CBF_FAIL_ADVISES)) { hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_ADVSTART, pDdeAdvise->cfFormat, (HCONV)pConv, pConv->hszTopic, pXAct->hszItem, 0, 0, 0); } else { hDdeData = 0; } if ((UINT)hDdeData) { fAck = TRUE; /* billx: first to see if the link is already created. */ pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE, pXAct->hszItem, TRUE, pDdeAdvise->cfFormat); if (pLink != NULL) { /* we found a link, and only need to modify it in case it changes */ pLink->transactionType = uType; } else { TRACE("Adding Link with hConv %p\n", pConv); WDML_AddLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE, uType, pXAct->hszItem, pDdeAdvise->cfFormat); } } else { TRACE("No data returned from the Callback\n"); fAck = FALSE; } 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); WDML_DecHSZ(pConv->instance, pXAct->hszItem); return WDML_QS_HANDLED;}/****************************************************************** * WDML_ServerQueueUnadvise * * */static WDML_XACT* WDML_ServerQueueUnadvise(WDML_CONV* pConv, LPARAM lParam){ UINT_PTR uiLo, uiHi; WDML_XACT* pXAct; UnpackDDElParam(WM_DDE_UNADVISE, lParam, &uiLo, &uiHi); pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_UNADVISE, uiLo, WDML_MakeHszFromAtom(pConv->instance, uiHi)); if (pXAct) pXAct->atom = uiHi; return pXAct;}/****************************************************************** * WDML_ServerHandleUnadvise * * */static WDML_QUEUE_STATE WDML_ServerHandleUnadvise(WDML_CONV* pConv, WDML_XACT* pXAct){ WDML_LINK* pLink; if (pXAct->hszItem == NULL || pXAct->wFmt == 0) { ERR("Unsupported yet options (null item or clipboard format)\n"); return WDML_QS_ERROR; } pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE, pXAct->hszItem, TRUE, pXAct->wFmt); if (pLink == NULL) { ERR("Couln'd find link for %p, dropping request\n", pXAct->hszItem); FreeDDElParam(WM_DDE_UNADVISE, pXAct->lParam); return WDML_QS_ERROR; } if (!(pConv->instance->CBFflags & CBF_FAIL_ADVISES)) { WDML_InvokeCallback(pConv->instance, XTYP_ADVSTOP, pXAct->wFmt, (HCONV)pConv, pConv->hszTopic, pXAct->hszItem, 0, 0, 0); } WDML_RemoveLink(pConv->instance, (HCONV)pConv, WDML_SERVER_SIDE, pXAct->hszItem, pXAct->wFmt); /* send back ack */ WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, FALSE, TRUE, pXAct->atom, pXAct->lParam, WM_DDE_UNADVISE); WDML_DecHSZ(pConv->instance, pXAct->hszItem); return WDML_QS_HANDLED;}/****************************************************************** * WDML_QueueExecute * * */static WDML_XACT* WDML_ServerQueueExecute(WDML_CONV* pConv, LPARAM lParam){ WDML_XACT* pXAct; pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_EXECUTE, 0, 0); if (pXAct) { pXAct->hMem = (HGLOBAL)lParam; } return pXAct;} /****************************************************************** * WDML_ServerHandleExecute * * */static WDML_QUEUE_STATE WDML_ServerHandleExecute(WDML_CONV* pConv, WDML_XACT* pXAct){ HDDEDATA hDdeData = DDE_FNOTPROCESSED; BOOL fAck = FALSE, fBusy = FALSE; if (!(pConv->instance->CBFflags & CBF_FAIL_EXECUTES)) { LPVOID ptr = GlobalLock(pXAct->hMem); if (ptr) { hDdeData = DdeCreateDataHandle(0, ptr, GlobalSize(pXAct->hMem), 0, 0, CF_TEXT, 0); GlobalUnlock(pXAct->hMem); } hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_EXECUTE, 0, (HCONV)pConv, pConv->hszTopic, 0, hDdeData, 0L, 0L); } switch ((UINT)hDdeData) { case DDE_FACK: fAck = TRUE; break; case DDE_FBUSY: fBusy = TRUE; break; default: WARN("Bad result code\n"); /* fall through */ case DDE_FNOTPROCESSED: break; } WDML_PostAck(pConv, WDML_SERVER_SIDE, 0, fBusy, fAck, (UINT)pXAct->hMem, 0, 0); return WDML_QS_HANDLED;}/****************************************************************** * WDML_ServerQueuePoke * * */static WDML_XACT* WDML_ServerQueuePoke(WDML_CONV* pConv, LPARAM lParam){ UINT_PTR uiLo, uiHi; WDML_XACT* pXAct; UnpackDDElParam(WM_DDE_POKE, lParam, &uiLo, &uiHi); pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_POKE, 0, WDML_MakeHszFromAtom(pConv->instance, uiHi)); if (pXAct) { pXAct->atom = uiHi; pXAct->hMem = (HGLOBAL)uiLo; } return pXAct;}/****************************************************************** * WDML_ServerHandlePoke * * */static WDML_QUEUE_STATE WDML_ServerHandlePoke(WDML_CONV* pConv, WDML_XACT* pXAct){ DDEPOKE* pDdePoke; HDDEDATA hDdeData; BOOL fBusy = FALSE, fAck = FALSE; pDdePoke = (DDEPOKE*)GlobalLock(pXAct->hMem); if (!pDdePoke) { return WDML_QS_ERROR; } if (!(pConv->instance->CBFflags & CBF_FAIL_POKES)) { hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, pDdePoke->Value, GlobalSize(pXAct->hMem) - sizeof(DDEPOKE) + 1, 0, 0, pDdePoke->cfFormat, 0); if (hDdeData) { HDDEDATA hDdeDataOut; hDdeDataOut = WDML_InvokeCallback(pConv->instance, XTYP_POKE, pDdePoke->cfFormat, (HCONV)pConv, pConv->hszTopic, pXAct->hszItem, hDdeData, 0, 0); switch ((ULONG_PTR)hDdeDataOut) { case DDE_FACK: fAck = TRUE; break; case DDE_FBUSY: fBusy = TRUE; break; default: FIXME("Unsupported returned value %p\n", hDdeDataOut); /* fal through */ case DDE_FNOTPROCESSED: break; } DdeFreeDataHandle(hDdeData); } } 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); return WDML_QS_HANDLED;}/****************************************************************** * WDML_ServerQueueTerminate * * */static WDML_XACT* WDML_ServerQueueTerminate(WDML_CONV* pConv, LPARAM lParam){ WDML_XACT* pXAct; pXAct = WDML_AllocTransaction(pConv->instance, WM_DDE_TERMINATE, 0, 0); return pXAct;}/****************************************************************** * WDML_ServerHandleTerminate * * */static WDML_QUEUE_STATE WDML_ServerHandleTerminate(WDML_CONV* pConv, WDML_XACT* pXAct){ /* billx: two things to remove: the conv, and associated links. * Respond with another WM_DDE_TERMINATE iMsg. */ 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); } PostMessageA(pConv->hwndClient, WM_DDE_TERMINATE, (WPARAM)pConv->hwndServer, 0); WDML_RemoveConv(pConv, WDML_SERVER_SIDE); return WDML_QS_HANDLED;}/****************************************************************** * WDML_ServerHandle * * */WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV* pConv, WDML_XACT* pXAct){ WDML_QUEUE_STATE qs = WDML_QS_ERROR; switch (pXAct->ddeMsg) { case WM_DDE_INITIATE: FIXME("WM_DDE_INITIATE shouldn't be there!\n"); break; case WM_DDE_REQUEST: qs = WDML_ServerHandleRequest(pConv, pXAct); break; case WM_DDE_ADVISE: qs = WDML_ServerHandleAdvise(pConv, pXAct); break; case WM_DDE_UNADVISE: qs = WDML_ServerHandleUnadvise(pConv, pXAct); break; case WM_DDE_EXECUTE: qs = WDML_ServerHandleExecute(pConv, pXAct); break; case WM_DDE_POKE: qs = WDML_ServerHandlePoke(pConv, pXAct); break; case WM_DDE_TERMINATE: qs = WDML_ServerHandleTerminate(pConv, pXAct); break; case WM_DDE_ACK: WARN("Shouldn't receive a ACK message (never requests them). Ignoring it\n"); break; default: FIXME("Unsupported message %d\n", pXAct->ddeMsg); } return qs;}/****************************************************************** * WDML_ServerConvProc * * */static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM wParam, LPARAM lParam){ WDML_INSTANCE* pInstance; WDML_CONV* pConv; WDML_XACT* pXAct = NULL; 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 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; } if (pConv->hwndClient != WIN_GetFullHandle( (HWND)wParam ) || pConv->hwndServer != hwndServer) { ERR("mismatch between C/S windows and converstation\n"); goto theError; } if (pConv->instance != pInstance || pConv->instance == NULL) { ERR("mismatch in instances\n"); goto theError; } switch (iMsg) { case WM_DDE_INITIATE: FIXME("WM_DDE_INITIATE message received!\n"); break; case WM_DDE_REQUEST: pXAct = WDML_ServerQueueRequest(pConv, lParam); break; case WM_DDE_ADVISE: pXAct = WDML_ServerQueueAdvise(pConv, lParam); break; case WM_DDE_UNADVISE: pXAct = WDML_ServerQueueUnadvise(pConv, lParam); break; case WM_DDE_EXECUTE: pXAct = WDML_ServerQueueExecute(pConv, lParam); break; case WM_DDE_POKE: pXAct = WDML_ServerQueuePoke(pConv, lParam); break; case WM_DDE_TERMINATE: pXAct = WDML_ServerQueueTerminate(pConv, lParam); break; case WM_DDE_ACK: WARN("Shouldn't receive a ACK message (never requests them). Ignoring it\n"); break; default: FIXME("Unsupported message %x\n", iMsg); } if (pXAct) { pXAct->lParam = lParam; if (WDML_ServerHandle(pConv, pXAct) == WDML_QS_BLOCK) { WDML_QueueTransaction(pConv, pXAct); } else { WDML_FreeTransaction(pInstance, pXAct, TRUE); } } theError: LeaveCriticalSection(&WDML_CritSect); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -