📄 mymoniker.cpp
字号:
// MyMoniker.cpp
#define _WIN32_DCOM
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include "registry.h"
const CLSID CLSID_MarvelousMoniker = {0x10000022,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}};
long g_cComponents = 0;
long g_cServerLocks = 0;
class CMarvyMoniker : public IMoniker, public IClassActivator
{
friend class CClassObject;
public:
// IUnknown
ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
// IPersist
HRESULT __stdcall GetClassID(CLSID* pClassID);
// IPersistStream
HRESULT __stdcall IsDirty();
HRESULT __stdcall Load(IStream* pStm);
HRESULT __stdcall Save(IStream* pStm, BOOL fClearDirty);
HRESULT __stdcall GetSizeMax(ULARGE_INTEGER *pcbSize);
// IMoniker
HRESULT __stdcall BindToObject(IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult);
HRESULT __stdcall BindToStorage(IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppvObj);
HRESULT __stdcall Reduce(IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced);
HRESULT __stdcall ComposeWith(IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite);
HRESULT __stdcall Enum(BOOL fForward, IEnumMoniker **ppenumMoniker);
HRESULT __stdcall IsEqual(IMoniker *pmkOtherMoniker);
HRESULT __stdcall Hash(DWORD *pdwHash);
HRESULT __stdcall IsRunning(IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning);
HRESULT __stdcall GetTimeOfLastChange(IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime);
HRESULT __stdcall Inverse(IMoniker **ppmk);
HRESULT __stdcall CommonPrefixWith(IMoniker *pmkOther, IMoniker **ppmkPrefix);
HRESULT __stdcall RelativePathTo(IMoniker *pmkOther, IMoniker **ppmkRelPath);
HRESULT __stdcall GetDisplayName(IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName);
HRESULT __stdcall ParseDisplayName(IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut);
HRESULT __stdcall IsSystemMoniker(DWORD *pdwMksys);
// IClassActivator
HRESULT __stdcall GetClassObject(REFCLSID pClassID, DWORD dwClsContext, LCID locale, REFIID riid, void** ppv);
CMarvyMoniker();
CMarvyMoniker(REFCLSID clsid, COSERVERINFO* pCSI);
~CMarvyMoniker();
private:
ULONG m_cRef;
wchar_t m_hostname[255];
CLSID m_clsid;
COSERVERINFO m_CoServerInfo;
};
CMarvyMoniker::CMarvyMoniker(REFCLSID clsid, COSERVERINFO* pCSI)
{
CMarvyMoniker();
m_clsid = clsid;
m_CoServerInfo.pwszName = wcscpy(m_hostname, pCSI->pwszName);
}
CMarvyMoniker::CMarvyMoniker() : m_cRef(1)
{
g_cComponents++;
m_CoServerInfo.dwReserved1 = 0;
m_CoServerInfo.pwszName = 0;
m_CoServerInfo.pAuthInfo = 0;
m_CoServerInfo.dwReserved2 = 0;
}
CMarvyMoniker::~CMarvyMoniker()
{
g_cComponents--;
}
HRESULT CMarvyMoniker::GetClassObject(REFCLSID pClassID, DWORD dwClsContext, LCID locale, REFIID riid, void** ppv)
{
wprintf(L"IClassActivator::GetClassObject connecting to %s\n", m_CoServerInfo.pwszName);
HRESULT hr = CoGetClassObject(pClassID, CLSCTX_SERVER, &m_CoServerInfo, riid, ppv);
if(FAILED(hr))
printf("CoCreateInstance failed %0x\n", hr);
return hr;
}
HRESULT CMarvyMoniker::GetClassID(CLSID* pClassID)
{
*pClassID = CLSID_MarvelousMoniker;
return S_OK;
}
HRESULT CMarvyMoniker::IsDirty()
{
return S_FALSE;
}
HRESULT CMarvyMoniker::Load(IStream* pStm)
{
return E_NOTIMPL;
}
HRESULT CMarvyMoniker::Save(IStream* pStm, BOOL fClearDirty)
{
return E_NOTIMPL;
}
HRESULT CMarvyMoniker::GetSizeMax(ULARGE_INTEGER *pcbSize)
{
return E_NOTIMPL;
}
HRESULT CMarvyMoniker::BindToObject(IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult)
{
// This catches the recursive call by the class moniker
if(riidResult == IID_IClassActivator)
{
*ppvResult = (IClassActivator*)this;
return S_OK;
}
// An AddRef a day keeps the doctor away
AddRef();
IMoniker* pClassMoniker;
HRESULT hr = CreateClassMoniker(m_clsid, &pClassMoniker);
if(FAILED(hr))
return hr;
// Bind the class moniker
hr = pClassMoniker->BindToObject(pbc, (IMoniker*)this, riidResult, ppvResult);
pClassMoniker->Release();
return hr;
}
HRESULT CMarvyMoniker::BindToStorage(IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppvObj)
{
return MK_E_NOSTORAGE;
}
HRESULT CMarvyMoniker::Reduce(IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
{
*ppmkReduced = (IMoniker*)this;
return MK_S_REDUCED_TO_SELF;
}
HRESULT CMarvyMoniker::ComposeWith(IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite)
{
if(fOnlyIfNotGeneric)
{
*ppmkComposite = NULL;
return MK_E_NEEDGENERIC;
}
return CreateGenericComposite((IMoniker*)this, pmkRight, ppmkComposite);
}
HRESULT CMarvyMoniker::Enum(BOOL fForward, IEnumMoniker **ppenumMoniker)
{
*ppenumMoniker = NULL;
return S_OK;
}
HRESULT CMarvyMoniker::IsEqual(IMoniker *pmkOtherMoniker)
{
return E_NOTIMPL;
}
HRESULT CMarvyMoniker::Hash(DWORD *pdwHash)
{
return E_NOTIMPL;
}
HRESULT CMarvyMoniker::IsRunning(IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning)
{
return E_NOTIMPL;
}
HRESULT CMarvyMoniker::GetTimeOfLastChange(IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime)
{
return MK_E_UNAVAILABLE;
}
HRESULT CMarvyMoniker::Inverse(IMoniker **ppmk)
{
return CreateAntiMoniker(ppmk);
}
HRESULT CMarvyMoniker::CommonPrefixWith(IMoniker *pmkOther, IMoniker **ppmkPrefix)
{
return E_NOTIMPL;
}
HRESULT CMarvyMoniker::RelativePathTo(IMoniker *pmkOther, IMoniker **ppmkRelPath)
{
return MonikerRelativePathTo((IMoniker*)this, pmkOther, ppmkRelPath, TRUE);
}
HRESULT CMarvyMoniker::GetDisplayName(IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
{
*ppszDisplayName = (wchar_t*)CoTaskMemAlloc(512);
wchar_t ppsz[39];
StringFromGUID2(m_clsid, ppsz, 39);
ppsz[37] = 0;
swprintf(*ppszDisplayName, L"host:%s!clsid:%s", m_hostname, wcstok(ppsz, L"{"));
return S_OK;
}
HRESULT CMarvyMoniker::ParseDisplayName(IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
{
return E_NOTIMPL;
}
HRESULT CMarvyMoniker::IsSystemMoniker(DWORD *pdwMksys)
{
*pdwMksys = MKSYS_NONE;
return S_OK;
}
ULONG CMarvyMoniker::AddRef()
{
cout << "Moniker::AddRef() m_cRef = " << m_cRef + 1 << endl;
return ++m_cRef;
}
ULONG CMarvyMoniker::Release()
{
cout << "Moniker::Release() m_cRef = " << m_cRef - 1 << endl;
if(--m_cRef != 0)
return m_cRef;
delete this;
return 0;
}
HRESULT CMarvyMoniker::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown)
{
cout << "Moniker::QueryInterface() for IUnknown" << endl;
*ppv = reinterpret_cast<IUnknown*>(this);
}
else if(riid == IID_IMoniker)
{
cout << "Moniker::QueryInterface() for IMoniker" << endl;
*ppv = (IMoniker*)this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
class CClassObject : public IParseDisplayName
{
public:
// IUnknown
ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
// IParseDisplayName
HRESULT __stdcall ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut);
CClassObject() : m_cRef(1) { }
~CClassObject() { }
private:
ULONG m_cRef;
};
ULONG CClassObject::AddRef()
{
return ++m_cRef;
}
ULONG CClassObject::Release()
{
if(--m_cRef != 0)
return m_cRef;
delete this;
return 0;
}
HRESULT CClassObject::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown)
*ppv = (IUnknown*)this;
else if(riid == IID_IParseDisplayName)
{
cout << "CClassObject::QueryInterface() for IParseDisplayName" << endl;
*ppv = (IParseDisplayName*)this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
HRESULT CClassObject::ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
{
// Instantiate the moniker
CMarvyMoniker* pCMarvyMoniker = new CMarvyMoniker();
// Parse and check display name
// It must have the following format:
// host:hostname!clsid:????????-????-????-????-????????????
if(_wcsicmp(wcstok(pszDisplayName, L":"), L"host") == 0)
{
pCMarvyMoniker->m_CoServerInfo.pwszName = wcscpy(pCMarvyMoniker->m_hostname, wcstok(NULL, L"!"));
if(_wcsicmp(wcstok(NULL, L":"), L"clsid") == 0)
{
wchar_t clsid_with_braces[39] = L"{";
wcscat(wcscat(clsid_with_braces, wcstok(NULL, L"!")), L"}");
CLSIDFromString(clsid_with_braces, &pCMarvyMoniker->m_clsid);
}
}
// Get IMoniker* to return to caller
pCMarvyMoniker->QueryInterface(IID_IMoniker, (void**)ppmkOut);
pCMarvyMoniker->Release();
// Indicate that we have digested the entire display name.
*pchEaten = (ULONG)wcslen(pszDisplayName);
return S_OK;
}
HRESULT __stdcall DllCanUnloadNow()
{
cout << "Moniker: DllCanUnloadNow() " << (g_cServerLocks == 0 && g_cComponents == 0 ? "Yes" : "No") << endl;
if(g_cServerLocks == 0 && g_cComponents == 0)
return S_OK;
else
return S_FALSE;
}
HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
{
cout << "Moniker: DllGetClassObject" << endl;
if(clsid != CLSID_MarvelousMoniker)
return CLASS_E_CLASSNOTAVAILABLE;
CClassObject* pClassObject = new CClassObject;
if(pClassObject == NULL)
return E_OUTOFMEMORY;
// QueryInterface probably for IClassFactory
HRESULT hr = pClassObject->QueryInterface(riid, ppv);
pClassObject->Release();
return hr;
}
HRESULT __stdcall DllRegisterServer()
{
// The progid "Host" must be registered in order for the moniker to work
return RegisterServer("moniker.dll", CLSID_MarvelousMoniker, "Marvelous Moniker", "Host", "Host", NULL);
}
HRESULT __stdcall DllUnregisterServer()
{
return UnregisterServer(CLSID_MarvelousMoniker, "Host", "Host");
}
HRESULT __stdcall CreateMarvelousMoniker(REFCLSID clsid, COSERVERINFO* pCSI, IMoniker** ppMoniker)
{
CMarvyMoniker *pCMarvyMoniker = new CMarvyMoniker(clsid, pCSI);
if(pCMarvyMoniker == NULL)
return E_OUTOFMEMORY;
HRESULT hr = pCMarvyMoniker->QueryInterface(IID_IMoniker, (void**)ppMoniker);
pCMarvyMoniker->Release();
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -