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.

819 lines
23 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) Microsoft Corporation.
  4. //
  5. // SYNOPSIS
  6. //
  7. // Declares various utility classes, functions, and macros that are useful
  8. // when implementating a request handler for the Internet Authentication
  9. // Service.
  10. //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #ifndef IASTLUTL_H
  13. #define IASTLUTL_H
  14. #pragma once
  15. //////////
  16. // 'C'-style API for manipulating IASATTRIBUTE struct's.
  17. //////////
  18. #include <iasattr.h>
  19. //////////
  20. // 'C'-style API for manipulating dictionary.
  21. //////////
  22. #include <iasapi.h>
  23. //////////
  24. // MIDL generated header files containing interfaces used by request handlers.
  25. //////////
  26. #include <iaspolcy.h>
  27. #include <sdoias.h>
  28. //////////
  29. // The entire library is contained within the IASTL namespace.
  30. //////////
  31. namespace IASTL {
  32. //////////
  33. // This function is called whenever an exception should be thrown. The
  34. // function is declared, but never defined. This allows the user to provide
  35. // their own implementation using an exception class of their choice.
  36. //////////
  37. void __stdcall issue_error(HRESULT hr);
  38. ///////////////////////////////////////////////////////////////////////////////
  39. //
  40. // CLASS
  41. //
  42. // IASAttribute
  43. //
  44. // DESCRIPTION
  45. //
  46. // Wrapper around an IASATTRIBUTE struct.
  47. //
  48. ///////////////////////////////////////////////////////////////////////////////
  49. class IASAttribute
  50. {
  51. public:
  52. //////////
  53. // Constructors.
  54. //////////
  55. IASAttribute() throw ()
  56. : p(NULL)
  57. { }
  58. explicit IASAttribute(bool alloc)
  59. {
  60. if (alloc) { _alloc(); } else { p = NULL; }
  61. }
  62. explicit IASAttribute(PIASATTRIBUTE attr, bool addRef = true) throw ()
  63. : p(attr)
  64. { if (addRef) { _addref(); } }
  65. IASAttribute(const IASAttribute& attr) throw ()
  66. : p(attr.p)
  67. { _addref(); }
  68. //////////
  69. // Destructor.
  70. //////////
  71. ~IASAttribute() throw ()
  72. { _release(); }
  73. //////////
  74. // Assignment operators.
  75. //////////
  76. IASAttribute& operator=(PIASATTRIBUTE attr) throw ();
  77. const IASAttribute& operator=(const IASAttribute& attr) throw ()
  78. { return operator=(attr.p); }
  79. // Allocate a new attribute. Any existing attribute is first released.
  80. void alloc()
  81. {
  82. _release();
  83. _alloc();
  84. }
  85. // Release the attribute (if any).
  86. void release() throw ()
  87. {
  88. if (p) { IASAttributeRelease(p); p = NULL; }
  89. }
  90. // Attach a new attribute to the object. Any existing attribute is first
  91. // released.
  92. void attach(PIASATTRIBUTE attr, bool addRef = true) throw ();
  93. // Detach the attribute from the object. The caller is responsible for
  94. // releasing the returned attribute.
  95. PIASATTRIBUTE detach() throw ()
  96. {
  97. PIASATTRIBUTE rv = p;
  98. p = NULL;
  99. return rv;
  100. }
  101. // Load an attribute with the given ID. Returns true if successful, false
  102. // if no such attribute exists.
  103. bool load(IAttributesRaw* request, DWORD dwId);
  104. // Load an attribute with the given ID and verify that it has an
  105. // appropriate value type. Returns true if successful, false if no such
  106. // attribute exists.
  107. bool load(IAttributesRaw* request, DWORD dwId, IASTYPE itType);
  108. // Store the attribute in a request.
  109. void store(IAttributesRaw* request) const;
  110. // Swap the contents of two objects.
  111. void swap(IASAttribute& attr) throw ()
  112. {
  113. PIASATTRIBUTE tmp = p;
  114. p = attr.p;
  115. attr.p = tmp;
  116. }
  117. //////////
  118. // Methods for setting the value of an attribute. The object must contain
  119. // a valid attribute before calling this method. The passed in data is
  120. // copied.
  121. //////////
  122. void setOctetString(DWORD dwLength, const BYTE* lpValue);
  123. void setOctetString(PCSTR szAnsi);
  124. void setOctetString(PCWSTR szWide);
  125. void setString(DWORD dwLength, const BYTE* lpValue);
  126. void setString(PCSTR szAnsi);
  127. void setString(PCWSTR szWide);
  128. //////////
  129. // Methods for manipulating the dwFlags field.
  130. //////////
  131. void clearFlag(DWORD flag) throw ()
  132. { p->dwFlags &= ~flag; }
  133. void setFlag(DWORD flag) throw ()
  134. { p->dwFlags |= flag; }
  135. bool testFlag(DWORD flag) const throw ()
  136. { return (p->dwFlags & flag) != 0; }
  137. // Address-of operator. Any existing attribute is first released.
  138. PIASATTRIBUTE* operator&() throw ()
  139. {
  140. release();
  141. return &p;
  142. }
  143. //////////
  144. // Assorted useful operators that allow an IASAttribute object to mimic
  145. // an IASATTRIBUTE pointer.
  146. //////////
  147. bool operator !() const throw () { return p == NULL; }
  148. operator bool() const throw () { return p != NULL; }
  149. operator PIASATTRIBUTE() const throw () { return p; }
  150. IASATTRIBUTE& operator*() const throw () { return *p; }
  151. PIASATTRIBUTE operator->() const throw () { return p; }
  152. protected:
  153. void _addref() throw ()
  154. { if (p) { IASAttributeAddRef(p); } }
  155. void _release() throw ()
  156. { if (p) { IASAttributeRelease(p); } }
  157. void _alloc()
  158. { if (IASAttributeAlloc(1, &p)) { issue_error(E_OUTOFMEMORY); } }
  159. void clearValue() throw ();
  160. PIASATTRIBUTE p; // The attribute being wrapped.
  161. };
  162. ///////////////////////////////////////////////////////////////////////////////
  163. //
  164. // CLASS
  165. //
  166. // IASAttributePosition
  167. //
  168. // DESCRIPTION
  169. //
  170. // Wrapper around an ATTRIBUTEPOSITION struct.
  171. //
  172. ///////////////////////////////////////////////////////////////////////////////
  173. class IASAttributePosition
  174. {
  175. public:
  176. IASAttributePosition() throw ()
  177. { pos.pAttribute = 0; }
  178. explicit IASAttributePosition(const ATTRIBUTEPOSITION& orig) throw ()
  179. : pos(orig)
  180. { _addref(); }
  181. IASAttributePosition(const IASAttributePosition& orig) throw ()
  182. : pos(orig.pos)
  183. { _addref(); }
  184. ~IASAttributePosition() throw ()
  185. { _release(); }
  186. IASAttributePosition& operator=(const ATTRIBUTEPOSITION& rhs) throw ();
  187. IASAttributePosition& operator=(const IASAttributePosition& rhs) throw ()
  188. { return operator=(rhs.pos); }
  189. IASAttributePosition& operator=(IASATTRIBUTE* rhs) throw ();
  190. IASATTRIBUTE* getAttribute() const throw ()
  191. { return pos.pAttribute; }
  192. ATTRIBUTEPOSITION* operator&() throw ()
  193. { return &pos; }
  194. const ATTRIBUTEPOSITION* operator&() const throw ()
  195. { return &pos; }
  196. private:
  197. void _addref() throw ()
  198. { if (pos.pAttribute) { IASAttributeAddRef(pos.pAttribute); } }
  199. void _release() throw ()
  200. { if (pos.pAttribute) { IASAttributeRelease(pos.pAttribute); } }
  201. ATTRIBUTEPOSITION pos;
  202. };
  203. ///////////////////////////////////////////////////////////////////////////////
  204. //
  205. // CLASS
  206. //
  207. // IASAttributeVector
  208. //
  209. // DESCRIPTION
  210. //
  211. // Implements an STL-style vector of ATTRIBUTEPOSITION structs. The user
  212. // may provide an empty C-style array that will be used for initial storage.
  213. // This array will not be freed by the IASAttributeVector object and must
  214. // remain valid for the lifetime of the object. The purpose of this feature
  215. // is to allow an initial stack-based allocation that will meet most
  216. // conditions while still allowing a dynamically-sized heap-based array
  217. // when necessary.
  218. //
  219. ///////////////////////////////////////////////////////////////////////////////
  220. class IASAttributeVector
  221. {
  222. public:
  223. //////////
  224. // STL typedefs.
  225. //////////
  226. typedef DWORD size_type;
  227. typedef ptrdiff_t difference_type;
  228. typedef ATTRIBUTEPOSITION& reference;
  229. typedef const ATTRIBUTEPOSITION& const_reference;
  230. typedef ATTRIBUTEPOSITION value_type;
  231. typedef PATTRIBUTEPOSITION iterator;
  232. typedef const ATTRIBUTEPOSITION* const_iterator;
  233. // Construct a vector with zero capacity.
  234. IASAttributeVector() throw ();
  235. // Construct a vector with heap-allocated capacity of 'N'.
  236. explicit IASAttributeVector(size_type N);
  237. // Construct a vector with initial capacity of 'initCap' using the
  238. // user-provided C-style array beginning at 'init'.
  239. IASAttributeVector(PATTRIBUTEPOSITION init, size_type initCap) throw ();
  240. // Copy-constructor.
  241. IASAttributeVector(const IASAttributeVector& v);
  242. // Assignment operator.
  243. IASAttributeVector& operator=(const IASAttributeVector& v);
  244. // Destructor.
  245. ~IASAttributeVector() throw ();
  246. // Returns true if vector contains at least one attribute with the given ID.
  247. bool contains(DWORD attrID) const throw ();
  248. // Similar to 'erase' except the attribute is not released.
  249. iterator discard(iterator p) throw ();
  250. // Similar to 'discard' except the order of the elements following 'p' is
  251. // not necessarily preserved.
  252. iterator fast_discard(iterator p) throw ();
  253. // Similar to 'erase' except the order of the elements following 'p' is
  254. // not necessarily preserved.
  255. iterator fast_erase(iterator p) throw ()
  256. {
  257. IASAttributeRelease(p->pAttribute);
  258. return fast_discard(p);
  259. }
  260. // Load the requested attributes into the vector.
  261. DWORD load(IAttributesRaw* request, DWORD attrIDCount, LPDWORD attrIDs);
  262. // Load all attributes with a given ID into the vector.
  263. DWORD load(IAttributesRaw* request, DWORD attrID)
  264. { return load(request, 1, &attrID); }
  265. // Load all the attributes in the request into the vector.
  266. DWORD load(IAttributesRaw* request);
  267. // Adds an ATTRIBUTEPOSITION struct to the end of the vetor, resizing as
  268. // necessary. The 'addRef' flag indicates whether IASAttributeAddRef should
  269. // be called for the embedded attribute.
  270. void push_back(ATTRIBUTEPOSITION& p, bool addRef = true);
  271. // Adds an attribute to the end of the vetor, resizing as necessary.
  272. // The 'addRef' flag indicates whether IASAttributeAddRef should be
  273. // called for the attribute.
  274. void push_back(PIASATTRIBUTE p, bool addRef = true)
  275. {
  276. ATTRIBUTEPOSITION pos = { 0, p };
  277. push_back(pos, addRef);
  278. }
  279. // Remove the contents of the vector from the request.
  280. void remove(IAttributesRaw* request);
  281. // Store the contents of the vector in the request.
  282. void store(IAttributesRaw* request) const;
  283. //////////
  284. // The remainder of the public interface follows the semantics of the
  285. // STL vector class (q.v.).
  286. //////////
  287. const_reference at(size_type pos) const throw ()
  288. { return *(begin_ + pos); }
  289. reference at(size_type pos) throw ()
  290. { return *(begin_ + pos); }
  291. iterator begin() throw ()
  292. { return begin_; }
  293. const_iterator begin() const throw ()
  294. { return begin_; }
  295. size_type capacity() const throw ()
  296. { return capacity_; }
  297. void clear() throw ();
  298. bool empty() const throw ()
  299. { return begin_ == end_; }
  300. iterator end() throw ()
  301. { return end_; }
  302. const_iterator end() const throw ()
  303. { return end_; }
  304. iterator erase(iterator p) throw ()
  305. {
  306. IASAttributeRelease(p->pAttribute);
  307. return discard(p);
  308. }
  309. reference back() throw ()
  310. { return *(end_ - 1); }
  311. const_reference back() const throw ()
  312. { return *(end_ - 1); }
  313. reference front() throw ()
  314. { return *begin_; }
  315. const_reference front() const throw ()
  316. { return *begin_; }
  317. void reserve(size_type N);
  318. size_type size() const throw ()
  319. { return (size_type)(end_ - begin_); }
  320. const_reference operator[](size_type pos) const throw ()
  321. { return at(pos); }
  322. reference operator[](size_type pos) throw ()
  323. { return at(pos); }
  324. protected:
  325. PATTRIBUTEPOSITION begin_; // Beginning of the vector.
  326. PATTRIBUTEPOSITION end_; // Points one past the last element.
  327. size_type capacity_; // Capacity of the vector in elements.
  328. bool owner; // true if the memory should be freed.
  329. };
  330. ///////////////////////////////////////////////////////////////////////////////
  331. //
  332. // CLASS
  333. //
  334. // IASAttributeVectorWithBuffer<N>
  335. //
  336. // DESCRIPTION
  337. //
  338. // Extens IASAttributeVector to provide an initial non-heap allocation
  339. // of 'N' elements. The vector will still support heap-based resizing.
  340. //
  341. ///////////////////////////////////////////////////////////////////////////////
  342. template <IASAttributeVector::size_type N>
  343. class IASAttributeVectorWithBuffer
  344. : public IASAttributeVector
  345. {
  346. public:
  347. IASAttributeVectorWithBuffer()
  348. : IASAttributeVector(buffer, N)
  349. { }
  350. IASAttributeVectorWithBuffer(const IASAttributeVectorWithBuffer& vec)
  351. : IASAttributeVector(vec)
  352. { }
  353. IASAttributeVectorWithBuffer&
  354. operator=(const IASAttributeVectorWithBuffer& vec)
  355. {
  356. IASAttributeVector::operator=(vec);
  357. return *this;
  358. }
  359. protected:
  360. ATTRIBUTEPOSITION buffer[N]; // Initial storage.
  361. };
  362. ///////////////////////////////////////////////////////////////////////////////
  363. //
  364. // MACRO
  365. //
  366. // IASAttributeVectorOnStack(identifier, request, extra)
  367. //
  368. // DESCRIPTION
  369. //
  370. // Uses _alloca to create an IASAttributeVector on the stack that is
  371. // exactly the right size to hold all the attributes in 'request' plus
  372. // 'extra' additional attributes. The 'request' pointer may be null in
  373. // which case this will allocate space for exactly 'extra' attributes.
  374. //
  375. // CAVEAT
  376. //
  377. // This can only be used for temporary variables.
  378. //
  379. ///////////////////////////////////////////////////////////////////////////////
  380. // Must be included in an enclosing scope prior to IASAttributeVectorOnStack
  381. #define USES_IAS_STACK_VECTOR() \
  382. ULONG IAS_VECCAP;
  383. #define IASAttributeVectorOnStack(identifier, request, extra) \
  384. IAS_VECCAP = 0; \
  385. if (static_cast<IAttributesRaw*>(request) != NULL) \
  386. static_cast<IAttributesRaw*>(request)->GetAttributeCount(&IAS_VECCAP); \
  387. IAS_VECCAP += (extra); \
  388. IASAttributeVector identifier( \
  389. (PATTRIBUTEPOSITION) \
  390. _alloca(IAS_VECCAP * sizeof(ATTRIBUTEPOSITION)), \
  391. IAS_VECCAP \
  392. )
  393. ///////////////////////////////////////////////////////////////////////////////
  394. //
  395. // CLASS
  396. //
  397. // IASOrderByID
  398. //
  399. // DESCRIPTION
  400. //
  401. // Functor class for sorting/searching an IASAttributeVector by ID.
  402. //
  403. ///////////////////////////////////////////////////////////////////////////////
  404. class IASOrderByID
  405. {
  406. public:
  407. bool operator()(const ATTRIBUTEPOSITION& lhs,
  408. const ATTRIBUTEPOSITION& rhs) throw ()
  409. { return lhs.pAttribute->dwId < rhs.pAttribute->dwId; }
  410. };
  411. ///////////////////////////////////////////////////////////////////////////////
  412. //
  413. // CLASS
  414. //
  415. // IASSelectByID<T>
  416. //
  417. // DESCRIPTION
  418. //
  419. // Functor class for selecting elements from an IASAttributeVector based
  420. // on the attribute ID.
  421. //
  422. ///////////////////////////////////////////////////////////////////////////////
  423. template <DWORD ID>
  424. class IASSelectByID
  425. {
  426. public:
  427. bool operator()(const ATTRIBUTEPOSITION& pos) throw ()
  428. { return (pos.pAttribute->dwId == ID); }
  429. };
  430. ///////////////////////////////////////////////////////////////////////////////
  431. //
  432. // CLASS
  433. //
  434. // IASSelectByFlag<T>
  435. //
  436. // DESCRIPTION
  437. //
  438. // Functor class for selecting elements from an IASAttributeVector based
  439. // on the attribute flags.
  440. //
  441. ///////////////////////////////////////////////////////////////////////////////
  442. template <DWORD Flag, bool Set = true>
  443. class IASSelectByFlag
  444. {
  445. public:
  446. bool operator()(const ATTRIBUTEPOSITION& pos) throw ()
  447. {
  448. return Set ? (pos.pAttribute->dwFlags & Flag) != 0
  449. : (pos.pAttribute->dwFlags & Flag) == 0;
  450. }
  451. };
  452. ///////////////////////////////////////////////////////////////////////////////
  453. //
  454. // CLASS
  455. //
  456. // IASRequest
  457. //
  458. // DESCRIPTION
  459. //
  460. // Wrapper around a COM-based request object. Note that this is *not* a
  461. // smart pointer class. There are several important differences:
  462. //
  463. // 1) An IASRequest object is guaranteed to contain a valid request;
  464. // there is no concept of a NULL IASRequest.
  465. // 2) The IASRequest object does not take ownership of the IRequest
  466. // interface. In particular, it does not call AddRef or Release.
  467. // 3) Methods are invoked directly on the IASRequest object rather than
  468. // through the -> operator.
  469. //
  470. ///////////////////////////////////////////////////////////////////////////////
  471. class IASRequest
  472. {
  473. public:
  474. explicit IASRequest(IRequest* request);
  475. IASRequest(const IASRequest& request) throw ()
  476. : req(request.req), raw(request.raw)
  477. { _addref(); }
  478. IASRequest& operator=(const IASRequest& request) throw ();
  479. ~IASRequest() throw ()
  480. { _release(); }
  481. IASREQUEST get_Request() const
  482. {
  483. LONG val;
  484. checkError(req->get_Request(&val));
  485. return (IASREQUEST)val;
  486. }
  487. void put_Request(IASREQUEST newVal)
  488. {
  489. checkError(req->put_Request(newVal));
  490. }
  491. IASRESPONSE get_Response() const
  492. {
  493. LONG val;
  494. checkError(req->get_Response(&val));
  495. return (IASRESPONSE)val;
  496. }
  497. DWORD get_Reason() const
  498. {
  499. LONG val;
  500. checkError(req->get_Reason(&val));
  501. return val;
  502. }
  503. IASPROTOCOL get_Protocol() const
  504. {
  505. IASPROTOCOL val;
  506. checkError(req->get_Protocol(&val));
  507. return val;
  508. }
  509. void put_Protocol(IASPROTOCOL newVal)
  510. {
  511. checkError(req->put_Protocol(newVal));
  512. }
  513. IRequestSource* get_Source() const
  514. {
  515. IRequestSource* val;
  516. checkError(req->get_Source(&val));
  517. return val;
  518. }
  519. void put_Source(IRequestSource* newVal)
  520. {
  521. checkError(req->put_Source(newVal));
  522. }
  523. void SetResponse(IASRESPONSE eResponse, DWORD dwReason = S_OK)
  524. {
  525. checkError(req->SetResponse(eResponse, (LONG)dwReason));
  526. }
  527. void ReturnToSource(IASREQUESTSTATUS eStatus)
  528. {
  529. checkError(req->ReturnToSource(eStatus));
  530. }
  531. void AddAttributes(DWORD dwPosCount, PATTRIBUTEPOSITION pPositions)
  532. {
  533. checkError(raw->AddAttributes(dwPosCount, pPositions));
  534. }
  535. void RemoveAttributes(DWORD dwPosCount, PATTRIBUTEPOSITION pPositions)
  536. {
  537. checkError(raw->RemoveAttributes(dwPosCount, pPositions));
  538. }
  539. void RemoveAttributesByType(DWORD dwAttrIDCount, LPDWORD lpdwAttrIDs)
  540. {
  541. checkError(raw->RemoveAttributesByType(dwAttrIDCount, lpdwAttrIDs));
  542. }
  543. DWORD GetAttributeCount() const
  544. {
  545. DWORD count;
  546. checkError(raw->GetAttributeCount(&count));
  547. return count;
  548. }
  549. // Returns the number of attributes retrieved.
  550. DWORD GetAttributes(DWORD dwPosCount,
  551. PATTRIBUTEPOSITION pPositions,
  552. DWORD dwAttrIDCount,
  553. LPDWORD lpdwAttrIDs);
  554. void InsertBefore(
  555. PATTRIBUTEPOSITION newAttr,
  556. PATTRIBUTEPOSITION refAttr
  557. )
  558. {
  559. checkError(raw->InsertBefore(newAttr, refAttr));
  560. }
  561. //////////
  562. // Cast operators to extract the embedded interfaces.
  563. //////////
  564. operator IRequest*() { return req; }
  565. operator IAttributesRaw*() { return raw; }
  566. protected:
  567. // Throws an exception if a COM method fails.
  568. static void checkError(HRESULT hr)
  569. { if (FAILED(hr)) { issue_error(hr); } }
  570. void _addref() { raw->AddRef(); }
  571. void _release() { raw->Release(); }
  572. IRequest* req; // Underlying interfaces.
  573. IAttributesRaw* raw; // Underlying interfaces.
  574. };
  575. ///////////////////////////////////////////////////////////////////////////////
  576. //
  577. // CLASS
  578. //
  579. // IASDictionary
  580. //
  581. // DESCRIPTION
  582. //
  583. // Provides access to the attribute dictionary.
  584. //
  585. ///////////////////////////////////////////////////////////////////////////////
  586. class IASDictionary
  587. {
  588. public:
  589. // selectNames: null terminated array of strings containing the columns to
  590. // be selected; a column name may be prepended with a hyphen
  591. // '-' to indicate that it's optional
  592. // path: full path to the dictionary database or NULL to use the
  593. // local dictionary
  594. IASDictionary(
  595. const WCHAR* const* selectNames,
  596. PCWSTR path = NULL
  597. );
  598. ~IASDictionary() throw ();
  599. ULONG getNumRows() const throw ()
  600. { return table->numRows; }
  601. // Advance to the next row. This must be called on a newly constructed
  602. // dictionary to advance to the first row.
  603. bool next() throw ();
  604. // Reset the dictionary to its initial state.
  605. void reset() throw ();
  606. // Returns true if the specified column is empty in the current row.
  607. bool isEmpty(ULONG ordinal) const;
  608. // Retrieve column values from the current row.
  609. VARIANT_BOOL getBool(ULONG ordinal) const;
  610. BSTR getBSTR(ULONG ordinal) const;
  611. LONG getLong(ULONG ordinal) const;
  612. const VARIANT* getVariant(ULONG ordinal) const;
  613. private:
  614. const IASTable* table; // The table data.
  615. ULONG mapSize; // Number of columns selected.
  616. PULONG selectMap; // Maps select ordinals to table ordinals.
  617. ULONG nextRowNumber; // Next row.
  618. VARIANT* currentRow; // Current row -- may be NULL.
  619. IASTable data; // Local storage for non-local dictionaries.
  620. CComVariant storage; // Storage associated with the dictionary.
  621. // Not implemented.
  622. IASDictionary(const IASDictionary&);
  623. IASDictionary& operator=(const IASDictionary&);
  624. };
  625. //////////
  626. // End of the IASTL namespace.
  627. //////////
  628. }
  629. ///////////////////////////////////////////////////////////////////////////////
  630. //
  631. // OctetString conversion macros and functions.
  632. //
  633. ///////////////////////////////////////////////////////////////////////////////
  634. // Compute the size of the buffer required by IASOctetStringToAnsi
  635. #define IAS_OCT2ANSI_LEN(oct) \
  636. (((oct).dwLength + 1) * sizeof(CHAR))
  637. // Compute the size of the buffer required by IASOctetStringToWide
  638. #define IAS_OCT2WIDE_LEN(oct) \
  639. (((oct).dwLength + 1) * sizeof(WCHAR))
  640. // Coerce an OctetString to a null-terminated ANSI string. There is no check
  641. // for overflow. The dst buffer must be at least IAS_OCT2ANSI_LEN bytes.
  642. PSTR IASOctetStringToAnsi(const IAS_OCTET_STRING& src, PSTR dst) throw ();
  643. // Coerce an OctetString to a null-terminated Unicode string. There is no
  644. // check for overflow. The dst buffer must be at least IAS_OCT2UNI_LEN bytes.
  645. PWSTR IASOctetStringToWide(const IAS_OCTET_STRING& src, PWSTR dst) throw ();
  646. // Convert an OctetString to ANSI on the stack.
  647. #define IAS_OCT2ANSI(oct) \
  648. (IASOctetStringToAnsi((oct), (PSTR)_alloca(IAS_OCT2ANSI_LEN(oct))))
  649. // Convert an OctetString to Unicode on the stack.
  650. #define IAS_OCT2WIDE(oct) \
  651. (IASOctetStringToWide((oct), (PWSTR)_alloca(IAS_OCT2WIDE_LEN(oct))))
  652. ///////////////////////////////////////////////////////////////////////////////
  653. //
  654. // Miscellaneous utility functions.
  655. //
  656. ///////////////////////////////////////////////////////////////////////////////
  657. // Retrieves and returns a single attribute with the given ID and type. The
  658. // attribute should *not* be released and is only valid while the caller holds
  659. // a reference to 'request'. On error or if the attribute is not found, the
  660. // function returns NULL.
  661. PIASATTRIBUTE IASPeekAttribute(
  662. IAttributesRaw* request,
  663. DWORD dwId,
  664. IASTYPE itType
  665. ) throw ();
  666. #endif // IASTLUTL_H