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.

749 lines
12 KiB

  1. //*************************************************************
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998
  5. //
  6. // File: smartptr.h
  7. //
  8. // Contents: Classes for smart pointers
  9. //
  10. // History: 7-Jun-99 SitaramR Created
  11. //
  12. // 2-Dec-99 LeonardM Major revision and cleanup.
  13. //
  14. //*************************************************************
  15. #ifndef SMARTPTR_H
  16. #define SMARTPTR_H
  17. #include <comdef.h>
  18. #include "userenv.h"
  19. #pragma once
  20. #pragma warning(disable:4284)
  21. //*************************************************************
  22. //
  23. // Class: XPtrST
  24. //
  25. // Purpose: Smart pointer template to wrap pointers to a single type.
  26. //
  27. //*************************************************************
  28. template<class T> class XPtrST
  29. {
  30. private:
  31. XPtrST (const XPtrST<T>& x);
  32. XPtrST<T>& operator=(const XPtrST<T>& x);
  33. T* _p;
  34. public:
  35. XPtrST(T* p = NULL) : _p(p){}
  36. ~XPtrST(){ delete _p; }
  37. T* operator->(){ return _p; }
  38. T** operator&(){ return &_p; }
  39. operator T*(){ return _p; }
  40. void operator=(T* p)
  41. {
  42. if(_p)
  43. {
  44. delete _p;
  45. }
  46. _p = p;
  47. }
  48. T* Acquire()
  49. {
  50. T* p = _p;
  51. _p = 0;
  52. return p;
  53. }
  54. };
  55. //*************************************************************
  56. //
  57. // Class: XPtrArray
  58. //
  59. // Purpose: Smart pointer template to wrap pointers to an array .
  60. //
  61. //*************************************************************
  62. template<class T> class XPtrArray
  63. {
  64. private:
  65. XPtrArray (const XPtrArray<T>& x);
  66. XPtrArray<T>& operator=(const XPtrArray<T>& x);
  67. T* _p;
  68. public:
  69. XPtrArray(T* p = NULL) : _p(p){}
  70. ~XPtrArray(){ delete[] _p; }
  71. T* operator->(){ return _p; }
  72. T** operator&(){ return &_p; }
  73. operator T*(){ return _p; }
  74. void operator=(T* p)
  75. {
  76. if(_p)
  77. {
  78. delete[] _p;
  79. }
  80. _p = p;
  81. }
  82. T* Acquire()
  83. {
  84. T* p = _p;
  85. _p = 0;
  86. return p;
  87. }
  88. };
  89. //*************************************************************
  90. //
  91. // Class: XInterface
  92. //
  93. // Purpose: Smart pointer template for items Release()'ed, not ~'ed
  94. //
  95. //*************************************************************
  96. template<class T> class XInterface
  97. {
  98. private:
  99. XInterface(const XInterface<T>& x);
  100. XInterface<T>& operator=(const XInterface<T>& x);
  101. T* _p;
  102. public:
  103. XInterface(T* p = NULL) : _p(p){}
  104. ~XInterface()
  105. {
  106. if (_p)
  107. {
  108. _p->Release();
  109. }
  110. }
  111. T* operator->(){ return _p; }
  112. T** operator&(){ return &_p; }
  113. operator T*(){ return _p; }
  114. void operator=(T* p)
  115. {
  116. if (_p)
  117. {
  118. _p->Release();
  119. }
  120. _p = p;
  121. }
  122. T* Acquire()
  123. {
  124. T* p = _p;
  125. _p = 0;
  126. return p;
  127. }
  128. };
  129. //*************************************************************
  130. //
  131. // Class: XBStr
  132. //
  133. // Purpose: Smart pointer class for BSTRs
  134. //
  135. //*************************************************************
  136. class XBStr
  137. {
  138. private:
  139. XBStr(const XBStr& x);
  140. XBStr& operator=(const XBStr& x);
  141. BSTR _p;
  142. public:
  143. XBStr(WCHAR* p = 0) : _p(0)
  144. {
  145. if(p)
  146. {
  147. _p = SysAllocString(p);
  148. }
  149. }
  150. ~XBStr()
  151. {
  152. SysFreeString(_p);
  153. }
  154. operator BSTR(){ return _p; }
  155. void operator=(WCHAR* p)
  156. {
  157. SysFreeString(_p);
  158. _p = p ? SysAllocString(p) : NULL;
  159. }
  160. BSTR Acquire()
  161. {
  162. BSTR p = _p;
  163. _p = 0;
  164. return p;
  165. }
  166. };
  167. //*************************************************************
  168. //
  169. // Class: XSafeArray
  170. //
  171. // Purpose: Smart pointer class for SafeArrays
  172. //
  173. //*************************************************************
  174. class XSafeArray
  175. {
  176. private:
  177. XSafeArray(const XSafeArray& x);
  178. XSafeArray& operator=(const XSafeArray& x);
  179. SAFEARRAY* _p;
  180. public:
  181. XSafeArray(SAFEARRAY* p = 0) : _p(p){}
  182. ~XSafeArray()
  183. {
  184. if (_p)
  185. {
  186. SafeArrayDestroy(_p);
  187. }
  188. }
  189. operator SAFEARRAY*(){ return _p; }
  190. SAFEARRAY ** operator&(){ return &_p; }
  191. void operator=(SAFEARRAY* p)
  192. {
  193. if(_p)
  194. {
  195. SafeArrayDestroy(_p);
  196. }
  197. _p = p;
  198. }
  199. SAFEARRAY* Acquire()
  200. {
  201. SAFEARRAY* p = _p;
  202. _p = 0;
  203. return p;
  204. }
  205. };
  206. //*************************************************************
  207. //
  208. // Class: XVariant
  209. //
  210. // Purpose: Smart pointer class for Variants
  211. //
  212. //*************************************************************
  213. class XVariant
  214. {
  215. private:
  216. XVariant(const XVariant& x);
  217. XVariant& operator=(const XVariant& x);
  218. VARIANT* _p;
  219. public:
  220. XVariant(VARIANT* p = 0) : _p(p){}
  221. ~XVariant()
  222. {
  223. if (_p)
  224. {
  225. VariantClear(_p);
  226. }
  227. }
  228. void operator=(VARIANT* p)
  229. {
  230. if(_p)
  231. {
  232. VariantClear(_p);
  233. }
  234. _p = p;
  235. }
  236. operator VARIANT*(){ return _p; }
  237. VARIANT* Acquire()
  238. {
  239. VARIANT* p = _p;
  240. _p = 0;
  241. return p;
  242. }
  243. };
  244. //*************************************************************
  245. //
  246. // Class: XPtrLF
  247. //
  248. // Purpose: Smart pointer template for pointers that should be LocalFree()'d
  249. //
  250. //*************************************************************
  251. template <typename T> class XPtrLF
  252. {
  253. private:
  254. XPtrLF(const XPtrLF<T>& x);
  255. XPtrLF<T>& operator=(const XPtrLF<T>& x);
  256. T* _p;
  257. public:
  258. XPtrLF(HLOCAL p = 0 ) :
  259. _p((T*)p)
  260. {
  261. }
  262. ~XPtrLF()
  263. {
  264. if(_p)
  265. {
  266. LocalFree(_p);
  267. }
  268. }
  269. T* operator->(){ return _p; }
  270. T** operator&(){ return &_p; }
  271. operator T*(){ return _p; }
  272. void operator=(T* p)
  273. {
  274. if(_p)
  275. {
  276. LocalFree(_p);
  277. }
  278. _p = p;
  279. }
  280. T* Acquire()
  281. {
  282. T* p = _p;
  283. _p = NULL;
  284. return p;
  285. }
  286. };
  287. //*************************************************************
  288. //
  289. // Class: XPtr
  290. //
  291. // Purpose: Smart pointer template for pointers that provide
  292. // a custom free memory routine
  293. //
  294. //*************************************************************
  295. typedef HLOCAL (__stdcall *PFNFREE)(HLOCAL);
  296. //
  297. // usage : XPtr<SID, FreeSid> xptrSid;
  298. //
  299. template <typename T, PFNFREE _f> class XPtr
  300. {
  301. private:
  302. XPtr(const XPtr<T, _f>& x);
  303. XPtr<T, _f>& operator=(const XPtr<T, _f>& x);
  304. T* _p;
  305. public:
  306. XPtr( HLOCAL p = 0 ) :
  307. _p( reinterpret_cast<T*>( p ) )
  308. {
  309. }
  310. ~XPtr()
  311. {
  312. if(_p)
  313. {
  314. _f(_p);
  315. }
  316. }
  317. T* operator->(){ return _p; }
  318. T** operator&(){ return &_p; }
  319. operator T*(){ return _p; }
  320. void operator=(T* p)
  321. {
  322. if(_p)
  323. {
  324. _f(_p);
  325. }
  326. _p = p;
  327. }
  328. T* Acquire()
  329. {
  330. T* p = _p;
  331. _p = NULL;
  332. return p;
  333. }
  334. };
  335. //*************************************************************
  336. //
  337. // Class: XArray
  338. //
  339. // Purpose: Smart pointer template for pointers that provide
  340. // a custom free memory routine
  341. //
  342. //*************************************************************
  343. typedef HLOCAL (__stdcall *PFNARRAYFREE)(HLOCAL, int);
  344. //
  345. // usage : XArray<EXPLICIT_ACCESS, 10> xaExplicitAccess( FreeAccessArray );
  346. //
  347. template <typename T, int nElements> class XArray
  348. {
  349. private:
  350. XArray(const XArray<T,nElements>& x);
  351. XArray<T,nElements>& operator=(const XArray<T,nElements>& x);
  352. T* _p;
  353. int _n;
  354. PFNARRAYFREE _f;
  355. public:
  356. XArray( PFNARRAYFREE pfnFree, HLOCAL p = 0 ) :
  357. _p( reinterpret_cast<T*>( p ) ), _f( pfnFree ), _n( nElements )
  358. {
  359. }
  360. ~XArray()
  361. {
  362. if(_p)
  363. {
  364. _f(_p, _n);
  365. }
  366. }
  367. T* operator->(){ return _p; }
  368. T** operator&(){ return &_p; }
  369. operator T*(){ return _p; }
  370. void operator=(T* p)
  371. {
  372. if(_p)
  373. {
  374. _f(_p, _n);
  375. }
  376. _p = p;
  377. }
  378. T* Acquire()
  379. {
  380. T* p = _p, _p = 0;
  381. return p;
  382. }
  383. };
  384. //******************************************************************************
  385. //
  386. // Class:
  387. //
  388. // Description:
  389. //
  390. // History: 8/20/99 leonardm Created.
  391. //
  392. //******************************************************************************
  393. class XHandle
  394. {
  395. private:
  396. HANDLE _h;
  397. public:
  398. XHandle(HANDLE h = NULL) : _h(h) {}
  399. ~XHandle()
  400. {
  401. if(_h && _h != INVALID_HANDLE_VALUE)
  402. {
  403. CloseHandle(_h);
  404. }
  405. }
  406. HANDLE* operator&(){return &_h;}
  407. operator HANDLE(){return _h;}
  408. void operator=(HANDLE h)
  409. {
  410. if(_h && _h != INVALID_HANDLE_VALUE)
  411. {
  412. CloseHandle(_h);
  413. }
  414. _h = h;
  415. }
  416. };
  417. class XKey
  418. {
  419. private:
  420. HKEY _h;
  421. public:
  422. XKey(HKEY h = NULL) : _h(h) {}
  423. ~XKey()
  424. {
  425. if(_h && _h != INVALID_HANDLE_VALUE)
  426. {
  427. RegCloseKey(_h);
  428. }
  429. }
  430. HKEY* operator&(){return &_h;}
  431. operator HKEY(){return _h;}
  432. void operator=(HKEY h)
  433. {
  434. if(_h && _h != INVALID_HANDLE_VALUE)
  435. {
  436. RegCloseKey(_h);
  437. }
  438. _h = h;
  439. }
  440. };
  441. class XCoInitialize
  442. {
  443. public:
  444. XCoInitialize()
  445. {
  446. m_hr = CoInitializeEx( 0, COINIT_MULTITHREADED );
  447. };
  448. ~XCoInitialize()
  449. {
  450. if ( SUCCEEDED( m_hr ) )
  451. {
  452. CoUninitialize();
  453. }
  454. };
  455. HRESULT Status()
  456. {
  457. return m_hr;
  458. };
  459. private:
  460. HRESULT m_hr;
  461. };
  462. class XImpersonate
  463. {
  464. public:
  465. XImpersonate() : m_hImpToken( 0 ), m_hThreadToken( 0 )
  466. {
  467. m_hr = CoImpersonateClient();
  468. };
  469. XImpersonate( HANDLE hToken ) : m_hThreadToken( 0 ), m_hImpToken( hToken )
  470. {
  471. OpenThreadToken( GetCurrentThread(), TOKEN_IMPERSONATE, TRUE, &m_hThreadToken );
  472. ImpersonateLoggedOnUser( hToken );
  473. m_hr = GetLastError();
  474. };
  475. ~XImpersonate()
  476. {
  477. if ( SUCCEEDED( m_hr ) )
  478. {
  479. if ( m_hImpToken )
  480. {
  481. SetThreadToken( 0, m_hThreadToken);
  482. }
  483. else
  484. {
  485. CoRevertToSelf();
  486. }
  487. }
  488. };
  489. HRESULT Status()
  490. {
  491. return m_hr;
  492. };
  493. private:
  494. HRESULT m_hr;
  495. XHandle m_hThreadToken;
  496. HANDLE m_hImpToken; // we don't own this
  497. };
  498. //*************************************************************
  499. //
  500. // Class: XCriticalPolicySection
  501. //
  502. // Purpose: Smart pointer for freeing Group Policy critical section
  503. //
  504. //*************************************************************
  505. class XCriticalPolicySection
  506. {
  507. private:
  508. HANDLE _h;
  509. public:
  510. XCriticalPolicySection(HANDLE h = NULL) : _h(h){}
  511. ~XCriticalPolicySection()
  512. {
  513. if(_h)
  514. {
  515. LeaveCriticalPolicySection (_h);
  516. }
  517. }
  518. void operator=(HANDLE h)
  519. {
  520. if(_h)
  521. {
  522. LeaveCriticalPolicySection (_h);
  523. }
  524. _h = h;
  525. }
  526. operator bool() {return _h ? true : false;}
  527. };
  528. // critical section smartptr
  529. class XCritSec
  530. {
  531. public:
  532. XCritSec()
  533. {
  534. lpCritSec = &CritSec;
  535. __try {
  536. InitializeCriticalSectionAndSpinCount(&CritSec, 0x80001000);
  537. }
  538. __except (EXCEPTION_EXECUTE_HANDLER) {
  539. // assumption, exception is out of memory
  540. // this is used in spewing debug messages. so cannot add a debug spew.
  541. lpCritSec = NULL;
  542. }
  543. }
  544. ~XCritSec()
  545. {
  546. if (lpCritSec)
  547. DeleteCriticalSection(lpCritSec);
  548. }
  549. operator LPCRITICAL_SECTION(){return lpCritSec;}
  550. private:
  551. CRITICAL_SECTION CritSec;
  552. LPCRITICAL_SECTION lpCritSec;
  553. };
  554. // enter and exit critical section
  555. class XEnterCritSec
  556. {
  557. public:
  558. XEnterCritSec(LPCRITICAL_SECTION lpCritSec) : m_lpCritSec( lpCritSec )
  559. {
  560. if (lpCritSec)
  561. EnterCriticalSection(lpCritSec);
  562. };
  563. ~XEnterCritSec()
  564. {
  565. if (m_lpCritSec)
  566. LeaveCriticalSection(m_lpCritSec);
  567. };
  568. private:
  569. LPCRITICAL_SECTION m_lpCritSec; // we don't own this
  570. };
  571. //////////////////////////////////////////////////////////////////////
  572. // XLastError
  573. //
  574. //
  575. // Sets the Last Error Correctly..
  576. //////////////////////////////////////////////////////////////////////
  577. class XLastError
  578. {
  579. private:
  580. DWORD _e;
  581. public:
  582. XLastError(){_e = GetLastError();}
  583. XLastError(DWORD e) : _e(e) {}
  584. ~XLastError(){SetLastError(_e);}
  585. void operator=(DWORD e) {_e = e;}
  586. operator DWORD() {return _e;}
  587. };
  588. #endif SMARTPTR_H