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.

2089 lines
52 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. RpcTryExcept
  518. {
  519. pAsyncSB = (CStdAsyncStubBuffer *) ( (uchar *)This -
  520. offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) );
  521. // It causes the Finish call to happen.
  522. hr = NdrpAsyncStubSignal( pAsyncSB );
  523. }
  524. RpcExcept( EXCEPTION_EXECUTE_HANDLER)
  525. {
  526. hr = NdrStubErrorHandler( RpcExceptionCode() );
  527. }
  528. RpcEndExcept
  529. return hr;
  530. }
  531. HRESULT STDMETHODCALLTYPE
  532. CStdAsyncStubBuffer_Synchronize_Reset(
  533. IN ISynchronize *This )
  534. /*++
  535. Routine Description:
  536. This is called by the Server's Call Object as part of its Begin_* method.
  537. Arguments:
  538. Return Value: Always S_OK.
  539. Note:
  540. Works for delegated and non-delegated async stubs.
  541. --*/
  542. {
  543. IRpcStubBuffer * pStubBuffer = (IRpcStubBuffer *) ( (uchar *)This -
  544. (offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) - offsetof(CStdAsyncStubBuffer, lpVtbl)) );
  545. // Server's Call object gets S_OK...
  546. return S_OK;
  547. }
  548. //
  549. // Implementation of the stub buffer itself.
  550. //
  551. HRESULT STDMETHODCALLTYPE
  552. CStdStubBuffer_QueryInterface(
  553. IN IRpcStubBuffer *This,
  554. IN REFIID riid,
  555. OUT void ** ppvObject)
  556. /*++
  557. Routine Description:
  558. Query for an interface on the interface stub. The interface
  559. stub supports the IUnknown and IRpcStubBuffer interfaces.
  560. Arguments:
  561. riid - Supplies the IID of the interface being requested.
  562. ppvObject - Returns a pointer to the requested interface.
  563. Return Value:
  564. S_OK
  565. E_NOINTERFACE
  566. Note:
  567. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  568. CStdStubBuffer,
  569. CStdStubBuffer2,
  570. This is correct for the stubs supporting async_uuid.
  571. --*/
  572. {
  573. HRESULT hr;
  574. if ((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  575. (memcmp(&riid, &IID_IRpcStubBuffer, sizeof(IID)) == 0))
  576. {
  577. This->lpVtbl->AddRef(This);
  578. *ppvObject = This;
  579. hr = S_OK;
  580. }
  581. else if ( ((CStdStubBuffer*)This)->pCallFactoryVtbl != 0 &&
  582. memcmp(&riid, &IID_ICallFactory, sizeof(IID)) == 0 )
  583. {
  584. This->lpVtbl->AddRef(This);
  585. *ppvObject = ( (uchar *)This +
  586. (offsetof(CStdStubBuffer, pCallFactoryVtbl) - offsetof(CStdStubBuffer,lpVtbl)) );
  587. hr = S_OK;
  588. }
  589. else if ( (((CStdStubBuffer*)This)->pRMBVtbl) &&
  590. (memcmp(&riid, &IID_IReleaseMarshalBuffers,sizeof(IID)) == 0))
  591. {
  592. This->lpVtbl->AddRef(This);
  593. *ppvObject = ( (uchar *)This + offsetof(CStdStubBuffer,pRMBVtbl)) ;
  594. hr = S_OK;
  595. }
  596. else if ( riid == IID_IPrivStubBuffer )
  597. {
  598. This->lpVtbl->AddRef(This);
  599. *ppvObject = This;
  600. hr = S_OK;
  601. }
  602. else
  603. {
  604. *ppvObject = 0;
  605. hr = E_NOINTERFACE;
  606. }
  607. return hr;
  608. }
  609. HRESULT STDMETHODCALLTYPE
  610. CStdAsyncStubBuffer_QueryInterface(
  611. IN IRpcStubBuffer *This,
  612. IN REFIID riid,
  613. OUT void ** ppvObject)
  614. /*++
  615. Routine Description:
  616. Query for an interface on the interface stub. The interface
  617. stub supports the IUnknown and IRpcStubBuffer interfaces.
  618. Arguments:
  619. riid - Supplies the IID of the interface being requested.
  620. ppvObject - Returns a pointer to the requested interface.
  621. Return Value:
  622. S_OK
  623. E_NOINTERFACE
  624. Note:
  625. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  626. CStdAsyncStubBuffer
  627. So this works for AsyncStubBuffer2_QueryInterface.
  628. --*/
  629. {
  630. HRESULT hr = E_NOINTERFACE;
  631. *ppvObject = 0;
  632. if ((memcmp(&riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  633. (memcmp(&riid, &IID_IRpcStubBuffer, sizeof(IID)) == 0))
  634. {
  635. *ppvObject = This;
  636. hr = S_OK;
  637. }
  638. else if ( memcmp(&riid, &IID_ISynchronize, sizeof(IID)) == 0 )
  639. {
  640. // For pSynchronize return &pAsyncSB->pSynchronizeVtbl.
  641. *ppvObject = ( (uchar *)This +
  642. (offsetof(CStdAsyncStubBuffer, pSynchronizeVtbl) - offsetof(CStdAsyncStubBuffer,lpVtbl)) );
  643. hr = S_OK;
  644. }
  645. else if ( (((CStdStubBuffer*)This)->pRMBVtbl) &&
  646. (memcmp(&riid, &IID_IReleaseMarshalBuffers,sizeof(IID)) == 0))
  647. {
  648. This->lpVtbl->AddRef(This);
  649. *ppvObject = (void *)((CStdStubBuffer*)This)->pRMBVtbl;
  650. hr = S_OK;
  651. }
  652. else if ( riid == IID_IPrivStubBuffer )
  653. {
  654. This->lpVtbl->AddRef(This);
  655. *ppvObject = This;
  656. hr = S_OK;
  657. }
  658. if ( SUCCEEDED(hr) )
  659. ((IUnknown*)*ppvObject)->lpVtbl->AddRef( (IUnknown*)*ppvObject );
  660. // This is async stub, the channel would never call a query
  661. // for anything else.
  662. return hr;
  663. }
  664. ULONG STDMETHODCALLTYPE
  665. CStdStubBuffer_AddRef(
  666. IN IRpcStubBuffer *This)
  667. /*++
  668. Routine Description:
  669. Increment reference count.
  670. Arguments:
  671. Return Value:
  672. Reference count.
  673. Note:
  674. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  675. CStdStubBuffer,
  676. CStdStubBuffer2,
  677. --*/
  678. {
  679. InterlockedIncrement(&((CStdStubBuffer *)This)->RefCount);
  680. return (ULONG) ((CStdStubBuffer *)This)->RefCount;
  681. }
  682. ULONG STDMETHODCALLTYPE
  683. CStdAsyncStubBuffer_AddRef(
  684. IN IRpcStubBuffer *This)
  685. /*++
  686. Routine Description:
  687. Increment reference count.
  688. Arguments:
  689. Return Value:
  690. Reference count.
  691. Note:
  692. The relative position of lpVtbl and pCallFactoryVtbl is the same for
  693. CStdAsyncStubBuffer,
  694. --*/
  695. {
  696. // ok: ISynchronize is not really public
  697. InterlockedIncrement(&((CStdStubBuffer *)This)->RefCount);
  698. return (ULONG) ((CStdStubBuffer *)This)->RefCount;
  699. }
  700. //
  701. // This is needed and used only by the synchronous stubs.
  702. //
  703. HRESULT STDMETHODCALLTYPE
  704. Forwarding_QueryInterface(
  705. IN IUnknown * This,
  706. IN REFIID riid,
  707. OUT void ** ppv)
  708. {
  709. *ppv = This;
  710. return S_OK;
  711. }
  712. ULONG STDMETHODCALLTYPE
  713. Forwarding_AddRef(
  714. IN IUnknown *This)
  715. {
  716. return 1;
  717. }
  718. ULONG STDMETHODCALLTYPE
  719. Forwarding_Release(
  720. IN IUnknown *This)
  721. {
  722. return 1;
  723. }
  724. ULONG STDMETHODCALLTYPE
  725. NdrCStdStubBuffer_Release(
  726. IN IRpcStubBuffer * This,
  727. IN IPSFactoryBuffer * pFactory)
  728. /*++
  729. Routine Description:
  730. Decrement reference count.
  731. Arguments:
  732. Return Value:
  733. Reference count.
  734. --*/
  735. {
  736. ULONG count;
  737. NDR_ASSERT(((CStdStubBuffer *)This)->RefCount > 0, "Invalid reference count");
  738. count = (ULONG) ((CStdStubBuffer *)This)->RefCount - 1;
  739. if(InterlockedDecrement(&((CStdStubBuffer *)This)->RefCount) == 0)
  740. {
  741. count = 0;
  742. #if DBG == 1
  743. memset(This, '\0', sizeof(CStdStubBuffer));
  744. #endif
  745. //Free the stub buffer
  746. NdrOleFree(This);
  747. //Decrement the DLL reference count.
  748. ((CStdPSFactoryBuffer*)pFactory)->lpVtbl->Release( pFactory );
  749. }
  750. return count;
  751. }
  752. ULONG STDMETHODCALLTYPE
  753. CStdAsyncStubBuffer_Release(
  754. IN IRpcStubBuffer * This
  755. )
  756. {
  757. CStdAsyncStubBuffer * pAsyncSB;
  758. ULONG count;
  759. pAsyncSB = (CStdAsyncStubBuffer*)((uchar*)This
  760. - offsetof(CStdAsyncStubBuffer,lpVtbl));
  761. NDR_ASSERT(pAsyncSB->RefCount > 0, "Async stub Invalid reference count");
  762. count = (ULONG) pAsyncSB->RefCount - 1;
  763. if ( InterlockedDecrement( &pAsyncSB->RefCount) == 0)
  764. {
  765. IPSFactoryBuffer * pFactory = pAsyncSB->pPSFactory;
  766. count = 0;
  767. NdrpAsyncStubMsgDestructor( pAsyncSB );
  768. #if DBG == 1
  769. memset( pAsyncSB, '\33', sizeof(CStdAsyncStubBuffer));
  770. #endif
  771. //Free the stub buffer
  772. NdrOleFree( pAsyncSB );
  773. //Decrement the DLL reference count.
  774. pFactory->lpVtbl->Release( pFactory );
  775. }
  776. return count;
  777. }
  778. ULONG STDMETHODCALLTYPE
  779. CStdAsyncStubBuffer2_Release(
  780. IN IRpcStubBuffer * This
  781. )
  782. {
  783. // O well, the main desctructor for the delegated async stub.
  784. CStdAsyncStubBuffer * pAsyncSB;
  785. ULONG count;
  786. pAsyncSB = (CStdAsyncStubBuffer*)((uchar*)This
  787. - offsetof(CStdAsyncStubBuffer,lpVtbl));
  788. NDR_ASSERT(pAsyncSB->RefCount > 0, "Async stub Invalid reference count");
  789. count = (ULONG) pAsyncSB->RefCount - 1;
  790. if ( InterlockedDecrement(&pAsyncSB->RefCount) == 0)
  791. {
  792. IPSFactoryBuffer * pFactory = pAsyncSB->pPSFactory;
  793. IRpcStubBuffer * pBaseStubBuffer = pAsyncSB->pBaseStubBuffer;
  794. count = 0;
  795. if( pBaseStubBuffer != 0)
  796. pBaseStubBuffer->lpVtbl->Release( pBaseStubBuffer );
  797. NdrpAsyncStubMsgDestructor( pAsyncSB );
  798. #if DBG == 1
  799. memset( pAsyncSB, '\33', sizeof(CStdAsyncStubBuffer));
  800. #endif
  801. //Free the stub buffer
  802. NdrOleFree( pAsyncSB );
  803. //Decrement the DLL reference count.
  804. pFactory->lpVtbl->Release( pFactory );
  805. }
  806. return count;
  807. }
  808. ULONG STDMETHODCALLTYPE
  809. NdrCStdStubBuffer2_Release(
  810. IN IRpcStubBuffer * This,
  811. IN IPSFactoryBuffer * pFactory)
  812. /*++
  813. Routine Description:
  814. Decrement reference count. This function supports delegation to the stub
  815. for the base interface.
  816. Arguments:
  817. Return Value:
  818. Reference count.
  819. --*/
  820. {
  821. ULONG count;
  822. unsigned char *pTemp;
  823. CStdStubBuffer2 * pStubBuffer;
  824. IRpcStubBuffer *pBaseStubBuffer;
  825. pTemp = (unsigned char *)This;
  826. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  827. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  828. NDR_ASSERT(pStubBuffer->RefCount > 0, "Invalid reference count");
  829. count = (ULONG) pStubBuffer->RefCount - 1;
  830. if(InterlockedDecrement(&pStubBuffer->RefCount) == 0)
  831. {
  832. count = 0;
  833. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  834. if(pBaseStubBuffer != 0)
  835. pBaseStubBuffer->lpVtbl->Release(pBaseStubBuffer);
  836. #if DBG == 1
  837. memset(pStubBuffer, '\0', sizeof(CStdStubBuffer2));
  838. #endif
  839. if (pStubBuffer->lpForwardingVtbl)
  840. ReleaseTemplateForwardVtbl((void **)pStubBuffer->lpForwardingVtbl);
  841. //Free the stub buffer
  842. NdrOleFree(pStubBuffer);
  843. //Decrement the DLL reference count.
  844. ((CStdPSFactoryBuffer*)pFactory)->lpVtbl->Release( pFactory );
  845. }
  846. return count;
  847. }
  848. HRESULT STDMETHODCALLTYPE
  849. CStdStubBuffer_Connect(
  850. IN IRpcStubBuffer *This,
  851. IN IUnknown * pUnkServer)
  852. /*++
  853. Routine Description:
  854. Connect the stub buffer to the server object.
  855. This is the non-delegated case.
  856. Arguments:
  857. Return Value:
  858. Notes:
  859. This works for CStdAsyncBuffer_Connect
  860. --*/
  861. {
  862. HRESULT hr;
  863. const IID *pIID;
  864. IUnknown *punk = 0;
  865. NDR_ASSERT(pUnkServer != 0, "pUnkServer parameter is invalid.");
  866. pIID = NdrpGetStubIID(This);
  867. hr = pUnkServer->lpVtbl->QueryInterface(pUnkServer, *pIID, (void**)&punk);
  868. punk = (IUnknown *) InterlockedExchangePointer(
  869. (PVOID *) &((CStdStubBuffer *) This)->pvServerObject, (PVOID) punk);
  870. if(punk != 0)
  871. {
  872. //The stub was already connected. Release the old interface pointer.
  873. punk->lpVtbl->Release(punk);
  874. }
  875. return hr;
  876. }
  877. HRESULT STDMETHODCALLTYPE
  878. CStdAsyncStubBuffer_Connect(
  879. IN IRpcStubBuffer *This,
  880. IN IUnknown * punkServer)
  881. /*++
  882. Routine Description:
  883. Connect the stub buffer to the server object.
  884. This is the non-delegated case.
  885. Arguments:
  886. punkServer - this is a pointer to AsyncIFoo already queried by the channel.
  887. (when delegation same thing)
  888. Return Value:
  889. Notes:
  890. This works the same as for StubBuffer_Connect.
  891. Note that an async stub is always created disconnected.
  892. It also always keep a pointer to the real server not
  893. to a forwarder object.
  894. --*/
  895. {
  896. IUnknown *punk = 0;
  897. NDR_ASSERT(punkServer != 0, "pUnkServer parameter is invalid.");
  898. punkServer->lpVtbl->AddRef( punkServer );
  899. punk = (IUnknown *) InterlockedExchangePointer(
  900. (PVOID *) &((CStdStubBuffer *) This)->pvServerObject, (PVOID) punkServer);
  901. if( punk != 0 )
  902. {
  903. // The stub was already connected. Release the old interface pointer.
  904. punk->lpVtbl->Release(punk);
  905. }
  906. return S_OK;
  907. }
  908. HRESULT STDMETHODCALLTYPE
  909. CStdStubBuffer2_Connect(
  910. IN IRpcStubBuffer *This,
  911. IN IUnknown * pUnkServer)
  912. /*++
  913. Routine Description:
  914. Connect the stub buffer to the server object.
  915. This is the delegated case.
  916. Arguments:
  917. Return Value:
  918. --*/
  919. {
  920. HRESULT hr;
  921. unsigned char * pTemp;
  922. CStdStubBuffer2 * pStubBuffer;
  923. IRpcStubBuffer * pBaseStubBuffer;
  924. hr = CStdStubBuffer_Connect(This, pUnkServer);
  925. if(SUCCEEDED(hr))
  926. {
  927. //Connect the stub for the base interface.
  928. pTemp = (unsigned char *)This;
  929. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  930. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  931. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  932. if(pBaseStubBuffer != 0)
  933. {
  934. hr = pBaseStubBuffer->lpVtbl->Connect(pBaseStubBuffer,
  935. (IUnknown *) &pStubBuffer->lpForwardingVtbl);
  936. }
  937. }
  938. return hr;
  939. }
  940. HRESULT STDMETHODCALLTYPE
  941. CStdAsyncStubBuffer2_Connect(
  942. IN IRpcStubBuffer *This,
  943. IN IUnknown * pUnkServer)
  944. /*++
  945. Routine Description:
  946. Connect the stub buffer to the server object.
  947. This is the delegated case.
  948. Arguments:
  949. Return Value:
  950. Notes:
  951. This is different from CStdAsyncBuffer2_Connect
  952. as the base is connected to the real server here.
  953. Note that an async stub is always created disconnected.
  954. It also always keep a pointer to the real server not
  955. to a forwarder object.
  956. --*/
  957. {
  958. HRESULT hr;
  959. unsigned char * pTemp;
  960. CStdStubBuffer2 * pStubBuffer;
  961. IRpcStubBuffer * pBaseStubBuffer;
  962. hr = CStdAsyncStubBuffer_Connect(This, pUnkServer);
  963. if(SUCCEEDED(hr))
  964. {
  965. //Connect the stub for the base interface.
  966. pTemp = (unsigned char *)This;
  967. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  968. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  969. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  970. if(pBaseStubBuffer != 0)
  971. {
  972. hr = pBaseStubBuffer->lpVtbl->Connect(
  973. pBaseStubBuffer,
  974. pUnkServer );
  975. }
  976. }
  977. return hr;
  978. }
  979. void STDMETHODCALLTYPE
  980. CStdStubBuffer_Disconnect(
  981. IN IRpcStubBuffer *This)
  982. /*++
  983. Routine Description:
  984. Disconnect the stub from the server object.
  985. Arguments:
  986. Return Value:
  987. None.
  988. Notes:
  989. This works for CStdAsyncBuffer_Disconnect
  990. --*/
  991. {
  992. IUnknown * punk;
  993. //Set pvServerObject to zero.
  994. punk = (IUnknown *) InterlockedExchangePointer(
  995. (PVOID*) &((CStdStubBuffer *)This)->pvServerObject, 0);
  996. if(punk != 0)
  997. {
  998. //
  999. // Free the old interface pointer.
  1000. //
  1001. punk->lpVtbl->Release(punk);
  1002. }
  1003. }
  1004. void STDMETHODCALLTYPE
  1005. CStdAsyncStubBuffer_Disconnect(
  1006. IN IRpcStubBuffer *This)
  1007. /*++
  1008. Routine Description:
  1009. Disconnect the stub from the server object.
  1010. Arguments:
  1011. Return Value:
  1012. None.
  1013. --*/
  1014. {
  1015. // Same as Buffer_Disconnect
  1016. IUnknown * punk;
  1017. //Set pvServerObject to zero.
  1018. punk = (IUnknown *) InterlockedExchangePointer(
  1019. (PVOID*) &((CStdStubBuffer *)This)->pvServerObject, 0);
  1020. // Free the old interface pointer.
  1021. if(punk != 0)
  1022. punk->lpVtbl->Release(punk);
  1023. }
  1024. void STDMETHODCALLTYPE
  1025. CStdStubBuffer2_Disconnect(
  1026. IN IRpcStubBuffer *This)
  1027. /*++
  1028. Routine Description:
  1029. Disconnect the stub buffer from the server object.
  1030. Arguments:
  1031. Return Value:
  1032. None.
  1033. --*/
  1034. {
  1035. IUnknown * punk;
  1036. unsigned char *pTemp;
  1037. CStdStubBuffer2 * pStubBuffer;
  1038. IRpcStubBuffer *pBaseStubBuffer;
  1039. pTemp = (unsigned char *)This;
  1040. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  1041. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  1042. //Disconnect the stub for the base interface.
  1043. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  1044. if(pBaseStubBuffer != 0)
  1045. pBaseStubBuffer->lpVtbl->Disconnect(pBaseStubBuffer);
  1046. //Set pvServerObject to zero.
  1047. punk = (IUnknown *) InterlockedExchangePointer(
  1048. (PVOID*) &pStubBuffer->pvServerObject, 0);
  1049. if(punk != 0)
  1050. {
  1051. //
  1052. // Free the old interface pointer.
  1053. //
  1054. punk->lpVtbl->Release(punk);
  1055. }
  1056. }
  1057. void STDMETHODCALLTYPE
  1058. CStdAsyncStubBuffer2_Disconnect(
  1059. IN IRpcStubBuffer *This)
  1060. /*++
  1061. Routine Description:
  1062. Disconnect the stub buffer from the server object.
  1063. Arguments:
  1064. Return Value:
  1065. None.
  1066. --*/
  1067. {
  1068. IUnknown * punk;
  1069. unsigned char *pTemp;
  1070. CStdStubBuffer2 * pStubBuffer;
  1071. IRpcStubBuffer *pBaseStubBuffer;
  1072. pTemp = (unsigned char *)This;
  1073. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  1074. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  1075. //Disconnect the stub for the base interface.
  1076. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  1077. if(pBaseStubBuffer != 0)
  1078. pBaseStubBuffer->lpVtbl->Disconnect(pBaseStubBuffer);
  1079. //Set pvServerObject to zero.
  1080. punk = (IUnknown *) InterlockedExchangePointer(
  1081. (PVOID*) &pStubBuffer->pvServerObject, 0);
  1082. // Free the old interface pointer.
  1083. if(punk != 0)
  1084. punk->lpVtbl->Release(punk);
  1085. }
  1086. HRESULT STDMETHODCALLTYPE
  1087. CStdStubBuffer_Invoke(
  1088. IN IRpcStubBuffer * This,
  1089. IN RPCOLEMESSAGE * prpcmsg,
  1090. IN IRpcChannelBuffer * pRpcChannelBuffer)
  1091. /*++
  1092. Routine Description:
  1093. Invoke a stub function via the dispatch table.
  1094. Arguments:
  1095. Return Value:
  1096. --*/
  1097. {
  1098. HRESULT hr = S_OK;
  1099. unsigned char ** ppTemp;
  1100. unsigned char * pTemp;
  1101. CInterfaceStubVtbl *pStubVtbl;
  1102. unsigned long dwServerPhase = STUB_UNMARSHAL;
  1103. //Get a pointer to the stub vtbl.
  1104. ppTemp = (unsigned char **) This;
  1105. pTemp = *ppTemp;
  1106. pTemp -= sizeof(CInterfaceStubHeader);
  1107. pStubVtbl = (CInterfaceStubVtbl *) pTemp;
  1108. RpcTryExcept
  1109. //
  1110. //Check if procnum is valid.
  1111. //
  1112. if((prpcmsg->iMethod >= pStubVtbl->header.DispatchTableCount) ||
  1113. (prpcmsg->iMethod < 3))
  1114. {
  1115. RpcRaiseException(RPC_S_PROCNUM_OUT_OF_RANGE);
  1116. }
  1117. // null indicates pure-interpreted
  1118. if ( pStubVtbl->header.pDispatchTable != 0)
  1119. {
  1120. (*pStubVtbl->header.pDispatchTable[prpcmsg->iMethod])(
  1121. This,
  1122. pRpcChannelBuffer,
  1123. (PRPC_MESSAGE) prpcmsg,
  1124. &dwServerPhase);
  1125. }
  1126. else
  1127. {
  1128. PMIDL_SERVER_INFO pServerInfo;
  1129. PMIDL_STUB_DESC pStubDesc;
  1130. pServerInfo = (PMIDL_SERVER_INFO) pStubVtbl->header.pServerInfo;
  1131. pStubDesc = pServerInfo->pStubDesc;
  1132. #ifdef BUILD_NDR64
  1133. if ( pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES )
  1134. {
  1135. NdrStubCall3(This,
  1136. pRpcChannelBuffer,
  1137. (PRPC_MESSAGE) prpcmsg,
  1138. &dwServerPhase);
  1139. }
  1140. else
  1141. #endif
  1142. if ( MIDL_VERSION_3_0_39 <= pServerInfo->pStubDesc->MIDLVersion )
  1143. {
  1144. // Since MIDL 3.0.39 we have a proc flag that indicates
  1145. // which interpeter to call. This is because the NDR version
  1146. // may be bigger than 1.1 for other reasons.
  1147. PFORMAT_STRING pProcFormat;
  1148. unsigned short ProcOffset;
  1149. ProcOffset = pServerInfo->FmtStringOffset[ prpcmsg->iMethod ];
  1150. pProcFormat = & pServerInfo->ProcString[ ProcOffset ];
  1151. if ( pProcFormat[1] & Oi_OBJ_USE_V2_INTERPRETER )
  1152. {
  1153. NdrStubCall2(
  1154. This,
  1155. pRpcChannelBuffer,
  1156. (PRPC_MESSAGE) prpcmsg,
  1157. &dwServerPhase );
  1158. }
  1159. else
  1160. {
  1161. #if defined(__RPC_WIN64__)
  1162. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  1163. #else
  1164. NdrStubCall(
  1165. This,
  1166. pRpcChannelBuffer,
  1167. (PRPC_MESSAGE) prpcmsg,
  1168. &dwServerPhase );
  1169. #endif
  1170. }
  1171. }
  1172. else
  1173. {
  1174. // Prior to that, the NDR version (on per file basis)
  1175. // was the only indication of -Oi2.
  1176. if ( pStubDesc->Version <= NDR_VERSION_1_1 )
  1177. {
  1178. #if defined(__RPC_WIN64__)
  1179. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  1180. #else
  1181. NdrStubCall(
  1182. This,
  1183. pRpcChannelBuffer,
  1184. (PRPC_MESSAGE) prpcmsg,
  1185. &dwServerPhase );
  1186. #endif
  1187. }
  1188. else
  1189. {
  1190. NdrStubCall2(
  1191. This,
  1192. pRpcChannelBuffer,
  1193. (PRPC_MESSAGE) prpcmsg,
  1194. &dwServerPhase );
  1195. }
  1196. }
  1197. }
  1198. RpcExcept(dwServerPhase == STUB_CALL_SERVER ?
  1199. EXCEPTION_CONTINUE_SEARCH :
  1200. EXCEPTION_EXECUTE_HANDLER)
  1201. hr = NdrStubErrorHandler( RpcExceptionCode() );
  1202. RpcEndExcept
  1203. return hr;
  1204. }
  1205. HRESULT STDMETHODCALLTYPE
  1206. CStdAsyncStubBuffer_Invoke(
  1207. IN IRpcStubBuffer * This,
  1208. IN RPCOLEMESSAGE * prpcmsg,
  1209. IN IRpcChannelBuffer * pRpcChannelBuffer)
  1210. /*++
  1211. Routine Description:
  1212. Invoke a stub function via the dispatch table.
  1213. Arguments:
  1214. Return Value:
  1215. --*/
  1216. {
  1217. HRESULT hr = S_OK;
  1218. unsigned char ** ppTemp;
  1219. unsigned char * pTemp;
  1220. CInterfaceStubVtbl *pStubVtbl;
  1221. unsigned long dwServerPhase = STUB_UNMARSHAL;
  1222. //Get a pointer to the stub vtbl.
  1223. ppTemp = (unsigned char **) This;
  1224. pTemp = *ppTemp;
  1225. pTemp -= sizeof(CInterfaceStubHeader);
  1226. pStubVtbl = (CInterfaceStubVtbl *) pTemp;
  1227. RpcTryExcept
  1228. {
  1229. PMIDL_SERVER_INFO pServerInfo;
  1230. // Check if procnum is valid.
  1231. // Note, this is a sync proc number.
  1232. //
  1233. if((prpcmsg->iMethod >= pStubVtbl->header.DispatchTableCount) ||
  1234. (prpcmsg->iMethod < 3))
  1235. {
  1236. RpcRaiseException(RPC_S_PROCNUM_OUT_OF_RANGE);
  1237. }
  1238. // Async DCOM is supported only in the new interpreter,
  1239. // and only since MIDL 5.0.+
  1240. pServerInfo = (PMIDL_SERVER_INFO) pStubVtbl->header.pServerInfo;
  1241. if ( pServerInfo->pStubDesc->MIDLVersion < MIDL_VERSION_5_0_136 )
  1242. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1243. // Non null would indicate an -Os stub or a delegation case.
  1244. if ( pStubVtbl->header.pDispatchTable != 0)
  1245. {
  1246. (*pStubVtbl->header.pDispatchTable[prpcmsg->iMethod])(
  1247. This,
  1248. pRpcChannelBuffer,
  1249. (PRPC_MESSAGE) prpcmsg,
  1250. &dwServerPhase);
  1251. }
  1252. else
  1253. {
  1254. #if defined(BUILD_NDR64)
  1255. if ( pServerInfo->pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES )
  1256. {
  1257. switch ( NdrpGetSyntaxType( ( (PRPC_MESSAGE) prpcmsg )->TransferSyntax ) )
  1258. {
  1259. case XFER_SYNTAX_DCE:
  1260. NdrDcomAsyncStubCall( This,
  1261. pRpcChannelBuffer,
  1262. (PRPC_MESSAGE) prpcmsg,
  1263. &dwServerPhase );
  1264. break;
  1265. case XFER_SYNTAX_NDR64:
  1266. Ndr64DcomAsyncStubCall( This,
  1267. pRpcChannelBuffer,
  1268. (PRPC_MESSAGE) prpcmsg,
  1269. &dwServerPhase );
  1270. break;
  1271. }
  1272. }
  1273. else
  1274. #endif
  1275. NdrDcomAsyncStubCall( This,
  1276. pRpcChannelBuffer,
  1277. (PRPC_MESSAGE) prpcmsg,
  1278. &dwServerPhase );
  1279. }
  1280. }
  1281. RpcExcept(dwServerPhase == STUB_CALL_SERVER ?
  1282. EXCEPTION_CONTINUE_SEARCH :
  1283. EXCEPTION_EXECUTE_HANDLER)
  1284. hr = NdrStubErrorHandler( RpcExceptionCode() );
  1285. RpcEndExcept
  1286. return hr;
  1287. }
  1288. IRpcStubBuffer * STDMETHODCALLTYPE
  1289. CStdStubBuffer_IsIIDSupported(
  1290. IN IRpcStubBuffer *This,
  1291. IN REFIID riid)
  1292. /*++
  1293. Routine Description:
  1294. If the stub buffer supports the specified interface,
  1295. then return an IRpcStubBuffer *. If the interface is not
  1296. supported, then return zero.
  1297. Arguments:
  1298. Return Value:
  1299. Notes:
  1300. This works for CStdAsyncStubBuffer,CStdAsyncStubBuffer2.
  1301. --*/
  1302. {
  1303. CStdStubBuffer * pCThis = (CStdStubBuffer *) This;
  1304. const IID * pIID;
  1305. IRpcStubBuffer * pInterfaceStub = 0;
  1306. pIID = NdrpGetStubIID(This);
  1307. if(memcmp(&riid, pIID, sizeof(IID)) == 0)
  1308. {
  1309. if(pCThis->pvServerObject != 0)
  1310. {
  1311. pInterfaceStub = This;
  1312. pInterfaceStub->lpVtbl->AddRef(pInterfaceStub);
  1313. }
  1314. }
  1315. return pInterfaceStub;
  1316. }
  1317. ULONG STDMETHODCALLTYPE
  1318. CStdStubBuffer_CountRefs(
  1319. IN IRpcStubBuffer *This)
  1320. /*++
  1321. Routine Description:
  1322. Count the number of references to the server object.
  1323. Arguments:
  1324. Return Value:
  1325. Notes:
  1326. This works for CStdAsyncStubBuffer.
  1327. --*/
  1328. {
  1329. ULONG count = 0;
  1330. if(((CStdStubBuffer *)This)->pvServerObject != 0)
  1331. count++;
  1332. return count;
  1333. }
  1334. ULONG STDMETHODCALLTYPE
  1335. CStdStubBuffer2_CountRefs(
  1336. IN IRpcStubBuffer *This)
  1337. /*++
  1338. Routine Description:
  1339. Count the number of references to the server object.
  1340. Arguments:
  1341. Return Value:
  1342. Notes:
  1343. This works for CStdAsyncStubBuffer2.
  1344. --*/
  1345. {
  1346. ULONG count;
  1347. unsigned char *pTemp;
  1348. CStdStubBuffer2 * pStubBuffer;
  1349. IRpcStubBuffer *pBaseStubBuffer;
  1350. pTemp = (unsigned char *)This;
  1351. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  1352. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  1353. count = CStdStubBuffer_CountRefs(This);
  1354. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  1355. if(pBaseStubBuffer != 0)
  1356. count += pBaseStubBuffer->lpVtbl->CountRefs(pBaseStubBuffer);
  1357. return count;
  1358. }
  1359. HRESULT STDMETHODCALLTYPE
  1360. CStdStubBuffer_DebugServerQueryInterface(
  1361. IN IRpcStubBuffer *This,
  1362. OUT void **ppv)
  1363. /*++
  1364. Routine Description:
  1365. Return the interface pointer to the server object.
  1366. Arguments:
  1367. Return Value:
  1368. --*/
  1369. {
  1370. HRESULT hr;
  1371. *ppv = ((CStdStubBuffer *)This)->pvServerObject;
  1372. if(*ppv != 0)
  1373. hr = S_OK;
  1374. else
  1375. hr = CO_E_OBJNOTCONNECTED;
  1376. return hr;
  1377. }
  1378. void STDMETHODCALLTYPE
  1379. CStdStubBuffer_DebugServerRelease(
  1380. IN IRpcStubBuffer *This,
  1381. IN void *pv)
  1382. /*++
  1383. Routine Description:
  1384. Release a pointer previously obtained via
  1385. DebugServerQueryInterface. This function does nothing.
  1386. Arguments:
  1387. This
  1388. pv
  1389. Return Value:
  1390. None.
  1391. --*/
  1392. {
  1393. }
  1394. const IID * RPC_ENTRY
  1395. NdrpGetStubIID(
  1396. IN IRpcStubBuffer *This)
  1397. /*++
  1398. Routine Description:
  1399. This function returns a pointer to the IID for the interface stub.
  1400. Arguments:
  1401. Return Value:
  1402. --*/
  1403. {
  1404. unsigned char ** ppTemp;
  1405. unsigned char * pTemp;
  1406. CInterfaceStubVtbl *pStubVtbl;
  1407. //Get a pointer to the stub vtbl.
  1408. ppTemp = (unsigned char **) This;
  1409. pTemp = *ppTemp;
  1410. pTemp -= sizeof(CInterfaceStubHeader);
  1411. pStubVtbl = (CInterfaceStubVtbl *) pTemp;
  1412. return pStubVtbl->header.piid;
  1413. }
  1414. void RPC_ENTRY
  1415. NdrStubInitialize(
  1416. IN PRPC_MESSAGE pRpcMsg,
  1417. IN PMIDL_STUB_MESSAGE pStubMsg,
  1418. IN PMIDL_STUB_DESC pStubDescriptor,
  1419. IN IRpcChannelBuffer * pRpcChannelBuffer )
  1420. /*++
  1421. Routine Description:
  1422. This routine is called by the server stub before unmarshalling.
  1423. It sets up some stub message fields.
  1424. Arguments:
  1425. pRpcMsg
  1426. pStubMsg
  1427. pStubDescriptor
  1428. pRpcChannelBuffer
  1429. Return Value:
  1430. None.
  1431. --*/
  1432. {
  1433. NdrServerInitialize( pRpcMsg,
  1434. pStubMsg,
  1435. pStubDescriptor);
  1436. pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
  1437. // This exception should be raised after initializing StubMsg.
  1438. if ( pStubDescriptor->Version > NDR_VERSION )
  1439. {
  1440. NDR_ASSERT( 0, "ServerInitializePartial : bad version number" );
  1441. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  1442. }
  1443. pRpcChannelBuffer->lpVtbl->GetDestCtx( pRpcChannelBuffer,
  1444. &pStubMsg->dwDestContext,
  1445. &pStubMsg->pvDestContext);
  1446. }
  1447. void RPC_ENTRY
  1448. NdrStubInitializePartial(
  1449. IN PRPC_MESSAGE pRpcMsg,
  1450. IN PMIDL_STUB_MESSAGE pStubMsg,
  1451. IN PMIDL_STUB_DESC pStubDescriptor,
  1452. IN IRpcChannelBuffer * pRpcChannelBuffer,
  1453. IN unsigned long RequestedBufferSize )
  1454. /*++
  1455. Routine Description:
  1456. This routine is called by the server stub before unmarshalling.
  1457. It sets up some stub message fields.
  1458. Arguments:
  1459. pRpcMsg
  1460. pStubMsg
  1461. pStubDescriptor
  1462. pRpcChannelBuffer
  1463. Return Value:
  1464. None.
  1465. --*/
  1466. {
  1467. NdrServerInitialize( pRpcMsg,
  1468. pStubMsg,
  1469. pStubDescriptor);
  1470. pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
  1471. pRpcChannelBuffer->lpVtbl->GetDestCtx( pRpcChannelBuffer,
  1472. &pStubMsg->dwDestContext,
  1473. &pStubMsg->pvDestContext);
  1474. MakeSureWeHaveNonPipeArgs( pStubMsg, RequestedBufferSize );
  1475. }
  1476. void RPC_ENTRY
  1477. NdrStubGetBuffer(
  1478. IN IRpcStubBuffer * This,
  1479. IN IRpcChannelBuffer * pChannel,
  1480. IN PMIDL_STUB_MESSAGE pStubMsg)
  1481. /*++
  1482. Routine Description:
  1483. Get a message buffer from the channel
  1484. Arguments:
  1485. This
  1486. pChannel
  1487. pStubMsg
  1488. Return Value:
  1489. None. If an error occurs, this functions raises an exception.
  1490. --*/
  1491. {
  1492. HRESULT hr;
  1493. const IID * pIID;
  1494. pIID = NdrpGetStubIID(This);
  1495. pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
  1496. pStubMsg->RpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
  1497. hr = pChannel->lpVtbl->GetBuffer(pChannel, (RPCOLEMESSAGE *) pStubMsg->RpcMsg, *pIID);
  1498. if(FAILED(hr))
  1499. {
  1500. RpcRaiseException(hr);
  1501. }
  1502. pStubMsg->Buffer = (unsigned char *) pStubMsg->RpcMsg->Buffer;
  1503. pStubMsg->fBufferValid = TRUE;
  1504. }
  1505. HRESULT RPC_ENTRY
  1506. NdrStubErrorHandler(
  1507. IN DWORD dwExceptionCode)
  1508. /*++
  1509. Routine Description:
  1510. Map exceptions into HRESULT failure codes. If we caught an
  1511. exception from the server object, then propagate the
  1512. exception to the channel.
  1513. Arguments:
  1514. dwExceptionCode
  1515. Return Value:
  1516. This function returns an HRESULT failure code.
  1517. --*/
  1518. {
  1519. HRESULT hr;
  1520. if(FAILED((HRESULT) dwExceptionCode))
  1521. hr = (HRESULT) dwExceptionCode;
  1522. else
  1523. hr = HRESULT_FROM_WIN32(dwExceptionCode);
  1524. return hr;
  1525. }
  1526. EXTERN_C void RPC_ENTRY
  1527. NdrStubInitializeMarshall (
  1528. IN PRPC_MESSAGE pRpcMsg,
  1529. IN PMIDL_STUB_MESSAGE pStubMsg,
  1530. IN IRpcChannelBuffer * pRpcChannelBuffer )
  1531. /*++
  1532. Routine Description:
  1533. This routine is called by the server stub before marshalling. It
  1534. sets up some stub message fields.
  1535. Arguments:
  1536. pRpcMsg
  1537. pStubMsg
  1538. pRpcChannelBuffer
  1539. Return Value:
  1540. None.
  1541. --*/
  1542. {
  1543. pStubMsg->BufferLength = 0;
  1544. pStubMsg->IgnoreEmbeddedPointers = FALSE;
  1545. pStubMsg->fDontCallFreeInst = 0;
  1546. pStubMsg->StackTop = 0;
  1547. pRpcChannelBuffer->lpVtbl->GetDestCtx(
  1548. pRpcChannelBuffer,
  1549. &pStubMsg->dwDestContext,
  1550. &pStubMsg->pvDestContext);
  1551. }
  1552. void __RPC_STUB NdrStubForwardingFunction(
  1553. IN IRpcStubBuffer * This,
  1554. IN IRpcChannelBuffer * pChannel,
  1555. IN PRPC_MESSAGE pmsg,
  1556. OUT DWORD * pdwStubPhase)
  1557. /*++
  1558. Routine Description:
  1559. This function forwards a call to the stub for the base interface.
  1560. Arguments:
  1561. pChannel
  1562. pmsg
  1563. pdwStubPhase
  1564. Return Value:
  1565. None.
  1566. --*/
  1567. {
  1568. HRESULT hr;
  1569. unsigned char *pTemp;
  1570. CStdStubBuffer2 * pStubBuffer;
  1571. IRpcStubBuffer *pBaseStubBuffer;
  1572. pTemp = (unsigned char *)This;
  1573. pTemp -= offsetof(CStdStubBuffer2, lpVtbl);
  1574. pStubBuffer = (CStdStubBuffer2 *) pTemp;
  1575. pBaseStubBuffer = pStubBuffer->pBaseStubBuffer;
  1576. hr = pBaseStubBuffer->lpVtbl->Invoke(pBaseStubBuffer,
  1577. (RPCOLEMESSAGE *) pmsg,
  1578. pChannel);
  1579. if(FAILED(hr))
  1580. RpcRaiseException(hr);
  1581. }