Leaked source code of windows server 2003
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.

2888 lines
70 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. LENGTH_ALIGN(pStubMsg->BufferLength, 3);
  1426. pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
  1427. pStubMsg->RpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
  1428. pStubMsg->dwStubPhase = PROXY_GETBUFFER;
  1429. hr = pStubMsg->pRpcChannelBuffer->lpVtbl->GetBuffer(
  1430. pStubMsg->pRpcChannelBuffer,
  1431. (RPCOLEMESSAGE *) pStubMsg->RpcMsg,
  1432. *pIID);
  1433. pStubMsg->dwStubPhase = PROXY_MARSHAL;
  1434. if(FAILED(hr))
  1435. {
  1436. RpcRaiseException(hr);
  1437. }
  1438. else
  1439. {
  1440. NDR_ASSERT( ! ((ULONG_PTR)pStubMsg->RpcMsg->Buffer & 0x7),
  1441. "marshaling buffer misaligned" );
  1442. pStubMsg->Buffer = (unsigned char *) pStubMsg->RpcMsg->Buffer;
  1443. pStubMsg->fBufferValid = TRUE;
  1444. }
  1445. }
  1446. void RPC_ENTRY
  1447. NdrProxySendReceive(
  1448. IN void * pThis,
  1449. IN MIDL_STUB_MESSAGE * pStubMsg)
  1450. /*++
  1451. Routine Description:
  1452. Send a message to server, then wait for reply message.
  1453. Arguments:
  1454. pThis - Supplies a pointer to the interface proxy.
  1455. pStubMsg
  1456. Return Value:
  1457. None. If an error occurs, this function will raise an exception.
  1458. --*/
  1459. {
  1460. HRESULT hr;
  1461. DWORD dwStatus;
  1462. //Calculate the number of bytes to send.
  1463. if ( pStubMsg->RpcMsg->BufferLength <
  1464. (uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer))
  1465. {
  1466. NDR_ASSERT( 0, "NdrProxySendReceive : buffer overflow" );
  1467. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1468. }
  1469. pStubMsg->RpcMsg->BufferLength = (ulong)( pStubMsg->Buffer -
  1470. (unsigned char *) pStubMsg->RpcMsg->Buffer );
  1471. pStubMsg->fBufferValid = FALSE;
  1472. pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
  1473. hr = pStubMsg->pRpcChannelBuffer->lpVtbl->SendReceive(
  1474. pStubMsg->pRpcChannelBuffer,
  1475. (RPCOLEMESSAGE *) pStubMsg->RpcMsg, &dwStatus);
  1476. pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
  1477. if(FAILED(hr))
  1478. {
  1479. switch(hr)
  1480. {
  1481. case RPC_E_FAULT:
  1482. RpcRaiseException(dwStatus);
  1483. break;
  1484. default:
  1485. RpcRaiseException(hr);
  1486. break;
  1487. }
  1488. }
  1489. else
  1490. {
  1491. NDR_ASSERT( ! ((ULONG_PTR)pStubMsg->RpcMsg->Buffer & 0x7),
  1492. "marshaling buffer misaligned" );
  1493. pStubMsg->Buffer = (uchar*)pStubMsg->RpcMsg->Buffer;
  1494. pStubMsg->BufferStart = pStubMsg->Buffer;
  1495. pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->RpcMsg->BufferLength;
  1496. pStubMsg->fBufferValid = TRUE;
  1497. }
  1498. }
  1499. void RPC_ENTRY
  1500. NdrProxyFreeBuffer(
  1501. IN void * pThis,
  1502. IN MIDL_STUB_MESSAGE * pStubMsg)
  1503. /*++
  1504. Routine Description:
  1505. Free the message buffer.
  1506. Arguments:
  1507. pThis - Supplies a pointer to the interface proxy.
  1508. pStubMsg
  1509. Return Value:
  1510. None.
  1511. --*/
  1512. {
  1513. if(pStubMsg->pRpcChannelBuffer != 0)
  1514. {
  1515. //Free the message buffer.
  1516. if(pStubMsg->fBufferValid == TRUE)
  1517. {
  1518. // If pipes, we need to reset the partial bit for some reason.
  1519. pStubMsg->RpcMsg->RpcFlags &= ~RPC_BUFFER_PARTIAL;
  1520. pStubMsg->pRpcChannelBuffer->lpVtbl->FreeBuffer(
  1521. pStubMsg->pRpcChannelBuffer, (RPCOLEMESSAGE *) pStubMsg->RpcMsg);
  1522. }
  1523. //Release the channel.
  1524. pStubMsg->pRpcChannelBuffer->lpVtbl->Release(pStubMsg->pRpcChannelBuffer);
  1525. pStubMsg->pRpcChannelBuffer = 0;
  1526. }
  1527. }
  1528. HRESULT RPC_ENTRY
  1529. NdrProxyErrorHandler(
  1530. IN DWORD dwExceptionCode)
  1531. /*++
  1532. Routine Description:
  1533. Maps an exception code into an HRESULT failure code.
  1534. Arguments:
  1535. dwExceptionCode
  1536. Return Value:
  1537. This function returns an HRESULT failure code.
  1538. --*/
  1539. {
  1540. HRESULT hr = dwExceptionCode;
  1541. if(FAILED((HRESULT) dwExceptionCode))
  1542. hr = (HRESULT) dwExceptionCode;
  1543. else
  1544. hr = HRESULT_FROM_WIN32(dwExceptionCode);
  1545. return hr;
  1546. }
  1547. HRESULT STDMETHODCALLTYPE
  1548. CreateChannelWrapper
  1549. /*++
  1550. Routine Description:
  1551. Creates a wrapper for the channel. The wrapper ensures
  1552. that we use the correct IID when the proxy for the base
  1553. interface calls GetBuffer.
  1554. Arguments:
  1555. pIID
  1556. pChannel
  1557. pChannelWrapper
  1558. Return Value:
  1559. S_OK
  1560. E_OUTOFMEMORY
  1561. --*/
  1562. (
  1563. const IID * pIID,
  1564. IRpcChannelBuffer * pChannel,
  1565. IRpcChannelBuffer ** ppChannelWrapper
  1566. )
  1567. {
  1568. HRESULT hr;
  1569. ChannelWrapper *pWrapper =
  1570. (ChannelWrapper*)(*pfnCoTaskMemAlloc)(sizeof(ChannelWrapper));
  1571. if(pWrapper != 0)
  1572. {
  1573. hr = S_OK;
  1574. pWrapper->lpVtbl = (IRpcChannelBufferVtbl*) &ChannelWrapperVtbl;
  1575. pWrapper->RefCount = 1;
  1576. pWrapper->pIID = pIID;
  1577. pChannel->lpVtbl->AddRef(pChannel);
  1578. pWrapper->pChannel = pChannel;
  1579. *ppChannelWrapper = (IRpcChannelBuffer *) pWrapper;
  1580. }
  1581. else
  1582. {
  1583. hr = E_OUTOFMEMORY;
  1584. *ppChannelWrapper = 0;
  1585. }
  1586. return hr;
  1587. }
  1588. HRESULT STDMETHODCALLTYPE
  1589. CreateAsyncChannelWrapper
  1590. /*++
  1591. Routine Description:
  1592. Creates a wrapper for the channel. The wrapper ensures
  1593. that we use the correct IID when the proxy for the base
  1594. interface calls GetBuffer.
  1595. Arguments:
  1596. pIID
  1597. pChannel
  1598. pChannelWrapper
  1599. Return Value:
  1600. S_OK
  1601. E_OUTOFMEMORY
  1602. --*/
  1603. (
  1604. const IID * pIID,
  1605. IRpcChannelBuffer * pChannel,
  1606. IRpcChannelBuffer ** ppChannelWrapper
  1607. )
  1608. {
  1609. HRESULT hr;
  1610. ChannelWrapper *pWrapper =
  1611. (ChannelWrapper*)(*pfnCoTaskMemAlloc)(sizeof(ChannelWrapper));
  1612. if(pWrapper != 0)
  1613. {
  1614. hr = S_OK;
  1615. pWrapper->lpVtbl = (IRpcChannelBufferVtbl*) &AsyncChannelWrapperVtbl;
  1616. pWrapper->RefCount = 1;
  1617. pWrapper->pIID = pIID;
  1618. pChannel->lpVtbl->AddRef(pChannel);
  1619. pWrapper->pChannel = pChannel;
  1620. *ppChannelWrapper = (IRpcChannelBuffer *) pWrapper;
  1621. }
  1622. else
  1623. {
  1624. hr = E_OUTOFMEMORY;
  1625. *ppChannelWrapper = 0;
  1626. }
  1627. return hr;
  1628. }
  1629. HRESULT STDMETHODCALLTYPE
  1630. ChannelWrapper_QueryInterface
  1631. /*++
  1632. Routine Description:
  1633. The channel wrapper supports the IUnknown and IRpcChannelBuffer interfaces.
  1634. Arguments:
  1635. riid
  1636. ppvObject
  1637. Return Value:
  1638. S_OK
  1639. E_NOINTERFACE
  1640. --*/
  1641. (
  1642. IRpcChannelBuffer3 * This,
  1643. REFIID riid,
  1644. void **ppvObject
  1645. )
  1646. {
  1647. HRESULT hr;
  1648. if((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  1649. (memcmp(&riid, &IID_IRpcChannelBuffer, sizeof(IID)) == 0) ||
  1650. (memcmp(&riid, &IID_IRpcChannelBuffer2, sizeof(IID)) == 0) ||
  1651. (memcmp(&riid, &IID_IRpcChannelBuffer3, sizeof(IID)) == 0))
  1652. {
  1653. hr = S_OK;
  1654. This->lpVtbl->AddRef(This);
  1655. *ppvObject = This;
  1656. }
  1657. else
  1658. {
  1659. hr = E_NOINTERFACE;
  1660. *ppvObject = 0;
  1661. }
  1662. return hr;
  1663. }
  1664. HRESULT STDMETHODCALLTYPE
  1665. AsyncChannelWrapper_QueryInterface
  1666. /*++
  1667. Routine Description:
  1668. The channel wrapper supports the IUnknown and IRpcChannelBuffer interfaces.
  1669. Arguments:
  1670. riid
  1671. ppvObject
  1672. Return Value:
  1673. S_OK
  1674. E_NOINTERFACE
  1675. --*/
  1676. (
  1677. IAsyncRpcChannelBuffer * This,
  1678. REFIID riid,
  1679. void ** ppvObject
  1680. )
  1681. {
  1682. HRESULT hr;
  1683. if((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  1684. (memcmp(&riid, &IID_IRpcChannelBuffer, sizeof(IID)) == 0) ||
  1685. (memcmp(&riid, &IID_IRpcChannelBuffer2, sizeof(IID)) == 0) ||
  1686. (memcmp(&riid, &IID_IAsyncRpcChannelBuffer, sizeof(IID)) == 0))
  1687. {
  1688. hr = S_OK;
  1689. This->lpVtbl->AddRef(This);
  1690. *ppvObject = This;
  1691. }
  1692. else
  1693. {
  1694. hr = E_NOINTERFACE;
  1695. *ppvObject = 0;
  1696. }
  1697. return hr;
  1698. }
  1699. ULONG STDMETHODCALLTYPE
  1700. ChannelWrapper_AddRef
  1701. /*++
  1702. Routine Description:
  1703. Increment reference count.
  1704. Arguments:
  1705. Return Value:
  1706. Reference count.
  1707. --*/
  1708. (
  1709. IRpcChannelBuffer3 * This
  1710. )
  1711. {
  1712. ChannelWrapper *pWrapper = (ChannelWrapper *) This;
  1713. InterlockedIncrement(&pWrapper->RefCount);
  1714. return (ULONG) pWrapper->RefCount;
  1715. }
  1716. ULONG STDMETHODCALLTYPE
  1717. AsyncChannelWrapper_AddRef(
  1718. IAsyncRpcChannelBuffer * This
  1719. )
  1720. {
  1721. return ChannelWrapper_AddRef( (IRpcChannelBuffer3 *) This );
  1722. }
  1723. ULONG STDMETHODCALLTYPE
  1724. ChannelWrapper_Release
  1725. /*++
  1726. Routine Description:
  1727. Decrement reference count.
  1728. Arguments:
  1729. Return Value:
  1730. Reference count.
  1731. --*/
  1732. (
  1733. IRpcChannelBuffer3 * This
  1734. )
  1735. {
  1736. unsigned long count;
  1737. IRpcChannelBuffer * pChannel;
  1738. NDR_ASSERT(((ChannelWrapper *)This)->RefCount > 0, "Invalid reference count");
  1739. count = (unsigned long) ((ChannelWrapper *)This)->RefCount - 1;
  1740. if(InterlockedDecrement(&((ChannelWrapper *)This)->RefCount) == 0)
  1741. {
  1742. count = 0;
  1743. pChannel = ((ChannelWrapper *)This)->pChannel;
  1744. if(pChannel != 0)
  1745. pChannel->lpVtbl->Release(pChannel);
  1746. #if DBG == 1
  1747. //In debug builds, zero fill the memory.
  1748. memset(This, '\0', sizeof(ChannelWrapper));
  1749. #endif
  1750. //Free the memory
  1751. (*pfnCoTaskMemFree)(This);
  1752. }
  1753. return count;
  1754. }
  1755. ULONG STDMETHODCALLTYPE
  1756. AsyncChannelWrapper_Release(
  1757. IAsyncRpcChannelBuffer * This
  1758. )
  1759. {
  1760. return ChannelWrapper_Release( (IRpcChannelBuffer3 *) This );
  1761. }
  1762. HRESULT STDMETHODCALLTYPE
  1763. ChannelWrapper_GetBuffer
  1764. /*++
  1765. Routine Description:
  1766. Get a message buffer from the channel.
  1767. This is the reason we have the ChannelWrapper at all.
  1768. We replace the riid of the current proxy by the one from the Wrapper.
  1769. Arguments:
  1770. pMessage
  1771. riid
  1772. Return Value:
  1773. --*/
  1774. (
  1775. IRpcChannelBuffer3 * This,
  1776. RPCOLEMESSAGE * pMessage,
  1777. REFIID riid
  1778. )
  1779. {
  1780. HRESULT hr;
  1781. IRpcChannelBuffer * pChannel;
  1782. const IID * pIID;
  1783. pChannel = ((ChannelWrapper *)This)->pChannel;
  1784. pIID = ((ChannelWrapper *)This)->pIID;
  1785. hr = pChannel->lpVtbl->GetBuffer(pChannel,
  1786. pMessage,
  1787. *pIID);
  1788. return hr;
  1789. }
  1790. HRESULT STDMETHODCALLTYPE
  1791. AsyncChannelWrapper_GetBuffer(
  1792. IAsyncRpcChannelBuffer * This,
  1793. RPCOLEMESSAGE * pMessage,
  1794. REFIID riid
  1795. )
  1796. {
  1797. return ChannelWrapper_GetBuffer( (IRpcChannelBuffer3 *) This,
  1798. pMessage,
  1799. riid );
  1800. }
  1801. HRESULT STDMETHODCALLTYPE
  1802. ChannelWrapper_SendReceive
  1803. /*++
  1804. Routine Description:
  1805. Get a message buffer from the channel
  1806. Arguments:
  1807. pMessage
  1808. pStatus
  1809. Return Value:
  1810. S_OK
  1811. --*/
  1812. (
  1813. IRpcChannelBuffer3 * This,
  1814. RPCOLEMESSAGE * pMessage,
  1815. ULONG * pStatus
  1816. )
  1817. {
  1818. HRESULT hr;
  1819. IRpcChannelBuffer * pChannel;
  1820. pChannel = ((ChannelWrapper *)This)->pChannel;
  1821. hr = pChannel->lpVtbl->SendReceive(pChannel,
  1822. pMessage,
  1823. pStatus);
  1824. return hr;
  1825. }
  1826. HRESULT STDMETHODCALLTYPE
  1827. AsyncChannelWrapper_SendReceive(
  1828. IAsyncRpcChannelBuffer * This,
  1829. RPCOLEMESSAGE * pMessage,
  1830. ULONG * pStatus
  1831. )
  1832. {
  1833. // This can never happen for an async call stub.
  1834. return E_NOTIMPL;
  1835. }
  1836. HRESULT STDMETHODCALLTYPE
  1837. ChannelWrapper_FreeBuffer
  1838. /*++
  1839. Routine Description:
  1840. Free the message buffer.
  1841. Arguments:
  1842. pMessage
  1843. Return Value:
  1844. S_OK
  1845. --*/
  1846. (
  1847. IRpcChannelBuffer3 * This,
  1848. RPCOLEMESSAGE *pMessage
  1849. )
  1850. {
  1851. HRESULT hr;
  1852. IRpcChannelBuffer * pChannel;
  1853. pChannel = ((ChannelWrapper *)This)->pChannel;
  1854. hr = pChannel->lpVtbl->FreeBuffer(pChannel,
  1855. pMessage);
  1856. return hr;
  1857. }
  1858. HRESULT STDMETHODCALLTYPE
  1859. AsyncChannelWrapper_FreeBuffer(
  1860. IAsyncRpcChannelBuffer * This,
  1861. RPCOLEMESSAGE * pMessage
  1862. )
  1863. {
  1864. return ChannelWrapper_FreeBuffer( (IRpcChannelBuffer3 *) This,
  1865. pMessage );
  1866. }
  1867. HRESULT STDMETHODCALLTYPE
  1868. ChannelWrapper_GetDestCtx
  1869. /*++
  1870. Routine Description:
  1871. Get the destination context from the channel
  1872. Arguments:
  1873. pdwDestContext
  1874. ppvDestContext
  1875. Return Value:
  1876. S_OK
  1877. --*/
  1878. (
  1879. IRpcChannelBuffer3 * This,
  1880. DWORD * pdwDestContext,
  1881. void ** ppvDestContext
  1882. )
  1883. {
  1884. HRESULT hr;
  1885. IRpcChannelBuffer * pChannel;
  1886. pChannel = ((ChannelWrapper *)This)->pChannel;
  1887. hr = pChannel->lpVtbl->GetDestCtx(pChannel,
  1888. pdwDestContext,
  1889. ppvDestContext);
  1890. return hr;
  1891. }
  1892. HRESULT STDMETHODCALLTYPE
  1893. AsyncChannelWrapper_GetDestCtx(
  1894. IAsyncRpcChannelBuffer * This,
  1895. DWORD * pdwDestContext,
  1896. void ** ppvDestContext
  1897. )
  1898. {
  1899. return ChannelWrapper_GetDestCtx( (IRpcChannelBuffer3 *) This,
  1900. pdwDestContext,
  1901. ppvDestContext );
  1902. }
  1903. HRESULT STDMETHODCALLTYPE
  1904. ChannelWrapper_IsConnected
  1905. /*++
  1906. Routine Description:
  1907. Determines if the channel is connected.
  1908. Arguments:
  1909. Return Value:
  1910. S_TRUE
  1911. S_FALSE
  1912. --*/
  1913. (
  1914. IRpcChannelBuffer3 * This
  1915. )
  1916. {
  1917. HRESULT hr;
  1918. IRpcChannelBuffer * pChannel;
  1919. pChannel = ((ChannelWrapper *)This)->pChannel;
  1920. hr = pChannel->lpVtbl->IsConnected(pChannel);
  1921. return hr;
  1922. }
  1923. HRESULT STDMETHODCALLTYPE
  1924. AsyncChannelWrapper_IsConnected(
  1925. IAsyncRpcChannelBuffer * This
  1926. )
  1927. {
  1928. return ChannelWrapper_IsConnected( (IRpcChannelBuffer3 *) This );
  1929. }
  1930. HRESULT STDMETHODCALLTYPE
  1931. ChannelWrapper_GetProtocolVersion
  1932. /*++
  1933. Routine Description:
  1934. Returns the protocol version if available.
  1935. Arguments:
  1936. Return Value:
  1937. S_OK
  1938. E_NOINTERFACE
  1939. --*/
  1940. (
  1941. IRpcChannelBuffer3 * This,
  1942. DWORD * pdwVersion
  1943. )
  1944. {
  1945. HRESULT hr;
  1946. IRpcChannelBuffer * pChannel;
  1947. IRpcChannelBuffer2 * pChannel2;
  1948. pChannel = ((ChannelWrapper *)This)->pChannel;
  1949. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer2, (void**)&pChannel2);
  1950. if (S_OK == hr)
  1951. {
  1952. hr = pChannel2->lpVtbl->GetProtocolVersion(pChannel2, pdwVersion);
  1953. pChannel2->lpVtbl->Release(pChannel2);
  1954. }
  1955. return hr;
  1956. }
  1957. HRESULT STDMETHODCALLTYPE
  1958. AsyncChannelWrapper_GetProtocolVersion(
  1959. IAsyncRpcChannelBuffer * This,
  1960. DWORD * pdwVersion
  1961. )
  1962. {
  1963. return ChannelWrapper_GetProtocolVersion( (IRpcChannelBuffer3 *) This,
  1964. pdwVersion );
  1965. }
  1966. HRESULT STDMETHODCALLTYPE
  1967. ChannelWrapper_Send
  1968. /*++
  1969. Routine Description:
  1970. Executes an asynchronous or partial send.
  1971. Arguments:
  1972. Return Value:
  1973. S_OK
  1974. E_NOINTERFACE
  1975. --*/
  1976. (
  1977. IRpcChannelBuffer3 * This,
  1978. RPCOLEMESSAGE * pMessage,
  1979. ULONG * pStatus
  1980. )
  1981. {
  1982. HRESULT hr;
  1983. IRpcChannelBuffer * pChannel;
  1984. IRpcChannelBuffer3 * pChannel3;
  1985. pChannel = ((ChannelWrapper *)This)->pChannel;
  1986. hr = pChannel->lpVtbl->QueryInterface( pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3 );
  1987. if (S_OK == hr)
  1988. {
  1989. hr = pChannel3->lpVtbl->Send(pChannel3, pMessage, pStatus);
  1990. pChannel3->lpVtbl->Release(pChannel3);
  1991. }
  1992. return hr;
  1993. }
  1994. HRESULT STDMETHODCALLTYPE
  1995. AsyncChannelWrapper_Send(
  1996. /*++
  1997. Routine Description:
  1998. Executes an asynchronous or partial send.
  1999. Arguments:
  2000. Return Value:
  2001. S_OK
  2002. E_NOINTERFACE
  2003. --*/
  2004. IAsyncRpcChannelBuffer * This,
  2005. RPCOLEMESSAGE * pMessage,
  2006. ISynchronize * pSynchronize,
  2007. ULONG * pStatus
  2008. )
  2009. {
  2010. HRESULT hr;
  2011. IRpcChannelBuffer * pChannel;
  2012. IAsyncRpcChannelBuffer * pAsChannel;
  2013. pChannel = ((ChannelWrapper *)This)->pChannel;
  2014. hr = pChannel->lpVtbl->QueryInterface( pChannel,
  2015. IID_IAsyncRpcChannelBuffer,
  2016. (void**)&pAsChannel );
  2017. if (S_OK == hr)
  2018. {
  2019. hr = pAsChannel->lpVtbl->Send( pAsChannel,
  2020. pMessage,
  2021. pSynchronize,
  2022. pStatus);
  2023. pAsChannel->lpVtbl->Release( pAsChannel);
  2024. }
  2025. return hr;
  2026. }
  2027. HRESULT STDMETHODCALLTYPE
  2028. ChannelWrapper_Receive
  2029. /*++
  2030. Routine Description:
  2031. Executes an asynchronous or partial receive.
  2032. Arguments:
  2033. Return Value:
  2034. S_OK
  2035. E_NOINTERFACE
  2036. --*/
  2037. (
  2038. IRpcChannelBuffer3 * This,
  2039. RPCOLEMESSAGE * pMessage,
  2040. ULONG ulSize,
  2041. ULONG * pStatus
  2042. )
  2043. {
  2044. HRESULT hr;
  2045. IRpcChannelBuffer * pChannel;
  2046. IRpcChannelBuffer3 * pChannel3;
  2047. pChannel = ((ChannelWrapper *)This)->pChannel;
  2048. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2049. if (S_OK == hr)
  2050. {
  2051. hr = pChannel3->lpVtbl->Receive( pChannel3, pMessage, ulSize, pStatus );
  2052. pChannel3->lpVtbl->Release(pChannel3);
  2053. }
  2054. return hr;
  2055. }
  2056. HRESULT STDMETHODCALLTYPE
  2057. AsyncChannelWrapper_Receive(
  2058. /*++
  2059. Routine Description:
  2060. Executes an asynchronous or partial receive.
  2061. Arguments:
  2062. Return Value:
  2063. S_OK
  2064. E_NOINTERFACE
  2065. --*/
  2066. IAsyncRpcChannelBuffer * This,
  2067. RPCOLEMESSAGE * pMessage,
  2068. ULONG * pStatus
  2069. )
  2070. {
  2071. HRESULT hr;
  2072. IRpcChannelBuffer * pChannel;
  2073. IAsyncRpcChannelBuffer *pAsChannel;
  2074. pChannel = ((ChannelWrapper *)This)->pChannel;
  2075. hr = pChannel->lpVtbl->QueryInterface( pChannel,
  2076. IID_IAsyncRpcChannelBuffer,
  2077. (void**)&pAsChannel);
  2078. if (S_OK == hr)
  2079. {
  2080. hr = pAsChannel->lpVtbl->Receive( pAsChannel,
  2081. pMessage,
  2082. pStatus );
  2083. pAsChannel->lpVtbl->Release(pAsChannel);
  2084. }
  2085. return hr;
  2086. }
  2087. HRESULT STDMETHODCALLTYPE
  2088. ChannelWrapper_Cancel(
  2089. /*++
  2090. Routine Description:
  2091. Executes an asynchronous Cancel.
  2092. Arguments:
  2093. Return Value:
  2094. S_OK
  2095. E_NOINTERFACE
  2096. --*/
  2097. IRpcChannelBuffer3 * This,
  2098. RPCOLEMESSAGE * pMessage
  2099. )
  2100. {
  2101. HRESULT hr;
  2102. IRpcChannelBuffer * pChannel;
  2103. IRpcChannelBuffer3 * pChannel3;
  2104. pChannel = ((ChannelWrapper *)This)->pChannel;
  2105. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2106. if (S_OK == hr)
  2107. {
  2108. hr = pChannel3->lpVtbl->Cancel( pChannel3, pMessage );
  2109. pChannel3->lpVtbl->Release(pChannel3);
  2110. }
  2111. return hr;
  2112. }
  2113. HRESULT STDMETHODCALLTYPE
  2114. ChannelWrapper_GetCallContext(
  2115. /*++
  2116. Routine Description:
  2117. Gets an asynchronous call context.
  2118. Arguments:
  2119. Return Value:
  2120. S_OK
  2121. E_NOINTERFACE
  2122. --*/
  2123. IRpcChannelBuffer3 * This,
  2124. RPCOLEMESSAGE * pMessage,
  2125. REFIID riid,
  2126. void ** ppInterface
  2127. )
  2128. {
  2129. HRESULT hr;
  2130. IRpcChannelBuffer * pChannel;
  2131. IRpcChannelBuffer3 * pChannel3;
  2132. pChannel = ((ChannelWrapper *)This)->pChannel;
  2133. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2134. if (S_OK == hr)
  2135. {
  2136. hr = pChannel3->lpVtbl->GetCallContext( pChannel3, pMessage, riid, ppInterface );
  2137. pChannel3->lpVtbl->Release(pChannel3);
  2138. }
  2139. return hr;
  2140. }
  2141. HRESULT STDMETHODCALLTYPE
  2142. AsyncChannelWrapper_GetDestCtxEx(
  2143. /*++
  2144. Routine Description:
  2145. Gets an asynchronous call context.
  2146. Arguments:
  2147. Return Value:
  2148. S_OK
  2149. E_NOINTERFACE
  2150. --*/
  2151. IAsyncRpcChannelBuffer * This,
  2152. RPCOLEMESSAGE * pMessage,
  2153. DWORD * pdw,
  2154. void ** ppv
  2155. )
  2156. {
  2157. HRESULT hr;
  2158. IRpcChannelBuffer * pChannel;
  2159. IAsyncRpcChannelBuffer * pAsChannel;
  2160. pChannel = ((ChannelWrapper *)This)->pChannel;
  2161. hr = pChannel->lpVtbl->QueryInterface( pChannel,
  2162. IID_IAsyncRpcChannelBuffer,
  2163. (void**)&pAsChannel);
  2164. if (S_OK == hr)
  2165. {
  2166. hr = pAsChannel->lpVtbl->GetDestCtxEx( pAsChannel,
  2167. pMessage,
  2168. pdw,
  2169. ppv );
  2170. pAsChannel->lpVtbl->Release(pAsChannel);
  2171. }
  2172. return hr;
  2173. }
  2174. HRESULT STDMETHODCALLTYPE
  2175. ChannelWrapper_GetDestCtxEx(
  2176. /*++
  2177. Routine Description:
  2178. Gets the new destination context.
  2179. Arguments:
  2180. Return Value:
  2181. S_OK
  2182. E_NOINTERFACE
  2183. --*/
  2184. IRpcChannelBuffer3 * This,
  2185. RPCOLEMESSAGE * pMessage,
  2186. DWORD * pdwDestContext,
  2187. void ** ppvDestContext
  2188. )
  2189. {
  2190. HRESULT hr;
  2191. IRpcChannelBuffer * pChannel;
  2192. IRpcChannelBuffer3 * pChannel3;
  2193. pChannel = ((ChannelWrapper *)This)->pChannel;
  2194. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2195. if (S_OK == hr)
  2196. {
  2197. hr = pChannel3->lpVtbl->GetDestCtxEx( pChannel3, pMessage, pdwDestContext, ppvDestContext );
  2198. pChannel3->lpVtbl->Release(pChannel3);
  2199. }
  2200. return hr;
  2201. }
  2202. HRESULT STDMETHODCALLTYPE
  2203. ChannelWrapper_GetState(
  2204. /*++
  2205. Routine Description:
  2206. Gets the call state.
  2207. Arguments:
  2208. Return Value:
  2209. S_OK
  2210. E_NOINTERFACE
  2211. --*/
  2212. IRpcChannelBuffer3 * This,
  2213. RPCOLEMESSAGE * pMessage,
  2214. DWORD * pState
  2215. )
  2216. {
  2217. HRESULT hr;
  2218. IRpcChannelBuffer * pChannel;
  2219. IRpcChannelBuffer3 * pChannel3;
  2220. pChannel = ((ChannelWrapper *)This)->pChannel;
  2221. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2222. if (S_OK == hr)
  2223. {
  2224. hr = pChannel3->lpVtbl->GetState( pChannel3, pMessage, pState );
  2225. pChannel3->lpVtbl->Release(pChannel3);
  2226. }
  2227. return hr;
  2228. }
  2229. HRESULT STDMETHODCALLTYPE
  2230. ChannelWrapper_RegisterAsync(
  2231. /*++
  2232. Routine Description:
  2233. Registers the async manager object and call with the channel.
  2234. Arguments:
  2235. Return Value:
  2236. S_OK
  2237. E_NOINTERFACE
  2238. --*/
  2239. IRpcChannelBuffer3 * This,
  2240. RPCOLEMESSAGE * pMessage,
  2241. IAsyncManager * pAsyncMgr
  2242. )
  2243. {
  2244. HRESULT hr;
  2245. IRpcChannelBuffer * pChannel;
  2246. IRpcChannelBuffer3 * pChannel3;
  2247. pChannel = ((ChannelWrapper *)This)->pChannel;
  2248. hr = pChannel->lpVtbl->QueryInterface(pChannel, IID_IRpcChannelBuffer3, (void**)&pChannel3);
  2249. if (S_OK == hr)
  2250. {
  2251. hr = pChannel3->lpVtbl->RegisterAsync( pChannel3, pMessage, pAsyncMgr );
  2252. pChannel3->lpVtbl->Release(pChannel3);
  2253. }
  2254. return hr;
  2255. }