Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1092 lines
24 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // File: myproxy.cxx
  4. //
  5. // Purpose: Sample implementation of wrappers to allow simultaneous
  6. // hand-crafted and MILD-generated stubs.
  7. //
  8. // History: 12-11-95 Rickhi Created
  9. //
  10. //---------------------------------------------------------------------------
  11. #include <ole2.h>
  12. #include <stddef.h> // offsetof
  13. #include <icube.h> // custom interface ICube, IID_ICube
  14. // flag set in rpcFlags field of RPCOLEMESSAGE if the call is from a
  15. // non-NDR client.
  16. #define RPCFLG_NON_NDR 0x80000000UL
  17. DEFINE_OLEGUID(IID_INonNDRStub, 0x0000013DL, 0, 0);
  18. DEFINE_OLEGUID(CLSID_MyProxy, 0x0000013EL, 0, 0);
  19. // IID that the proxy querys the channel for to see if the server
  20. // has an NDR or NON NDR stub.
  21. const GUID IID_INonNDRStub =
  22. {0x0000013d,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  23. // class id of my custom proxy dll
  24. const GUID CLSID_MyProxy =
  25. {0x0000013e,0x0001,0x0008,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  26. // class id of the MIDL generated proxy dll
  27. const GUID CLSID_CubeProxy =
  28. {0x00000138,0x0001,0x0008,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  29. #define GETPPARENT(pmemb, struc, membname) (\
  30. (struc FAR *)(((char FAR *)(pmemb))-offsetof(struc, membname)))
  31. //---------------------------------------------------------------------------
  32. //
  33. // Class: CPSFactory
  34. //
  35. // Purpose: ProxyStub Class Factory
  36. //
  37. // Notes: fill in the CreateProxy and CreateStub methods for
  38. // other custom interfaces supported by this DLL.
  39. //
  40. //---------------------------------------------------------------------------
  41. class CPSFactory : public IPSFactoryBuffer
  42. {
  43. public:
  44. // no ctor or dtor needed. DllGetClassObject returns a static
  45. // instance of this class.
  46. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  47. STDMETHOD_(ULONG, AddRef)(void);
  48. STDMETHOD_(ULONG, Release)(void);
  49. STDMETHOD(CreateProxy)(IUnknown *pUnkOuter, REFIID riid,
  50. IRpcProxyBuffer **ppProxy, void **ppv);
  51. STDMETHOD(CreateStub)(REFIID riid, IUnknown *pUnkObj,
  52. IRpcStubBuffer **ppStub);
  53. };
  54. //---------------------------------------------------------------------------
  55. //
  56. // Class: CStubWrapper
  57. //
  58. // Purpose: Wrapper object for stubs.
  59. //
  60. // Notes: This class can wrap any stub object regardless of
  61. // the interface the stub is for.
  62. //
  63. //---------------------------------------------------------------------------
  64. class CStubWrapper : public IRpcStubBuffer
  65. {
  66. public:
  67. CStubWrapper(IUnknown *pUnkObj, REFIID riid);
  68. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  69. STDMETHOD_(ULONG, AddRef)(void);
  70. STDMETHOD_(ULONG, Release)(void);
  71. STDMETHOD(Connect)(IUnknown *pUnkObj);
  72. STDMETHOD_(void, Disconnect)(void);
  73. STDMETHOD(Invoke)(RPCOLEMESSAGE *pMsg, IRpcChannelBuffer *pChnl);
  74. STDMETHOD_(IRpcStubBuffer *, IsIIDSupported)(REFIID riid);
  75. STDMETHOD_(ULONG, CountRefs)(void);
  76. STDMETHOD(DebugServerQueryInterface)(void **ppv);
  77. STDMETHOD_(void, DebugServerRelease)(void *pv);
  78. private:
  79. ~CStubWrapper(void);
  80. ULONG _cRefs;
  81. IUnknown * _pUnkObj;
  82. IRpcStubBuffer *_pHCStub;
  83. IRpcStubBuffer *_pMIDLStub;
  84. IID _iid;
  85. };
  86. //---------------------------------------------------------------------------
  87. //
  88. // Class: CCubesStub
  89. //
  90. // Purpose: Hand-Crafted stub object for interface ICube.
  91. //
  92. // Notes: Replace this with your exisitng 32bit hand-crafted stubs.
  93. //
  94. //---------------------------------------------------------------------------
  95. class CCubesStub : public IRpcStubBuffer
  96. {
  97. public:
  98. CCubesStub(IUnknown *pUnkObj);
  99. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  100. STDMETHOD_(ULONG, AddRef)(void);
  101. STDMETHOD_(ULONG, Release)(void);
  102. STDMETHOD(Connect)(IUnknown *pUnkObj);
  103. STDMETHOD_(void, Disconnect)(void);
  104. STDMETHOD(Invoke)(RPCOLEMESSAGE *pMsg, IRpcChannelBuffer *pChnl);
  105. STDMETHOD_(IRpcStubBuffer *, IsIIDSupported)(REFIID riid);
  106. STDMETHOD_(ULONG, CountRefs)(void);
  107. STDMETHOD(DebugServerQueryInterface)(void **ppv);
  108. STDMETHOD_(void, DebugServerRelease)(void *pv);
  109. private:
  110. ~CCubesStub(void);
  111. ULONG _cRefs;
  112. IUnknown * _pUnkObj;
  113. };
  114. //---------------------------------------------------------------------------
  115. //
  116. // Class: CInternalUnk
  117. //
  118. // Purpose: Internal proxy class that implements IRpcProxyBuffer
  119. //
  120. // Notes: This could use some work. Perhaps dont make it an internal
  121. // class, but derive the other proxy classes from it, allowing
  122. // common code.
  123. //
  124. //---------------------------------------------------------------------------
  125. #define DECLARE_INTERNAL_PROXY() \
  126. class CInternalUnk : public IRpcProxyBuffer \
  127. { \
  128. public: \
  129. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj); \
  130. STDMETHOD_(ULONG,AddRef)(void) ; \
  131. STDMETHOD_(ULONG,Release)(void); \
  132. STDMETHOD(Connect)(IRpcChannelBuffer *pChnl); \
  133. STDMETHOD_(void, Disconnect)(void); \
  134. }; \
  135. friend CInternalUnk; \
  136. CInternalUnk _InternalUnk;
  137. //---------------------------------------------------------------------------
  138. //
  139. // Class: CProxyWrapper
  140. //
  141. // Purpose: Wrapper object for itnerface proxies.
  142. //
  143. // Notes: the routines in this class simply delegate to the
  144. // real proxy or the internal proxy unknown, or to the
  145. // controlling unknown.
  146. //
  147. //---------------------------------------------------------------------------
  148. class CProxyWrapper : public ICube
  149. {
  150. public:
  151. CProxyWrapper(IUnknown *pUnkOuter, IRpcProxyBuffer **ppProxy);
  152. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  153. STDMETHOD_(ULONG, AddRef)(void);
  154. STDMETHOD_(ULONG, Release)(void);
  155. // interface specific routines below here
  156. STDMETHOD(MoveCube)(ULONG xPos, ULONG yPos);
  157. STDMETHOD(GetCubePos)(ULONG *pxPos, ULONG *pyPos);
  158. STDMETHOD(Contains)(IBalls *pIFDb);
  159. STDMETHOD(SimpleCall)(DWORD pidCaller,
  160. DWORD tidCaller,
  161. GUID lidCaller);
  162. DECLARE_INTERNAL_PROXY()
  163. private:
  164. ~CProxyWrapper(void);
  165. ULONG _cRefs;
  166. IUnknown *_pUnkOuter;
  167. IRpcProxyBuffer *_pRealProxy;
  168. ICube *_pRealIf;
  169. };
  170. //---------------------------------------------------------------------------
  171. //
  172. // Class: CCubesProxy
  173. //
  174. // Purpose: Hand-Crafted proxy object for ICube interface.
  175. //
  176. //---------------------------------------------------------------------------
  177. class CCubesProxy : public ICube
  178. {
  179. public:
  180. CCubesProxy(IUnknown *pUnkOuter, IRpcProxyBuffer **ppProxy);
  181. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  182. STDMETHOD_(ULONG, AddRef)(void);
  183. STDMETHOD_(ULONG, Release)(void);
  184. // interface specific routines below here
  185. STDMETHOD(MoveCube)(ULONG xPos, ULONG yPos);
  186. STDMETHOD(GetCubePos)(ULONG *pxPos, ULONG *pyPos);
  187. STDMETHOD(Contains)(IBalls *pIFDb);
  188. STDMETHOD(SimpleCall)(DWORD pidCaller,
  189. DWORD tidCaller,
  190. GUID lidCaller);
  191. DECLARE_INTERNAL_PROXY()
  192. private:
  193. ~CCubesProxy(void);
  194. ULONG _cRefs;
  195. IUnknown *_pUnkOuter;
  196. IRpcChannelBuffer *_pChnl;
  197. };
  198. //---------------------------------------------------------------------------
  199. //
  200. // Function: DllMain
  201. //
  202. // Purpose: Entry point for the Proxy/Stub Dll
  203. //
  204. //---------------------------------------------------------------------------
  205. extern "C" BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, void *pvReserved)
  206. {
  207. return TRUE;
  208. }
  209. //---------------------------------------------------------------------------
  210. //
  211. // Function: DllGetClassObject
  212. //
  213. // Purpose: Entry point to return proxy/stub class factory
  214. //
  215. //---------------------------------------------------------------------------
  216. // static instance of the class factory
  217. CPSFactory gPSFactory;
  218. STDAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **ppv)
  219. {
  220. if (IsEqualCLSID(clsid, CLSID_MyProxy))
  221. {
  222. *ppv = (void *)(IClassFactory *)&gPSFactory;
  223. return S_OK;
  224. }
  225. return E_UNEXPECTED;
  226. }
  227. //---------------------------------------------------------------------------
  228. //
  229. // Function: DllCanUnloadNow
  230. //
  231. // Purpose: Entry point to determine if DLL is unloadable.
  232. //
  233. //---------------------------------------------------------------------------
  234. STDAPI DllCanUnloadNow(void)
  235. {
  236. return FALSE;
  237. }
  238. //---------------------------------------------------------------------------
  239. //
  240. // Function: GetMIDLPSFactory
  241. //
  242. // Purpose: Function for getting the MIDL generated PSFactoryBuffer
  243. // for the test interface.
  244. //
  245. //---------------------------------------------------------------------------
  246. HRESULT GetMIDLPSFactory(REFIID riid, IPSFactoryBuffer **ppIPSF)
  247. {
  248. *ppIPSF = NULL;
  249. // load the dll and get the PS class object
  250. return CoGetClassObject(CLSID_CubeProxy,
  251. CLSCTX_INPROC_SERVER, // | CLSCTX_PS_DLL,
  252. NULL,
  253. IID_IPSFactoryBuffer,
  254. (void **)ppIPSF);
  255. }
  256. //---------------------------------------------------------------------------
  257. //
  258. // Function: CreateMIDLProxy
  259. //
  260. // Purpose: Function for creating the MIDL generated proxy
  261. // for the test interface.
  262. //
  263. //---------------------------------------------------------------------------
  264. IUnknown *CreateMIDLProxy(REFIID riid,
  265. IUnknown *pUnkOuter,
  266. IRpcProxyBuffer **ppProxy)
  267. {
  268. IUnknown *pRealIf = NULL;
  269. IPSFactoryBuffer *pPSFactory = NULL;
  270. HRESULT hr = GetMIDLPSFactory(riid, &pPSFactory);
  271. if (SUCCEEDED(hr))
  272. {
  273. hr = pPSFactory->CreateProxy(pUnkOuter,riid,ppProxy,(void **)&pRealIf);
  274. pPSFactory->Release();
  275. }
  276. return pRealIf;
  277. }
  278. //---------------------------------------------------------------------------
  279. //
  280. // Function: CreateMIDLStub
  281. //
  282. // Purpose: Function for creating the MIDL generated stub
  283. // for the test interface.
  284. //
  285. //---------------------------------------------------------------------------
  286. IRpcStubBuffer *CreateMIDLStub(REFIID riid,
  287. IUnknown *pUnkOuter)
  288. {
  289. IRpcStubBuffer *pStub = NULL;
  290. IPSFactoryBuffer *pPSFactory = NULL;
  291. HRESULT hr = GetMIDLPSFactory(riid, &pPSFactory);
  292. if (SUCCEEDED(hr))
  293. {
  294. hr = pPSFactory->CreateStub(riid, pUnkOuter, &pStub);
  295. pPSFactory->Release();
  296. }
  297. return pStub;
  298. }
  299. //---------------------------------------------------------------------------
  300. //
  301. // Implement: CPSFactory
  302. //
  303. // Purpose: ProxyStub Class Factory
  304. //
  305. // Notes: just fill in the CreateProxy and CreateStub methods for
  306. // your other custom interfaces.
  307. //
  308. //---------------------------------------------------------------------------
  309. HRESULT CPSFactory::QueryInterface(REFIID riid, void **ppv)
  310. {
  311. if (IsEqualIID(riid, IID_IPSFactoryBuffer) ||
  312. IsEqualIID(riid, IID_IUnknown))
  313. {
  314. *ppv = (IPSFactoryBuffer *)this;
  315. // static object, dont need refcnt
  316. return S_OK;
  317. }
  318. *ppv = NULL;
  319. return E_NOINTERFACE;
  320. }
  321. ULONG CPSFactory::AddRef(void)
  322. {
  323. // static object, dont need refcnt
  324. return 1;
  325. }
  326. ULONG CPSFactory::Release(void)
  327. {
  328. // static object, dont need refcnt
  329. return 1;
  330. }
  331. HRESULT CPSFactory::CreateProxy(IUnknown *pUnkOuter, REFIID riid,
  332. IRpcProxyBuffer **ppProxy, void **ppv)
  333. {
  334. // check for supported interfaces
  335. if (IsEqualIID(riid, IID_ICube))
  336. {
  337. CProxyWrapper *pProxy = new CProxyWrapper(pUnkOuter, ppProxy);
  338. if (pProxy)
  339. {
  340. *ppv = (void *)(ICube *) pProxy;
  341. ((IUnknown *)(*ppv))->AddRef(); // AddRef the returned interface
  342. return S_OK;
  343. }
  344. }
  345. *ppProxy = NULL;
  346. *ppv = NULL;
  347. return E_NOINTERFACE;
  348. }
  349. HRESULT CPSFactory::CreateStub(REFIID riid, IUnknown *pUnkObj, IRpcStubBuffer **ppStub)
  350. {
  351. // check for supported interfaces
  352. if (IsEqualIID(riid, IID_ICube))
  353. {
  354. CStubWrapper *pStub = new CStubWrapper(pUnkObj, riid);
  355. if (pStub)
  356. {
  357. *ppStub = (IRpcStubBuffer *) pStub;
  358. return S_OK;
  359. }
  360. }
  361. *ppStub = NULL;
  362. return E_NOINTERFACE;
  363. }
  364. //---------------------------------------------------------------------------
  365. //
  366. // Implement: CStubWrapper
  367. //
  368. // Purpose: Wrapper object for stubs.
  369. //
  370. // Notes: This same class can wrap any stub object regardless of
  371. // the interface the stub is for.
  372. //
  373. //---------------------------------------------------------------------------
  374. CStubWrapper::CStubWrapper(IUnknown *pUnkObj, REFIID riid) :
  375. _cRefs(1),
  376. _pUnkObj(pUnkObj),
  377. _pHCStub(NULL),
  378. _pMIDLStub(NULL),
  379. _iid(riid)
  380. {
  381. _pUnkObj->AddRef();
  382. }
  383. CStubWrapper::~CStubWrapper(void)
  384. {
  385. Disconnect();
  386. }
  387. HRESULT CStubWrapper::QueryInterface(REFIID riid, void **ppv)
  388. {
  389. if (IsEqualIID(riid, IID_IRpcStubBuffer) ||
  390. IsEqualIID(riid, IID_IUnknown))
  391. {
  392. *ppv = (IRpcStubBuffer *)this;
  393. AddRef();
  394. return S_OK;
  395. }
  396. *ppv = NULL;
  397. return E_NOINTERFACE;
  398. }
  399. ULONG CStubWrapper::AddRef(void)
  400. {
  401. InterlockedIncrement((LONG *)&_cRefs);
  402. return _cRefs;
  403. }
  404. ULONG CStubWrapper::Release(void)
  405. {
  406. ULONG cRefs = _cRefs-1;
  407. if (InterlockedDecrement((LONG *)&_cRefs) == 0)
  408. {
  409. delete this;
  410. return 0;
  411. }
  412. return cRefs;
  413. }
  414. HRESULT CStubWrapper::Connect(IUnknown *pUnkObj)
  415. {
  416. if (_pUnkObj)
  417. {
  418. // already connected, disconnect
  419. Disconnect();
  420. }
  421. // get the requested interface and hold it.
  422. HRESULT hr = pUnkObj->QueryInterface(_iid, (void **)&_pUnkObj);
  423. if (FAILED(hr))
  424. {
  425. // make sure our ptr is NULL else we might think we're connected
  426. _pUnkObj = NULL;
  427. }
  428. return hr;
  429. }
  430. void CStubWrapper::Disconnect()
  431. {
  432. if (_pHCStub)
  433. {
  434. _pHCStub->Disconnect();
  435. _pHCStub->Release();
  436. _pHCStub = NULL;
  437. }
  438. if (_pMIDLStub)
  439. {
  440. _pMIDLStub->Disconnect();
  441. _pMIDLStub->Release();
  442. _pMIDLStub = NULL;
  443. }
  444. if (_pUnkObj)
  445. {
  446. _pUnkObj->Release();
  447. _pUnkObj = NULL;
  448. }
  449. }
  450. HRESULT CStubWrapper::Invoke(RPCOLEMESSAGE *pMsg, IRpcChannelBuffer *pChnl)
  451. {
  452. if (pMsg->rpcFlags & RPCFLG_NON_NDR)
  453. {
  454. // call is not NDR format, so use the hand-crafted stub.
  455. // create the stub if it does not exist yet.
  456. if (_pHCStub == NULL)
  457. {
  458. if ((_pHCStub = new CCubesStub(_pUnkObj)) == NULL)
  459. return E_OUTOFMEMORY;
  460. }
  461. return _pHCStub->Invoke(pMsg, pChnl);
  462. }
  463. // call is NDR format, so use the MIDL generated stub.
  464. // create the stub if it does not exist yet.
  465. if (_pMIDLStub == NULL)
  466. {
  467. _pMIDLStub = CreateMIDLStub(IID_ICube, _pUnkObj);
  468. if (_pMIDLStub == NULL)
  469. return E_OUTOFMEMORY;
  470. }
  471. return _pMIDLStub->Invoke(pMsg, pChnl);
  472. }
  473. IRpcStubBuffer *CStubWrapper::IsIIDSupported(REFIID riid)
  474. {
  475. if (IsEqualIID(riid, _iid))
  476. {
  477. AddRef();
  478. return (IRpcStubBuffer *)this;
  479. }
  480. return NULL;
  481. }
  482. ULONG CStubWrapper::CountRefs()
  483. {
  484. ULONG cRefs = (_pUnkObj) ? 1 : 0;
  485. if (_pHCStub)
  486. cRefs += _pHCStub->CountRefs();
  487. if (_pMIDLStub)
  488. cRefs += _pMIDLStub->CountRefs();
  489. return cRefs;
  490. }
  491. HRESULT CStubWrapper::DebugServerQueryInterface(void **ppv)
  492. {
  493. *ppv = (void *)_pUnkObj;
  494. return S_OK;
  495. }
  496. void CStubWrapper::DebugServerRelease(void *pv)
  497. {
  498. return;
  499. }
  500. //---------------------------------------------------------------------------
  501. //
  502. // Implement: CProxyWrapper
  503. //
  504. // Purpose: Wrapper object for itnerface proxies.
  505. //
  506. // Notes: the top several routines are the same for all proxies
  507. // but you must change the interface specific routines for
  508. // each new interface.
  509. //
  510. //---------------------------------------------------------------------------
  511. CProxyWrapper::CProxyWrapper(IUnknown *pUnkOuter, IRpcProxyBuffer **ppProxy) :
  512. _cRefs(1),
  513. _pUnkOuter(pUnkOuter), // don't AddRef
  514. _pRealProxy(NULL)
  515. {
  516. *ppProxy = (IRpcProxyBuffer *)&_InternalUnk;
  517. }
  518. CProxyWrapper::~CProxyWrapper(void)
  519. {
  520. if (_pRealProxy)
  521. {
  522. _InternalUnk.Disconnect();
  523. }
  524. }
  525. HRESULT CProxyWrapper::CInternalUnk::QueryInterface(REFIID riid, void **ppv)
  526. {
  527. CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
  528. if (IsEqualIID(riid, IID_IRpcProxyBuffer) ||
  529. IsEqualIID(riid, IID_IUnknown))
  530. {
  531. pProxy->AddRef();
  532. *ppv = (IRpcProxyBuffer *)this;
  533. return S_OK;
  534. }
  535. else if (IsEqualIID(riid, IID_ICube))
  536. {
  537. *ppv = (ICube *)pProxy;
  538. AddRef();
  539. return S_OK;
  540. }
  541. *ppv = NULL;
  542. return E_NOINTERFACE;
  543. }
  544. ULONG CProxyWrapper::CInternalUnk::AddRef(void)
  545. {
  546. CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
  547. InterlockedIncrement((LONG *)&pProxy->_cRefs);
  548. return pProxy->_cRefs;
  549. }
  550. ULONG CProxyWrapper::CInternalUnk::Release(void)
  551. {
  552. CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
  553. ULONG cRefs = pProxy->_cRefs-1;
  554. if (InterlockedDecrement((LONG *)&pProxy->_cRefs) == 0)
  555. {
  556. delete this;
  557. return 0;
  558. }
  559. return cRefs;
  560. }
  561. HRESULT CProxyWrapper::CInternalUnk::Connect(IRpcChannelBuffer *pChnl)
  562. {
  563. CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
  564. void *pv;
  565. HRESULT hr = pChnl->QueryInterface(IID_INonNDRStub, &pv);
  566. if (SUCCEEDED(hr))
  567. {
  568. ((IUnknown *)pv)->Release();
  569. // create the hand-crafted proxy
  570. pProxy->_pRealIf = new CCubesProxy(pProxy->_pUnkOuter,
  571. &pProxy->_pRealProxy);
  572. }
  573. else
  574. {
  575. // create the MIDL generated proxy
  576. pProxy->_pRealIf = (ICube *) CreateMIDLProxy(IID_ICube,
  577. pProxy->_pUnkOuter,
  578. &pProxy->_pRealProxy);
  579. }
  580. if (pProxy->_pRealIf == NULL)
  581. return E_OUTOFMEMORY;
  582. // since the proxy AddRef'd the punkOuter, we need to release it.
  583. pProxy->_pUnkOuter->Release();
  584. // connect the proxy
  585. hr = pProxy->_pRealProxy->Connect(pChnl);
  586. if (FAILED(hr))
  587. {
  588. pProxy->_pRealProxy->Release();
  589. pProxy->_pRealProxy = NULL;
  590. }
  591. return hr;
  592. }
  593. void CProxyWrapper::CInternalUnk::Disconnect(void)
  594. {
  595. CProxyWrapper *pProxy = GETPPARENT(this, CProxyWrapper, _InternalUnk);
  596. if (pProxy->_pRealProxy)
  597. {
  598. pProxy->_pRealProxy->Disconnect();
  599. pProxy->_pRealProxy->Release();
  600. pProxy->_pRealProxy = NULL;
  601. }
  602. }
  603. //---------------------------------------------------------------------------
  604. //
  605. // ICube specific proxy wrapper code below here.
  606. //
  607. //---------------------------------------------------------------------------
  608. HRESULT CProxyWrapper::QueryInterface(REFIID riid, void **ppv)
  609. {
  610. return _pUnkOuter->QueryInterface(riid, ppv);
  611. }
  612. ULONG CProxyWrapper::AddRef(void)
  613. {
  614. return _pUnkOuter->AddRef();
  615. }
  616. ULONG CProxyWrapper::Release(void)
  617. {
  618. return _pUnkOuter->Release();
  619. }
  620. HRESULT CProxyWrapper::MoveCube(ULONG xPos, ULONG yPos)
  621. {
  622. if (_pRealProxy)
  623. {
  624. return _pRealIf->MoveCube(xPos, yPos);
  625. }
  626. return CO_E_OBJNOTCONNECTED;
  627. }
  628. HRESULT CProxyWrapper::GetCubePos(ULONG *pxPos, ULONG *pyPos)
  629. {
  630. if (_pRealProxy)
  631. {
  632. return _pRealIf->GetCubePos(pxPos, pyPos);
  633. }
  634. *pxPos = 0;
  635. *pyPos = 0;
  636. return CO_E_OBJNOTCONNECTED;
  637. }
  638. HRESULT CProxyWrapper::Contains(IBalls *pIFDb)
  639. {
  640. if (_pRealProxy)
  641. {
  642. return _pRealIf->Contains(pIFDb);
  643. }
  644. return CO_E_OBJNOTCONNECTED;
  645. }
  646. HRESULT CProxyWrapper::SimpleCall(
  647. DWORD pidCaller,
  648. DWORD tidCaller,
  649. GUID lidCaller)
  650. {
  651. return CO_E_OBJNOTCONNECTED;
  652. }
  653. //---------------------------------------------------------------------------
  654. //
  655. // Implement: CCubesProxy
  656. //
  657. // Purpose: Hand-Crafted proxy object for interface ICube.
  658. //
  659. // Notes: Replace this with your exisitng 32bit hand-crafted proxies.
  660. //
  661. //---------------------------------------------------------------------------
  662. CCubesProxy::CCubesProxy(IUnknown *pUnkOuter, IRpcProxyBuffer **ppProxy) :
  663. _pUnkOuter(pUnkOuter),
  664. _pChnl(NULL)
  665. {
  666. _pUnkOuter->AddRef();
  667. *ppProxy = (IRpcProxyBuffer *)&_InternalUnk;
  668. }
  669. CCubesProxy::~CCubesProxy(void)
  670. {
  671. _InternalUnk.Disconnect();
  672. }
  673. HRESULT CCubesProxy::CInternalUnk::QueryInterface(REFIID riid, void **ppv)
  674. {
  675. if (IsEqualIID(riid, IID_IRpcProxyBuffer) ||
  676. IsEqualIID(riid, IID_IUnknown))
  677. {
  678. CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
  679. pProxy->AddRef();
  680. *ppv = (IRpcProxyBuffer *)this;
  681. return S_OK;
  682. }
  683. *ppv = NULL;
  684. return E_NOINTERFACE;
  685. }
  686. ULONG CCubesProxy::CInternalUnk::AddRef(void)
  687. {
  688. CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
  689. InterlockedIncrement((LONG *)&pProxy->_cRefs);
  690. return pProxy->_cRefs;
  691. }
  692. ULONG CCubesProxy::CInternalUnk::Release(void)
  693. {
  694. CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
  695. ULONG cRefs = pProxy->_cRefs-1;
  696. if (InterlockedDecrement((LONG *)&pProxy->_cRefs) == 0)
  697. {
  698. delete this;
  699. return 0;
  700. }
  701. return cRefs;
  702. }
  703. HRESULT CCubesProxy::CInternalUnk::Connect(IRpcChannelBuffer *pChnl)
  704. {
  705. Disconnect(); // make sure we are disconnected
  706. CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
  707. pProxy->_pChnl = pChnl; // keep the channel ptr
  708. pChnl->AddRef();
  709. return S_OK;
  710. }
  711. void CCubesProxy::CInternalUnk::Disconnect(void)
  712. {
  713. CCubesProxy *pProxy = GETPPARENT(this, CCubesProxy, _InternalUnk);
  714. if (pProxy->_pChnl)
  715. {
  716. pProxy->_pChnl->Release();
  717. pProxy->_pChnl = NULL;
  718. }
  719. }
  720. //---------------------------------------------------------------------------
  721. //
  722. // ICubes Proxy Implementation
  723. //
  724. //---------------------------------------------------------------------------
  725. HRESULT CCubesProxy::QueryInterface(REFIID riid, void **ppv)
  726. {
  727. return _pUnkOuter->QueryInterface(riid, ppv);
  728. }
  729. ULONG CCubesProxy::AddRef(void)
  730. {
  731. return _pUnkOuter->AddRef();
  732. }
  733. ULONG CCubesProxy::Release(void)
  734. {
  735. return _pUnkOuter->Release();
  736. }
  737. HRESULT CCubesProxy::MoveCube(ULONG xPos, ULONG yPos)
  738. {
  739. // set up the message and get the buffer
  740. RPCOLEMESSAGE msg;
  741. memset(&msg, 0, sizeof(msg));
  742. msg.iMethod = 3;
  743. msg.dataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
  744. msg.cbBuffer = 16;
  745. HRESULT hrFromServer;
  746. HRESULT hr = _pChnl->GetBuffer(&msg, IID_ICube);
  747. if (SUCCEEDED(hr))
  748. {
  749. // Marshal the parameters. The string "myproxy" followed by
  750. // xPos and yPos values.
  751. char *pBuf = (char *)msg.Buffer;
  752. strcpy((char *)pBuf, "myproxy");
  753. pBuf += 8;
  754. DWORD *dwp = (DWORD *)pBuf;
  755. *dwp = xPos;
  756. pBuf += 4;
  757. dwp = (DWORD *)pBuf;
  758. *dwp = yPos;
  759. // Send the message and get the reply
  760. ULONG ulStatus = 0;
  761. hr = _pChnl->SendReceive(&msg, &ulStatus);
  762. if (SUCCEEDED(hr))
  763. {
  764. // unmarshal the results
  765. hrFromServer = (DWORD)(msg.Buffer);
  766. }
  767. // FreeBuffer
  768. hr = _pChnl->FreeBuffer(&msg);
  769. }
  770. return hr;
  771. }
  772. HRESULT CCubesProxy::GetCubePos(ULONG *pxPos, ULONG *pyPos)
  773. {
  774. *pxPos = 0;
  775. *pyPos = 0;
  776. return E_NOTIMPL;
  777. }
  778. HRESULT CCubesProxy::Contains(IBalls *pIFDb)
  779. {
  780. return E_NOTIMPL;
  781. }
  782. HRESULT CCubesProxy::SimpleCall(
  783. DWORD pidCaller,
  784. DWORD tidCaller,
  785. GUID lidCaller)
  786. {
  787. return E_NOTIMPL;
  788. }
  789. //---------------------------------------------------------------------------
  790. //
  791. // Implement: CCubesStub
  792. //
  793. // Purpose: Hand-Crafted stub object for interface ICube.
  794. //
  795. // Notes: Replace this with your exisitng 32bit hand-crafted stubs.
  796. //
  797. //---------------------------------------------------------------------------
  798. CCubesStub::CCubesStub(IUnknown *pUnkObj) :
  799. _cRefs(1),
  800. _pUnkObj(pUnkObj)
  801. {
  802. _pUnkObj->AddRef();
  803. }
  804. CCubesStub::~CCubesStub(void)
  805. {
  806. Disconnect();
  807. }
  808. HRESULT CCubesStub::QueryInterface(REFIID riid, void **ppv)
  809. {
  810. if (IsEqualIID(riid, IID_IRpcStubBuffer) ||
  811. IsEqualIID(riid, IID_IUnknown))
  812. {
  813. *ppv = (IRpcStubBuffer *)this;
  814. }
  815. else
  816. {
  817. *ppv = NULL;
  818. return E_NOINTERFACE;
  819. }
  820. AddRef();
  821. return S_OK;
  822. }
  823. ULONG CCubesStub::AddRef(void)
  824. {
  825. InterlockedIncrement((LONG *)&_cRefs);
  826. return _cRefs;
  827. }
  828. ULONG CCubesStub::Release(void)
  829. {
  830. ULONG cRefs = _cRefs-1;
  831. if (InterlockedDecrement((LONG *)&_cRefs) == 0)
  832. {
  833. delete this;
  834. return 0;
  835. }
  836. return cRefs;
  837. }
  838. HRESULT CCubesStub::Connect(IUnknown *pUnkObj)
  839. {
  840. if (_pUnkObj)
  841. {
  842. // already connected, disconnect
  843. Disconnect();
  844. }
  845. // get the requested interface and hold it.
  846. HRESULT hr = pUnkObj->QueryInterface(IID_ICube, (void **)&_pUnkObj);
  847. if (FAILED(hr))
  848. {
  849. _pUnkObj = NULL;
  850. }
  851. return hr;
  852. }
  853. void CCubesStub::Disconnect()
  854. {
  855. if (_pUnkObj)
  856. {
  857. _pUnkObj->Release();
  858. _pUnkObj = NULL;
  859. }
  860. }
  861. HRESULT CCubesStub::Invoke(RPCOLEMESSAGE *pMsg, IRpcChannelBuffer *pChnl)
  862. {
  863. // Check the method number.
  864. if (pMsg->iMethod !=3 || pMsg->cbBuffer != 16)
  865. return E_INVALIDARG;
  866. // unmarshal the parameters
  867. char *pBuf = (char *)pMsg->Buffer;
  868. pBuf += 8;
  869. DWORD *dwp = (DWORD *)pBuf;
  870. ULONG xPos = *dwp;
  871. pBuf += 4;
  872. dwp = (DWORD *)pBuf;
  873. ULONG yPos = *dwp;
  874. // call the real object
  875. HRESULT hrFromServer = ((ICube *)_pUnkObj)->MoveCube(xPos, yPos);
  876. // get a new buffer
  877. pMsg->cbBuffer = 4;
  878. HRESULT hr = pChnl->GetBuffer(pMsg, IID_ICube);
  879. if (SUCCEEDED(hr))
  880. {
  881. // marshal the return values
  882. pBuf = (char *)pMsg->Buffer;
  883. dwp = (DWORD *)pBuf;
  884. *dwp = hrFromServer;
  885. }
  886. return hr;
  887. }
  888. IRpcStubBuffer *CCubesStub::IsIIDSupported(REFIID riid)
  889. {
  890. if (IsEqualIID(riid, IID_ICube))
  891. {
  892. AddRef();
  893. return (IRpcStubBuffer *)this;
  894. }
  895. return NULL;
  896. }
  897. ULONG CCubesStub::CountRefs()
  898. {
  899. // only keep one reference
  900. return 1;
  901. }
  902. HRESULT CCubesStub::DebugServerQueryInterface(void **ppv)
  903. {
  904. *ppv = (void *)_pUnkObj;
  905. return S_OK;
  906. }
  907. void CCubesStub::DebugServerRelease(void *pv)
  908. {
  909. return;
  910. }