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

Windows编程

开发平台:

Visual C++

  1. // handler.cpp
  2. #include <iostream.h>
  3. #include "Componentcomponent.h"
  4. #include "registry.h"
  5. const REG_DATA g_regData[] = {
  6.     { "CLSID\{11000006-0000-0000-0000-000000000001}", 0, "InsideCOM Handler" },
  7. { "CLSID\{11000006-0000-0000-0000-000000000001}\InprocHandler32", 0, (const char*)-1 }, 
  8. { "CLSID\{11000006-0000-0000-0000-000000000001}\InprocHandler32", "ThreadingModel", "Both" },
  9. { 0, 0, 0 }
  10. };
  11. const CLSID CLSID_InsideCOMHandler = {0x11000006,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
  12. HINSTANCE g_hInstance;
  13. long g_cComponents = 0;
  14. long g_cServerLocks = 0;
  15. interface INoAggregationUnknown
  16. {
  17. virtual HRESULT __stdcall QueryInterface_NoAggregation(REFIID riid, void** ppv)=0;
  18. virtual ULONG __stdcall AddRef_NoAggregation()=0;
  19. virtual ULONG __stdcall Release_NoAggregation()=0;
  20. };
  21. class CInsideCOM : public ISum, public INoAggregationUnknown
  22. {
  23. public:
  24. // IUnknown
  25. ULONG __stdcall AddRef();
  26. ULONG __stdcall Release();
  27. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  28. // INoAggregationUnknown
  29. ULONG __stdcall AddRef_NoAggregation();
  30. ULONG __stdcall Release_NoAggregation();
  31. HRESULT __stdcall QueryInterface_NoAggregation(REFIID riid, void** ppv);
  32. // ISum
  33. HRESULT __stdcall Sum(int x, int y, int* retval);
  34. HRESULT __stdcall Init(IUnknown* pUnknownOuter);
  35. CInsideCOM() : m_cRef(1) { g_cComponents++; }
  36. ~CInsideCOM()
  37. {
  38. cout << "Handler: CInsideCOM::~CInsideCOM()" << endl;
  39. g_cComponents--;
  40. // Important: Release the proxy manager in order to release the object
  41. m_pUnknownInner->Release();
  42. }
  43. private:
  44. ULONG m_cRef;
  45. IUnknown* m_pUnknownInner; // Proxy manager
  46. IUnknown* m_pUnknownOuter; // Identity object
  47. };
  48. HRESULT CInsideCOM::Init(IUnknown* pUnknownOuter)
  49. {
  50. // We are aggregated by the identity object (outer)
  51. m_pUnknownOuter = pUnknownOuter;
  52. // And we aggregate the proxy manager (inner)
  53. // For the controlling unknown we simple pass the identity object
  54. // We could also pass _this_, but that would simply delegate IUnknown calls to the outer object
  55. return CoGetStdMarshalEx(pUnknownOuter, SMEXF_HANDLER, &m_pUnknownInner);
  56. }
  57. HRESULT CInsideCOM::QueryInterface_NoAggregation(REFIID riid, void** ppv)
  58. {
  59. if(riid == IID_IUnknown)
  60. *ppv = (INoAggregationUnknown*)this;
  61. else if(riid == IID_ISum)
  62. *ppv = (ISum*)this;
  63. // IMarshal is provided by the proxy manager (inner)
  64. else if(riid == IID_IMarshal)
  65. return m_pUnknownInner->QueryInterface(riid, ppv);
  66. else 
  67. {
  68. *ppv = NULL;
  69. return E_NOINTERFACE;
  70. }
  71. ((IUnknown*)(*ppv))->AddRef();
  72. return S_OK;
  73. }
  74. ULONG CInsideCOM::AddRef_NoAggregation()
  75. {
  76. return ++m_cRef;
  77. }
  78. ULONG CInsideCOM::Release_NoAggregation()
  79. {
  80. if(--m_cRef != 0)
  81. return m_cRef;
  82. delete this;
  83. return 0;
  84. }
  85. // These set of IUnknown calls delegate to the identity object
  86. ULONG CInsideCOM::AddRef()
  87. {
  88. return m_pUnknownOuter->AddRef();
  89. }
  90. ULONG CInsideCOM::Release()
  91. {
  92. return m_pUnknownOuter->Release();
  93. }
  94. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  95. {
  96. return m_pUnknownOuter->QueryInterface(riid, ppv);
  97. }
  98. HRESULT CInsideCOM::Sum(int x, int y, int* retval)
  99. {
  100. HRESULT hr;
  101. if(x > 50 || y > 50)
  102. {
  103. ISum* pSum = 0;
  104. hr = m_pUnknownInner->QueryInterface(IID_ISum, (void**)&pSum);
  105. if(FAILED(hr))
  106. cout << "QueryInterface failed" << endl;
  107. hr = pSum->Sum(x, y, retval);
  108. pSum->Release();
  109. return hr;
  110. }
  111. *retval = x + y;
  112. cout << "Handler: CInsideCOM::Sum() " << x << " + " << y << " = " << *retval << endl;
  113. return S_OK;
  114. }
  115. class CFactory : public IClassFactory
  116. {
  117. public:
  118. // IUnknown
  119. ULONG __stdcall AddRef();
  120. ULONG __stdcall Release();
  121. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  122. // IClassFactory
  123. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv);
  124. HRESULT __stdcall LockServer(BOOL bLock);
  125. CFactory() : m_cRef(1) { };
  126. ~CFactory() { };
  127. private:
  128. long m_cRef;
  129. };
  130. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
  131. {
  132. HRESULT hr;
  133. if(pUnknownOuter != NULL && riid != IID_IUnknown)
  134. return CLASS_E_NOAGGREGATION;
  135. CInsideCOM *pInsideCOM = new CInsideCOM;
  136. cout << "Handler: CFactory::CreateInstance() " << pInsideCOM << endl;
  137. if(pInsideCOM == NULL)
  138. return E_OUTOFMEMORY;
  139. hr = pInsideCOM->Init(pUnknownOuter);
  140. if(FAILED(hr))
  141. cout << "CoGetStdMarshalEx failed" << endl;
  142. hr = pInsideCOM->QueryInterface_NoAggregation(riid, ppv);
  143. pInsideCOM->Release_NoAggregation();
  144. return hr;
  145. }
  146. HRESULT CFactory::LockServer(BOOL bLock)
  147. {
  148. if(bLock)
  149. g_cServerLocks++;
  150. else
  151. g_cServerLocks--;
  152. return S_OK;
  153. }
  154. ULONG CFactory::AddRef()
  155. {
  156. return ++m_cRef;
  157. }
  158. ULONG CFactory::Release()
  159. {
  160. if(--m_cRef != 0)
  161. return m_cRef;
  162. delete this;
  163. return 0;
  164. }
  165. HRESULT CFactory::QueryInterface(REFIID riid, void** ppv)
  166. {
  167.   if(riid == IID_IUnknown || riid == IID_IClassFactory)
  168. *ppv = (IClassFactory*)this;
  169. else 
  170. {
  171. *ppv = NULL;
  172. return E_NOINTERFACE;
  173. }
  174. AddRef();
  175. return S_OK;
  176. }
  177. HRESULT __stdcall DllCanUnloadNow()
  178. {
  179. cout << "Handler: DllCanUnloadNow() " << (g_cServerLocks == 0 && g_cComponents == 0 ? "Yes" : "No") << endl;
  180. if(g_cServerLocks == 0 && g_cComponents == 0)
  181. return S_OK;
  182. else
  183. return S_FALSE;
  184. }
  185. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
  186. {
  187. HRESULT hr;
  188. if(clsid != CLSID_InsideCOMHandler)
  189. return CLASS_E_CLASSNOTAVAILABLE;
  190. CFactory* pFactory = new CFactory;
  191. if(pFactory == NULL)
  192. return E_OUTOFMEMORY;
  193. hr = pFactory->QueryInterface(riid, ppv);
  194. pFactory->Release();
  195. return hr;
  196. }
  197. HRESULT __stdcall DllRegisterServer()
  198. {
  199. char DllPath[MAX_PATH];
  200. GetModuleFileName(g_hInstance, DllPath, sizeof(DllPath));
  201. return RegisterServerEx(g_regData, DllPath);
  202. }
  203. HRESULT __stdcall DllUnregisterServer()
  204. {
  205. return UnregisterServerEx(g_regData);
  206. }
  207. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void* pv)
  208. {
  209. g_hInstance = hInstance;
  210. return TRUE;
  211. }