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

Windows编程

开发平台:

Visual C++

  1. // proxy.cpp
  2. #define _WIN32_DCOM
  3. #include <iostream.h>
  4. #include "Componentcomponent.h"
  5. #include "registry.h"
  6. CLSID CLSID_InsideCOMProxy = {0x10000004,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}};
  7. long g_cComponents = 0;
  8. long g_cServerLocks = 0;
  9. class CInsideCOM : public ISum, public IMarshal
  10. {
  11. public:
  12. // IUnknown
  13. ULONG __stdcall AddRef();
  14. ULONG __stdcall Release();
  15. HRESULT __stdcall QueryInterface(REFIID riid, void **ppv);
  16. // IMarshal
  17. HRESULT __stdcall GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags, CLSID* pClsid);
  18. HRESULT __stdcall GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags, DWORD* pSize);
  19. HRESULT __stdcall MarshalInterface(IStream* pStream, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags);
  20. HRESULT __stdcall DisconnectObject(DWORD dwReserved);
  21. HRESULT __stdcall UnmarshalInterface(IStream* pStream, REFIID riid, void** ppv);
  22. HRESULT __stdcall ReleaseMarshalData(IStream* pStream);
  23. // ISum
  24. HRESULT __stdcall Sum(int x, int y, int *sum);
  25. CInsideCOM() : m_cRef(1) { g_cComponents++; }
  26. ~CInsideCOM() { cout << "Proxy: CInsideCOM::~CInsideCOM()" << endl, g_cComponents--; }
  27. private:
  28. ULONG m_cRef;
  29. HANDLE hFileMap;
  30. void* pMem;
  31. HANDLE hStubEvent;
  32. HANDLE hProxyEvent;
  33. };
  34. HRESULT CInsideCOM::GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags, CLSID* pClsid)
  35. {
  36. cout << "GetUnmarshalClass" << endl;
  37.     return E_NOTIMPL;
  38. }
  39. HRESULT CInsideCOM::GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags, DWORD* pSize)
  40.     {
  41. cout << "GetMarshalSize" << endl;
  42.     return E_NOTIMPL;
  43.     }
  44. HRESULT CInsideCOM::MarshalInterface(IStream* pStream, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD dwFlags)
  45.     {
  46. cout << "MarshalInterface" << endl;
  47.     return E_NOTIMPL;
  48.     }
  49. HRESULT CInsideCOM::DisconnectObject(DWORD dwReserved)
  50.     {
  51. cout << "DisconnectObject" << endl;
  52.     return E_NOTIMPL;
  53.     }
  54. HRESULT CInsideCOM::UnmarshalInterface(IStream* pStream, REFIID riid, void** ppv)
  55.     {
  56. unsigned long num_read;
  57. char buffer_to_read[255];
  58. char* pszFileMapName;
  59. char* pszStubEventName;
  60. char* pszProxyEventName;
  61.     pStream->Read((void *)buffer_to_read, 255, &num_read);
  62. cout << "Proxy: CInsideCOM::UnmarshalInterface() = " << buffer_to_read << endl;
  63. pszFileMapName = strtok(buffer_to_read, ",");
  64. pszStubEventName = strtok(NULL, ",");
  65. pszProxyEventName = strtok(NULL, ",");
  66. hFileMap = OpenFileMapping(FILE_MAP_WRITE, FALSE, pszFileMapName);
  67. pMem = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
  68. hStubEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, pszStubEventName);
  69. hProxyEvent = OpenEvent(EVENT_MODIFY_STATE|SYNCHRONIZE, FALSE, pszProxyEventName);
  70.     //Get the pointer to return to the client
  71.     return QueryInterface(riid, ppv);
  72.     }
  73. HRESULT CInsideCOM::ReleaseMarshalData(IStream* pStream)
  74.     {
  75. cout << "ReleaseMarshalData" << endl;
  76.     return S_OK;
  77.     }
  78. HRESULT CInsideCOM::QueryInterface(REFIID riid, void **ppv)
  79. {
  80. if(riid == IID_IUnknown)
  81. {
  82. cout << "Proxy: CInsideCOM::QueryInterface() for IUnknown" << endl;
  83. *ppv = reinterpret_cast<IUnknown*>(this);
  84. }
  85. else if(riid == IID_IMarshal)
  86. {
  87. cout << "Proxy: CInsideCOM::QueryInterface() for IMarshal" << endl;
  88. *ppv = (IMarshal*)this;
  89. }
  90. else if(riid == IID_ISum)
  91. {
  92. cout << "Proxy: CInsideCOM::QueryInterface() for ISum" << endl;
  93. *ppv = (ISum*)this;
  94. }
  95. else 
  96. {
  97. *ppv = NULL;
  98. return E_NOINTERFACE;
  99. }
  100. AddRef();
  101. return S_OK;
  102. }
  103. ULONG CInsideCOM::AddRef()
  104. {
  105. cout << "Proxy: CInsideCOM::AddRef() m_cRef = " << m_cRef + 1 << endl;
  106. return ++m_cRef;
  107. }
  108. ULONG CInsideCOM::Release()
  109. {
  110. cout << "Proxy: CInsideCOM::Release() m_cRef = " << m_cRef - 1 << endl;
  111. if(--m_cRef != 0)
  112. return m_cRef;
  113. short method_id = 1; // ISum::Release
  114. memcpy(pMem, &method_id, sizeof(short));
  115. cout << "Proxy Setting event to destroy object " << endl;
  116. SetEvent(hStubEvent);
  117. delete this;
  118. return 0;
  119. }
  120. struct SumTransmit
  121. {
  122. int x;
  123. int y;
  124. int sum;
  125. };
  126. HRESULT CInsideCOM::Sum(int x, int y, int *sum)
  127. {
  128. SumTransmit s;
  129. s.x = x;
  130. s.y = y;
  131. short method_id = 2; // ISum::Sum
  132. memcpy(pMem, &method_id, sizeof(short));
  133. memcpy((short*)pMem+1, &s, sizeof(SumTransmit));
  134. cout << "Proxy: Going to call component CInsideCOM::Sum() " << x << " + " << y << endl;
  135. SetEvent(hStubEvent);
  136. WaitForSingleObject(hProxyEvent, INFINITE);
  137. memcpy(&s, pMem, sizeof(s));
  138. *sum = s.sum;
  139. return S_OK;
  140. }
  141. class CFactory : public IClassFactory
  142. {
  143. public:
  144. // IUnknown
  145. ULONG __stdcall AddRef();
  146. ULONG __stdcall Release();
  147. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  148. // IClassFactory
  149. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv);
  150. HRESULT __stdcall LockServer(BOOL bLock);
  151. CFactory() : m_cRef(1) { };
  152. ~CFactory() { };
  153. private:
  154. ULONG m_cRef;
  155. };
  156. ULONG CFactory::AddRef()
  157. {
  158. cout << "Proxy: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  159. return ++m_cRef;
  160. }
  161. ULONG CFactory::Release()
  162. {
  163. cout << "Proxy: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  164. if(--m_cRef != 0)
  165. return m_cRef;
  166. delete this;
  167. return 0;
  168. }
  169. HRESULT CFactory::QueryInterface(REFIID riid, void **ppv)
  170. {
  171. if((riid == IID_IUnknown) || (riid == IID_IClassFactory))
  172. {
  173. cout << "Proxy: CFactory::QueryInteface() for IUnknown or IClassFactory " << this << endl;
  174. *ppv = (IClassFactory *)this;
  175. }
  176. else 
  177. {
  178. *ppv = NULL;
  179. return E_NOINTERFACE;
  180. }
  181. AddRef();
  182. return S_OK;
  183. }
  184. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void **ppv)
  185. {
  186. if(pUnknownOuter != NULL)
  187. return CLASS_E_NOAGGREGATION;
  188. CInsideCOM *pInsideCOM = new CInsideCOM;
  189. cout << "Proxy: CFactory::CreateInstance() " << pInsideCOM << endl;
  190. if(pInsideCOM == NULL)
  191. return E_OUTOFMEMORY;
  192. HRESULT hr = pInsideCOM->QueryInterface(riid, ppv);
  193. pInsideCOM->Release();
  194. return hr;
  195. }
  196. HRESULT CFactory::LockServer(BOOL bLock)
  197. {
  198. if(bLock)
  199. g_cServerLocks++;
  200. else
  201. g_cServerLocks--;
  202. return S_OK;
  203. }
  204. HRESULT __stdcall DllCanUnloadNow()
  205. {
  206. cout << "Proxy: DllCanUnloadNow() " << (g_cServerLocks == 0 && g_cComponents == 0 ? "Yes" : "No") << endl;
  207. if(g_cServerLocks == 0 && g_cComponents == 0)
  208. return S_OK;
  209. else
  210. return S_FALSE;
  211. }
  212. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
  213. {
  214. cout << "Proxy: DllGetClassObject" << endl;
  215. if(clsid != CLSID_InsideCOMProxy)
  216. return CLASS_E_CLASSNOTAVAILABLE;
  217. CFactory* pFactory = new CFactory;
  218. if(pFactory == NULL)
  219. return E_OUTOFMEMORY;
  220. // QueryInterface for IClassFactory
  221. HRESULT hr = pFactory->QueryInterface(riid, ppv);
  222. pFactory->Release();
  223. return hr;
  224. }
  225. HRESULT __stdcall DllRegisterServer()
  226. {
  227. return RegisterServer("proxy.dll", CLSID_InsideCOMProxy, "Inside COM Sample #1", "Component.InsideCOM", "Component.InsideCOM.1", NULL);
  228. }
  229. HRESULT __stdcall DllUnregisterServer()
  230. {
  231. return UnregisterServer(CLSID_InsideCOMProxy, "Component.InsideCOM", "Component.InsideCOM.1");
  232. }
  233. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  234. {
  235. // cout << "Proxy: DllMain()" << endl;
  236. return TRUE;
  237. }