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.

1776 lines
49 KiB

  1. //#--------------------------------------------------------------
  2. //
  3. // File: crascom.cpp
  4. //
  5. // Synopsis: Implementation of CRasCom class methods
  6. //
  7. //
  8. // History: 2/10/98 MKarki Created
  9. // 5/15/98 SBens Do not consolidate VSAs.
  10. // 9/16/98 SBens Signature of VSAFilter::radiusFromIAS changed.
  11. // 11/17/99 TPerraut Split code for MS-Filter Attribute added
  12. // 428843
  13. //
  14. //
  15. // Copyright (C) 1997-98 Microsoft Corporation
  16. // All rights reserved.
  17. //
  18. //----------------------------------------------------------------
  19. #include "rascominclude.h"
  20. #include "crascom.h"
  21. #include <iastlutl.h>
  22. const DWORD MAX_SLEEP_TIME = 50; //milli-seconds
  23. //
  24. // const and defines below added for the split functions. 428843
  25. //
  26. const CHAR NUL = '\0';
  27. //
  28. // these are the largest values that the attribute type
  29. // packet type have
  30. //
  31. #define MAX_ATTRIBUTE_TYPE 255
  32. //
  33. // these are the related constants
  34. //
  35. #define MAX_ATTRIBUTE_LENGTH 253
  36. #define MAX_VSA_ATTRIBUTE_LENGTH 247
  37. //++--------------------------------------------------------------
  38. //
  39. // Function: SplitAndAdd
  40. //
  41. // Synopsis: This method is used to remove the original attribute
  42. // and add new ones
  43. // Arguments:
  44. // [in] IAttributesRaw*
  45. // [in] PIASATTRIBUTE
  46. // [in] IASTYPE
  47. // [in] DWORD - attribute length
  48. // [in] DWORD - max attribute length
  49. //
  50. // Returns: HRESULT - status
  51. //
  52. // History: MKarki Created 1/19/99
  53. // TPerraut Copied from CRecvFromPipe::SplitAndAdd 11/17/99
  54. //
  55. // Called By: SplitAttributes
  56. //
  57. //----------------------------------------------------------------
  58. HRESULT SplitAndAdd (
  59. /*[in]*/ IAttributesRaw *pIAttributesRaw,
  60. /*[in]*/ PIASATTRIBUTE pIasAttribute,
  61. /*[in]*/ IASTYPE iasType,
  62. /*[in]*/ DWORD dwAttributeLength,
  63. /*[in]*/ DWORD dwMaxLength
  64. )
  65. {
  66. HRESULT hr = S_OK;
  67. DWORD dwPacketsNeeded = 0;
  68. DWORD dwFailed = 0;
  69. PIASATTRIBUTE *ppAttribArray = NULL;
  70. PATTRIBUTEPOSITION pAttribPos = NULL;
  71. _ASSERT (pIAttributesRaw && pIasAttribute);
  72. __try
  73. {
  74. dwPacketsNeeded = dwAttributeLength / dwMaxLength;
  75. if (dwAttributeLength % dwMaxLength) {++dwPacketsNeeded;}
  76. //
  77. // allocate memory for the ATTRIBUTEPOSITION array
  78. //
  79. pAttribPos = reinterpret_cast <PATTRIBUTEPOSITION> (
  80. ::CoTaskMemAlloc (
  81. sizeof (ATTRIBUTEPOSITION)*dwPacketsNeeded));
  82. if (NULL == pAttribPos)
  83. {
  84. IASTracePrintf (
  85. "Unable to allocate memory for attribute position array "
  86. "while split and add of attributese in out-bound packet"
  87. );
  88. hr = E_OUTOFMEMORY;
  89. __leave;
  90. }
  91. //
  92. // allocate array to store the attributes in
  93. //
  94. ppAttribArray =
  95. reinterpret_cast <PIASATTRIBUTE*> (
  96. ::CoTaskMemAlloc (sizeof (PIASATTRIBUTE)*dwPacketsNeeded));
  97. if (NULL == ppAttribArray)
  98. {
  99. IASTracePrintf (
  100. "Unable to allocate memory"
  101. "while split and add of out-bound attribues"
  102. );
  103. hr = E_OUTOFMEMORY;
  104. __leave;
  105. }
  106. DWORD dwFailed =
  107. ::IASAttributeAlloc (dwPacketsNeeded, ppAttribArray);
  108. if (0 != dwFailed)
  109. {
  110. IASTracePrintf (
  111. "Unable to allocate attributes while splitting out-bound"
  112. "attributes"
  113. );
  114. hr = HRESULT_FROM_WIN32 (dwFailed);
  115. __leave;
  116. }
  117. if (IASTYPE_STRING == iasType)
  118. {
  119. PCHAR pStart = (pIasAttribute->Value).String.pszAnsi;
  120. DWORD dwCopySize = dwMaxLength;
  121. //
  122. // set value in each of the new attributes
  123. //
  124. for (DWORD dwCount1 = 0; dwCount1 < dwPacketsNeeded; dwCount1++)
  125. {
  126. (ppAttribArray[dwCount1])->Value.String.pszAnsi =
  127. reinterpret_cast <PCHAR>
  128. (::CoTaskMemAlloc ((dwCopySize + 1)*sizeof (CHAR)));
  129. if (NULL == (ppAttribArray[dwCount1])->Value.String.pszAnsi)
  130. {
  131. IASTracePrintf (
  132. "Unable to allocate memory for new attribute values"
  133. "while split and add of out-bound attribues"
  134. );
  135. hr = E_OUTOFMEMORY;
  136. __leave;
  137. }
  138. //
  139. // set the value now
  140. //
  141. ::CopyMemory (
  142. (ppAttribArray[dwCount1])->Value.String.pszAnsi,
  143. pStart,
  144. dwCopySize
  145. );
  146. //
  147. // nul terminate the values
  148. //
  149. ((ppAttribArray[dwCount1])->Value.String.pszAnsi)[dwCopySize]=NUL;
  150. (ppAttribArray[dwCount1])->Value.itType = iasType;
  151. (ppAttribArray[dwCount1])->dwId = pIasAttribute->dwId;
  152. (ppAttribArray[dwCount1])->dwFlags = pIasAttribute->dwFlags;
  153. //
  154. // calculate for next attribute
  155. //
  156. pStart = pStart + dwCopySize;
  157. dwAttributeLength -= dwCopySize;
  158. dwCopySize = (dwAttributeLength > dwMaxLength) ?
  159. dwMaxLength : dwAttributeLength;
  160. //
  161. // add attribute to position array
  162. //
  163. pAttribPos[dwCount1].pAttribute = ppAttribArray[dwCount1];
  164. }
  165. }
  166. else
  167. {
  168. PBYTE pStart = (pIasAttribute->Value).OctetString.lpValue;
  169. DWORD dwCopySize = dwMaxLength;
  170. //
  171. // fill the new attributes now
  172. //
  173. for (DWORD dwCount1 = 0; dwCount1 < dwPacketsNeeded; dwCount1++)
  174. {
  175. (ppAttribArray[dwCount1])->Value.OctetString.lpValue =
  176. reinterpret_cast <PBYTE> (::CoTaskMemAlloc (dwCopySize));
  177. if (NULL ==(ppAttribArray[dwCount1])->Value.OctetString.lpValue)
  178. {
  179. IASTracePrintf (
  180. "Unable to allocate memory for new attribute values"
  181. "while split and add of out-bound attribues"
  182. );
  183. hr = E_OUTOFMEMORY;
  184. __leave;
  185. }
  186. //
  187. // set the value now
  188. //
  189. ::CopyMemory (
  190. (ppAttribArray[dwCount1])->Value.OctetString.lpValue,
  191. pStart,
  192. dwCopySize
  193. );
  194. (ppAttribArray[dwCount1])->Value.OctetString.dwLength = dwCopySize;
  195. (ppAttribArray[dwCount1])->Value.itType = iasType;
  196. (ppAttribArray[dwCount1])->dwId = pIasAttribute->dwId;
  197. (ppAttribArray[dwCount1])->dwFlags = pIasAttribute->dwFlags;
  198. //
  199. // calculate for next attribute
  200. //
  201. pStart = pStart + dwCopySize;
  202. dwAttributeLength -= dwCopySize;
  203. dwCopySize = (dwAttributeLength > dwMaxLength) ?
  204. dwMaxLength :
  205. dwAttributeLength;
  206. //
  207. // add attribute to position array
  208. //
  209. pAttribPos[dwCount1].pAttribute = ppAttribArray[dwCount1];
  210. }
  211. }
  212. //
  213. // add the attribute to the collection
  214. //
  215. hr = pIAttributesRaw->AddAttributes (dwPacketsNeeded, pAttribPos);
  216. if (FAILED (hr))
  217. {
  218. IASTracePrintf (
  219. "Failed to add attributes to the collection"
  220. "on split and add out-bound attributes"
  221. );
  222. __leave;
  223. }
  224. }
  225. __finally
  226. {
  227. if ((FAILED (hr)) && (ppAttribArray) && (0 == dwFailed))
  228. {
  229. for (DWORD dwCount = 0; dwCount < dwPacketsNeeded; dwCount++)
  230. {
  231. ::IASAttributeRelease (ppAttribArray[dwCount]);
  232. }
  233. }
  234. if (ppAttribArray) {::CoTaskMemFree (ppAttribArray);}
  235. if (pAttribPos) {::CoTaskMemFree (pAttribPos);}
  236. }
  237. return (hr);
  238. } // end of SplitAndAdd method
  239. //++--------------------------------------------------------------
  240. //
  241. // Function: SplitAttributes
  242. //
  243. // Synopsis: This method is used to split up the following
  244. // out-bound attributes:
  245. // 1) Reply-Message attribute
  246. // 1) MS-Filter-VSA Attribute
  247. //
  248. // Arguments:
  249. // [in] IAttributesRaw*
  250. //
  251. // Returns: HRESULT - status
  252. //
  253. // History: MKarki Created 1/19/99
  254. // TPerraut Copied from CRecvFromPipe::SplitAttributes
  255. // 11/17/99
  256. //
  257. // Called By: CRasCom::Process method
  258. //
  259. //----------------------------------------------------------------
  260. HRESULT SplitAttributes (
  261. /*[in]*/ IAttributesRaw *pIAttributesRaw
  262. )
  263. {
  264. const DWORD SPLIT_ATTRIBUTE_COUNT = 2;
  265. static DWORD AttribIds [] = {
  266. RADIUS_ATTRIBUTE_REPLY_MESSAGE,
  267. MS_ATTRIBUTE_FILTER
  268. };
  269. HRESULT hr = S_OK;
  270. DWORD dwAttributesFound = 0;
  271. PATTRIBUTEPOSITION pAttribPos = NULL;
  272. _ASSERT (pIAttributesRaw);
  273. __try
  274. {
  275. //
  276. // get the count of the total attributes in the collection
  277. //
  278. DWORD dwAttributeCount = 0;
  279. hr = pIAttributesRaw->GetAttributeCount (&dwAttributeCount);
  280. if (FAILED (hr))
  281. {
  282. IASTracePrintf (
  283. "Unable to obtain attribute count in request while "
  284. "splitting attributes in out-bound packet "
  285. );
  286. __leave;
  287. }
  288. else if (0 == dwAttributeCount)
  289. {
  290. __leave;
  291. }
  292. //
  293. // allocate memory for the ATTRIBUTEPOSITION array
  294. //
  295. pAttribPos = reinterpret_cast <PATTRIBUTEPOSITION> (
  296. ::CoTaskMemAlloc (
  297. sizeof (ATTRIBUTEPOSITION)*dwAttributeCount)
  298. );
  299. if (NULL == pAttribPos)
  300. {
  301. IASTracePrintf (
  302. "Unable to allocate memory for attribute position array "
  303. "while splitting attributes in out-bound packet"
  304. );
  305. hr = E_OUTOFMEMORY;
  306. __leave;
  307. }
  308. //
  309. // get the attributes we are interested in from the interface
  310. //
  311. hr = pIAttributesRaw->GetAttributes (
  312. &dwAttributeCount,
  313. pAttribPos,
  314. SPLIT_ATTRIBUTE_COUNT,
  315. static_cast <PDWORD> (AttribIds)
  316. );
  317. if (FAILED (hr))
  318. {
  319. IASTracePrintf (
  320. "Unable to obtain information about attributes"
  321. "while splitting attributes in out-bound RADIUS packet"
  322. );
  323. __leave;
  324. }
  325. else if (0 == dwAttributeCount)
  326. {
  327. __leave;
  328. }
  329. //
  330. // save the count of attributes returned
  331. //
  332. dwAttributesFound = dwAttributeCount;
  333. DWORD dwAttribLength = 0;
  334. DWORD dwMaxPossibleLength = 0;
  335. IASTYPE iasType = IASTYPE_INVALID;
  336. //
  337. // evaluate each attribute now
  338. //
  339. for (DWORD dwCount = 0; dwCount < dwAttributeCount; dwCount++)
  340. {
  341. if ((pAttribPos[dwCount].pAttribute)->dwFlags &
  342. IAS_INCLUDE_IN_RESPONSE)
  343. {
  344. //
  345. // get attribute type and length
  346. //
  347. if (
  348. (iasType = (pAttribPos[dwCount].pAttribute)->Value.itType) ==
  349. IASTYPE_STRING
  350. )
  351. {
  352. ::IASAttributeAnsiAlloc (pAttribPos[dwCount].pAttribute);
  353. dwAttribLength =
  354. strlen (
  355. (pAttribPos[dwCount].pAttribute)->Value.String.pszAnsi);
  356. }
  357. else if (
  358. (iasType = (pAttribPos[dwCount].pAttribute)->Value.itType) ==
  359. IASTYPE_OCTET_STRING
  360. )
  361. {
  362. dwAttribLength =
  363. (pAttribPos[dwCount].pAttribute)->Value.OctetString.dwLength;
  364. }
  365. else
  366. {
  367. //
  368. // only string values need to be split
  369. //
  370. continue;
  371. }
  372. //
  373. // get max possible attribute length
  374. //
  375. if ((pAttribPos[dwCount].pAttribute)->dwId > MAX_ATTRIBUTE_TYPE)
  376. {
  377. dwMaxPossibleLength = MAX_VSA_ATTRIBUTE_LENGTH;
  378. }
  379. else
  380. {
  381. dwMaxPossibleLength = MAX_ATTRIBUTE_LENGTH;
  382. }
  383. //
  384. // check if we need to split this attribute
  385. //
  386. if (dwAttribLength <= dwMaxPossibleLength) {continue;}
  387. //
  388. // split the attribute now
  389. //
  390. hr = SplitAndAdd (
  391. pIAttributesRaw,
  392. pAttribPos[dwCount].pAttribute,
  393. iasType,
  394. dwAttribLength,
  395. dwMaxPossibleLength
  396. );
  397. if (SUCCEEDED (hr))
  398. {
  399. //
  400. // remove this attribute from the collection now
  401. //
  402. hr = pIAttributesRaw->RemoveAttributes (
  403. 1,
  404. &(pAttribPos[dwCount])
  405. );
  406. if (FAILED (hr))
  407. {
  408. IASTracePrintf (
  409. "Unable to remove attribute from collection"
  410. "while splitting out-bound attributes"
  411. );
  412. }
  413. }
  414. }
  415. }
  416. }
  417. __finally
  418. {
  419. if (pAttribPos)
  420. {
  421. for (DWORD dwCount = 0; dwCount < dwAttributesFound; dwCount++)
  422. {
  423. ::IASAttributeRelease (pAttribPos[dwCount].pAttribute);
  424. }
  425. ::CoTaskMemFree (pAttribPos);
  426. }
  427. }
  428. return (hr);
  429. } // end of SplitAttributes method
  430. //++--------------------------------------------------------------
  431. //
  432. // Function: CRasCom
  433. //
  434. // Synopsis: This is CRasCom Class constructor
  435. //
  436. // Arguments: NONE
  437. //
  438. // Returns: NONE
  439. //
  440. // History: MKarki Created 2/10/98
  441. //
  442. //----------------------------------------------------------------
  443. CRasCom::CRasCom (
  444. VOID
  445. )
  446. :m_objCRequestSource (this),
  447. m_pIRequestHandler(NULL),
  448. m_pIClassFactory (NULL),
  449. m_bVSAFilterInitialized (FALSE),
  450. m_lRequestCount (0),
  451. m_eCompState (COMP_SHUTDOWN)
  452. {
  453. } // end of CRasCom class constructor
  454. //++--------------------------------------------------------------
  455. //
  456. // Function: ~CRasCom
  457. //
  458. // Synopsis: This is CRasCom class destructor
  459. //
  460. // Arguments: NONE
  461. //
  462. // Returns: NONE
  463. //
  464. //
  465. // History: MKarki Created 2/10/98
  466. //
  467. //----------------------------------------------------------------
  468. CRasCom::~CRasCom(
  469. VOID
  470. )
  471. {
  472. } // end of CRasCom class destructor
  473. //++--------------------------------------------------------------
  474. //
  475. // Function: InitNew
  476. //
  477. // Synopsis: This is the InitNew method exposed through the
  478. // IIasComponent COM Interface.
  479. // For the RasCom Component it is implemented for
  480. // completeness
  481. //
  482. //
  483. // Arguments: none
  484. //
  485. // Returns: HRESULT - status
  486. //
  487. // History: MKarki Created 2/10/98
  488. //
  489. // Called By: by the Component intializer through the IIasComponent
  490. // interface
  491. //
  492. //----------------------------------------------------------------
  493. STDMETHODIMP
  494. CRasCom::InitNew (
  495. VOID
  496. )
  497. {
  498. //
  499. // InitNew call can only be made from SHUTDOWN state
  500. //
  501. if (COMP_SHUTDOWN != m_eCompState)
  502. {
  503. IASTracePrintf ("The Surrogate can not be called in this state");
  504. return (E_UNEXPECTED);
  505. }
  506. //
  507. // reset the total pending request count
  508. //
  509. m_lRequestCount = 0;
  510. //
  511. // now we are initialized
  512. m_eCompState = COMP_UNINITIALIZED;
  513. return (S_OK);
  514. } // end of CRasCom::InitNew method
  515. //++--------------------------------------------------------------
  516. //
  517. // Function: Initialize
  518. //
  519. // Synopsis: This is the Initialize method exposed through the
  520. // IIasComponent COM Interface. It initializes the
  521. // Request object ClassFactory
  522. //
  523. // Arguments: none
  524. //
  525. // Returns: HRESULT - status
  526. //
  527. // History: MKarki Created 2/10/98
  528. //
  529. // Called By: by the Component intializer through the IIasComponent
  530. // interface
  531. //
  532. //----------------------------------------------------------------
  533. STDMETHODIMP
  534. CRasCom::Initialize (
  535. VOID
  536. )
  537. {
  538. HRESULT hr = S_OK;
  539. //
  540. // Initialize call can only be made from Uninitialized state
  541. //
  542. if (COMP_INITIALIZED == m_eCompState)
  543. {
  544. return (S_OK);
  545. }
  546. else if (COMP_UNINITIALIZED != m_eCompState)
  547. {
  548. IASTracePrintf ("The Surrogate can not be initialized in this state");
  549. return (E_UNEXPECTED);
  550. }
  551. //
  552. // get the IClassFactory interface to be used to create
  553. // the Request COM object
  554. //
  555. hr = ::CoGetClassObject (
  556. __uuidof (Request),
  557. CLSCTX_INPROC_SERVER,
  558. NULL,
  559. IID_IClassFactory,
  560. reinterpret_cast <PVOID*> (&m_pIClassFactory)
  561. );
  562. if (FAILED (hr))
  563. {
  564. IASTracePrintf ("The Surrogate was unable to obtain request factory");
  565. return (hr);
  566. }
  567. //
  568. // initialize the VSAFilter class object
  569. //
  570. hr = m_objVSAFilter.initialize ();
  571. if (FAILED (hr))
  572. {
  573. IASTracePrintf ("The Surrogate was unable to initializa VSA filtering");
  574. m_pIClassFactory->Release ();
  575. m_pIClassFactory = NULL;
  576. return (hr);
  577. }
  578. else
  579. {
  580. m_bVSAFilterInitialized = TRUE;
  581. }
  582. //
  583. // correctly initialized the surrogate
  584. //
  585. m_eCompState = COMP_INITIALIZED;
  586. return (S_OK);
  587. } // end of CRasCom::Initialize method
  588. //++--------------------------------------------------------------
  589. //
  590. // Function: Shutdown
  591. //
  592. // Synopsis: This is the ShutDown method exposed through the
  593. // IIasComponent COM Interface. It is used to stop
  594. // processing data
  595. //
  596. // Arguments: NONE
  597. //
  598. // Returns: HRESULT - status
  599. //
  600. // History: MKarki Created 2/10/98
  601. //
  602. // Called By: by the Component shutdown through the IIasComponent
  603. // interface
  604. //
  605. //----------------------------------------------------------------
  606. STDMETHODIMP
  607. CRasCom::Shutdown (
  608. VOID
  609. )
  610. {
  611. BOOL bStatus = FALSE;
  612. //
  613. // shutdown can only be called from the suspend state
  614. //
  615. if (COMP_SHUTDOWN == m_eCompState)
  616. {
  617. return (S_OK);
  618. }
  619. else if (
  620. (COMP_SUSPENDED != m_eCompState) &&
  621. (COMP_UNINITIALIZED != m_eCompState)
  622. )
  623. {
  624. IASTracePrintf ("The Surrogate can not be shutdown in current state");
  625. return (E_UNEXPECTED);
  626. }
  627. //
  628. // release the interfaces
  629. //
  630. if (NULL != m_pIRequestHandler)
  631. {
  632. m_pIRequestHandler->Release ();
  633. m_pIRequestHandler = NULL;
  634. }
  635. if (NULL != m_pIClassFactory)
  636. {
  637. m_pIClassFactory->Release ();
  638. m_pIClassFactory = NULL;
  639. }
  640. //
  641. // shutdown the VSAFilter
  642. //
  643. if (TRUE == m_bVSAFilterInitialized)
  644. {
  645. m_objVSAFilter.shutdown ();
  646. m_bVSAFilterInitialized = FALSE;
  647. }
  648. //
  649. // cleanly shutting down
  650. //
  651. m_eCompState = COMP_SHUTDOWN;
  652. return (S_OK);
  653. } // end of CRasCom::Shutdown method
  654. //++--------------------------------------------------------------
  655. //
  656. // Function: Suspend
  657. //
  658. // Synopsis: This is the Suspend method exposed through the
  659. // IComponent COM Interface. It is used to suspend
  660. // packet processing operations
  661. //
  662. // Arguments: NONE
  663. //
  664. // Returns: HRESULT - status
  665. //
  666. //
  667. // History: MKarki Created 10/2/97
  668. //
  669. //----------------------------------------------------------------
  670. STDMETHODIMP
  671. CRasCom::Suspend (
  672. VOID
  673. )
  674. {
  675. BOOL bStatus = FALSE;
  676. HRESULT hr = S_OK;
  677. //
  678. // suspend can only be called from the initialized state
  679. //
  680. if (COMP_SUSPENDED == m_eCompState)
  681. {
  682. return (S_OK);
  683. }
  684. else if (COMP_INITIALIZED != m_eCompState)
  685. {
  686. IASTracePrintf ("The Surrogate can not be suspended in current state");
  687. return (E_UNEXPECTED);
  688. }
  689. //
  690. // change state
  691. //
  692. m_eCompState = COMP_SUSPENDED;
  693. while (0 != m_lRequestCount) { Sleep (MAX_SLEEP_TIME); }
  694. //
  695. // we have successfully suspended RADIUS component's packet
  696. // processing operations
  697. //
  698. return (hr);
  699. } // end of CRasCom::Suspend method
  700. //++--------------------------------------------------------------
  701. //
  702. // Function: Resume
  703. //
  704. // Synopsis: This is the Resume method exposed through the
  705. // IComponent COM Interface. It is used to resume
  706. // packet processing operations which had been
  707. // stopped by a previous call to Suspend API
  708. //
  709. //
  710. // Arguments: NONE
  711. //
  712. // Returns: HRESULT - status
  713. //
  714. //
  715. // History: MKarki Created 10/2/97
  716. //
  717. //----------------------------------------------------------------
  718. STDMETHODIMP
  719. CRasCom::Resume (
  720. VOID
  721. )
  722. {
  723. if (COMP_SUSPENDED != m_eCompState)
  724. {
  725. IASTracePrintf ("The Surrogate can not resume in current state");
  726. return (E_UNEXPECTED);
  727. }
  728. //
  729. // we have successfully resumed operations in the RADIUS component
  730. //
  731. m_eCompState = COMP_INITIALIZED;
  732. return (S_OK);
  733. } // end of CRasCom::Resume method
  734. //++--------------------------------------------------------------
  735. //
  736. // Function: GetProperty
  737. //
  738. // Synopsis: This is the IIasComponent Interface method.
  739. // Only Implemented for the sake of completeness
  740. //
  741. // Arguments:
  742. // [in] LONG - id
  743. // [out] VARIANT - *pValue
  744. //
  745. // Returns: HRESULT - status
  746. //
  747. //
  748. // History: MKarki Created 2/10/98
  749. //
  750. //----------------------------------------------------------------
  751. STDMETHODIMP
  752. CRasCom::GetProperty (
  753. LONG id,
  754. VARIANT *pValue
  755. )
  756. {
  757. return (S_OK);
  758. } // end of CRasCom::GetProperty method
  759. //++--------------------------------------------------------------
  760. //
  761. // Function: PutProperty
  762. //
  763. // Synopsis: This is the IIasComponent Interface method.
  764. // Only Implemented for the sake of completeness
  765. // Arguments:
  766. // [in] LONG - id
  767. // [out] VARIANT - *pValue
  768. //
  769. // Returns: HRESULT - status
  770. //
  771. // History: MKarki Created 2/10/98
  772. //
  773. //----------------------------------------------------------------
  774. STDMETHODIMP
  775. CRasCom::PutProperty (
  776. LONG id,
  777. VARIANT *pValue
  778. )
  779. {
  780. HRESULT hr = S_OK;
  781. //
  782. // PutProperty method can only be called from
  783. // Uninitialized, Initialized or Suspended state
  784. //
  785. if (
  786. (COMP_UNINITIALIZED != m_eCompState) &&
  787. (COMP_INITIALIZED != m_eCompState) &&
  788. (COMP_SUSPENDED == m_eCompState)
  789. )
  790. {
  791. IASTracePrintf ("Surrogate can not put property in current state");
  792. return (E_UNEXPECTED);
  793. }
  794. //
  795. // check if valid arguments where passed in
  796. //
  797. if (NULL == pValue) { return (E_POINTER); }
  798. //
  799. // carry out the property intialization now
  800. //
  801. switch (id)
  802. {
  803. case PROPERTY_PROTOCOL_REQUEST_HANDLER:
  804. if (NULL != m_pIRequestHandler)
  805. {
  806. //
  807. // clients can not be updated in INITIALIZED or
  808. // SUSPENDED state
  809. //
  810. hr = HRESULT_FROM_WIN32 (ERROR_ALREADY_INITIALIZED);
  811. }
  812. else if (VT_DISPATCH != pValue->vt)
  813. {
  814. hr = DISP_E_TYPEMISMATCH;
  815. }
  816. else if (NULL == pValue->punkVal)
  817. {
  818. hr = E_INVALIDARG;
  819. }
  820. else
  821. {
  822. //
  823. // initialize the providers
  824. //
  825. m_pIRequestHandler = reinterpret_cast <IRequestHandler*>
  826. (pValue->punkVal);
  827. m_pIRequestHandler->AddRef ();
  828. }
  829. break;
  830. default:
  831. hr = DISP_E_MEMBERNOTFOUND;
  832. break;
  833. }
  834. return (hr);
  835. } // end of CRasCom::PutProperty method
  836. //++--------------------------------------------------------------
  837. //
  838. // Function: QueryInterfaceReqSrc
  839. //
  840. // Synopsis: This is the function called when this Component
  841. // is called and queried for its IRequestSource
  842. // interface
  843. //
  844. // Arguments:
  845. // [in] PVOID - this object refrence
  846. // [in] REFIID - IID of interface requested
  847. // [out] LPVOID - return appropriate interface
  848. // [in] DWORD
  849. //
  850. //
  851. // Returns: HRESULT - status
  852. //
  853. // History: MKarki Created 2/10/98
  854. //
  855. //----------------------------------------------------------------
  856. HRESULT WINAPI
  857. CRasCom::QueryInterfaceReqSrc (
  858. PVOID pThis,
  859. REFIID riid,
  860. LPVOID *ppv,
  861. DWORD_PTR dwValue
  862. )
  863. {
  864. if ((NULL == pThis) || (NULL == ppv))
  865. return (E_FAIL);
  866. //
  867. // get a reference to the nested CRequestSource object
  868. //
  869. *ppv =
  870. &(static_cast<CRasCom*>(pThis))->m_objCRequestSource;
  871. //
  872. // increment count
  873. //
  874. ((LPUNKNOWN)*ppv)->AddRef();
  875. return (S_OK);
  876. } // end of CRasCom::QueryInterfaceReqSrc method
  877. //++--------------------------------------------------------------
  878. //
  879. // Function: CRequestSource
  880. //
  881. // Synopsis: This is the constructor of the CRequestSource
  882. // nested class
  883. //
  884. // Arguments:
  885. // [in] CRasCom*
  886. //
  887. // Returns: none
  888. //
  889. // History: MKarki Created 2/10/98
  890. //
  891. //----------------------------------------------------------------
  892. CRasCom::CRequestSource::CRequestSource(
  893. CRasCom *pCRasCom
  894. )
  895. :m_pCRasCom (pCRasCom)
  896. {
  897. _ASSERT (NULL != pCRasCom);
  898. } // end of CRequestSource class constructor
  899. //++--------------------------------------------------------------
  900. //
  901. // Function: ~CRequestSource
  902. //
  903. // Synopsis: This is the destructor of the CRequestSource
  904. // nested class
  905. //
  906. // Arguments:
  907. //
  908. // Returns: HRESULT - status
  909. //
  910. //
  911. // History: MKarki Created 11/21/97
  912. //
  913. //----------------------------------------------------------------
  914. CRasCom::CRequestSource::~CRequestSource()
  915. {
  916. } // end of CRequestSource destructor
  917. //++--------------------------------------------------------------
  918. //
  919. // Function: OnRequestComplete
  920. //
  921. // Synopsis: This is a method of IRequestHandler COM interface
  922. // This is the function called when a request is
  923. // is being pushed back after backend processing
  924. // we just return here as we are only be doing
  925. // synchronous processing
  926. //
  927. // Arguments:
  928. // [in] IRequest*
  929. // [in] IASREQUESTSTATUS
  930. //
  931. // Returns: HRESULT - status
  932. //
  933. // History: MKarki Created 2/10/98
  934. //
  935. // Called By: Pipeline through the IRequestHandler interface
  936. //
  937. //----------------------------------------------------------------
  938. STDMETHODIMP CRasCom::CRequestSource::OnRequestComplete (
  939. IRequest *pIRequest,
  940. IASREQUESTSTATUS eStatus
  941. )
  942. {
  943. BOOL bStatus = FALSE;
  944. HANDLE hEvent = NULL;
  945. HRESULT hr = S_OK;
  946. unsigned hyper uhyState = 0;
  947. CComPtr <IRequestState> pIRequestState;
  948. if (NULL == pIRequest)
  949. {
  950. IASTracePrintf (
  951. "Surrogate passed invalid argumen in OnRequestComplete method"
  952. );
  953. return (E_POINTER);
  954. }
  955. //
  956. // get the IRequestState interface now
  957. //
  958. hr = pIRequest->QueryInterface (
  959. __uuidof(IRequestState),
  960. reinterpret_cast <PVOID*> (&pIRequestState)
  961. );
  962. if (FAILED (hr))
  963. {
  964. IASTracePrintf (
  965. "Surrogate unable to obtain IRequestState interface in"
  966. " OnRequestComplete method"
  967. );
  968. return (hr);
  969. }
  970. //
  971. // get the CPacketRadius class object
  972. //
  973. hr = pIRequestState->Pop (
  974. reinterpret_cast <unsigned hyper*> (&uhyState)
  975. );
  976. if (FAILED (hr))
  977. {
  978. IASTracePrintf (
  979. "Surrogate unable to obtain information from Request State"
  980. " in OnRequestComplete method"
  981. );
  982. return (hr);
  983. }
  984. //
  985. // get the hEvent;
  986. //
  987. hEvent = reinterpret_cast <HANDLE> (uhyState);
  988. //
  989. // set the event now
  990. //
  991. bStatus = ::SetEvent (hEvent);
  992. if (FALSE == bStatus)
  993. {
  994. IASTracePrintf (
  995. "Surrogate unable to send notification that request is"
  996. " processed in OnRequestComplete method"
  997. );
  998. return (E_FAIL);
  999. }
  1000. return (S_OK);
  1001. } // end of CRasCom::CRequestSource::OnRequestComplete method
  1002. //++--------------------------------------------------------------
  1003. //
  1004. // Function: Process
  1005. //
  1006. // Synopsis: This is the method of the IRecvRequest COM interface
  1007. // It is called to generate and send request to the
  1008. // pipeline
  1009. //
  1010. // Arguments:
  1011. // [in] DWORD - number of in attributes
  1012. // [in] PIASATTRIBUTE* - array of pointer to attribs
  1013. // [out] PDWORD - number of out attributes
  1014. // [out] PIASATTRIBUTE** - pointer
  1015. // [in] LONG
  1016. // [in/out]LONG*
  1017. // [in] IASPROTCOL
  1018. //
  1019. // Returns: HRESULT - status
  1020. //
  1021. // History: MKarki Created 2/10/98
  1022. //
  1023. // Called By: Called by DoRequest C style API
  1024. //
  1025. //----------------------------------------------------------------
  1026. STDMETHODIMP
  1027. CRasCom::Process (
  1028. /*[in]*/ DWORD dwInAttributeCount,
  1029. /*[in]*/ PIASATTRIBUTE *ppInIasAttribute,
  1030. /*[out]*/ PDWORD pdwOutAttributeCount,
  1031. /*[out]*/ PIASATTRIBUTE **pppOutIasAttribute,
  1032. /*[in]*/ LONG IasRequest,
  1033. /*[in/out]*/ LONG *pIasResponse,
  1034. /*[in]*/ IASPROTOCOL IasProtocol,
  1035. /*[out]*/ PLONG plReason,
  1036. /*[in]*/ BOOL bProcessVSA
  1037. )
  1038. {
  1039. DWORD dwCount = 0;
  1040. HRESULT hr = S_OK;
  1041. HANDLE hEvent = NULL;
  1042. DWORD dwRetVal = 0;
  1043. IRequest *pIRequest = NULL;
  1044. IAttributesRaw *pIAttributesRaw = NULL;
  1045. IRequestState *pIRequestState = NULL;
  1046. PATTRIBUTEPOSITION pIasAttribPos = NULL;
  1047. static DWORD dwRequestCount = 0;
  1048. //
  1049. // check if processing is enabled
  1050. //
  1051. if ((COMP_INITIALIZED != m_eCompState) || (NULL == m_pIRequestHandler))
  1052. {
  1053. IASTracePrintf (
  1054. "Surrogate passed invalid argument for request processing"
  1055. );
  1056. return (E_FAIL);
  1057. }
  1058. __try
  1059. {
  1060. //
  1061. // increment the request count
  1062. //
  1063. InterlockedIncrement (&m_lRequestCount);
  1064. // check if we are processing requests at this time
  1065. //
  1066. if ((COMP_INITIALIZED != m_eCompState) || (NULL == m_pIRequestHandler))
  1067. {
  1068. IASTracePrintf (
  1069. "Surrogate unable to process request in the current state"
  1070. );
  1071. hr = E_FAIL;
  1072. __leave;
  1073. }
  1074. if (
  1075. (0 == dwInAttributeCount) ||
  1076. (NULL == ppInIasAttribute) ||
  1077. (NULL == pdwOutAttributeCount) ||
  1078. (NULL == pppOutIasAttribute) ||
  1079. (NULL == pIasResponse) ||
  1080. (NULL == plReason)
  1081. )
  1082. {
  1083. IASTracePrintf (
  1084. "Surrogate passed invalid argument for processing request"
  1085. );
  1086. hr = E_INVALIDARG;
  1087. __leave;
  1088. }
  1089. _ASSERT (NULL != m_pIClassFactory);
  1090. //
  1091. // create the request object
  1092. //
  1093. HRESULT hr = m_pIClassFactory->CreateInstance (
  1094. NULL,
  1095. __uuidof (IRequest),
  1096. reinterpret_cast <PVOID*> (&pIRequest)
  1097. );
  1098. if (FAILED (hr))
  1099. {
  1100. IASTracePrintf (
  1101. "Surrogate failed in creation of a new request object"
  1102. );
  1103. __leave;
  1104. }
  1105. //
  1106. // get IAttributesRaw interface
  1107. //
  1108. hr = pIRequest->QueryInterface (
  1109. __uuidof (IAttributesRaw),
  1110. reinterpret_cast <PVOID*> (&pIAttributesRaw)
  1111. );
  1112. if (FAILED (hr))
  1113. {
  1114. IASTracePrintf (
  1115. "Surrogate unable to obtain Attribute interface while"
  1116. " processing request"
  1117. );
  1118. __leave;
  1119. }
  1120. //
  1121. // allocate memory for the ATTRIBUTEPOSITION array
  1122. //
  1123. pIasAttribPos = reinterpret_cast <PATTRIBUTEPOSITION>(
  1124. ::CoTaskMemAlloc (
  1125. sizeof (ATTRIBUTEPOSITION)*dwInAttributeCount)
  1126. );
  1127. if (NULL == pIasAttribPos)
  1128. {
  1129. IASTracePrintf (
  1130. "Surrogate unable to allocate memory while processing request"
  1131. );
  1132. hr = E_OUTOFMEMORY;
  1133. __leave;
  1134. }
  1135. //
  1136. // put the attributes in the ATTRIBUTEPOSITION structs
  1137. //
  1138. for (dwCount = 0; dwCount < dwInAttributeCount; dwCount++)
  1139. {
  1140. //
  1141. // mark the attribute as having been received from client
  1142. //
  1143. ppInIasAttribute[dwCount]->dwFlags |= IAS_RECVD_FROM_CLIENT;
  1144. pIasAttribPos[dwCount].pAttribute = ppInIasAttribute[dwCount];
  1145. }
  1146. //
  1147. // put the attributes collection that we are holding into the
  1148. // Request object through the IAttributesRaw interface
  1149. //
  1150. hr = pIAttributesRaw->AddAttributes (
  1151. dwInAttributeCount,
  1152. pIasAttribPos
  1153. );
  1154. if (FAILED (hr))
  1155. {
  1156. IASTracePrintf (
  1157. "Surrogate failed to add attributes to request being processed"
  1158. );
  1159. __leave;
  1160. }
  1161. //
  1162. // set the request type now
  1163. //
  1164. hr = pIRequest->put_Request (IasRequest);
  1165. if (FAILED (hr))
  1166. {
  1167. IASTracePrintf (
  1168. "Surrogate unable to set the request type for processing"
  1169. );
  1170. __leave;
  1171. }
  1172. //
  1173. // set the protocol now
  1174. //
  1175. hr = pIRequest->put_Protocol (IasProtocol);
  1176. if (FAILED (hr))
  1177. {
  1178. IASTracePrintf (
  1179. "Surrogate unable to set protocol type in request for processing"
  1180. );
  1181. __leave;
  1182. }
  1183. //
  1184. // put your IRequestSource interface in now
  1185. //
  1186. hr = pIRequest->put_Source (&m_objCRequestSource);
  1187. if (FAILED (hr))
  1188. {
  1189. IASTracePrintf (
  1190. "Surrogate unable to set source in request for processing"
  1191. );
  1192. __leave;
  1193. }
  1194. //
  1195. // convert the VSA attributes to IAS format if requested
  1196. //
  1197. if (TRUE == bProcessVSA)
  1198. {
  1199. hr = m_objVSAFilter.radiusToIAS (pIAttributesRaw);
  1200. if (FAILED (hr))
  1201. {
  1202. IASTracePrintf (
  1203. "Surrogate unable to convert VSAs to IAS format"
  1204. );
  1205. __leave;
  1206. }
  1207. }
  1208. //
  1209. // create an event which will be used to wake this thread
  1210. // when the pipeline does multithreaded processing
  1211. //
  1212. hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
  1213. if (NULL == hEvent)
  1214. {
  1215. IASTracePrintf (
  1216. "Surrogate unable to create event while processing request"
  1217. );
  1218. __leave;
  1219. }
  1220. //
  1221. // get the request state interface to put in our state now
  1222. //
  1223. //
  1224. hr = pIRequest->QueryInterface (
  1225. __uuidof (IRequestState),
  1226. reinterpret_cast <PVOID*> (&pIRequestState)
  1227. );
  1228. if (FAILED (hr))
  1229. {
  1230. IASTracePrintf (
  1231. "Surrogate unable to extract request state interface"
  1232. );
  1233. __leave;
  1234. }
  1235. //
  1236. // put in the request state - which is our event handle in
  1237. //
  1238. hr = pIRequestState->Push (
  1239. reinterpret_cast <unsigned hyper> (hEvent)
  1240. );
  1241. if (FAILED (hr))
  1242. {
  1243. IASTracePrintf (
  1244. "Surrogate unable to set event in request state"
  1245. );
  1246. __leave;
  1247. }
  1248. _ASSERT (NULL != m_pIRequestHandler);
  1249. //
  1250. // send the request to the pipeline now
  1251. //
  1252. hr = m_pIRequestHandler->OnRequest (pIRequest);
  1253. if (FAILED (hr))
  1254. {
  1255. IASTracePrintf (
  1256. "Surrogate request failed backend processing..."
  1257. );
  1258. __leave;
  1259. }
  1260. //
  1261. // now wait for the event now
  1262. //
  1263. dwRetVal = ::WaitForSingleObjectEx (hEvent, INFINITE, TRUE);
  1264. if (0XFFFFFFFF == dwRetVal)
  1265. {
  1266. IASTracePrintf (
  1267. "Surrogate failed on waiting for process completion"
  1268. );
  1269. hr = E_FAIL;
  1270. __leave;
  1271. }
  1272. //
  1273. // convert the IAS attributes to VSA format if requested
  1274. //
  1275. if (TRUE == bProcessVSA)
  1276. {
  1277. //
  1278. // TPERRAUT ADDED Bug 428843
  1279. // Always called from RAS with bProcessVSA = true
  1280. //
  1281. // split the attributes which can not fit in a radius packet
  1282. //
  1283. hr = SplitAttributes (pIAttributesRaw);
  1284. if (FAILED (hr))
  1285. {
  1286. IASTracePrintf (
  1287. "TPERRAUT: Unable to split IAS attribute received from backend"
  1288. );
  1289. __leave;
  1290. }
  1291. // TPERRAUT ADDED: END
  1292. hr = m_objVSAFilter.radiusFromIAS (pIAttributesRaw);
  1293. if (FAILED (hr))
  1294. {
  1295. IASTracePrintf (
  1296. "Surrogate failed on extracting VSAs from IAS format"
  1297. );
  1298. __leave;
  1299. }
  1300. }
  1301. //
  1302. // now its time to dismantle the request sent to find out
  1303. // what we got back
  1304. //
  1305. hr = pIRequest->get_Response (pIasResponse);
  1306. if (FAILED (hr))
  1307. {
  1308. IASTracePrintf (
  1309. "Surrogate unable to obtain response from processed request"
  1310. );
  1311. __leave;
  1312. }
  1313. hr = pIRequest->get_Reason (plReason);
  1314. if (FAILED (hr))
  1315. {
  1316. IASTracePrintf (
  1317. "Surrogate unable to obtain reason from processed request"
  1318. );
  1319. __leave;
  1320. }
  1321. //
  1322. // remove all the attributes from the request object now
  1323. //
  1324. hr = RemoveAttributesFromRequest (
  1325. *pIasResponse,
  1326. pIAttributesRaw,
  1327. pdwOutAttributeCount,
  1328. pppOutIasAttribute
  1329. );
  1330. if (FAILED (hr))
  1331. {
  1332. IASTracePrintf (
  1333. "Surrogate unable to remove attributes from processed request"
  1334. );
  1335. __leave;
  1336. }
  1337. }
  1338. __finally
  1339. {
  1340. //
  1341. // do the cleanup now
  1342. //
  1343. if (NULL != hEvent)
  1344. {
  1345. CloseHandle (hEvent);
  1346. }
  1347. if (NULL != pIasAttribPos)
  1348. {
  1349. ::CoTaskMemFree (pIasAttribPos);
  1350. }
  1351. if (NULL != pIRequestState)
  1352. {
  1353. pIRequestState->Release ();
  1354. }
  1355. if (NULL != pIAttributesRaw)
  1356. {
  1357. pIAttributesRaw->Release ();
  1358. }
  1359. if (NULL != pIRequest)
  1360. {
  1361. pIRequest->Release ();
  1362. }
  1363. //
  1364. // increment the requestreceived
  1365. //
  1366. dwRequestCount =
  1367. (0xFFFFFFFF == dwRequestCount) ? 1 : dwRequestCount+ 1;
  1368. //
  1369. // decrement the request count
  1370. //
  1371. InterlockedDecrement (&m_lRequestCount);
  1372. }
  1373. return (hr);
  1374. } // end of CRasCom::Process method
  1375. //++--------------------------------------------------------------
  1376. //
  1377. // Function: RemoveAttributesFromRequest
  1378. //
  1379. // Synopsis: This is the CRasCom class private method
  1380. // that is used to remove the attributes
  1381. // from the Request object through the
  1382. // IAttributesRaw interface
  1383. //
  1384. // Arguments:
  1385. // [in] LONG - response received from pipe
  1386. // [in] IAttributesRaw*
  1387. // [out] PIASATTRIBUTE**
  1388. // [out] PDWORD - out attribute count
  1389. //
  1390. // Returns: HRESULT - status
  1391. //
  1392. // History: MKarki Created 2/10/98
  1393. //
  1394. // Called By: CRasCom::Process method
  1395. //
  1396. //----------------------------------------------------------------
  1397. STDMETHODIMP
  1398. CRasCom::RemoveAttributesFromRequest (
  1399. LONG lResponse,
  1400. IAttributesRaw *pIasAttributesRaw,
  1401. PDWORD pdwOutAttributeCount,
  1402. PIASATTRIBUTE **pppIasAttribute
  1403. )
  1404. {
  1405. HRESULT hr = S_OK;
  1406. PATTRIBUTEPOSITION pIasOutAttributePos = NULL;
  1407. DWORD dwCount = 0;
  1408. DWORD dwAttribCount = 0;
  1409. DWORD dwOutCount = 0;
  1410. BOOL bGotAttributes = FALSE;
  1411. PIASATTRIBUTE pIasAttribute = NULL;
  1412. _ASSERT (
  1413. (NULL != pIasAttributesRaw) &&
  1414. (NULL != pppIasAttribute) &&
  1415. (NULL != pdwOutAttributeCount)
  1416. );
  1417. __try
  1418. {
  1419. //
  1420. // get the count of the attributes remaining in the collection
  1421. // these will be the OUT attributes
  1422. //
  1423. hr = pIasAttributesRaw->GetAttributeCount (&dwAttribCount);
  1424. if (FAILED (hr))
  1425. {
  1426. IASTracePrintf (
  1427. "Surrogate unable to obtain attribute count from request in"
  1428. "while removing attributes from request"
  1429. );
  1430. __leave;
  1431. }
  1432. //
  1433. // allocate memory for the ATTRIBUTEPOSITION array
  1434. //
  1435. pIasOutAttributePos = reinterpret_cast <PATTRIBUTEPOSITION> (
  1436. ::CoTaskMemAlloc (
  1437. sizeof (ATTRIBUTEPOSITION)*(dwAttribCount))
  1438. );
  1439. if (NULL == pIasOutAttributePos)
  1440. {
  1441. IASTracePrintf (
  1442. "Surrogate unable to allocate memory"
  1443. "while removing attributes from request"
  1444. );
  1445. hr = E_OUTOFMEMORY;
  1446. __leave;
  1447. }
  1448. //
  1449. // get all the attributes from the collection
  1450. //
  1451. hr = pIasAttributesRaw->GetAttributes (
  1452. &dwAttribCount,
  1453. pIasOutAttributePos,
  1454. 0,
  1455. NULL
  1456. );
  1457. if (FAILED (hr))
  1458. {
  1459. IASTracePrintf (
  1460. "Surrogate unable get attributes from request interface"
  1461. "while removing attributes"
  1462. );
  1463. __leave;
  1464. }
  1465. //
  1466. // we have obtained the attributes
  1467. //
  1468. bGotAttributes = TRUE;
  1469. //
  1470. // remove the attributes from the collection now
  1471. //
  1472. hr = pIasAttributesRaw->RemoveAttributes (
  1473. dwAttribCount,
  1474. pIasOutAttributePos
  1475. );
  1476. if (FAILED (hr))
  1477. {
  1478. IASTracePrintf (
  1479. "Surrogate unable remove attributes from request"
  1480. );
  1481. __leave;
  1482. }
  1483. //
  1484. // calculate the number of attributes not added by the client
  1485. //
  1486. *pdwOutAttributeCount = 0;
  1487. for (dwCount = 0; dwCount < dwAttribCount; dwCount++)
  1488. {
  1489. pIasAttribute = pIasOutAttributePos[dwCount].pAttribute;
  1490. //
  1491. // verify that this attributes has to be sent to client
  1492. //
  1493. if
  1494. (
  1495. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_ACCEPT) &&
  1496. (IAS_RESPONSE_ACCESS_ACCEPT == lResponse)) ||
  1497. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_REJECT) &&
  1498. (IAS_RESPONSE_ACCESS_REJECT == lResponse)) ||
  1499. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_CHALLENGE) &&
  1500. (IAS_RESPONSE_ACCESS_CHALLENGE == lResponse))
  1501. )
  1502. {
  1503. (*pdwOutAttributeCount)++;
  1504. }
  1505. }
  1506. //
  1507. // allocate memory for PIASATTRIBUTE array
  1508. //
  1509. *pppIasAttribute = reinterpret_cast <PIASATTRIBUTE*> (
  1510. ::CoTaskMemAlloc (sizeof(PIASATTRIBUTE)*(*pdwOutAttributeCount))
  1511. );
  1512. if (NULL == *pppIasAttribute)
  1513. {
  1514. IASTracePrintf (
  1515. "Surrogate unable to allocate memory for attrib pointer array"
  1516. "while removing attribute from request"
  1517. );
  1518. hr = E_OUTOFMEMORY;
  1519. __leave;
  1520. }
  1521. //
  1522. // put the attributes in the PIASATTRIBUTE array
  1523. //
  1524. for (dwCount = 0, dwOutCount = 0; dwCount < dwAttribCount; dwCount++)
  1525. {
  1526. pIasAttribute = pIasOutAttributePos[dwCount].pAttribute;
  1527. if (
  1528. (((pIasAttribute->dwFlags & IAS_INCLUDE_IN_ACCEPT) &&
  1529. (IAS_RESPONSE_ACCESS_ACCEPT == lResponse)) ||
  1530. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_REJECT) &&
  1531. (IAS_RESPONSE_ACCESS_REJECT == lResponse)) ||
  1532. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_CHALLENGE) &&
  1533. (IAS_RESPONSE_ACCESS_CHALLENGE == lResponse)))
  1534. &&
  1535. (dwOutCount < *pdwOutAttributeCount)
  1536. )
  1537. {
  1538. //
  1539. // put the out attribute in the output array
  1540. //
  1541. (*pppIasAttribute)[dwOutCount] = pIasAttribute;
  1542. dwOutCount++;
  1543. }
  1544. else
  1545. {
  1546. //
  1547. // decrement the reference count for the
  1548. // attributes we created or the ones we are
  1549. // not sending as out to client
  1550. //
  1551. ::IASAttributeRelease (pIasAttribute);
  1552. }
  1553. }
  1554. //
  1555. // now put in the number of out attribute we are actually
  1556. // giving the client
  1557. //
  1558. *pdwOutAttributeCount = dwOutCount;
  1559. }
  1560. __finally
  1561. {
  1562. //
  1563. // cleanup on failure
  1564. //
  1565. if (FAILED (hr))
  1566. {
  1567. if (NULL != *pppIasAttribute)
  1568. {
  1569. ::CoTaskMemFree (*pppIasAttribute);
  1570. pppIasAttribute = NULL;
  1571. }
  1572. //
  1573. // correct the out attribute count
  1574. //
  1575. *pdwOutAttributeCount = 0;
  1576. //
  1577. // free up all the attributes also
  1578. //
  1579. if ((TRUE == bGotAttributes) && (NULL != pIasOutAttributePos))
  1580. {
  1581. for (dwCount = 0; dwCount < dwAttribCount; dwCount++)
  1582. {
  1583. ::IASAttributeRelease (
  1584. pIasOutAttributePos[dwCount].pAttribute
  1585. );
  1586. }
  1587. }
  1588. }
  1589. //
  1590. // delete the dynamically allocated memory
  1591. //
  1592. if (NULL != pIasOutAttributePos)
  1593. {
  1594. ::CoTaskMemFree (pIasOutAttributePos);
  1595. }
  1596. }
  1597. return (hr);
  1598. } // end of CRasCom::RemoveAttributesFromRequest method