Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1092 lines
24 KiB

//---------------------------------------------------------------------------
//
// File: myproxy.cxx
//
// Purpose: Sample implementation of wrappers to allow simultaneous
// hand-crafted and MILD-generated stubs.
//
// History: 12-11-95 Rickhi Created
//
//---------------------------------------------------------------------------
#include <ole2.h>
#include <stddef.h> // offsetof
#include <icube.h> // custom interface ICube, IID_ICube
// flag set in rpcFlags field of RPCOLEMESSAGE if the call is from a
// non-NDR client.
#define RPCFLG_NON_NDR 0x80000000UL
DEFINE_OLEGUID(IID_INonNDRStub, 0x0000013DL, 0, 0);
DEFINE_OLEGUID(CLSID_MyProxy, 0x0000013EL, 0, 0);
// IID that the proxy querys the channel for to see if the server
// has an NDR or NON NDR stub.
const GUID IID_INonNDRStub =
{0x0000013d,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
// class id of my custom proxy dll
const GUID CLSID_MyProxy =
{0x0000013e,0x0001,0x0008,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
// class id of the MIDL generated proxy dll
const GUID CLSID_CubeProxy =
{0x00000138,0x0001,0x0008,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
#define GETPPARENT(pmemb, struc, membname) (\
(struc FAR *)(((char FAR *)(pmemb))-offsetof(struc, membname)))
//---------------------------------------------------------------------------
//
// Class: CPSFactory
//
// Purpose: ProxyStub Class Factory
//
// Notes: fill in the CreateProxy and CreateStub methods for
// other custom interfaces supported by this DLL.
//
//---------------------------------------------------------------------------
class CPSFactory : public IPSFactoryBuffer
{
public:
// no ctor or dtor needed. DllGetClassObject returns a static
// instance of this class.
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
STDMETHOD(CreateProxy)(IUnknown *pUnkOuter, REFIID riid,
IRpcProxyBuffer **ppProxy, void **ppv);
STDMETHOD(CreateStub)(REFIID riid, IUnknown *pUnkObj,
IRpcStubBuffer **ppStub);
};
//---------------------------------------------------------------------------
//
// Class: CStubWrapper
//
// Purpose: Wrapper object for stubs.
//
// Notes: This class can wrap any stub object regardless of
// the interface the stub is for.
//
//---------------------------------------------------------------------------
class CStubWrapper : public IRpcStubBuffer
{
public:
CStubWrapper(IUnknown *pUnkObj, REFIID riid);
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
STDMETHOD(Connect)(IUnknown *pUnkObj);
STDMETHOD_(void, Disconnect)(void);
STDMETHOD(Invoke)(RPCOLEMESSAGE *pMsg, IRpcChannelBuffer *pChnl);
STDMETHOD_(IRpcStubBuffer *, IsIIDSupported)(REFIID riid);
STDMETHOD_(ULONG, CountRefs)(void);
STDMETHOD(DebugServerQueryInterface)(void **ppv);
STDMETHOD_(void, DebugServerRelease)(void *pv);
private:
~CStubWrapper(void);
ULONG _cRefs;
IUnknown * _pUnkObj;
IRpcStubBuffer *_pHCStub;
IRpcStubBuffer *_pMIDLStub;
IID _iid;
};
//---------------------------------------------------------------------------
//
// Class: CCubesStub
//
// Purpose: Hand-Crafted stub object for interface ICube.
//
// Notes: Replace this with your exisitng 32bit hand-crafted stubs.
//
//---------------------------------------------------------------------------
class CCubesStub : public IRpcStubBuffer
{
public:
CCubesStub(IUnknown *pUnkObj);
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
STDMETHOD(Connect)(IUnknown *pUnkObj);
STDMETHOD_(void, Disconnect)(void);
STDMETHOD(Invoke)(RPCOLEMESSAGE *pMsg, IRpcChannelBuffer *pChnl);
STDMETHOD_(IRpcStubBuffer *, IsIIDSupported)(REFIID riid);
STDMETHOD_(ULONG, CountRefs)(void);
STDMETHOD(DebugServerQueryInterface)(void **ppv);
STDMETHOD_(void, DebugServerRelease)(void *pv);
private:
~CCubesStub(void);
ULONG _cRefs;
IUnknown * _pUnkObj;
};
//---------------------------------------------------------------------------
//
// Class: CInternalUnk
//
// Purpose: Internal proxy class that implements IRpcProxyBuffer
//
// Notes: This could use some work. Perhaps dont make it an internal
// class, but derive the other proxy classes from it, allowing
// common code.
//
//---------------------------------------------------------------------------
#define DECLARE_INTERNAL_PROXY() \
class CInternalUnk : public IRpcProxyBuffer \
{ \
public: \
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj); \
STDMETHOD_(ULONG,AddRef)(void) ; \
STDMETHOD_(ULONG,Release)(void); \
STDMETHOD(Connect)(IRpcChannelBuffer *pChnl); \
STDMETHOD_(void, Disconnect)(void); \
}; \
friend CInternalUnk; \
CInternalUnk _InternalUnk;
//---------------------------------------------------------------------------
//
// Class: CProxyWrapper
//
// Purpose: Wrapper object for itnerface proxies.
//
// Notes: the routines in this class simply delegate to the
// real proxy or the internal proxy unknown, or to the
// controlling unknown.
//
//---------------------------------------------------------------------------
class CProxyWrapper : public ICube
{
public:
CProxyWrapper(IUnknown *pUnkOuter, IRpcProxyBuffer **ppProxy);
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
// interface specific routines below here
STDMETHOD(MoveCube)(ULONG xPos, ULONG yPos);
STDMETHOD(GetCubePos)(ULONG *pxPos, ULONG *pyPos);
STDMETHOD(Contains)(IBalls *pIFDb);
STDMETHOD(SimpleCall)(DWORD pidCaller,
DWORD tidCaller,
GUID lidCaller);
DECLARE_INTERNAL_PROXY()
private:
~CProxyWrapper(void);
ULONG _cRefs;
IUnknown *_pUnkOuter;
IRpcProxyBuffer *_pRealProxy;
ICube *_pRealIf;
};
//---------------------------------------------------------------------------
//
// Class: CCubesProxy
//
// Purpose: Hand-Crafted proxy object for ICube interface.
//
//---------------------------------------------------------------------------
class CCubesProxy : public ICube
{
public:
CCubesProxy(IUnknown *pUnkOuter, IRpcProxyBuffer **ppProxy);
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
// interface specific routines below here
STDMETHOD(MoveCube)(ULONG xPos, ULONG yPos);
STDMETHOD(GetCubePos)(ULONG *pxPos, ULONG *pyPos);
STDMETHOD(Contains)(IBalls *pIFDb);
STDMETHOD(SimpleCall)(DWORD pidCaller,
DWORD tidCaller,
GUID lidCaller);
DECLARE_INTERNAL_PROXY()
private:
~CCubesProxy(void);
ULONG _cRefs;
IUnknown *_pUnkOuter;
IRpcChannelBuffer *_pChnl;
};
//---------------------------------------------------------------------------
//
// Function: DllMain
//
// Purpose: Entry point for the Proxy/Stub Dll
//
//---------------------------------------------------------------------------
extern "C" BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, void *pvReserved)
{
return TRUE;
}
//---------------------------------------------------------------------------
//
// Function: DllGetClassObject
//
// Purpose: Entry point to return proxy/stub class factory
//
//---------------------------------------------------------------------------
// static instance of the class factory
CPSFactory gPSFactory;
STDAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **ppv)
{
if (IsEqualCLSID(clsid, CLSID_MyProxy))
{
*ppv = (void *)(IClassFactory *)&gPSFactory;
return S_OK;
}
return E_UNEXPECTED;
}
//---------------------------------------------------------------------------
//
// Function: DllCanUnloadNow
//
// Purpose: Entry point to determine if DLL is unloadable.
//
//---------------------------------------------------------------------------
STDAPI DllCanUnloadNow(void)
{
return FALSE;
}
//---------------------------------------------------------------------------
//
// Function: GetMIDLPSFactory
//
// Purpose: Function for getting the MIDL generated PSFactoryBuffer
// for the test interface.
//
//---------------------------------------------------------------------------
HRESULT GetMIDLPSFactory(REFIID riid, IPSFactoryBuffer **ppIPSF)
{
*ppIPSF = NULL;
// load the dll and get the PS class object
return CoGetClassObject(CLSID_CubeProxy,
CLSCTX_INPROC_SERVER, // | CLSCTX_PS_DLL,
NULL,
IID_IPSFactoryBuffer,
(void **)ppIPSF);
}
//---------------------------------------------------------------------------
//
// Function: CreateMIDLProxy
//
// Purpose: Function for creating the MIDL generated proxy
// for the test interface.
//
//---------------------------------------------------------------------------
IUnknown *CreateMIDLProxy(REFIID riid,
IUnknown *pUnkOuter,
IRpcProxyBuffer **ppProxy)
{
IUnknown *pRealIf = NULL;
IPSFactoryBuffer *pPSFactory = NULL;
HRESULT hr = GetMIDLPSFactory(riid, &pPSFactory);
if (SUCCEEDED(hr))
{
hr = pPSFactory->CreateProxy(pUnkOuter,riid,ppProxy,(void **)&pRealIf);
pPSFactory->Release();
}
return pRealIf;
}
//---------------------------------------------------------------------------
//
// Function: CreateMIDLStub
//
// Purpose: Function for creating the MIDL generated stub
// for the test interface.
//
//---------------------------------------------------------------------------
IRpcStubBuffer *CreateMIDLStub(REFIID riid,
IUnknown *pUnkOuter)
{
IRpcStubBuffer *pStub = NULL;
IPSFactoryBuffer *pPSFactory = NULL;
HRESULT hr = GetMIDLPSFactory(riid, &pPSFactory);
if (SUCCEEDED(hr))
{
hr = pPSFactory->CreateStub(riid, pUnkOuter, &pStub);
pPSFactory->Release();
}
return pStub;
}
//---------------------------------------------------------------------------
//
// Implement: CPSFactory
//
// Purpose: ProxyStub Class Factory
//
// Notes: just fill in the CreateProxy and CreateStub methods for
// your other custom interfaces.
//
//---------------------------------------------------------------------------
HRESULT CPSFactory::QueryInterface(REFIID riid, void **ppv)
{
if (IsEqualIID(riid, IID_IPSFactoryBuffer) ||
IsEqualIID(riid, IID_IUnknown))
{
*ppv = (IPSFactoryBuffer *)this;
// static object, dont need refcnt
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
ULONG CPSFactory::AddRef(void)
{
// static object, dont need refcnt
return 1;
}
ULONG CPSFactory::Release(void)
{
// static object, dont need refcnt
return 1;
}
HRESULT CPSFactory::CreateProxy(IUnknown *pUnkOuter, REFIID riid,
IRpcProxyBuffer **ppProxy, void **ppv)
{
// check for supported interfaces
if (IsEqualIID(riid, IID_ICube))
{
CProxyWrapper *pProxy = new CProxyWrapper(pUnkOuter, ppProxy);
if (pProxy)
{
*ppv = (void *)(ICube *) pProxy;
((IUnknown *)(*ppv))->AddRef(); // AddRef the returned interface
return S_OK;
}
}
*ppProxy = NULL;
*ppv = NULL;
return E_NOINTERFACE;
}
HRESULT CPSFactory::CreateStub(REFIID riid, IUnknown *pUnkObj, IRpcStubBuffer **ppStub)
{
// check for supported interfaces
if (IsEqualIID(riid, IID_ICube))
{
CStubWrapper *pStub = new CStubWrapper(pUnkObj, riid);
if (pStub)
{
*ppStub = (IRpcStubBuffer *) pStub;
return S_OK;
}
}
*ppStub = NULL;
return E_NOINTERFACE;
}
//---------------------------------------------------------------------------
//
// Implement: CStubWrapper
//
// Purpose: Wrapper object for stubs.
//
// Notes: This same class can wrap any stub object regardless of
// the interface the stub is for.
//
//---------------------------------------------------------------------------
CStubWrapper::CStubWrapper(IUnknown *pUnkObj, REFIID riid) :
_cRefs(1),
_pUnkObj(pUnkObj),
_pHCStub(NULL),
_pMIDLStub(NULL),
_iid(riid)
{
_pUnkObj->AddRef();
}
CStubWrapper::~CStubWrapper(void)
{
Disconnect();
}
HRESULT CStubWrapper::QueryInterface(REFIID riid, void **ppv)
{
if (IsEqualIID(riid, IID_IRpcStubBuffer) ||
IsEqualIID(riid, IID_IUnknown))
{
*ppv = (IRpcStubBuffer *)this;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
ULONG CStubWrapper::AddRef(void)
{
InterlockedIncrement((LONG *)&_cRefs);
return _cRefs;
}
ULONG CStubWrapper::Release(void)
{
ULONG cRefs = _cRefs-1;
if (InterlockedDecrement((LONG *)&_cRefs) == 0)
{
delete this;
return 0;
}
return cRefs;
}
HRESULT CStubWrapper::Connect(IUnknown *pUnkObj)
{
if (_pUnkObj)
{
// already connected, disconnect
Disconnect();
}
// get the requested interface and hold it.
HRESULT hr = pUnkObj->QueryInterface(_iid, (void **)&_pUnkObj);
if (FAILED(hr))
{
// make sure our ptr is NULL else we might think we're connected
_pUnkObj = NULL;
}
return hr;
}
void CStubWrapper::Disconnect()
{
if (_pHCStub)
{
_pHCStub->Disconnect();
_pHCStub->Release();
_pHCStub = NULL;
}
if (_pMIDLStub)
{
_pMIDLStub->Disconnect();
_pMIDLStub->Release();
_pMIDLStub = NULL;
}
if (_pUnkObj)
{
_pUnkObj->Release();
_pUnkObj = NULL;
}
}
HRESULT CStubWrapper::Invoke(RPCOLEMESSAGE *pMsg, IRpcChannelBuffer *pChnl)
{
if (pMsg->rpcFlags & RPCFLG_NON_NDR)
{
// call is not NDR format, so use the hand-crafted stub.
// create the stub if it does not exist yet.
if (_pHCStub == NULL)
{
if ((_pHCStub = new CCubesStub(_pUnkObj)) == NULL)
return E_OUTOFMEMORY;
}
return _pHCStub->Invoke(pMsg, pChnl);
}
// call is NDR format, so use the MIDL generated stub.
// create the stub if it does not exist yet.
if (_pMIDLStub == NULL)
{
_pMIDLStub = CreateMIDLStub(IID_ICube, _pUnkObj);
if (_pMIDLStub == NULL)
return E_OUTOFMEMORY;
}
return _pMIDLStub->Invoke(pMsg, pChnl);
}
IRpcStubBuffer *CStubWrapper::IsIIDSupported(REFIID riid)
{
if (IsEqualIID(riid, _iid))
{
AddRef();
return (IRpcStubBuffer *)this;
}
return NULL;
}
ULONG CStubWrapper::CountRefs()
{
ULONG cRefs = (_pUnkObj) ? 1 : 0;
if (_pHCStub)
cRefs += _pHCStub->CountRefs();
if (_pMIDLStub)
cRefs += _pMIDLStub->CountRefs();
return cRefs;
}
HRESULT CStubWrapper::DebugServerQueryInterface(void **ppv)
{
*ppv = (void *)_pUnkObj;
return S_OK;
}
void CStubWrapper::DebugServerRelease(void *pv)
{
return;
}
//---------------------------------------------------------------------------
//
// Implement: CProxyWrapper
//
// Purpose: Wrapper object for itnerface proxies.
//
// Notes: the top several routines are the same for all proxies
// but you must change the interface specific routines for
// each new interface.
//
//---------------------------------------------------------------------------
CProxyWrapper::CProxyWrapper(IUnknown *pUnkOuter, IRpcProxyBuffer **ppProxy) :
_cRefs(1),
_pUnkOuter(pUnkOuter), // don't AddRef
_pRealProxy(NULL)
{
*ppProxy = (IRpcProxyBuffer *)&_InternalUnk;
}
CProxyWrapper::~CProxyWrapper(void)
{
if (_pRealProxy)
{
_InternalUnk.Disconnect();
}
}
HRESULT CProxyWrapper::CInternalUnk::QueryInterface(REFIID riid, void **ppv)
{
CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
if (IsEqualIID(riid, IID_IRpcProxyBuffer) ||
IsEqualIID(riid, IID_IUnknown))
{
pProxy->AddRef();
*ppv = (IRpcProxyBuffer *)this;
return S_OK;
}
else if (IsEqualIID(riid, IID_ICube))
{
*ppv = (ICube *)pProxy;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
ULONG CProxyWrapper::CInternalUnk::AddRef(void)
{
CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
InterlockedIncrement((LONG *)&pProxy->_cRefs);
return pProxy->_cRefs;
}
ULONG CProxyWrapper::CInternalUnk::Release(void)
{
CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
ULONG cRefs = pProxy->_cRefs-1;
if (InterlockedDecrement((LONG *)&pProxy->_cRefs) == 0)
{
delete this;
return 0;
}
return cRefs;
}
HRESULT CProxyWrapper::CInternalUnk::Connect(IRpcChannelBuffer *pChnl)
{
CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
void *pv;
HRESULT hr = pChnl->QueryInterface(IID_INonNDRStub, &pv);
if (SUCCEEDED(hr))
{
((IUnknown *)pv)->Release();
// create the hand-crafted proxy
pProxy->_pRealIf = new CCubesProxy(pProxy->_pUnkOuter,
&pProxy->_pRealProxy);
}
else
{
// create the MIDL generated proxy
pProxy->_pRealIf = (ICube *) CreateMIDLProxy(IID_ICube,
pProxy->_pUnkOuter,
&pProxy->_pRealProxy);
}
if (pProxy->_pRealIf == NULL)
return E_OUTOFMEMORY;
// since the proxy AddRef'd the punkOuter, we need to release it.
pProxy->_pUnkOuter->Release();
// connect the proxy
hr = pProxy->_pRealProxy->Connect(pChnl);
if (FAILED(hr))
{
pProxy->_pRealProxy->Release();
pProxy->_pRealProxy = NULL;
}
return hr;
}
void CProxyWrapper::CInternalUnk::Disconnect(void)
{
CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
if (pProxy->_pRealProxy)
{
pProxy->_pRealProxy->Disconnect();
pProxy->_pRealProxy->Release();
pProxy->_pRealProxy = NULL;
}
}
//---------------------------------------------------------------------------
//
// ICube specific proxy wrapper code below here.
//
//---------------------------------------------------------------------------
HRESULT CProxyWrapper::QueryInterface(REFIID riid, void **ppv)
{
return _pUnkOuter->QueryInterface(riid, ppv);
}
ULONG CProxyWrapper::AddRef(void)
{
return _pUnkOuter->AddRef();
}
ULONG CProxyWrapper::Release(void)
{
return _pUnkOuter->Release();
}
HRESULT CProxyWrapper::MoveCube(ULONG xPos, ULONG yPos)
{
if (_pRealProxy)
{
return _pRealIf->MoveCube(xPos, yPos);
}
return CO_E_OBJNOTCONNECTED;
}
HRESULT CProxyWrapper::GetCubePos(ULONG *pxPos, ULONG *pyPos)
{
if (_pRealProxy)
{
return _pRealIf->GetCubePos(pxPos, pyPos);
}
*pxPos = 0;
*pyPos = 0;
return CO_E_OBJNOTCONNECTED;
}
HRESULT CProxyWrapper::Contains(IBalls *pIFDb)
{
if (_pRealProxy)
{
return _pRealIf->Contains(pIFDb);
}
return CO_E_OBJNOTCONNECTED;
}
HRESULT CProxyWrapper::SimpleCall(
DWORD pidCaller,
DWORD tidCaller,
GUID lidCaller)
{
return CO_E_OBJNOTCONNECTED;
}
//---------------------------------------------------------------------------
//
// Implement: CCubesProxy
//
// Purpose: Hand-Crafted proxy object for interface ICube.
//
// Notes: Replace this with your exisitng 32bit hand-crafted proxies.
//
//---------------------------------------------------------------------------
CCubesProxy::CCubesProxy(IUnknown *pUnkOuter, IRpcProxyBuffer **ppProxy) :
_pUnkOuter(pUnkOuter),
_pChnl(NULL)
{
_pUnkOuter->AddRef();
*ppProxy = (IRpcProxyBuffer *)&_InternalUnk;
}
CCubesProxy::~CCubesProxy(void)
{
_InternalUnk.Disconnect();
}
HRESULT CCubesProxy::CInternalUnk::QueryInterface(REFIID riid, void **ppv)
{
if (IsEqualIID(riid, IID_IRpcProxyBuffer) ||
IsEqualIID(riid, IID_IUnknown))
{
CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
pProxy->AddRef();
*ppv = (IRpcProxyBuffer *)this;
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
ULONG CCubesProxy::CInternalUnk::AddRef(void)
{
CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
InterlockedIncrement((LONG *)&pProxy->_cRefs);
return pProxy->_cRefs;
}
ULONG CCubesProxy::CInternalUnk::Release(void)
{
CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
ULONG cRefs = pProxy->_cRefs-1;
if (InterlockedDecrement((LONG *)&pProxy->_cRefs) == 0)
{
delete this;
return 0;
}
return cRefs;
}
HRESULT CCubesProxy::CInternalUnk::Connect(IRpcChannelBuffer *pChnl)
{
Disconnect(); // make sure we are disconnected
CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
pProxy->_pChnl = pChnl; // keep the channel ptr
pChnl->AddRef();
return S_OK;
}
void CCubesProxy::CInternalUnk::Disconnect(void)
{
CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
if (pProxy->_pChnl)
{
pProxy->_pChnl->Release();
pProxy->_pChnl = NULL;
}
}
//---------------------------------------------------------------------------
//
// ICubes Proxy Implementation
//
//---------------------------------------------------------------------------
HRESULT CCubesProxy::QueryInterface(REFIID riid, void **ppv)
{
return _pUnkOuter->QueryInterface(riid, ppv);
}
ULONG CCubesProxy::AddRef(void)
{
return _pUnkOuter->AddRef();
}
ULONG CCubesProxy::Release(void)
{
return _pUnkOuter->Release();
}
HRESULT CCubesProxy::MoveCube(ULONG xPos, ULONG yPos)
{
// set up the message and get the buffer
RPCOLEMESSAGE msg;
memset(&msg, 0, sizeof(msg));
msg.iMethod = 3;
msg.dataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
msg.cbBuffer = 16;
HRESULT hrFromServer;
HRESULT hr = _pChnl->GetBuffer(&msg, IID_ICube);
if (SUCCEEDED(hr))
{
// Marshal the parameters. The string "myproxy" followed by
// xPos and yPos values.
char *pBuf = (char *)msg.Buffer;
strcpy((char *)pBuf, "myproxy");
pBuf += 8;
DWORD *dwp = (DWORD *)pBuf;
*dwp = xPos;
pBuf += 4;
dwp = (DWORD *)pBuf;
*dwp = yPos;
// Send the message and get the reply
ULONG ulStatus = 0;
hr = _pChnl->SendReceive(&msg, &ulStatus);
if (SUCCEEDED(hr))
{
// unmarshal the results
hrFromServer = (DWORD)(msg.Buffer);
}
// FreeBuffer
hr = _pChnl->FreeBuffer(&msg);
}
return hr;
}
HRESULT CCubesProxy::GetCubePos(ULONG *pxPos, ULONG *pyPos)
{
*pxPos = 0;
*pyPos = 0;
return E_NOTIMPL;
}
HRESULT CCubesProxy::Contains(IBalls *pIFDb)
{
return E_NOTIMPL;
}
HRESULT CCubesProxy::SimpleCall(
DWORD pidCaller,
DWORD tidCaller,
GUID lidCaller)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------
//
// Implement: CCubesStub
//
// Purpose: Hand-Crafted stub object for interface ICube.
//
// Notes: Replace this with your exisitng 32bit hand-crafted stubs.
//
//---------------------------------------------------------------------------
CCubesStub::CCubesStub(IUnknown *pUnkObj) :
_cRefs(1),
_pUnkObj(pUnkObj)
{
_pUnkObj->AddRef();
}
CCubesStub::~CCubesStub(void)
{
Disconnect();
}
HRESULT CCubesStub::QueryInterface(REFIID riid, void **ppv)
{
if (IsEqualIID(riid, IID_IRpcStubBuffer) ||
IsEqualIID(riid, IID_IUnknown))
{
*ppv = (IRpcStubBuffer *)this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG CCubesStub::AddRef(void)
{
InterlockedIncrement((LONG *)&_cRefs);
return _cRefs;
}
ULONG CCubesStub::Release(void)
{
ULONG cRefs = _cRefs-1;
if (InterlockedDecrement((LONG *)&_cRefs) == 0)
{
delete this;
return 0;
}
return cRefs;
}
HRESULT CCubesStub::Connect(IUnknown *pUnkObj)
{
if (_pUnkObj)
{
// already connected, disconnect
Disconnect();
}
// get the requested interface and hold it.
HRESULT hr = pUnkObj->QueryInterface(IID_ICube, (void **)&_pUnkObj);
if (FAILED(hr))
{
_pUnkObj = NULL;
}
return hr;
}
void CCubesStub::Disconnect()
{
if (_pUnkObj)
{
_pUnkObj->Release();
_pUnkObj = NULL;
}
}
HRESULT CCubesStub::Invoke(RPCOLEMESSAGE *pMsg, IRpcChannelBuffer *pChnl)
{
// Check the method number.
if (pMsg->iMethod !=3 || pMsg->cbBuffer != 16)
return E_INVALIDARG;
// unmarshal the parameters
char *pBuf = (char *)pMsg->Buffer;
pBuf += 8;
DWORD *dwp = (DWORD *)pBuf;
ULONG xPos = *dwp;
pBuf += 4;
dwp = (DWORD *)pBuf;
ULONG yPos = *dwp;
// call the real object
HRESULT hrFromServer = ((ICube *)_pUnkObj)->MoveCube(xPos, yPos);
// get a new buffer
pMsg->cbBuffer = 4;
HRESULT hr = pChnl->GetBuffer(pMsg, IID_ICube);
if (SUCCEEDED(hr))
{
// marshal the return values
pBuf = (char *)pMsg->Buffer;
dwp = (DWORD *)pBuf;
*dwp = hrFromServer;
}
return hr;
}
IRpcStubBuffer *CCubesStub::IsIIDSupported(REFIID riid)
{
if (IsEqualIID(riid, IID_ICube))
{
AddRef();
return (IRpcStubBuffer *)this;
}
return NULL;
}
ULONG CCubesStub::CountRefs()
{
// only keep one reference
return 1;
}
HRESULT CCubesStub::DebugServerQueryInterface(void **ppv)
{
*ppv = (void *)_pUnkObj;
return S_OK;
}
void CCubesStub::DebugServerRelease(void *pv)
{
return;
}