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.

1174 lines
37 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name :
  4. mulsyntx.c
  5. Abstract :
  6. This file contains multiple transfer syntaxes negotiation related code
  7. Author :
  8. Yong Qu yongqu September 1999.
  9. Revision History :
  10. ---------------------------------------------------------------------*/
  11. #include "precomp.hxx"
  12. #define CINTERFACE
  13. #include "ndrole.h"
  14. #include "rpcproxy.h"
  15. #include "expr.h"
  16. #include "auxilary.h"
  17. #include "..\..\ndr20\pipendr.h"
  18. extern const uchar Ndr64HandleTypeMap[] =
  19. {
  20. 0,
  21. FC64_BIND_GENERIC,
  22. FC64_BIND_PRIMITIVE,
  23. FC64_AUTO_HANDLE,
  24. FC64_CALLBACK_HANDLE
  25. } ;
  26. extern const SYNTAX_DISPATCH_TABLE SyncDceClient =
  27. {
  28. NdrpClientInit,
  29. NdrpSizing,
  30. NdrpClientMarshal,
  31. NdrpClientUnMarshal,
  32. NdrpClientExceptionHandling,
  33. NdrpClientFinally
  34. };
  35. extern const SYNTAX_DISPATCH_TABLE AsyncDceClient =
  36. {
  37. NdrpClientInit,
  38. NdrpSizing,
  39. NdrpClientMarshal,
  40. NdrpClientUnMarshal,
  41. NdrpAsyncClientExceptionHandling,
  42. NdrpClientFinally
  43. };
  44. extern const SYNTAX_DISPATCH_TABLE SyncDcomDceClient =
  45. {
  46. NdrpClientInit,
  47. NdrpSizing,
  48. NdrpClientMarshal,
  49. NdrpClientUnMarshal,
  50. NdrpDcomClientExceptionHandling,
  51. NdrpClientFinally
  52. };
  53. extern const SYNTAX_DISPATCH_TABLE SyncNdr64Client =
  54. {
  55. Ndr64pClientInit,
  56. Ndr64pSizing,
  57. Ndr64pClientMarshal,
  58. Ndr64pClientUnMarshal,
  59. Ndr64pClientExceptionHandling,
  60. Ndr64pClientFinally
  61. };
  62. extern const SYNTAX_DISPATCH_TABLE SyncDcomNdr64Client =
  63. {
  64. Ndr64pClientInit,
  65. Ndr64pSizing,
  66. Ndr64pClientMarshal,
  67. Ndr64pClientUnMarshal,
  68. Ndr64pDcomClientExceptionHandling,
  69. Ndr64pClientFinally
  70. };
  71. const RPC_SYNTAX_IDENTIFIER NDR_TRANSFER_SYNTAX = {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
  72. const RPC_SYNTAX_IDENTIFIER NDR64_TRANSFER_SYNTAX = {{0x71710533,0xbeba,0x4937,{0x83, 0x19, 0xb5, 0xdb, 0xef, 0x9c, 0xcc, 0x36}},{1,0}};
  73. const RPC_SYNTAX_IDENTIFIER FAKE_NDR64_TRANSFER_SYNTAX = { { 0xb4537da9,0x3d03,0x4f6b,{0xb5, 0x94, 0x52, 0xb2, 0x87, 0x4e, 0xe9, 0xd0} }, {1,0} };
  74. CStdProxyBuffer * RPC_ENTRY
  75. NdrGetProxyBuffer(
  76. void *pThis);
  77. void
  78. EnsureNSLoaded();
  79. #pragma code_seg(".ndr64")
  80. __inline
  81. const IID * RPC_ENTRY
  82. NdrGetSyncProxyIID(
  83. IN void *pThis)
  84. /*++
  85. Routine Description:
  86. The NDRGetSyncProxyIID function returns a pointer to IID.
  87. Arguments:
  88. pThis - Supplies a pointer to the async interface proxy.
  89. Return Value:
  90. This function returns a pointer to the corresponding sync IID.
  91. --*/
  92. {
  93. CStdAsyncProxyBuffer * pAsyncPB = ( CStdAsyncProxyBuffer *) NdrGetProxyBuffer( pThis );
  94. return pAsyncPB->pSyncIID;
  95. }
  96. void RPC_ENTRY
  97. Ndr64SetupClientContextVtbl ( NDR_PROC_CONTEXT * pContext )
  98. {
  99. if ( pContext->CurrentSyntaxType == XFER_SYNTAX_DCE )
  100. {
  101. if ( pContext->IsObject )
  102. memcpy( & (pContext->pfnInit), &SyncDcomDceClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
  103. else
  104. {
  105. if ( pContext->IsAsync )
  106. memcpy( & (pContext->pfnInit), &AsyncDceClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
  107. else
  108. memcpy( & (pContext->pfnInit), &SyncDceClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
  109. }
  110. }
  111. else
  112. {
  113. if ( pContext->IsObject )
  114. memcpy( & (pContext->pfnInit), &SyncDcomNdr64Client, sizeof( SYNTAX_DISPATCH_TABLE ) );
  115. else
  116. memcpy( & (pContext->pfnInit), &SyncNdr64Client, sizeof( SYNTAX_DISPATCH_TABLE ) );
  117. }
  118. }
  119. /*++
  120. Routine Description :
  121. This routine initialize the server side NDR_PROC_CONTEXT when using
  122. NDR64.
  123. Arguments :
  124. Return :
  125. None.
  126. --*/
  127. void
  128. NdrServerSetupNDR64TransferSyntax(
  129. ulong ProcNum,
  130. MIDL_SYNTAX_INFO * pSyntaxInfo,
  131. NDR_PROC_CONTEXT * pContext)
  132. {
  133. PFORMAT_STRING pFormat;
  134. SYNTAX_TYPE SyntaxType = XFER_SYNTAX_NDR64;
  135. NDR_ASSERT( SyntaxType == NdrpGetSyntaxType( &pSyntaxInfo->TransferSyntax ) ,
  136. "invalid transfer sytnax" );
  137. pFormat = NdrpGetProcString( pSyntaxInfo,
  138. SyntaxType,
  139. ProcNum );
  140. MulNdrpInitializeContextFromProc(
  141. SyntaxType,
  142. pFormat,
  143. pContext,
  144. NULL ); // StartofStack. Don't have it yet.
  145. pContext->pSyntaxInfo = pSyntaxInfo;
  146. }
  147. /*++
  148. Routine Description :
  149. Setup the client side transfer syntax information from MIDL_PROXY_INFO
  150. This is the first thing the engine do from the public entries, so if
  151. somethings goes wrong here, we don't have enough information about the
  152. procedure and we can't recover from the error. We have to raise exception
  153. back to the application.
  154. Arguments :
  155. Return :
  156. RPC_S_OK if
  157. --*/
  158. void RPC_ENTRY
  159. Ndr64ClientInitializeContext(
  160. SYNTAX_TYPE SyntaxType,
  161. const MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
  162. ulong nProcNum,
  163. NDR_PROC_CONTEXT * pContext,
  164. uchar * StartofStack )
  165. {
  166. PFORMAT_STRING pFormat;
  167. RPC_STATUS res = RPC_S_OK;
  168. MIDL_SYNTAX_INFO * pSyntaxInfo = NULL;
  169. ulong i;
  170. pContext->StartofStack = StartofStack;
  171. for ( i = 0; i < pProxyInfo->nCount; i ++ )
  172. if ( SyntaxType == NdrpGetSyntaxType( &pProxyInfo->pSyntaxInfo[i].TransferSyntax ) )
  173. {
  174. pSyntaxInfo = & pProxyInfo->pSyntaxInfo[i];
  175. break;
  176. }
  177. // We can't do much if we are reading invalid format string
  178. if ( NULL == pSyntaxInfo )
  179. RpcRaiseException( RPC_S_UNSUPPORTED_TRANS_SYN );
  180. else
  181. {
  182. pFormat = NdrpGetProcString( pSyntaxInfo, SyntaxType, nProcNum );
  183. MulNdrpInitializeContextFromProc( SyntaxType, pFormat, pContext, StartofStack );
  184. pContext->pSyntaxInfo = pSyntaxInfo;
  185. }
  186. }
  187. // Fill in RPC_CLIENT_INTERFACE in rpcmessage if the proxy only support one transfer syntax.
  188. __inline
  189. HRESULT NdrpDcomSetupSimpleClientInterface(
  190. MIDL_STUB_MESSAGE * pStubMsg,
  191. RPC_CLIENT_INTERFACE * pClientIf,
  192. const IID * riid,
  193. MIDL_STUBLESS_PROXY_INFO * pProxyInfo )
  194. {
  195. memset(pClientIf, 0, sizeof( RPC_CLIENT_INTERFACE ) );
  196. pClientIf->Length = sizeof( RPC_CLIENT_INTERFACE );
  197. pClientIf->InterfaceId.SyntaxGUID = *riid;
  198. memcpy(&pClientIf->TransferSyntax,
  199. pProxyInfo->pTransferSyntax,
  200. sizeof(RPC_SYNTAX_IDENTIFIER) );
  201. pClientIf->InterpreterInfo = pProxyInfo;
  202. pStubMsg->RpcMsg->RpcInterfaceInformation = pClientIf;
  203. return S_OK;
  204. }
  205. RPC_STATUS RPC_ENTRY
  206. Ndr64pClientSetupTransferSyntax( void * pThis,
  207. RPC_MESSAGE * pRpcMsg,
  208. MIDL_STUB_MESSAGE * pStubMsg,
  209. MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
  210. NDR_PROC_CONTEXT * pContext,
  211. ulong nProcNum )
  212. {
  213. const MIDL_STUB_DESC * pStubDesc = pProxyInfo->pStubDesc;
  214. RPC_STATUS res = S_OK;
  215. // setup vtbl first so we can recover from error
  216. Ndr64SetupClientContextVtbl( pContext );
  217. pStubMsg->pContext = pContext;
  218. pStubMsg->StackTop = pContext->StartofStack;
  219. if ( pThis )
  220. {
  221. ulong SyncProcNum;
  222. // In DCOM async interface, the proc number in rpcmessage is the sync method id
  223. // instead of async methodid, so we need to setup the proxy differently.
  224. if ( pContext->IsAsync )
  225. SyncProcNum = (nProcNum + 3 ) / 2;
  226. else
  227. SyncProcNum = nProcNum;
  228. Ndr64ProxyInitialize( pThis,
  229. pRpcMsg,
  230. pStubMsg,
  231. pProxyInfo,
  232. SyncProcNum );
  233. }
  234. else
  235. {
  236. handle_t Handle;
  237. PFNEXPLICITBINDHANDLEMGR pfnExpBindMgr = NULL;
  238. PFNIMPLICITBINDHANDLEMGR pfnImpBindMgr = NULL;
  239. if ( pContext->CurrentSyntaxType == XFER_SYNTAX_NDR64 )
  240. {
  241. pfnExpBindMgr = &Ndr64ExplicitBindHandleMgr;
  242. pfnImpBindMgr = &Ndr64ImplicitBindHandleMgr;
  243. }
  244. else
  245. {
  246. pfnExpBindMgr = &ExplicitBindHandleMgr;
  247. pfnImpBindMgr = &ImplicitBindHandleMgr;
  248. }
  249. Ndr64ClientInitialize( pRpcMsg,
  250. pStubMsg,
  251. pProxyInfo,
  252. (uint) nProcNum );
  253. if ( pContext->HandleType )
  254. {
  255. //
  256. // We have an implicit handle.
  257. //
  258. Handle = (*pfnImpBindMgr)( pStubDesc,
  259. pContext->HandleType,
  260. &(pContext->SavedGenericHandle) );
  261. }
  262. else
  263. {
  264. PFORMAT_STRING pFormat;
  265. if ( pContext->CurrentSyntaxType == XFER_SYNTAX_DCE )
  266. pFormat = (PFORMAT_STRING) pContext->pHandleFormatSave;
  267. else
  268. pFormat = (uchar *) pContext->Ndr64Header+ sizeof(NDR64_PROC_FORMAT);
  269. Handle = (*pfnExpBindMgr)( pStubDesc,
  270. pContext->StartofStack,
  271. pFormat,
  272. &(pContext->SavedGenericHandle ) );
  273. }
  274. pStubMsg->RpcMsg->Handle = pStubMsg->SavedHandle = Handle;
  275. }
  276. pStubMsg->RpcMsg->RpcFlags = pContext->RpcFlags;
  277. // The client only negotiates when the stub support more than one
  278. // transfer syntax.
  279. if ( pProxyInfo->nCount > 1 )
  280. {
  281. res = Ndr64ClientNegotiateTransferSyntax( pThis,
  282. pStubMsg,
  283. pProxyInfo,
  284. pContext );
  285. if ( RPC_S_OK == res )
  286. {
  287. PFORMAT_STRING pFormat;
  288. SYNTAX_TYPE SyntaxType;
  289. ulong i = 0;
  290. SyntaxType = NdrpGetSyntaxType( pStubMsg->RpcMsg->TransferSyntax );
  291. if ( SyntaxType != pContext->CurrentSyntaxType )
  292. {
  293. for (i = 0; i < pProxyInfo->nCount; i++)
  294. {
  295. if ( SyntaxType == NdrpGetSyntaxType( &pProxyInfo->pSyntaxInfo[i].TransferSyntax ) )
  296. {
  297. pContext->pSyntaxInfo = &( pProxyInfo->pSyntaxInfo[i] );
  298. break;
  299. }
  300. }
  301. NDR_ASSERT( i < pProxyInfo->nCount, "can't find the right syntax" );
  302. // Reread the format string if we select a different transfer syntax
  303. pFormat = NdrpGetProcString( pContext->pSyntaxInfo,
  304. SyntaxType,
  305. nProcNum );
  306. MulNdrpInitializeContextFromProc( SyntaxType ,
  307. pFormat,
  308. pContext,
  309. pContext->StartofStack,
  310. TRUE ); // reset
  311. Ndr64SetupClientContextVtbl( pContext );
  312. }
  313. }
  314. }
  315. else
  316. {
  317. pContext->pSyntaxInfo = pProxyInfo->pSyntaxInfo;
  318. // we need to fake the RPC_CLIENT_INTERFACE if client only support NDR64
  319. if ( pThis )
  320. {
  321. const IID * riid;
  322. RPC_CLIENT_INTERFACE * pClientIf;
  323. pClientIf = (RPC_CLIENT_INTERFACE *)NdrpAlloca( &pContext->AllocateContext, sizeof( RPC_CLIENT_INTERFACE ) );
  324. if ( pContext->IsAsync )
  325. {
  326. riid = NdrGetSyncProxyIID( pThis );
  327. }
  328. else
  329. riid = NdrGetProxyIID(pThis);
  330. NdrpDcomSetupSimpleClientInterface( pStubMsg,
  331. pClientIf,
  332. riid,
  333. pProxyInfo );
  334. }
  335. }
  336. return res;
  337. }
  338. HRESULT NdrpDcomNegotiateSyntax( void * pThis,
  339. MIDL_STUB_MESSAGE *pStubMsg,
  340. MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
  341. NDR_PROC_CONTEXT * pContext
  342. )
  343. {
  344. IRpcSyntaxNegotiate * pNegotiate = NULL;
  345. IRpcChannelBuffer * pChannel = pStubMsg->pRpcChannelBuffer;
  346. HRESULT hr = E_FAIL ;
  347. ulong nPrefer;
  348. const IID * riid;
  349. RPC_CLIENT_INTERFACE * pclientIf;
  350. pclientIf = ( RPC_CLIENT_INTERFACE * ) NdrpAlloca( &pContext->AllocateContext, sizeof( RPC_CLIENT_INTERFACE ) );
  351. if ( pContext->IsAsync )
  352. {
  353. riid = NdrGetSyncProxyIID( pThis );
  354. }
  355. else
  356. riid = NdrGetProxyIID(pThis);
  357. hr = pChannel->lpVtbl->QueryInterface( pChannel, IID_IRpcSyntaxNegotiate, (void **)&pNegotiate );
  358. if ( SUCCEEDED( hr ) )
  359. {
  360. // create RPC_CLIENT_INTERFACE here.
  361. memset(pclientIf, 0, sizeof( RPC_CLIENT_INTERFACE ) );
  362. pclientIf->Length = sizeof( RPC_CLIENT_INTERFACE ) ;
  363. pclientIf->InterfaceId.SyntaxGUID = *riid;
  364. memcpy(&pclientIf->TransferSyntax,
  365. pProxyInfo->pTransferSyntax,
  366. sizeof(RPC_SYNTAX_IDENTIFIER) );
  367. pclientIf->InterpreterInfo = pProxyInfo;
  368. pclientIf->Flags |= RPCFLG_HAS_MULTI_SYNTAXES;
  369. pStubMsg->RpcMsg->RpcInterfaceInformation = pclientIf;
  370. hr = pNegotiate->lpVtbl->NegotiateSyntax( pNegotiate, (RPCOLEMESSAGE *)pStubMsg->RpcMsg );
  371. // OLE will return S_FALSE in local server case, where OLE doesn't involve RPC runtime
  372. // to send package, such that I_RpcNegotiateSyntax can't be called.
  373. if ( hr == S_FALSE )
  374. {
  375. NdrpGetPreferredSyntax( (ulong )pProxyInfo->nCount, pProxyInfo->pSyntaxInfo, &nPrefer );
  376. pStubMsg->RpcMsg->TransferSyntax = &pProxyInfo->pSyntaxInfo[nPrefer].TransferSyntax;
  377. hr = S_OK;
  378. }
  379. pNegotiate->lpVtbl->Release( pNegotiate );
  380. }
  381. else
  382. {
  383. // old style proxy
  384. hr = NdrpDcomSetupSimpleClientInterface( pStubMsg, pclientIf, riid, pProxyInfo );
  385. }
  386. return hr;
  387. }
  388. RPC_STATUS RPC_ENTRY
  389. Ndr64ClientNegotiateTransferSyntax(
  390. void * pThis,
  391. MIDL_STUB_MESSAGE *pStubMsg,
  392. MIDL_STUBLESS_PROXY_INFO *pProxyInfo,
  393. NDR_PROC_CONTEXT *pContext )
  394. {
  395. RPC_STATUS status = RPC_S_UNSUPPORTED_TRANS_SYN ;
  396. RPC_MESSAGE *pRpcMsg = pStubMsg->RpcMsg;
  397. const MIDL_STUB_DESC * pStubDesc = pProxyInfo->pStubDesc;
  398. ulong i;
  399. ushort FormatOffset;
  400. ushort * pFormat;
  401. uchar HandleType;
  402. HRESULT hr;
  403. SYNTAX_TYPE SyntaxType;
  404. if ( pThis )
  405. {
  406. hr = NdrpDcomNegotiateSyntax( pThis, pStubMsg, pProxyInfo, pContext );
  407. if ( FAILED( hr ) )
  408. RpcRaiseException( hr );
  409. status = RPC_S_OK;
  410. }
  411. else
  412. {
  413. if ( pContext->UseLocator )
  414. {
  415. // call into locator's negotiation code
  416. EnsureNSLoaded();
  417. status = (*pRpcNsNegotiateTransferSyntax)( pStubMsg->RpcMsg );
  418. }
  419. else
  420. {
  421. status = I_RpcNegotiateTransferSyntax( pStubMsg->RpcMsg );
  422. }
  423. if ( status != RPC_S_OK )
  424. RpcRaiseException( status );
  425. }
  426. return status;
  427. }
  428. void RPC_ENTRY
  429. Ndr64pSizing( MIDL_STUB_MESSAGE * pStubMsg,
  430. BOOL IsClient )
  431. {
  432. long n;
  433. uchar * pArg;
  434. NDR64_PARAM_FLAGS * pParamFlags;
  435. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  436. NDR64_PARAM_FORMAT * Params =
  437. (NDR64_PARAM_FORMAT*)pContext->Params;
  438. CORRELATION_CONTEXT CorrCtxt( pStubMsg, pContext->StartofStack );
  439. for (ulong n = 0; n < pContext->NumberParams; n++ )
  440. {
  441. pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
  442. if ( IsClient && pParamFlags->IsPartialIgnore )
  443. {
  444. LENGTH_ALIGN(pStubMsg->BufferLength, NDR64_PTR_WIRE_ALIGN );
  445. pStubMsg->BufferLength += sizeof(NDR64_PTR_WIRE_TYPE);
  446. continue;
  447. }
  448. if ( !NDR64SAMEDIRECTION(IsClient, pParamFlags) ||
  449. ! ( pParamFlags->MustSize ) )
  450. continue;
  451. //
  452. // Note : Basetypes will always be factored into the
  453. // constant buffer size emitted by in the format strings.
  454. //
  455. pArg = pContext->StartofStack + Params[n].StackOffset;
  456. if ( ! pParamFlags->IsByValue )
  457. pArg = *((uchar **)pArg);
  458. Ndr64TopLevelTypeSize( pStubMsg,
  459. pArg,
  460. Params[n].Type );
  461. }
  462. }
  463. void
  464. Ndr64ClientZeroOut(
  465. PMIDL_STUB_MESSAGE pStubMsg,
  466. PNDR64_FORMAT pFormat,
  467. uchar * pArg
  468. )
  469. {
  470. const NDR64_POINTER_FORMAT *pPointerFormat =
  471. (const NDR64_POINTER_FORMAT*)pFormat;
  472. //
  473. // In an object proc, we must zero all [out] unique and interface
  474. // pointers which occur as the referent of a ref pointer or embedded in a
  475. // structure or union.
  476. //
  477. // Let's not die on a null ref pointer.
  478. if ( !pArg )
  479. return;
  480. //
  481. // The only top level [out] type allowed is a ref pointer or an array.
  482. //
  483. if ( *(PFORMAT_STRING)pFormat == FC64_RP )
  484. {
  485. pFormat = pPointerFormat->Pointee;
  486. // Double pointer.
  487. if ( NDR64_POINTER_DEREF( pPointerFormat->Flags ) )
  488. {
  489. *((void **)pArg) = 0;
  490. return;
  491. }
  492. // we need to zero out basetype because it might be conformant/
  493. // varying descriptor.
  494. if ( NDR64_SIMPLE_POINTER( pPointerFormat->Flags ) )
  495. {
  496. MIDL_memset( pArg, 0,
  497. (uint) NDR64_SIMPLE_TYPE_MEMSIZE( *(PFORMAT_STRING)pFormat ) );
  498. return;
  499. }
  500. }
  501. NDR64_UINT32 Size = Ndr64pMemorySize( pStubMsg,
  502. pFormat,
  503. FALSE );
  504. MIDL_memset( pArg, 0, (size_t)Size );
  505. }
  506. void RPC_ENTRY
  507. Ndr64pClientInit( MIDL_STUB_MESSAGE * pStubMsg,
  508. void * pReturnValue )
  509. {
  510. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  511. NDR64_PROC_FORMAT * pHeader = pContext->Ndr64Header;
  512. BOOL fRaiseExcFlag = FALSE;
  513. ulong n;
  514. uchar * pArg;
  515. NDR64_PARAM_FORMAT * Params;
  516. NDR64_PROC_FLAGS * pNdr64Flags;
  517. NDR64_PARAM_FLAGS * pParamFlags;
  518. pNdr64Flags = (NDR64_PROC_FLAGS * )&(pHeader->Flags) ;
  519. Params = ( NDR64_PARAM_FORMAT *) pContext->Params;
  520. if ( pNdr64Flags->UsesFullPtrPackage )
  521. pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit( 0, XLAT_CLIENT );
  522. else
  523. pStubMsg->FullPtrXlatTables = 0;
  524. if ( pNdr64Flags->UsesRpcSmPackage )
  525. NdrRpcSmSetClientToOsf( pStubMsg );
  526. if ( pNdr64Flags->UsesPipes )
  527. NdrpPipesInitialize64( pStubMsg,
  528. &pContext->AllocateContext,
  529. (PFORMAT_STRING) Params,
  530. (char *)pContext->StartofStack,
  531. pContext->NumberParams );
  532. pStubMsg->StackTop = pContext->StartofStack;
  533. pStubMsg->pCorrMemory = pStubMsg->StackTop;
  534. // get initial size here: we might not need to get into sizing code.
  535. pStubMsg->BufferLength = pHeader->ConstantClientBufferSize;
  536. for ( n = 0; n < pContext->NumberParams; n++ )
  537. {
  538. pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
  539. if ( pParamFlags->IsReturn )
  540. pArg = (uchar *) &pReturnValue;
  541. else
  542. pArg = pContext->StartofStack + Params[n].StackOffset;
  543. if ( pParamFlags->IsSimpleRef && !pParamFlags->IsReturn )
  544. {
  545. // We cannot raise the exception here,
  546. // as some out args may not be zeroed out yet.
  547. if ( ! *((uchar **)pArg) )
  548. {
  549. fRaiseExcFlag = TRUE;
  550. continue;
  551. }
  552. }
  553. // if top level point is ref pointer and the stack is NULL, we'll catch this
  554. // before the call goes to server.
  555. if ( pParamFlags->IsOut && !pParamFlags->IsBasetype )
  556. {
  557. if ( *(PFORMAT_STRING) Params[n].Type == FC64_RP && !*((uchar **)pArg) )
  558. {
  559. fRaiseExcFlag = TRUE;
  560. continue;
  561. }
  562. }
  563. if ( ( pNdr64Flags->IsObject &&
  564. ! pContext->IsAsync &&
  565. ( pParamFlags->IsPartialIgnore ||
  566. ( ! pParamFlags->IsIn &&
  567. ! pParamFlags->IsReturn &&
  568. ! pParamFlags->IsPipe ) ) ) ||
  569. ( pNdr64Flags->HasComplexReturn &&
  570. pParamFlags->IsReturn ) )
  571. {
  572. if ( pParamFlags->IsBasetype )
  573. {
  574. // [out] only arg can only be ref, we checked that above.
  575. NDR64_FORMAT_CHAR type = *(PFORMAT_STRING) Params[n].Type;
  576. MIDL_memset( *(uchar **)pArg,
  577. 0,
  578. (size_t)NDR64_SIMPLE_TYPE_MEMSIZE( type ));
  579. }
  580. else
  581. {
  582. Ndr64ClientZeroOut(
  583. pStubMsg,
  584. Params[n].Type,
  585. *(uchar **)pArg );
  586. }
  587. }
  588. }
  589. if ( fRaiseExcFlag )
  590. RpcRaiseException( RPC_X_NULL_REF_POINTER );
  591. if ( !pNdr64Flags->ClientMustSize )
  592. pContext->pfnSizing = (PFNSIZING)NdrpNoopSizing;
  593. }
  594. void RPC_ENTRY
  595. Ndr64pDcomClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
  596. ulong ProcNum,
  597. RPC_STATUS ExceptionCode,
  598. CLIENT_CALL_RETURN * pReturnValue )
  599. {
  600. ulong NumberParams ;
  601. NDR64_PARAM_FORMAT * Params ;
  602. ulong n;
  603. uchar * pArg;
  604. NDR64_PARAM_FLAGS * pParamFlags;
  605. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  606. pReturnValue->Simple = NdrProxyErrorHandler(ExceptionCode);
  607. if( pStubMsg->dwStubPhase != PROXY_UNMARSHAL)
  608. return ;
  609. NumberParams = pContext->NumberParams;
  610. Params = ( NDR64_PARAM_FORMAT * ) pContext->Params;
  611. //
  612. // Set the Buffer endpoints so the Ndr64Free routines work.
  613. //
  614. pStubMsg->BufferStart = 0;
  615. pStubMsg->BufferEnd = 0;
  616. for ( n = 0; n < NumberParams; n++ )
  617. {
  618. pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
  619. //
  620. // Skip everything but [out] only parameters. We make
  621. // the basetype check to cover [out] simple ref pointers
  622. // to basetypes.
  623. //
  624. if ( !pParamFlags->IsPartialIgnore )
  625. {
  626. if ( pParamFlags->IsIn ||
  627. pParamFlags->IsReturn ||
  628. pParamFlags->IsBasetype ||
  629. pParamFlags->IsPipe )
  630. continue;
  631. }
  632. pArg = pContext->StartofStack + Params[n].StackOffset;
  633. Ndr64ClearOutParameters( pStubMsg,
  634. Params[n].Type,
  635. *((uchar **)pArg) );
  636. }
  637. return ;
  638. }
  639. void RPC_ENTRY
  640. Ndr64pClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
  641. ulong ProcNum,
  642. RPC_STATUS ExceptionCode,
  643. CLIENT_CALL_RETURN * pReturnValue )
  644. {
  645. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  646. if ( ( (NDR64_PROC_FLAGS *) & pContext->Ndr64Header->Flags)->HandlesExceptions )
  647. {
  648. NdrClientMapCommFault( pStubMsg,
  649. ProcNum,
  650. ExceptionCode,
  651. (ULONG_PTR*)&pReturnValue->Simple );
  652. }
  653. else
  654. {
  655. RpcRaiseException(ExceptionCode);
  656. }
  657. return;
  658. }
  659. void RPC_ENTRY
  660. Ndr64pClientMarshal( MIDL_STUB_MESSAGE * pStubMsg,
  661. BOOL IsObject )
  662. {
  663. NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
  664. // if ( (ULONG_PTR)pStubMsg->Buffer & 15 )
  665. // RpcRaiseException( RPC_X_INVALID_BUFFER );
  666. CORRELATION_CONTEXT CorrCtxt( pStubMsg, pContext->StartofStack );
  667. NDR64_PARAM_FORMAT *Params = (NDR64_PARAM_FORMAT *) pContext->Params;
  668. for ( ulong n = 0; n < pContext->NumberParams; n++ )
  669. {
  670. NDR64_PARAM_FLAGS *pParamFlags =
  671. ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
  672. uchar *pArg = pContext->StartofStack + Params[n].StackOffset;
  673. if ( pParamFlags->IsPartialIgnore )
  674. {
  675. ALIGN( pStubMsg->Buffer, NDR64_PTR_WIRE_ALIGN );
  676. *((NDR64_PTR_WIRE_TYPE*)pStubMsg->Buffer) = (*pArg) ? (NDR64_PTR_WIRE_TYPE)1 :
  677. (NDR64_PTR_WIRE_TYPE)0;
  678. pStubMsg->Buffer += sizeof(NDR64_PTR_WIRE_TYPE);
  679. continue;
  680. }
  681. if ( !pParamFlags->IsIn ||
  682. pParamFlags->IsPipe )
  683. continue;
  684. if ( pParamFlags->IsBasetype )
  685. {
  686. NDR64_FORMAT_CHAR type = *(PFORMAT_STRING)Params[n].Type;
  687. //
  688. // Check for pointer to basetype.
  689. //
  690. if ( pParamFlags->IsSimpleRef )
  691. pArg = *((uchar **)pArg);
  692. else
  693. {
  694. #if defined(_IA64_) || defined(_AMD64_)
  695. if ( !IsObject && type == FC64_FLOAT32 )
  696. {
  697. // Due to the fact that NdrClientCall2 is called with the
  698. // parameters in ... arguments, floats get promoted to doubles.
  699. // This is not true for DCOM since an assembly langauge wrapper
  700. // is used that saves the floats as floats.
  701. //
  702. // We do not handle this case properly.
  703. *((float *) pArg) = (float) *((double *)pArg);
  704. }
  705. #endif
  706. }
  707. Ndr64SimpleTypeMarshallRoutinesTable[type](pStubMsg, pArg );
  708. continue;
  709. }
  710. if ( ! pParamFlags->IsByValue )
  711. pArg = *((uchar **)pArg);
  712. Ndr64TopLevelTypeMarshall( pStubMsg,
  713. pArg,
  714. Params[n].Type );
  715. }
  716. if ( pStubMsg->RpcMsg->BufferLength <
  717. (uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer) )
  718. {
  719. NDR_ASSERT( 0, "Ndr64pClientmarshal: buffer overflow!" );
  720. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  721. }
  722. }
  723. void RPC_ENTRY
  724. Ndr64pServerMarshal( MIDL_STUB_MESSAGE * pStubMsg )
  725. {
  726. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  727. // if ( (ULONG_PTR)pStubMsg->Buffer & 15 )
  728. // RpcRaiseException( RPC_X_INVALID_BUFFER );
  729. CORRELATION_CONTEXT CorrCtxt( pStubMsg, pContext->StartofStack );
  730. NDR64_PARAM_FORMAT *Params = (NDR64_PARAM_FORMAT *) pContext->Params;
  731. for ( ulong n = 0; n < pContext->NumberParams; n++ )
  732. {
  733. NDR64_PARAM_FLAGS *pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
  734. uchar *pArg = pContext->StartofStack + Params[n].StackOffset;
  735. if (!pParamFlags->IsOut ||
  736. pParamFlags->IsPipe )
  737. continue;
  738. if ( pParamFlags->IsBasetype )
  739. {
  740. NDR64_FORMAT_CHAR type = *(PFORMAT_STRING)Params[n].Type;
  741. //
  742. // Check for pointer to basetype.
  743. //
  744. if ( pParamFlags->IsSimpleRef )
  745. pArg = *((uchar **)pArg);
  746. Ndr64SimpleTypeMarshallRoutinesTable[type](pStubMsg, pArg );
  747. continue;
  748. }
  749. if ( ! pParamFlags->IsByValue )
  750. pArg = *((uchar **)pArg);
  751. Ndr64TopLevelTypeMarshall( pStubMsg,
  752. pArg,
  753. Params[n].Type);
  754. }
  755. if ( pStubMsg->RpcMsg->BufferLength <
  756. (uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer) )
  757. {
  758. NDR_ASSERT( 0, "Ndr64pCompleteAsyncServerCall marshal: buffer overflow!" );
  759. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  760. }
  761. }
  762. void RPC_ENTRY
  763. Ndr64pClientUnMarshal ( MIDL_STUB_MESSAGE * pStubMsg,
  764. void * pReturnValue )
  765. {
  766. uchar * pArg;
  767. NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
  768. NDR64_PARAM_FORMAT *Params = (NDR64_PARAM_FORMAT *)pContext->Params;
  769. // if ( (ULONG_PTR)pStubMsg->Buffer & 15 )
  770. // RpcRaiseException( RPC_X_INVALID_BUFFER );
  771. CORRELATION_CONTEXT( pStubMsg, pContext->StartofStack );
  772. //
  773. // ----------------------------------------------------------
  774. // Unmarshall Pass.
  775. // ----------------------------------------------------------
  776. //
  777. for ( ulong n = 0; n < pContext->NumberParams; n++ )
  778. {
  779. NDR64_PARAM_FLAGS *pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
  780. if ( pParamFlags->IsPipe )
  781. continue;
  782. if ( !pParamFlags->IsOut )
  783. {
  784. if ( !pParamFlags->IsIn && !pParamFlags->IsReturn )
  785. {
  786. // If a param is not [in], [out], or a return value,
  787. // then it is a "hidden" client-side only status
  788. // paramater. It will get set below if an exception
  789. // happens. If everything is ok we need to zero it
  790. // out here.
  791. NDR_ASSERT( pParamFlags->IsSimpleRef
  792. && pParamFlags->IsBasetype
  793. && FC64_ERROR_STATUS_T ==
  794. *(PFORMAT_STRING)Params[n].Type,
  795. "Apparently not a hidden status param" );
  796. pArg = pContext->StartofStack + Params[n].StackOffset;
  797. ** (error_status_t **) pArg = RPC_S_OK;
  798. }
  799. continue;
  800. }
  801. if ( pParamFlags->IsReturn )
  802. {
  803. if ( ! pReturnValue )
  804. RpcRaiseException( RPC_S_INVALID_ARG );
  805. pArg = (uchar *) pReturnValue;
  806. }
  807. else
  808. pArg = pContext->StartofStack + Params[n].StackOffset;
  809. //
  810. // This is for returned basetypes and for pointers to
  811. // basetypes.
  812. //
  813. if ( pParamFlags->IsBasetype )
  814. {
  815. NDR64_FORMAT_CHAR type = *(PFORMAT_STRING)Params[n].Type;
  816. //
  817. // Check for a pointer to a basetype.
  818. //
  819. if ( pParamFlags->IsSimpleRef )
  820. pArg = *((uchar **)pArg);
  821. ALIGN( pStubMsg->Buffer, NDR64_SIMPLE_TYPE_BUFALIGN( type ) );
  822. RpcpMemoryCopy(
  823. pArg,
  824. pStubMsg->Buffer,
  825. NDR64_SIMPLE_TYPE_BUFSIZE( type ) );
  826. pStubMsg->Buffer +=
  827. NDR64_SIMPLE_TYPE_BUFSIZE( type );
  828. continue;
  829. }
  830. uchar **ppArg = pParamFlags->IsByValue ? &pArg : (uchar **)pArg;
  831. //
  832. // Transmit/Represent as can be passed as [out] only, thus
  833. // the IsByValue check.
  834. //
  835. Ndr64TopLevelTypeUnmarshall( pStubMsg,
  836. ppArg,
  837. Params[n].Type,
  838. false );
  839. }
  840. if ( pStubMsg->pCorrInfo )
  841. Ndr64CorrelationPass( pStubMsg );
  842. return ;
  843. }
  844. void RPC_ENTRY
  845. Ndr64pClientFinally( PMIDL_STUB_MESSAGE pStubMsg,
  846. void * pThis )
  847. {
  848. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  849. PMIDL_STUB_DESC pStubDesc = pStubMsg->StubDesc;
  850. NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
  851. //
  852. // Free the RPC buffer.
  853. //
  854. if ( pThis )
  855. {
  856. NdrProxyFreeBuffer( pThis, pStubMsg );
  857. }
  858. else
  859. {
  860. NdrFreeBuffer( pStubMsg );
  861. //
  862. // Unbind if generic handle used. We do this last so that if the
  863. // the user's unbind routine faults, then all of our internal stuff
  864. // will already have been freed.
  865. //
  866. if ( pContext->SavedGenericHandle )
  867. Ndr64GenericHandleUnbind( pStubDesc,
  868. pContext->StartofStack,
  869. (uchar *)pContext->Ndr64Header+ sizeof(NDR64_PROC_FORMAT),
  870. (pContext->HandleType) ? IMPLICIT_MASK : 0,
  871. &pContext->SavedGenericHandle );
  872. }
  873. NdrpAllocaDestroy( & pContext->AllocateContext );
  874. }
  875. void
  876. Ndr64pServerOutInit( PMIDL_STUB_MESSAGE pStubMsg )
  877. {
  878. NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
  879. NDR64_PARAM_FLAGS * pParamFlags;
  880. NDR64_PARAM_FORMAT* Params = (NDR64_PARAM_FORMAT*)pContext->Params;
  881. NDR64_PROC_FLAGS * pNdr64Flags = (NDR64_PROC_FLAGS *)&pContext->Ndr64Header->Flags;
  882. uchar * pArg;
  883. for ( ulong n = 0; n < pContext->NumberParams; n++ )
  884. {
  885. pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
  886. if ( !pParamFlags->IsPartialIgnore )
  887. {
  888. if ( pParamFlags->IsIn ||
  889. (pParamFlags->IsReturn && !pNdr64Flags->HasComplexReturn) ||
  890. pParamFlags->IsPipe )
  891. continue;
  892. pArg = pContext->StartofStack + Params[n].StackOffset;
  893. }
  894. else
  895. {
  896. pArg = pContext->StartofStack + Params[n].StackOffset;
  897. if ( !*(void**)pArg )
  898. continue;
  899. }
  900. //
  901. // Check if we can initialize this parameter using some of our
  902. // stack.
  903. //
  904. if ( pParamFlags->UseCache )
  905. {
  906. *((void **)pArg) = NdrpAlloca( &pContext->AllocateContext, 64 );
  907. MIDL_memset( *((void **)pArg),
  908. 0,
  909. 64 );
  910. continue;
  911. }
  912. else if ( pParamFlags->IsBasetype )
  913. {
  914. *((void **)pArg) = NdrpAlloca( &pContext->AllocateContext,8);
  915. MIDL_memset( *((void **)pArg), 0, 8 );
  916. continue;
  917. };
  918. Ndr64OutInit( pStubMsg,
  919. Params[n].Type,
  920. (uchar **)pArg );
  921. }
  922. }
  923. #pragma code_seg()