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.

688 lines
11 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. void operator=(SAFEARRAY* p)
  191. {
  192. if(_p)
  193. {
  194. SafeArrayDestroy(_p);
  195. }
  196. _p = p;
  197. }
  198. SAFEARRAY* Acquire()
  199. {
  200. SAFEARRAY* p = _p;
  201. _p = 0;
  202. return p;
  203. }
  204. };
  205. //*************************************************************
  206. //
  207. // Class: XVariant
  208. //
  209. // Purpose: Smart pointer class for Variants
  210. //
  211. //*************************************************************
  212. class XVariant
  213. {
  214. private:
  215. XVariant(const XVariant& x);
  216. XVariant& operator=(const XVariant& x);
  217. VARIANT* _p;
  218. public:
  219. XVariant(VARIANT* p = 0) : _p(p){}
  220. ~XVariant()
  221. {
  222. if (_p)
  223. {
  224. VariantClear(_p);
  225. }
  226. }
  227. void operator=(VARIANT* p)
  228. {
  229. if(_p)
  230. {
  231. VariantClear(_p);
  232. }
  233. _p = p;
  234. }
  235. operator VARIANT*(){ return _p; }
  236. VARIANT* Acquire()
  237. {
  238. VARIANT* p = _p;
  239. _p = 0;
  240. return p;
  241. }
  242. };
  243. //*************************************************************
  244. //
  245. // Class: XPtrLF
  246. //
  247. // Purpose: Smart pointer template for pointers that should be LocalFree()'d
  248. //
  249. //*************************************************************
  250. template <typename T> class XPtrLF
  251. {
  252. private:
  253. XPtrLF(const XPtrLF<T>& x);
  254. XPtrLF<T>& operator=(const XPtrLF<T>& x);
  255. T* _p;
  256. public:
  257. XPtrLF(HLOCAL p = 0 ) :
  258. _p((T*)p)
  259. {
  260. }
  261. ~XPtrLF()
  262. {
  263. if(_p)
  264. {
  265. LocalFree(_p);
  266. }
  267. }
  268. T* operator->(){ return _p; }
  269. T** operator&(){ return &_p; }
  270. operator T*(){ return _p; }
  271. void operator=(T* p)
  272. {
  273. if(_p)
  274. {
  275. LocalFree(_p);
  276. }
  277. _p = p;
  278. }
  279. T* Acquire()
  280. {
  281. T* p = _p;
  282. _p = NULL;
  283. return p;
  284. }
  285. };
  286. //*************************************************************
  287. //
  288. // Class: XPtr
  289. //
  290. // Purpose: Smart pointer template for pointers that provide
  291. // a custom free memory routine
  292. //
  293. //*************************************************************
  294. typedef HLOCAL (__stdcall *PFNFREE)(HLOCAL);
  295. //
  296. // usage : XPtr<SID, FreeSid> xptrSid;
  297. //
  298. template <typename T, PFNFREE _f> class XPtr
  299. {
  300. private:
  301. XPtr(const XPtr<T, _f>& x);
  302. XPtr<T, _f>& operator=(const XPtr<T, _f>& x);
  303. T* _p;
  304. public:
  305. XPtr( HLOCAL p = 0 ) :
  306. _p( reinterpret_cast<T*>( p ) )
  307. {
  308. }
  309. ~XPtr()
  310. {
  311. if(_p)
  312. {
  313. _f(_p);
  314. }
  315. }
  316. T* operator->(){ return _p; }
  317. T** operator&(){ return &_p; }
  318. operator T*(){ return _p; }
  319. void operator=(T* p)
  320. {
  321. if(_p)
  322. {
  323. _f(_p);
  324. }
  325. _p = p;
  326. }
  327. T* Acquire()
  328. {
  329. T* p = _p;
  330. _p = NULL;
  331. return p;
  332. }
  333. };
  334. //*************************************************************
  335. //
  336. // Class: XArray
  337. //
  338. // Purpose: Smart pointer template for pointers that provide
  339. // a custom free memory routine
  340. //
  341. //*************************************************************
  342. typedef HLOCAL (__stdcall *PFNARRAYFREE)(HLOCAL, int);
  343. //
  344. // usage : XArray<EXPLICIT_ACCESS, 10> xaExplicitAccess( FreeAccessArray );
  345. //
  346. template <typename T, int nElements> class XArray
  347. {
  348. private:
  349. XArray(const XArray<T,nElements>& x);
  350. XArray<T,nElements>& operator=(const XArray<T,nElements>& x);
  351. T* _p;
  352. int _n;
  353. PFNARRAYFREE _f;
  354. public:
  355. XArray( PFNARRAYFREE pfnFree, HLOCAL p = 0 ) :
  356. _p( reinterpret_cast<T*>( p ) ), _f( pfnFree ), _n( nElements )
  357. {
  358. }
  359. ~XArray()
  360. {
  361. if(_p)
  362. {
  363. _f(_p, _n);
  364. }
  365. }
  366. T* operator->(){ return _p; }
  367. T** operator&(){ return &_p; }
  368. operator T*(){ return _p; }
  369. void operator=(T* p)
  370. {
  371. if(_p)
  372. {
  373. _f(_p, _n);
  374. }
  375. _p = p;
  376. }
  377. T* Acquire()
  378. {
  379. T* p = _p, _p = 0;
  380. return p;
  381. }
  382. };
  383. //******************************************************************************
  384. //
  385. // Class:
  386. //
  387. // Description:
  388. //
  389. // History: 8/20/99 leonardm Created.
  390. //
  391. //******************************************************************************
  392. class XHandle
  393. {
  394. private:
  395. HANDLE _h;
  396. public:
  397. XHandle(HANDLE h = NULL) : _h(h) {}
  398. ~XHandle()
  399. {
  400. if(_h && _h != INVALID_HANDLE_VALUE)
  401. {
  402. CloseHandle(_h);
  403. }
  404. }
  405. HANDLE* operator&(){return &_h;}
  406. operator HANDLE(){return _h;}
  407. void operator=(HANDLE h)
  408. {
  409. if(_h && _h != INVALID_HANDLE_VALUE)
  410. {
  411. CloseHandle(_h);
  412. }
  413. _h = h;
  414. }
  415. };
  416. class XCoInitialize
  417. {
  418. public:
  419. XCoInitialize()
  420. {
  421. m_hr = CoInitializeEx( 0, COINIT_MULTITHREADED );
  422. };
  423. ~XCoInitialize()
  424. {
  425. if ( SUCCEEDED( m_hr ) )
  426. {
  427. CoUninitialize();
  428. }
  429. };
  430. HRESULT Status()
  431. {
  432. return m_hr;
  433. };
  434. private:
  435. HRESULT m_hr;
  436. };
  437. class XImpersonate
  438. {
  439. public:
  440. XImpersonate() : m_hImpToken( 0 ), m_hThreadToken( 0 )
  441. {
  442. m_hr = CoImpersonateClient();
  443. };
  444. XImpersonate( HANDLE hToken ) : m_hThreadToken( 0 ), m_hImpToken( hToken )
  445. {
  446. OpenThreadToken( GetCurrentThread(), TOKEN_IMPERSONATE, TRUE, &m_hThreadToken );
  447. ImpersonateLoggedOnUser( hToken );
  448. m_hr = GetLastError();
  449. };
  450. ~XImpersonate()
  451. {
  452. if ( SUCCEEDED( m_hr ) )
  453. {
  454. if ( m_hImpToken )
  455. {
  456. SetThreadToken( 0, m_hThreadToken);
  457. }
  458. else
  459. {
  460. CoRevertToSelf();
  461. }
  462. }
  463. };
  464. HRESULT Status()
  465. {
  466. return m_hr;
  467. };
  468. private:
  469. HRESULT m_hr;
  470. XHandle m_hThreadToken;
  471. HANDLE m_hImpToken; // we don't own this
  472. };
  473. //*************************************************************
  474. //
  475. // Class: XCriticalPolicySection
  476. //
  477. // Purpose: Smart pointer for freeing Group Policy critical section
  478. //
  479. //*************************************************************
  480. class XCriticalPolicySection
  481. {
  482. private:
  483. HANDLE _h;
  484. public:
  485. XCriticalPolicySection(HANDLE h) : _h(h){}
  486. ~XCriticalPolicySection()
  487. {
  488. if(_h)
  489. {
  490. LeaveCriticalPolicySection (_h);
  491. }
  492. }
  493. operator bool() {return _h ? true : false;}
  494. };
  495. // critical section smartptr
  496. class XCritSec
  497. {
  498. public:
  499. XCritSec()
  500. {
  501. lpCritSec = &CritSec;
  502. __try {
  503. InitializeCriticalSectionAndSpinCount(&CritSec, 0x80001000);
  504. }
  505. __except (EXCEPTION_EXECUTE_HANDLER) {
  506. // assumption, exception is out of memory
  507. // this is used in spewing debug messages. so cannot add a debug spew.
  508. lpCritSec = NULL;
  509. }
  510. }
  511. ~XCritSec()
  512. {
  513. if (lpCritSec)
  514. DeleteCriticalSection(lpCritSec);
  515. }
  516. operator LPCRITICAL_SECTION(){return lpCritSec;}
  517. private:
  518. CRITICAL_SECTION CritSec;
  519. LPCRITICAL_SECTION lpCritSec;
  520. };
  521. // enter and exit critical section
  522. class XEnterCritSec
  523. {
  524. public:
  525. XEnterCritSec(LPCRITICAL_SECTION lpCritSec) : m_lpCritSec( lpCritSec )
  526. {
  527. if (lpCritSec)
  528. EnterCriticalSection(lpCritSec);
  529. };
  530. ~XEnterCritSec()
  531. {
  532. if (m_lpCritSec)
  533. LeaveCriticalSection(m_lpCritSec);
  534. };
  535. private:
  536. LPCRITICAL_SECTION m_lpCritSec; // we don't own this
  537. };
  538. #endif SMARTPTR_H