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.

2621 lines
55 KiB

  1. // autoall.h
  2. //
  3. // A plethora of smart pointers / objects
  4. //
  5. // INDEX:
  6. // auto_bstr - BSTR
  7. // auto_tm - CoTaskFreeMemory
  8. // auto_sid - FreeSid
  9. // auto_sa - SafeArray
  10. // auto_rel - COM
  11. // auto_reg - HKEY
  12. // auto_pv - PROPVARIANT
  13. // auto_prg - [] delete (pointer to range)
  14. // pointer - delete
  15. // auto_hr - throw HRESULT
  16. // auto_os - throw DWORD
  17. // auto_imp - Impersonation / Rever
  18. // auto_handle - HANDLE
  19. // auto_cs - CriticalSection
  20. // auto_leave - LeaveCriticalSection
  21. // auto_var - VARIANT
  22. // auto_virt - VirtualFree
  23. // RCObject - Reference counting
  24. // RCPtr<T>
  25. // auto_menu - DestroyMenu
  26. //
  27. // History:
  28. // 1/25/99 anbrad Unified from many differnt files created over the ages
  29. // 2/8/99 anbrad added auto_menu
  30. // auto_bstr ******************************************************************
  31. //
  32. // Smart Pointers for BSTR
  33. #pragma once
  34. #include <xstddef>
  35. // Forward declarations
  36. //
  37. // If you get class not defined you may just need to include a file or two.
  38. // These are listed below.
  39. class auto_bstr; // (oleauto.h) __wtypes_h__
  40. template<class _Ty>
  41. class auto_tm; //
  42. class auto_sid; //
  43. class auto_sa; // (ole2.h) __oaidl_h__
  44. template<class T, class I = T>
  45. class auto_rel; //
  46. class auto_reg; //
  47. class auto_pv; // (propidl.h) __propidl_h__
  48. template<class _Ty>
  49. class auto_prg; //
  50. template<class _Ty>
  51. class pointer; //
  52. class auto_hr; //
  53. class auto_os; //
  54. class auto_imp; // (atlconv.h) __ATLCONV_H__
  55. template<class T>
  56. class auto_handle; //
  57. class auto_cs; //
  58. class auto_leave; //
  59. class auto_var; // (oleauto.h) __wtypes_h__ && (comutil.h) _INC_COMUTIL
  60. template<class _Ty>
  61. class auto_virt; // (winbase.h)
  62. class auto_menu;
  63. #if defined (__wtypes_h__)
  64. class auto_bstr
  65. {
  66. public:
  67. auto_bstr( BSTR b= 0, bool o= true)
  68. : _bstr(b), _Owns(o)
  69. {}
  70. ~auto_bstr()
  71. {
  72. if(_bstr && _Owns)
  73. ::SysFreeString(_bstr);
  74. }
  75. bool Ownership(bool fOwns)
  76. { return _Owns = fOwns; }
  77. operator BSTR() { return _bstr; }
  78. operator const BSTR() const { return _bstr; }
  79. BSTR* operator &() {return &_bstr; }
  80. auto_bstr& operator=(auto_bstr& rhs)
  81. {
  82. if(_bstr == rhs._bstr)
  83. return *this;
  84. clear();
  85. _Owns= rhs._Owns;
  86. _bstr= rhs.release();
  87. return *this;
  88. }
  89. auto_bstr& operator=(BSTR bstr)
  90. {
  91. clear();
  92. _bstr= bstr;
  93. _Owns= true;
  94. return *this;
  95. }
  96. operator bool()
  97. { return NULL != _bstr; }
  98. operator !()
  99. { return NULL == _bstr; }
  100. WCHAR operator[] (int index)
  101. { return _bstr[index]; }
  102. void clear()
  103. {
  104. if(_bstr && _Owns)
  105. {
  106. ::SysFreeString(_bstr);
  107. }
  108. _bstr= NULL;
  109. }
  110. BSTR release()
  111. {
  112. BSTR bstr= _bstr;
  113. _bstr= NULL;
  114. return bstr;
  115. }
  116. protected:
  117. bool _Owns;
  118. BSTR _bstr;
  119. };
  120. #endif // __wtypes_h__
  121. // auto_tm ********************************************************************
  122. //
  123. // Smart Pointers for memory freed with CoTaskFreeMem
  124. template<class _Ty>
  125. class auto_tm
  126. {
  127. public:
  128. typedef _Ty element_type;
  129. explicit auto_tm(_Ty *_P = 0) _THROW0()
  130. : _Owns(_P != 0), _Ptr(_P) {}
  131. auto_tm(const auto_tm<_Ty>& _Y) _THROW0()
  132. : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
  133. auto_tm<_Ty>& operator=(const auto_tm<_Ty>& _Y) _THROW0()
  134. {if (_Ptr != _Y.get())
  135. {if (_Owns && _Ptr)
  136. CoTaskMemFree(_Ptr);
  137. _Owns = _Y._Owns;
  138. _Ptr = _Y.release(); }
  139. else if (_Y._Owns)
  140. _Owns = true;
  141. return (*this); }
  142. auto_tm<_Ty>& operator=(_Ty* _Y) _THROW0()
  143. { {if (_Owns && _Ptr)
  144. CoTaskMemFree(_Ptr);
  145. _Owns = _Y != 0;
  146. _Ptr = _Y; }
  147. return (*this); }
  148. ~auto_tm()
  149. {if (_Owns && _Ptr)
  150. CoTaskMemFree(_Ptr);}
  151. _Ty** operator&() _THROW0()
  152. {if (_Owns && _Ptr)
  153. CoTaskMemFree(_Ptr);
  154. _Owns = true;
  155. _Ptr = 0;
  156. return &_Ptr;
  157. }
  158. operator _Ty* () const
  159. { return _Ptr; }
  160. _Ty& operator*() const _THROW0()
  161. {return (*get()); }
  162. _Ty *operator->() const _THROW0()
  163. {return (get()); }
  164. _Ty& operator[] (int ndx) const _THROW0()
  165. {return *(get() + ndx); }
  166. _Ty *get() const _THROW0()
  167. {return (_Ptr); }
  168. _Ty *release() const _THROW0()
  169. {((auto_tm<_Ty> *)this)->_Owns = false;
  170. return (_Ptr); }
  171. bool Ownership(bool fOwns)
  172. { return _Owns = fOwns; }
  173. protected:
  174. bool _Owns;
  175. _Ty *_Ptr;
  176. };
  177. // auto_sid *******************************************************************
  178. //
  179. // Smart Pointers for SID's (Security ID's)
  180. class auto_sid
  181. {
  182. public:
  183. explicit auto_sid(SID* p = 0)
  184. : m_psid(p) {};
  185. auto_sid(auto_sid& rhs)
  186. : m_psid(rhs.release()) {};
  187. ~auto_sid()
  188. { reset(); };
  189. auto_sid& operator= (auto_sid& rhs)
  190. { if (this != rhs.getThis())
  191. reset (rhs.release() );
  192. return *this;
  193. };
  194. SID operator*() const
  195. { return *m_psid; };
  196. void** operator& ()
  197. { reset(); return (void**)&m_psid; };
  198. operator SID* ()
  199. { return m_psid; };
  200. // Checks for NULL
  201. BOOL operator== (LPVOID lpv)
  202. { return m_psid == lpv; };
  203. BOOL operator!= (LPVOID lpv)
  204. { return m_psid != lpv; };
  205. // return value of current dumb pointer
  206. SID* get() const
  207. { return m_psid; };
  208. // relinquish ownership
  209. SID* release()
  210. { SID* oldpsid = m_psid;
  211. m_psid = 0;
  212. return oldpsid;
  213. };
  214. // delete owned pointer; assume ownership of p
  215. void reset (SID* p = 0)
  216. {
  217. if (m_psid)
  218. FreeSid(m_psid);
  219. m_psid = p;
  220. };
  221. private:
  222. // operator& throws off operator=
  223. const auto_sid* getThis() const
  224. { return this; };
  225. SID* m_psid;
  226. };
  227. // auto_sa ********************************************************************
  228. //
  229. // Smart Pointers for SafeArray's (those VB arrays)
  230. #ifdef __oaidl_h__
  231. class auto_sa
  232. {
  233. public:
  234. auto_sa()
  235. : _psa(0),
  236. _Owns(true)
  237. {}
  238. ~auto_sa()
  239. {
  240. if(_psa && _Owns)
  241. {
  242. _psa->cLocks= 0;
  243. ::SafeArrayDestroy(_psa);
  244. }
  245. }
  246. bool Ownership(bool fOwns)
  247. { return _Owns = fOwns; }
  248. operator SAFEARRAY *() { return _psa; }
  249. operator const SAFEARRAY *() const { return _psa; }
  250. auto_sa& operator=(auto_sa& rhs)
  251. {
  252. if(_psa == rhs._psa)
  253. return *this;
  254. clear();
  255. _Owns= rhs._Owns;
  256. _psa= rhs.release();
  257. return *this;
  258. }
  259. auto_sa& operator=(SAFEARRAY* psa)
  260. {
  261. clear();
  262. _psa= psa;
  263. _Owns= true;
  264. return *this;
  265. }
  266. operator bool()
  267. { return NULL != _psa; }
  268. operator !()
  269. { return NULL == _psa; }
  270. void clear()
  271. {
  272. if(_psa && _Owns)
  273. {
  274. _psa->cLocks= 0;
  275. ::SafeArrayDestroy(_psa);
  276. }
  277. _psa= NULL;
  278. }
  279. SAFEARRAY* release()
  280. {
  281. SAFEARRAY* psa= _psa;
  282. _psa= NULL;
  283. return psa;
  284. }
  285. protected:
  286. SAFEARRAY *_psa;
  287. bool _Owns;
  288. };
  289. #endif
  290. // auto_rel *******************************************************************
  291. //
  292. // Smart pointer for COM interfaces
  293. //
  294. // class I - Multi-Inheritance casting for ATL type classes
  295. // ergo C2385 - T::Release() is ambiguous
  296. template<class T, class I = T>
  297. class auto_rel
  298. {
  299. public:
  300. auto_rel()
  301. {
  302. p = 0;
  303. }
  304. auto_rel(T* p2)
  305. {
  306. assign(p2);
  307. }
  308. auto_rel(const auto_rel<T, I>& p2)
  309. {
  310. assign(p2.p);
  311. }
  312. auto_rel(void* p2)
  313. {
  314. if(p2)
  315. {
  316. auto_hr hr = ((IUnknown*)p2)->QueryInterface(__uuidof(T), (void**)&p);
  317. }
  318. else
  319. {
  320. p = 0;
  321. }
  322. }
  323. ~auto_rel()
  324. {
  325. clear(p);
  326. }
  327. // for the NULL case - have to have int explicitly or it won't compile
  328. // due to an ambiguous conversion (can't decide between T* and void*).
  329. auto_rel<T, I>& operator =(int p2)
  330. {
  331. clear(p);
  332. p = 0;
  333. return(*this);
  334. }
  335. // normal case is nice and fast - do the assign before the clear in case
  336. // p2 == p (so we don't accidentally delete it if we hold the only ref).
  337. auto_rel<T, I>& operator =(T* p2)
  338. {
  339. T* p3 = p;
  340. assign(p2);
  341. clear(p3);
  342. return(*this);
  343. }
  344. // copy is also fast - must have copy otherwise compiler generates it
  345. // and it doesn't correctly addref.
  346. auto_rel<T, I>& operator =(const auto_rel<T, I>& p2)
  347. {
  348. T* p3 = p;
  349. assign(p2.p);
  350. clear(p3);
  351. return(*this);
  352. }
  353. // QI if its not a T* - has to be void* rather than IUnknown since if
  354. // T happens to be IUnknown it produces a conflict and won't compile.
  355. auto_rel<T, I>& operator =(void* p2)
  356. {
  357. if(p2)
  358. {
  359. T* p3 = p;
  360. auto_hr hr = ((IUnknown*)p2)->QueryInterface(__uuidof(T), (void**)&p);
  361. clear(p3);
  362. }
  363. else
  364. {
  365. clear(p);
  366. p = 0;
  367. }
  368. return(*this);
  369. }
  370. T& operator *() const
  371. {
  372. if(!p)
  373. {
  374. throw(E_POINTER);
  375. }
  376. return(*p);
  377. }
  378. T* operator ->() const
  379. {
  380. if(!p)
  381. {
  382. throw(E_POINTER);
  383. }
  384. return(p);
  385. }
  386. // CComPtr doesn't clear like we do for this one
  387. T** operator &()
  388. {
  389. clear(p);
  390. p = 0;
  391. return(&p);
  392. }
  393. T** Address()
  394. {
  395. return(&p);
  396. }
  397. operator T*()
  398. {
  399. return(p);
  400. }
  401. operator void*()
  402. {
  403. return((IUnknown*)p);
  404. }
  405. operator bool()
  406. {
  407. return(!!p);
  408. }
  409. operator bool() const
  410. {
  411. return(!!p);
  412. }
  413. bool operator !()
  414. {
  415. return(!p);
  416. }
  417. bool operator !() const
  418. {
  419. return(!p);
  420. }
  421. bool operator ==(void* p2)
  422. {
  423. return(p == p2);
  424. }
  425. bool operator !=(void* p2)
  426. {
  427. return(p != p2);
  428. }
  429. bool operator ==(const auto_rel<T, I>& p2)
  430. {
  431. return p == p2.p;
  432. }
  433. bool operator <(const auto_rel<T, I>& p2)
  434. {
  435. return p < p2.p;
  436. }
  437. T* p;
  438. private:
  439. void clear(T* p2)
  440. {
  441. if(p2)
  442. {
  443. #ifdef DEBUG
  444. ULONG cRef =
  445. #endif
  446. ((I*)p2)->Release();
  447. }
  448. }
  449. void assign(T* p2)
  450. {
  451. if(p = p2)
  452. {
  453. ((I*)p)->AddRef();
  454. }
  455. }
  456. };
  457. // auto_os ********************************************************************
  458. //
  459. // Smart pointer for OS system calls.
  460. class auto_os
  461. {
  462. public:
  463. auto_os() : dw(0) {}
  464. auto_os& operator= (LONG rhs)
  465. {
  466. dw = rhs;
  467. #ifdef _DEBUG_AUTOHR
  468. if (debug().CheckOsFail())
  469. throw (int)debug().m_pInfo->m_os;
  470. #endif
  471. if (rhs)
  472. {
  473. #ifdef _DEBUG_AUTOHR
  474. if (debug().m_pInfo->m_bDebugBreakOnError)
  475. #ifdef _M_IX86
  476. __asm int 3;
  477. #else
  478. DebugBreak();
  479. #endif
  480. #endif
  481. throw (int)rhs;
  482. }
  483. return *this;
  484. };
  485. auto_os& operator= (BOOL rhs)
  486. {
  487. dw = rhs;
  488. #ifdef _DEBUG_AUTOHR
  489. if (debug().CheckOsFail())
  490. throw (int)(debug().m_pInfo->m_os);
  491. #endif
  492. if (!rhs)
  493. {
  494. #ifdef _DEBUG_AUTOHR
  495. if (debug().m_pInfo->m_bDebugBreakOnError)
  496. #ifdef _M_IX86
  497. __asm int 3;
  498. #else
  499. DebugBreak();
  500. #endif
  501. #endif
  502. throw (int)GetLastError();
  503. }
  504. return *this;
  505. };
  506. operator LONG ()
  507. { return dw; }
  508. friend void operator| (BOOL b, auto_os& rhs)
  509. {
  510. rhs = b;
  511. }
  512. friend void operator| (LONG l, auto_os& rhs)
  513. {
  514. rhs = l;
  515. }
  516. protected:
  517. DWORD dw;
  518. };
  519. // auto_reg *******************************************************************
  520. //
  521. // Smart pointer for HKEY's
  522. class auto_reg
  523. {
  524. public:
  525. auto_reg(HKEY p = 0)
  526. : h(p) {};
  527. auto_reg(auto_reg& rhs)
  528. : h(rhs.release()) {};
  529. ~auto_reg()
  530. { if (h) RegCloseKey(h); };
  531. auto_reg& operator= (auto_reg& rhs)
  532. { if (this != rhs.getThis())
  533. reset (rhs.release() );
  534. return *this;
  535. };
  536. auto_reg& operator= (HKEY rhs)
  537. { if ((NULL == rhs) || (INVALID_HANDLE_VALUE == rhs))
  538. { // be sure and go through auto_os for dbg.lib
  539. auto_os os;
  540. os = (BOOL)FALSE;
  541. }
  542. reset (rhs);
  543. return *this;
  544. };
  545. HKEY* operator& ()
  546. { reset(); return &h; };
  547. operator HKEY ()
  548. { return h; };
  549. // Checks for NULL
  550. bool operator== (LPVOID lpv)
  551. { return h == lpv; };
  552. bool operator!= (LPVOID lpv)
  553. { return h != lpv; };
  554. // return value of current dumb pointer
  555. HKEY get() const
  556. { return h; };
  557. // relinquish ownership
  558. HKEY release()
  559. { HKEY oldh = h;
  560. h = 0;
  561. return oldh;
  562. };
  563. // delete owned pointer; assume ownership of p
  564. BOOL reset (HKEY p = 0)
  565. {
  566. BOOL rt = TRUE;
  567. if (h)
  568. rt = RegCloseKey(h);
  569. h = p;
  570. return rt;
  571. };
  572. private:
  573. // operator& throws off operator=
  574. const auto_reg* getThis() const
  575. { return this; };
  576. HKEY h;
  577. };
  578. // auto_pv ********************************************************************
  579. //
  580. // Smart pointer for PROPVARIANT's
  581. //
  582. // pretty minimal functionality, designed to provide auto release only
  583. //
  584. #ifdef __propidl_h__
  585. class auto_pv : public ::tagPROPVARIANT {
  586. public:
  587. // Constructors
  588. //
  589. auto_pv() throw();
  590. // Destructor
  591. //
  592. ~auto_pv() throw();
  593. // Low-level operations
  594. //
  595. void Clear() throw();
  596. void Attach(PROPVARIANT& varSrc) throw();
  597. PROPVARIANT Detach() throw();
  598. bool Ownership(bool fOwns)
  599. { return _Owns = fOwns; }
  600. protected:
  601. bool _Owns;
  602. };
  603. // Default constructor
  604. //
  605. inline auto_pv::auto_pv() throw()
  606. : _Owns(true)
  607. {
  608. ::PropVariantInit(this);
  609. }
  610. // destructor
  611. inline auto_pv::~auto_pv() throw()
  612. {
  613. if(_Owns)
  614. ::PropVariantClear(this);
  615. else
  616. ::PropVariantInit(this);
  617. }
  618. // Clear the auto_var
  619. //
  620. inline void auto_pv::Clear() throw()
  621. {
  622. if(_Owns)
  623. ::PropVariantClear(this);
  624. else
  625. ::PropVariantInit(this);
  626. }
  627. inline void auto_pv::Attach(PROPVARIANT& varSrc) throw()
  628. {
  629. //
  630. // Free up previous VARIANT
  631. //
  632. Clear();
  633. //
  634. // Give control of data to auto_var
  635. //
  636. memcpy(this, &varSrc, sizeof(varSrc));
  637. varSrc.vt = VT_EMPTY;
  638. }
  639. inline PROPVARIANT auto_pv::Detach() throw()
  640. {
  641. PROPVARIANT varResult = *this;
  642. this->vt = VT_EMPTY;
  643. return varResult;
  644. }
  645. #endif
  646. // auto_prg *******************************************************************
  647. //
  648. // Same as auto_ptr/pointer but for an array
  649. // auto pointer to range
  650. template<class _Ty>
  651. class auto_prg
  652. {
  653. public:
  654. typedef _Ty element_type;
  655. explicit auto_prg(_Ty *_P = 0) _THROW0()
  656. : _Owns(_P != 0), _Ptr(_P) {}
  657. auto_prg(const auto_prg<_Ty>& _Y) _THROW0()
  658. : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
  659. auto_prg<_Ty>& operator=(const auto_prg<_Ty>& _Y) _THROW0()
  660. {if (_Ptr != _Y.get())
  661. {if (_Owns)
  662. delete [] _Ptr;
  663. _Owns = _Y._Owns;
  664. _Ptr = _Y.release(); }
  665. else if (_Y._Owns)
  666. _Owns = true;
  667. return (*this); }
  668. auto_prg<_Ty>& operator=(_Ty* _Y) _THROW0()
  669. { {if (_Owns)
  670. delete [] _Ptr;
  671. _Owns = _Y != 0;
  672. _Ptr = _Y; }
  673. return (*this); }
  674. ~auto_prg()
  675. {if (_Owns)
  676. delete [] _Ptr; }
  677. _Ty** operator&() _THROW0()
  678. { return &_Ptr; }
  679. operator _Ty* () const
  680. { return _Ptr; }
  681. _Ty& operator*() const _THROW0()
  682. {return (*get()); }
  683. _Ty *operator->() const _THROW0()
  684. {return (get()); }
  685. _Ty& operator[] (unsigned long ndx) const _THROW0()
  686. {return *(get() + ndx); }
  687. _Ty& operator[] (int ndx) const _THROW0()
  688. {return *(get() + ndx); }
  689. _Ty *get() const _THROW0()
  690. {return (_Ptr); }
  691. _Ty *release() const _THROW0()
  692. {((auto_prg<_Ty> *)this)->_Owns = false;
  693. return (_Ptr); }
  694. bool Ownership(bool fOwns)
  695. { return _Owns = fOwns; }
  696. protected:
  697. bool _Owns;
  698. _Ty *_Ptr;
  699. };
  700. // pointer ********************************************************************
  701. //
  702. // Same as auto_ptr (with the operator's you normally use)
  703. //
  704. template<class _Ty>
  705. class pointer
  706. {
  707. public:
  708. typedef _Ty element_type;
  709. explicit pointer(_Ty *_P = 0) _THROW0()
  710. : _Owns(_P != 0), _Ptr(_P) {}
  711. pointer(const pointer<_Ty>& _Y) _THROW0()
  712. : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
  713. pointer<_Ty>& operator=(const pointer<_Ty>& _Y) _THROW0()
  714. {if (_Ptr != _Y.get())
  715. {if (_Owns)
  716. delete _Ptr;
  717. _Owns = _Y._Owns;
  718. _Ptr = _Y.release(); }
  719. else if (_Y._Owns)
  720. _Owns = true;
  721. return (*this); }
  722. pointer<_Ty>& operator=(_Ty* _Y) _THROW0()
  723. { {if (_Owns)
  724. delete _Ptr;
  725. _Owns = _Y != 0;
  726. _Ptr = _Y; }
  727. return (*this); }
  728. ~pointer()
  729. {if (_Owns)
  730. delete _Ptr; }
  731. _Ty** operator&() _THROW0()
  732. { return &_Ptr; }
  733. operator _Ty* () const
  734. { return _Ptr; }
  735. _Ty& operator*() const _THROW0()
  736. {return (*get()); }
  737. _Ty *operator->() const _THROW0()
  738. {return (get()); }
  739. _Ty& operator[] (int ndx) const _THROW0()
  740. {return *(get() + ndx); }
  741. _Ty *get() const _THROW0()
  742. {return (_Ptr); }
  743. _Ty *release() const _THROW0()
  744. {((pointer<_Ty> *)this)->_Owns = false;
  745. return (_Ptr); }
  746. bool Ownership(bool fOwns)
  747. { return _Owns = fOwns; }
  748. protected:
  749. bool _Owns;
  750. _Ty *_Ptr;
  751. };
  752. // auto_hr ********************************************************************
  753. //
  754. // Throws and HRESULT to keep from writing a thousand if (hr) ....
  755. //
  756. class auto_hr
  757. {
  758. public:
  759. auto_hr() : hr(S_OK) {}
  760. auto_hr(HRESULT rhs)
  761. {
  762. (*this) = rhs;
  763. }
  764. auto_hr& operator= (HRESULT rhs)
  765. {
  766. hr = rhs;
  767. #ifdef _DEBUG_AUTOHR
  768. if (debug().CheckHrFail())
  769. throw HRESULT (debug().m_pInfo->m_hr);
  770. #endif
  771. if (FAILED(rhs))
  772. {
  773. #ifdef _DEBUG_AUTOHR
  774. if (debug().m_pInfo->m_bDebugBreakOnError)
  775. #ifdef _M_IX86
  776. __asm int 3;
  777. #else
  778. DebugBreak();
  779. #endif
  780. #endif
  781. throw HRESULT(rhs);
  782. }
  783. return *this;
  784. };
  785. operator HRESULT ()
  786. { return hr; }
  787. HRESULT operator <<(HRESULT h)
  788. {
  789. hr = h;
  790. return hr;
  791. }
  792. protected:
  793. auto_hr& operator= (bool rhs) { return *this; }
  794. auto_hr& operator= (int rhs) { return *this; }
  795. auto_hr& operator= (ULONG rhs) { return *this; }
  796. HRESULT hr;
  797. };
  798. // auto_handle ****************************************************************
  799. //
  800. // Smart pointer for any HANDLE that needs a CloseHandle()
  801. //
  802. template<class T> class auto_handle;
  803. // CHandleProxy
  804. //
  805. // By Proxy I mean this is just a mux for return values. C++ won't let you
  806. // differentiate calls with just a different return value.
  807. //
  808. // You can return an object and have that implicitly cast to different values.
  809. // Sneaky but it works well.
  810. //
  811. // The class will just be inlined out, and doesn't really have anything but a
  812. // pointer.
  813. template<class T>
  814. class CHandleProxy
  815. {
  816. public:
  817. CHandleProxy (auto_handle<T>& ah) :
  818. m_ah(ah) {};
  819. CHandleProxy (const auto_handle<T>& ah) :
  820. m_ah(const_cast<auto_handle<T>&> (ah)) {};
  821. operator T* () { return &m_ah.h; }
  822. operator const T* () const { return &m_ah.h; }
  823. operator auto_handle<T>* () { return &m_ah; }
  824. protected:
  825. mutable auto_handle<T>& m_ah;
  826. };
  827. template<class T>
  828. class auto_handle
  829. {
  830. public:
  831. auto_handle(T p = 0)
  832. : h(p) {};
  833. auto_handle(const auto_handle<T>& rhs)
  834. : h(rhs.release()) {};
  835. ~auto_handle()
  836. { if (h && INVALID_HANDLE_VALUE != h) CloseHandle(h); };
  837. auto_handle<T>& operator= (const auto_handle<T>& rhs)
  838. { if (this != rhs.getThis())
  839. reset (rhs.release() );
  840. return *this;
  841. };
  842. auto_handle<T>& operator= (T rhs)
  843. { if ((NULL == rhs) || (INVALID_HANDLE_VALUE == rhs))
  844. {
  845. // be sure and go through auto_os for dbg.lib
  846. auto_os os;
  847. os = (BOOL)FALSE;
  848. }
  849. reset (rhs);
  850. return *this;
  851. };
  852. CHandleProxy<T> operator& ()
  853. { reset(); return CHandleProxy<T> (*this); }; // &h;
  854. const CHandleProxy<T> operator& () const
  855. { return CHandleProxy<T> (*this); }; // &h;
  856. operator T ()
  857. { return h; };
  858. // Checks for NULL
  859. bool operator! ()
  860. { return h == NULL; }
  861. operator bool()
  862. { return h != NULL; }
  863. bool operator== (LPVOID lpv) const
  864. { return h == lpv; };
  865. bool operator!= (LPVOID lpv) const
  866. { return h != lpv; };
  867. bool operator== (const auto_handle<T>& rhs) const
  868. { return h == rhs.h; };
  869. bool operator< (const auto_handle<T>& rhs) const
  870. { return h < rhs.h; };
  871. // return value of current dumb pointer
  872. T get() const
  873. { return h; };
  874. // relinquish ownership
  875. T release() const
  876. { T oldh = h;
  877. h = 0;
  878. return oldh;
  879. };
  880. // delete owned pointer; assume ownership of p
  881. BOOL reset (T p = 0)
  882. {
  883. BOOL rt = TRUE;
  884. if (h && INVALID_HANDLE_VALUE != h)
  885. rt = CloseHandle(h);
  886. h = p;
  887. return rt;
  888. };
  889. private:
  890. friend class CHandleProxy<T>;
  891. // operator& throws off operator=
  892. const auto_handle<T> * getThis() const
  893. { return this; };
  894. // mutable is needed for release call in ctor and copy ctor
  895. mutable T h;
  896. };
  897. // auto_imp *******************************************************************
  898. //
  899. // Impersonate a user and revert
  900. //
  901. #ifdef __ATLCONV_H__
  902. class auto_imp
  903. {
  904. public:
  905. auto_imp() :
  906. m_hUser(0)
  907. {
  908. }
  909. ~auto_imp()
  910. {
  911. if(m_hUser)
  912. {
  913. RevertToSelf();
  914. CloseHandle(m_hUser);
  915. }
  916. }
  917. HRESULT Impersonate(LPOLESTR pszDomain, LPOLESTR pszName, LPOLESTR pszPassword)
  918. {
  919. HRESULT hr = S_OK;
  920. try
  921. {
  922. USES_CONVERSION;
  923. auto_os os;
  924. auto_handle<HANDLE> hUser;
  925. os = LogonUser(OLE2T(pszName), OLE2T(pszDomain), pszPassword ? OLE2T(pszPassword) : _T(""), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hUser);
  926. os = ImpersonateLoggedOnUser(hUser);
  927. m_hUser = hUser.release();
  928. }
  929. catch(HRESULT hrException)
  930. {
  931. hr = hrException;
  932. }
  933. return(hr);
  934. }
  935. HRESULT Impersonate(LPOLESTR pszDomainName, LPOLESTR pszPassword)
  936. {
  937. LPOLESTR pszSeperator;
  938. _bstr_t sName;
  939. _bstr_t sDomain;
  940. pszSeperator = wcschr(pszDomainName, '\\');
  941. if(pszSeperator)
  942. {
  943. *pszSeperator = 0;
  944. sDomain = pszDomainName;
  945. *pszSeperator = '\\';
  946. sName = pszSeperator + 1;
  947. }
  948. else
  949. {
  950. sName = pszDomainName;
  951. }
  952. return Impersonate(sDomain, sName, pszPassword);
  953. }
  954. protected:
  955. HANDLE m_hUser;
  956. };
  957. #endif // __ATLCONV_H__
  958. // auto_cs ********************************************************************
  959. //
  960. // Smart object for CriticalSections
  961. #ifdef TRYENTRYCS
  962. typedef BOOL (WINAPI *LPTRYENTERCRITICALSECTION)(LPCRITICAL_SECTION lpCriticalSection);
  963. static LPTRYENTERCRITICALSECTION g_pfnTryEnter = NULL;
  964. #endif
  965. class auto_leave;
  966. class auto_cs
  967. {
  968. public:
  969. auto_cs()
  970. {
  971. InitializeCriticalSection(&m_cs);
  972. #ifdef TRYENTRYCS
  973. if (!g_pfnTryEnter)
  974. {
  975. HINSTANCE hinst = GetModuleHandleA("kernel32.dll");
  976. if (INVALID_HANDLE_VALUE != hinst)
  977. {
  978. // note: GetProcAddress is ANSI only, there is no A flavor
  979. g_pfnTryEnter = (LPTRYENTERCRITICALSECTION)GetProcAddress(
  980. hinst, "TryEnterCriticalSection");
  981. }
  982. }
  983. #endif
  984. }
  985. ~auto_cs()
  986. {
  987. DeleteCriticalSection(&m_cs);
  988. };
  989. // return value of current dumb pointer
  990. LPCRITICAL_SECTION get()
  991. { return &m_cs; };
  992. LPCRITICAL_SECTION get() const
  993. { return (LPCRITICAL_SECTION)&m_cs; };
  994. protected:
  995. CRITICAL_SECTION m_cs;
  996. };
  997. // auto_leave *****************************************************************
  998. //
  999. // Smart LeaveCriticalSections
  1000. class auto_leave
  1001. {
  1002. public:
  1003. auto_leave(auto_cs& cs)
  1004. : m_ulCount(0), m_pcs(cs.get()) {}
  1005. auto_leave(const auto_cs& cs)
  1006. {
  1007. m_ulCount =0;
  1008. m_pcs = cs.get();
  1009. }
  1010. ~auto_leave()
  1011. {
  1012. reset();
  1013. }
  1014. auto_leave& operator=(auto_cs& cs)
  1015. {
  1016. reset();
  1017. m_pcs = cs.get();
  1018. return *this;
  1019. }
  1020. void EnterCriticalSection()
  1021. { ::EnterCriticalSection(m_pcs); m_ulCount++; }
  1022. void LeaveCriticalSection()
  1023. {
  1024. if (m_ulCount)
  1025. {
  1026. m_ulCount--;
  1027. ::LeaveCriticalSection(m_pcs);
  1028. }
  1029. }
  1030. #ifdef TRYENTRYCS
  1031. BOOL TryEnterCriticalSection()
  1032. {
  1033. if (g_pfnTryEnter)
  1034. {
  1035. if ((*g_pfnTryEnter)(m_pcs))
  1036. {
  1037. m_ulCount++;
  1038. return TRUE;
  1039. }
  1040. return FALSE;
  1041. }
  1042. else
  1043. {
  1044. ::EnterCriticalSection(m_pcs);
  1045. m_ulCount++;
  1046. return TRUE;
  1047. }
  1048. }
  1049. #endif
  1050. protected:
  1051. void reset()
  1052. {
  1053. while (m_ulCount)
  1054. {
  1055. LeaveCriticalSection();
  1056. }
  1057. m_pcs = 0;
  1058. }
  1059. ULONG m_ulCount;
  1060. LPCRITICAL_SECTION m_pcs;
  1061. };
  1062. class _bstr_t;
  1063. class auto_var;
  1064. // auto_var *******************************************************************
  1065. //
  1066. // Wrapper class for VARIANT
  1067. //
  1068. // NOTE : the one included w/ C++ has mem leaks in op= and op&. Otherwise this
  1069. // is a direct copy
  1070. /*
  1071. * VARENUM usage key,
  1072. *
  1073. * * [V] - may appear in a VARIANT
  1074. * * [T] - may appear in a TYPEDESC
  1075. * * [P] - may appear in an OLE property set
  1076. * * [S] - may appear in a Safe Array
  1077. * * [C] - supported by class auto_var
  1078. *
  1079. *
  1080. * VT_EMPTY [V] [P] nothing
  1081. * VT_NULL [V] [P] SQL style Null
  1082. * VT_I2 [V][T][P][S][C] 2 byte signed int
  1083. * VT_I4 [V][T][P][S][C] 4 byte signed int
  1084. * VT_R4 [V][T][P][S][C] 4 byte real
  1085. * VT_R8 [V][T][P][S][C] 8 byte real
  1086. * VT_CY [V][T][P][S][C] currency
  1087. * VT_DATE [V][T][P][S][C] date
  1088. * VT_BSTR [V][T][P][S][C] OLE Automation string
  1089. * VT_DISPATCH [V][T][P][S][C] IDispatch *
  1090. * VT_ERROR [V][T] [S][C] SCODE
  1091. * VT_BOOL [V][T][P][S][C] True=-1, False=0
  1092. * VT_VARIANT [V][T][P][S] VARIANT *
  1093. * VT_UNKNOWN [V][T] [S][C] IUnknown *
  1094. * VT_DECIMAL [V][T] [S][C] 16 byte fixed point
  1095. * VT_I1 [T] signed char
  1096. * VT_UI1 [V][T][P][S][C] unsigned char
  1097. * VT_UI2 [T][P] unsigned short
  1098. * VT_UI4 [T][P] unsigned short
  1099. * VT_I8 [T][P] signed 64-bit int
  1100. * VT_UI8 [T][P] unsigned 64-bit int
  1101. * VT_INT [T] signed machine int
  1102. * VT_UINT [T] unsigned machine int
  1103. * VT_VOID [T] C style void
  1104. * VT_HRESULT [T] Standard return type
  1105. * VT_PTR [T] pointer type
  1106. * VT_SAFEARRAY [T] (use VT_ARRAY in VARIANT)
  1107. * VT_CARRAY [T] C style array
  1108. * VT_USERDEFINED [T] user defined type
  1109. * VT_LPSTR [T][P] null terminated string
  1110. * VT_LPWSTR [T][P] wide null terminated string
  1111. * VT_FILETIME [P] FILETIME
  1112. * VT_BLOB [P] Length prefixed bytes
  1113. * VT_STREAM [P] Name of the stream follows
  1114. * VT_STORAGE [P] Name of the storage follows
  1115. * VT_STREAMED_OBJECT [P] Stream contains an object
  1116. * VT_STORED_OBJECT [P] Storage contains an object
  1117. * VT_BLOB_OBJECT [P] Blob contains an object
  1118. * VT_CF [P] Clipboard format
  1119. * VT_CLSID [P] A Class ID
  1120. * VT_VECTOR [P] simple counted array
  1121. * VT_ARRAY [V] SAFEARRAY*
  1122. * VT_BYREF [V] void* for local use
  1123. */
  1124. #if defined (__wtypes_h__) && defined(_INC_COMUTIL) // where VARIANT/_com_error is defined
  1125. class auto_var : public ::tagVARIANT {
  1126. public:
  1127. // Constructors
  1128. //
  1129. auto_var() throw();
  1130. auto_var(const VARIANT& varSrc) throw(_com_error);
  1131. auto_var(const VARIANT* pSrc) throw(_com_error);
  1132. auto_var(const auto_var& varSrc) throw(_com_error);
  1133. auto_var(VARIANT& varSrc, bool fCopy) throw(_com_error); // Attach VARIANT if !fCopy
  1134. auto_var(short sSrc, VARTYPE vtSrc = VT_I2) throw(_com_error); // Creates a VT_I2, or a VT_BOOL
  1135. auto_var(long lSrc, VARTYPE vtSrc = VT_I4) throw(_com_error); // Creates a VT_I4, a VT_ERROR, or a VT_BOOL
  1136. auto_var(float fltSrc) throw(); // Creates a VT_R4
  1137. auto_var(double dblSrc, VARTYPE vtSrc = VT_R8) throw(_com_error); // Creates a VT_R8, or a VT_DATE
  1138. auto_var(const CY& cySrc) throw(); // Creates a VT_CY
  1139. auto_var(const _bstr_t& bstrSrc) throw(_com_error); // Creates a VT_BSTR
  1140. auto_var(const wchar_t *pSrc) throw(_com_error); // Creates a VT_BSTR
  1141. auto_var(const char* pSrc) throw(_com_error); // Creates a VT_BSTR
  1142. auto_var(IDispatch* pSrc, bool fAddRef = true) throw(); // Creates a VT_DISPATCH
  1143. auto_var(bool bSrc) throw(); // Creates a VT_BOOL
  1144. auto_var(IUnknown* pSrc, bool fAddRef = true) throw(); // Creates a VT_UNKNOWN
  1145. auto_var(const DECIMAL& decSrc) throw(); // Creates a VT_DECIMAL
  1146. auto_var(BYTE bSrc) throw(); // Creates a VT_UI1
  1147. // Destructor
  1148. //
  1149. ~auto_var() throw(_com_error);
  1150. // Extractors
  1151. //
  1152. operator short() const throw(_com_error); // Extracts a short from a VT_I2
  1153. operator long() const throw(_com_error); // Extracts a long from a VT_I4
  1154. operator float() const throw(_com_error); // Extracts a float from a VT_R4
  1155. operator double() const throw(_com_error); // Extracts a double from a VT_R8
  1156. operator CY() const throw(_com_error); // Extracts a CY from a VT_CY
  1157. operator _bstr_t() const throw(_com_error); // Extracts a _bstr_t from a VT_BSTR
  1158. operator IDispatch*() const throw(_com_error); // Extracts a IDispatch* from a VT_DISPATCH
  1159. operator bool() const throw(_com_error); // Extracts a bool from a VT_BOOL
  1160. operator IUnknown*() const throw(_com_error); // Extracts a IUnknown* from a VT_UNKNOWN
  1161. operator DECIMAL() const throw(_com_error); // Extracts a DECIMAL from a VT_DECIMAL
  1162. operator BYTE() const throw(_com_error); // Extracts a BTYE (unsigned char) from a VT_UI1
  1163. // Assignment operations
  1164. //
  1165. auto_var& operator=(const VARIANT& varSrc) throw(_com_error);
  1166. auto_var& operator=(const VARIANT* pSrc) throw(_com_error);
  1167. auto_var& operator=(const auto_var& varSrc) throw(_com_error);
  1168. auto_var& operator=(short sSrc) throw(_com_error); // Assign a VT_I2, or a VT_BOOL
  1169. auto_var& operator=(long lSrc) throw(_com_error); // Assign a VT_I4, a VT_ERROR or a VT_BOOL
  1170. auto_var& operator=(float fltSrc) throw(_com_error); // Assign a VT_R4
  1171. auto_var& operator=(double dblSrc) throw(_com_error); // Assign a VT_R8, or a VT_DATE
  1172. auto_var& operator=(const CY& cySrc) throw(_com_error); // Assign a VT_CY
  1173. auto_var& operator=(const _bstr_t& bstrSrc) throw(_com_error); // Assign a VT_BSTR
  1174. auto_var& operator=(const wchar_t* pSrc) throw(_com_error); // Assign a VT_BSTR
  1175. auto_var& operator=(const char* pSrc) throw(_com_error); // Assign a VT_BSTR
  1176. auto_var& operator=(IDispatch* pSrc) throw(_com_error); // Assign a VT_DISPATCH
  1177. auto_var& operator=(bool bSrc) throw(_com_error); // Assign a VT_BOOL
  1178. auto_var& operator=(IUnknown* pSrc) throw(_com_error); // Assign a VT_UNKNOWN
  1179. auto_var& operator=(const DECIMAL& decSrc) throw(_com_error); // Assign a VT_DECIMAL
  1180. auto_var& operator=(BYTE bSrc) throw(_com_error); // Assign a VT_UI1
  1181. // Comparison operations
  1182. //
  1183. bool operator==(const VARIANT& varSrc) const throw(_com_error);
  1184. bool operator==(const VARIANT* pSrc) const throw(_com_error);
  1185. bool operator!=(const VARIANT& varSrc) const throw(_com_error);
  1186. bool operator!=(const VARIANT* pSrc) const throw(_com_error);
  1187. // Low-level operations
  1188. //
  1189. void Clear() throw(_com_error);
  1190. void Attach(VARIANT& varSrc) throw(_com_error);
  1191. VARIANT Detach() throw(_com_error);
  1192. void ChangeType(VARTYPE vartype, const auto_var* pSrc = NULL) throw(_com_error);
  1193. void SetString(const char* pSrc) throw(_com_error); // used to set ANSI string
  1194. };
  1195. //////////////////////////////////////////////////////////////////////////////////////////
  1196. //
  1197. // Constructors
  1198. //
  1199. //////////////////////////////////////////////////////////////////////////////////////////
  1200. // Default constructor
  1201. //
  1202. inline auto_var::auto_var() throw()
  1203. {
  1204. ::VariantInit(this);
  1205. }
  1206. // Construct a auto_var from a const VARIANT&
  1207. //
  1208. inline auto_var::auto_var(const VARIANT& varSrc) throw(_com_error)
  1209. {
  1210. ::VariantInit(this);
  1211. _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(&varSrc)));
  1212. }
  1213. // Construct a auto_var from a const VARIANT*
  1214. //
  1215. inline auto_var::auto_var(const VARIANT* pSrc) throw(_com_error)
  1216. {
  1217. ::VariantInit(this);
  1218. _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(pSrc)));
  1219. }
  1220. // Construct a auto_var from a const auto_var&
  1221. //
  1222. inline auto_var::auto_var(const auto_var& varSrc) throw(_com_error)
  1223. {
  1224. ::VariantInit(this);
  1225. _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
  1226. }
  1227. // Construct a auto_var from a VARIANT&. If fCopy is FALSE, give control of
  1228. // data to the auto_var without doing a VariantCopy.
  1229. //
  1230. inline auto_var::auto_var(VARIANT& varSrc, bool fCopy) throw(_com_error)
  1231. {
  1232. if (fCopy) {
  1233. ::VariantInit(this);
  1234. _com_util::CheckError(::VariantCopy(this, &varSrc));
  1235. } else {
  1236. memcpy(this, &varSrc, sizeof(varSrc));
  1237. V_VT(&varSrc) = VT_EMPTY;
  1238. }
  1239. }
  1240. // Construct either a VT_I2 VARIANT or a VT_BOOL VARIANT from
  1241. // a short (the default is VT_I2)
  1242. //
  1243. inline auto_var::auto_var(short sSrc, VARTYPE vtSrc) throw(_com_error)
  1244. {
  1245. if ((vtSrc != VT_I2) && (vtSrc != VT_BOOL)) {
  1246. _com_issue_error(E_INVALIDARG);
  1247. }
  1248. if (vtSrc == VT_BOOL) {
  1249. V_VT(this) = VT_BOOL;
  1250. V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1251. }
  1252. else {
  1253. V_VT(this) = VT_I2;
  1254. V_I2(this) = sSrc;
  1255. }
  1256. }
  1257. // Construct either a VT_I4 VARIANT, a VT_BOOL VARIANT, or a
  1258. // VT_ERROR VARIANT from a long (the default is VT_I4)
  1259. //
  1260. inline auto_var::auto_var(long lSrc, VARTYPE vtSrc) throw(_com_error)
  1261. {
  1262. if ((vtSrc != VT_I4) && (vtSrc != VT_ERROR) && (vtSrc != VT_BOOL)) {
  1263. _com_issue_error(E_INVALIDARG);
  1264. }
  1265. if (vtSrc == VT_ERROR) {
  1266. V_VT(this) = VT_ERROR;
  1267. V_ERROR(this) = lSrc;
  1268. }
  1269. else if (vtSrc == VT_BOOL) {
  1270. V_VT(this) = VT_BOOL;
  1271. V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1272. }
  1273. else {
  1274. V_VT(this) = VT_I4;
  1275. V_I4(this) = lSrc;
  1276. }
  1277. }
  1278. // Construct a VT_R4 VARIANT from a float
  1279. //
  1280. inline auto_var::auto_var(float fltSrc) throw()
  1281. {
  1282. V_VT(this) = VT_R4;
  1283. V_R4(this) = fltSrc;
  1284. }
  1285. // Construct either a VT_R8 VARIANT, or a VT_DATE VARIANT from
  1286. // a double (the default is VT_R8)
  1287. //
  1288. inline auto_var::auto_var(double dblSrc, VARTYPE vtSrc) throw(_com_error)
  1289. {
  1290. if ((vtSrc != VT_R8) && (vtSrc != VT_DATE)) {
  1291. _com_issue_error(E_INVALIDARG);
  1292. }
  1293. if (vtSrc == VT_DATE) {
  1294. V_VT(this) = VT_DATE;
  1295. V_DATE(this) = dblSrc;
  1296. }
  1297. else {
  1298. V_VT(this) = VT_R8;
  1299. V_R8(this) = dblSrc;
  1300. }
  1301. }
  1302. // Construct a VT_CY from a CY
  1303. //
  1304. inline auto_var::auto_var(const CY& cySrc) throw()
  1305. {
  1306. V_VT(this) = VT_CY;
  1307. V_CY(this) = cySrc;
  1308. }
  1309. // Construct a VT_BSTR VARIANT from a const _bstr_t&
  1310. //
  1311. inline auto_var::auto_var(const _bstr_t& bstrSrc) throw(_com_error)
  1312. {
  1313. V_VT(this) = VT_BSTR;
  1314. BSTR bstr = static_cast<wchar_t*>(bstrSrc);
  1315. V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char*>(bstr),
  1316. ::SysStringByteLen(bstr));
  1317. if (V_BSTR(this) == NULL) {
  1318. _com_issue_error(E_OUTOFMEMORY);
  1319. }
  1320. }
  1321. // Construct a VT_BSTR VARIANT from a const wchar_t*
  1322. //
  1323. inline auto_var::auto_var(const wchar_t* pSrc) throw(_com_error)
  1324. {
  1325. V_VT(this) = VT_BSTR;
  1326. V_BSTR(this) = ::SysAllocString(pSrc);
  1327. if (V_BSTR(this) == NULL && pSrc != NULL) {
  1328. _com_issue_error(E_OUTOFMEMORY);
  1329. }
  1330. }
  1331. // Construct a VT_BSTR VARIANT from a const char*
  1332. //
  1333. inline auto_var::auto_var(const char* pSrc) throw(_com_error)
  1334. {
  1335. V_VT(this) = VT_BSTR;
  1336. V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
  1337. if (V_BSTR(this) == NULL && pSrc != NULL) {
  1338. _com_issue_error(E_OUTOFMEMORY);
  1339. }
  1340. }
  1341. // Construct a VT_DISPATCH VARIANT from an IDispatch*
  1342. //
  1343. inline auto_var::auto_var(IDispatch* pSrc, bool fAddRef) throw()
  1344. {
  1345. V_VT(this) = VT_DISPATCH;
  1346. V_DISPATCH(this) = pSrc;
  1347. // Need the AddRef() as VariantClear() calls Release(), unless fAddRef
  1348. // false indicates we're taking ownership
  1349. //
  1350. if (fAddRef) {
  1351. V_DISPATCH(this)->AddRef();
  1352. }
  1353. }
  1354. // Construct a VT_BOOL VARIANT from a bool
  1355. //
  1356. inline auto_var::auto_var(bool bSrc) throw()
  1357. {
  1358. V_VT(this) = VT_BOOL;
  1359. V_BOOL(this) = (bSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1360. }
  1361. // Construct a VT_UNKNOWN VARIANT from an IUnknown*
  1362. //
  1363. inline auto_var::auto_var(IUnknown* pSrc, bool fAddRef) throw()
  1364. {
  1365. V_VT(this) = VT_UNKNOWN;
  1366. V_UNKNOWN(this) = pSrc;
  1367. // Need the AddRef() as VariantClear() calls Release(), unless fAddRef
  1368. // false indicates we're taking ownership
  1369. //
  1370. if (fAddRef) {
  1371. V_UNKNOWN(this)->AddRef();
  1372. }
  1373. }
  1374. // Construct a VT_DECIMAL VARIANT from a DECIMAL
  1375. //
  1376. inline auto_var::auto_var(const DECIMAL& decSrc) throw()
  1377. {
  1378. // Order is important here! Setting V_DECIMAL wipes out the entire VARIANT
  1379. //
  1380. V_DECIMAL(this) = decSrc;
  1381. V_VT(this) = VT_DECIMAL;
  1382. }
  1383. // Construct a VT_UI1 VARIANT from a BYTE (unsigned char)
  1384. //
  1385. inline auto_var::auto_var(BYTE bSrc) throw()
  1386. {
  1387. V_VT(this) = VT_UI1;
  1388. V_UI1(this) = bSrc;
  1389. }
  1390. //////////////////////////////////////////////////////////////////////////////////////////
  1391. //
  1392. // Extractors
  1393. //
  1394. //////////////////////////////////////////////////////////////////////////////////////////
  1395. // Extracts a VT_I2 into a short
  1396. //
  1397. inline auto_var::operator short() const throw(_com_error)
  1398. {
  1399. if (V_VT(this) == VT_I2) {
  1400. return V_I2(this);
  1401. }
  1402. auto_var varDest;
  1403. varDest.ChangeType(VT_I2, this);
  1404. return V_I2(&varDest);
  1405. }
  1406. // Extracts a VT_I4 into a long
  1407. //
  1408. inline auto_var::operator long() const throw(_com_error)
  1409. {
  1410. if (V_VT(this) == VT_I4) {
  1411. return V_I4(this);
  1412. }
  1413. auto_var varDest;
  1414. varDest.ChangeType(VT_I4, this);
  1415. return V_I4(&varDest);
  1416. }
  1417. // Extracts a VT_R4 into a float
  1418. //
  1419. inline auto_var::operator float() const throw(_com_error)
  1420. {
  1421. if (V_VT(this) == VT_R4) {
  1422. return V_R4(this);
  1423. }
  1424. auto_var varDest;
  1425. varDest.ChangeType(VT_R4, this);
  1426. return V_R4(&varDest);
  1427. }
  1428. // Extracts a VT_R8 into a double
  1429. //
  1430. inline auto_var::operator double() const throw(_com_error)
  1431. {
  1432. if (V_VT(this) == VT_R8) {
  1433. return V_R8(this);
  1434. }
  1435. auto_var varDest;
  1436. varDest.ChangeType(VT_R8, this);
  1437. return V_R8(&varDest);
  1438. }
  1439. // Extracts a VT_CY into a CY
  1440. //
  1441. inline auto_var::operator CY() const throw(_com_error)
  1442. {
  1443. if (V_VT(this) == VT_CY) {
  1444. return V_CY(this);
  1445. }
  1446. auto_var varDest;
  1447. varDest.ChangeType(VT_CY, this);
  1448. return V_CY(&varDest);
  1449. }
  1450. // Extracts a VT_BSTR into a _bstr_t
  1451. //
  1452. inline auto_var::operator _bstr_t() const throw(_com_error)
  1453. {
  1454. if (V_VT(this) == VT_BSTR) {
  1455. return V_BSTR(this);
  1456. }
  1457. auto_var varDest;
  1458. varDest.ChangeType(VT_BSTR, this);
  1459. return V_BSTR(&varDest);
  1460. }
  1461. // Extracts a VT_DISPATCH into an IDispatch*
  1462. //
  1463. inline auto_var::operator IDispatch*() const throw(_com_error)
  1464. {
  1465. if (V_VT(this) == VT_DISPATCH) {
  1466. V_DISPATCH(this)->AddRef();
  1467. return V_DISPATCH(this);
  1468. }
  1469. auto_var varDest;
  1470. varDest.ChangeType(VT_DISPATCH, this);
  1471. V_DISPATCH(&varDest)->AddRef();
  1472. return V_DISPATCH(&varDest);
  1473. }
  1474. // Extract a VT_BOOL into a bool
  1475. //
  1476. inline auto_var::operator bool() const throw(_com_error)
  1477. {
  1478. if (V_VT(this) == VT_BOOL) {
  1479. return V_BOOL(this) ? true : false;
  1480. }
  1481. auto_var varDest;
  1482. varDest.ChangeType(VT_BOOL, this);
  1483. return V_BOOL(&varDest) ? true : false;
  1484. }
  1485. // Extracts a VT_UNKNOWN into an IUnknown*
  1486. //
  1487. inline auto_var::operator IUnknown*() const throw(_com_error)
  1488. {
  1489. if (V_VT(this) == VT_UNKNOWN) {
  1490. return V_UNKNOWN(this);
  1491. }
  1492. auto_var varDest;
  1493. varDest.ChangeType(VT_UNKNOWN, this);
  1494. return V_UNKNOWN(&varDest);
  1495. }
  1496. // Extracts a VT_DECIMAL into a DECIMAL
  1497. //
  1498. inline auto_var::operator DECIMAL() const throw(_com_error)
  1499. {
  1500. if (V_VT(this) == VT_DECIMAL) {
  1501. return V_DECIMAL(this);
  1502. }
  1503. auto_var varDest;
  1504. varDest.ChangeType(VT_DECIMAL, this);
  1505. return V_DECIMAL(&varDest);
  1506. }
  1507. // Extracts a VT_UI1 into a BYTE (unsigned char)
  1508. //
  1509. inline auto_var::operator BYTE() const throw(_com_error)
  1510. {
  1511. if (V_VT(this) == VT_UI1) {
  1512. return V_UI1(this);
  1513. }
  1514. auto_var varDest;
  1515. varDest.ChangeType(VT_UI1, this);
  1516. return V_UI1(&varDest);
  1517. }
  1518. //////////////////////////////////////////////////////////////////////////////////////////
  1519. //
  1520. // Assignment operations
  1521. //
  1522. //////////////////////////////////////////////////////////////////////////////////////////
  1523. // Assign a const VARIANT& (::VariantCopy handles everything)
  1524. //
  1525. inline auto_var& auto_var::operator=(const VARIANT& varSrc) throw(_com_error)
  1526. {
  1527. Clear();
  1528. _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(&varSrc)));
  1529. return *this;
  1530. }
  1531. // Assign a const VARIANT* (::VariantCopy handles everything)
  1532. //
  1533. inline auto_var& auto_var::operator=(const VARIANT* pSrc) throw(_com_error)
  1534. {
  1535. Clear();
  1536. _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(pSrc)));
  1537. return *this;
  1538. }
  1539. // Assign a const auto_var& (::VariantCopy handles everything)
  1540. //
  1541. inline auto_var& auto_var::operator=(const auto_var& varSrc) throw(_com_error)
  1542. {
  1543. Clear();
  1544. _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
  1545. return *this;
  1546. }
  1547. // Assign a short creating either VT_I2 VARIANT or a
  1548. // VT_BOOL VARIANT (VT_I2 is the default)
  1549. //
  1550. inline auto_var& auto_var::operator=(short sSrc) throw(_com_error)
  1551. {
  1552. if (V_VT(this) == VT_I2) {
  1553. V_I2(this) = sSrc;
  1554. }
  1555. else if (V_VT(this) == VT_BOOL) {
  1556. V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1557. }
  1558. else {
  1559. // Clear the VARIANT and create a VT_I2
  1560. //
  1561. Clear();
  1562. V_VT(this) = VT_I2;
  1563. V_I2(this) = sSrc;
  1564. }
  1565. return *this;
  1566. }
  1567. // Assign a long creating either VT_I4 VARIANT, a VT_ERROR VARIANT
  1568. // or a VT_BOOL VARIANT (VT_I4 is the default)
  1569. //
  1570. inline auto_var& auto_var::operator=(long lSrc) throw(_com_error)
  1571. {
  1572. if (V_VT(this) == VT_I4) {
  1573. V_I4(this) = lSrc;
  1574. }
  1575. else if (V_VT(this) == VT_ERROR) {
  1576. V_ERROR(this) = lSrc;
  1577. }
  1578. else if (V_VT(this) == VT_BOOL) {
  1579. V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1580. }
  1581. else {
  1582. // Clear the VARIANT and create a VT_I4
  1583. //
  1584. Clear();
  1585. V_VT(this) = VT_I4;
  1586. V_I4(this) = lSrc;
  1587. }
  1588. return *this;
  1589. }
  1590. // Assign a float creating a VT_R4 VARIANT
  1591. //
  1592. inline auto_var& auto_var::operator=(float fltSrc) throw(_com_error)
  1593. {
  1594. if (V_VT(this) != VT_R4) {
  1595. // Clear the VARIANT and create a VT_R4
  1596. //
  1597. Clear();
  1598. V_VT(this) = VT_R4;
  1599. }
  1600. V_R4(this) = fltSrc;
  1601. return *this;
  1602. }
  1603. // Assign a double creating either a VT_R8 VARIANT, or a VT_DATE
  1604. // VARIANT (VT_R8 is the default)
  1605. //
  1606. inline auto_var& auto_var::operator=(double dblSrc) throw(_com_error)
  1607. {
  1608. if (V_VT(this) == VT_R8) {
  1609. V_R8(this) = dblSrc;
  1610. }
  1611. else if(V_VT(this) == VT_DATE) {
  1612. V_DATE(this) = dblSrc;
  1613. }
  1614. else {
  1615. // Clear the VARIANT and create a VT_R8
  1616. //
  1617. Clear();
  1618. V_VT(this) = VT_R8;
  1619. V_R8(this) = dblSrc;
  1620. }
  1621. return *this;
  1622. }
  1623. // Assign a CY creating a VT_CY VARIANT
  1624. //
  1625. inline auto_var& auto_var::operator=(const CY& cySrc) throw(_com_error)
  1626. {
  1627. if (V_VT(this) != VT_CY) {
  1628. // Clear the VARIANT and create a VT_CY
  1629. //
  1630. Clear();
  1631. V_VT(this) = VT_CY;
  1632. }
  1633. V_CY(this) = cySrc;
  1634. return *this;
  1635. }
  1636. // Assign a const _bstr_t& creating a VT_BSTR VARIANT
  1637. //
  1638. inline auto_var& auto_var::operator=(const _bstr_t& bstrSrc) throw(_com_error)
  1639. {
  1640. // Clear the VARIANT (This will SysFreeString() any previous occupant)
  1641. //
  1642. Clear();
  1643. V_VT(this) = VT_BSTR;
  1644. if (!bstrSrc) {
  1645. V_BSTR(this) = NULL;
  1646. }
  1647. else {
  1648. BSTR bstr = static_cast<wchar_t*>(bstrSrc);
  1649. V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char*>(bstr),
  1650. ::SysStringByteLen(bstr));
  1651. if (V_BSTR(this) == NULL) {
  1652. _com_issue_error(E_OUTOFMEMORY);
  1653. }
  1654. }
  1655. return *this;
  1656. }
  1657. // Assign a const wchar_t* creating a VT_BSTR VARIANT
  1658. //
  1659. inline auto_var& auto_var::operator=(const wchar_t* pSrc) throw(_com_error)
  1660. {
  1661. // Clear the VARIANT (This will SysFreeString() any previous occupant)
  1662. //
  1663. Clear();
  1664. V_VT(this) = VT_BSTR;
  1665. if (pSrc == NULL) {
  1666. V_BSTR(this) = NULL;
  1667. }
  1668. else {
  1669. V_BSTR(this) = ::SysAllocString(pSrc);
  1670. if (V_BSTR(this) == NULL) {
  1671. _com_issue_error(E_OUTOFMEMORY);
  1672. }
  1673. }
  1674. return *this;
  1675. }
  1676. // Assign a const char* creating a VT_BSTR VARIANT
  1677. //
  1678. inline auto_var& auto_var::operator=(const char* pSrc) throw(_com_error)
  1679. {
  1680. // Clear the VARIANT (This will SysFreeString() any previous occupant)
  1681. //
  1682. Clear();
  1683. V_VT(this) = VT_BSTR;
  1684. V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
  1685. if (V_BSTR(this) == NULL && pSrc != NULL) {
  1686. _com_issue_error(E_OUTOFMEMORY);
  1687. }
  1688. return *this;
  1689. }
  1690. // Assign an IDispatch* creating a VT_DISPATCH VARIANT
  1691. //
  1692. inline auto_var& auto_var::operator=(IDispatch* pSrc) throw(_com_error)
  1693. {
  1694. // Clear the VARIANT (This will Release() any previous occupant)
  1695. //
  1696. Clear();
  1697. V_VT(this) = VT_DISPATCH;
  1698. V_DISPATCH(this) = pSrc;
  1699. // Need the AddRef() as VariantClear() calls Release()
  1700. //
  1701. V_DISPATCH(this)->AddRef();
  1702. return *this;
  1703. }
  1704. // Assign a bool creating a VT_BOOL VARIANT
  1705. //
  1706. inline auto_var& auto_var::operator=(bool bSrc) throw(_com_error)
  1707. {
  1708. if (V_VT(this) != VT_BOOL) {
  1709. // Clear the VARIANT and create a VT_BOOL
  1710. //
  1711. Clear();
  1712. V_VT(this) = VT_BOOL;
  1713. }
  1714. V_BOOL(this) = (bSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1715. return *this;
  1716. }
  1717. // Assign an IUnknown* creating a VT_UNKNOWN VARIANT
  1718. //
  1719. inline auto_var& auto_var::operator=(IUnknown* pSrc) throw(_com_error)
  1720. {
  1721. // Clear VARIANT (This will Release() any previous occupant)
  1722. //
  1723. Clear();
  1724. V_VT(this) = VT_UNKNOWN;
  1725. V_UNKNOWN(this) = pSrc;
  1726. // Need the AddRef() as VariantClear() calls Release()
  1727. //
  1728. V_UNKNOWN(this)->AddRef();
  1729. return *this;
  1730. }
  1731. // Assign a DECIMAL creating a VT_DECIMAL VARIANT
  1732. //
  1733. inline auto_var& auto_var::operator=(const DECIMAL& decSrc) throw(_com_error)
  1734. {
  1735. if (V_VT(this) != VT_DECIMAL) {
  1736. // Clear the VARIANT
  1737. //
  1738. Clear();
  1739. }
  1740. // Order is important here! Setting V_DECIMAL wipes out the entire VARIANT
  1741. V_DECIMAL(this) = decSrc;
  1742. V_VT(this) = VT_DECIMAL;
  1743. return *this;
  1744. }
  1745. // Assign a BTYE (unsigned char) creating a VT_UI1 VARIANT
  1746. //
  1747. inline auto_var& auto_var::operator=(BYTE bSrc) throw(_com_error)
  1748. {
  1749. if (V_VT(this) != VT_UI1) {
  1750. // Clear the VARIANT and create a VT_UI1
  1751. //
  1752. Clear();
  1753. V_VT(this) = VT_UI1;
  1754. }
  1755. V_UI1(this) = bSrc;
  1756. return *this;
  1757. }
  1758. //////////////////////////////////////////////////////////////////////////////////////////
  1759. //
  1760. // Comparison operations
  1761. //
  1762. //////////////////////////////////////////////////////////////////////////////////////////
  1763. // Compare a auto_var against a const VARIANT& for equality
  1764. //
  1765. inline bool auto_var::operator==(const VARIANT& varSrc) const throw()
  1766. {
  1767. return *this == &varSrc;
  1768. }
  1769. // Compare a auto_var against a const VARIANT* for equality
  1770. //
  1771. inline bool auto_var::operator==(const VARIANT* pSrc) const throw()
  1772. {
  1773. if (this == pSrc) {
  1774. return true;
  1775. }
  1776. //
  1777. // Variants not equal if types don't match
  1778. //
  1779. if (V_VT(this) != V_VT(pSrc)) {
  1780. return false;
  1781. }
  1782. //
  1783. // Check type specific values
  1784. //
  1785. switch (V_VT(this)) {
  1786. case VT_EMPTY:
  1787. case VT_NULL:
  1788. return true;
  1789. case VT_I2:
  1790. return V_I2(this) == V_I2(pSrc);
  1791. case VT_I4:
  1792. return V_I4(this) == V_I4(pSrc);
  1793. case VT_R4:
  1794. return V_R4(this) == V_R4(pSrc);
  1795. case VT_R8:
  1796. return V_R8(this) == V_R8(pSrc);
  1797. case VT_CY:
  1798. return memcmp(&(V_CY(this)), &(V_CY(pSrc)), sizeof(CY)) == 0;
  1799. case VT_DATE:
  1800. return V_DATE(this) == V_DATE(pSrc);
  1801. case VT_BSTR:
  1802. return (::SysStringByteLen(V_BSTR(this)) == ::SysStringByteLen(V_BSTR(pSrc))) &&
  1803. (memcmp(V_BSTR(this), V_BSTR(pSrc), ::SysStringByteLen(V_BSTR(this))) == 0);
  1804. case VT_DISPATCH:
  1805. return V_DISPATCH(this) == V_DISPATCH(pSrc);
  1806. case VT_ERROR:
  1807. return V_ERROR(this) == V_ERROR(pSrc);
  1808. case VT_BOOL:
  1809. return V_BOOL(this) == V_BOOL(pSrc);
  1810. case VT_UNKNOWN:
  1811. return V_UNKNOWN(this) == V_UNKNOWN(pSrc);
  1812. case VT_DECIMAL:
  1813. return memcmp(&(V_DECIMAL(this)), &(V_DECIMAL(pSrc)), sizeof(DECIMAL)) == 0;
  1814. case VT_UI1:
  1815. return V_UI1(this) == V_UI1(pSrc);
  1816. default:
  1817. _com_issue_error(E_INVALIDARG);
  1818. // fall through
  1819. }
  1820. return false;
  1821. }
  1822. // Compare a auto_var against a const VARIANT& for in-equality
  1823. //
  1824. inline bool auto_var::operator!=(const VARIANT& varSrc) const throw()
  1825. {
  1826. return !(*this == &varSrc);
  1827. }
  1828. // Compare a auto_var against a const VARIANT* for in-equality
  1829. //
  1830. inline bool auto_var::operator!=(const VARIANT* pSrc) const throw()
  1831. {
  1832. return !(*this == pSrc);
  1833. }
  1834. //////////////////////////////////////////////////////////////////////////////////////////
  1835. //
  1836. // Low-level operations
  1837. //
  1838. //////////////////////////////////////////////////////////////////////////////////////////
  1839. // Clear the auto_var
  1840. //
  1841. inline void auto_var::Clear() throw(_com_error)
  1842. {
  1843. _com_util::CheckError(::VariantClear(this));
  1844. }
  1845. inline void auto_var::Attach(VARIANT& varSrc) throw(_com_error)
  1846. {
  1847. //
  1848. // Free up previous VARIANT
  1849. //
  1850. Clear();
  1851. //
  1852. // Give control of data to auto_var
  1853. //
  1854. memcpy(this, &varSrc, sizeof(varSrc));
  1855. V_VT(&varSrc) = VT_EMPTY;
  1856. }
  1857. inline VARIANT auto_var::Detach() throw(_com_error)
  1858. {
  1859. VARIANT varResult = *this;
  1860. V_VT(this) = VT_EMPTY;
  1861. return varResult;
  1862. }
  1863. // Change the type and contents of this auto_var to the type vartype and
  1864. // contents of pSrc
  1865. //
  1866. inline void auto_var::ChangeType(VARTYPE vartype, const auto_var* pSrc) throw(_com_error)
  1867. {
  1868. //
  1869. // If pDest is NULL, convert type in place
  1870. //
  1871. if (pSrc == NULL) {
  1872. pSrc = this;
  1873. }
  1874. if ((this != pSrc) || (vartype != V_VT(this))) {
  1875. _com_util::CheckError(::VariantChangeType(static_cast<VARIANT*>(this),
  1876. const_cast<VARIANT*>(static_cast<const VARIANT*>(pSrc)),
  1877. 0, vartype));
  1878. }
  1879. }
  1880. inline void auto_var::SetString(const char* pSrc) throw(_com_error)
  1881. {
  1882. //
  1883. // Free up previous VARIANT
  1884. //
  1885. Clear();
  1886. V_VT(this) = VT_BSTR;
  1887. V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
  1888. if (V_BSTR(this) == NULL && pSrc != NULL) {
  1889. _com_issue_error(E_OUTOFMEMORY);
  1890. }
  1891. }
  1892. inline auto_var::~auto_var() throw(_com_error)
  1893. {
  1894. _com_util::CheckError(::VariantClear(this));
  1895. }
  1896. #endif // __wtypes_h__
  1897. // auto_internet **************************************************************
  1898. //
  1899. // Smart Pointers for HINTERNET
  1900. #ifdef _WININET_
  1901. class auto_internet
  1902. {
  1903. public:
  1904. explicit auto_internet(HINTERNET p = 0)
  1905. : m_p(p) {};
  1906. auto_internet(auto_internet& rhs)
  1907. : m_p(rhs.release()) {};
  1908. ~auto_internet()
  1909. { reset(); };
  1910. auto_internet& operator= (auto_internet& rhs)
  1911. { if (this != rhs.getThis())
  1912. reset (rhs.release() );
  1913. return *this;
  1914. };
  1915. auto_internet& operator= (HINTERNET rhs)
  1916. {
  1917. reset (rhs);
  1918. return *this;
  1919. };
  1920. // HINTERNET operator*() const
  1921. // { return m_p; };
  1922. // void** operator& ()
  1923. // { reset(); return (void**)&m_p; };
  1924. operator HINTERNET ()
  1925. { return m_p; };
  1926. // Checks for NULL
  1927. BOOL operator== (LPVOID lpv)
  1928. { return m_p == lpv; };
  1929. BOOL operator!= (LPVOID lpv)
  1930. { return m_p != lpv; };
  1931. // return value of current dumb pointer
  1932. HINTERNET get() const
  1933. { return m_p; };
  1934. // relinquish ownership
  1935. HINTERNET release()
  1936. { HINTERNET oldp = m_p;
  1937. m_p = 0;
  1938. return oldp;
  1939. };
  1940. // delete owned pointer; assume ownership of p
  1941. void reset (HINTERNET p = 0)
  1942. {
  1943. if (m_p)
  1944. InternetCloseHandle(m_p);
  1945. m_p = p;
  1946. };
  1947. private:
  1948. // operator& throws off operator=
  1949. const auto_internet* getThis() const
  1950. { return this; };
  1951. HINTERNET m_p;
  1952. };
  1953. #endif // _WININET_
  1954. // auto_virt ******************************************************************
  1955. //
  1956. // Smart Pointers for memory freed with VirtualFree
  1957. #ifdef _WINBASE_
  1958. template<class _Ty>
  1959. class auto_virt
  1960. {
  1961. public:
  1962. typedef _Ty element_type;
  1963. explicit auto_virt(_Ty *_P = 0) _THROW0()
  1964. : _Owns(_P != 0), _Ptr(_P) {}
  1965. auto_virt(const auto_virt<_Ty>& _Y) _THROW0()
  1966. : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
  1967. auto_virt<_Ty>& operator=(const auto_virt<_Ty>& _Y) _THROW0()
  1968. {if (_Ptr != _Y.get())
  1969. {if (_Owns && _Ptr)
  1970. VirtualFree(_Ptr);
  1971. _Owns = _Y._Owns;
  1972. _Ptr = _Y.release(); }
  1973. else if (_Y._Owns)
  1974. _Owns = true;
  1975. return (*this); }
  1976. auto_virt<_Ty>& operator=(_Ty* _Y) _THROW0()
  1977. { {if (_Owns && _Ptr)
  1978. VirtualFree(_Ptr,0,MEM_RELEASE);
  1979. _Owns = _Y != 0;
  1980. _Ptr = _Y; }
  1981. return (*this); }
  1982. ~auto_virt()
  1983. {if (_Owns && _Ptr)
  1984. VirtualFree(_Ptr,0,MEM_RELEASE);}
  1985. _Ty** operator&() _THROW0()
  1986. {if (_Owns && _Ptr)
  1987. VirtualFree(_Ptr,0,MEM_RELEASE);
  1988. _Owns = true;
  1989. _Ptr = 0;
  1990. return &_Ptr;
  1991. }
  1992. operator _Ty* () const
  1993. { return _Ptr; }
  1994. _Ty& operator*() const _THROW0()
  1995. {return (*get()); }
  1996. _Ty *operator->() const _THROW0()
  1997. {return (get()); }
  1998. _Ty& operator[] (int ndx) const _THROW0()
  1999. {return *(get() + ndx); }
  2000. _Ty *get() const _THROW0()
  2001. {return (_Ptr); }
  2002. _Ty *release() const _THROW0()
  2003. {((auto_virt<_Ty> *)this)->_Owns = false;
  2004. return (_Ptr); }
  2005. bool Ownership(bool fOwns)
  2006. { return _Owns = fOwns; }
  2007. protected:
  2008. bool _Owns;
  2009. _Ty *_Ptr;
  2010. };
  2011. #endif // _WINBASE_
  2012. // RCObject *******************************************************************
  2013. //
  2014. // Smart objects for reference counting
  2015. class RCObject
  2016. {
  2017. public:
  2018. void addReference()
  2019. {
  2020. ++refCount;
  2021. }
  2022. void removeReference()
  2023. {
  2024. if (--refCount == 0)
  2025. delete this;
  2026. }
  2027. void markUnshareable()
  2028. {
  2029. shareable = FALSE;
  2030. }
  2031. BOOL isShareable() const
  2032. {
  2033. return shareable;
  2034. }
  2035. BOOL isShared() const
  2036. {
  2037. return refCount > 1;
  2038. }
  2039. protected:
  2040. RCObject()
  2041. : refCount(0), shareable(TRUE) {};
  2042. RCObject(const RCObject& rhs)
  2043. : refCount(0), shareable(TRUE) {};
  2044. RCObject& operator= (const RCObject& rhs)
  2045. {
  2046. return *this;
  2047. }
  2048. virtual ~RCObject() {};
  2049. private:
  2050. int refCount;
  2051. BOOL shareable;
  2052. };
  2053. // RCPtr **********************************************************************
  2054. //
  2055. // Smart Pointers for reference counting, use w/ RCObject
  2056. template<class T>
  2057. class RCPtr
  2058. {
  2059. public:
  2060. RCPtr(T* realPtr = 0);
  2061. RCPtr(const RCPtr&rhs);
  2062. ~RCPtr();
  2063. RCPtr& operator=(const RCPtr& rhs);
  2064. BOOL operator==(const RCPtr&rhs) const;
  2065. BOOL operator< (const RCPtr&rhs) const;
  2066. BOOL operator> (const RCPtr&rhs) const;
  2067. operator bool(void) const;
  2068. T* operator->() const;
  2069. T& operator*() const;
  2070. T* get(void) const;
  2071. protected:
  2072. T* pointee;
  2073. void init();
  2074. };
  2075. template<class T>
  2076. void RCPtr<T>::init ()
  2077. {
  2078. if (pointee == 0)
  2079. return;
  2080. if (pointee->isShareable() == FALSE)
  2081. {
  2082. pointee = new T(*pointee);
  2083. }
  2084. pointee->addReference();
  2085. }
  2086. template<class T>
  2087. RCPtr<T>::RCPtr (T* realPtr)
  2088. : pointee(realPtr)
  2089. {
  2090. init();
  2091. }
  2092. template<class T>
  2093. RCPtr<T>::RCPtr (const RCPtr& rhs)
  2094. : pointee(rhs.pointee)
  2095. {
  2096. init();
  2097. }
  2098. template<class T>
  2099. RCPtr<T>::~RCPtr()
  2100. {
  2101. if (pointee)
  2102. pointee->removeReference();
  2103. }
  2104. template<class T>
  2105. RCPtr<T>& RCPtr<T>::operator= (const RCPtr<T>& rhs)
  2106. {
  2107. if (pointee != rhs.pointee)
  2108. {
  2109. if (pointee)
  2110. pointee->removeReference();
  2111. pointee = rhs.pointee;
  2112. init();
  2113. }
  2114. return *this;
  2115. }
  2116. template<class T>
  2117. BOOL RCPtr<T>::operator==(const RCPtr&rhs) const
  2118. { return pointee == rhs.pointee; }
  2119. template<class T>
  2120. BOOL RCPtr<T>::operator< (const RCPtr&rhs) const
  2121. { return pointee < rhs.pointee; }
  2122. template<class T>
  2123. BOOL RCPtr<T>::operator> (const RCPtr&rhs) const
  2124. { return pointee > rhs.pointee; }
  2125. template<class T>
  2126. T* RCPtr<T>::operator->() const
  2127. {
  2128. return pointee;
  2129. }
  2130. template<class T>
  2131. T& RCPtr<T>::operator*() const
  2132. {
  2133. return *pointee;
  2134. }
  2135. template<class T>
  2136. RCPtr<T>::operator bool(void) const
  2137. {
  2138. return pointee != NULL;
  2139. }
  2140. template<class T>
  2141. T* RCPtr<T>::get(void) const
  2142. {
  2143. return pointee;
  2144. }
  2145. // auto_menu ******************************************************************
  2146. //
  2147. // Smart Pointers for DestroyMenu
  2148. // auto_reg *******************************************************************
  2149. //
  2150. // Smart pointer for HKEY's
  2151. class auto_menu
  2152. {
  2153. public:
  2154. auto_menu(HMENU p = 0)
  2155. : h(p) {};
  2156. auto_menu(auto_menu& rhs)
  2157. : h(rhs.release()) {};
  2158. ~auto_menu()
  2159. { if (h) DestroyMenu(h); };
  2160. auto_menu& operator= (auto_menu& rhs)
  2161. { if (this != rhs.getThis())
  2162. reset (rhs.release() );
  2163. return *this;
  2164. };
  2165. auto_menu& operator= (HMENU rhs)
  2166. { if ((NULL == rhs) || (INVALID_HANDLE_VALUE == rhs))
  2167. { // be sure and go through auto_os for dbg.lib
  2168. auto_os os;
  2169. os = (BOOL)FALSE;
  2170. }
  2171. reset (rhs);
  2172. return *this;
  2173. };
  2174. HMENU* operator& ()
  2175. { reset(); return &h; };
  2176. operator HMENU ()
  2177. { return h; };
  2178. // Checks for NULL
  2179. bool operator== (LPVOID lpv)
  2180. { return h == lpv; };
  2181. bool operator!= (LPVOID lpv)
  2182. { return h != lpv; };
  2183. // return value of current dumb pointer
  2184. HMENU get() const
  2185. { return h; };
  2186. // relinquish ownership
  2187. HMENU release()
  2188. { HMENU oldh = h;
  2189. h = 0;
  2190. return oldh;
  2191. };
  2192. // delete owned pointer; assume ownership of p
  2193. BOOL reset (HMENU p = 0)
  2194. {
  2195. BOOL rt = TRUE;
  2196. if (h)
  2197. rt = DestroyMenu(h);
  2198. h = p;
  2199. return rt;
  2200. };
  2201. private:
  2202. // operator& throws off operator=
  2203. const auto_menu* getThis() const
  2204. { return this; };
  2205. HMENU h;
  2206. };