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.

765 lines
22 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1996-2000 Microsoft Corporation
  3. Module Name :
  4. attack.c
  5. Abstract :
  6. This file contains the ndr correlation check for denial of attacks.
  7. Author :
  8. Ryszard K. Kott (ryszardk) Sep 1997
  9. Revision History :
  10. ---------------------------------------------------------------------*/
  11. #include "ndrp.h"
  12. #include "hndl.h"
  13. #include "ndrole.h"
  14. #include "attack.h"
  15. #include "interp.h"
  16. #include "interp2.h"
  17. #include "mulsyntx.h"
  18. #include "asyncu.h"
  19. extern "C" {
  20. extern const GUID CLSID_RpcHelper;
  21. }
  22. inline
  23. PFORMAT_STRING
  24. GetConformanceDescriptor(
  25. PFORMAT_STRING pFormat )
  26. {
  27. static const uchar
  28. ConformanceDescIncrements[] =
  29. {
  30. 4, // Conformant array.
  31. 4, // Conformant varying array.
  32. 0, 0, // Fixed arrays - unused.
  33. 0, 0, // Varying arrays - unused.
  34. 4, // Complex array.
  35. 2, // Conformant char string.
  36. 2, // Conformant byte string.
  37. 4, // Conformant stringable struct.
  38. 2, // Conformant wide char string.
  39. 0, 0, 0, 0, // Non-conformant strings - unused.
  40. 0, // Encapsulated union - unused.
  41. 2, // Non-encapsulated union.
  42. 2, // Byte count pointer.
  43. 0, 0, // Xmit/Rep as - unused.
  44. 2 // Interface pointer.
  45. };
  46. ASSERT( FC_CARRAY <= *pFormat && *pFormat < FC_END);
  47. return pFormat + ConformanceDescIncrements[ *pFormat - FC_CARRAY ];
  48. }
  49. inline
  50. PFORMAT_STRING
  51. GetVarianceDescriptor(
  52. PFORMAT_STRING pFormat )
  53. {
  54. // The array gives offset according to the size of the new correlation descriptors.
  55. static const uchar
  56. VarianceDescIncrements[] =
  57. { 8 + NDR_CORR_EXTENSION_SIZE, // Conformant varying array.
  58. 0, 0, // Fixed arrays - unsed.
  59. 8, 12, // Varying array.
  60. 8 + NDR_CORR_EXTENSION_SIZE, // Complex array.
  61. };
  62. ASSERT( FC_CVARRAY <= *pFormat && *pFormat <= FC_BOGUS_ARRAY );
  63. return pFormat + VarianceDescIncrements[ *pFormat - FC_CVARRAY ];
  64. }
  65. void
  66. NdrpCheckCorrelation(
  67. PMIDL_STUB_MESSAGE pStubMsg,
  68. LONG_PTR Value,
  69. PFORMAT_STRING pFormat,
  70. int CheckKind )
  71. /*
  72. Checks if a correlation check can be performed or needs postponing.
  73. For early correlations it performs the check.
  74. For late correlations it adds an entry in the late correlatrion data base.
  75. Parameters
  76. Value - conformant value related to the descriptor
  77. pFormat - array, string etc object with the descriptor
  78. pStubMsg->pCorrMemory - current memory context like struct
  79. */
  80. {
  81. // pStubMsg->pCorrelationInfo->pCorrFstr - descriptor for the current object
  82. // ASSERT( pStubMsg->pCorrInfo );
  83. // TBD performance: index through 2 dim table could be faster.
  84. if ( ( CheckKind & ~NDR_RESET_VALUE ) == NDR_CHECK_CONFORMANCE )
  85. pFormat = GetConformanceDescriptor( pFormat );
  86. else
  87. pFormat = GetVarianceDescriptor( pFormat );
  88. // See if we can actually check it out or whether we have to postpone it
  89. // till the correlation pass.
  90. NDR_FCDEF_CORRELATION * pConf = (NDR_FCDEF_CORRELATION *)pFormat;
  91. if ( pConf->CorrFlags.DontCheck )
  92. return;
  93. unsigned char * pMemory = pStubMsg->pCorrMemory;
  94. if ( pConf->CorrFlags.Early )
  95. {
  96. ULONG_PTR MaxCountSave = pStubMsg->MaxCount;
  97. ulong OffsetSave = pStubMsg->Offset;
  98. pStubMsg->Offset = 0;
  99. // this call overwrites pStubMsg->MaxCount
  100. NdrpValidateCorrelatedValue( pStubMsg, pMemory, pFormat, Value, CheckKind );
  101. pStubMsg->MaxCount = MaxCountSave;
  102. pStubMsg->Offset = OffsetSave;
  103. }
  104. else
  105. {
  106. // Create correlation data base entry for the correlation pass.
  107. NdrpAddCorrelationData( pStubMsg, pMemory, pFormat, Value, CheckKind );
  108. }
  109. }
  110. //
  111. void
  112. NdrpValidateCorrelatedValue (
  113. PMIDL_STUB_MESSAGE pStubMsg,
  114. uchar * pMemory,
  115. PFORMAT_STRING pFormat,
  116. LONG_PTR Value,
  117. int CheckKind
  118. )
  119. /*++
  120. Routine Description :
  121. This routine computes the conformant size for an array or the switch_is
  122. value for a union.
  123. Arguments :
  124. pStubMsg - Pointer to the stub message.
  125. pMemory - Pointer to the embedding entity: a struct or a stack top.
  126. pFormat - Format string description of the correlation (at old).
  127. It indicates the correlated argument value.
  128. Value - value from the array etc, i.e. from the buffer, to be checked against
  129. Return :
  130. The array or string size or the union switch_is.
  131. --*/
  132. {
  133. void * pCount = 0;
  134. LONG_PTR Count;
  135. unsigned char FormatCopy[4];
  136. BOOL fAsyncSplit = FALSE;
  137. BOOL fResetValue;
  138. fResetValue = CheckKind & NDR_RESET_VALUE;
  139. CheckKind = CheckKind & ~NDR_RESET_VALUE;
  140. // Ignore top level checks for -Os stubs.
  141. if ( !pMemory )
  142. return;
  143. PNDR_FCDEF_CORRELATION pFormatCorr = (PNDR_FCDEF_CORRELATION) pFormat;
  144. //
  145. // First check if this is a callback to an expression evaluation routine.
  146. //
  147. if ( pFormatCorr->Operation == FC_CALLBACK )
  148. {
  149. uchar * pOldStackTop;
  150. ushort Index;
  151. // Index into expression callback routines table.
  152. Index = (ushort) pFormatCorr->Offset;
  153. NDR_ASSERT(pStubMsg->StubDesc->apfnExprEval != 0,
  154. "NdrpComputeConformance : no expr eval routines");
  155. NDR_ASSERT(pStubMsg->StubDesc->apfnExprEval[Index] != 0,
  156. "NdrpComputeConformance : bad expr eval routine index");
  157. pOldStackTop = pStubMsg->StackTop;
  158. //
  159. // The callback routine uses the StackTop field of the stub message
  160. // to base it's offsets from. So if this is a complex attribute for
  161. // an embedded field of a structure then set StackTop equal to the
  162. // pointer to the structure.
  163. //
  164. if ( (*pFormat & 0xf0) != FC_TOP_LEVEL_CONFORMANCE )
  165. {
  166. pStubMsg->StackTop = pMemory;
  167. }
  168. //
  169. // This call puts the result in pStubMsg->MaxCount.
  170. //
  171. (*pStubMsg->StubDesc->apfnExprEval[Index])( pStubMsg );
  172. pStubMsg->StackTop = pOldStackTop;
  173. if ( CheckKind == NDR_CHECK_OFFSET )
  174. pStubMsg->MaxCount = pStubMsg->Offset;
  175. goto ValidateValue;
  176. }
  177. if ( CheckKind == NDR_CHECK_OFFSET )
  178. {
  179. // Checking offset without a call to expr eval routine -
  180. // this means that the offset should be zero.
  181. pStubMsg->MaxCount = 0;
  182. goto ValidateValue;
  183. }
  184. if ( (*pFormat & 0xf0) == FC_NORMAL_CONFORMANCE )
  185. {
  186. // Get the address where the conformance variable is in the struct.
  187. pCount = pMemory + pFormatCorr->Offset;
  188. goto ComputeConformantGetCount;
  189. }
  190. // See if this is an async split
  191. if ( pFormat[1] & 0x20 )
  192. {
  193. fAsyncSplit = TRUE;
  194. RpcpMemoryCopy( & FormatCopy[0], pFormat, 4 );
  195. pFormat = (PFORMAT_STRING) & FormatCopy[0];
  196. // Remove the async marker
  197. FormatCopy[1] = pFormat[1] & 0xdf; // ~0x20
  198. }
  199. //
  200. // Get a pointer to the conformance describing variable.
  201. //
  202. if ( (*pFormat & 0xf0) == FC_TOP_LEVEL_CONFORMANCE )
  203. {
  204. //
  205. // Top level conformance. For /Os stubs, the stubs put the max
  206. // count in the stub message. For /Oi stubs, we get the max count
  207. // via an offset from the stack top.
  208. //
  209. if ( pStubMsg->StackTop )
  210. {
  211. if ( fAsyncSplit )
  212. {
  213. PNDR_DCOM_ASYNC_MESSAGE pAsyncMsg;
  214. pAsyncMsg = (PNDR_DCOM_ASYNC_MESSAGE) pStubMsg->pAsyncMsg;
  215. pCount = pAsyncMsg->BeginStack + (ushort)pFormatCorr->Offset;
  216. }
  217. else
  218. pCount = pStubMsg->StackTop + (ushort)pFormatCorr->Offset;
  219. goto ComputeConformantGetCount;
  220. }
  221. else
  222. {
  223. // Top level conformance with -Os - not supported yet.
  224. //
  225. // If this is top level conformance with /Os then
  226. // a) For early correlation, the compiler should generate the code to
  227. // assign appropriate value to pStubMsg->MaxCount.
  228. // goto ValideValue
  229. // b) For late correlation, we should have a registration call generated,
  230. // so there would be nothing to do.
  231. //
  232. return;
  233. }
  234. }
  235. //
  236. // If we're computing the size of an embedded sized pointer then we
  237. // use the memory pointer in the stub message, which points to the
  238. // beginning of the embedding structure.
  239. //
  240. if ( (*pFormat & 0xf0) == FC_POINTER_CONFORMANCE )
  241. {
  242. pCount = pMemory + pFormatCorr->Offset;
  243. goto ComputeConformantGetCount;
  244. }
  245. //
  246. // Check for constant size/switch.
  247. //
  248. if ( (*pFormat & 0xf0) == FC_CONSTANT_CONFORMANCE )
  249. {
  250. //
  251. // The size/switch is contained in the lower three bytes of the
  252. // long currently pointed to by pFormat.
  253. //
  254. Count = (ULONG_PTR)pFormat[1] << 16;
  255. Count |= (ULONG_PTR) *((ushort *)(pFormat + 2));
  256. goto ComputeConformanceEnd;
  257. }
  258. //
  259. // Check for conformance of a multidimensional array element in
  260. // a -Os stub.
  261. //
  262. if ( (*pFormat & 0xf0) == FC_TOP_LEVEL_MULTID_CONFORMANCE )
  263. {
  264. long Dimension;
  265. if ( fAsyncSplit )
  266. RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
  267. //
  268. // If pArrayInfo is non-null than we have a multi-D array. If it
  269. // is null then we have multi-leveled sized pointers.
  270. //
  271. if ( pStubMsg->pArrayInfo )
  272. {
  273. Dimension = pStubMsg->pArrayInfo->Dimension;
  274. pStubMsg->MaxCount = pStubMsg->pArrayInfo->MaxCountArray[Dimension];
  275. }
  276. else
  277. {
  278. Dimension = *((ushort *)(pFormat + 2));
  279. pStubMsg->MaxCount = pStubMsg->SizePtrCountArray[Dimension];
  280. }
  281. goto ValidateValue;
  282. }
  283. NDR_ASSERT(0, "NdrpValidateCorrelatedValue:, Invalid Correlation type");
  284. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  285. return;
  286. ComputeConformantGetCount:
  287. //
  288. // Must check now if there is a dereference op.
  289. //
  290. if ( pFormatCorr->Operation == FC_DEREFERENCE )
  291. {
  292. pCount = *(void **)pCount;
  293. }
  294. //
  295. // If we're supposed to whack the value instead of checking it do it
  296. // and quit
  297. //
  298. if ( fResetValue )
  299. {
  300. // hypers are not legal types for cs_char size/length_is expressions
  301. if ( FC_HYPER == pFormatCorr->Type )
  302. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  303. CHECK_BOUND( (long)Value, pFormatCorr->Type );
  304. switch ( pFormatCorr->Type )
  305. {
  306. case FC_ULONG:
  307. * (ulong *) pCount = (ulong) Value;
  308. return;
  309. case FC_LONG:
  310. * (ulong *) pCount = (long) Value;
  311. return;
  312. case FC_ENUM16 :
  313. case FC_USHORT :
  314. * (ushort *) pCount = (ushort) Value;
  315. return;
  316. case FC_SHORT :
  317. * (short *) pCount = (short) Value;
  318. return;
  319. case FC_USMALL :
  320. * (uchar *) pCount = (uchar) Value;
  321. return;
  322. case FC_SMALL :
  323. * (char *) pCount = (char) Value;
  324. return;
  325. default :
  326. NDR_ASSERT(0,"NdrpValidateCorrelatedValue : bad reset type");
  327. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  328. }
  329. }
  330. //
  331. // Now get the conformance count.
  332. //
  333. switch ( pFormatCorr->Type )
  334. {
  335. case FC_HYPER :
  336. // iid_is on 64b platforms only.
  337. Count = *((LONG_PTR *)pCount);
  338. break;
  339. case FC_ULONG :
  340. Count = (LONG_PTR)*((ulong *)pCount);
  341. break;
  342. case FC_LONG :
  343. Count = *((long *)pCount);
  344. break;
  345. case FC_ENUM16:
  346. case FC_USHORT :
  347. Count = (long) *((ushort *)pCount);
  348. break;
  349. case FC_SHORT :
  350. Count = (long) *((short *)pCount);
  351. break;
  352. case FC_USMALL :
  353. Count = (long) *((uchar *)pCount);
  354. break;
  355. case FC_SMALL :
  356. Count = (long) *((char *)pCount);
  357. break;
  358. default :
  359. NDR_ASSERT(0,"NdrpValidateCorrelatedValue : bad count type");
  360. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  361. }
  362. //
  363. // Check the operator.
  364. //
  365. switch ( pFormatCorr->Operation )
  366. {
  367. case FC_DIV_2 :
  368. Count /= 2;
  369. break;
  370. case FC_MULT_2 :
  371. if ( (ulong)Count >= 0x40000000 )
  372. RpcRaiseException ( RPC_X_INVALID_BOUND );
  373. Count *= 2;
  374. break;
  375. case FC_SUB_1 :
  376. Count -= 1;
  377. if ( Count < 0 )
  378. RpcRaiseException ( RPC_X_INVALID_BOUND );
  379. break;
  380. case FC_ADD_1 :
  381. Count += 1;
  382. if ( Count < 0 )
  383. RpcRaiseException ( RPC_X_INVALID_BOUND );
  384. break;
  385. default :
  386. // OK
  387. break;
  388. }
  389. ComputeConformanceEnd:
  390. pStubMsg->MaxCount = (ulong) Count;
  391. ValidateValue:
  392. // Compare pStubMsg->MaxCount with the value
  393. BOOL fValueOK = FALSE;
  394. LONG_PTR ArgValue = (LONG_PTR) pStubMsg->MaxCount;
  395. unsigned char FcType = (uchar)pFormatCorr->Type;
  396. if ( (*pFormat & 0xf0) == FC_CONSTANT_CONFORMANCE ||
  397. pFormatCorr->Operation == FC_CALLBACK )
  398. FcType = FC_ULONG;
  399. switch ( FcType )
  400. {
  401. case FC_HYPER :
  402. fValueOK = ArgValue == (LONG_PTR)Value;
  403. break;
  404. case FC_ULONG :
  405. fValueOK = ArgValue == (LONG_PTR)(ulong)Value;
  406. break;
  407. case FC_LONG :
  408. fValueOK = ArgValue == (LONG_PTR)(long)Value;
  409. break;
  410. case FC_ENUM16:
  411. case FC_USHORT :
  412. fValueOK = ArgValue == (LONG_PTR)(ushort)Value;
  413. break;
  414. case FC_SHORT :
  415. fValueOK = ArgValue == (LONG_PTR)(short)Value;
  416. break;
  417. case FC_USMALL :
  418. fValueOK = ArgValue == (LONG_PTR)(uchar)Value;
  419. break;
  420. case FC_SMALL :
  421. fValueOK = ArgValue == (LONG_PTR)(char)Value;
  422. break;
  423. default :
  424. NDR_ASSERT(0,"NdrpValidateCorrelatedValue : bad count type");
  425. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  426. }
  427. if ( !pFormatCorr->CorrFlags.IsIidIs )
  428. {
  429. if (!fValueOK )
  430. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  431. }
  432. else
  433. {
  434. NDR_ASSERT( CheckKind != NDR_CHECK_OFFSET, "invalid check kind" );
  435. if ( CheckKind == NDR_CHECK_OFFSET )
  436. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  437. IID * piidValue = (IID *)Value;
  438. IID * piidArg = (IID *)ArgValue;
  439. if ( 0 != memcmp( piidValue, piidArg, sizeof( IID )))
  440. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  441. }
  442. return;
  443. }
  444. RPCRTAPI
  445. void
  446. RPC_ENTRY
  447. NdrCorrelationInitialize(
  448. PMIDL_STUB_MESSAGE pStubMsg,
  449. void * pCache,
  450. unsigned long CacheSize,
  451. unsigned long Flags
  452. )
  453. /*
  454. Initializes the correlation package for -Os stubs.
  455. */
  456. {
  457. PNDR_CORRELATION_INFO pCorrInfo = (PNDR_CORRELATION_INFO)pCache;
  458. if ( CacheSize == 0xffffffff )
  459. CacheSize = NDR_DEFAULT_CORR_CACHE_SIZE;
  460. pCorrInfo->Header.pCache = (NDR_CORRELATION_INFO *)pCache;
  461. pCorrInfo->Header.pInfo = (NDR_CORRELATION_INFO *)pCache;
  462. pCorrInfo->Header.DataLen = 0;
  463. pCorrInfo->Header.DataSize = (CacheSize - sizeof(NDR_CORRELATION_INFO))
  464. / sizeof(NDR_CORRELATION_INFO_DATA);
  465. pStubMsg->pCorrMemory = pStubMsg->StackTop;
  466. pStubMsg->pCorrInfo = (NDR_CORRELATION_INFO *)pCache;
  467. pStubMsg->fHasExtensions = 1;
  468. pStubMsg->fHasNewCorrDesc = 1;
  469. }
  470. void
  471. NdrpAddCorrelationData(
  472. PMIDL_STUB_MESSAGE pStubMsg,
  473. uchar * pMemory,
  474. PFORMAT_STRING pFormat,
  475. LONG_PTR Value,
  476. int CheckKind
  477. )
  478. /*
  479. Adds a check data to the correlation data base for a later evaluation.
  480. */
  481. {
  482. ASSERT( pStubMsg->pCorrInfo );
  483. PNDR_CORRELATION_INFO pCorrInfo = (PNDR_CORRELATION_INFO)pStubMsg->pCorrInfo;
  484. if ( pCorrInfo->Header.DataSize <= pCorrInfo->Header.DataLen )
  485. {
  486. // Not enough space, need to realloc.
  487. unsigned long NewDataSize;
  488. PNDR_CORRELATION_INFO pCorrInfoNew;
  489. NewDataSize = 2 * pCorrInfo->Header.DataSize;
  490. pCorrInfoNew = (PNDR_CORRELATION_INFO) I_RpcAllocate(
  491. sizeof(NDR_CORRELATION_INFO_HEADER) +
  492. NewDataSize * sizeof(NDR_CORRELATION_INFO_DATA) );
  493. if ( ! pCorrInfoNew )
  494. RpcRaiseException( RPC_S_OUT_OF_MEMORY );
  495. RpcpMemoryCopy( pCorrInfoNew,
  496. pCorrInfo,
  497. sizeof(NDR_CORRELATION_INFO_HEADER) +
  498. pCorrInfo->Header.DataSize * sizeof(NDR_CORRELATION_INFO_DATA) );
  499. pCorrInfoNew->Header.pInfo = pCorrInfoNew;
  500. pCorrInfoNew->Header.DataSize = NewDataSize;
  501. pStubMsg->pCorrInfo = pCorrInfoNew;
  502. if ( pCorrInfo->Header.pInfo != pCorrInfo->Header.pCache )
  503. I_RpcFree( pCorrInfo->Header.pInfo );
  504. pCorrInfo = pCorrInfoNew;
  505. }
  506. pCorrInfo->Data[ pCorrInfo->Header.DataLen ].pMemoryObject = pMemory;
  507. pCorrInfo->Data[ pCorrInfo->Header.DataLen ].Value = Value;
  508. pCorrInfo->Data[ pCorrInfo->Header.DataLen ].pCorrDesc = pFormat;
  509. pCorrInfo->Data[ pCorrInfo->Header.DataLen ].CheckKind = CheckKind;
  510. pCorrInfo->Header.DataLen++;
  511. }
  512. RPCRTAPI
  513. void
  514. RPC_ENTRY
  515. NdrCorrelationPass(
  516. PMIDL_STUB_MESSAGE pStubMsg
  517. )
  518. /*
  519. Walks the data base to check all the correlated values that could not be checked
  520. on fly.
  521. */
  522. {
  523. ASSERT( pStubMsg->pCorrInfo );
  524. if ( pStubMsg->pCorrInfo->Header.DataLen == 0 )
  525. return;
  526. PNDR_CORRELATION_INFO pCorrInfo = (PNDR_CORRELATION_INFO)pStubMsg->pCorrInfo;
  527. for ( int i = 0; i < pCorrInfo->Header.DataLen; i++ )
  528. {
  529. NdrpValidateCorrelatedValue( pStubMsg,
  530. pCorrInfo->Data[ i ].pMemoryObject,
  531. pCorrInfo->Data[ i ].pCorrDesc,
  532. pCorrInfo->Data[ i ].Value,
  533. pCorrInfo->Data[ i ].CheckKind );
  534. }
  535. }
  536. RPCRTAPI
  537. void
  538. RPC_ENTRY
  539. NdrCorrelationFree(
  540. PMIDL_STUB_MESSAGE pStubMsg
  541. )
  542. /*
  543. Releases the correlation data structures.
  544. In /Os stub, NdrCorrelationInitialize is called after fullpointer initialization
  545. and NdrCorrelationFree is called without checking pStubMsg->pCorrInfo. changing
  546. ndr might be better in this case.
  547. */
  548. {
  549. // ASSERT( pStubMsg->pCorrInfo );
  550. PNDR_CORRELATION_INFO pCorrInfo = (PNDR_CORRELATION_INFO)pStubMsg->pCorrInfo;
  551. if ( NULL == pCorrInfo )
  552. return;
  553. if ( pCorrInfo->Header.pInfo != pCorrInfo->Header.pCache )
  554. {
  555. I_RpcFree( pCorrInfo->Header.pInfo );
  556. }
  557. }
  558. HRESULT
  559. NdrpGetRpcHelper(
  560. IRpcHelper ** ppRpcHelper )
  561. /*++
  562. This routine attempts to get hold of an IRpcHelper interface pointer.
  563. We cache the one IP on each process and never release it. This is an inproc server
  564. and interface will be cleanup when process exit.
  565. --*/
  566. {
  567. HRESULT hr;
  568. static IRpcHelper *pRpcHelper = NULL;
  569. *ppRpcHelper = NULL;
  570. if (pRpcHelper)
  571. {
  572. *ppRpcHelper = pRpcHelper;
  573. hr = S_OK;
  574. }
  575. else
  576. {
  577. hr = NdrLoadOleRoutines();
  578. if (SUCCEEDED(hr))
  579. hr = (*pfnCoCreateInstance)( CLSID_RpcHelper,
  580. NULL,
  581. CLSCTX_INPROC_SERVER,
  582. IID_IRpcHelper,
  583. (void **)&pRpcHelper );
  584. if (SUCCEEDED(hr))
  585. *ppRpcHelper = pRpcHelper;
  586. }
  587. return hr;
  588. }
  589. void
  590. NdrpGetIIDFromBuffer(
  591. PMIDL_STUB_MESSAGE pStubMsg,
  592. IID ** ppIID
  593. )
  594. /*
  595. The routine recovers an interface pointer IID from the marshaling buffer.
  596. The IID stays in the buffer, an IID* is returned by the routine.
  597. */
  598. {
  599. IRpcHelper * pRpcHelper = 0;
  600. HRESULT hr;
  601. *ppIID = 0;
  602. hr = NdrpGetRpcHelper( & pRpcHelper );
  603. if(FAILED(hr))
  604. RpcRaiseException(hr);
  605. hr = pRpcHelper->GetIIDFromOBJREF( pStubMsg->Buffer,
  606. ppIID );
  607. if (FAILED(hr))
  608. RpcRaiseException( RPC_X_BAD_STUB_DATA );
  609. // The IRpcHelper is cached in NdrpGetRpcHelper so we don't need to release it.
  610. // pRpcHelper->Release();
  611. }