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.

2887 lines
67 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (c) 1994-2000 Microsoft Corporation. All rights reserved.
  4. Module Name:
  5. proxy.c
  6. Abstract:
  7. Implements the IRpcProxyBuffer interface.
  8. Author:
  9. ShannonC 12-Oct-1994
  10. Environment:
  11. Windows NT and Windows 95 and PowerMac.
  12. We do not support DOS, Win16 and Mac.
  13. Revision History:
  14. --*/
  15. #define USE_STUBLESS_PROXY
  16. #define CINTERFACE
  17. #include <ndrp.h>
  18. #include <ndrole.h>
  19. #include <rpcproxy.h>
  20. #include <stddef.h>
  21. CStdProxyBuffer * RPC_ENTRY
  22. NdrGetProxyBuffer(
  23. void *pThis);
  24. const IID * RPC_ENTRY
  25. NdrGetProxyIID(
  26. const void *pThis);
  27. ULONG STDMETHODCALLTYPE
  28. CStdProxyBuffer_Release(
  29. IN IRpcProxyBuffer *This);
  30. ULONG STDMETHODCALLTYPE
  31. CStdProxyBuffer2_Release(
  32. IN IRpcProxyBuffer *This);
  33. BOOL NdrpFindInterface(
  34. IN const ProxyFileInfo ** pProxyFileList,
  35. IN REFIID riid,
  36. OUT const ProxyFileInfo ** ppProxyFileInfo,
  37. OUT long * pIndex );
  38. // The channel wrapper
  39. //
  40. typedef struct tagChannelWrapper
  41. {
  42. const IRpcChannelBufferVtbl *lpVtbl;
  43. long RefCount;
  44. const IID * pIID;
  45. struct IRpcChannelBuffer * pChannel;
  46. } ChannelWrapper;
  47. HRESULT STDMETHODCALLTYPE
  48. CreateChannelWrapper
  49. (
  50. const IID * pIID,
  51. IRpcChannelBuffer * pChannel,
  52. IRpcChannelBuffer ** pChannelWrapper
  53. );
  54. HRESULT STDMETHODCALLTYPE
  55. CreateAsyncChannelWrapper
  56. (
  57. const IID * pIID,
  58. IRpcChannelBuffer * pChannel,
  59. IRpcChannelBuffer ** pChannelWrapper
  60. );
  61. HRESULT STDMETHODCALLTYPE
  62. ChannelWrapper_QueryInterface
  63. (
  64. IRpcChannelBuffer3 * This,
  65. REFIID riid,
  66. void ** ppvObject
  67. );
  68. ULONG STDMETHODCALLTYPE
  69. ChannelWrapper_AddRef
  70. (
  71. IRpcChannelBuffer3 * This
  72. );
  73. ULONG STDMETHODCALLTYPE
  74. ChannelWrapper_Release
  75. (
  76. IRpcChannelBuffer3 * This
  77. );
  78. HRESULT STDMETHODCALLTYPE
  79. ChannelWrapper_GetBuffer
  80. (
  81. IRpcChannelBuffer3 * This,
  82. RPCOLEMESSAGE * pMessage,
  83. REFIID riid
  84. );
  85. HRESULT STDMETHODCALLTYPE
  86. ChannelWrapper_SendReceive
  87. (
  88. IRpcChannelBuffer3 * This,
  89. RPCOLEMESSAGE * pMessage,
  90. ULONG * pStatus
  91. );
  92. HRESULT STDMETHODCALLTYPE
  93. ChannelWrapper_FreeBuffer
  94. (
  95. IRpcChannelBuffer3 * This,
  96. RPCOLEMESSAGE * pMessage
  97. );
  98. HRESULT STDMETHODCALLTYPE
  99. ChannelWrapper_GetDestCtx
  100. (
  101. IRpcChannelBuffer3 * This,
  102. DWORD * pdwDestContext,
  103. void ** ppvDestContext
  104. );
  105. HRESULT STDMETHODCALLTYPE
  106. ChannelWrapper_IsConnected
  107. (
  108. IRpcChannelBuffer3 * This
  109. );
  110. HRESULT STDMETHODCALLTYPE
  111. ChannelWrapper_GetProtocolVersion
  112. (
  113. IRpcChannelBuffer3 * This,
  114. DWORD * pdwVersion
  115. );
  116. HRESULT STDMETHODCALLTYPE
  117. ChannelWrapper_Send(
  118. IRpcChannelBuffer3 * This,
  119. RPCOLEMESSAGE * pMessage,
  120. ULONG * pStatus
  121. );
  122. HRESULT STDMETHODCALLTYPE
  123. ChannelWrapper_Receive(
  124. IRpcChannelBuffer3 * This,
  125. RPCOLEMESSAGE * pMessage,
  126. ULONG ulSize,
  127. ULONG * pStatus
  128. );
  129. HRESULT STDMETHODCALLTYPE
  130. ChannelWrapper_Cancel(
  131. IRpcChannelBuffer3 * This,
  132. RPCOLEMESSAGE * pMessage
  133. );
  134. HRESULT STDMETHODCALLTYPE
  135. ChannelWrapper_GetCallContext(
  136. IRpcChannelBuffer3 * This,
  137. RPCOLEMESSAGE * pMessage,
  138. REFIID riid,
  139. void ** pInterface
  140. );
  141. HRESULT STDMETHODCALLTYPE
  142. ChannelWrapper_GetDestCtxEx(
  143. IRpcChannelBuffer3 * This,
  144. RPCOLEMESSAGE * pMessage,
  145. DWORD * pdwDestContext,
  146. void ** ppvDestContext
  147. );
  148. HRESULT STDMETHODCALLTYPE
  149. ChannelWrapper_GetState(
  150. IRpcChannelBuffer3 * This,
  151. RPCOLEMESSAGE * pMessage,
  152. DWORD * pState
  153. );
  154. HRESULT STDMETHODCALLTYPE
  155. ChannelWrapper_RegisterAsync(
  156. IRpcChannelBuffer3 * This,
  157. RPCOLEMESSAGE * pMessage,
  158. IAsyncManager * pAsyncMgr
  159. );
  160. HRESULT STDMETHODCALLTYPE
  161. AsyncChannelWrapper_QueryInterface
  162. (
  163. IAsyncRpcChannelBuffer * This,
  164. REFIID riid,
  165. void ** ppvObject
  166. );
  167. ULONG STDMETHODCALLTYPE
  168. AsyncChannelWrapper_AddRef
  169. (
  170. IAsyncRpcChannelBuffer * This
  171. );
  172. ULONG STDMETHODCALLTYPE
  173. AsyncChannelWrapper_Release
  174. (
  175. IAsyncRpcChannelBuffer * This
  176. );
  177. HRESULT STDMETHODCALLTYPE
  178. AsyncChannelWrapper_GetBuffer
  179. (
  180. IAsyncRpcChannelBuffer * This,
  181. RPCOLEMESSAGE * pMessage,
  182. REFIID riid
  183. );
  184. HRESULT STDMETHODCALLTYPE
  185. AsyncChannelWrapper_SendReceive
  186. (
  187. IAsyncRpcChannelBuffer * This,
  188. RPCOLEMESSAGE * pMessage,
  189. ULONG * pStatus
  190. );
  191. HRESULT STDMETHODCALLTYPE
  192. AsyncChannelWrapper_FreeBuffer
  193. (
  194. IAsyncRpcChannelBuffer * This,
  195. RPCOLEMESSAGE * pMessage
  196. );
  197. HRESULT STDMETHODCALLTYPE
  198. AsyncChannelWrapper_GetDestCtx
  199. (
  200. IAsyncRpcChannelBuffer * This,
  201. DWORD * pdwDestContext,
  202. void ** ppvDestContext
  203. );
  204. HRESULT STDMETHODCALLTYPE
  205. AsyncChannelWrapper_IsConnected
  206. (
  207. IAsyncRpcChannelBuffer * This
  208. );
  209. HRESULT STDMETHODCALLTYPE
  210. AsyncChannelWrapper_GetProtocolVersion
  211. (
  212. IAsyncRpcChannelBuffer * This,
  213. DWORD * pdwVersion
  214. );
  215. HRESULT STDMETHODCALLTYPE
  216. AsyncChannelWrapper_Send(
  217. IAsyncRpcChannelBuffer * This,
  218. RPCOLEMESSAGE * pMessage,
  219. ISynchronize * pSynchronize,
  220. ULONG * pStatus
  221. );
  222. HRESULT STDMETHODCALLTYPE
  223. AsyncChannelWrapper_Receive(
  224. IAsyncRpcChannelBuffer * This,
  225. RPCOLEMESSAGE * pMessage,
  226. ULONG * pStatus
  227. );
  228. HRESULT STDMETHODCALLTYPE
  229. AsyncChannelWrapper_GetDestCtxEx
  230. (
  231. IAsyncRpcChannelBuffer * This,
  232. RPCOLEMESSAGE * pMessage,
  233. DWORD * pdwDestContext,
  234. void ** ppvDestContext
  235. );
  236. //+-------------------------------------------------------------------------
  237. //
  238. // Global data
  239. //
  240. //--------------------------------------------------------------------------
  241. // ProxyBuffer vtables for non-delegaed and delegated case.
  242. extern const IRpcProxyBufferVtbl CStdProxyBufferVtbl = {
  243. CStdProxyBuffer_QueryInterface,
  244. CStdProxyBuffer_AddRef,
  245. CStdProxyBuffer_Release,
  246. CStdProxyBuffer_Connect,
  247. CStdProxyBuffer_Disconnect };
  248. extern const IRpcProxyBufferVtbl CStdProxyBuffer2Vtbl = {
  249. CStdProxyBuffer_QueryInterface,
  250. CStdProxyBuffer_AddRef,
  251. CStdProxyBuffer2_Release,
  252. CStdProxyBuffer2_Connect,
  253. CStdProxyBuffer2_Disconnect };
  254. // ICallFactory interface on the ProxyBuffer objects.
  255. // ICallFactory is an interface on a sync proxy only.
  256. // It has been introduced for NT5 beta2.
  257. extern const ICallFactoryVtbl CStdProxyBuffer_CallFactoryVtbl = {
  258. CStdProxyBuffer_CF_QueryInterface,
  259. CStdProxyBuffer_CF_AddRef,
  260. CStdProxyBuffer_CF_Release,
  261. CStdProxyBuffer_CF_CreateCall };
  262. extern const ICallFactoryVtbl CStdProxyBuffer2_CallFactoryVtbl = {
  263. CStdProxyBuffer_CF_QueryInterface,
  264. CStdProxyBuffer_CF_AddRef,
  265. CStdProxyBuffer_CF_Release,
  266. CStdProxyBuffer2_CF_CreateCall };
  267. extern const IReleaseMarshalBuffersVtbl CStdProxyBuffer_ReleaseMarshalBuffersVtbl = {
  268. CStdProxyBuffer_RMB_QueryInterface,
  269. CStdProxyBuffer_RMB_AddRef,
  270. CStdProxyBuffer_RMB_Release,
  271. CStdProxyBuffer_RMB_ReleaseMarshalBuffer };
  272. extern const IReleaseMarshalBuffersVtbl CStdAsyncProxyBuffer_ReleaseMarshalBuffersVtbl = {
  273. CStdProxyBuffer_RMB_QueryInterface,
  274. CStdProxyBuffer_RMB_AddRef,
  275. CStdProxyBuffer_RMB_Release,
  276. CStdAsyncProxyBuffer_RMB_ReleaseMarshalBuffer };
  277. // Async proxy buffer vtables
  278. extern const IRpcProxyBufferVtbl CStdAsyncProxyBufferVtbl = {
  279. CStdAsyncProxyBuffer_QueryInterface,
  280. CStdProxyBuffer_AddRef,
  281. CStdAsyncProxyBuffer_Release,
  282. CStdAsyncProxyBuffer_Connect,
  283. CStdProxyBuffer_Disconnect };
  284. extern const IRpcProxyBufferVtbl CStdAsyncProxyBuffer2Vtbl = {
  285. CStdAsyncProxyBuffer_QueryInterface,
  286. CStdProxyBuffer_AddRef,
  287. CStdAsyncProxyBuffer2_Release,
  288. CStdAsyncProxyBuffer2_Connect,
  289. CStdProxyBuffer2_Disconnect };
  290. // Channel wrapper is used for delegetion only.
  291. extern const IRpcChannelBuffer3Vtbl ChannelWrapperVtbl = {
  292. ChannelWrapper_QueryInterface,
  293. ChannelWrapper_AddRef,
  294. ChannelWrapper_Release,
  295. ChannelWrapper_GetBuffer,
  296. ChannelWrapper_SendReceive,
  297. ChannelWrapper_FreeBuffer,
  298. ChannelWrapper_GetDestCtx,
  299. ChannelWrapper_IsConnected,
  300. ChannelWrapper_GetProtocolVersion,
  301. ChannelWrapper_Send,
  302. ChannelWrapper_Receive,
  303. ChannelWrapper_Cancel,
  304. ChannelWrapper_GetCallContext,
  305. ChannelWrapper_GetDestCtxEx,
  306. ChannelWrapper_GetState,
  307. ChannelWrapper_RegisterAsync
  308. };
  309. extern const IAsyncRpcChannelBufferVtbl AsyncChannelWrapperVtbl = {
  310. AsyncChannelWrapper_QueryInterface,
  311. AsyncChannelWrapper_AddRef,
  312. AsyncChannelWrapper_Release,
  313. AsyncChannelWrapper_GetBuffer,
  314. AsyncChannelWrapper_SendReceive,
  315. AsyncChannelWrapper_FreeBuffer,
  316. AsyncChannelWrapper_GetDestCtx,
  317. AsyncChannelWrapper_IsConnected,
  318. AsyncChannelWrapper_GetProtocolVersion,
  319. AsyncChannelWrapper_Send,
  320. AsyncChannelWrapper_Receive,
  321. AsyncChannelWrapper_GetDestCtxEx
  322. };
  323. //+-------------------------------------------------------------------------
  324. //
  325. // End of Global data
  326. //
  327. //--------------------------------------------------------------------------
  328. #pragma code_seg(".orpc")
  329. // __inline
  330. CStdProxyBuffer * RPC_ENTRY
  331. NdrGetProxyBuffer(
  332. IN void *pThis)
  333. /*++
  334. Routine Description:
  335. The "this" pointer points to the pProxyVtbl field in the
  336. CStdProxyBuffer structure. The NdrGetProxyBuffer function
  337. returns a pointer to the top of the CStdProxyBuffer
  338. structure.
  339. Arguments:
  340. pThis - Supplies a pointer to the interface proxy.
  341. Return Value:
  342. This function returns a pointer to the proxy buffer.
  343. --*/
  344. {
  345. unsigned char *pTemp;
  346. pTemp = (unsigned char *) pThis;
  347. pTemp -= offsetof(CStdProxyBuffer, pProxyVtbl);
  348. return (CStdProxyBuffer *)pTemp;
  349. }
  350. //__inline
  351. const IID * RPC_ENTRY
  352. NdrGetProxyIID(
  353. IN const void *pThis)
  354. /*++
  355. Routine Description:
  356. The NDRGetProxyIID function returns a pointer to IID.
  357. Arguments:
  358. pThis - Supplies a pointer to the interface proxy.
  359. Return Value:
  360. This function returns a pointer to the IID.
  361. --*/
  362. {
  363. unsigned char ** ppTemp;
  364. unsigned char * pTemp;
  365. CInterfaceProxyVtbl *pProxyVtbl;
  366. //Get a pointer to the proxy vtbl.
  367. ppTemp = (unsigned char **) pThis;
  368. pTemp = *ppTemp;
  369. pTemp -= sizeof(CInterfaceProxyHeader);
  370. pProxyVtbl = (CInterfaceProxyVtbl *) pTemp;
  371. return pProxyVtbl->header.piid;
  372. }
  373. HRESULT STDMETHODCALLTYPE
  374. CStdProxyBuffer_QueryInterface(
  375. IN IRpcProxyBuffer * This,
  376. IN REFIID riid,
  377. OUT void ** ppv)
  378. /*++
  379. Routine Description:
  380. Query for an interface on the proxy. This function provides access
  381. to both internal and external interfaces.
  382. Arguments:
  383. riid - Supplies the IID of the requested interface.
  384. ppv - Returns a pointer to the requested interface.
  385. Return Value:
  386. S_OK
  387. E_NOINTERFACE
  388. --*/
  389. {
  390. CStdProxyBuffer * pCThis = (CStdProxyBuffer *) This;
  391. HRESULT hr = E_NOINTERFACE;
  392. const IID * pIID;
  393. *ppv = 0;
  394. if( (memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  395. (memcmp(&riid, &IID_IRpcProxyBuffer, sizeof(IID)) == 0) )
  396. {
  397. //This is an internal interface. Increment the internal reference count.
  398. InterlockedIncrement( &pCThis->RefCount);
  399. *ppv = This;
  400. hr = S_OK;
  401. return hr;
  402. }
  403. else if ( pCThis->pCallFactoryVtbl != 0 &&
  404. memcmp(&riid, &IID_ICallFactory, sizeof(IID)) == 0 )
  405. {
  406. // This is an exposed interface so go through punkOuter ot addref.
  407. pCThis->punkOuter->lpVtbl->AddRef(pCThis->punkOuter);
  408. *ppv = (void *) & pCThis->pCallFactoryVtbl;
  409. hr = S_OK;
  410. return hr;
  411. }
  412. else if ( pCThis->pRMBVtbl &&
  413. (memcmp(&riid, &IID_IReleaseMarshalBuffers,sizeof(IID)) == 0))
  414. {
  415. InterlockedIncrement( &pCThis->RefCount);
  416. *ppv = (void *) & pCThis->pRMBVtbl;
  417. hr = S_OK;
  418. return hr;
  419. }
  420. pIID = NdrGetProxyIID(&pCThis->pProxyVtbl);
  421. if( memcmp(&riid, pIID, sizeof(IID)) == 0)
  422. {
  423. //Increment the reference count.
  424. pCThis->punkOuter->lpVtbl->AddRef(pCThis->punkOuter);
  425. *ppv = (void *) &pCThis->pProxyVtbl;
  426. hr = S_OK;
  427. }
  428. return hr;
  429. };
  430. HRESULT STDMETHODCALLTYPE
  431. CStdAsyncProxyBuffer_QueryInterface(
  432. IN IRpcProxyBuffer * This,
  433. IN REFIID riid,
  434. OUT void ** ppv)
  435. /*++
  436. Routine Description:
  437. Query for an interface on the proxy. This function provides access
  438. to both internal and external interfaces.
  439. Used for
  440. CStdAsyncProxyBuffer2 as well.
  441. Arguments:
  442. riid - Supplies the IID of the requested interface.
  443. ppv - Returns a pointer to the requested interface.
  444. Return Value:
  445. S_OK
  446. E_NOINTERFACE
  447. --*/
  448. {
  449. CStdProxyBuffer * pCThis = (CStdProxyBuffer *) This;
  450. HRESULT hr = E_NOINTERFACE;
  451. const IID * pIID;
  452. *ppv = 0;
  453. if( (memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  454. (memcmp(&riid, &IID_IRpcProxyBuffer, sizeof(IID)) == 0))
  455. {
  456. //This is an internal interface. Increment the internal reference count.
  457. InterlockedIncrement( &pCThis->RefCount);
  458. *ppv = This;
  459. hr = S_OK;
  460. return hr;
  461. }
  462. else if ( pCThis->pRMBVtbl &&
  463. (memcmp(&riid, &IID_IReleaseMarshalBuffers,sizeof(IID)) == 0))
  464. {
  465. InterlockedIncrement( &pCThis->RefCount);
  466. *ppv = (void *) & pCThis->pRMBVtbl;
  467. hr = S_OK;
  468. return hr;
  469. }
  470. if(memcmp(&riid, &IID_ISynchronize, sizeof(IID)) == 0)
  471. {
  472. hr = pCThis->punkOuter->lpVtbl->QueryInterface( pCThis->punkOuter,
  473. IID_ISynchronize,
  474. ppv);
  475. }
  476. pIID = NdrGetProxyIID(&pCThis->pProxyVtbl);
  477. if(memcmp(&riid, pIID, sizeof(IID)) == 0)
  478. {
  479. //Increment the reference count.
  480. pCThis->punkOuter->lpVtbl->AddRef(pCThis->punkOuter);
  481. *ppv = (void *) &pCThis->pProxyVtbl;
  482. hr = S_OK;
  483. }
  484. return hr;
  485. };
  486. ULONG STDMETHODCALLTYPE
  487. CStdProxyBuffer_AddRef(
  488. IN IRpcProxyBuffer *This)
  489. /*++
  490. Routine Description:
  491. Increment reference count.
  492. Used for
  493. CStdProxyBuffer2
  494. CStdAsyncProxyBuffer
  495. CStdAsuncProxyBuffer2
  496. Arguments:
  497. Return Value:
  498. Reference count.
  499. --*/
  500. {
  501. // We do not need to go through punkOuter for ICallFactory.
  502. CStdProxyBuffer * pCThis = (CStdProxyBuffer *) This;
  503. InterlockedIncrement(&pCThis->RefCount);
  504. return (ULONG) pCThis->RefCount;
  505. };
  506. ULONG STDMETHODCALLTYPE
  507. CStdProxyBuffer_Release(
  508. IN IRpcProxyBuffer *This)
  509. /*++
  510. Routine Description:
  511. Decrement reference count.
  512. Arguments:
  513. Return Value:
  514. Reference count.
  515. --*/
  516. {
  517. ULONG count;
  518. IPSFactoryBuffer *pFactory;
  519. NDR_ASSERT(((CStdProxyBuffer *)This)->RefCount > 0, "Invalid reference count");
  520. count = (unsigned long) ((CStdProxyBuffer *)This)->RefCount - 1;
  521. if(InterlockedDecrement(&((CStdProxyBuffer *)This)->RefCount) == 0)
  522. {
  523. count = 0;
  524. pFactory = (IPSFactoryBuffer *) ((CStdProxyBuffer *)This)->pPSFactory;
  525. //Decrement the DLL reference count.
  526. pFactory->lpVtbl->Release(pFactory);
  527. #if DBG == 1
  528. //In debug builds, zero fill the memory.
  529. memset(This, '\0', sizeof(CStdProxyBuffer));
  530. #endif
  531. //Free the memory
  532. (*pfnCoTaskMemFree)(This);
  533. }
  534. return count;
  535. };
  536. ULONG STDMETHODCALLTYPE
  537. CStdProxyBuffer2_Release(
  538. IN IRpcProxyBuffer * This)
  539. /*++
  540. Routine Description:
  541. Decrement reference count. This function is used by proxies
  542. which delegate to the base interface.
  543. Arguments:
  544. This - Points to a CStdProxyBuffer2.
  545. Return Value:
  546. Reference count.
  547. --*/
  548. {
  549. ULONG count;
  550. IPSFactoryBuffer * pFactory;
  551. IRpcProxyBuffer * pBaseProxyBuffer;
  552. IUnknown * pBaseProxy;
  553. NDR_ASSERT(((CStdProxyBuffer2 *)This)->RefCount > 0, "Invalid reference count");
  554. count = (ULONG) ((CStdProxyBuffer2 *)This)->RefCount - 1;
  555. if(InterlockedDecrement(&((CStdProxyBuffer2 *)This)->RefCount) == 0)
  556. {
  557. count = 0;
  558. //Delegation support.
  559. pBaseProxy = ((CStdProxyBuffer2 *)This)->pBaseProxy;
  560. if(pBaseProxy != 0)
  561. {
  562. // Shannon - why?
  563. //This is a weak reference, so we don't release it.
  564. //pBaseProxy->lpVtbl->Release(pBaseProxy);
  565. }
  566. pBaseProxyBuffer = ((CStdProxyBuffer2 *)This)->pBaseProxyBuffer;
  567. if( pBaseProxyBuffer != 0)
  568. {
  569. pBaseProxyBuffer->lpVtbl->Release(pBaseProxyBuffer);
  570. }
  571. //Decrement the DLL reference count.
  572. pFactory = (IPSFactoryBuffer *) ((CStdProxyBuffer2 *)This)->pPSFactory;
  573. pFactory->lpVtbl->Release(pFactory);
  574. #if DBG == 1
  575. //In debug builds, zero fill the memory.
  576. memset(This, '\0', sizeof(CStdProxyBuffer2));
  577. #endif
  578. //Free the memory
  579. (*pfnCoTaskMemFree)(This);
  580. }
  581. return count;
  582. };
  583. ULONG STDMETHODCALLTYPE
  584. CStdAsyncProxyBuffer_Release(
  585. IN IRpcProxyBuffer *This)
  586. /*++
  587. Routine Description:
  588. Decrement reference count.
  589. Arguments:
  590. Return Value:
  591. Reference count.
  592. --*/
  593. {
  594. // We do not need to go through punkOuter for ICallFactory
  595. // and so everything is local.
  596. CStdAsyncProxyBuffer * pAsyncPB = (CStdAsyncProxyBuffer *)This;
  597. ULONG count;
  598. NDR_ASSERT( pAsyncPB->RefCount > 0, "Async proxy Invalid reference count");
  599. count = (unsigned long) pAsyncPB->RefCount - 1;
  600. if ( InterlockedDecrement(&pAsyncPB->RefCount) == 0)
  601. {
  602. IPSFactoryBuffer * pFactory = pAsyncPB->pPSFactory;
  603. count = 0;
  604. // Release the pAsyncMsg and the related state
  605. NdrpAsyncProxyMsgDestructor( pAsyncPB );
  606. //Decrement the DLL reference count.
  607. pFactory->lpVtbl->Release( pFactory );
  608. #if DBG == 1
  609. //In debug builds, zero fill the memory.
  610. memset( pAsyncPB, '\32', sizeof(CStdAsyncProxyBuffer));
  611. #endif
  612. //Free the memory
  613. (*pfnCoTaskMemFree)(pAsyncPB);
  614. }
  615. return count;
  616. };
  617. ULONG STDMETHODCALLTYPE
  618. CStdAsyncProxyBuffer2_Release(
  619. IN IRpcProxyBuffer * This)
  620. /*++
  621. Routine Description:
  622. Decrement reference count. This function is used by proxies
  623. which delegate to the base interface.
  624. Arguments:
  625. This - Points to a CStdProxyBuffer2.
  626. Return Value:
  627. Reference count.
  628. --*/
  629. {
  630. CStdAsyncProxyBuffer * pAsyncPB = (CStdAsyncProxyBuffer *)This;
  631. ULONG count;
  632. NDR_ASSERT( pAsyncPB->RefCount > 0, "Invalid reference count");
  633. count = (ULONG) pAsyncPB->RefCount - 1;
  634. if ( InterlockedDecrement(&pAsyncPB->RefCount) == 0)
  635. {
  636. IRpcProxyBuffer * pBaseProxyBuffer ;
  637. IPSFactoryBuffer * pFactory = pAsyncPB->pPSFactory;
  638. count = 0;
  639. // Delegation support - release the base async proxy.
  640. if( pAsyncPB->map.pBaseProxy != 0)
  641. {
  642. // Shannon - why?
  643. //This is a weak reference, so we don't release it.
  644. //pBaseProxy->lpVtbl->Release(pBaseProxy);
  645. }
  646. pBaseProxyBuffer = pAsyncPB->pBaseProxyBuffer;
  647. if( pBaseProxyBuffer != 0)
  648. pBaseProxyBuffer->lpVtbl->Release(pBaseProxyBuffer);
  649. // Release the pAsyncMsg and the related state
  650. NdrpAsyncProxyMsgDestructor( (CStdAsyncProxyBuffer*)This );
  651. // Then clean up the async proxy itself.
  652. //Decrement the DLL reference count.
  653. pFactory->lpVtbl->Release(pFactory);
  654. #if DBG == 1
  655. //In debug builds, zero fill the memory.
  656. memset(pAsyncPB, '\32', sizeof(CStdAsyncProxyBuffer));
  657. #endif
  658. //Free the memory
  659. (*pfnCoTaskMemFree)(pAsyncPB);
  660. }
  661. return count;
  662. };
  663. HRESULT STDMETHODCALLTYPE
  664. CStdProxyBuffer_RMB_QueryInterface(
  665. IN IReleaseMarshalBuffers *This,
  666. IN REFIID riid,
  667. OUT void ** ppvObject)
  668. /*++
  669. Routine Description:
  670. Query for an interface on the interface stub IReleaseMarshalBuffers pointer.
  671. Arguments:
  672. riid - Supplies the IID of the interface being requested.
  673. ppvObject - Returns a pointer to the requested interface.
  674. Return Value:
  675. S_OK
  676. E_NOINTERFACE
  677. Note:
  678. Works the same way for ProxyBuffer2 and AsyncProxyBuffer.
  679. --*/
  680. {
  681. CStdProxyBuffer * pSyncPB = (CStdProxyBuffer *)
  682. ((uchar *)This - offsetof(CStdProxyBuffer,pRMBVtbl));
  683. return pSyncPB->lpVtbl->QueryInterface( (IRpcProxyBuffer *)pSyncPB,
  684. riid,
  685. ppvObject );
  686. }
  687. ULONG STDMETHODCALLTYPE
  688. CStdProxyBuffer_RMB_AddRef(
  689. IN IReleaseMarshalBuffers *This)
  690. /*++
  691. Routine Description:
  692. Implementation of AddRef for interface proxy.
  693. Arguments:
  694. Return Value:
  695. Reference count.
  696. --*/
  697. {
  698. ULONG count;
  699. CStdProxyBuffer * pSyncPB = (CStdProxyBuffer *)
  700. ((uchar *)This - offsetof(CStdProxyBuffer,pRMBVtbl));
  701. // It needs to go through punkOuter.
  702. count = pSyncPB->lpVtbl->AddRef((IRpcProxyBuffer *) pSyncPB );
  703. return count;
  704. };
  705. ULONG STDMETHODCALLTYPE
  706. CStdProxyBuffer_RMB_Release(
  707. IN IReleaseMarshalBuffers *This)
  708. /*++
  709. Routine Description:
  710. Implementation of Release for interface proxy.
  711. Arguments:
  712. Return Value:
  713. Reference count.
  714. --*/
  715. {
  716. ULONG count;
  717. CStdProxyBuffer2 * pSyncPB = (CStdProxyBuffer2 *)
  718. ((uchar *)This - offsetof(CStdProxyBuffer2,pRMBVtbl));
  719. count = pSyncPB->lpVtbl->Release( (IRpcProxyBuffer *)pSyncPB);
  720. return count;
  721. };
  722. HRESULT STDMETHODCALLTYPE
  723. CStdProxyBuffer_RMB_ReleaseMarshalBuffer(
  724. IN IReleaseMarshalBuffers *This,
  725. IN RPCOLEMESSAGE * pMsg,
  726. IN DWORD dwFlags,
  727. IN IUnknown *pChnl)
  728. {
  729. CStdProxyBuffer * pSyncPB;
  730. HRESULT hr;
  731. if (NULL != pChnl)
  732. return E_INVALIDARG;
  733. // [in] only in client side.
  734. if (dwFlags)
  735. return E_INVALIDARG;
  736. hr = NdrpClientReleaseMarshalBuffer(This,
  737. (RPC_MESSAGE *)pMsg,
  738. dwFlags,
  739. FALSE ); // SYNC
  740. return hr;
  741. }
  742. #define IN_BUFFER 0
  743. #define OUT_BUFFER 1
  744. // the pRMBVtbl member is in the same position is both CStdProxyBuffer(2) and
  745. // CStdAsyncProxyBuffer so we can cast it anyway.
  746. HRESULT STDMETHODCALLTYPE
  747. CStdAsyncProxyBuffer_RMB_ReleaseMarshalBuffer(
  748. IN IReleaseMarshalBuffers *This,
  749. IN RPCOLEMESSAGE * pMsg,
  750. IN DWORD dwIOFlags,
  751. IN IUnknown *pChnl)
  752. {
  753. HRESULT hr;
  754. if (NULL != pChnl)
  755. return E_INVALIDARG;
  756. // [in] only in client side.
  757. if (dwIOFlags != IN_BUFFER)
  758. return E_INVALIDARG;
  759. hr = NdrpClientReleaseMarshalBuffer(This,
  760. (RPC_MESSAGE *)pMsg,
  761. dwIOFlags,
  762. TRUE); // is async
  763. return hr;
  764. }
  765. HRESULT STDMETHODCALLTYPE
  766. CStdProxyBuffer_Connect(
  767. IN IRpcProxyBuffer * This,
  768. IN IRpcChannelBuffer * pChannel)
  769. /*++
  770. Routine Description:
  771. Connect the proxy to the channel.
  772. Arguments:
  773. pChannel - Supplies a pointer to the channel.
  774. Return Value:
  775. S_OK
  776. --*/
  777. {
  778. CStdProxyBuffer * pCThis = (CStdProxyBuffer *) This;
  779. HRESULT hr;
  780. IRpcChannelBuffer * pTemp = 0;
  781. //
  782. // Get a pointer to the new channel.
  783. //
  784. hr = pChannel->lpVtbl->QueryInterface(
  785. pChannel, IID_IRpcChannelBuffer, (void **) &pTemp);
  786. if(hr == S_OK)
  787. {
  788. //
  789. // Save the pointer to the new channel.
  790. //
  791. pTemp = (IRpcChannelBuffer *) InterlockedExchangePointer(
  792. (PVOID *) &pCThis->pChannel, (PVOID) pTemp);
  793. if(pTemp != 0)
  794. {
  795. //
  796. //Release the old channel.
  797. //
  798. pTemp->lpVtbl->Release(pTemp);
  799. pTemp = 0;
  800. }
  801. }
  802. return hr;
  803. };
  804. HRESULT STDMETHODCALLTYPE
  805. CStdAsyncProxyBuffer_Connect(
  806. IN IRpcProxyBuffer * This,
  807. IN IRpcChannelBuffer * pChannel)
  808. /*++
  809. Routine Description:
  810. Connect the proxy to the channel.
  811. Arguments:
  812. pChannel - Supplies a pointer to the channel.
  813. Return Value:
  814. S_OK
  815. --*/
  816. {
  817. CStdProxyBuffer * pCThis = (CStdProxyBuffer *) This;
  818. HRESULT hr;
  819. IRpcChannelBuffer * pTemp = 0;
  820. // Get a pointer to the new channel.
  821. // Note, the async proxy is not aggregated with the channel,
  822. // It simply keeps the channel pointer.
  823. //
  824. hr = pChannel->lpVtbl->QueryInterface(
  825. pChannel, IID_IAsyncRpcChannelBuffer, (void **) &pTemp);
  826. if(hr == S_OK)
  827. {
  828. //
  829. // Save the pointer to the new channel.
  830. //
  831. pTemp = (IRpcChannelBuffer *) InterlockedExchangePointer(
  832. (PVOID *) &pCThis->pChannel, (PVOID) pTemp);
  833. if(pTemp != 0)
  834. {
  835. //
  836. //Release the old channel.
  837. //
  838. pTemp->lpVtbl->Release(pTemp);
  839. pTemp = 0;
  840. }
  841. }
  842. return hr;
  843. };
  844. HRESULT STDMETHODCALLTYPE
  845. CStdProxyBuffer2_Connect(
  846. IN IRpcProxyBuffer * This,
  847. IN IRpcChannelBuffer * pChannel)
  848. /*++
  849. Routine Description:
  850. Connect the proxy to the channel. Supports delegation.
  851. Arguments:
  852. pChannel - Supplies a pointer to the channel.
  853. Return Value:
  854. S_OK
  855. E_NOINTERFACE
  856. E_OUTOFMEMORY
  857. --*/
  858. {
  859. HRESULT hr;
  860. IRpcProxyBuffer * pBaseProxyBuffer;
  861. IRpcChannelBuffer * pWrapper;
  862. const IID * pIID;
  863. hr = CStdProxyBuffer_Connect(This, pChannel);
  864. if(SUCCEEDED(hr))
  865. {
  866. pBaseProxyBuffer = ((CStdProxyBuffer2 *)This)->pBaseProxyBuffer;
  867. if(pBaseProxyBuffer != 0)
  868. {
  869. pIID = NdrGetProxyIID(&((CStdProxyBuffer2 *)This)->pProxyVtbl);
  870. hr = CreateChannelWrapper(pIID,
  871. pChannel,
  872. &pWrapper);
  873. if(SUCCEEDED(hr))
  874. {
  875. hr = pBaseProxyBuffer->lpVtbl->Connect(pBaseProxyBuffer, pWrapper);
  876. // HACKALERT: OleAutomation returns NULL pv in CreateProxy
  877. // in cases where they don't know whether to return an NDR
  878. // proxy or a custom-format proxy. So we have to go connect
  879. // the proxy first then Query for the real interface once that
  880. // is done.
  881. if((NULL == ((CStdProxyBuffer2 *)This)->pBaseProxy) &&
  882. SUCCEEDED(hr))
  883. {
  884. IUnknown *pv;
  885. hr = pBaseProxyBuffer->lpVtbl->QueryInterface(pBaseProxyBuffer,
  886. ((CStdProxyBuffer2 *)This)->iidBase,
  887. (void **) &pv);
  888. if(SUCCEEDED(hr))
  889. {
  890. //Release our reference here.
  891. pv->lpVtbl->Release(pv);
  892. //We keep a weak reference to pv.
  893. ((CStdProxyBuffer2 *)This)->pBaseProxy = pv;
  894. }
  895. }
  896. pWrapper->lpVtbl->Release(pWrapper);
  897. }
  898. }
  899. }
  900. return hr;
  901. };
  902. HRESULT STDMETHODCALLTYPE
  903. CStdAsyncProxyBuffer2_Connect(
  904. IN IRpcProxyBuffer * This,
  905. IN IRpcChannelBuffer * pChannel)
  906. /*++
  907. Routine Description:
  908. Connect the proxy to the channel. Supports delegation.
  909. Arguments:
  910. pChannel - Supplies a pointer to the channel.
  911. Return Value:
  912. S_OK
  913. E_NOINTERFACE
  914. E_OUTOFMEMORY
  915. --*/
  916. {
  917. HRESULT hr;
  918. IRpcProxyBuffer * pBaseProxyBuffer;
  919. IRpcChannelBuffer * pWrapper;
  920. const IID * pIID;
  921. hr = CStdAsyncProxyBuffer_Connect(This, pChannel);
  922. if(SUCCEEDED(hr))
  923. {
  924. // Note that all the fields from CStdProxyBuffer2 that we indicate below
  925. // have the same offsets in CStdAsyncProxyBuffer that is being handled.
  926. // So I leave the cast unchanged to make future code merge easier.
  927. //
  928. pBaseProxyBuffer = ((CStdProxyBuffer2 *)This)->pBaseProxyBuffer;
  929. if(pBaseProxyBuffer != 0)
  930. {
  931. pIID = NdrGetProxyIID(&((CStdProxyBuffer2 *)This)->pProxyVtbl);
  932. // We need a pChannel that is guaranteed to be IAsyncRpcChannelBuffer -
  933. // but note, this is exactly what we obtained in the Connect call above.
  934. hr = CreateAsyncChannelWrapper( pIID,
  935. ((CStdProxyBuffer2*)This)->pChannel,
  936. &pWrapper);
  937. if(SUCCEEDED(hr))
  938. {
  939. hr = pBaseProxyBuffer->lpVtbl->Connect(pBaseProxyBuffer, pWrapper);
  940. // This hack alert is rather for future.
  941. // HACKALERT: OleAutomation returns NULL pv in CreateProxy
  942. // in cases where they don't know whether to return an NDR
  943. // proxy or a custom-format proxy. So we have to go connect
  944. // the proxy first then Query for the real interface once that
  945. // is done.
  946. if((NULL == ((CStdProxyBuffer2 *)This)->pBaseProxy) &&
  947. SUCCEEDED(hr))
  948. {
  949. IUnknown *pv;
  950. hr = pBaseProxyBuffer->lpVtbl->QueryInterface(pBaseProxyBuffer,
  951. ((CStdProxyBuffer2 *)This)->iidBase,
  952. (void **) &pv);
  953. if(SUCCEEDED(hr))
  954. {
  955. //Release our reference here.
  956. pv->lpVtbl->Release(pv);
  957. //We keep a weak reference to pv.
  958. ((CStdProxyBuffer2 *)This)->pBaseProxy = pv;
  959. }
  960. }
  961. pWrapper->lpVtbl->Release(pWrapper);
  962. }
  963. }
  964. }
  965. return hr;
  966. };
  967. void STDMETHODCALLTYPE
  968. CStdProxyBuffer_Disconnect(
  969. IN IRpcProxyBuffer *This)
  970. /*++
  971. Routine Description:
  972. Disconnect the proxy from the channel.
  973. Also used for:
  974. CStdAsyncProxyBuffer_Disconnect
  975. Arguments:
  976. Return Value:
  977. None.
  978. --*/
  979. {
  980. CStdProxyBuffer * pCThis = (CStdProxyBuffer *) This;
  981. IRpcChannelBuffer * pOldChannel;
  982. pOldChannel = (IRpcChannelBuffer *) InterlockedExchangePointer(
  983. (PVOID *) &pCThis->pChannel, 0);
  984. if(pOldChannel != 0)
  985. {
  986. //Release the old channel.
  987. //
  988. pOldChannel->lpVtbl->Release(pOldChannel);
  989. }
  990. };
  991. void STDMETHODCALLTYPE
  992. CStdProxyBuffer2_Disconnect(
  993. IN IRpcProxyBuffer *This)
  994. /*++
  995. Routine Description:
  996. Disconnect the proxy from the channel.
  997. Also used for:
  998. CStdAsyncProxyBuffer2_Disconnect
  999. Arguments:
  1000. Return Value:
  1001. None.
  1002. --*/
  1003. {
  1004. IRpcProxyBuffer *pBaseProxyBuffer;
  1005. CStdProxyBuffer_Disconnect(This);
  1006. pBaseProxyBuffer = ((CStdProxyBuffer2 *)This)->pBaseProxyBuffer;
  1007. if(pBaseProxyBuffer != 0)
  1008. pBaseProxyBuffer->lpVtbl->Disconnect(pBaseProxyBuffer);
  1009. };
  1010. HRESULT
  1011. NdrpCreateNonDelegatedAsyncProxy(
  1012. //CStdProxyBuffer_CreateAsyncProxy(
  1013. IN IRpcProxyBuffer *This,
  1014. IN REFIID riid, // async IID
  1015. IN IUnknown * punkOuter, // controlling unknown
  1016. OUT CStdAsyncProxyBuffer ** ppAsyncProxy
  1017. )
  1018. /*
  1019. Creates a call object, i.e. an async proxy object.
  1020. An async proxy doesn't have a pSynchronize, just passes it.
  1021. Note, because the call comes via a CStdProxyBuffer, not Buffer2,
  1022. we know that we need to create only a non-delegated async proxy.
  1023. This is because CStdProxyBuffer itself is a non-delegated proxy.
  1024. */
  1025. {
  1026. BOOL fFound;
  1027. long j; // if index
  1028. const ProxyFileInfo * pProxyFileInfo;
  1029. CStdProxyBuffer * pSyncPB = (CStdProxyBuffer *)This;
  1030. *ppAsyncProxy = 0;
  1031. if ( ! pSyncPB->pCallFactoryVtbl || !pSyncPB->pAsyncIID )
  1032. return E_NOINTERFACE;
  1033. // Check if sync and async iids match.
  1034. if ( memcmp( &riid, pSyncPB->pAsyncIID, sizeof(IID)) != 0 )
  1035. return E_NOINTERFACE;
  1036. // same file, so we can use the sync pPSFactory.
  1037. fFound = NdrpFindInterface( ((CStdPSFactoryBuffer *)pSyncPB->pPSFactory)->pProxyFileList,
  1038. riid,
  1039. &pProxyFileInfo,
  1040. & j);
  1041. if ( !fFound )
  1042. return E_NOINTERFACE;
  1043. CStdAsyncProxyBuffer *pAsyncPB =
  1044. (CStdAsyncProxyBuffer*)(*pfnCoTaskMemAlloc)(sizeof(CStdAsyncProxyBuffer));
  1045. if( ! pAsyncPB )
  1046. return E_OUTOFMEMORY;
  1047. memset( pAsyncPB, 0, sizeof(CStdAsyncProxyBuffer));
  1048. //
  1049. // Everything gets zeroed out regardless of their position
  1050. // when mapping CStdBuffer vs. CstdBuffer2 into CStdAsyncBuffer
  1051. // Non-delegated case.
  1052. pAsyncPB->lpVtbl = & CStdAsyncProxyBufferVtbl;
  1053. pAsyncPB->pProxyVtbl = & pProxyFileInfo->pProxyVtblList[j]->Vtbl;
  1054. pAsyncPB->RefCount = 1;
  1055. pAsyncPB->punkOuter = punkOuter ? punkOuter
  1056. : (IUnknown *) pAsyncPB;
  1057. pAsyncPB->pSyncIID = NdrGetProxyIID( &pSyncPB->pProxyVtbl );
  1058. // Note, no connection to channel yet.
  1059. // Actually we never call create call on the channel.
  1060. NdrpAsyncProxyMsgConstructor( pAsyncPB );
  1061. // Increment the DLL reference count for DllCanUnloadNow.
  1062. // Same dll, so we can use the sync pPSFactory.
  1063. //
  1064. pSyncPB->pPSFactory->lpVtbl->AddRef( pSyncPB->pPSFactory );
  1065. // This is in the "map".
  1066. ((CStdProxyBuffer *)pAsyncPB)->pPSFactory = pSyncPB->pPSFactory;
  1067. // Just have it in both places.
  1068. pAsyncPB->pPSFactory = pSyncPB->pPSFactory;
  1069. *ppAsyncProxy = pAsyncPB;
  1070. return S_OK;
  1071. }
  1072. HRESULT
  1073. // CStdProxyBuffer2_CreateAsyncProxy(
  1074. NdrpCreateDelegatedAsyncProxy(
  1075. IN IRpcProxyBuffer *This,
  1076. IN REFIID riid, // async IID
  1077. IN IUnknown * punkOuter, // controlling unknown
  1078. OUT CStdAsyncProxyBuffer ** ppAsyncProxy
  1079. )
  1080. /*
  1081. Creates a call object, i.e. an async proxy object.
  1082. Note, because the call comes via a CStdProxyBuffer2, not Buffer,
  1083. we know that we need to create only a delegated async proxy.
  1084. */
  1085. {
  1086. HRESULT hr;
  1087. BOOL fFound;
  1088. long j; // if index
  1089. const ProxyFileInfo * pProxyFileInfo;
  1090. CStdProxyBuffer2 * pSyncPB = (CStdProxyBuffer2 *)This;
  1091. CStdAsyncProxyBuffer *pBaseAsyncPB;
  1092. ICallFactory * pCallFactory;
  1093. *ppAsyncProxy = 0;
  1094. if ( ! pSyncPB->pCallFactoryVtbl || !pSyncPB->pAsyncIID )
  1095. return E_NOINTERFACE;
  1096. if ( memcmp( &riid, pSyncPB->pAsyncIID, sizeof(IID)) != 0 )
  1097. return E_NOINTERFACE;
  1098. // same file, so we can use the sync pPSFactory.
  1099. fFound = NdrpFindInterface( ((CStdPSFactoryBuffer *)pSyncPB->pPSFactory)->pProxyFileList,
  1100. riid,
  1101. &pProxyFileInfo,
  1102. & j);
  1103. if ( !fFound )
  1104. return E_NOINTERFACE;
  1105. // Create async proxy.
  1106. CStdAsyncProxyBuffer *pAsyncPB =
  1107. (CStdAsyncProxyBuffer*)(*pfnCoTaskMemAlloc)(sizeof(CStdAsyncProxyBuffer));
  1108. if( ! pAsyncPB )
  1109. return E_OUTOFMEMORY;
  1110. memset( pAsyncPB, 0, sizeof(CStdAsyncProxyBuffer));
  1111. //
  1112. // Everything gets zeroed out regardless of their position
  1113. // when mapping CStdBuffer vs. CstdBuffer2 into CStdAsyncBuffer
  1114. // Fill in for a delegated case.
  1115. pAsyncPB->lpVtbl = & CStdAsyncProxyBuffer2Vtbl;
  1116. pAsyncPB->pProxyVtbl = & pProxyFileInfo->pProxyVtblList[j]->Vtbl;
  1117. pAsyncPB->RefCount = 1;
  1118. pAsyncPB->punkOuter = punkOuter ? punkOuter
  1119. : (IUnknown *) pAsyncPB;
  1120. pAsyncPB->iidBase = *pProxyFileInfo->pDelegatedIIDs[j];
  1121. pAsyncPB->pPSFactory = pSyncPB->pPSFactory;
  1122. pAsyncPB->pSyncIID = NdrGetProxyIID( &pSyncPB->pProxyVtbl );
  1123. // Note, no connection to channel yet.
  1124. // So we cannot call create call on the channel.
  1125. NdrpAsyncProxyMsgConstructor( pAsyncPB );
  1126. // Create an async proxy for the base interface.
  1127. // We don't know if the base is delegated, so we have to use base call factory.
  1128. // Get the call factory from the base proxy.
  1129. hr = pSyncPB->pBaseProxyBuffer->lpVtbl->QueryInterface(
  1130. pSyncPB->pBaseProxyBuffer,
  1131. IID_ICallFactory,
  1132. (void**)& pCallFactory );
  1133. if ( SUCCEEDED(hr) )
  1134. {
  1135. const IID * pBaseAsyncIID;
  1136. pBaseAsyncIID = *(const IID **)( (uchar*)pSyncPB->pBaseProxyBuffer
  1137. + offsetof(CStdProxyBuffer, pAsyncIID));
  1138. // Aggregate the base async proxy with the current async proxy,
  1139. // not with the channel's punkOuter.
  1140. hr = pCallFactory->lpVtbl->CreateCall( pCallFactory,
  1141. *pBaseAsyncIID,
  1142. (IUnknown*) pAsyncPB,
  1143. IID_IUnknown,
  1144. (IUnknown**)& pBaseAsyncPB );
  1145. pCallFactory->lpVtbl->Release( pCallFactory );
  1146. }
  1147. if ( SUCCEEDED(hr) )
  1148. {
  1149. // Increment the DLL reference count for DllCanUnloadNow.
  1150. // Same dll, so we can use the sync pPSFactory.
  1151. //
  1152. pSyncPB->pPSFactory->lpVtbl->AddRef( pSyncPB->pPSFactory );
  1153. // Hook up the base async proxy.
  1154. pAsyncPB->pBaseProxyBuffer = (IRpcProxyBuffer*) pBaseAsyncPB;
  1155. pAsyncPB->map.pBaseProxy = (IUnknown *) & pBaseAsyncPB->pProxyVtbl;
  1156. *ppAsyncProxy = pAsyncPB;
  1157. }
  1158. else
  1159. {
  1160. (*pfnCoTaskMemFree)( pAsyncPB );
  1161. }
  1162. return hr;
  1163. }
  1164. //
  1165. // ICallFactory interface on the sync ProxyBuffer and ProxyBuffer2 objects.
  1166. //
  1167. HRESULT STDMETHODCALLTYPE
  1168. CStdProxyBuffer_CF_QueryInterface(
  1169. IN ICallFactory *This,
  1170. IN REFIID riid,
  1171. OUT void ** ppvObject)
  1172. /*++
  1173. Routine Description:
  1174. Query for an interface on the interface stub CallFactory pointer.
  1175. Arguments:
  1176. riid - Supplies the IID of the interface being requested.
  1177. ppvObject - Returns a pointer to the requested interface.
  1178. Return Value:
  1179. S_OK
  1180. E_NOINTERFACE
  1181. Note:
  1182. Works the same way for ProxyBuffer2 and AsyncProxyBuffer.
  1183. --*/
  1184. {
  1185. CStdProxyBuffer * pSyncPB = (CStdProxyBuffer *)
  1186. ((uchar *)This - offsetof(CStdProxyBuffer,pCallFactoryVtbl));
  1187. return pSyncPB->punkOuter->lpVtbl->QueryInterface( pSyncPB->punkOuter,
  1188. riid,
  1189. ppvObject );
  1190. }
  1191. ULONG STDMETHODCALLTYPE
  1192. CStdProxyBuffer_CF_AddRef(
  1193. IN ICallFactory *This)
  1194. /*++
  1195. Routine Description:
  1196. Implementation of AddRef for interface proxy.
  1197. Arguments:
  1198. Return Value:
  1199. Reference count.
  1200. --*/
  1201. {
  1202. ULONG count;
  1203. CStdProxyBuffer * pSyncPB = (CStdProxyBuffer *)
  1204. ((uchar *)This - offsetof(CStdProxyBuffer,pCallFactoryVtbl));
  1205. // It needs to go through punkOuter.
  1206. count = pSyncPB->punkOuter->lpVtbl->AddRef( pSyncPB->punkOuter );
  1207. return count;
  1208. };
  1209. ULONG STDMETHODCALLTYPE
  1210. CStdProxyBuffer_CF_Release(
  1211. IN ICallFactory *This)
  1212. /*++
  1213. Routine Description:
  1214. Implementation of Release for interface proxy.
  1215. Arguments:
  1216. Return Value:
  1217. Reference count.
  1218. --*/
  1219. {
  1220. ULONG count;
  1221. CStdProxyBuffer2 * pSyncPB = (CStdProxyBuffer2 *)
  1222. ((uchar *)This - offsetof(CStdProxyBuffer2,pCallFactoryVtbl));
  1223. count = pSyncPB->punkOuter->lpVtbl->Release( pSyncPB->punkOuter );
  1224. return count;
  1225. };
  1226. HRESULT STDMETHODCALLTYPE
  1227. CStdProxyBuffer_CF_CreateCall(
  1228. IN ICallFactory *This,
  1229. IN REFIID riid,
  1230. IN IUnknown * punkOuter, // controlling unknown
  1231. IN REFIID riid2,
  1232. OUT IUnknown ** ppv
  1233. )
  1234. /*
  1235. Creates a call object, i.e. an async proxy object.
  1236. Note, because the call comes via a CStdProxyBuffer, not Buffer2,
  1237. we know that we need to create only a non-delegated async proxy.
  1238. */
  1239. {
  1240. CStdProxyBuffer * pSyncPB;
  1241. if ( memcmp( &riid2, &IID_IUnknown, sizeof(IID)) != 0 )
  1242. return E_INVALIDARG;
  1243. pSyncPB = (CStdProxyBuffer *)
  1244. (((uchar *)This) - offsetof( CStdProxyBuffer, pCallFactoryVtbl ));
  1245. return NdrpCreateNonDelegatedAsyncProxy( (IRpcProxyBuffer*) pSyncPB,
  1246. riid,
  1247. punkOuter,
  1248. (CStdAsyncProxyBuffer**) ppv );
  1249. }
  1250. HRESULT STDMETHODCALLTYPE
  1251. CStdProxyBuffer2_CF_CreateCall(
  1252. IN ICallFactory *This,
  1253. IN REFIID riid,
  1254. IN IUnknown * punkOuter, // controlling unknown
  1255. IN REFIID riid2,
  1256. OUT IUnknown ** ppv
  1257. )
  1258. /*
  1259. Creates a call object, i.e. an async proxy object.
  1260. Note, because the virtual call comes via a CStdProxyBuffer2,
  1261. we know that we need to create only a delegated async proxy.
  1262. */
  1263. {
  1264. CStdProxyBuffer2 * pSyncPB;
  1265. if ( memcmp( &riid2, &IID_IUnknown, sizeof(IID)) != 0 )
  1266. return E_INVALIDARG;
  1267. pSyncPB = (CStdProxyBuffer2 *)
  1268. (((uchar *)This) - offsetof( CStdProxyBuffer2, pCallFactoryVtbl ));
  1269. return NdrpCreateDelegatedAsyncProxy( (IRpcProxyBuffer*) pSyncPB,
  1270. riid,
  1271. punkOuter,
  1272. (CStdAsyncProxyBuffer**) ppv );
  1273. }
  1274. /*
  1275. HRESULT STDAPICALLTYPE
  1276. NdrClientReleaseMarshalBuffer(
  1277. IN IRpcProxyBuffer *pProxy,
  1278. IN RPCOLEMESSAGE * pMsg,
  1279. IN DWORD dwFlags,
  1280. IN IUnknown *pChnl)
  1281. {
  1282. CStdProxyBuffer * pSyncPB;
  1283. void * This = NULL;
  1284. HRESULT hr;
  1285. if (NULL != pChnl)
  1286. return E_INVALIDARG;
  1287. if (dwFlags)
  1288. return E_INVALIDARG;
  1289. hr = pProxy->lpVtbl->QueryInterface(pProxy,&IID_IReleaseMarshalBuffers, &This);
  1290. if (FAILED(hr))
  1291. return E_NOTIMPL;
  1292. pSyncPB = (CStdProxyBuffer *)
  1293. (((uchar *)This) - offsetof( CStdProxyBuffer, lpVtbl ));
  1294. hr = NdrpClientReleaseMarshalBuffer(pSyncPB,(RPC_MESSAGE *)pMsg, dwFlags);
  1295. ((IRpcProxyBuffer *)This)->lpVtbl->Release(This);
  1296. return hr;
  1297. }
  1298. */
  1299. //
  1300. // IUknown Query, AddRef and Release.
  1301. //
  1302. HRESULT STDMETHODCALLTYPE
  1303. IUnknown_QueryInterface_Proxy(
  1304. IN IUnknown * This,
  1305. IN REFIID riid,
  1306. OUT void ** ppv)
  1307. /*++
  1308. Routine Description:
  1309. Implementation of QueryInterface for interface proxy.
  1310. Arguments:
  1311. riid - Supplies the IID of the requested interface.
  1312. ppv - Returns a pointer to the requested interface.
  1313. Return Value:
  1314. S_OK
  1315. E_NOINTERFACE
  1316. --*/
  1317. {
  1318. HRESULT hr = E_NOINTERFACE;
  1319. CStdProxyBuffer * pProxyBuffer;
  1320. pProxyBuffer = NdrGetProxyBuffer(This);
  1321. hr = pProxyBuffer->punkOuter->lpVtbl->QueryInterface(
  1322. pProxyBuffer->punkOuter, riid, ppv);
  1323. return hr;
  1324. };
  1325. ULONG STDMETHODCALLTYPE
  1326. IUnknown_AddRef_Proxy(
  1327. IN IUnknown *This)
  1328. /*++
  1329. Routine Description:
  1330. Implementation of AddRef for interface proxy.
  1331. Arguments:
  1332. Return Value:
  1333. Reference count.
  1334. --*/
  1335. {
  1336. CStdProxyBuffer * pProxyBuffer;
  1337. ULONG count;
  1338. pProxyBuffer = NdrGetProxyBuffer(This);
  1339. count = pProxyBuffer->punkOuter->lpVtbl->AddRef(pProxyBuffer->punkOuter);
  1340. return count;
  1341. };
  1342. ULONG STDMETHODCALLTYPE
  1343. IUnknown_Release_Proxy(
  1344. IN IUnknown *This)
  1345. /*++
  1346. Routine Description:
  1347. Implementation of Release for interface proxy.
  1348. Arguments:
  1349. Return Value:
  1350. Reference count.
  1351. --*/
  1352. {
  1353. CStdProxyBuffer * pProxyBuffer;
  1354. ULONG count;
  1355. pProxyBuffer = NdrGetProxyBuffer(This);
  1356. count = pProxyBuffer->punkOuter->lpVtbl->Release(pProxyBuffer->punkOuter);
  1357. return count;
  1358. };
  1359. void RPC_ENTRY
  1360. NdrProxyInitialize(
  1361. IN void * pThis,
  1362. IN PRPC_MESSAGE pRpcMsg,
  1363. IN PMIDL_STUB_MESSAGE pStubMsg,
  1364. IN PMIDL_STUB_DESC pStubDescriptor,
  1365. IN unsigned int ProcNum )
  1366. /*++
  1367. Routine Description:
  1368. Initialize the MIDL_STUB_MESSAGE.
  1369. Arguments:
  1370. pThis - Supplies a pointer to the interface proxy.
  1371. pRpcMsg
  1372. pStubMsg
  1373. pStubDescriptor
  1374. ProcNum
  1375. Return Value:
  1376. --*/
  1377. {
  1378. CStdProxyBuffer * pProxyBuffer;
  1379. HRESULT hr;
  1380. pProxyBuffer = NdrGetProxyBuffer(pThis);
  1381. //
  1382. // Initialize the stub message fields.
  1383. //
  1384. NdrClientInitializeNew(
  1385. pRpcMsg,
  1386. pStubMsg,
  1387. pStubDescriptor,
  1388. ProcNum );
  1389. //Note that NdrClientInitializeNew sets RPC_FLAGS_VALID_BIT in the ProcNum.
  1390. //We don't want to do this for object interfaces, so we clear the flag here.
  1391. pRpcMsg->ProcNum &= ~RPC_FLAGS_VALID_BIT;
  1392. pStubMsg->pRpcChannelBuffer = pProxyBuffer->pChannel;
  1393. //Check if we are connected to a channel.
  1394. if(pStubMsg->pRpcChannelBuffer != 0)
  1395. {
  1396. //AddRef the channel.
  1397. //We will release it later in NdrProxyFreeBuffer.
  1398. pStubMsg->pRpcChannelBuffer->lpVtbl->AddRef(pStubMsg->pRpcChannelBuffer);
  1399. //Get the destination context from the channel
  1400. hr = pStubMsg->pRpcChannelBuffer->lpVtbl->GetDestCtx(
  1401. pStubMsg->pRpcChannelBuffer, &pStubMsg->dwDestContext, &pStubMsg->pvDestContext);
  1402. }
  1403. else
  1404. {
  1405. //We are not connected to a channel.
  1406. RpcRaiseException(CO_E_OBJNOTCONNECTED);
  1407. }
  1408. }
  1409. void RPC_ENTRY
  1410. NdrProxyGetBuffer(
  1411. IN void * pThis,
  1412. IN PMIDL_STUB_MESSAGE pStubMsg)
  1413. /*++
  1414. Routine Description:
  1415. Get a message buffer from the channel
  1416. Arguments:
  1417. pThis - Supplies a pointer to the interface proxy.
  1418. pStubMsg
  1419. Return Value:
  1420. None. If an error occurs, this function will raise an exception.
  1421. --*/
  1422. {
  1423. HRESULT hr;
  1424. const IID * pIID = NdrGetProxyIID(pThis);
  1425. pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
  1426. pStubMsg->RpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
  1427. pStubMsg->dwStubPhase = PROXY_GETBUFFER;
  1428. hr = pStubMsg->pRpcChannelBuffer->lpVtbl->GetBuffer(
  1429. pStubMsg->pRpcChannelBuffer,
  1430. (RPCOLEMESSAGE *) pStubMsg->RpcMsg,
  1431. *pIID);
  1432. pStubMsg->dwStubPhase = PROXY_MARSHAL;
  1433. if(FAILED(hr))
  1434. {
  1435. RpcRaiseException(hr);
  1436. }
  1437. else
  1438. {
  1439. NDR_ASSERT( ! ((ULONG_PTR)pStubMsg->RpcMsg->Buffer & 0x7),
  1440. "marshaling buffer misaligned" );
  1441. pStubMsg->Buffer = (unsigned char *) pStubMsg->RpcMsg->Buffer;
  1442. pStubMsg->fBufferValid = TRUE;
  1443. }
  1444. }
  1445. void RPC_ENTRY
  1446. NdrProxySendReceive(
  1447. IN void * pThis,
  1448. IN MIDL_STUB_MESSAGE * pStubMsg)
  1449. /*++
  1450. Routine Description:
  1451. Send a message to server, then wait for reply message.
  1452. Arguments:
  1453. pThis - Supplies a pointer to the interface proxy.
  1454. pStubMsg
  1455. Return Value:
  1456. None. If an error occurs, this function will raise an exception.
  1457. --*/
  1458. {
  1459. HRESULT hr;
  1460. DWORD dwStatus;
  1461. //Calculate the number of bytes to send.
  1462. if ( pStubMsg->RpcMsg->BufferLength <
  1463. (uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer))
  1464. {
  1465. NDR_ASSERT( 0, "NdrProxySendReceive : buffer overflow" );
  1466. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1467. }
  1468. pStubMsg->RpcMsg->BufferLength = (ulong)( pStubMsg->Buffer -
  1469. (unsigned char *) pStubMsg->RpcMsg->Buffer );
  1470. pStubMsg->fBufferValid = FALSE;
  1471. pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
  1472. hr = pStubMsg->pRpcChannelBuffer->lpVtbl->SendReceive(
  1473. pStubMsg->pRpcChannelBuffer,
  1474. (RPCOLEMESSAGE *) pStubMsg->RpcMsg, &dwStatus);
  1475. pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
  1476. if(FAILED(hr))
  1477. {
  1478. switch(hr)
  1479. {
  1480. case RPC_E_FAULT:
  1481. RpcRaiseException(dwStatus);
  1482. break;
  1483. default:
  1484. RpcRaiseException(hr);
  1485. break;
  1486. }
  1487. }
  1488. else
  1489. {
  1490. NDR_ASSERT( ! ((ULONG_PTR)pStubMsg->RpcMsg->Buffer & 0x7),
  1491. "marshaling buffer misaligned" );
  1492. pStubMsg->Buffer = (uchar*)pStubMsg->RpcMsg->Buffer;
  1493. pStubMsg->BufferStart = pStubMsg->Buffer;
  1494. pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->RpcMsg->BufferLength;
  1495. pStubMsg->fBufferValid = TRUE;
  1496. }
  1497. }
  1498. void RPC_ENTRY
  1499. NdrProxyFreeBuffer(
  1500. IN void * pThis,
  1501. IN MIDL_STUB_MESSAGE * pStubMsg)
  1502. /*++
  1503. Routine Description:
  1504. Free the message buffer.
  1505. Arguments:
  1506. pThis - Supplies a pointer to the interface proxy.
  1507. pStubMsg
  1508. Return Value:
  1509. None.
  1510. --*/
  1511. {
  1512. if(pStubMsg->pRpcChannelBuffer != 0)
  1513. {
  1514. //Free the message buffer.
  1515. if(pStubMsg->fBufferValid == TRUE)
  1516. {
  1517. // If pipes, we need to reset the partial bit for some reason.
  1518. pStubMsg->RpcMsg->RpcFlags &= ~RPC_BUFFER_PARTIAL;
  1519. pStubMsg->pRpcChannelBuffer->lpVtbl->FreeBuffer(
  1520. pStubMsg->pRpcChannelBuffer, (RPCOLEMESSAGE *) pStubMsg->RpcMsg);
  1521. }
  1522. //Release the channel.
  1523. pStubMsg->pRpcChannelBuffer->lpVtbl->Release(pStubMsg->pRpcChannelBuffer);
  1524. pStubMsg->pRpcChannelBuffer = 0;
  1525. }
  1526. }
  1527. HRESULT RPC_ENTRY
  1528. NdrProxyErrorHandler(
  1529. IN DWORD dwExceptionCode)
  1530. /*++
  1531. Routine Description:
  1532. Maps an exception code into an HRESULT failure code.
  1533. Arguments:
  1534. dwExceptionCode
  1535. Return Value:
  1536. This function returns an HRESULT failure code.
  1537. --*/
  1538. {
  1539. HRESULT hr = dwExceptionCode;
  1540. if(FAILED((HRESULT) dwExceptionCode))
  1541. hr = (HRESULT) dwExceptionCode;
  1542. else
  1543. hr = HRESULT_FROM_WIN32(dwExceptionCode);
  1544. return hr;
  1545. }
  1546. HRESULT STDMETHODCALLTYPE
  1547. CreateChannelWrapper
  1548. /*++
  1549. Routine Description:
  1550. Creates a wrapper for the channel. The wrapper ensures
  1551. that we use the correct IID when the proxy for the base
  1552. interface calls GetBuffer.
  1553. Arguments:
  1554. pIID
  1555. pChannel
  1556. pChannelWrapper
  1557. Return Value:
  1558. S_OK
  1559. E_OUTOFMEMORY
  1560. --*/
  1561. (
  1562. const IID * pIID,
  1563. IRpcChannelBuffer * pChannel,
  1564. IRpcChannelBuffer ** ppChannelWrapper
  1565. )
  1566. {
  1567. HRESULT hr;
  1568. ChannelWrapper *pWrapper =
  1569. (ChannelWrapper*)(*pfnCoTaskMemAlloc)(sizeof(ChannelWrapper));
  1570. if(pWrapper != 0)
  1571. {
  1572. hr = S_OK;
  1573. pWrapper->lpVtbl = (IRpcChannelBufferVtbl*) &ChannelWrapperVtbl;
  1574. pWrapper->RefCount = 1;
  1575. pWrapper->pIID = pIID;
  1576. pChannel->lpVtbl->AddRef(pChannel);
  1577. pWrapper->pChannel = pChannel;
  1578. *ppChannelWrapper = (IRpcChannelBuffer *) pWrapper;
  1579. }
  1580. else
  1581. {
  1582. hr = E_OUTOFMEMORY;
  1583. *ppChannelWrapper = 0;
  1584. }
  1585. return hr;
  1586. }
  1587. HRESULT STDMETHODCALLTYPE
  1588. CreateAsyncChannelWrapper
  1589. /*++
  1590. Routine Description:
  1591. Creates a wrapper for the channel. The wrapper ensures
  1592. that we use the correct IID when the proxy for the base
  1593. interface calls GetBuffer.
  1594. Arguments:
  1595. pIID
  1596. pChannel
  1597. pChannelWrapper
  1598. Return Value:
  1599. S_OK
  1600. E_OUTOFMEMORY
  1601. --*/
  1602. (
  1603. const IID * pIID,
  1604. IRpcChannelBuffer * pChannel,
  1605. IRpcChannelBuffer ** ppChannelWrapper
  1606. )
  1607. {
  1608. HRESULT hr;
  1609. ChannelWrapper *pWrapper =
  1610. (ChannelWrapper*)(*pfnCoTaskMemAlloc)(sizeof(ChannelWrapper));
  1611. if(pWrapper != 0)
  1612. {
  1613. hr = S_OK;
  1614. pWrapper->lpVtbl = (IRpcChannelBufferVtbl*) &AsyncChannelWrapperVtbl;
  1615. pWrapper->RefCount = 1;
  1616. pWrapper->pIID = pIID;
  1617. pChannel->lpVtbl->AddRef(pChannel);
  1618. pWrapper->pChannel = pChannel;
  1619. *ppChannelWrapper = (IRpcChannelBuffer *) pWrapper;
  1620. }
  1621. else
  1622. {
  1623. hr = E_OUTOFMEMORY;
  1624. *ppChannelWrapper = 0;
  1625. }
  1626. return hr;
  1627. }
  1628. HRESULT STDMETHODCALLTYPE
  1629. ChannelWrapper_QueryInterface
  1630. /*++
  1631. Routine Description:
  1632. The channel wrapper supports the IUnknown and IRpcChannelBuffer interfaces.
  1633. Arguments:
  1634. riid
  1635. ppvObject
  1636. Return Value:
  1637. S_OK
  1638. E_NOINTERFACE
  1639. --*/
  1640. (
  1641. IRpcChannelBuffer3 * This,
  1642. REFIID riid,
  1643. void **ppvObject
  1644. )
  1645. {
  1646. HRESULT hr;
  1647. if((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  1648. (memcmp(&riid, &IID_IRpcChannelBuffer, sizeof(IID)) == 0) ||
  1649. (memcmp(&riid, &IID_IRpcChannelBuffer2, sizeof(IID)) == 0) ||
  1650. (memcmp(&riid, &IID_IRpcChannelBuffer3, sizeof(IID)) == 0))
  1651. {
  1652. hr = S_OK;
  1653. This->lpVtbl->AddRef(This);
  1654. *ppvObject = This;
  1655. }
  1656. else
  1657. {
  1658. hr = E_NOINTERFACE;
  1659. *ppvObject = 0;
  1660. }
  1661. return hr;
  1662. }
  1663. HRESULT STDMETHODCALLTYPE
  1664. AsyncChannelWrapper_QueryInterface
  1665. /*++
  1666. Routine Description:
  1667. The channel wrapper supports the IUnknown and IRpcChannelBuffer interfaces.
  1668. Arguments:
  1669. riid
  1670. ppvObject
  1671. Return Value:
  1672. S_OK
  1673. E_NOINTERFACE
  1674. --*/
  1675. (
  1676. IAsyncRpcChannelBuffer * This,
  1677. REFIID riid,
  1678. void ** ppvObject
  1679. )
  1680. {
  1681. HRESULT hr;
  1682. if((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  1683. (memcmp(&riid, &IID_IRpcChannelBuffer, sizeof(IID)) == 0) ||
  1684. (memcmp(&riid, &IID_IRpcChannelBuffer2, sizeof(IID)) == 0) ||
  1685. (memcmp(&riid, &IID_IAsyncRpcChannelBuffer, sizeof(IID)) == 0))
  1686. {
  1687. hr = S_OK;
  1688. This->lpVtbl->AddRef(This);
  1689. *ppvObject = This;
  1690. }
  1691. else
  1692. {
  1693. hr = E_NOINTERFACE;
  1694. *ppvObject = 0;
  1695. }
  1696. return hr;
  1697. }
  1698. ULONG STDMETHODCALLTYPE
  1699. ChannelWrapper_AddRef
  1700. /*++
  1701. Routine Description:
  1702. Increment reference count.
  1703. Arguments:
  1704. Return Value:
  1705. Reference count.
  1706. --*/
  1707. (
  1708. IRpcChannelBuffer3 * This
  1709. )
  1710. {
  1711. ChannelWrapper *pWrapper = (ChannelWrapper *) This;
  1712. InterlockedIncrement(&pWrapper->RefCount);
  1713. return (ULONG) pWrapper->RefCount;
  1714. }
  1715. ULONG STDMETHODCALLTYPE
  1716. AsyncChannelWrapper_AddRef(
  1717. IAsyncRpcChannelBuffer * This
  1718. )
  1719. {
  1720. return ChannelWrapper_AddRef( (IRpcChannelBuffer3 *) This );
  1721. }
  1722. ULONG STDMETHODCALLTYPE
  1723. ChannelWrapper_Release
  1724. /*++
  1725. Routine Description:
  1726. Decrement reference count.
  1727. Arguments:
  1728. Return Value:
  1729. Reference count.
  1730. --*/
  1731. (
  1732. IRpcChannelBuffer3 * This
  1733. )
  1734. {
  1735. unsigned long count;
  1736. IRpcChannelBuffer * pChannel;
  1737. NDR_ASSERT(((ChannelWrapper *)This)->RefCount > 0, "Invalid reference count");
  1738. count = (unsigned long) ((ChannelWrapper *)This)->RefCount - 1;
  1739. if(InterlockedDecrement(&((ChannelWrapper *)This)->RefCount) == 0)
  1740. {
  1741. count = 0;
  1742. pChannel = ((ChannelWrapper *)This)->pChannel;
  1743. if(pChannel != 0)
  1744. pChannel->lpVtbl->Release(pChannel);
  1745. #if DBG == 1
  1746. //In debug builds, zero fill the memory.
  1747. memset(This, '\0', sizeof(ChannelWrapper));
  1748. #endif
  1749. //Free the memory
  1750. (*pfnCoTaskMemFree)(This);
  1751. }
  1752. return count;
  1753. }
  1754. ULONG STDMETHODCALLTYPE
  1755. AsyncChannelWrapper_Release(
  1756. IAsyncRpcChannelBuffer * This
  1757. )
  1758. {
  1759. return ChannelWrapper_Release( (IRpcChannelBuffer3 *) This );
  1760. }
  1761. HRESULT STDMETHODCALLTYPE
  1762. ChannelWrapper_GetBuffer
  1763. /*++
  1764. Routine Description:
  1765. Get a message buffer from the channel.
  1766. This is the reason we have the ChannelWrapper at all.
  1767. We replace the riid of the current proxy by the one from the Wrapper.
  1768. Arguments:
  1769. pMessage
  1770. riid
  1771. Return Value:
  1772. --*/
  1773. (
  1774. IRpcChannelBuffer3 * This,
  1775. RPCOLEMESSAGE * pMessage,
  1776. REFIID riid
  1777. )
  1778. {
  1779. HRESULT hr;
  1780. IRpcChannelBuffer * pChannel;
  1781. const IID * pIID;
  1782. pChannel = ((ChannelWrapper *)This)->pChannel;
  1783. pIID = ((ChannelWrapper *)This)->pIID;
  1784. hr = pChannel->lpVtbl->GetBuffer(pChannel,
  1785. pMessage,
  1786. *pIID);
  1787. return hr;
  1788. }
  1789. HRESULT STDMETHODCALLTYPE
  1790. AsyncChannelWrapper_GetBuffer(
  1791. IAsyncRpcChannelBuffer * This,
  1792. RPCOLEMESSAGE * pMessage,
  1793. REFIID riid
  1794. )
  1795. {
  1796. return ChannelWrapper_GetBuffer( (IRpcChannelBuffer3 *) This,
  1797. pMessage,
  1798. riid );
  1799. }
  1800. HRESULT STDMETHODCALLTYPE
  1801. ChannelWrapper_SendReceive
  1802. /*++
  1803. Routine Description:
  1804. Get a message buffer from the channel
  1805. Arguments:
  1806. pMessage
  1807. pStatus
  1808. Return Value:
  1809. S_OK
  1810. --*/
  1811. (
  1812. IRpcChannelBuffer3 * This,
  1813. RPCOLEMESSAGE * pMessage,
  1814. ULONG * pStatus
  1815. )
  1816. {
  1817. HRESULT hr;
  1818. IRpcChannelBuffer * pChannel;
  1819. pChannel = ((ChannelWrapper *)This)->pChannel;
  1820. hr = pChannel->lpVtbl->SendReceive(pChannel,
  1821. pMessage,
  1822. pStatus);
  1823. return hr;
  1824. }
  1825. HRESULT STDMETHODCALLTYPE
  1826. AsyncChannelWrapper_SendReceive(
  1827. IAsyncRpcChannelBuffer * This,
  1828. RPCOLEMESSAGE * pMessage,
  1829. ULONG * pStatus
  1830. )
  1831. {
  1832. // This can never happen for an async call stub.
  1833. return E_NOTIMPL;
  1834. }
  1835. HRESULT STDMETHODCALLTYPE
  1836. ChannelWrapper_FreeBuffer
  1837. /*++
  1838. Routine Description:
  1839. Free the message buffer.
  1840. Arguments:
  1841. pMessage
  1842. Return Value:
  1843. S_OK
  1844. --*/
  1845. (
  1846. IRpcChannelBuffer3 * This,
  1847. RPCOLEMESSAGE *pMessage
  1848. )
  1849. {
  1850. HRESULT hr;
  1851. IRpcChannelBuffer * pChannel;
  1852. pChannel = ((ChannelWrapper *)This)->pChannel;
  1853. hr = pChannel->lpVtbl->FreeBuffer(pChannel,
  1854. pMessage);
  1855. return hr;
  1856. }
  1857. HRESULT STDMETHODCALLTYPE
  1858. AsyncChannelWrapper_FreeBuffer(
  1859. IAsyncRpcChannelBuffer * This,
  1860. RPCOLEMESSAGE * pMessage
  1861. )
  1862. {
  1863. return ChannelWrapper_FreeBuffer( (IRpcChannelBuffer3 *) This,
  1864. pMessage );
  1865. }
  1866. HRESULT STDMETHODCALLTYPE
  1867. ChannelWrapper_GetDestCtx
  1868. /*++
  1869. Routine Description:
  1870. Get the destination context from the channel
  1871. Arguments:
  1872. pdwDestContext
  1873. ppvDestContext
  1874. Return Value:
  1875. S_OK
  1876. --*/
  1877. (
  1878. IRpcChannelBuffer3 * This,
  1879. DWORD * pdwDestContext,
  1880. void ** ppvDestContext
  1881. )
  1882. {
  1883. HRESULT hr;
  1884. IRpcChannelBuffer * pChannel;
  1885. pChannel = ((ChannelWrapper *)This)->pChannel;
  1886. hr = pChannel->lpVtbl->GetDestCtx(pChannel,
  1887. pdwDestContext,
  1888. ppvDestContext);
  1889. return hr;
  1890. }
  1891. HRESULT STDMETHODCALLTYPE
  1892. AsyncChannelWrapper_GetDestCtx(
  1893. IAsyncRpcChannelBuffer * This,
  1894. DWORD * pdwDestContext,
  1895. void ** ppvDestContext
  1896. )
  1897. {
  1898. return ChannelWrapper_GetDestCtx( (IRpcChannelBuffer3 *) This,
  1899. pdwDestContext,
  1900. ppvDestContext );
  1901. }
  1902. HRESULT STDMETHODCALLTYPE
  1903. ChannelWrapper_IsConnected
  1904. /*++
  1905. Routine Description:
  1906. Determines if the channel is connected.
  1907. Arguments:
  1908. Return Value:
  1909. S_TRUE
  1910. S_FALSE
  1911. --*/
  1912. (
  1913. IRpcChannelBuffer3 * This
  1914. )
  1915. {
  1916. HRESULT hr;
  1917. IRpcChannelBuffer * pChannel;
  1918. pChannel = ((ChannelWrapper *)This)->pChannel;
  1919. hr = pChannel->lpVtbl->IsConnected(pChannel);
  1920. return hr;
  1921. }
  1922. HRESULT STDMETHODCALLTYPE
  1923. AsyncChannelWrapper_IsConnected(
  1924. IAsyncRpcChannelBuffer * This
  1925. )
  1926. {
  1927. return ChannelWrapper_IsConnected( (IRpcChannelBuffer3 *) This );
  1928. }
  1929. HRESULT STDMETHODCALLTYPE
  1930. ChannelWrapper_GetProtocolVersion
  1931. /*++
  1932. Routine Description:
  1933. Returns the protocol version if available.
  1934. Arguments:
  1935. Return Value:
  1936. S_OK
  1937. E_NOINTERFACE
  1938. --*/
  1939. (
  1940. IRpcChannelBuffer3 * This,
  1941. DWORD * pdwVersion
  1942. )
  1943. {
  1944. HRESULT hr;
  1945. IRpcChannelBuffer * pChannel;
  1946. IRpcChannelBuffer2 * pChannel2;
  1947. pChannel = ((ChannelWrapper *)This)->pChannel;
  1948. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer2, (void**)&pChannel2);
  1949. if (S_OK == hr)
  1950. {
  1951. hr = pChannel2->lpVtbl->GetProtocolVersion(pChannel2, pdwVersion);
  1952. pChannel2->lpVtbl->Release(pChannel2);
  1953. }
  1954. return hr;
  1955. }
  1956. HRESULT STDMETHODCALLTYPE
  1957. AsyncChannelWrapper_GetProtocolVersion(
  1958. IAsyncRpcChannelBuffer * This,
  1959. DWORD * pdwVersion
  1960. )
  1961. {
  1962. return ChannelWrapper_GetProtocolVersion( (IRpcChannelBuffer3 *) This,
  1963. pdwVersion );
  1964. }
  1965. HRESULT STDMETHODCALLTYPE
  1966. ChannelWrapper_Send
  1967. /*++
  1968. Routine Description:
  1969. Executes an asynchronous or partial send.
  1970. Arguments:
  1971. Return Value:
  1972. S_OK
  1973. E_NOINTERFACE
  1974. --*/
  1975. (
  1976. IRpcChannelBuffer3 * This,
  1977. RPCOLEMESSAGE * pMessage,
  1978. ULONG * pStatus
  1979. )
  1980. {
  1981. HRESULT hr;
  1982. IRpcChannelBuffer * pChannel;
  1983. IRpcChannelBuffer3 * pChannel3;
  1984. pChannel = ((ChannelWrapper *)This)->pChannel;
  1985. hr = pChannel->lpVtbl->QueryInterface( pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3 );
  1986. if (S_OK == hr)
  1987. {
  1988. hr = pChannel3->lpVtbl->Send(pChannel3, pMessage, pStatus);
  1989. pChannel3->lpVtbl->Release(pChannel3);
  1990. }
  1991. return hr;
  1992. }
  1993. HRESULT STDMETHODCALLTYPE
  1994. AsyncChannelWrapper_Send(
  1995. /*++
  1996. Routine Description:
  1997. Executes an asynchronous or partial send.
  1998. Arguments:
  1999. Return Value:
  2000. S_OK
  2001. E_NOINTERFACE
  2002. --*/
  2003. IAsyncRpcChannelBuffer * This,
  2004. RPCOLEMESSAGE * pMessage,
  2005. ISynchronize * pSynchronize,
  2006. ULONG * pStatus
  2007. )
  2008. {
  2009. HRESULT hr;
  2010. IRpcChannelBuffer * pChannel;
  2011. IAsyncRpcChannelBuffer * pAsChannel;
  2012. pChannel = ((ChannelWrapper *)This)->pChannel;
  2013. hr = pChannel->lpVtbl->QueryInterface( pChannel,
  2014. IID_IAsyncRpcChannelBuffer,
  2015. (void**)&pAsChannel );
  2016. if (S_OK == hr)
  2017. {
  2018. hr = pAsChannel->lpVtbl->Send( pAsChannel,
  2019. pMessage,
  2020. pSynchronize,
  2021. pStatus);
  2022. pAsChannel->lpVtbl->Release( pAsChannel);
  2023. }
  2024. return hr;
  2025. }
  2026. HRESULT STDMETHODCALLTYPE
  2027. ChannelWrapper_Receive
  2028. /*++
  2029. Routine Description:
  2030. Executes an asynchronous or partial receive.
  2031. Arguments:
  2032. Return Value:
  2033. S_OK
  2034. E_NOINTERFACE
  2035. --*/
  2036. (
  2037. IRpcChannelBuffer3 * This,
  2038. RPCOLEMESSAGE * pMessage,
  2039. ULONG ulSize,
  2040. ULONG * pStatus
  2041. )
  2042. {
  2043. HRESULT hr;
  2044. IRpcChannelBuffer * pChannel;
  2045. IRpcChannelBuffer3 * pChannel3;
  2046. pChannel = ((ChannelWrapper *)This)->pChannel;
  2047. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2048. if (S_OK == hr)
  2049. {
  2050. hr = pChannel3->lpVtbl->Receive( pChannel3, pMessage, ulSize, pStatus );
  2051. pChannel3->lpVtbl->Release(pChannel3);
  2052. }
  2053. return hr;
  2054. }
  2055. HRESULT STDMETHODCALLTYPE
  2056. AsyncChannelWrapper_Receive(
  2057. /*++
  2058. Routine Description:
  2059. Executes an asynchronous or partial receive.
  2060. Arguments:
  2061. Return Value:
  2062. S_OK
  2063. E_NOINTERFACE
  2064. --*/
  2065. IAsyncRpcChannelBuffer * This,
  2066. RPCOLEMESSAGE * pMessage,
  2067. ULONG * pStatus
  2068. )
  2069. {
  2070. HRESULT hr;
  2071. IRpcChannelBuffer * pChannel;
  2072. IAsyncRpcChannelBuffer *pAsChannel;
  2073. pChannel = ((ChannelWrapper *)This)->pChannel;
  2074. hr = pChannel->lpVtbl->QueryInterface( pChannel,
  2075. IID_IAsyncRpcChannelBuffer,
  2076. (void**)&pAsChannel);
  2077. if (S_OK == hr)
  2078. {
  2079. hr = pAsChannel->lpVtbl->Receive( pAsChannel,
  2080. pMessage,
  2081. pStatus );
  2082. pAsChannel->lpVtbl->Release(pAsChannel);
  2083. }
  2084. return hr;
  2085. }
  2086. HRESULT STDMETHODCALLTYPE
  2087. ChannelWrapper_Cancel(
  2088. /*++
  2089. Routine Description:
  2090. Executes an asynchronous Cancel.
  2091. Arguments:
  2092. Return Value:
  2093. S_OK
  2094. E_NOINTERFACE
  2095. --*/
  2096. IRpcChannelBuffer3 * This,
  2097. RPCOLEMESSAGE * pMessage
  2098. )
  2099. {
  2100. HRESULT hr;
  2101. IRpcChannelBuffer * pChannel;
  2102. IRpcChannelBuffer3 * pChannel3;
  2103. pChannel = ((ChannelWrapper *)This)->pChannel;
  2104. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2105. if (S_OK == hr)
  2106. {
  2107. hr = pChannel3->lpVtbl->Cancel( pChannel3, pMessage );
  2108. pChannel3->lpVtbl->Release(pChannel3);
  2109. }
  2110. return hr;
  2111. }
  2112. HRESULT STDMETHODCALLTYPE
  2113. ChannelWrapper_GetCallContext(
  2114. /*++
  2115. Routine Description:
  2116. Gets an asynchronous call context.
  2117. Arguments:
  2118. Return Value:
  2119. S_OK
  2120. E_NOINTERFACE
  2121. --*/
  2122. IRpcChannelBuffer3 * This,
  2123. RPCOLEMESSAGE * pMessage,
  2124. REFIID riid,
  2125. void ** ppInterface
  2126. )
  2127. {
  2128. HRESULT hr;
  2129. IRpcChannelBuffer * pChannel;
  2130. IRpcChannelBuffer3 * pChannel3;
  2131. pChannel = ((ChannelWrapper *)This)->pChannel;
  2132. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2133. if (S_OK == hr)
  2134. {
  2135. hr = pChannel3->lpVtbl->GetCallContext( pChannel3, pMessage, riid, ppInterface );
  2136. pChannel3->lpVtbl->Release(pChannel3);
  2137. }
  2138. return hr;
  2139. }
  2140. HRESULT STDMETHODCALLTYPE
  2141. AsyncChannelWrapper_GetDestCtxEx(
  2142. /*++
  2143. Routine Description:
  2144. Gets an asynchronous call context.
  2145. Arguments:
  2146. Return Value:
  2147. S_OK
  2148. E_NOINTERFACE
  2149. --*/
  2150. IAsyncRpcChannelBuffer * This,
  2151. RPCOLEMESSAGE * pMessage,
  2152. DWORD * pdw,
  2153. void ** ppv
  2154. )
  2155. {
  2156. HRESULT hr;
  2157. IRpcChannelBuffer * pChannel;
  2158. IAsyncRpcChannelBuffer * pAsChannel;
  2159. pChannel = ((ChannelWrapper *)This)->pChannel;
  2160. hr = pChannel->lpVtbl->QueryInterface( pChannel,
  2161. IID_IAsyncRpcChannelBuffer,
  2162. (void**)&pAsChannel);
  2163. if (S_OK == hr)
  2164. {
  2165. hr = pAsChannel->lpVtbl->GetDestCtxEx( pAsChannel,
  2166. pMessage,
  2167. pdw,
  2168. ppv );
  2169. pAsChannel->lpVtbl->Release(pAsChannel);
  2170. }
  2171. return hr;
  2172. }
  2173. HRESULT STDMETHODCALLTYPE
  2174. ChannelWrapper_GetDestCtxEx(
  2175. /*++
  2176. Routine Description:
  2177. Gets the new destination context.
  2178. Arguments:
  2179. Return Value:
  2180. S_OK
  2181. E_NOINTERFACE
  2182. --*/
  2183. IRpcChannelBuffer3 * This,
  2184. RPCOLEMESSAGE * pMessage,
  2185. DWORD * pdwDestContext,
  2186. void ** ppvDestContext
  2187. )
  2188. {
  2189. HRESULT hr;
  2190. IRpcChannelBuffer * pChannel;
  2191. IRpcChannelBuffer3 * pChannel3;
  2192. pChannel = ((ChannelWrapper *)This)->pChannel;
  2193. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2194. if (S_OK == hr)
  2195. {
  2196. hr = pChannel3->lpVtbl->GetDestCtxEx( pChannel3, pMessage, pdwDestContext, ppvDestContext );
  2197. pChannel3->lpVtbl->Release(pChannel3);
  2198. }
  2199. return hr;
  2200. }
  2201. HRESULT STDMETHODCALLTYPE
  2202. ChannelWrapper_GetState(
  2203. /*++
  2204. Routine Description:
  2205. Gets the call state.
  2206. Arguments:
  2207. Return Value:
  2208. S_OK
  2209. E_NOINTERFACE
  2210. --*/
  2211. IRpcChannelBuffer3 * This,
  2212. RPCOLEMESSAGE * pMessage,
  2213. DWORD * pState
  2214. )
  2215. {
  2216. HRESULT hr;
  2217. IRpcChannelBuffer * pChannel;
  2218. IRpcChannelBuffer3 * pChannel3;
  2219. pChannel = ((ChannelWrapper *)This)->pChannel;
  2220. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2221. if (S_OK == hr)
  2222. {
  2223. hr = pChannel3->lpVtbl->GetState( pChannel3, pMessage, pState );
  2224. pChannel3->lpVtbl->Release(pChannel3);
  2225. }
  2226. return hr;
  2227. }
  2228. HRESULT STDMETHODCALLTYPE
  2229. ChannelWrapper_RegisterAsync(
  2230. /*++
  2231. Routine Description:
  2232. Registers the async manager object and call with the channel.
  2233. Arguments:
  2234. Return Value:
  2235. S_OK
  2236. E_NOINTERFACE
  2237. --*/
  2238. IRpcChannelBuffer3 * This,
  2239. RPCOLEMESSAGE * pMessage,
  2240. IAsyncManager * pAsyncMgr
  2241. )
  2242. {
  2243. HRESULT hr;
  2244. IRpcChannelBuffer * pChannel;
  2245. IRpcChannelBuffer3 * pChannel3;
  2246. pChannel = ((ChannelWrapper *)This)->pChannel;
  2247. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2248. if (S_OK == hr)
  2249. {
  2250. hr = pChannel3->lpVtbl->RegisterAsync( pChannel3, pMessage, pAsyncMgr );
  2251. pChannel3->lpVtbl->Release(pChannel3);
  2252. }
  2253. return hr;
  2254. }