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

Windows编程

开发平台:

Visual C++

  1. // mbv.cpp
  2. #include <windows.h>
  3. #include <iostream.h>
  4. #include "registry.h"
  5. const REG_DATA g_regData[] = {
  6.     { "CLSID\{10000001-1111-0000-0000-000000000001}", 0, "Marshal By Value" },
  7. { "CLSID\{10000001-1111-0000-0000-000000000001}\InprocServer32", 0, (const char*)-1 }, 
  8. { "CLSID\{10000001-1111-0000-0000-000000000001}\InprocServer32", "ThreadingModel", "Both" }, 
  9. { "CLSID\{10000001-1111-0000-0000-000000000001}\ProgID", 0, "Component.MarshalByValue.1" },
  10. { "CLSID\{10000001-1111-0000-0000-000000000001}\VersionIndependentProgID", 0, "Component.MarshalByValue" },
  11. { "Component.MarshalByValue", 0, "Marshal By Value" },
  12. { "Component.MarshalByValue\CLSID", 0, "{10000001-1111-0000-0000-000000000001}" },
  13. { "Component.MarshalByValue\CurVer", 0, "Component.MarshalByValue.1" },
  14. { "Component.MarshalByValue.1", 0, "Marshal By Value" },
  15. { "Component.MarshalByValue.1\CLSID", 0, "{10000001-1111-0000-0000-000000000001}" },
  16. { 0, 0, 0 }
  17. };
  18. // {10000001-1111-0000-0000-000000000001}
  19. const CLSID CLSID_MarshalByValue = {0x10000001,0x1111,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
  20. HINSTANCE g_hInstance = 0;
  21. long g_cLocks = 0;
  22. interface INoAggregationUnknown
  23. {
  24. virtual HRESULT __stdcall QueryInterface_NoAggregation(REFIID riid, void** ppv)=0;
  25. virtual ULONG __stdcall AddRef_NoAggregation()=0;
  26. virtual ULONG __stdcall Release_NoAggregation()=0;
  27. };
  28. class CMarshalByValue : public IMarshal, public INoAggregationUnknown
  29. {
  30. public:
  31. // IUnknown
  32. ULONG __stdcall AddRef();
  33. ULONG __stdcall Release();
  34. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  35. // INoAggregationUnknown
  36. ULONG __stdcall AddRef_NoAggregation();
  37. ULONG __stdcall Release_NoAggregation();
  38. HRESULT __stdcall QueryInterface_NoAggregation(REFIID riid, void** ppv);
  39. // IMarshal
  40. HRESULT __stdcall GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags, CLSID* pClsid);
  41. HRESULT __stdcall GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags, DWORD* pSize);
  42. HRESULT __stdcall MarshalInterface(IStream* pStream, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags);
  43. HRESULT __stdcall DisconnectObject(DWORD dwReserved);
  44. HRESULT __stdcall UnmarshalInterface(IStream* pStream, REFIID riid, void** ppv);
  45. HRESULT __stdcall ReleaseMarshalData(IStream* pStream);
  46. CMarshalByValue(IUnknown* pUnknownOuter);
  47. ~CMarshalByValue();
  48. private:
  49. ULONG m_cRef;
  50. IUnknown* m_pUnknownOuter;
  51. };
  52. CMarshalByValue::CMarshalByValue(IUnknown* pUnknownOuter) : m_cRef(1)
  53. {
  54. InterlockedIncrement(&g_cLocks);
  55. if(pUnknownOuter != NULL)
  56. m_pUnknownOuter = pUnknownOuter;
  57. else
  58. m_pUnknownOuter = (IUnknown*)(INoAggregationUnknown*)this;
  59. }
  60. CMarshalByValue::~CMarshalByValue()
  61. {
  62. cout << "CMarshalByValue::~CMarshalByValue()" << endl;
  63. InterlockedDecrement(&g_cLocks);
  64. }
  65. HRESULT CMarshalByValue::GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags, CLSID* pClsid)
  66. {
  67. cout << "GetUnmarshalClass" << endl;
  68. IPersistStream* pPersistStream = 0;
  69. HRESULT hr = m_pUnknownOuter->QueryInterface(IID_IPersistStream, (void**)&pPersistStream);
  70. if(FAILED(hr))
  71. cout << "QI failed for persist" << endl;
  72. pPersistStream->GetClassID(pClsid);
  73. pPersistStream->Release();
  74. return S_OK;
  75. }
  76. HRESULT CMarshalByValue::GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags, DWORD* pSize)
  77. {
  78. cout << "CMarshalByValue::GetMarshalSizeMax()" << endl;
  79. IPersistStream* pPersistStream = 0;
  80. m_pUnknownOuter->QueryInterface(IID_IPersistStream, (void**)&pPersistStream);
  81. ULARGE_INTEGER size;
  82.   pPersistStream->GetSizeMax(&size);
  83. *pSize = size.LowPart;
  84. pPersistStream->Release();
  85. return S_OK;
  86. }
  87. HRESULT CMarshalByValue::MarshalInterface(IStream* pStream, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags)
  88. {
  89. AddRef();
  90. cout << "CMarshalByValue::MarshalInterface()" << endl;
  91. IPersistStream* pPersistStream = 0;
  92. m_pUnknownOuter->QueryInterface(IID_IPersistStream, (void**)&pPersistStream);
  93. HRESULT hr = pPersistStream->Save(pStream, TRUE);
  94. pPersistStream->Release();
  95. return hr;
  96. }
  97. HRESULT CMarshalByValue::DisconnectObject(DWORD dwReserved)
  98.     {
  99. cout << "DisconnectObject" << endl;
  100.     return S_OK;;
  101.     }
  102. HRESULT CMarshalByValue::ReleaseMarshalData(IStream* pStream)
  103.     {
  104. cout << "ReleaseMarshalData" << endl;
  105.     return S_OK;
  106.     }
  107. HRESULT CMarshalByValue::UnmarshalInterface(IStream* pStream, REFIID riid, void** ppv)
  108.     {
  109. cout << "IMarshal::UnmarshalInterface" << endl;
  110. IPersistStream* pPersistStream = 0;
  111. m_pUnknownOuter->QueryInterface(IID_IPersistStream, (void**)&pPersistStream);
  112. pPersistStream->Load(pStream);
  113. pPersistStream->Release();
  114. return m_pUnknownOuter->QueryInterface(riid, ppv);
  115.     }
  116. HRESULT CMarshalByValue::QueryInterface_NoAggregation(REFIID riid, void** ppv)
  117. {
  118. if(riid == IID_IUnknown)
  119. {
  120. cout << "CMarshalByValue::QueryInterface() for IUnknown returning " << this << endl;
  121. *ppv = (INoAggregationUnknown*)this;
  122. }
  123. else if(riid == IID_IMarshal)
  124. {
  125. cout << "CMarshalByValue::QueryInterface() for IMarshal returning " << this << endl;
  126. *ppv = (IMarshal*)this;
  127. }
  128. else 
  129. {
  130. *ppv = NULL;
  131. return E_NOINTERFACE;
  132. }
  133. ((IUnknown*)(*ppv))->AddRef();
  134. return S_OK;
  135. }
  136. ULONG CMarshalByValue::AddRef_NoAggregation()
  137. {
  138. return InterlockedIncrement((long*)&m_cRef);
  139. }
  140. ULONG CMarshalByValue::Release_NoAggregation()
  141. {
  142. ULONG cRef = InterlockedDecrement((long*)&m_cRef);
  143. if(cRef != 0)
  144. return cRef;
  145. delete this;
  146. return 0;
  147. }
  148. ULONG CMarshalByValue::AddRef()
  149. {
  150. return m_pUnknownOuter->AddRef();
  151. }
  152. ULONG CMarshalByValue::Release()
  153. {
  154. return m_pUnknownOuter->Release();
  155. }
  156. HRESULT CMarshalByValue::QueryInterface(REFIID riid, void** ppv)
  157. {
  158. return m_pUnknownOuter->QueryInterface(riid, ppv);
  159. }
  160. class CFactory : public IClassFactory
  161. {
  162. public:
  163. // IUnknown
  164. ULONG __stdcall AddRef();
  165. ULONG __stdcall Release();
  166. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  167. // IClassFactory
  168. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv);
  169. HRESULT __stdcall LockServer(BOOL bLock);
  170. CFactory() : m_cRef(1) { InterlockedIncrement(&g_cLocks); }
  171. ~CFactory() { InterlockedDecrement(&g_cLocks); }
  172. private:
  173. ULONG m_cRef;
  174. };
  175. ULONG CFactory::AddRef()
  176. {
  177. return InterlockedIncrement((long*)&m_cRef);
  178. }
  179. ULONG CFactory::Release()
  180. {
  181. ULONG cRef = InterlockedDecrement((long*)&m_cRef);
  182. if(cRef != 0)
  183. return cRef;
  184. delete this;
  185. return 0;
  186. }
  187. HRESULT CFactory::QueryInterface(REFIID riid, void** ppv)
  188. {
  189. if(riid == IID_IUnknown || riid == IID_IClassFactory)
  190. {
  191. cout << "CFactory::QueryInteface() for IUnknown or IClassFactory " << this << endl;
  192. *ppv = (IClassFactory*)this;
  193. }
  194. else
  195. {
  196. *ppv = NULL;
  197. return E_NOINTERFACE;
  198. }
  199. AddRef();
  200. return S_OK;
  201. }
  202. HRESULT CFactory::CreateInstance(IUnknown* pUnknownOuter, REFIID riid, void** ppv)
  203. {
  204. if(pUnknownOuter != NULL && riid != IID_IUnknown)
  205. return CLASS_E_NOAGGREGATION;
  206. CMarshalByValue *pMarshalByValue = new CMarshalByValue(pUnknownOuter);
  207. if(pMarshalByValue == NULL)
  208. return E_OUTOFMEMORY;
  209. HRESULT hr = pMarshalByValue->QueryInterface_NoAggregation(riid, ppv);
  210. pMarshalByValue->Release_NoAggregation();
  211. return hr;
  212. }
  213. HRESULT CFactory::LockServer(BOOL bLock)
  214. {
  215. if(bLock)
  216. InterlockedIncrement(&g_cLocks);
  217. else
  218. InterlockedDecrement(&g_cLocks);
  219. return S_OK;
  220. }
  221. HRESULT __stdcall DllCanUnloadNow()
  222. {
  223. cout << "MarshalByValue DllCanUnloadNow() " << (g_cLocks == 0 ? "Yes" : "No") << endl;
  224. if(g_cLocks == 0)
  225. return S_OK;
  226. else
  227. return S_FALSE;
  228. }
  229. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID iid, void** ppv)
  230. {
  231. cout << "DllGetClassObject" << endl;
  232. if(clsid != CLSID_MarshalByValue)
  233. return CLASS_E_CLASSNOTAVAILABLE;
  234. CFactory* pFactory = new CFactory;
  235. if(pFactory == NULL)
  236. return E_OUTOFMEMORY;
  237. HRESULT hr = pFactory->QueryInterface(iid, ppv);
  238. pFactory->Release();
  239. return hr;
  240. }
  241. HRESULT __stdcall DllRegisterServer()
  242. {
  243. char DllPath[MAX_PATH];
  244. GetModuleFileName(g_hInstance, DllPath, sizeof(DllPath));
  245. return RegisterServerEx(g_regData, DllPath);
  246. }
  247. HRESULT __stdcall DllUnregisterServer()
  248. {
  249. return UnregisterServerEx(g_regData);
  250. }
  251. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void* pv)
  252. {
  253. g_hInstance = hInstance;
  254. return TRUE;
  255. }