diff options
Diffstat (limited to '')
-rw-r--r-- | private/ole32/com/remote/dde/client/ddechc.cxx | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/private/ole32/com/remote/dde/client/ddechc.cxx b/private/ole32/com/remote/dde/client/ddechc.cxx new file mode 100644 index 000000000..0034b5ef3 --- /dev/null +++ b/private/ole32/com/remote/dde/client/ddechc.cxx @@ -0,0 +1,265 @@ +//+------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1993. +// +// File: DdeChC.cxx +// +// Contents: CDdeChannelControl implementation for DDE. This +// implementation requires no instance data, therefore it is +// intended to be static. +// +// Functions: +// +// History: 08-May-94 Johann Posch (johannp) Created +// 10-May-94 KevinRo Made simpler +// 29-May-94 KevinRo Added DDE Server support +// +//-------------------------------------------------------------------------- +#include "ddeproxy.h" + +// +// All threads can use a single instance of this class. Therefore, we +// provide the following global variable that generates the instance. +// + +CDdeChannelControl g_CDdeChannelControl; + +STDMETHODIMP CDdeChannelControl::QueryInterface( THIS_ REFIID riid, LPVOID FAR* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) +// || IsEqualIID(riid, IID_IChannelControl) + ) + { + *ppvObj = (IChannelControl *) this; + } + else + { + *ppvObj = NULL; + return E_NOINTERFACE; + } + + return S_OK; +} + +STDMETHODIMP_(ULONG) CDdeChannelControl::Release( THIS ) +{ + return(1); +} + +STDMETHODIMP_(ULONG) CDdeChannelControl::AddRef( THIS ) +{ + return 1; +} + + +//+--------------------------------------------------------------------------- +// +// Method: CDdeChannelControl::DispatchCall +// +// Synopsis: DispatchCall is called to handle incoming calls. +// +// Effects: Dispatches a call to the specified in the DispatchData. +// This function is the result of a call in OnData(), which +// processes incoming calls from the OLE 1.0 server. +// +// Arguments: [pDispData] -- Points to the dispatch data structure +// +// Requires: +// +// Returns: +// +// Signals: +// +// Modifies: +// +// Derivation: +// +// Algorithm: +// +// History: 5-16-94 JohannP Created +// +// Notes: +// +//---------------------------------------------------------------------------- +STDMETHODIMP CDdeChannelControl::DispatchCall( PDISPATCHDATA pDispData ) +{ + intrDebugOut((DEB_ITRACE, + "CDdeChannelControl::DispatchCall(%x,pDispData=%x)\n", + this, + pDispData)); + + intrAssert(pDispData != NULL); + POLE1DISPATCHDATA pData = (POLE1DISPATCHDATA)pDispData->pData; + intrAssert(pData != NULL); + + switch (pData->wDispFunc) + { + case DDE_DISP_SENDONDATACHANGE: // OnDataChange + { + PDDEDISPATCHDATA pDData = (PDDEDISPATCHDATA)pDispData->pData; + return pDData->pCDdeObject->SendOnDataChange(pDData->iArg); + } + + case DDE_DISP_OLECALLBACK: // OleCallBack + { + PDDEDISPATCHDATA pDData = (PDDEDISPATCHDATA)pDispData->pData; + return pDData->pCDdeObject->OleCallBack(pDData->iArg,NULL); + } + + // + // The server window has an incoming call. Look in dde\server\srvr.cxx + // + case DDE_DISP_SRVRWNDPROC: + return(SrvrDispatchIncomingCall((PSRVRDISPATCHDATA)pDispData->pData)); + // + // This dispatches to a Document window + // + case DDE_DISP_DOCWNDPROC: + return(DocDispatchIncomingCall((PDOCDISPATCHDATA)pDispData->pData)); + + default: + intrAssert(!"Unknown wDispFunc"); + } + return E_FAIL; +} + +//+--------------------------------------------------------------------------- +// +// Method: CDdeChannelControl::OnEvent +// +// Synopsis: OnEvent should never be called on this channel +// +// Effects: +// +// Arguments: [pCallData] -- +// +// Requires: +// +// Returns: +// +// Signals: +// +// Modifies: +// +// Derivation: +// +// Algorithm: +// +// History: 5-16-94 JohannP Created +// +// Notes: +// +//---------------------------------------------------------------------------- +STDMETHODIMP CDdeChannelControl::OnEvent( PCALLDATA pCallData ) +{ + // should be never called + + intrAssert(!"CDdeChannelControl::OnEvent( PCALLDATA pCallData ) not implemented\n"); + return E_FAIL; +} + +//+--------------------------------------------------------------------------- +// +// Method: CDdeChannelControl::TransmitCall +// +// Synopsis: Transmit the parameters to the server. +// +// Effects: This function transmits the pCallData to the server. This +// may be called multiple times, if a retry is required. +// +// A by product of the way the DDE channel was implemented +// atop existing code is that the existing code may transmit +// the first round of data on its own. If it does this, it +// will set the fInitialSend to TRUE. Therefore, if this +// routine sees the flag as true, it will not send the data, +// but will set the flag to FALSE for a possible retry later. +// +// Arguments: [pCallData] -- Points to the DDE specific call data +// +// Requires: +// +// Returns: If the Post fails, this function returns E_FAIL +// +// Signals: +// +// Modifies: +// +// Derivation: +// +// Algorithm: +// +// History: 5-16-94 JohannP Created +// +// Notes: +// +//---------------------------------------------------------------------------- +STDMETHODIMP CDdeChannelControl::TransmitCall( PCALLDATA pCallData ) +{ + intrDebugOut((DEB_ITRACE, + "CDdeChannelControl::TransmitCall(%x,pCallData=%x)\n", + this, + pCallData)); + // reset the event + pCallData->Event = 0; + pCallData->fDirectedYield = FALSE; + + PDDECALLDATA pDdeCD = (PDDECALLDATA)pCallData->pRpcMsg; + + // + // If the routine wPostServerMessage has already posted the + // first send, then fInitialSend will be TRUE. In that case, + // don't TransmitCall() this time, but reset the flag for + // future retries. + // + + if (!pDdeCD->fInitialSend) + { + intrDebugOut((DEB_ITRACE, + "::TransmitCall(%x) PostMessage(%x,%x,%x,%x)\n", + this, + pDdeCD->hwndSvr, + pDdeCD->wMsg, + (WPARAM) pDdeCD->hwndCli, + pDdeCD->lParam)); + + if(!PostMessage (pDdeCD->hwndSvr, + pDdeCD->wMsg, + (WPARAM) pDdeCD->hwndCli, + pDdeCD->lParam)) + { + return(E_FAIL); + } + } + else + { + intrDebugOut((DEB_ITRACE, + "::TransmitCall(%x) Already Posted Message\n", + this)); + + pDdeCD->fInitialSend = FALSE; + } + + // + // Figure out if we want the call control to do a directed yield. + // Do this only if the server is in the same VDM as us. + // + + + if (IsWOWProcess()) + { + DWORD dwPID, dwTID; + dwTID = GetWindowThreadProcessId(pDdeCD->hwndSvr, &dwPID); + + if (dwPID == GetCurrentProcessId()) + { + // Make sure we have the right thread id to yield to + pCallData->TIDCallee = dwTID; + + // same VDM so do directed yield + pCallData->fDirectedYield = TRUE; + } + } + + return NOERROR; +} |