MyMoniker.cpp
上传用户:bjlvip
上传日期:2010-02-08
资源大小:744k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // MyMoniker.cpp
  2. #define _WIN32_DCOM
  3. #include <windows.h>
  4. #include <iostream.h>
  5. #include <stdio.h>
  6. #include "registry.h"
  7. const CLSID CLSID_MarvelousMoniker = {0x10000022,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}};
  8. long g_cComponents = 0;
  9. long g_cServerLocks = 0;
  10. class CMarvyMoniker : public IMoniker, public IClassActivator
  11. {
  12. friend class CClassObject;
  13. public:
  14. // IUnknown
  15. ULONG __stdcall AddRef();
  16. ULONG __stdcall Release();
  17. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  18. // IPersist
  19. HRESULT __stdcall GetClassID(CLSID* pClassID);
  20. // IPersistStream
  21. HRESULT __stdcall IsDirty();
  22. HRESULT __stdcall Load(IStream* pStm);
  23. HRESULT __stdcall Save(IStream* pStm, BOOL fClearDirty);
  24. HRESULT __stdcall GetSizeMax(ULARGE_INTEGER *pcbSize);
  25. // IMoniker
  26. HRESULT __stdcall BindToObject(IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult);
  27. HRESULT __stdcall BindToStorage(IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppvObj);
  28. HRESULT __stdcall Reduce(IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced);
  29. HRESULT __stdcall ComposeWith(IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite);
  30. HRESULT __stdcall Enum(BOOL fForward, IEnumMoniker **ppenumMoniker);
  31. HRESULT __stdcall IsEqual(IMoniker *pmkOtherMoniker);
  32. HRESULT __stdcall Hash(DWORD *pdwHash);
  33. HRESULT __stdcall IsRunning(IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning);
  34. HRESULT __stdcall GetTimeOfLastChange(IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime);
  35. HRESULT __stdcall Inverse(IMoniker **ppmk);
  36. HRESULT __stdcall CommonPrefixWith(IMoniker *pmkOther, IMoniker **ppmkPrefix);
  37. HRESULT __stdcall RelativePathTo(IMoniker *pmkOther, IMoniker **ppmkRelPath);
  38. HRESULT __stdcall GetDisplayName(IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName);
  39. HRESULT __stdcall ParseDisplayName(IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut);
  40. HRESULT __stdcall IsSystemMoniker(DWORD *pdwMksys);
  41. // IClassActivator
  42. HRESULT __stdcall GetClassObject(REFCLSID pClassID, DWORD dwClsContext, LCID locale, REFIID riid, void** ppv);
  43. CMarvyMoniker();
  44. CMarvyMoniker(REFCLSID clsid, COSERVERINFO* pCSI);
  45. ~CMarvyMoniker();
  46. private:
  47. ULONG m_cRef;
  48. wchar_t m_hostname[255];
  49. CLSID m_clsid;
  50. COSERVERINFO m_CoServerInfo;
  51. };
  52. CMarvyMoniker::CMarvyMoniker(REFCLSID clsid, COSERVERINFO* pCSI)
  53. {
  54. CMarvyMoniker();
  55. m_clsid = clsid;
  56. m_CoServerInfo.pwszName = wcscpy(m_hostname, pCSI->pwszName);
  57. }
  58. CMarvyMoniker::CMarvyMoniker() : m_cRef(1)
  59. {
  60. g_cComponents++;
  61. m_CoServerInfo.dwReserved1 = 0;
  62. m_CoServerInfo.pwszName = 0;
  63. m_CoServerInfo.pAuthInfo = 0;
  64. m_CoServerInfo.dwReserved2 = 0;
  65. }
  66. CMarvyMoniker::~CMarvyMoniker()
  67. {
  68. g_cComponents--;
  69. }
  70. HRESULT CMarvyMoniker::GetClassObject(REFCLSID pClassID, DWORD dwClsContext, LCID locale, REFIID riid, void** ppv)
  71. {
  72. wprintf(L"IClassActivator::GetClassObject connecting to %sn", m_CoServerInfo.pwszName);
  73. HRESULT hr = CoGetClassObject(pClassID, CLSCTX_SERVER, &m_CoServerInfo, riid, ppv);
  74. if(FAILED(hr))
  75. printf("CoCreateInstance failed %0xn", hr);
  76. return hr;
  77. }
  78. HRESULT CMarvyMoniker::GetClassID(CLSID* pClassID)
  79. {
  80. *pClassID = CLSID_MarvelousMoniker;
  81. return S_OK;
  82. }
  83. HRESULT CMarvyMoniker::IsDirty()
  84. {
  85. return S_FALSE;
  86. }
  87. HRESULT CMarvyMoniker::Load(IStream* pStm)
  88. {
  89. return E_NOTIMPL;
  90. }
  91. HRESULT CMarvyMoniker::Save(IStream* pStm, BOOL fClearDirty)
  92. {
  93. return E_NOTIMPL;
  94. }
  95. HRESULT CMarvyMoniker::GetSizeMax(ULARGE_INTEGER *pcbSize)
  96. {
  97. return E_NOTIMPL;
  98. }
  99. HRESULT CMarvyMoniker::BindToObject(IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult)
  100. {
  101. // This catches the recursive call by the class moniker
  102. if(riidResult == IID_IClassActivator)
  103. {
  104. *ppvResult = (IClassActivator*)this;
  105. return S_OK;
  106. }
  107. // An AddRef a day keeps the doctor away
  108. AddRef();
  109. IMoniker* pClassMoniker;
  110. HRESULT hr = CreateClassMoniker(m_clsid, &pClassMoniker);
  111. if(FAILED(hr))
  112. return hr;
  113. // Bind the class moniker
  114. hr = pClassMoniker->BindToObject(pbc, (IMoniker*)this, riidResult, ppvResult);
  115. pClassMoniker->Release();
  116. return hr;
  117. }
  118. HRESULT CMarvyMoniker::BindToStorage(IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppvObj)
  119. {
  120. return MK_E_NOSTORAGE;
  121. }
  122. HRESULT CMarvyMoniker::Reduce(IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
  123. {
  124. *ppmkReduced = (IMoniker*)this;
  125. return MK_S_REDUCED_TO_SELF;
  126. }
  127. HRESULT CMarvyMoniker::ComposeWith(IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite)
  128. {
  129. if(fOnlyIfNotGeneric)
  130. {
  131. *ppmkComposite = NULL;
  132. return MK_E_NEEDGENERIC;
  133. }
  134. return CreateGenericComposite((IMoniker*)this, pmkRight, ppmkComposite);
  135. }
  136. HRESULT CMarvyMoniker::Enum(BOOL fForward, IEnumMoniker **ppenumMoniker)
  137. {
  138. *ppenumMoniker = NULL;
  139. return S_OK;
  140. }
  141. HRESULT CMarvyMoniker::IsEqual(IMoniker *pmkOtherMoniker)
  142. {
  143. return E_NOTIMPL;
  144. }
  145. HRESULT CMarvyMoniker::Hash(DWORD *pdwHash)
  146. {
  147. return E_NOTIMPL;
  148. }
  149. HRESULT CMarvyMoniker::IsRunning(IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning)
  150. {
  151. return E_NOTIMPL;
  152. }
  153. HRESULT CMarvyMoniker::GetTimeOfLastChange(IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime)
  154. {
  155. return MK_E_UNAVAILABLE;
  156. }
  157. HRESULT CMarvyMoniker::Inverse(IMoniker **ppmk)
  158. {
  159. return CreateAntiMoniker(ppmk);
  160. }
  161. HRESULT CMarvyMoniker::CommonPrefixWith(IMoniker *pmkOther, IMoniker **ppmkPrefix)
  162. {
  163. return E_NOTIMPL;
  164. }
  165. HRESULT CMarvyMoniker::RelativePathTo(IMoniker *pmkOther, IMoniker **ppmkRelPath)
  166. {
  167. return MonikerRelativePathTo((IMoniker*)this, pmkOther, ppmkRelPath, TRUE);
  168. }
  169. HRESULT CMarvyMoniker::GetDisplayName(IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
  170. {
  171. *ppszDisplayName = (wchar_t*)CoTaskMemAlloc(512);
  172. wchar_t ppsz[39];
  173. StringFromGUID2(m_clsid, ppsz, 39);
  174. ppsz[37] = 0;
  175. swprintf(*ppszDisplayName, L"host:%s!clsid:%s", m_hostname, wcstok(ppsz, L"{"));
  176. return S_OK;
  177. }
  178. HRESULT CMarvyMoniker::ParseDisplayName(IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
  179. {
  180. return E_NOTIMPL;
  181. }
  182. HRESULT CMarvyMoniker::IsSystemMoniker(DWORD *pdwMksys)
  183. {
  184. *pdwMksys = MKSYS_NONE;
  185. return S_OK;
  186. }
  187. ULONG CMarvyMoniker::AddRef()
  188. {
  189. cout << "Moniker::AddRef() m_cRef = " << m_cRef + 1 << endl;
  190. return ++m_cRef;
  191. }
  192. ULONG CMarvyMoniker::Release()
  193. {
  194. cout << "Moniker::Release() m_cRef = " << m_cRef - 1 << endl;
  195. if(--m_cRef != 0)
  196. return m_cRef;
  197. delete this;
  198. return 0;
  199. }
  200. HRESULT CMarvyMoniker::QueryInterface(REFIID riid, void** ppv)
  201. {
  202. if(riid == IID_IUnknown)
  203. {
  204. cout << "Moniker::QueryInterface() for IUnknown" << endl;
  205. *ppv = reinterpret_cast<IUnknown*>(this);
  206. }
  207. else if(riid == IID_IMoniker)
  208. {
  209. cout << "Moniker::QueryInterface() for IMoniker" << endl;
  210. *ppv = (IMoniker*)this;
  211. }
  212. else 
  213. {
  214. *ppv = NULL;
  215. return E_NOINTERFACE;
  216. }
  217. AddRef();
  218. return S_OK;
  219. }
  220. class CClassObject : public IParseDisplayName
  221. {
  222. public:
  223. // IUnknown
  224. ULONG __stdcall AddRef();
  225. ULONG __stdcall Release();
  226. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  227. // IParseDisplayName
  228. HRESULT __stdcall ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut);
  229. CClassObject() : m_cRef(1) { }
  230. ~CClassObject() { }
  231. private:
  232. ULONG m_cRef;
  233. };
  234. ULONG CClassObject::AddRef()
  235. {
  236. return ++m_cRef;
  237. }
  238. ULONG CClassObject::Release()
  239. {
  240. if(--m_cRef != 0)
  241. return m_cRef;
  242. delete this;
  243. return 0;
  244. }
  245. HRESULT CClassObject::QueryInterface(REFIID riid, void** ppv)
  246. {
  247. if(riid == IID_IUnknown)
  248. *ppv = (IUnknown*)this;
  249. else if(riid == IID_IParseDisplayName)
  250. {
  251. cout << "CClassObject::QueryInterface() for IParseDisplayName" << endl;
  252. *ppv = (IParseDisplayName*)this;
  253. }
  254. else
  255. {
  256. *ppv = NULL;
  257. return E_NOINTERFACE;
  258. }
  259. AddRef();
  260. return S_OK;
  261. }
  262. HRESULT CClassObject::ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
  263. {
  264. // Instantiate the moniker
  265. CMarvyMoniker* pCMarvyMoniker = new CMarvyMoniker();
  266. // Parse and check display name
  267. // It must have the following format:
  268. // host:hostname!clsid:????????-????-????-????-????????????
  269. if(_wcsicmp(wcstok(pszDisplayName, L":"), L"host") == 0)
  270. {
  271. pCMarvyMoniker->m_CoServerInfo.pwszName = wcscpy(pCMarvyMoniker->m_hostname, wcstok(NULL, L"!"));
  272. if(_wcsicmp(wcstok(NULL, L":"), L"clsid") == 0)
  273. {
  274. wchar_t clsid_with_braces[39] = L"{";
  275. wcscat(wcscat(clsid_with_braces, wcstok(NULL, L"!")), L"}");
  276. CLSIDFromString(clsid_with_braces, &pCMarvyMoniker->m_clsid);
  277. }
  278. }
  279. // Get IMoniker* to return to caller
  280. pCMarvyMoniker->QueryInterface(IID_IMoniker, (void**)ppmkOut);
  281. pCMarvyMoniker->Release();
  282. // Indicate that we have digested the entire display name.
  283. *pchEaten = (ULONG)wcslen(pszDisplayName);
  284. return S_OK;
  285. }
  286. HRESULT __stdcall DllCanUnloadNow()
  287. {
  288. cout << "Moniker: DllCanUnloadNow() " << (g_cServerLocks == 0 && g_cComponents == 0 ? "Yes" : "No") << endl;
  289. if(g_cServerLocks == 0 && g_cComponents == 0)
  290. return S_OK;
  291. else
  292. return S_FALSE;
  293. }
  294. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
  295. {
  296. cout << "Moniker: DllGetClassObject" << endl;
  297. if(clsid != CLSID_MarvelousMoniker)
  298. return CLASS_E_CLASSNOTAVAILABLE;
  299. CClassObject* pClassObject = new CClassObject;
  300. if(pClassObject == NULL)
  301. return E_OUTOFMEMORY;
  302. // QueryInterface probably for IClassFactory
  303. HRESULT hr = pClassObject->QueryInterface(riid, ppv);
  304. pClassObject->Release();
  305. return hr;
  306. }
  307. HRESULT __stdcall DllRegisterServer()
  308. {
  309. // The progid "Host" must be registered in order for the moniker to work
  310. return RegisterServer("moniker.dll", CLSID_MarvelousMoniker, "Marvelous Moniker", "Host", "Host", NULL);
  311. }
  312. HRESULT __stdcall DllUnregisterServer()
  313. {
  314. return UnregisterServer(CLSID_MarvelousMoniker, "Host", "Host");
  315. }
  316. HRESULT __stdcall CreateMarvelousMoniker(REFCLSID clsid, COSERVERINFO* pCSI, IMoniker** ppMoniker)
  317. {
  318. CMarvyMoniker *pCMarvyMoniker = new CMarvyMoniker(clsid, pCSI);
  319. if(pCMarvyMoniker == NULL)
  320. return E_OUTOFMEMORY;
  321. HRESULT hr = pCMarvyMoniker->QueryInterface(IID_IMoniker, (void**)ppMoniker);
  322. pCMarvyMoniker->Release();
  323. return hr;
  324. }