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.

2080 lines
50 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (c) 1994-2000 Microsoft Corporation. All rights reserved.
  4. Module Name:
  5. stub.c
  6. Abstract:
  7. Implements the IRpcStubBuffer interface.
  8. Author:
  9. ShannonC 12-Oct-1994
  10. Environment:
  11. Windows NT and Windows 95. We do not support DOS and Win16.
  12. Revision History:
  13. --*/
  14. #define USE_STUBLESS_PROXY
  15. #define CINTERFACE
  16. #include <ndrp.h>
  17. #include <ndrole.h>
  18. #include <rpcproxy.h>
  19. #include <stddef.h>
  20. #include "ndrtypes.h"
  21. EXTERN_C const IID IID_IPrivStubBuffer = { /* 3e0ac23f-eff6-41f3-b44b-fbfa4544265f */
  22. 0x3e0ac23f,
  23. 0xeff6,
  24. 0x41f3,
  25. {0xb4, 0x4b, 0xfb, 0xfa, 0x45, 0x44, 0x26, 0x5f}
  26. };
  27. const IID * RPC_ENTRY
  28. NdrpGetStubIID(
  29. IRpcStubBuffer *This);
  30. void
  31. MakeSureWeHaveNonPipeArgs(
  32. PMIDL_STUB_MESSAGE pStubMsg,
  33. unsigned long BufferSize );
  34. BOOL NdrpFindInterface(
  35. IN const ProxyFileInfo ** pProxyFileList,
  36. IN REFIID riid,
  37. OUT const ProxyFileInfo ** ppProxyFileInfo,
  38. OUT long * pIndex );
  39. extern void ReleaseTemplateForwardVtbl(void ** pVtbl);
  40. //+-------------------------------------------------------------------------
  41. //
  42. // Global data
  43. //
  44. //--------------------------------------------------------------------------
  45. // ICallFactory interface on the StubBuffer objects.
  46. // ICallFactory is an interface on a sync stub only.
  47. // It has been introduced for NT5 beta2.
  48. extern const ICallFactoryVtbl CStdStubBuffer_CallFactoryVtbl = {
  49. CStdStubBuffer_CF_QueryInterface,
  50. CStdStubBuffer_CF_AddRef,
  51. CStdStubBuffer_CF_Release,
  52. CStdStubBuffer_CF_CreateCall };
  53. extern const ICallFactoryVtbl CStdStubBuffer2_CallFactoryVtbl = {
  54. CStdStubBuffer_CF_QueryInterface,
  55. CStdStubBuffer_CF_AddRef,
  56. CStdStubBuffer_CF_Release,
  57. CStdStubBuffer2_CF_CreateCall };
  58. extern const IReleaseMarshalBuffersVtbl CStdStubBuffer_ReleaseMarshalBuffersVtbl = {
  59. CStdStubBuffer_RMB_QueryInterface,
  60. CStdStubBuffer_RMB_AddRef,
  61. CStdStubBuffer_RMB_Release,
  62. CStdStubBuffer_RMB_ReleaseMarshalBuffer};
  63. extern const IReleaseMarshalBuffersVtbl CStdAsyncStubBuffer_ReleaseMarshalBuffersVtbl = {
  64. CStdStubBuffer_RMB_QueryInterface,
  65. CStdStubBuffer_RMB_AddRef,
  66. CStdStubBuffer_RMB_Release,
  67. CStdAsyncStubBuffer_RMB_ReleaseMarshalBuffer };
  68. extern const ISynchronizeVtbl CStdAsyncStubBuffer_ISynchronizeVtbl = {
  69. CStdAsyncStubBuffer_Synchronize_QueryInterface,
  70. CStdAsyncStubBuffer_Synchronize_AddRef,
  71. CStdAsyncStubBuffer_Synchronize_Release,
  72. CStdAsyncStubBuffer_Synchronize_Wait,
  73. CStdAsyncStubBuffer_Synchronize_Signal,
  74. CStdAsyncStubBuffer_Synchronize_Reset };
  75. //+-------------------------------------------------------------------------
  76. //
  77. // End of Global data
  78. //
  79. //--------------------------------------------------------------------------
  80. #pragma code_seg(".orpc")
  81. //
  82. // ICallFactory interface on the sync stub object.
  83. //
  84. HRESULT STDMETHODCALLTYPE
  85. CStdStubBuffer_CF_QueryInterface(
  86. IN ICallFactory *This,
  87. IN REFIID riid,
  88. OUT void ** ppvObject)
  89. /*++
  90. Routine Description:
  91. Query for an interface on the interface stub CallFactory pointer.
  92. Arguments:
  93. riid - Supplies the IID of the interface being requested.
  94. ppvObject - Returns a pointer to the requested interface.
  95. Return Value:
  96. S_OK
  97. E_NOINTERFACE
  98. Note:
  99. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  100. CStdStubBuffer,
  101. CStdStubBuffer2,
  102. CStdAsyncStubBuffer,
  103. --*/
  104. {
  105. IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) -
  106. (offsetof(CStdStubBuffer, pCallFactoryVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
  107. return pStubBuffer->lpVtbl->QueryInterface( pStubBuffer,
  108. riid,
  109. ppvObject );
  110. }
  111. ULONG STDMETHODCALLTYPE
  112. CStdStubBuffer_CF_AddRef(
  113. IN ICallFactory *This )
  114. /*++
  115. Routine Description:
  116. No need to go through punkOuter.
  117. Arguments:
  118. Return Value:
  119. S_OK
  120. E_NOINTERFACE
  121. --*/
  122. {
  123. IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) -
  124. (offsetof(CStdStubBuffer, pCallFactoryVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
  125. return pStubBuffer->lpVtbl->AddRef( pStubBuffer );
  126. }
  127. ULONG STDMETHODCALLTYPE
  128. CStdStubBuffer_CF_Release(
  129. IN ICallFactory *This )
  130. /*++
  131. Routine Description:
  132. Arguments:
  133. Return Value:
  134. S_OK
  135. E_NOINTERFACE
  136. --*/
  137. {
  138. IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) -
  139. (offsetof(CStdStubBuffer, pCallFactoryVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
  140. return pStubBuffer->lpVtbl->Release( pStubBuffer );
  141. }
  142. HRESULT
  143. NdrpCreateNonDelegatedAsyncStub(
  144. IN IRpcStubBuffer *This,
  145. IN REFIID riid, // async IID
  146. IN IUnknown * punkOuter, // controlling unknown
  147. OUT IRpcStubBuffer ** ppAsyncStub
  148. )
  149. {
  150. BOOL fFound;
  151. long j; // if index
  152. const ProxyFileInfo * pProxyFileInfo;
  153. CStdStubBuffer * pSyncSB = (CStdStubBuffer *)This;
  154. CStdAsyncStubBuffer * pAsyncSB;
  155. *ppAsyncStub = 0;
  156. if ( ! pSyncSB->pCallFactoryVtbl || !pSyncSB->pAsyncIID )
  157. return E_NOINTERFACE;
  158. if ( memcmp( &riid, pSyncSB->pAsyncIID, sizeof(IID)) != 0 )
  159. return E_NOINTERFACE;
  160. if ( 0 == pSyncSB->pvServerObject )
  161. return CO_E_OBJNOTCONNECTED;
  162. if ( 0 != punkOuter )
  163. return CLASS_E_NOAGGREGATION;
  164. // same file, so we can use the sync pPSFactory.
  165. fFound = NdrpFindInterface( ((CStdPSFactoryBuffer *)pSyncSB->pPSFactory)->pProxyFileList,
  166. riid,
  167. &pProxyFileInfo,
  168. & j);
  169. if ( !fFound )
  170. return E_NOINTERFACE;
  171. pAsyncSB = (CStdAsyncStubBuffer *)(*pfnCoTaskMemAlloc)(sizeof(CStdAsyncStubBuffer));
  172. if( ! pAsyncSB )
  173. return E_OUTOFMEMORY;
  174. memset( pAsyncSB, 0, sizeof(CStdAsyncStubBuffer));
  175. //Initialize the new stub buffer.
  176. pAsyncSB->lpVtbl = &pProxyFileInfo->pStubVtblList[j]->Vtbl;
  177. pAsyncSB->RefCount = 1;
  178. pAsyncSB->pSynchronizeVtbl = & CStdAsyncStubBuffer_ISynchronizeVtbl;
  179. // Create the stub disconnected from the server call object.
  180. // There will be a separate Connect call later.
  181. // pAsyncSB->pvServerObject = 0;
  182. NdrpAsyncStubMsgConstructor( pAsyncSB );
  183. //Increment the DLL reference count for DllCanUnloadNow.
  184. pSyncSB->pPSFactory->lpVtbl->AddRef( pSyncSB->pPSFactory );
  185. pAsyncSB->pPSFactory = pSyncSB->pPSFactory;
  186. *ppAsyncStub = (IRpcStubBuffer *) & pAsyncSB->lpVtbl;
  187. return S_OK;
  188. }
  189. HRESULT
  190. NdrpCreateDelegatedAsyncStub(
  191. IN IRpcStubBuffer *This,
  192. IN REFIID riid, // async IID
  193. IN IUnknown * punkOuter, // controlling unknown
  194. OUT IRpcStubBuffer ** ppAsyncStub
  195. )
  196. {
  197. HRESULT hr;
  198. BOOL fFound;
  199. long j; // if index
  200. const ProxyFileInfo * pProxyFileInfo;
  201. BOOL fDelegate = FALSE;
  202. CStdStubBuffer2 * pSyncSB = (CStdStubBuffer2 *)This;
  203. CStdAsyncStubBuffer * pAsyncSB;
  204. ICallFactory * pCallFactory;
  205. IRpcStubBuffer * pBaseSyncSB;
  206. *ppAsyncStub = 0;
  207. pSyncSB = (CStdStubBuffer2 *) ((uchar*)This -
  208. offsetof(CStdStubBuffer2,lpVtbl)) ;
  209. if ( ! pSyncSB->pCallFactoryVtbl || !pSyncSB->pAsyncIID )
  210. return E_NOINTERFACE;
  211. if ( memcmp( &riid, pSyncSB->pAsyncIID, sizeof(IID)) != 0 )
  212. return E_NOINTERFACE;
  213. if ( 0 == pSyncSB->pvServerObject )
  214. return CO_E_OBJNOTCONNECTED;
  215. if ( 0 != punkOuter )
  216. return CLASS_E_NOAGGREGATION;
  217. // same file, so we can use the sync pPSFactory.
  218. fFound = NdrpFindInterface( ((CStdPSFactoryBuffer *)pSyncSB->pPSFactory)->pProxyFileList,
  219. riid,
  220. &pProxyFileInfo,
  221. & j);
  222. if ( !fFound )
  223. return E_NOINTERFACE;
  224. pAsyncSB = (CStdAsyncStubBuffer*)(*pfnCoTaskMemAlloc)(sizeof(CStdAsyncStubBuffer));
  225. if( ! pAsyncSB )
  226. return E_OUTOFMEMORY;
  227. memset( pAsyncSB, 0, sizeof(CStdAsyncStubBuffer));
  228. //Initialize the new stub buffer.
  229. pAsyncSB->lpVtbl = &pProxyFileInfo->pStubVtblList[j]->Vtbl;
  230. pAsyncSB->RefCount = 1;
  231. pAsyncSB->pSynchronizeVtbl = & CStdAsyncStubBuffer_ISynchronizeVtbl;
  232. // As the Connect connects to real server we don't need that.
  233. // pAsyncSB->lpForwardingVtbl = & ForwardingVtbl;
  234. // Create the stub disconnected from the server call object.
  235. // There will be a separate Connect call later.
  236. // pAsyncSB->pvServerObject = 0;
  237. // Create an async stub for the base interface.
  238. // We don't know if the base is delegated, so we have to use
  239. // the base create call method.
  240. // The base async stub will also be disconnected.
  241. pBaseSyncSB = pSyncSB->pBaseStubBuffer;
  242. hr = pBaseSyncSB->lpVtbl->QueryInterface( pBaseSyncSB,
  243. IID_ICallFactory,
  244. (void**)& pCallFactory );
  245. if ( SUCCEEDED(hr) )
  246. {
  247. // Aggregate the base async stub with the current async stub,
  248. // not with the channel's punkOuter.
  249. // We should not need it, and the base stub is aggregated with
  250. // upper stub mostly for debug tracing.
  251. const IID * pBaseAsyncIID;
  252. pBaseAsyncIID = *(const IID **) ( (uchar*)pBaseSyncSB
  253. + offsetof(CStdStubBuffer, pAsyncIID) );
  254. hr = pCallFactory->lpVtbl->CreateCall( pCallFactory,
  255. *pBaseAsyncIID,
  256. 0, // no need for punkOuter (IUnknown*) & pAsyncSB->lpVtbl,
  257. IID_IUnknown,
  258. (IUnknown**)& pAsyncSB->pBaseStubBuffer );
  259. pCallFactory->lpVtbl->Release( pCallFactory );
  260. }
  261. if(SUCCEEDED(hr))
  262. {
  263. NdrpAsyncStubMsgConstructor( pAsyncSB );
  264. //Increment the DLL reference count for DllCanUnloadNow.
  265. pSyncSB->pPSFactory->lpVtbl->AddRef( pSyncSB->pPSFactory );
  266. pAsyncSB->pPSFactory = pSyncSB->pPSFactory;
  267. *ppAsyncStub = (IRpcStubBuffer *) & pAsyncSB->lpVtbl;
  268. }
  269. else
  270. {
  271. (*pfnCoTaskMemFree)(pAsyncSB);
  272. }
  273. return hr;
  274. }
  275. HRESULT STDMETHODCALLTYPE
  276. CStdStubBuffer_CF_CreateCall(
  277. IN ICallFactory *This,
  278. IN REFIID riid,
  279. IN IUnknown * punkOuter, // controlling unknown
  280. IN REFIID riid2,
  281. OUT IUnknown ** ppv
  282. )
  283. /*
  284. Creates a call object, i.e. an async stub object.
  285. Note, because the call comes via a CStdStubBuffer, not Buffer2,
  286. we know that we need to create only a non-delegated async stub.
  287. */
  288. {
  289. IRpcStubBuffer * pStubBuffer;
  290. if ( memcmp( &riid2, & IID_IUnknown, sizeof(IID)) != 0 )
  291. return E_INVALIDARG;
  292. pStubBuffer = (IRpcStubBuffer*) (((uchar *)This)
  293. - offsetof(CStdStubBuffer, pCallFactoryVtbl)
  294. + offsetof(CStdStubBuffer, lpVtbl) );
  295. return NdrpCreateNonDelegatedAsyncStub( pStubBuffer,
  296. riid,
  297. punkOuter,
  298. (IRpcStubBuffer **) ppv );
  299. }
  300. HRESULT STDMETHODCALLTYPE
  301. CStdStubBuffer2_CF_CreateCall(
  302. IN ICallFactory *This,
  303. IN REFIID riid,
  304. IN IUnknown * punkOuter, // controlling unknown
  305. IN REFIID riid2,
  306. OUT IUnknown ** ppv
  307. )
  308. /*
  309. Creates a call object, i.e. an async stub object.
  310. Note, because the call comes via a CStdStubBuffer, not Buffer2,
  311. we know that we need to create only a non-delegated async stub.
  312. */
  313. {
  314. IRpcStubBuffer * pStubBuffer;
  315. if ( memcmp( &riid2, & IID_IUnknown, sizeof(IID)) != 0 )
  316. return E_INVALIDARG;
  317. pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This
  318. - offsetof(CStdStubBuffer2, pCallFactoryVtbl)
  319. + offsetof(CStdStubBuffer2, lpVtbl) );
  320. return NdrpCreateDelegatedAsyncStub( pStubBuffer,
  321. riid,
  322. punkOuter,
  323. (IRpcStubBuffer **) ppv );
  324. }
  325. HRESULT STDMETHODCALLTYPE
  326. CStdStubBuffer_RMB_QueryInterface(
  327. IN IReleaseMarshalBuffers *This,
  328. IN REFIID riid,
  329. OUT void ** ppvObject)
  330. /*++
  331. Routine Description:
  332. Query for an interface on the interface stub CallFactory pointer.
  333. Arguments:
  334. riid - Supplies the IID of the interface being requested.
  335. ppvObject - Returns a pointer to the requested interface.
  336. Return Value:
  337. S_OK
  338. E_NOINTERFACE
  339. Note:
  340. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  341. CStdStubBuffer,
  342. CStdStubBuffer2,
  343. CStdAsyncStubBuffer,
  344. --*/
  345. {
  346. IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) -
  347. (offsetof(CStdStubBuffer, pRMBVtbl) -
  348. offsetof(CStdStubBuffer,lpVtbl)) );
  349. return pStubBuffer->lpVtbl->QueryInterface( pStubBuffer,
  350. riid,
  351. ppvObject );
  352. }
  353. ULONG STDMETHODCALLTYPE
  354. CStdStubBuffer_RMB_AddRef(
  355. IN IReleaseMarshalBuffers *This )
  356. /*++
  357. Routine Description:
  358. No need to go through punkOuter.
  359. Arguments:
  360. Return Value:
  361. S_OK
  362. E_NOINTERFACE
  363. --*/
  364. {
  365. IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) -
  366. (offsetof(CStdStubBuffer, pRMBVtbl) -
  367. offsetof(CStdStubBuffer,lpVtbl)) );
  368. return pStubBuffer->lpVtbl->AddRef( pStubBuffer );
  369. }
  370. ULONG STDMETHODCALLTYPE
  371. CStdStubBuffer_RMB_Release(
  372. IN IReleaseMarshalBuffers *This )
  373. /*++
  374. Routine Description:
  375. Arguments:
  376. Return Value:
  377. S_OK
  378. E_NOINTERFACE
  379. --*/
  380. {
  381. IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) (((uchar *)This) -
  382. (offsetof(CStdStubBuffer, pRMBVtbl) -
  383. offsetof(CStdStubBuffer,lpVtbl)) );
  384. return pStubBuffer->lpVtbl->Release( pStubBuffer );
  385. }
  386. HRESULT STDMETHODCALLTYPE
  387. CStdStubBuffer_RMB_ReleaseMarshalBuffer(
  388. IN IReleaseMarshalBuffers *pRMB,
  389. IN RPCOLEMESSAGE * pMsg,
  390. IN DWORD dwIOFlags,
  391. IN IUnknown *pChnl)
  392. {
  393. HRESULT hr;
  394. CStdStubBuffer * pStubBuffer = (CStdStubBuffer *) (((uchar *)pRMB) -
  395. offsetof(CStdStubBuffer, pRMBVtbl));
  396. hr = NdrpServerReleaseMarshalBuffer(pRMB,(RPC_MESSAGE *)pMsg,dwIOFlags,FALSE);
  397. return hr;
  398. }
  399. HRESULT STDMETHODCALLTYPE
  400. CStdAsyncStubBuffer_RMB_ReleaseMarshalBuffer(
  401. IN IReleaseMarshalBuffers *pRMB,
  402. IN RPCOLEMESSAGE * pMsg,
  403. IN DWORD dwIOFlags,
  404. IN IUnknown *pChnl)
  405. {
  406. HRESULT hr;
  407. CStdStubBuffer * pStubBuffer = (CStdStubBuffer *) (((uchar *)pRMB) -
  408. offsetof(CStdStubBuffer, pRMBVtbl));
  409. hr = NdrpServerReleaseMarshalBuffer(pRMB,(RPC_MESSAGE *)pMsg,dwIOFlags,TRUE);
  410. return hr;
  411. }
  412. //
  413. // The ISynchronize interface on an async stub object
  414. //
  415. HRESULT STDMETHODCALLTYPE
  416. CStdAsyncStubBuffer_Synchronize_QueryInterface(
  417. IN ISynchronize *This,
  418. IN REFIID riid,
  419. OUT void ** ppvObject)
  420. /*++
  421. Routine Description:
  422. Query for an interface on the interface stub CallFactory pointer.
  423. Arguments:
  424. riid - Supplies the IID of the interface being requested.
  425. ppvObject - Returns a pointer to the requested interface.
  426. Return Value:
  427. S_OK
  428. E_NOINTERFACE
  429. Note:
  430. Works for delegated and non-delegated async stubs.
  431. ISynchronize is public, go through punkOuter.
  432. --*/
  433. {
  434. IRpcStubBuffer * pStubBuffer;
  435. pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This
  436. - offsetof(CStdAsyncStubBuffer,pSynchronizeVtbl)
  437. + offsetof(CStdAsyncStubBuffer,lpVtbl) );
  438. return pStubBuffer->lpVtbl->QueryInterface( pStubBuffer,
  439. riid,
  440. ppvObject );
  441. }
  442. ULONG STDMETHODCALLTYPE
  443. CStdAsyncStubBuffer_Synchronize_AddRef(
  444. IN ISynchronize *This )
  445. /*++
  446. Routine Description:
  447. Arguments:
  448. Return Value:
  449. S_OK
  450. E_NOINTERFACE
  451. Note:
  452. Works for delegated and non-delegated async stubs.
  453. --*/
  454. {
  455. IRpcStubBuffer * pStubBuffer;
  456. pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This
  457. - offsetof(CStdAsyncStubBuffer,pSynchronizeVtbl)
  458. + offsetof(CStdAsyncStubBuffer,lpVtbl) );
  459. return pStubBuffer->lpVtbl->AddRef( pStubBuffer );
  460. }
  461. ULONG STDMETHODCALLTYPE
  462. CStdAsyncStubBuffer_Synchronize_Release(
  463. IN ISynchronize *This )
  464. /*++
  465. Routine Description:
  466. Arguments:
  467. Return Value:
  468. S_OK
  469. E_NOINTERFACE
  470. Note:
  471. Works for delegated and non-delegated async stubs.
  472. --*/
  473. {
  474. IRpcStubBuffer * pStubBuffer;
  475. pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This
  476. - offsetof(CStdAsyncStubBuffer,pSynchronizeVtbl)
  477. + offsetof(CStdAsyncStubBuffer,lpVtbl) );
  478. return pStubBuffer->lpVtbl->Release( pStubBuffer );
  479. }
  480. HRESULT STDMETHODCALLTYPE
  481. CStdAsyncStubBuffer_Synchronize_Wait(
  482. IN ISynchronize *This,
  483. IN DWORD dwFlags,
  484. IN DWORD dwMilisec )
  485. /*++
  486. Routine Description:
  487. It should never be called.
  488. Arguments:
  489. Return Value:
  490. Note:
  491. Works for delegated and non-delegated async stubs.
  492. --*/
  493. {
  494. IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This -
  495. (offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) - offsetof(CStdAsyncStubBuffer, lpVtbl)) );
  496. // It should never be called.
  497. return E_NOTIMPL;
  498. }
  499. HRESULT STDMETHODCALLTYPE
  500. CStdAsyncStubBuffer_Synchronize_Signal(
  501. IN ISynchronize *This )
  502. /*++
  503. Routine Description:
  504. Query for an interface on the interface stub CallFactory pointer.
  505. Arguments:
  506. riid - Supplies the IID of the interface being requested.
  507. ppvObject - Returns a pointer to the requested interface.
  508. Return Value:
  509. S_OK
  510. E_NOINTERFACE
  511. Note:
  512. Works for delegated and non-delegated async stubs.
  513. --*/
  514. {
  515. CStdAsyncStubBuffer * pAsyncSB;
  516. HRESULT hr;
  517. pAsyncSB = (CStdAsyncStubBuffer *) ( (uchar *)This -
  518. offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) );
  519. // It causes the Finish call to happen.
  520. hr = NdrpAsyncStubSignal( pAsyncSB );
  521. return hr;
  522. }
  523. HRESULT STDMETHODCALLTYPE
  524. CStdAsyncStubBuffer_Synchronize_Reset(
  525. IN ISynchronize *This )
  526. /*++
  527. Routine Description:
  528. This is called by the Server's Call Object as part of its Begin_* method.
  529. Arguments:
  530. Return Value: Always S_OK.
  531. Note:
  532. Works for delegated and non-delegated async stubs.
  533. --*/
  534. {
  535. IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This -
  536. (offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) - offsetof(CStdAsyncStubBuffer, lpVtbl)) );
  537. // Server's Call object gets S_OK...
  538. return S_OK;
  539. }
  540. //
  541. // Implementation of the stub buffer itself.
  542. //
  543. HRESULT STDMETHODCALLTYPE
  544. CStdStubBuffer_QueryInterface(
  545. IN IRpcStubBuffer *This,
  546. IN REFIID riid,
  547. OUT void ** ppvObject)
  548. /*++
  549. Routine Description:
  550. Query for an interface on the interface stub. The interface
  551. stub supports the IUnknown and IRpcStubBuffer interfaces.
  552. Arguments:
  553. riid - Supplies the IID of the interface being requested.
  554. ppvObject - Returns a pointer to the requested interface.
  555. Return Value:
  556. S_OK
  557. E_NOINTERFACE
  558. Note:
  559. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  560. CStdStubBuffer,
  561. CStdStubBuffer2,
  562. This is correct for the stubs supporting async_uuid.
  563. --*/
  564. {
  565. HRESULT hr;
  566. if ((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  567. (memcmp(&riid, &IID_IRpcStubBuffer, sizeof(IID)) == 0))
  568. {
  569. This->lpVtbl->AddRef(This);
  570. *ppvObject = This;
  571. hr = S_OK;
  572. }
  573. else if ( ((CStdStubBuffer*)This)->pCallFactoryVtbl != 0 &&
  574. memcmp(&riid, &IID_ICallFactory, sizeof(IID)) == 0 )
  575. {
  576. This->lpVtbl->AddRef(This);
  577. *ppvObject = ( (uchar *)This +
  578. (offsetof(CStdStubBuffer, pCallFactoryVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
  579. hr = S_OK;
  580. }
  581. else if ( (((CStdStubBuffer*)This)->pRMBVtbl) &&
  582. (memcmp(&riid, &IID_IReleaseMarshalBuffers,sizeof(IID)) == 0))
  583. {
  584. This->lpVtbl->AddRef(This);
  585. *ppvObject = ( (uchar *)This + offsetof(CStdStubBuffer,pRMBVtbl)) ;
  586. hr = S_OK;
  587. }
  588. else if ( riid == IID_IPrivStubBuffer )
  589. {
  590. This->lpVtbl->AddRef(This);
  591. *ppvObject = This;
  592. hr = S_OK;
  593. }
  594. else
  595. {
  596. *ppvObject = 0;
  597. hr = E_NOINTERFACE;
  598. }
  599. return hr;
  600. }
  601. HRESULT STDMETHODCALLTYPE
  602. CStdAsyncStubBuffer_QueryInterface(
  603. IN IRpcStubBuffer *This,
  604. IN REFIID riid,
  605. OUT void ** ppvObject)
  606. /*++
  607. Routine Description:
  608. Query for an interface on the interface stub. The interface
  609. stub supports the IUnknown and IRpcStubBuffer interfaces.
  610. Arguments:
  611. riid - Supplies the IID of the interface being requested.
  612. ppvObject - Returns a pointer to the requested interface.
  613. Return Value:
  614. S_OK
  615. E_NOINTERFACE
  616. Note:
  617. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  618. CStdAsyncStubBuffer
  619. So this works for AsyncStubBuffer2_QueryInterface.
  620. --*/
  621. {
  622. HRESULT hr = E_NOINTERFACE;
  623. *ppvObject = 0;
  624. if ((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  625. (memcmp(&riid, &IID_IRpcStubBuffer, sizeof(IID)) == 0))
  626. {
  627. *ppvObject = This;
  628. hr = S_OK;
  629. }
  630. else if ( memcmp(&riid, &IID_ISynchronize, sizeof(IID)) == 0 )
  631. {
  632. // For pSynchronize return &pAsyncSB->pSynchronizeVtbl.
  633. *ppvObject = ( (uchar *)This +
  634. (offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) - offsetof(CStdAsyncStubBuffer,lpVtbl)) );
  635. hr = S_OK;
  636. }
  637. else if ( (((CStdStubBuffer*)This)->pRMBVtbl) &&
  638. (memcmp(&riid, &IID_IReleaseMarshalBuffers,sizeof(IID)) == 0))
  639. {
  640. This->lpVtbl->AddRef(This);
  641. *ppvObject = (void *)((CStdStubBuffer*)This)->pRMBVtbl;
  642. hr = S_OK;
  643. }
  644. else if ( riid == IID_IPrivStubBuffer )
  645. {
  646. This->lpVtbl->AddRef(This);
  647. *ppvObject = This;
  648. hr = S_OK;
  649. }
  650. if ( SUCCEEDED(hr) )
  651. ((IUnknown*)*ppvObject)->lpVtbl->AddRef( (IUnknown*)*ppvObject );
  652. // This is async stub, the channel would never call a query
  653. // for anything else.
  654. return hr;
  655. }
  656. ULONG STDMETHODCALLTYPE
  657. CStdStubBuffer_AddRef(
  658. IN IRpcStubBuffer *This)
  659. /*++
  660. Routine Description:
  661. Increment reference count.
  662. Arguments:
  663. Return Value:
  664. Reference count.
  665. Note:
  666. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  667. CStdStubBuffer,
  668. CStdStubBuffer2,
  669. --*/
  670. {
  671. InterlockedIncrement(&((CStdStubBuffer *)This)->RefCount);
  672. return (ULONG) ((CStdStubBuffer *)This)->RefCount;
  673. }
  674. ULONG STDMETHODCALLTYPE
  675. CStdAsyncStubBuffer_AddRef(
  676. IN IRpcStubBuffer *This)
  677. /*++
  678. Routine Description:
  679. Increment reference count.
  680. Arguments:
  681. Return Value:
  682. Reference count.
  683. Note:
  684. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  685. CStdAsyncStubBuffer,
  686. --*/
  687. {
  688. // ok: ISynchronize is not really public
  689. InterlockedIncrement(&((CStdStubBuffer *)This)->RefCount);
  690. return (ULONG) ((CStdStubBuffer *)This)->RefCount;
  691. }
  692. //
  693. // This is needed and used only by the synchronous stubs.
  694. //
  695. HRESULT STDMETHODCALLTYPE
  696. Forwarding_QueryInterface(
  697. IN IUnknown * This,
  698. IN REFIID riid,
  699. OUT void ** ppv)
  700. {
  701. *ppv = This;
  702. return S_OK;
  703. }
  704. ULONG STDMETHODCALLTYPE
  705. Forwarding_AddRef(
  706. IN IUnknown *This)
  707. {
  708. return 1;
  709. }
  710. ULONG STDMETHODCALLTYPE
  711. Forwarding_Release(
  712. IN IUnknown *This)
  713. {
  714. return 1;
  715. }
  716. ULONG STDMETHODCALLTYPE
  717. NdrCStdStubBuffer_Release(
  718. IN IRpcStubBuffer * This,
  719. IN IPSFactoryBuffer * pFactory)
  720. /*++
  721. Routine Description:
  722. Decrement reference count.
  723. Arguments:
  724. Return Value:
  725. Reference count.
  726. --*/
  727. {
  728. ULONG count;
  729. NDR_ASSERT(((CStdStubBuffer *)This)->RefCount > 0, "Invalid reference count");
  730. count = (ULONG) ((CStdStubBuffer *)This)->RefCount - 1;
  731. if(InterlockedDecrement(&((CStdStubBuffer *)This)->RefCount) == 0)
  732. {
  733. count = 0;
  734. #if DBG == 1
  735. memset(This, '\0', sizeof(CStdStubBuffer));
  736. #endif
  737. //Free the stub buffer
  738. NdrOleFree(This);
  739. //Decrement the DLL reference count.
  740. ((CStdPSFactoryBuffer*)pFactory)->lpVtbl->Release( pFactory );
  741. }
  742. return count;
  743. }
  744. ULONG STDMETHODCALLTYPE
  745. CStdAsyncStubBuffer_Release(
  746. IN IRpcStubBuffer * This
  747. )
  748. {
  749. CStdAsyncStubBuffer * pAsyncSB;
  750. ULONG count;
  751. pAsyncSB = (CStdAsyncStubBuffer*)((uchar*)This
  752. - offsetof(CStdAsyncStubBuffer,lpVtbl));
  753. NDR_ASSERT(pAsyncSB->RefCount > 0, "Async stub Invalid reference count");
  754. count = (ULONG) pAsyncSB->RefCount - 1;
  755. if ( InterlockedDecrement( &pAsyncSB->RefCount) == 0)
  756. {
  757. IPSFactoryBuffer * pFactory = pAsyncSB->pPSFactory;
  758. count = 0;
  759. NdrpAsyncStubMsgDestructor( pAsyncSB );
  760. #if DBG == 1
  761. memset( pAsyncSB, '\33', sizeof(CStdAsyncStubBuffer));
  762. #endif
  763. //Free the stub buffer
  764. NdrOleFree( pAsyncSB );
  765. //Decrement the DLL reference count.
  766. pFactory->lpVtbl->Release( pFactory );
  767. }
  768. return count;
  769. }
  770. ULONG STDMETHODCALLTYPE
  771. CStdAsyncStubBuffer2_Release(
  772. IN IRpcStubBuffer * This
  773. )
  774. {
  775. // O well, the main desctructor for the delegated async stub.
  776. CStdAsyncStubBuffer * pAsyncSB;
  777. ULONG count;
  778. pAsyncSB = (CStdAsyncStubBuffer*)((uchar*)This
  779. - offsetof(CStdAsyncStubBuffer,lpVtbl));
  780. NDR_ASSERT(pAsyncSB->RefCount > 0, "Async stub Invalid reference count");
  781. count = (ULONG) pAsyncSB->RefCount - 1;
  782. if ( InterlockedDecrement(&pAsyncSB->RefCount) == 0)
  783. {
  784. IPSFactoryBuffer * pFactory = pAsyncSB->pPSFactory;
  785. IRpcStubBuffer * pBaseStubBuffer = pAsyncSB->pBaseStubBuffer;
  786. count = 0;
  787. if( pBaseStubBuffer != 0)
  788. pBaseStubBuffer->lpVtbl->Release( pBaseStubBuffer );
  789. NdrpAsyncStubMsgDestructor( pAsyncSB );
  790. #if DBG == 1
  791. memset( pAsyncSB, '\33', sizeof(CStdAsyncStubBuffer));
  792. #endif
  793. //Free the stub buffer
  794. NdrOleFree( pAsyncSB );
  795. //Decrement the DLL reference count.
  796. pFactory->lpVtbl->Release( pFactory );
  797. }
  798. return count;
  799. }
  800. ULONG STDMETHODCALLTYPE
  801. NdrCStdStubBuffer2_Release(
  802. IN IRpcStubBuffer * This,
  803. IN IPSFactoryBuffer * pFactory)
  804. /*++
  805. Routine Description:
  806. Decrement reference count. This function supports delegation to the stub
  807. for the base interface.
  808. Arguments:
  809. Return Value:
  810. Reference count.
  811. --*/
  812. {
  813. ULONG count;
  814. unsigned char *pTemp;
  815. CStdStubBuffer2 * pStubBuffer;
  816. IRpcStubBuffer *pBaseStubBuffer;
  817. pTemp = (unsigned char *)This;
  818. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  819. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  820. NDR_ASSERT(pStubBuffer->RefCount > 0, "Invalid reference count");
  821. count = (ULONG) pStubBuffer->RefCount - 1;
  822. if(InterlockedDecrement(&pStubBuffer->RefCount) == 0)
  823. {
  824. count = 0;
  825. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  826. if(pBaseStubBuffer != 0)
  827. pBaseStubBuffer->lpVtbl->Release(pBaseStubBuffer);
  828. #if DBG == 1
  829. memset(pStubBuffer, '\0', sizeof(CStdStubBuffer2));
  830. #endif
  831. if (pStubBuffer->lpForwardingVtbl)
  832. ReleaseTemplateForwardVtbl((void **)pStubBuffer->lpForwardingVtbl);
  833. //Free the stub buffer
  834. NdrOleFree(pStubBuffer);
  835. //Decrement the DLL reference count.
  836. ((CStdPSFactoryBuffer*)pFactory)->lpVtbl->Release( pFactory );
  837. }
  838. return count;
  839. }
  840. HRESULT STDMETHODCALLTYPE
  841. CStdStubBuffer_Connect(
  842. IN IRpcStubBuffer *This,
  843. IN IUnknown * pUnkServer)
  844. /*++
  845. Routine Description:
  846. Connect the stub buffer to the server object.
  847. This is the non-delegated case.
  848. Arguments:
  849. Return Value:
  850. Notes:
  851. This works for CStdAsyncBuffer_Connect
  852. --*/
  853. {
  854. HRESULT hr;
  855. const IID *pIID;
  856. IUnknown *punk = 0;
  857. NDR_ASSERT(pUnkServer != 0, "pUnkServer parameter is invalid.");
  858. pIID = NdrpGetStubIID(This);
  859. hr = pUnkServer->lpVtbl->QueryInterface(pUnkServer, *pIID, (void**)&punk);
  860. punk = (IUnknown *) InterlockedExchangePointer(
  861. (PVOID *) &((CStdStubBuffer *) This)->pvServerObject, (PVOID) punk);
  862. if(punk != 0)
  863. {
  864. //The stub was already connected. Release the old interface pointer.
  865. punk->lpVtbl->Release(punk);
  866. }
  867. return hr;
  868. }
  869. HRESULT STDMETHODCALLTYPE
  870. CStdAsyncStubBuffer_Connect(
  871. IN IRpcStubBuffer *This,
  872. IN IUnknown * punkServer)
  873. /*++
  874. Routine Description:
  875. Connect the stub buffer to the server object.
  876. This is the non-delegated case.
  877. Arguments:
  878. punkServer - this is a pointer to AsyncIFoo already queried by the channel.
  879. (when delegation same thing)
  880. Return Value:
  881. Notes:
  882. This works the same as for StubBuffer_Connect.
  883. Note that an async stub is always created disconnected.
  884. It also always keep a pointer to the real server not
  885. to a forwarder object.
  886. --*/
  887. {
  888. IUnknown *punk = 0;
  889. NDR_ASSERT(punkServer != 0, "pUnkServer parameter is invalid.");
  890. punkServer->lpVtbl->AddRef( punkServer );
  891. punk = (IUnknown *) InterlockedExchangePointer(
  892. (PVOID *) &((CStdStubBuffer *) This)->pvServerObject, (PVOID) punkServer);
  893. if( punk != 0 )
  894. {
  895. // The stub was already connected. Release the old interface pointer.
  896. punk->lpVtbl->Release(punk);
  897. }
  898. return S_OK;
  899. }
  900. HRESULT STDMETHODCALLTYPE
  901. CStdStubBuffer2_Connect(
  902. IN IRpcStubBuffer *This,
  903. IN IUnknown * pUnkServer)
  904. /*++
  905. Routine Description:
  906. Connect the stub buffer to the server object.
  907. This is the delegated case.
  908. Arguments:
  909. Return Value:
  910. --*/
  911. {
  912. HRESULT hr;
  913. unsigned char * pTemp;
  914. CStdStubBuffer2 * pStubBuffer;
  915. IRpcStubBuffer * pBaseStubBuffer;
  916. hr = CStdStubBuffer_Connect(This, pUnkServer);
  917. if(SUCCEEDED(hr))
  918. {
  919. //Connect the stub for the base interface.
  920. pTemp = (unsigned char *)This;
  921. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  922. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  923. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  924. if(pBaseStubBuffer != 0)
  925. {
  926. hr = pBaseStubBuffer->lpVtbl->Connect(pBaseStubBuffer,
  927. (IUnknown *) &pStubBuffer->lpForwardingVtbl);
  928. }
  929. }
  930. return hr;
  931. }
  932. HRESULT STDMETHODCALLTYPE
  933. CStdAsyncStubBuffer2_Connect(
  934. IN IRpcStubBuffer *This,
  935. IN IUnknown * pUnkServer)
  936. /*++
  937. Routine Description:
  938. Connect the stub buffer to the server object.
  939. This is the delegated case.
  940. Arguments:
  941. Return Value:
  942. Notes:
  943. This is different from CStdAsyncBuffer2_Connect
  944. as the base is connected to the real server here.
  945. Note that an async stub is always created disconnected.
  946. It also always keep a pointer to the real server not
  947. to a forwarder object.
  948. --*/
  949. {
  950. HRESULT hr;
  951. unsigned char * pTemp;
  952. CStdStubBuffer2 * pStubBuffer;
  953. IRpcStubBuffer * pBaseStubBuffer;
  954. hr = CStdAsyncStubBuffer_Connect(This, pUnkServer);
  955. if(SUCCEEDED(hr))
  956. {
  957. //Connect the stub for the base interface.
  958. pTemp = (unsigned char *)This;
  959. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  960. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  961. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  962. if(pBaseStubBuffer != 0)
  963. {
  964. hr = pBaseStubBuffer->lpVtbl->Connect(
  965. pBaseStubBuffer,
  966. pUnkServer );
  967. }
  968. }
  969. return hr;
  970. }
  971. void STDMETHODCALLTYPE
  972. CStdStubBuffer_Disconnect(
  973. IN IRpcStubBuffer *This)
  974. /*++
  975. Routine Description:
  976. Disconnect the stub from the server object.
  977. Arguments:
  978. Return Value:
  979. None.
  980. Notes:
  981. This works for CStdAsyncBuffer_Disconnect
  982. --*/
  983. {
  984. IUnknown * punk;
  985. //Set pvServerObject to zero.
  986. punk = (IUnknown *) InterlockedExchangePointer(
  987. (PVOID*) &((CStdStubBuffer *)This)->pvServerObject, 0);
  988. if(punk != 0)
  989. {
  990. //
  991. // Free the old interface pointer.
  992. //
  993. punk->lpVtbl->Release(punk);
  994. }
  995. }
  996. void STDMETHODCALLTYPE
  997. CStdAsyncStubBuffer_Disconnect(
  998. IN IRpcStubBuffer *This)
  999. /*++
  1000. Routine Description:
  1001. Disconnect the stub from the server object.
  1002. Arguments:
  1003. Return Value:
  1004. None.
  1005. --*/
  1006. {
  1007. // Same as Buffer_Disconnect
  1008. IUnknown * punk;
  1009. //Set pvServerObject to zero.
  1010. punk = (IUnknown *) InterlockedExchangePointer(
  1011. (PVOID*) &((CStdStubBuffer *)This)->pvServerObject, 0);
  1012. // Free the old interface pointer.
  1013. if(punk != 0)
  1014. punk->lpVtbl->Release(punk);
  1015. }
  1016. void STDMETHODCALLTYPE
  1017. CStdStubBuffer2_Disconnect(
  1018. IN IRpcStubBuffer *This)
  1019. /*++
  1020. Routine Description:
  1021. Disconnect the stub buffer from the server object.
  1022. Arguments:
  1023. Return Value:
  1024. None.
  1025. --*/
  1026. {
  1027. IUnknown * punk;
  1028. unsigned char *pTemp;
  1029. CStdStubBuffer2 * pStubBuffer;
  1030. IRpcStubBuffer *pBaseStubBuffer;
  1031. pTemp = (unsigned char *)This;
  1032. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  1033. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  1034. //Disconnect the stub for the base interface.
  1035. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  1036. if(pBaseStubBuffer != 0)
  1037. pBaseStubBuffer->lpVtbl->Disconnect(pBaseStubBuffer);
  1038. //Set pvServerObject to zero.
  1039. punk = (IUnknown *) InterlockedExchangePointer(
  1040. (PVOID*) &pStubBuffer->pvServerObject, 0);
  1041. if(punk != 0)
  1042. {
  1043. //
  1044. // Free the old interface pointer.
  1045. //
  1046. punk->lpVtbl->Release(punk);
  1047. }
  1048. }
  1049. void STDMETHODCALLTYPE
  1050. CStdAsyncStubBuffer2_Disconnect(
  1051. IN IRpcStubBuffer *This)
  1052. /*++
  1053. Routine Description:
  1054. Disconnect the stub buffer from the server object.
  1055. Arguments:
  1056. Return Value:
  1057. None.
  1058. --*/
  1059. {
  1060. IUnknown * punk;
  1061. unsigned char *pTemp;
  1062. CStdStubBuffer2 * pStubBuffer;
  1063. IRpcStubBuffer *pBaseStubBuffer;
  1064. pTemp = (unsigned char *)This;
  1065. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  1066. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  1067. //Disconnect the stub for the base interface.
  1068. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  1069. if(pBaseStubBuffer != 0)
  1070. pBaseStubBuffer->lpVtbl->Disconnect(pBaseStubBuffer);
  1071. //Set pvServerObject to zero.
  1072. punk = (IUnknown *) InterlockedExchangePointer(
  1073. (PVOID*) &pStubBuffer->pvServerObject, 0);
  1074. // Free the old interface pointer.
  1075. if(punk != 0)
  1076. punk->lpVtbl->Release(punk);
  1077. }
  1078. HRESULT STDMETHODCALLTYPE
  1079. CStdStubBuffer_Invoke(
  1080. IN IRpcStubBuffer * This,
  1081. IN RPCOLEMESSAGE * prpcmsg,
  1082. IN IRpcChannelBuffer * pRpcChannelBuffer)
  1083. /*++
  1084. Routine Description:
  1085. Invoke a stub function via the dispatch table.
  1086. Arguments:
  1087. Return Value:
  1088. --*/
  1089. {
  1090. HRESULT hr = S_OK;
  1091. unsigned char ** ppTemp;
  1092. unsigned char * pTemp;
  1093. CInterfaceStubVtbl *pStubVtbl;
  1094. unsigned long dwServerPhase = STUB_UNMARSHAL;
  1095. //Get a pointer to the stub vtbl.
  1096. ppTemp = (unsigned char **) This;
  1097. pTemp = *ppTemp;
  1098. pTemp -= sizeof(CInterfaceStubHeader);
  1099. pStubVtbl = (CInterfaceStubVtbl *) pTemp;
  1100. RpcTryExcept
  1101. //
  1102. //Check if procnum is valid.
  1103. //
  1104. if((prpcmsg->iMethod >= pStubVtbl->header.DispatchTableCount) ||
  1105. (prpcmsg->iMethod < 3))
  1106. {
  1107. RpcRaiseException(RPC_S_PROCNUM_OUT_OF_RANGE);
  1108. }
  1109. // null indicates pure-interpreted
  1110. if ( pStubVtbl->header.pDispatchTable != 0)
  1111. {
  1112. (*pStubVtbl->header.pDispatchTable[prpcmsg->iMethod])(
  1113. This,
  1114. pRpcChannelBuffer,
  1115. (PRPC_MESSAGE) prpcmsg,
  1116. &dwServerPhase);
  1117. }
  1118. else
  1119. {
  1120. PMIDL_SERVER_INFO pServerInfo;
  1121. PMIDL_STUB_DESC pStubDesc;
  1122. pServerInfo = (PMIDL_SERVER_INFO) pStubVtbl->header.pServerInfo;
  1123. pStubDesc = pServerInfo->pStubDesc;
  1124. #ifdef BUILD_NDR64
  1125. if ( pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES )
  1126. {
  1127. NdrStubCall3(This,
  1128. pRpcChannelBuffer,
  1129. (PRPC_MESSAGE) prpcmsg,
  1130. &dwServerPhase);
  1131. }
  1132. else
  1133. #endif
  1134. if ( MIDL_VERSION_3_0_39 <= pServerInfo->pStubDesc->MIDLVersion )
  1135. {
  1136. // Since MIDL 3.0.39 we have a proc flag that indicates
  1137. // which interpeter to call. This is because the NDR version
  1138. // may be bigger than 1.1 for other reasons.
  1139. PFORMAT_STRING pProcFormat;
  1140. unsigned short ProcOffset;
  1141. ProcOffset = pServerInfo->FmtStringOffset[ prpcmsg->iMethod ];
  1142. pProcFormat = & pServerInfo->ProcString[ ProcOffset ];
  1143. if ( pProcFormat[1] & Oi_OBJ_USE_V2_INTERPRETER )
  1144. {
  1145. NdrStubCall2(
  1146. This,
  1147. pRpcChannelBuffer,
  1148. (PRPC_MESSAGE) prpcmsg,
  1149. &dwServerPhase );
  1150. }
  1151. else
  1152. {
  1153. #if defined(__RPC_WIN64__)
  1154. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  1155. #else
  1156. NdrStubCall(
  1157. This,
  1158. pRpcChannelBuffer,
  1159. (PRPC_MESSAGE) prpcmsg,
  1160. &dwServerPhase );
  1161. #endif
  1162. }
  1163. }
  1164. else
  1165. {
  1166. // Prior to that, the NDR version (on per file basis)
  1167. // was the only indication of -Oi2.
  1168. if ( pStubDesc->Version <= NDR_VERSION_1_1 )
  1169. {
  1170. #if defined(__RPC_WIN64__)
  1171. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  1172. #else
  1173. NdrStubCall(
  1174. This,
  1175. pRpcChannelBuffer,
  1176. (PRPC_MESSAGE) prpcmsg,
  1177. &dwServerPhase );
  1178. #endif
  1179. }
  1180. else
  1181. {
  1182. NdrStubCall2(
  1183. This,
  1184. pRpcChannelBuffer,
  1185. (PRPC_MESSAGE) prpcmsg,
  1186. &dwServerPhase );
  1187. }
  1188. }
  1189. }
  1190. RpcExcept(dwServerPhase == STUB_CALL_SERVER ?
  1191. EXCEPTION_CONTINUE_SEARCH :
  1192. EXCEPTION_EXECUTE_HANDLER)
  1193. hr = NdrStubErrorHandler( RpcExceptionCode() );
  1194. RpcEndExcept
  1195. return hr;
  1196. }
  1197. HRESULT STDMETHODCALLTYPE
  1198. CStdAsyncStubBuffer_Invoke(
  1199. IN IRpcStubBuffer * This,
  1200. IN RPCOLEMESSAGE * prpcmsg,
  1201. IN IRpcChannelBuffer * pRpcChannelBuffer)
  1202. /*++
  1203. Routine Description:
  1204. Invoke a stub function via the dispatch table.
  1205. Arguments:
  1206. Return Value:
  1207. --*/
  1208. {
  1209. HRESULT hr = S_OK;
  1210. unsigned char ** ppTemp;
  1211. unsigned char * pTemp;
  1212. CInterfaceStubVtbl *pStubVtbl;
  1213. unsigned long dwServerPhase = STUB_UNMARSHAL;
  1214. //Get a pointer to the stub vtbl.
  1215. ppTemp = (unsigned char **) This;
  1216. pTemp = *ppTemp;
  1217. pTemp -= sizeof(CInterfaceStubHeader);
  1218. pStubVtbl = (CInterfaceStubVtbl *) pTemp;
  1219. RpcTryExcept
  1220. {
  1221. PMIDL_SERVER_INFO pServerInfo;
  1222. // Check if procnum is valid.
  1223. // Note, this is a sync proc number.
  1224. //
  1225. if((prpcmsg->iMethod >= pStubVtbl->header.DispatchTableCount) ||
  1226. (prpcmsg->iMethod < 3))
  1227. {
  1228. RpcRaiseException(RPC_S_PROCNUM_OUT_OF_RANGE);
  1229. }
  1230. // Async DCOM is supported only in the new interpreter,
  1231. // and only since MIDL 5.0.+
  1232. pServerInfo = (PMIDL_SERVER_INFO) pStubVtbl->header.pServerInfo;
  1233. if ( pServerInfo->pStubDesc->MIDLVersion < MIDL_VERSION_5_0_136 )
  1234. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1235. // Non null would indicate an -Os stub or a delegation case.
  1236. if ( pStubVtbl->header.pDispatchTable != 0)
  1237. {
  1238. (*pStubVtbl->header.pDispatchTable[prpcmsg->iMethod])(
  1239. This,
  1240. pRpcChannelBuffer,
  1241. (PRPC_MESSAGE) prpcmsg,
  1242. &dwServerPhase);
  1243. }
  1244. else
  1245. {
  1246. #if defined(BUILD_NDR64)
  1247. if ( pServerInfo->pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES )
  1248. {
  1249. switch ( NdrpGetSyntaxType( ( (PRPC_MESSAGE) prpcmsg )->TransferSyntax ) )
  1250. {
  1251. case XFER_SYNTAX_DCE:
  1252. NdrDcomAsyncStubCall( This,
  1253. pRpcChannelBuffer,
  1254. (PRPC_MESSAGE) prpcmsg,
  1255. &dwServerPhase );
  1256. break;
  1257. case XFER_SYNTAX_NDR64:
  1258. Ndr64DcomAsyncStubCall( This,
  1259. pRpcChannelBuffer,
  1260. (PRPC_MESSAGE) prpcmsg,
  1261. &dwServerPhase );
  1262. break;
  1263. }
  1264. }
  1265. else
  1266. #endif
  1267. NdrDcomAsyncStubCall( This,
  1268. pRpcChannelBuffer,
  1269. (PRPC_MESSAGE) prpcmsg,
  1270. &dwServerPhase );
  1271. }
  1272. }
  1273. RpcExcept(dwServerPhase == STUB_CALL_SERVER ?
  1274. EXCEPTION_CONTINUE_SEARCH :
  1275. EXCEPTION_EXECUTE_HANDLER)
  1276. hr = NdrStubErrorHandler( RpcExceptionCode() );
  1277. RpcEndExcept
  1278. return hr;
  1279. }
  1280. IRpcStubBuffer * STDMETHODCALLTYPE
  1281. CStdStubBuffer_IsIIDSupported(
  1282. IN IRpcStubBuffer *This,
  1283. IN REFIID riid)
  1284. /*++
  1285. Routine Description:
  1286. If the stub buffer supports the specified interface,
  1287. then return an IRpcStubBuffer *. If the interface is not
  1288. supported, then return zero.
  1289. Arguments:
  1290. Return Value:
  1291. Notes:
  1292. This works for CStdAsyncStubBuffer,CStdAsyncStubBuffer2.
  1293. --*/
  1294. {
  1295. CStdStubBuffer * pCThis = (CStdStubBuffer *) This;
  1296. const IID * pIID;
  1297. IRpcStubBuffer * pInterfaceStub = 0;
  1298. pIID = NdrpGetStubIID(This);
  1299. if(memcmp(&riid, pIID, sizeof(IID)) == 0)
  1300. {
  1301. if(pCThis->pvServerObject != 0)
  1302. {
  1303. pInterfaceStub = This;
  1304. pInterfaceStub->lpVtbl->AddRef(pInterfaceStub);
  1305. }
  1306. }
  1307. return pInterfaceStub;
  1308. }
  1309. ULONG STDMETHODCALLTYPE
  1310. CStdStubBuffer_CountRefs(
  1311. IN IRpcStubBuffer *This)
  1312. /*++
  1313. Routine Description:
  1314. Count the number of references to the server object.
  1315. Arguments:
  1316. Return Value:
  1317. Notes:
  1318. This works for CStdAsyncStubBuffer.
  1319. --*/
  1320. {
  1321. ULONG count = 0;
  1322. if(((CStdStubBuffer *)This)->pvServerObject != 0)
  1323. count++;
  1324. return count;
  1325. }
  1326. ULONG STDMETHODCALLTYPE
  1327. CStdStubBuffer2_CountRefs(
  1328. IN IRpcStubBuffer *This)
  1329. /*++
  1330. Routine Description:
  1331. Count the number of references to the server object.
  1332. Arguments:
  1333. Return Value:
  1334. Notes:
  1335. This works for CStdAsyncStubBuffer2.
  1336. --*/
  1337. {
  1338. ULONG count;
  1339. unsigned char *pTemp;
  1340. CStdStubBuffer2 * pStubBuffer;
  1341. IRpcStubBuffer *pBaseStubBuffer;
  1342. pTemp = (unsigned char *)This;
  1343. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  1344. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  1345. count = CStdStubBuffer_CountRefs(This);
  1346. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  1347. if(pBaseStubBuffer != 0)
  1348. count += pBaseStubBuffer->lpVtbl->CountRefs(pBaseStubBuffer);
  1349. return count;
  1350. }
  1351. HRESULT STDMETHODCALLTYPE
  1352. CStdStubBuffer_DebugServerQueryInterface(
  1353. IN IRpcStubBuffer *This,
  1354. OUT void **ppv)
  1355. /*++
  1356. Routine Description:
  1357. Return the interface pointer to the server object.
  1358. Arguments:
  1359. Return Value:
  1360. --*/
  1361. {
  1362. HRESULT hr;
  1363. *ppv = ((CStdStubBuffer *)This)->pvServerObject;
  1364. if(*ppv != 0)
  1365. hr = S_OK;
  1366. else
  1367. hr = CO_E_OBJNOTCONNECTED;
  1368. return hr;
  1369. }
  1370. void STDMETHODCALLTYPE
  1371. CStdStubBuffer_DebugServerRelease(
  1372. IN IRpcStubBuffer *This,
  1373. IN void *pv)
  1374. /*++
  1375. Routine Description:
  1376. Release a pointer previously obtained via
  1377. DebugServerQueryInterface. This function does nothing.
  1378. Arguments:
  1379. This
  1380. pv
  1381. Return Value:
  1382. None.
  1383. --*/
  1384. {
  1385. }
  1386. const IID * RPC_ENTRY
  1387. NdrpGetStubIID(
  1388. IN IRpcStubBuffer *This)
  1389. /*++
  1390. Routine Description:
  1391. This function returns a pointer to the IID for the interface stub.
  1392. Arguments:
  1393. Return Value:
  1394. --*/
  1395. {
  1396. unsigned char ** ppTemp;
  1397. unsigned char * pTemp;
  1398. CInterfaceStubVtbl *pStubVtbl;
  1399. //Get a pointer to the stub vtbl.
  1400. ppTemp = (unsigned char **) This;
  1401. pTemp = *ppTemp;
  1402. pTemp -= sizeof(CInterfaceStubHeader);
  1403. pStubVtbl = (CInterfaceStubVtbl *) pTemp;
  1404. return pStubVtbl->header.piid;
  1405. }
  1406. void RPC_ENTRY
  1407. NdrStubInitialize(
  1408. IN PRPC_MESSAGE pRpcMsg,
  1409. IN PMIDL_STUB_MESSAGE pStubMsg,
  1410. IN PMIDL_STUB_DESC pStubDescriptor,
  1411. IN IRpcChannelBuffer * pRpcChannelBuffer )
  1412. /*++
  1413. Routine Description:
  1414. This routine is called by the server stub before unmarshalling.
  1415. It sets up some stub message fields.
  1416. Arguments:
  1417. pRpcMsg
  1418. pStubMsg
  1419. pStubDescriptor
  1420. pRpcChannelBuffer
  1421. Return Value:
  1422. None.
  1423. --*/
  1424. {
  1425. NdrServerInitialize( pRpcMsg,
  1426. pStubMsg,
  1427. pStubDescriptor);
  1428. pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
  1429. // This exception should be raised after initializing StubMsg.
  1430. if ( pStubDescriptor->Version > NDR_VERSION )
  1431. {
  1432. NDR_ASSERT( 0, "ServerInitializePartial : bad version number" );
  1433. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  1434. }
  1435. pRpcChannelBuffer->lpVtbl->GetDestCtx( pRpcChannelBuffer,
  1436. &pStubMsg->dwDestContext,
  1437. &pStubMsg->pvDestContext);
  1438. }
  1439. void RPC_ENTRY
  1440. NdrStubInitializePartial(
  1441. IN PRPC_MESSAGE pRpcMsg,
  1442. IN PMIDL_STUB_MESSAGE pStubMsg,
  1443. IN PMIDL_STUB_DESC pStubDescriptor,
  1444. IN IRpcChannelBuffer * pRpcChannelBuffer,
  1445. IN unsigned long RequestedBufferSize )
  1446. /*++
  1447. Routine Description:
  1448. This routine is called by the server stub before unmarshalling.
  1449. It sets up some stub message fields.
  1450. Arguments:
  1451. pRpcMsg
  1452. pStubMsg
  1453. pStubDescriptor
  1454. pRpcChannelBuffer
  1455. Return Value:
  1456. None.
  1457. --*/
  1458. {
  1459. NdrServerInitialize( pRpcMsg,
  1460. pStubMsg,
  1461. pStubDescriptor);
  1462. pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
  1463. pRpcChannelBuffer->lpVtbl->GetDestCtx( pRpcChannelBuffer,
  1464. &pStubMsg->dwDestContext,
  1465. &pStubMsg->pvDestContext);
  1466. MakeSureWeHaveNonPipeArgs( pStubMsg, RequestedBufferSize );
  1467. }
  1468. void RPC_ENTRY
  1469. NdrStubGetBuffer(
  1470. IN IRpcStubBuffer * This,
  1471. IN IRpcChannelBuffer * pChannel,
  1472. IN PMIDL_STUB_MESSAGE pStubMsg)
  1473. /*++
  1474. Routine Description:
  1475. Get a message buffer from the channel
  1476. Arguments:
  1477. This
  1478. pChannel
  1479. pStubMsg
  1480. Return Value:
  1481. None. If an error occurs, this functions raises an exception.
  1482. --*/
  1483. {
  1484. HRESULT hr;
  1485. const IID * pIID;
  1486. pIID = NdrpGetStubIID(This);
  1487. pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
  1488. pStubMsg->RpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
  1489. hr = pChannel->lpVtbl->GetBuffer(pChannel, (RPCOLEMESSAGE *) pStubMsg->RpcMsg, *pIID);
  1490. if(FAILED(hr))
  1491. {
  1492. RpcRaiseException(hr);
  1493. }
  1494. pStubMsg->Buffer = (unsigned char *) pStubMsg->RpcMsg->Buffer;
  1495. pStubMsg->fBufferValid = TRUE;
  1496. }
  1497. HRESULT RPC_ENTRY
  1498. NdrStubErrorHandler(
  1499. IN DWORD dwExceptionCode)
  1500. /*++
  1501. Routine Description:
  1502. Map exceptions into HRESULT failure codes. If we caught an
  1503. exception from the server object, then propagate the
  1504. exception to the channel.
  1505. Arguments:
  1506. dwExceptionCode
  1507. Return Value:
  1508. This function returns an HRESULT failure code.
  1509. --*/
  1510. {
  1511. HRESULT hr;
  1512. if(FAILED((HRESULT) dwExceptionCode))
  1513. hr = (HRESULT) dwExceptionCode;
  1514. else
  1515. hr = HRESULT_FROM_WIN32(dwExceptionCode);
  1516. return hr;
  1517. }
  1518. EXTERN_C void RPC_ENTRY
  1519. NdrStubInitializeMarshall (
  1520. IN PRPC_MESSAGE pRpcMsg,
  1521. IN PMIDL_STUB_MESSAGE pStubMsg,
  1522. IN IRpcChannelBuffer * pRpcChannelBuffer )
  1523. /*++
  1524. Routine Description:
  1525. This routine is called by the server stub before marshalling. It
  1526. sets up some stub message fields.
  1527. Arguments:
  1528. pRpcMsg
  1529. pStubMsg
  1530. pRpcChannelBuffer
  1531. Return Value:
  1532. None.
  1533. --*/
  1534. {
  1535. pStubMsg->BufferLength = 0;
  1536. pStubMsg->IgnoreEmbeddedPointers = FALSE;
  1537. pStubMsg->fDontCallFreeInst = 0;
  1538. pStubMsg->StackTop = 0;
  1539. pRpcChannelBuffer->lpVtbl->GetDestCtx(
  1540. pRpcChannelBuffer,
  1541. &pStubMsg->dwDestContext,
  1542. &pStubMsg->pvDestContext);
  1543. }
  1544. void __RPC_STUB NdrStubForwardingFunction(
  1545. IN IRpcStubBuffer * This,
  1546. IN IRpcChannelBuffer * pChannel,
  1547. IN PRPC_MESSAGE pmsg,
  1548. OUT DWORD * pdwStubPhase)
  1549. /*++
  1550. Routine Description:
  1551. This function forwards a call to the stub for the base interface.
  1552. Arguments:
  1553. pChannel
  1554. pmsg
  1555. pdwStubPhase
  1556. Return Value:
  1557. None.
  1558. --*/
  1559. {
  1560. HRESULT hr;
  1561. unsigned char *pTemp;
  1562. CStdStubBuffer2 * pStubBuffer;
  1563. IRpcStubBuffer *pBaseStubBuffer;
  1564. pTemp = (unsigned char *)This;
  1565. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  1566. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  1567. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  1568. hr = pBaseStubBuffer->lpVtbl->Invoke(pBaseStubBuffer,
  1569. (RPCOLEMESSAGE *) pmsg,
  1570. pChannel);
  1571. if(FAILED(hr))
  1572. RpcRaiseException(hr);
  1573. }