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.

1474 lines
48 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name :
  4. mulsyntx.cxx
  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 "ndrp.h"
  12. #define CINTERFACE
  13. #include "ndrole.h"
  14. #include "rpcproxy.h"
  15. #include "mulsyntx.h"
  16. #include "hndl.h"
  17. #include "auxilary.h"
  18. #include "pipendr.h"
  19. #include "ndr64tkn.h"
  20. const extern PMARSHALL_ROUTINE MarshallRoutinesTable[];
  21. const extern PUNMARSHALL_ROUTINE UnmarshallRoutinesTable[];
  22. const extern PSIZE_ROUTINE SizeRoutinesTable[];
  23. const extern PMEM_SIZE_ROUTINE MemSizeRoutinesTable[];
  24. const extern PFREE_ROUTINE FreeRoutinesTable[];
  25. //const extern PWALKIP_ROUTINE WalkIPRoutinesTable[];
  26. // TODO: move this to ndrpall.h after Preview.
  27. #define MIDL_VERSION_6_0_322 ((6UL << 24) | (0UL << 16) | 322UL)
  28. void RPC_ENTRY
  29. NdrpClientInit(MIDL_STUB_MESSAGE * pStubMsg,
  30. void * pReturnValue )
  31. {
  32. PFORMAT_STRING pFormatParam;
  33. ulong ProcNum;
  34. BOOL fRaiseExcFlag;
  35. ulong n;
  36. uchar * pArg;
  37. INTERPRETER_FLAGS InterpreterFlags;
  38. PPARAM_DESCRIPTION Params;
  39. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *) pStubMsg->pContext;
  40. INTERPRETER_OPT_FLAGS OptFlags = pContext->NdrInfo.pProcDesc->Oi2Flags;
  41. PFORMAT_STRING pTypeFormat;
  42. // When this routine is called from ndrclientcall2, we don't have MIDL_SYNTAX_INFO,
  43. // so we need to read it from MIDL_STUB_DESC;
  44. // Note: we need to conenct StubDesc to pStubMsg before calling into here.
  45. if ( NULL == pContext->pSyntaxInfo )
  46. pContext->DceTypeFormatString = pStubMsg->StubDesc->pFormatTypes;
  47. else
  48. pContext->DceTypeFormatString = pContext->pSyntaxInfo->TypeString;
  49. InterpreterFlags = pContext->NdrInfo.InterpreterFlags;
  50. Params = ( PPARAM_DESCRIPTION )pContext->Params;
  51. pTypeFormat = pContext->DceTypeFormatString;
  52. if ( InterpreterFlags.FullPtrUsed )
  53. pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit( 0, XLAT_CLIENT );
  54. else
  55. pStubMsg->FullPtrXlatTables = 0;
  56. if ( InterpreterFlags.RpcSsAllocUsed )
  57. NdrRpcSmSetClientToOsf( pStubMsg );
  58. // Set Rpc flags after the call to client initialize.
  59. pStubMsg->RpcMsg->RpcFlags = pContext->RpcFlags;
  60. if ( OptFlags.HasPipes )
  61. NdrpPipesInitialize32( pStubMsg,
  62. &pContext->AllocateContext,
  63. (PFORMAT_STRING) pContext->Params,
  64. ( char * )pContext->StartofStack,
  65. pContext->NumberParams );
  66. // Must do this before the sizing pass!
  67. pStubMsg->StackTop = pContext->StartofStack;
  68. if ( OptFlags.HasExtensions )
  69. {
  70. pStubMsg->fHasExtensions = 1;
  71. pStubMsg->fHasNewCorrDesc = pContext->NdrInfo.pProcDesc->NdrExts.Flags2.HasNewCorrDesc;
  72. if ( pContext->NdrInfo.pProcDesc->NdrExts.Flags2.ClientCorrCheck )
  73. {
  74. ulong *pCache =
  75. (ulong*)NdrpAlloca(&pContext->AllocateContext,
  76. NDR_DEFAULT_CORR_CACHE_SIZE );
  77. NdrCorrelationInitialize( pStubMsg,
  78. pCache,
  79. NDR_DEFAULT_CORR_CACHE_SIZE,
  80. 0 /* flags */ );
  81. }
  82. }
  83. //
  84. // Get the compile time computed buffer size.
  85. //
  86. pStubMsg->BufferLength = pContext->NdrInfo.pProcDesc->ClientBufferSize;
  87. //
  88. // Check ref pointers and do object proc [out] zeroing.
  89. //
  90. fRaiseExcFlag = FALSE;
  91. for ( n = 0; n < pContext->NumberParams; n++ )
  92. {
  93. if ( Params[n].ParamAttr.IsReturn )
  94. pArg = (uchar *) &pReturnValue;
  95. else
  96. pArg = pContext->StartofStack + Params[n].StackOffset;
  97. if ( Params[n].ParamAttr.IsSimpleRef && !Params[n].ParamAttr.IsReturn )
  98. {
  99. // We cannot raise the exception here,
  100. // as some out args may not be zeroed out yet.
  101. if ( ! *((uchar **)pArg) )
  102. {
  103. fRaiseExcFlag = TRUE;
  104. continue;
  105. }
  106. }
  107. // if top level point is FC_RP and the arg is NULL, we'll catch this
  108. // before the call goes to server.
  109. // We wouldn't catch all the null ref pointer here, but we should be able
  110. // to catch the most obvious ones.
  111. // This code is called from sync & raw async code; in async dcom,
  112. // we only go through outinit in finish routine so we can't do anything anyhow.
  113. if ( Params[n].ParamAttr.IsOut && ! Params[n].ParamAttr.IsBasetype )
  114. {
  115. pFormatParam = pTypeFormat + Params[n].TypeOffset;
  116. if ( * pFormatParam == FC_RP && !*((uchar **)pArg) )
  117. {
  118. fRaiseExcFlag = TRUE;
  119. continue;
  120. }
  121. }
  122. //
  123. // In object procs and complex return types we have to zero
  124. // out all [out] parameters. We do the basetype check to
  125. // cover the [out] simple ref to basetype case.
  126. //
  127. if ( ( InterpreterFlags.ObjectProc &&
  128. ! pContext->IsAsync &&
  129. ( Params[n].ParamAttr.IsPartialIgnore ||
  130. ( ! Params[n].ParamAttr.IsIn &&
  131. ! Params[n].ParamAttr.IsReturn &&
  132. ! Params[n].ParamAttr.IsPipe ) ) ) ||
  133. ( pContext->HasComplexReturn &&
  134. Params[n].ParamAttr.IsReturn ) )
  135. {
  136. if ( Params[n].ParamAttr.IsBasetype )
  137. {
  138. // [out] only arg can only be ref, we checked that above.
  139. MIDL_memset( *(uchar **)pArg,
  140. 0,
  141. (size_t)SIMPLE_TYPE_MEMSIZE( Params[n].SimpleType.Type ));
  142. }
  143. else
  144. {
  145. pFormatParam = pTypeFormat +
  146. Params[n].TypeOffset;
  147. NdrClientZeroOut(
  148. pStubMsg,
  149. pFormatParam,
  150. *(uchar **)pArg );
  151. }
  152. }
  153. }
  154. if ( fRaiseExcFlag )
  155. RpcRaiseException( RPC_X_NULL_REF_POINTER );
  156. if ( OptFlags.ClientMustSize )
  157. {
  158. // Compiler prevents variable size non-pipe args for NT v.4.0.
  159. if ( OptFlags.HasPipes )
  160. RpcRaiseException( RPC_X_WRONG_PIPE_VERSION );
  161. }
  162. else
  163. pContext->pfnSizing = (PFNSIZING)NdrpNoopSizing;
  164. }
  165. void RPC_ENTRY
  166. NdrpNoopSizing( MIDL_STUB_MESSAGE * pStubMsg,
  167. BOOL IsClient )
  168. {
  169. return;
  170. }
  171. void RPC_ENTRY
  172. NdrpSizing( MIDL_STUB_MESSAGE * pStubMsg,
  173. BOOL IsClient )
  174. {
  175. PFORMAT_STRING pFormatParam;
  176. ulong n;
  177. uchar * pArg;
  178. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  179. PPARAM_DESCRIPTION Params = ( PPARAM_DESCRIPTION )pContext->Params;
  180. PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
  181. //
  182. // Skip buffer size pass if possible.
  183. //
  184. for ( n = 0; n < pContext->NumberParams; n++ )
  185. {
  186. if ( !SAMEDIRECTION(IsClient, Params[n]) ||
  187. ! Params[n].ParamAttr.MustSize )
  188. continue;
  189. if ( IsClient &&
  190. Params[n].ParamAttr.IsPartialIgnore )
  191. {
  192. LENGTH_ALIGN( pStubMsg->BufferLength, 0x3 );
  193. pStubMsg->BufferLength += PTR_WIRE_SIZE;
  194. continue;
  195. }
  196. //
  197. // Note : Basetypes will always be factored into the
  198. // constant buffer size emitted by in the format strings.
  199. //
  200. pFormatParam = pTypeFormat +
  201. Params[n].TypeOffset;
  202. pArg = pContext->StartofStack + Params[n].StackOffset;
  203. if ( ! Params[n].ParamAttr.IsByValue )
  204. pArg = *((uchar **)pArg);
  205. (*SizeRoutinesTable[ROUTINE_INDEX(*pFormatParam)])
  206. ( pStubMsg,
  207. pArg,
  208. pFormatParam );
  209. }
  210. }
  211. void RPC_ENTRY
  212. NdrpClientMarshal( MIDL_STUB_MESSAGE * pStubMsg,
  213. BOOL IsObject )
  214. {
  215. ulong n;
  216. uchar * pArg;
  217. PFORMAT_STRING pFormatParam;
  218. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  219. PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION ) pContext->Params;
  220. PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
  221. //
  222. // ----------------------------------------------------------
  223. // Marshall Pass.
  224. // ----------------------------------------------------------
  225. //
  226. for ( n = 0; n < pContext->NumberParams; n++ )
  227. {
  228. if (!Params[n].ParamAttr.IsIn ||
  229. Params[n].ParamAttr.IsPipe )
  230. continue;
  231. if ( Params[n].ParamAttr.IsPartialIgnore )
  232. {
  233. pArg = pContext->StartofStack + Params[n].StackOffset;
  234. ALIGN( pStubMsg->Buffer, 0x3 );
  235. *(ulong*)pStubMsg->Buffer = *(void**)pArg ? 1 : 0;
  236. pStubMsg->Buffer += PTR_WIRE_SIZE;
  237. continue;
  238. }
  239. pArg = pContext->StartofStack + Params[n].StackOffset;
  240. if ( Params[n].ParamAttr.IsBasetype )
  241. {
  242. //
  243. // Check for pointer to basetype.
  244. //
  245. if ( Params[n].ParamAttr.IsSimpleRef )
  246. pArg = *((uchar **)pArg);
  247. else
  248. {
  249. #ifdef _IA64_
  250. if ( !IsObject &&
  251. Params[n].SimpleType.Type == FC_FLOAT )
  252. {
  253. // Due to the fact that NdrClientCall2 is called with the
  254. // parameters in ... arguments, floats get promoted to doubles.
  255. // This is not true for DCOM since an assembly langauge wrapper
  256. // is used that saves the floats as floats.
  257. //
  258. // BUG, BUG. IA64 passes byval structures that consist
  259. // entirely of float fields with each field in a separate register.
  260. // We do not handle this case properly.
  261. *((float *) pArg) = (float) *((double *)pArg);
  262. }
  263. #endif
  264. }
  265. if ( Params[n].SimpleType.Type == FC_ENUM16 )
  266. {
  267. if ( *((int *)pArg) & ~((int)0x7fff) )
  268. RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
  269. }
  270. ALIGN( pStubMsg->Buffer,
  271. SIMPLE_TYPE_ALIGNMENT( Params[n].SimpleType.Type ) );
  272. RpcpMemoryCopy(
  273. pStubMsg->Buffer,
  274. pArg,
  275. (uint)SIMPLE_TYPE_BUFSIZE(Params[n].SimpleType.Type) );
  276. pStubMsg->Buffer +=
  277. SIMPLE_TYPE_BUFSIZE( Params[n].SimpleType.Type );
  278. continue;
  279. }
  280. pFormatParam = pTypeFormat +
  281. Params[n].TypeOffset;
  282. if ( ! Params[n].ParamAttr.IsByValue )
  283. pArg = *((uchar **)pArg);
  284. (* MarshallRoutinesTable[ROUTINE_INDEX(*pFormatParam)] )
  285. ( pStubMsg,
  286. pArg,
  287. pFormatParam );
  288. }
  289. if ( pStubMsg->RpcMsg->BufferLength <
  290. (uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer) )
  291. {
  292. NDR_ASSERT( 0, "NdrpClientMarshal marshal: buffer overflow!" );
  293. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  294. }
  295. }
  296. void RPC_ENTRY
  297. NdrpServerMarshal( MIDL_STUB_MESSAGE * pStubMsg,
  298. BOOL IsObject )
  299. {
  300. ulong n;
  301. uchar * pArg;
  302. PFORMAT_STRING pFormatParam;
  303. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  304. PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION ) pContext->Params;
  305. PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
  306. //
  307. // ----------------------------------------------------------
  308. // Marshall Pass.
  309. // ----------------------------------------------------------
  310. //
  311. for ( n = 0; n < pContext->NumberParams; n++ )
  312. {
  313. if (!Params[n].ParamAttr.IsOut ||
  314. Params[n].ParamAttr.IsPipe )
  315. continue;
  316. pArg = pContext->StartofStack + Params[n].StackOffset;
  317. if ( Params[n].ParamAttr.IsBasetype )
  318. {
  319. //
  320. // Check for pointer to basetype.
  321. //
  322. if ( Params[n].ParamAttr.IsSimpleRef )
  323. pArg = *((uchar **)pArg);
  324. if ( Params[n].SimpleType.Type == FC_ENUM16 )
  325. {
  326. if ( *((int *)pArg) & ~((int)0x7fff) )
  327. RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
  328. }
  329. ALIGN( pStubMsg->Buffer,
  330. SIMPLE_TYPE_ALIGNMENT( Params[n].SimpleType.Type ) );
  331. RpcpMemoryCopy(
  332. pStubMsg->Buffer,
  333. pArg,
  334. (uint)SIMPLE_TYPE_BUFSIZE(Params[n].SimpleType.Type) );
  335. pStubMsg->Buffer +=
  336. SIMPLE_TYPE_BUFSIZE( Params[n].SimpleType.Type );
  337. continue;
  338. }
  339. pFormatParam = pTypeFormat +
  340. Params[n].TypeOffset;
  341. if ( ! Params[n].ParamAttr.IsByValue )
  342. pArg = *((uchar **)pArg);
  343. (* MarshallRoutinesTable[ROUTINE_INDEX(*pFormatParam)] )
  344. ( pStubMsg,
  345. pArg,
  346. pFormatParam );
  347. }
  348. if ( pStubMsg->RpcMsg->BufferLength <
  349. (uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer) )
  350. {
  351. NDR_ASSERT( 0, "NdrpServerMarshal marshal: buffer overflow!" );
  352. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  353. }
  354. }
  355. /*
  356. From: To: Marshall: User Exception: Cleanup:Rundown: context handle:
  357. ---------- ---------------------------------- --------------------------------
  358. Any NULL Y N/A No No INVALID_HANDLE from the server
  359. !NULL Same value Any Any No No Same as before
  360. !NULL Different Any Any No No New context on the server
  361. !NULL Any N/A Y No No No new context handle is created
  362. NULL ANY N/A Y Yes No INVALID_HANDLE from the server
  363. NULL !NULL Y N Yes Yes INVALID_HANDLE from the server
  364. NULL !NULL N N Yes Yes INVALID_HANDLE from the server
  365. !NULL NULL N N Yes No No new context handle is created
  366. NULL NULL N N Yes No No new context handle is created
  367. In the OUT only context handle case:
  368. To: Marshall: User Exception: Cleanup:Rundown: context handle:
  369. --------------------------------------------------------------------------------------
  370. Any N/A Y N N No new context handle is created
  371. NULL N N N N No new context handle is created
  372. NULL Y N N N No new context handle is created
  373. !NULL N N N Y No new context handle is created
  374. !NULL Y N Y Y No new context handle is created
  375. */
  376. void
  377. NdrpEmergencyContextCleanup(
  378. MIDL_STUB_MESSAGE * pStubMsg,
  379. PNDR_CONTEXT_HANDLE_ARG_DESC pCtxtDesc,
  380. void * pArg,
  381. BOOL fManagerRoutineException
  382. )
  383. {
  384. int RtnIndex = pCtxtDesc->RundownRtnIndex;
  385. NDR_RUNDOWN pfnRundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[ RtnIndex ];
  386. NDR_SCONTEXT SContext = pStubMsg->SavedContextHandles[ pCtxtDesc->ParamOrdinal ];
  387. void * NewHandle = pArg;
  388. // if runtime failes during marshalling context handle, we shouldn't call into
  389. // cleanup routine since it's already cleanup by runtime.
  390. if ( SContext == (NDR_SCONTEXT )CONTEXT_HANDLE_BEFORE_MARSHAL_MARKER )
  391. return;
  392. if ( fManagerRoutineException )
  393. {
  394. // NDR_ASSERT( SContext != NULL || pCtxtDesc->Flags.IsReturn ,
  395. // "only return context handle can have null scontext in exception" );
  396. // if we failed somewhere during unmarshalling, or this is a return context handle,
  397. // we don't need to cleanup
  398. if ( SContext == NULL )
  399. return;
  400. // in NdrServerOutInit, we initialize the scontext for regular [out] parameters,
  401. // and runtime has already allocated some memory. But for return context handle,
  402. // we initialize the scontext during marshalling and saved context is NULL till
  403. // just before marshalling.
  404. }
  405. else
  406. {
  407. // haven't unmarshalled yet.
  408. if ( SContext == NULL )
  409. {
  410. if ( NULL == NewHandle )
  411. return;
  412. else
  413. {
  414. // note : what if the context handle is both return and viaptr?
  415. NDR_ASSERT( pCtxtDesc->Flags.IsReturn, "has to be return context handle" );
  416. }
  417. }
  418. else
  419. if ( SContext == (NDR_SCONTEXT )CONTEXT_HANDLE_AFTER_MARSHAL_MARKER )
  420. {
  421. // this particular context handle has been marshalled; the exception happens
  422. // during marshalling other parameters after this one.
  423. // After marshalling is done, the runtime will release the user context if new context
  424. // handle is NULL, so we can't reference to the user context at this point.
  425. NewHandle = NULL;
  426. }
  427. else
  428. {
  429. if ( pCtxtDesc->Flags.IsViaPtr )
  430. NewHandle = *((void * UNALIGNED *)pArg);
  431. }
  432. // if this is a regular [in,out] or [out] context handle, and it hasn't been marshalled
  433. // yet, we need to call into runtime to cleanup.
  434. }
  435. // Kamen volunteer to process the logic of calling runtime or not. In NDR we just
  436. // don't call into the routine when it isn't supposed to.
  437. NDRSContextEmergencyCleanup( pStubMsg->RpcMsg->Handle,
  438. SContext,
  439. pfnRundown,
  440. NewHandle,
  441. fManagerRoutineException );
  442. }
  443. void
  444. NdrpCleanupServerContextHandles(
  445. MIDL_STUB_MESSAGE * pStubMsg,
  446. uchar * pStartOfStack,
  447. BOOL fManagerRoutineException )
  448. {
  449. ulong n;
  450. uchar * pArg;
  451. PFORMAT_STRING pFormatParam;
  452. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  453. PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION ) pContext->Params;
  454. PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
  455. //
  456. // ------------------------------------------------------------------------
  457. // Context handle loop: clean up out context handles to prevent leaks.
  458. //
  459. // Note, this routine handles only the handles that may have been dropped
  460. // due to the NDR engine raising exception between a clean return from
  461. // the manager routine and end of marshaling back of the parameters.
  462. // This addresses a situation where handles get dropped by NDR without being
  463. // registered with the runtime and so the server leaks because the rundown
  464. // routine is never called on the dropped handles.
  465. // ------------------------------------------------------------------------
  466. //
  467. for ( n = 0; n < pContext->NumberParams; n++ )
  468. {
  469. if (!Params[n].ParamAttr.IsOut ||
  470. Params[n].ParamAttr.IsPipe )
  471. continue;
  472. pArg = pContext->StartofStack + Params[n].StackOffset;
  473. if ( Params[n].ParamAttr.IsBasetype )
  474. {
  475. //
  476. // Check for pointer to basetype.
  477. //
  478. continue;
  479. }
  480. pFormatParam = pTypeFormat +
  481. Params[n].TypeOffset;
  482. if ( ! Params[n].ParamAttr.IsByValue )
  483. pArg = *((uchar **)pArg);
  484. // Context handle have their own "via pointer" flag to mark dereference.
  485. if ( *pFormatParam == FC_BIND_CONTEXT )
  486. {
  487. NdrpEmergencyContextCleanup( pStubMsg,
  488. (PNDR_CONTEXT_HANDLE_ARG_DESC) pFormatParam,
  489. pArg,
  490. fManagerRoutineException
  491. );
  492. }
  493. } // parameter loop
  494. }
  495. void RPC_ENTRY
  496. NdrpClientUnMarshal ( MIDL_STUB_MESSAGE * pStubMsg,
  497. void * pReturnValue )
  498. {
  499. ulong n;
  500. uchar * pArg;
  501. uchar ** ppArg;
  502. PFORMAT_STRING pFormatParam, pFormat;
  503. NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
  504. PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION)pContext->Params;
  505. PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
  506. // we only need to do conversion in NDR32 now: we cut off endian
  507. // conversion in NDR64.
  508. // Do endian/floating point conversions if necessary.
  509. //
  510. if ( (pStubMsg->RpcMsg->DataRepresentation & 0X0000FFFFUL) !=
  511. NDR_LOCAL_DATA_REPRESENTATION )
  512. {
  513. NdrConvert2( pStubMsg,
  514. (PFORMAT_STRING) Params,
  515. pContext->NumberParams );
  516. }
  517. //
  518. // ----------------------------------------------------------
  519. // Unmarshall Pass.
  520. // ----------------------------------------------------------
  521. //
  522. for ( n = 0; n < pContext->NumberParams; n++ )
  523. {
  524. if ( Params[n].ParamAttr.IsPipe )
  525. continue;
  526. if ( !Params[n].ParamAttr.IsOut )
  527. {
  528. if ( !Params[n].ParamAttr.IsIn
  529. && !Params[n].ParamAttr.IsReturn )
  530. {
  531. // If a param is not [in], [out], or a return value,
  532. // then it is a "hidden" client-side only status
  533. // paramater. It will get set below if an exception
  534. // happens. If everything is ok we need to zero it
  535. // out here.
  536. NDR_ASSERT( Params[n].ParamAttr.IsSimpleRef
  537. && Params[n].ParamAttr.IsBasetype
  538. && FC_ERROR_STATUS_T ==
  539. Params[n].SimpleType.Type,
  540. "Apparently not a hidden status param" );
  541. pArg = pContext->StartofStack + Params[n].StackOffset;
  542. ** (error_status_t **) pArg = RPC_S_OK;
  543. }
  544. continue;
  545. }
  546. if ( Params[n].ParamAttr.IsReturn )
  547. pArg = (uchar *) pReturnValue;
  548. else
  549. pArg = pContext->StartofStack + Params[n].StackOffset;
  550. //
  551. // This is for returned basetypes and for pointers to
  552. // basetypes.
  553. //
  554. if ( Params[n].ParamAttr.IsBasetype )
  555. {
  556. //
  557. // Check for a pointer to a basetype.
  558. //
  559. if ( Params[n].ParamAttr.IsSimpleRef )
  560. pArg = *((uchar **)pArg);
  561. ALIGN( pStubMsg->Buffer,
  562. SIMPLE_TYPE_ALIGNMENT(Params[n].SimpleType.Type) );
  563. #if defined(__RPC_WIN64__)
  564. // Special case for int3264.
  565. if ( Params[n].SimpleType.Type == FC_INT3264 ||
  566. Params[n].SimpleType.Type == FC_UINT3264 )
  567. {
  568. if ( Params[n].SimpleType.Type == FC_INT3264 )
  569. *((INT64 *)pArg) = *((long * &)pStubMsg->Buffer)++;
  570. else
  571. *((UINT64 *)pArg) = *((ulong * &)pStubMsg->Buffer)++;
  572. continue;
  573. }
  574. #endif
  575. if ( Params[n].SimpleType.Type == FC_ENUM16 )
  576. {
  577. *((int *)(pArg)) = *((int *)pArg) & ((int)0x7fff) ;
  578. }
  579. RpcpMemoryCopy(
  580. pArg,
  581. pStubMsg->Buffer,
  582. (uint)SIMPLE_TYPE_BUFSIZE(Params[n].SimpleType.Type) );
  583. pStubMsg->Buffer +=
  584. SIMPLE_TYPE_BUFSIZE( Params[n].SimpleType.Type );
  585. continue;
  586. }
  587. ppArg = Params[n].ParamAttr.IsByValue ? &pArg : (uchar **)pArg;
  588. pFormatParam = pTypeFormat +
  589. Params[n].TypeOffset;
  590. //
  591. // Transmit/Represent as can be passed as [out] only, thus
  592. // the IsByValue check.
  593. //
  594. (* UnmarshallRoutinesTable[ROUTINE_INDEX(*pFormatParam)] )
  595. ( pStubMsg,
  596. ppArg,
  597. pFormatParam,
  598. FALSE );
  599. }
  600. if ( pStubMsg->pCorrInfo )
  601. NdrCorrelationPass( pStubMsg );
  602. return ;
  603. }
  604. void RPC_ENTRY
  605. NdrpServerUnMarshal ( MIDL_STUB_MESSAGE * pStubMsg )
  606. {
  607. ulong n;
  608. uchar * pArg;
  609. uchar ** ppArg;
  610. PFORMAT_STRING pFormatParam, pFormat;
  611. NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
  612. PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION)pContext->Params;
  613. PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
  614. // we only need to do conversion in NDR32 now: we cut off endian
  615. // conversion in NDR64.
  616. // Do endian/floating point conversions if necessary.
  617. //
  618. if ( ( pStubMsg->RpcMsg->DataRepresentation & 0X0000FFFFUL) !=
  619. NDR_LOCAL_DATA_REPRESENTATION )
  620. {
  621. NdrConvert2( pStubMsg,
  622. (PFORMAT_STRING) Params,
  623. (long) pContext->NumberParams );
  624. }
  625. // --------------------------------
  626. // Unmarshall all of our parameters.
  627. // --------------------------------
  628. for ( n = 0; n < pContext->NumberParams; n++ )
  629. {
  630. if ( ! Params[n].ParamAttr.IsIn ||
  631. Params[n].ParamAttr.IsPipe )
  632. continue;
  633. if ( Params[n].ParamAttr.IsPartialIgnore )
  634. {
  635. pArg = pContext->StartofStack + Params[n].StackOffset;
  636. ALIGN( pStubMsg->Buffer, 0x3 );
  637. *(void**)pArg = *(ulong*)pStubMsg->Buffer ? (void*)1 : (void*)0;
  638. pStubMsg->Buffer += PTR_WIRE_SIZE;
  639. continue;
  640. }
  641. pArg = pContext->StartofStack + Params[n].StackOffset;
  642. if ( Params[n].ParamAttr.IsBasetype )
  643. {
  644. //
  645. // Check for a pointer to a basetype. Set the arg pointer
  646. // at the correct buffer location and you're done.
  647. // Except darn int3264
  648. if ( Params[n].ParamAttr.IsSimpleRef )
  649. {
  650. ALIGN( pStubMsg->Buffer,
  651. SIMPLE_TYPE_ALIGNMENT( Params[n].SimpleType.Type ) );
  652. #if defined(__RPC_WIN64__)
  653. // Special case for a ref pointer to int3264.
  654. if ( Params[n].SimpleType.Type == FC_INT3264 ||
  655. Params[n].SimpleType.Type == FC_UINT3264 )
  656. {
  657. *((void **)pArg) = NdrpAlloca( &pContext->AllocateContext, 8 );
  658. if ( Params[n].SimpleType.Type == FC_INT3264 )
  659. *(*(INT64**)pArg) = *((long * &)pStubMsg->Buffer)++;
  660. else
  661. *(*(UINT64**)pArg)= *((ulong * &)pStubMsg->Buffer)++;
  662. continue;
  663. }
  664. #endif
  665. *((uchar **)pArg) = pStubMsg->Buffer;
  666. pStubMsg->Buffer +=
  667. SIMPLE_TYPE_BUFSIZE( Params[n].SimpleType.Type );
  668. }
  669. else
  670. {
  671. NdrUnmarshallBasetypeInline(
  672. pStubMsg,
  673. pArg,
  674. Params[n].SimpleType.Type );
  675. }
  676. continue;
  677. } // IsBasetype
  678. //
  679. // This is an initialization of [in] and [in,out] ref pointers
  680. // to pointers. These can not be initialized to point into the
  681. // rpc buffer and we want to avoid doing a malloc of 4 bytes!
  682. // 32b: a ref pointer to any pointer, we allocate the pointee pointer.
  683. //
  684. if ( Params[n].ParamAttr.ServerAllocSize != 0 )
  685. {
  686. *((void **)pArg) = NdrpAlloca(& pContext->AllocateContext, PTR_MEM_SIZE );
  687. // Triple indirection - cool!
  688. **((void ***)pArg) = 0;
  689. }
  690. pStubMsg->ReuseBuffer = Params[n].ParamAttr.IsForceAllocate;
  691. ppArg = Params[n].ParamAttr.IsByValue ? &pArg : (uchar **)pArg;
  692. pFormatParam = pTypeFormat +
  693. Params[n].TypeOffset;
  694. (*UnmarshallRoutinesTable[ROUTINE_INDEX(*pFormatParam)])
  695. ( pStubMsg,
  696. ppArg,
  697. pFormatParam,
  698. Params[n].ParamAttr.IsForceAllocate &&
  699. !Params[n].ParamAttr.IsByValue );
  700. pStubMsg->ReuseBuffer = FALSE;
  701. }
  702. if ( pStubMsg->pCorrInfo )
  703. NdrCorrelationPass( pStubMsg );
  704. return ;
  705. }
  706. void RPC_ENTRY
  707. NdrpDcomClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
  708. ulong ProcNum,
  709. RPC_STATUS ExceptionCode,
  710. CLIENT_CALL_RETURN * pReturnValue )
  711. {
  712. ulong NumberParams;
  713. PPARAM_DESCRIPTION Params;
  714. PFORMAT_STRING pTypeFormat;
  715. ulong n;
  716. uchar * pArg;
  717. PFORMAT_STRING pFormatParam;
  718. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  719. pReturnValue->Simple = NdrProxyErrorHandler(ExceptionCode);
  720. if( pStubMsg->dwStubPhase != PROXY_UNMARSHAL)
  721. return;
  722. NumberParams = pContext->NumberParams;
  723. Params = ( PPARAM_DESCRIPTION )pContext->Params;
  724. // alert: this can't be directly called from ndrclientcall2: we don't have pSyntaxInfo.
  725. pTypeFormat = pContext->DceTypeFormatString;
  726. //
  727. // In OLE, since they don't know about error_status_t and wanted to
  728. // reinvent the wheel, check to see if we need to map the exception.
  729. // In either case, set the return value and then try to free the
  730. // [out] params, if required.
  731. //
  732. pStubMsg->BufferStart = 0;
  733. pStubMsg->BufferEnd = 0;
  734. for ( n = 0; n < pContext->NumberParams; n++ )
  735. {
  736. //
  737. // Skip everything but [out] only parameters. We make
  738. // the basetype check to cover [out] simple ref pointers
  739. // to basetypes.
  740. //
  741. if ( !Params[n].ParamAttr.IsPartialIgnore )
  742. {
  743. if ( Params[n].ParamAttr.IsIn ||
  744. Params[n].ParamAttr.IsReturn ||
  745. Params[n].ParamAttr.IsBasetype ||
  746. Params[n].ParamAttr.IsPipe )
  747. continue;
  748. }
  749. pArg = pContext->StartofStack + Params[n].StackOffset;
  750. pFormatParam = pTypeFormat +
  751. Params[n].TypeOffset;
  752. NdrClearOutParameters( pStubMsg,
  753. pFormatParam,
  754. *((uchar **)pArg) );
  755. }
  756. return ;
  757. }
  758. void RPC_ENTRY
  759. NdrpClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
  760. ulong ProcNum,
  761. RPC_STATUS ExceptionCode,
  762. CLIENT_CALL_RETURN * pReturnValue )
  763. {
  764. NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT * ) pStubMsg->pContext;
  765. NDR_ASSERT( pContext->NdrInfo.InterpreterFlags.HasCommOrFault,
  766. " must have comm or fault to catch" );
  767. NdrClientMapCommFault( pStubMsg,
  768. ProcNum,
  769. ExceptionCode,
  770. (ULONG_PTR*)&pReturnValue->Simple );
  771. return ;
  772. }
  773. void RPC_ENTRY
  774. NdrpAsyncClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
  775. ulong ProcNum,
  776. RPC_STATUS ExceptionCode,
  777. CLIENT_CALL_RETURN * pReturnValue )
  778. {
  779. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  780. if ( pContext->NdrInfo.InterpreterFlags.HasCommOrFault )
  781. {
  782. NdrClientMapCommFault( pStubMsg,
  783. ProcNum,
  784. ExceptionCode,
  785. (ULONG_PTR*)&pReturnValue->Simple );
  786. if ( ExceptionCode == RPC_S_ASYNC_CALL_PENDING )
  787. {
  788. // If the call is just pending, force the pending error code
  789. // to show up in the return value of RpcAsyncCallComplete.
  790. pReturnValue->Simple = RPC_S_ASYNC_CALL_PENDING;
  791. }
  792. }
  793. else
  794. {
  795. RpcRaiseException(ExceptionCode);
  796. }
  797. return ;
  798. }
  799. void RPC_ENTRY
  800. NdrpClientFinally( PMIDL_STUB_MESSAGE pStubMsg,
  801. void * pThis )
  802. {
  803. NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT * ) pStubMsg->pContext;
  804. NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
  805. NdrCorrelationFree( pStubMsg );
  806. //
  807. // Free the RPC buffer.
  808. //
  809. if ( pThis )
  810. {
  811. NdrProxyFreeBuffer( pThis, pStubMsg );
  812. }
  813. else
  814. {
  815. NdrFreeBuffer( pStubMsg );
  816. //
  817. // Unbind if generic handle used. We do this last so that if the
  818. // the user's unbind routine faults, then all of our internal stuff
  819. // will already have been freed.
  820. //
  821. if ( pContext->SavedGenericHandle )
  822. GenericHandleUnbind( pStubMsg->StubDesc,
  823. pContext->StartofStack,
  824. pContext->pHandleFormatSave,
  825. (pContext->HandleType) ? IMPLICIT_MASK : 0,
  826. &pContext->SavedGenericHandle );
  827. }
  828. NdrpAllocaDestroy( & pContext->AllocateContext );
  829. }
  830. void
  831. NdrpServerInit( PMIDL_STUB_MESSAGE pStubMsg,
  832. RPC_MESSAGE * pRpcMsg,
  833. PMIDL_STUB_DESC pStubDesc,
  834. void * pThis,
  835. IRpcChannelBuffer * pChannel,
  836. PNDR_ASYNC_MESSAGE pAsyncMsg )
  837. {
  838. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *) pStubMsg->pContext;
  839. uchar * pArg;
  840. uchar * pArgBuffer = pContext->StartofStack;
  841. if ( pContext->pSyntaxInfo == NULL )
  842. pContext->DceTypeFormatString = pStubDesc->pFormatTypes;
  843. else
  844. pContext->DceTypeFormatString = pContext->pSyntaxInfo->TypeString;
  845. if ( ! pContext->HandleType )
  846. {
  847. //
  848. // For a handle_t parameter we must pass the handle field of
  849. // the RPC message to the server manager.
  850. //
  851. if ( *pContext->pHandleFormatSave == FC_BIND_PRIMITIVE )
  852. {
  853. pArg = pArgBuffer + *((ushort *)&pContext->pHandleFormatSave[2]);
  854. if ( IS_HANDLE_PTR(pContext->pHandleFormatSave[1]) )
  855. pArg = *((uchar **)pArg);
  856. *((handle_t *)pArg) = pRpcMsg->Handle;
  857. }
  858. }
  859. //
  860. // If OLE, put pThis in first dword of stack.
  861. //
  862. if ( pThis )
  863. {
  864. *((void **)pArgBuffer) =
  865. (void *)((CStdStubBuffer *)pThis)->pvServerObject;
  866. }
  867. //
  868. // Initialize the Stub message.
  869. //
  870. if ( ! pChannel )
  871. {
  872. if ( ! pContext->NdrInfo.pProcDesc->Oi2Flags.HasPipes )
  873. {
  874. NdrServerInitializeNew( pRpcMsg,
  875. pStubMsg,
  876. pStubDesc );
  877. }
  878. else
  879. NdrServerInitializePartial( pRpcMsg,
  880. pStubMsg,
  881. pStubDesc,
  882. pContext->NdrInfo.pProcDesc->ClientBufferSize );
  883. }
  884. else
  885. {
  886. // pipe is not supported in obj interface.
  887. NDR_ASSERT( ! pContext->HasPipe, "Pipe is not supported in dcom" );
  888. NdrStubInitialize( pRpcMsg,
  889. pStubMsg,
  890. pStubDesc,
  891. pChannel );
  892. }
  893. if ( pAsyncMsg )
  894. {
  895. pStubMsg->pAsyncMsg = pAsyncMsg;
  896. pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
  897. }
  898. if ( pContext->NdrInfo.InterpreterFlags.FullPtrUsed )
  899. pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit( 0, XLAT_SERVER );
  900. else
  901. pStubMsg->FullPtrXlatTables = NULL;
  902. //
  903. // Set StackTop AFTER the initialize call, since it zeros the field
  904. // out.
  905. //
  906. pStubMsg->StackTop = pArgBuffer;
  907. if ( pContext->NdrInfo.pProcDesc->Oi2Flags.HasPipes )
  908. {
  909. NdrpPipesInitialize32( pStubMsg,
  910. &pContext->AllocateContext,
  911. (PFORMAT_STRING) pContext->Params,
  912. (char*)pArgBuffer,
  913. pContext->NumberParams );
  914. }
  915. //
  916. // We must make this check AFTER the call to ServerInitialize,
  917. // since that routine puts the stub descriptor alloc/dealloc routines
  918. // into the stub message.
  919. //
  920. if ( pContext->NdrInfo.InterpreterFlags.RpcSsAllocUsed )
  921. NdrRpcSsEnableAllocate( pStubMsg );
  922. if ( pContext->NdrInfo.pProcDesc->Oi2Flags.HasExtensions )
  923. {
  924. pStubMsg->fHasExtensions = 1;
  925. pStubMsg->fHasNewCorrDesc = pContext->NdrInfo.pProcDesc->NdrExts.Flags2.HasNewCorrDesc;
  926. if ( pContext->NdrInfo.pProcDesc->NdrExts.Flags2.ServerCorrCheck )
  927. {
  928. void * pCorr = NdrpAlloca( &pContext->AllocateContext, NDR_DEFAULT_CORR_CACHE_SIZE );
  929. NdrCorrelationInitialize( pStubMsg,
  930. pCorr,
  931. NDR_DEFAULT_CORR_CACHE_SIZE,
  932. 0 /* flags */ );
  933. }
  934. }
  935. }
  936. void NdrpServerOutInit( PMIDL_STUB_MESSAGE pStubMsg )
  937. {
  938. ulong n;
  939. NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
  940. PPARAM_DESCRIPTION Params = ( PPARAM_DESCRIPTION ) pContext->Params;
  941. PFORMAT_STRING pFormatTypes = pContext->DceTypeFormatString;
  942. uchar * pArgBuffer = pContext->StartofStack;
  943. uchar * pArg;
  944. PFORMAT_STRING pFormatParam;
  945. for ( n = 0; n < pContext->NumberParams; n++ )
  946. {
  947. if ( !Params[n].ParamAttr.IsPartialIgnore )
  948. {
  949. if ( Params[n].ParamAttr.IsIn ||
  950. ( Params[n].ParamAttr.IsReturn && !pContext->HasComplexReturn ) ||
  951. Params[n].ParamAttr.IsPipe )
  952. continue;
  953. pArg = pArgBuffer + Params[n].StackOffset;
  954. }
  955. else
  956. {
  957. pArg = pArgBuffer + Params[n].StackOffset;
  958. if ( !*(void**)pArg )
  959. continue;
  960. }
  961. //
  962. // Check if we can initialize this parameter using some of our
  963. // stack.
  964. //
  965. if ( Params[n].ParamAttr.ServerAllocSize != 0 )
  966. {
  967. *((void **)pArg) = NdrpAlloca( &pContext->AllocateContext,
  968. Params[n].ParamAttr.ServerAllocSize * 8);
  969. MIDL_memset( *((void **)pArg),
  970. 0,
  971. Params[n].ParamAttr.ServerAllocSize * 8 );
  972. continue;
  973. }
  974. else if ( Params[n].ParamAttr.IsBasetype )
  975. {
  976. *((void **)pArg) = NdrpAlloca( &pContext->AllocateContext, 8 );
  977. MIDL_memset( *((void **)pArg), 0, 8 );
  978. continue;
  979. };
  980. pFormatParam = pFormatTypes + Params[n].TypeOffset;
  981. NdrOutInit( pStubMsg,
  982. pFormatParam,
  983. (uchar **)pArg );
  984. }
  985. }
  986. #if defined( BUILD_NDR64 )
  987. BOOL IsServerSupportNDR64( MIDL_SERVER_INFO *pServerInfo )
  988. {
  989. if ( ( pServerInfo->pStubDesc->Version > NDR_VERSION ) ||
  990. ( pServerInfo->pStubDesc->Version < NDR_VERSION_6_0 ) ||
  991. ( pServerInfo->pStubDesc->MIDLVersion < MIDL_VERSION_6_0_322 ) ||
  992. ! ( pServerInfo->pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES ) )
  993. return FALSE;
  994. return TRUE;
  995. }
  996. #endif
  997. RPC_STATUS RPC_ENTRY
  998. NdrClientGetSupportedSyntaxes(
  999. IN RPC_CLIENT_INTERFACE * pInf,
  1000. OUT ulong * pCount,
  1001. MIDL_SYNTAX_INFO ** pArr )
  1002. {
  1003. MIDL_SYNTAX_INFO *pSyntaxInfo;
  1004. NDR_ASSERT( pInf->Flags & RPCFLG_HAS_MULTI_SYNTAXES, "invalid clientif" );
  1005. if ( pInf->Flags & RPCFLG_HAS_CALLBACK )
  1006. {
  1007. // interpreter info is MIDL_SERVER_INFO
  1008. MIDL_SERVER_INFO * pServerInfo = ( MIDL_SERVER_INFO *) pInf->InterpreterInfo;
  1009. *pCount = ( ulong ) pServerInfo->nCount ;
  1010. *pArr = pServerInfo->pSyntaxInfo;
  1011. }
  1012. else
  1013. {
  1014. MIDL_STUBLESS_PROXY_INFO * pProxyInfo = ( MIDL_STUBLESS_PROXY_INFO *) pInf->InterpreterInfo;
  1015. *pCount = ( ulong ) pProxyInfo->nCount ;
  1016. *pArr = pProxyInfo->pSyntaxInfo;
  1017. }
  1018. return RPC_S_OK;
  1019. }
  1020. RPC_STATUS RPC_ENTRY
  1021. NdrServerGetSupportedSyntaxes(
  1022. IN RPC_SERVER_INTERFACE * pInf,
  1023. OUT ulong * pCount,
  1024. MIDL_SYNTAX_INFO ** pArr,
  1025. OUT ulong * pPrefer)
  1026. {
  1027. NDR_ASSERT( pInf->Flags & RPCFLG_HAS_MULTI_SYNTAXES,"invalid serverif" );
  1028. MIDL_SERVER_INFO *pServerInfo = ( MIDL_SERVER_INFO *) pInf->InterpreterInfo;
  1029. *pCount = ( ulong ) pServerInfo->nCount;
  1030. *pArr = pServerInfo->pSyntaxInfo;
  1031. NdrpGetPreferredSyntax( ( ulong )pServerInfo->nCount, pServerInfo->pSyntaxInfo, pPrefer );
  1032. return RPC_S_OK;
  1033. }
  1034. RPC_STATUS RPC_ENTRY
  1035. NdrCreateServerInterfaceFromStub(
  1036. IN IRpcStubBuffer* pStub,
  1037. IN OUT RPC_SERVER_INTERFACE *pServerIf )
  1038. {
  1039. #if !defined( BUILD_NDR64 )
  1040. return S_OK;
  1041. #else
  1042. CInterfaceStubVtbl * pStubVTable;
  1043. PMIDL_SERVER_INFO pServerInfo;
  1044. IRpcStubBuffer * pv = NULL;
  1045. RpcTryExcept
  1046. {
  1047. // filter out non-ndr stub first.
  1048. if ( S_OK != pStub->lpVtbl->QueryInterface(pStub, IID_IPrivStubBuffer, (void **)& pv ) )
  1049. return S_OK;
  1050. pv->lpVtbl->Release(pv);
  1051. pStubVTable = (CInterfaceStubVtbl *)
  1052. (*((uchar **)pStub) - sizeof(CInterfaceStubHeader));
  1053. pServerInfo = (PMIDL_SERVER_INFO) pStubVTable->header.pServerInfo;
  1054. // In /Os mode, we don't have pServerInfo.
  1055. if ( pServerInfo &&
  1056. IsServerSupportNDR64( pServerInfo ) )
  1057. {
  1058. memcpy ( &pServerIf->TransferSyntax, pServerInfo->pTransferSyntax, sizeof( RPC_SYNTAX_IDENTIFIER ) );
  1059. pServerIf->Flags |= RPCFLG_HAS_MULTI_SYNTAXES;
  1060. pServerIf->InterpreterInfo = pServerInfo;
  1061. }
  1062. }
  1063. RpcExcept( 1 )
  1064. {
  1065. }
  1066. RpcEndExcept
  1067. #endif
  1068. return S_OK;
  1069. }
  1070. /*++
  1071. Routine Description :
  1072. Read the proc header for different transfer syntax.
  1073. We need to return proc number in dce because for stubs compiled with
  1074. DCE only, proc header is the only place to get the procnum.
  1075. This rountine being called from both client and server. The difference
  1076. is that client side we are reading from the default one; server side we
  1077. are reading from the selected one.
  1078. Arguments :
  1079. Return :
  1080. none. Raise exception if something goes wrong. We can't recovered
  1081. from here because we don't have enough information about how the
  1082. stub looks like if we don't have valid proc header.
  1083. --*/
  1084. ulong RPC_ENTRY
  1085. MulNdrpInitializeContextFromProc (
  1086. SYNTAX_TYPE SyntaxType,
  1087. PFORMAT_STRING pFormat,
  1088. NDR_PROC_CONTEXT * pContext,
  1089. uchar * StartofStack,
  1090. BOOLEAN IsReset )
  1091. {
  1092. ulong RpcFlags;
  1093. ulong ProcNum = 0;
  1094. if ( !IsReset )
  1095. NdrpInitializeProcContext( pContext );
  1096. pContext->pProcFormat = pFormat;
  1097. pContext->StartofStack = StartofStack;
  1098. if ( SyntaxType == XFER_SYNTAX_DCE )
  1099. {
  1100. PPARAM_DESCRIPTION Params;
  1101. INTERPRETER_FLAGS InterpreterFlags;
  1102. PFORMAT_STRING pNewProcDescr;
  1103. INTERPRETER_OPT_FLAGS OptFlags;
  1104. pContext->CurrentSyntaxType = XFER_SYNTAX_DCE;
  1105. pContext->HandleType = *pFormat++ ;
  1106. pContext->UseLocator = (FC_AUTO_HANDLE == pContext->HandleType);
  1107. pContext->NdrInfo.InterpreterFlags = *((PINTERPRETER_FLAGS)pFormat++);
  1108. InterpreterFlags = pContext->NdrInfo.InterpreterFlags;
  1109. if ( InterpreterFlags.HasRpcFlags )
  1110. RpcFlags = *(( UNALIGNED ulong* &)pFormat)++;
  1111. else
  1112. RpcFlags = 0;
  1113. ProcNum = *(ushort *)pFormat; pFormat += 2;
  1114. pContext->StackSize = *(ushort *)pFormat; pFormat += 2;
  1115. pContext->pHandleFormatSave = pFormat;
  1116. pNewProcDescr = pFormat;
  1117. if ( ! pContext->HandleType )
  1118. {
  1119. // explicit handle
  1120. pNewProcDescr += ((*pFormat == FC_BIND_PRIMITIVE) ? 4 : 6);
  1121. }
  1122. pContext->NdrInfo.pProcDesc = (NDR_PROC_DESC *)pNewProcDescr;
  1123. OptFlags = ( (NDR_PROC_DESC *)pNewProcDescr )->Oi2Flags;
  1124. pContext->NumberParams = pContext->NdrInfo.pProcDesc->NumberParams;
  1125. //
  1126. // Parameter descriptions are nicely spit out by MIDL.
  1127. // If there is no extension, Params is in the position of extensions.
  1128. //
  1129. Params = (PPARAM_DESCRIPTION) &( pContext->NdrInfo.pProcDesc->NdrExts );
  1130. // Proc header extentions, from NDR ver. 5.2.
  1131. // Params must be set correctly here because of exceptions.
  1132. if ( OptFlags.HasExtensions )
  1133. {
  1134. pContext->HasComplexReturn = pContext->NdrInfo.pProcDesc->NdrExts.Flags2.HasComplexReturn;
  1135. Params = (PPARAM_DESCRIPTION)((uchar*)Params + pContext->NdrInfo.pProcDesc->NdrExts.Size);
  1136. #if defined(_AMD64_) || defined(_IA64_)
  1137. PNDR_PROC_HEADER_EXTS64 pExts = (PNDR_PROC_HEADER_EXTS64 )&pContext->NdrInfo.pProcDesc->NdrExts;
  1138. pContext->FloatDoubleMask = pExts->FloatArgMask;
  1139. #endif // defined(_AMD64_) || defined(_IA64_)
  1140. }
  1141. pContext->Params = Params;
  1142. pContext->IsAsync = OptFlags.HasAsyncUuid ;
  1143. pContext->IsObject = InterpreterFlags.ObjectProc;
  1144. pContext->HasPipe = OptFlags.HasPipes;
  1145. pContext->ExceptionFlag = ! ( InterpreterFlags.IgnoreObjectException ) &&
  1146. ( pContext->IsObject || InterpreterFlags.HasCommOrFault );
  1147. } // XFER_SYNTAX_DCE
  1148. #if defined(BUILD_NDR64)
  1149. else if ( SyntaxType == XFER_SYNTAX_NDR64 )
  1150. {
  1151. NDR64_PROC_FLAGS * pProcFlags;
  1152. pContext->CurrentSyntaxType = XFER_SYNTAX_NDR64;
  1153. pContext->Ndr64Header = (NDR64_PROC_FORMAT *)pFormat;
  1154. pContext->HandleType =
  1155. NDR64MAPHANDLETYPE( NDR64GETHANDLETYPE( &pContext->Ndr64Header->Flags ) );
  1156. pContext->UseLocator = (FC64_AUTO_HANDLE == pContext->HandleType);
  1157. RpcFlags = pContext->Ndr64Header->RpcFlags;
  1158. #if defined(_AMD64_) || defined(_IA64_)
  1159. pContext->FloatDoubleMask = pContext->Ndr64Header->FloatDoubleMask;
  1160. #endif // defined(_AMD64_) || defined(_IA64_)
  1161. pContext->NumberParams = pContext->Ndr64Header->NumberOfParams;
  1162. pContext->Params = (NDR64_PROC_FORMAT *)( (char *) pFormat + sizeof( NDR64_PROC_FORMAT ) + pContext->Ndr64Header->ExtensionSize );
  1163. pContext->StackSize = pContext->Ndr64Header->StackSize;
  1164. pProcFlags = (NDR64_PROC_FLAGS *) &pContext->Ndr64Header->Flags;
  1165. pContext->HasComplexReturn = pProcFlags->HasComplexReturn;
  1166. pContext->IsAsync = pProcFlags->IsAsync;
  1167. pContext->IsObject = pProcFlags->IsObject;
  1168. pContext->HasPipe = pProcFlags->UsesPipes;
  1169. pContext->ExceptionFlag = pContext->IsObject || pProcFlags->HandlesExceptions;
  1170. } // XFER_SYNTAX_NDR64
  1171. #endif
  1172. else
  1173. NDR_ASSERT( 0, "Invalid transfer syntax.");
  1174. // setup the pipe flag before negotiation.
  1175. if ( pContext->HasPipe )
  1176. {
  1177. RpcFlags &= ~RPC_BUFFER_COMPLETE;
  1178. RpcFlags |= RPC_BUFFER_PARTIAL;
  1179. }
  1180. pContext->RpcFlags = RpcFlags;
  1181. // We need to cleanup the resend flag during initialization in preparation
  1182. // for retry later.
  1183. pContext->NeedsResend = FALSE;
  1184. return ProcNum;
  1185. }