Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

818 lines
15 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() :
  466. m_hImpToken( 0 ),
  467. m_hThreadToken( 0 ),
  468. m_bRevertAttempted(FALSE),
  469. m_bImpersonated(FALSE),
  470. m_hr(S_OK)
  471. {
  472. m_hr = CoImpersonateClient();
  473. if (SUCCEEDED(m_hr))
  474. {
  475. m_bImpersonated = TRUE;
  476. }
  477. };
  478. XImpersonate( HANDLE hToken ) :
  479. m_hImpToken( hToken ),
  480. m_hThreadToken( 0 ),
  481. m_bRevertAttempted(FALSE),
  482. m_bImpersonated(FALSE),
  483. m_hr(S_OK)
  484. {
  485. if (!OpenThreadToken( GetCurrentThread(), TOKEN_IMPERSONATE, TRUE, &m_hThreadToken )) {
  486. if (GetLastError() != ERROR_NO_TOKEN )
  487. {
  488. m_hr = HRESULT_FROM_WIN32(GetLastError());
  489. }
  490. }
  491. if (SUCCEEDED(m_hr)) {
  492. if (!ImpersonateLoggedOnUser( hToken )) {
  493. m_hr = HRESULT_FROM_WIN32(GetLastError());
  494. }
  495. else {
  496. m_bImpersonated = TRUE;
  497. }
  498. }
  499. };
  500. HRESULT Revert()
  501. {
  502. if ( m_bImpersonated )
  503. {
  504. m_bRevertAttempted = TRUE;
  505. if ( m_hImpToken )
  506. {
  507. if (!SetThreadToken( 0, m_hThreadToken)) {
  508. m_hr = HRESULT_FROM_WIN32(GetLastError());
  509. }
  510. else {
  511. m_bImpersonated = FALSE;
  512. m_hr = S_OK;
  513. }
  514. }
  515. else
  516. {
  517. m_hr = CoRevertToSelf();
  518. if (SUCCEEDED(m_hr))
  519. {
  520. m_bImpersonated = FALSE;
  521. }
  522. }
  523. }
  524. return m_hr;
  525. }
  526. ~XImpersonate()
  527. {
  528. HRESULT hr = S_OK;
  529. if (!m_bRevertAttempted)
  530. {
  531. hr = Revert();
  532. }
  533. if (m_hThreadToken)
  534. {
  535. CloseHandle(m_hThreadToken);
  536. }
  537. if (FAILED(hr))
  538. {
  539. RaiseException(Status(),
  540. EXCEPTION_NONCONTINUABLE,
  541. 0,
  542. NULL);
  543. }
  544. };
  545. HRESULT Status()
  546. {
  547. return m_hr;
  548. };
  549. private:
  550. HRESULT m_hr;
  551. XHandle m_hThreadToken;
  552. HANDLE m_hImpToken; // we don't own this
  553. BOOL m_bImpersonated;
  554. BOOL m_bRevertAttempted;
  555. };
  556. //*************************************************************
  557. //
  558. // Class: XCriticalPolicySection
  559. //
  560. // Purpose: Smart pointer for freeing Group Policy critical section
  561. //
  562. //*************************************************************
  563. class XCriticalPolicySection
  564. {
  565. private:
  566. HANDLE _h;
  567. public:
  568. XCriticalPolicySection(HANDLE h = NULL) : _h(h){}
  569. ~XCriticalPolicySection()
  570. {
  571. if(_h)
  572. {
  573. LeaveCriticalPolicySection (_h);
  574. }
  575. }
  576. void operator=(HANDLE h)
  577. {
  578. if(_h)
  579. {
  580. LeaveCriticalPolicySection (_h);
  581. }
  582. _h = h;
  583. }
  584. operator bool() {return _h ? true : false;}
  585. };
  586. // critical section smartptr
  587. class XCritSec
  588. {
  589. public:
  590. XCritSec()
  591. {
  592. lpCritSec = &CritSec;
  593. __try {
  594. if (!InitializeCriticalSectionAndSpinCount(&CritSec, 0x80001000)) {
  595. lpCritSec = NULL;
  596. }
  597. }
  598. __except (EXCEPTION_EXECUTE_HANDLER) {
  599. // assumption, exception is out of memory
  600. // this is used in spewing debug messages. so cannot add a debug spew.
  601. lpCritSec = NULL;
  602. }
  603. }
  604. ~XCritSec()
  605. {
  606. if (lpCritSec)
  607. DeleteCriticalSection(lpCritSec);
  608. }
  609. operator LPCRITICAL_SECTION(){return lpCritSec;}
  610. private:
  611. CRITICAL_SECTION CritSec;
  612. LPCRITICAL_SECTION lpCritSec;
  613. };
  614. // enter and exit critical section
  615. class XEnterCritSec
  616. {
  617. public:
  618. XEnterCritSec(LPCRITICAL_SECTION lpCritSec) : m_lpCritSec( lpCritSec )
  619. {
  620. if (lpCritSec)
  621. EnterCriticalSection(lpCritSec);
  622. };
  623. ~XEnterCritSec()
  624. {
  625. if (m_lpCritSec)
  626. LeaveCriticalSection(m_lpCritSec);
  627. };
  628. private:
  629. LPCRITICAL_SECTION m_lpCritSec; // we don't own this
  630. };
  631. //////////////////////////////////////////////////////////////////////
  632. // XLastError
  633. //
  634. //
  635. // Sets the Last Error Correctly..
  636. //////////////////////////////////////////////////////////////////////
  637. class XLastError
  638. {
  639. private:
  640. DWORD _e;
  641. public:
  642. XLastError(){_e = GetLastError();}
  643. XLastError(DWORD e) : _e(e) {}
  644. ~XLastError(){SetLastError(_e);}
  645. void operator=(DWORD e) {_e = e;}
  646. operator DWORD() {return _e;}
  647. };
  648. #endif SMARTPTR_H