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

Windows编程

开发平台:

Visual C++

  1. // standard.cpp
  2. #define _WIN32_DCOM
  3. #include <iostream.h>
  4. #include "Componentcomponent.h"
  5. #include "registry.h"
  6. const REG_DATA g_regData[] = {
  7.     { "CLSID\{10000006-0000-0000-0000-000000000001}", 0, "PSSum" },
  8. { "CLSID\{10000006-0000-0000-0000-000000000001}\InprocServer32", 0, (const char*)-1 }, 
  9. { "CLSID\{10000006-0000-0000-0000-000000000001}\InprocServer32", "ThreadingModel", "Both" }, 
  10. { "Interface\{10000001-0000-0000-0000-000000000001}", 0, "ISum" }, 
  11. { "Interface\{10000001-0000-0000-0000-000000000001}\ProxyStubClsid32", 0, "{10000006-0000-0000-0000-000000000001}" }, 
  12. { "Interface\{10000001-0000-0000-0000-000000000001}\NumMethods", 0, "4" }, 
  13. { 0, 0, 0 }
  14. };
  15. const CLSID CLSID_InsideDCOMStdProxy = {0x10000006,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}};
  16. long g_cObjects = 0;
  17. HINSTANCE g_hInstance;
  18. class CRpcStubBuffer : public IRpcStubBuffer
  19. {
  20. public:
  21. // IUnknown
  22. ULONG __stdcall AddRef();
  23. ULONG __stdcall Release();
  24. HRESULT __stdcall QueryInterface(REFIID iid, void **ppv);
  25. // IRpcStubBuffer
  26. HRESULT __stdcall Connect(IUnknown* pUnknown);
  27. HRESULT __stdcall Invoke(RPCOLEMESSAGE* pMessage, IRpcChannelBuffer* pRpcChannel);
  28. IRpcStubBuffer* __stdcall IsIIDSupported(REFIID riid);
  29. ULONG __stdcall CountRefs();
  30. HRESULT __stdcall DebugServerQueryInterface(void**);
  31. void __stdcall DebugServerRelease(void*);
  32. void __stdcall Disconnect();
  33. CRpcStubBuffer(REFIID riid);
  34. ~CRpcStubBuffer() { g_cObjects--; }
  35. private:
  36. long m_cRef;
  37. long m_cConnection;
  38. ISum* m_pObj;
  39. IID m_iid;
  40. };
  41. CRpcStubBuffer::CRpcStubBuffer(REFIID riid) : m_cRef(0), m_cConnection(0)
  42. {
  43. g_cObjects++;
  44. m_iid = riid;
  45. }
  46. HRESULT CRpcStubBuffer::QueryInterface(REFIID riid, void** ppv)
  47. {
  48. if(riid == IID_IUnknown || riid == IID_IRpcStubBuffer)
  49. {
  50. cout << "Stub: IRpcStubBuffer::QueryInterface() for IRpcStubBuffer" << endl;
  51. *ppv = (IRpcStubBuffer*)this;
  52. }
  53. else
  54. {
  55. *ppv = NULL;
  56. return E_NOINTERFACE;
  57. }
  58. AddRef();
  59. return S_OK;
  60. }
  61. ULONG CRpcStubBuffer::AddRef()
  62. {
  63. return ++m_cRef;
  64. }
  65. ULONG CRpcStubBuffer::Release()
  66. {
  67. if(--m_cRef != 0)
  68. return m_cRef;
  69. delete this;
  70. return 0;
  71. }
  72. HRESULT CRpcStubBuffer::Connect(IUnknown* pUnknown)
  73. {
  74. cout << "Stub: IRpcStubBuffer::Connect " << pUnknown << endl;
  75. m_cConnection++;
  76. return pUnknown->QueryInterface(m_iid, (void**)&m_pObj);
  77. }
  78. HRESULT CRpcStubBuffer::Invoke(RPCOLEMESSAGE* pMessage, IRpcChannelBuffer* pRpcChannel)
  79. {
  80. cout << "Stub: IRpcStubBuffer::Invoke cbBuffer = " << pMessage->cbBuffer << endl;
  81. switch(pMessage->iMethod) // What method of ISum is the proxy calling?
  82. {
  83. case 3: // The proxy is calling ISum::Sum
  84. int result;
  85. m_pObj->Sum(((int*)pMessage->Buffer)[0], ((int*)pMessage->Buffer)[1], &result);
  86. pMessage->cbBuffer = sizeof(int);
  87. pRpcChannel->GetBuffer(pMessage, m_iid);
  88. ((int*)pMessage->Buffer)[0] = result;
  89. return NOERROR;
  90. // case other methods here...
  91. }
  92. return E_UNEXPECTED;
  93. }
  94. IRpcStubBuffer* CRpcStubBuffer::IsIIDSupported(REFIID riid)
  95. {
  96. if(riid == m_iid)
  97. return (IRpcStubBuffer*)true;
  98. return (IRpcStubBuffer*)false;
  99. }
  100. ULONG CRpcStubBuffer::CountRefs()
  101. {
  102. return m_cConnection;
  103. }
  104. HRESULT CRpcStubBuffer::DebugServerQueryInterface(void**)
  105. {
  106. return E_NOTIMPL;
  107. }
  108. void CRpcStubBuffer::DebugServerRelease(void*)
  109. {
  110. }
  111. void CRpcStubBuffer::Disconnect()
  112. {
  113. cout << "Stub: IRpcStubBuffer::Disconnect" << endl;
  114. m_pObj->Release();
  115. m_cConnection--;
  116. }
  117. interface INoAggregationRpcProxyBuffer
  118. {
  119. virtual HRESULT __stdcall QueryInterface_NoAggregation(REFIID riid, void** ppv)=0;
  120. virtual ULONG __stdcall AddRef_NoAggregation()=0;
  121. virtual ULONG __stdcall Release_NoAggregation()=0;
  122. virtual HRESULT __stdcall Connect(IRpcChannelBuffer* pRpcChannel)=0;
  123. virtual void __stdcall Disconnect(void)=0;
  124. };
  125. class CRpcProxyBuffer : public IRpcProxyBuffer, public ISum, public INoAggregationRpcProxyBuffer
  126. {
  127. public:
  128. // IUnknown
  129. ULONG __stdcall AddRef();
  130. ULONG __stdcall Release();
  131. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  132. // INoAggregationRpcProxyBuffer
  133. ULONG __stdcall AddRef_NoAggregation();
  134. ULONG __stdcall Release_NoAggregation();
  135. HRESULT __stdcall QueryInterface_NoAggregation(REFIID riid, void** ppv);
  136. // IRpcProxyBuffer
  137. HRESULT __stdcall Connect(IRpcChannelBuffer* pRpcChannel);
  138. void __stdcall Disconnect(void);
  139. // ISum
  140. HRESULT __stdcall Sum(int x, int y, int* retval);
  141. CRpcProxyBuffer(IUnknown* pUnknownOuter);
  142. ~CRpcProxyBuffer();
  143. private:
  144. long m_cRef;
  145. IRpcChannelBuffer* m_pRpcChannel;
  146. IUnknown* m_pUnknownOuter;
  147. };
  148. CRpcProxyBuffer::CRpcProxyBuffer(IUnknown* pUnknownOuter) : m_cRef(0)
  149. {
  150. g_cObjects++;
  151. m_pUnknownOuter = pUnknownOuter;
  152. }
  153. CRpcProxyBuffer::~CRpcProxyBuffer()
  154. {
  155. g_cObjects--;
  156. }
  157. HRESULT CRpcProxyBuffer::QueryInterface(REFIID riid, void** ppv)
  158. {
  159. return m_pUnknownOuter->QueryInterface(riid, ppv);
  160. }
  161. ULONG CRpcProxyBuffer::AddRef()
  162. {
  163. return m_pUnknownOuter->AddRef();
  164. }
  165. ULONG CRpcProxyBuffer::Release()
  166. {
  167. return m_pUnknownOuter->Release();
  168. }
  169. HRESULT CRpcProxyBuffer::QueryInterface_NoAggregation(REFIID riid, void** ppv)
  170. {
  171. if(riid == IID_IUnknown || riid == IID_IRpcProxyBuffer)
  172. {
  173. cout << "Proxy: IRpcProxyBuffer::QueryInterface() for IRpcProxyBuffer" << endl;
  174. *ppv = (INoAggregationRpcProxyBuffer*)this;
  175. }
  176. else if(riid == IID_ISum)
  177. {
  178. cout << "Proxy: IRpcProxyBuffer::QueryInterface() for ISum" << endl;
  179. *ppv = (ISum*)this;
  180. }
  181. else
  182. {
  183. *ppv = NULL;
  184. return E_NOINTERFACE;
  185. }
  186. ((IUnknown*)(*ppv))->AddRef();
  187. return S_OK;
  188. }
  189. ULONG CRpcProxyBuffer::AddRef_NoAggregation()
  190. {
  191. return ++m_cRef;
  192. }
  193. ULONG CRpcProxyBuffer::Release_NoAggregation()
  194. {
  195. if(--m_cRef != 0)
  196. return m_cRef;
  197. delete this;
  198. return 0;
  199. }
  200. HRESULT CRpcProxyBuffer::Connect(IRpcChannelBuffer* pRpcChannel)
  201. {
  202. cout << "Proxy: IRpcProxyBuffer::Connect " << pRpcChannel << endl;
  203. m_pRpcChannel = pRpcChannel;
  204. m_pRpcChannel->AddRef();
  205. return S_OK;
  206. }
  207. void CRpcProxyBuffer::Disconnect()
  208. {
  209. m_pRpcChannel->Release();
  210. m_pRpcChannel = NULL;
  211. cout << "Proxy: IRpcProxyBuffer::Disconnect" << endl;
  212. }
  213. HRESULT CRpcProxyBuffer::Sum(int x, int y, int* retval)
  214. {
  215. cout << "IRpcProxyBuffer::Sum" << endl;
  216. RPCOLEMESSAGE Message = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  217. ULONG status;
  218. Message.cbBuffer = sizeof(int)*2;
  219. Message.iMethod = 3; // VTBL entry for ISum::Sum
  220. m_pRpcChannel->GetBuffer(&Message, IID_ISum);
  221. ((int*)Message.Buffer)[0] = x;
  222. ((int*)Message.Buffer)[1] = y;
  223. m_pRpcChannel->SendReceive(&Message, &status);
  224. cout << "Proxy: IRpcProxyBuffer::Sum Message = " << ((int*)Message.Buffer)[0] << " status = " << status << endl;
  225. *retval = ((int*)Message.Buffer)[0];
  226. m_pRpcChannel->FreeBuffer(&Message);
  227. return S_OK;
  228. }
  229. class CPSFactoryBuffer : public IPSFactoryBuffer
  230. {
  231. public:
  232. // IUnknown
  233. ULONG __stdcall AddRef();
  234. ULONG __stdcall Release();
  235. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  236. // IPSFactoryBuffer
  237.     HRESULT __stdcall CreateProxy(IUnknown* pUnknownOuter, REFIID riid, IRpcProxyBuffer** ppProxy, void** ppv);
  238. HRESULT __stdcall CreateStub(REFIID riid, IUnknown* pUnkServer, IRpcStubBuffer** ppStub);
  239. CPSFactoryBuffer() : m_cRef(0) { };
  240. ~CPSFactoryBuffer() { };
  241. private:
  242. long m_cRef;
  243. };
  244. HRESULT CPSFactoryBuffer::CreateProxy(IUnknown* pUnknownOuter, REFIID riid, IRpcProxyBuffer** ppProxy, void** ppv)
  245. {
  246. CRpcProxyBuffer* pRpcProxyBuffer = new CRpcProxyBuffer(pUnknownOuter);
  247. cout << "Proxy: CFactory::CreateProxy() " << pRpcProxyBuffer << endl;
  248. HRESULT hr = pRpcProxyBuffer->QueryInterface_NoAggregation(riid, ppv); // For IID_ISum
  249. return pRpcProxyBuffer->QueryInterface_NoAggregation(IID_IRpcProxyBuffer, (void**)ppProxy);
  250. }
  251. HRESULT CPSFactoryBuffer::CreateStub(REFIID riid, IUnknown* pUnkServer, IRpcStubBuffer** ppStub)
  252. {
  253. cout << "Stub: CFactory::CreateStub() " << pUnkServer << endl;
  254. CRpcStubBuffer *pRpcStubBuffer = new CRpcStubBuffer(riid);
  255. pRpcStubBuffer->Connect(pUnkServer);
  256. return pRpcStubBuffer->QueryInterface(IID_IRpcStubBuffer, (void**)ppStub);
  257. }
  258. ULONG CPSFactoryBuffer::AddRef()
  259. {
  260. return ++m_cRef;
  261. }
  262. ULONG CPSFactoryBuffer::Release()
  263. {
  264. if(--m_cRef != 0)
  265. return m_cRef;
  266. delete this;
  267. return 0;
  268. }
  269. HRESULT CPSFactoryBuffer::QueryInterface(REFIID riid, void** ppv)
  270. {
  271. if(riid == IID_IUnknown || riid == IID_IPSFactoryBuffer)
  272. {
  273. cout << "Proxy/Stub: CFactory::QueryInteface() for IPSFactoryBuffer" << endl;
  274. *ppv = (IPSFactoryBuffer*)this;
  275. }
  276. else 
  277. {
  278. *ppv = NULL;
  279. return E_NOINTERFACE;
  280. }
  281. AddRef();
  282. return S_OK;
  283. }
  284. HRESULT __stdcall DllCanUnloadNow()
  285. {
  286. cout << "Proxy/Stub: DllCanUnloadNow() " << (g_cObjects == 0 ? "Yes" : "No") << endl;
  287. if(g_cObjects == 0)
  288. return S_OK;
  289. else
  290. return S_FALSE;
  291. }
  292. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
  293. {
  294. cout << "Proxy/Stub: DllGetClassObject" << endl;
  295. if(clsid != CLSID_InsideDCOMStdProxy)
  296. return CLASS_E_CLASSNOTAVAILABLE;
  297. CPSFactoryBuffer* pPSFactoryBuffer = new CPSFactoryBuffer;
  298. if(pPSFactoryBuffer == NULL)
  299. return E_OUTOFMEMORY;
  300. // QueryInterface for IPSFactoryBuffer
  301. return pPSFactoryBuffer->QueryInterface(riid, ppv);
  302. }
  303. HRESULT __stdcall DllRegisterServer()
  304. {
  305. char DllPath[MAX_PATH];
  306. GetModuleFileName(g_hInstance, DllPath, sizeof(DllPath));
  307. return RegisterServerEx(g_regData, DllPath);
  308. }
  309. HRESULT __stdcall DllUnregisterServer()
  310. {
  311. return UnregisterServerEx(g_regData);
  312. }
  313. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void* pv)
  314. {
  315. cout << "Proxy/Stub: DllMain() Reason is " << dwReason << endl;
  316. g_hInstance = hInstance;
  317. return TRUE;
  318. }