483 lines
8.5 KiB
C++
483 lines
8.5 KiB
C++
|
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <ole2.h>
|
||
|
#include <stdio.h>
|
||
|
#include <tunk.h>
|
||
|
|
||
|
|
||
|
CTestUnk::CTestUnk(void) : _cRefs(1)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CTestUnk::~CTestUnk(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP CTestUnk::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
|
||
|
{
|
||
|
HRESULT hRslt = S_OK;
|
||
|
|
||
|
if (IsEqualIID(riid, IID_IUnknown) ||
|
||
|
IsEqualIID(riid, IID_IParseDisplayName))
|
||
|
{
|
||
|
*ppvObj = (void *)(IParseDisplayName *)this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else if (IsEqualIID(riid, IID_ICube))
|
||
|
{
|
||
|
*ppvObj = (void *) new CTestUnkCube((IUnknown *)(IParseDisplayName *)this);
|
||
|
if (*ppvObj == NULL)
|
||
|
{
|
||
|
hRslt = E_NOINTERFACE;
|
||
|
}
|
||
|
}
|
||
|
else if (IsEqualIID(riid, IID_IOleWindow))
|
||
|
{
|
||
|
*ppvObj = (void *)(IOleWindow *)this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else if (IsEqualIID(riid, IID_IAdviseSink))
|
||
|
{
|
||
|
*ppvObj = (void *)(IAdviseSink *)this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppvObj = NULL;
|
||
|
hRslt = E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
return hRslt;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CTestUnk::AddRef(void)
|
||
|
{
|
||
|
_cRefs++;
|
||
|
return _cRefs;
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CTestUnk::Release(void)
|
||
|
{
|
||
|
_cRefs--;
|
||
|
if (_cRefs == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return _cRefs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP CTestUnk::ParseDisplayName(LPBC pbc, LPOLESTR lpszDisplayName,
|
||
|
ULONG *pchEaten, LPMONIKER *ppmkOut)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnk::GetWindow(HWND *phwnd)
|
||
|
{
|
||
|
*phwnd = NULL;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnk::ContextSensitiveHelp(BOOL fEnterMode)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(void) CTestUnk::OnDataChange(FORMATETC *pFormatetc,
|
||
|
STGMEDIUM *pStgmed)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(void) CTestUnk::OnViewChange(DWORD dwAspect,
|
||
|
LONG lindex)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(void) CTestUnk::OnRename(IMoniker *pmk)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(void) CTestUnk::OnSave()
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(void) CTestUnk::OnClose()
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
CTestUnkCube::CTestUnkCube(IUnknown *pUnkCtrl) :
|
||
|
_cRefs(1),
|
||
|
_pUnkCtrl(pUnkCtrl),
|
||
|
_pUnkIn(NULL)
|
||
|
{
|
||
|
_pUnkCtrl->AddRef();
|
||
|
}
|
||
|
|
||
|
CTestUnkCube::~CTestUnkCube(void)
|
||
|
{
|
||
|
_pUnkCtrl->Release();
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP CTestUnkCube::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
|
||
|
{
|
||
|
return _pUnkCtrl->QueryInterface(riid, ppvObj);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CTestUnkCube::AddRef(void)
|
||
|
{
|
||
|
_cRefs++;
|
||
|
return _cRefs;
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CTestUnkCube::Release(void)
|
||
|
{
|
||
|
_cRefs--;
|
||
|
if (_cRefs == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return _cRefs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// these methods dont really have to do anything, we are just testing that
|
||
|
// they are callable.
|
||
|
|
||
|
STDMETHODIMP CTestUnkCube::MoveCube(ULONG xPos, ULONG yPos)
|
||
|
{
|
||
|
if (_cRefs > 0)
|
||
|
return S_OK;
|
||
|
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkCube::GetCubePos(ULONG *xPos, ULONG *yPos)
|
||
|
{
|
||
|
if (_cRefs > 0)
|
||
|
return S_OK;
|
||
|
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkCube::Contains(IBalls *pIFDb)
|
||
|
{
|
||
|
if (_cRefs > 0)
|
||
|
return S_OK;
|
||
|
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkCube::SimpleCall(DWORD pidCaller, DWORD tidCaller, GUID lidCaller)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
GUID lid;
|
||
|
HRESULT hr2 = CoGetCurrentLogicalThreadId(&lid);
|
||
|
|
||
|
if (SUCCEEDED(hr2))
|
||
|
{
|
||
|
if (!IsEqualGUID(lid, lidCaller))
|
||
|
{
|
||
|
// LIDs dont match, error
|
||
|
hr |= 0x80000001;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return hr2;
|
||
|
}
|
||
|
|
||
|
DWORD tid;
|
||
|
hr2 = CoGetCallerTID(&tid);
|
||
|
|
||
|
if (SUCCEEDED(hr2))
|
||
|
{
|
||
|
if (pidCaller == GetCurrentProcessId())
|
||
|
{
|
||
|
// if in same process, CoGetCallerTID should return S_OK
|
||
|
if (hr2 != S_OK)
|
||
|
{
|
||
|
hr |= 0x80000002;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// if in different process, CoGetCallerTID should return S_FALSE
|
||
|
if (hr2 != S_FALSE)
|
||
|
{
|
||
|
hr |= 0x80000004;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return hr2;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkCube::PrepForInputSyncCall(IUnknown *pUnkIn)
|
||
|
{
|
||
|
// just remember the input ptr
|
||
|
|
||
|
_pUnkIn = pUnkIn;
|
||
|
_pUnkIn->AddRef();
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkCube::InputSyncCall()
|
||
|
{
|
||
|
// just attempt to release an Interface Pointer inside an InputSync
|
||
|
// method.
|
||
|
|
||
|
if (_pUnkIn)
|
||
|
{
|
||
|
if (_pUnkIn->Release() != 0)
|
||
|
return RPC_E_CANTCALLOUT_ININPUTSYNCCALL;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CTestUnkCF::CTestUnkCF, public
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: 23-Nov-92 Rickhi Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------
|
||
|
CTestUnkCF::CTestUnkCF()
|
||
|
{
|
||
|
_cRefs = 1;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CTestUnkCF::QueryInterface, public
|
||
|
//
|
||
|
// Algorithm: if the interface is not one implemented by us,
|
||
|
// pass the request to the proxy manager
|
||
|
//
|
||
|
// History: 23-Nov-92 Rickhi Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------
|
||
|
STDMETHODIMP CTestUnkCF::QueryInterface(REFIID riid, void **ppUnk)
|
||
|
{
|
||
|
if (IsEqualIID(riid, IID_IUnknown) ||
|
||
|
IsEqualIID(riid, IID_IClassFactory))
|
||
|
{
|
||
|
*ppUnk = (void *)(IClassFactory *) this;
|
||
|
AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
*ppUnk = NULL;
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CTestUnkCF::AddRef(void)
|
||
|
{
|
||
|
_cRefs++;
|
||
|
return _cRefs;
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CTestUnkCF::Release(void)
|
||
|
{
|
||
|
_cRefs--;
|
||
|
if (_cRefs == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return _cRefs;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CTestUnkCF::CreateInstance, public
|
||
|
//
|
||
|
// Synopsis: create a new object with the same class
|
||
|
//
|
||
|
// History: 23-Nov-92 Rickhi Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------
|
||
|
STDMETHODIMP CTestUnkCF::CreateInstance(IUnknown *punkOuter,
|
||
|
REFIID riid,
|
||
|
void **ppunkObject)
|
||
|
{
|
||
|
SCODE sc = E_OUTOFMEMORY;
|
||
|
*ppunkObject = NULL; // in case of failure
|
||
|
|
||
|
// create an instance object.
|
||
|
IUnknown *punk = (IUnknown *)(IParseDisplayName *) new CTestUnk();
|
||
|
|
||
|
if (punk)
|
||
|
{
|
||
|
// get the interface the caller wants to use
|
||
|
sc = punk->QueryInterface(riid, ppunkObject);
|
||
|
|
||
|
// release our hold, since the QI got a hold for the client.
|
||
|
punk->Release();
|
||
|
}
|
||
|
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CTestUnkCF::LockServer, public
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// History: 23-Nov-92 Rickhi Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------
|
||
|
STDMETHODIMP CTestUnkCF::LockServer(BOOL fLock)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
CTestUnkMarshal::CTestUnkMarshal(void) : _cRefs(1), _pIM(NULL)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CTestUnkMarshal::~CTestUnkMarshal(void)
|
||
|
{
|
||
|
if (_pIM)
|
||
|
{
|
||
|
_pIM->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkMarshal::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
|
||
|
{
|
||
|
HRESULT hRslt = S_OK;
|
||
|
|
||
|
if (IsEqualIID(riid, IID_IUnknown) ||
|
||
|
IsEqualIID(riid, IID_IMarshal))
|
||
|
{
|
||
|
*ppvObj = (void *)(IMarshal *)this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppvObj = NULL;
|
||
|
hRslt = E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
return hRslt;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CTestUnkMarshal::AddRef(void)
|
||
|
{
|
||
|
_cRefs++;
|
||
|
return _cRefs;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CTestUnkMarshal::Release(void)
|
||
|
{
|
||
|
_cRefs--;
|
||
|
if (_cRefs == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return _cRefs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkMarshal::GetUnmarshalClass(REFIID riid, LPVOID pv,
|
||
|
DWORD dwDestCtx, LPVOID pvDestCtx, DWORD mshlflags, LPCLSID pClsid)
|
||
|
{
|
||
|
if (GetStdMarshal() == NULL)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
return _pIM->GetUnmarshalClass(riid, pv, dwDestCtx, pvDestCtx,
|
||
|
(mshlflags | MSHLFLAGS_NOPING), pClsid);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkMarshal::GetMarshalSizeMax(REFIID riid, LPVOID pv,
|
||
|
DWORD dwDestCtx, LPVOID pvDestCtx, DWORD mshlflags, LPDWORD pSize)
|
||
|
{
|
||
|
if (GetStdMarshal() == NULL)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
return _pIM->GetMarshalSizeMax(riid, pv, dwDestCtx, pvDestCtx,
|
||
|
(mshlflags | MSHLFLAGS_NOPING), pSize);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkMarshal::MarshalInterface(LPSTREAM pStm, REFIID riid,
|
||
|
LPVOID pv, DWORD dwDestCtx, LPVOID pvDestCtx, DWORD mshlflags)
|
||
|
{
|
||
|
if (GetStdMarshal() == NULL)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
return _pIM->MarshalInterface(pStm, riid, pv, dwDestCtx, pvDestCtx,
|
||
|
(mshlflags | MSHLFLAGS_NOPING));
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkMarshal::UnmarshalInterface(LPSTREAM pStm, REFIID riid,
|
||
|
LPVOID *ppv)
|
||
|
{
|
||
|
return CoUnmarshalInterface(pStm, riid, ppv);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkMarshal::ReleaseMarshalData(LPSTREAM pStm)
|
||
|
{
|
||
|
return CoReleaseMarshalData(pStm);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTestUnkMarshal::DisconnectObject(DWORD dwReserved)
|
||
|
{
|
||
|
if (GetStdMarshal() == NULL)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
return _pIM->DisconnectObject(dwReserved);
|
||
|
}
|
||
|
|
||
|
IMarshal *CTestUnkMarshal::GetStdMarshal(void)
|
||
|
{
|
||
|
if (_pIM == NULL)
|
||
|
{
|
||
|
HRESULT hr = CoGetStandardMarshal(IID_IUnknown, (IUnknown *)this, 0,
|
||
|
0, MSHLFLAGS_NOPING, &_pIM);
|
||
|
}
|
||
|
|
||
|
return _pIM;
|
||
|
}
|