summaryrefslogblamecommitdiffstats
path: root/private/ole32/com/remote/dde/client/ddechc.cxx
blob: 0034b5ef37a5db6c5fe98892b9a7984fb3130fca (plain) (tree)








































































































































































































































































                                                                                        
//+-------------------------------------------------------------------------
//
//  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;
}