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.

623 lines
18 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: gensph.h
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: LazarI
  10. *
  11. * DATE: 23-Dec-2000
  12. *
  13. * DESCRIPTION: generic smart pointers & smart handles templates
  14. *
  15. *****************************************************************************/
  16. #ifndef _GENSPH_H_
  17. #define _GENSPH_H_
  18. // include the core definitions first
  19. #include "coredefs.h"
  20. ////////////////////////////////////////////////
  21. //
  22. // class CGenericSP
  23. //
  24. // a generic smart pointer
  25. // everything starts here -:)
  26. //
  27. template < class T,
  28. class inheritorClass,
  29. class pType = T*,
  30. INT_PTR null = 0,
  31. class pCType = const T* >
  32. class CGenericSP
  33. {
  34. public:
  35. // construction/destruction
  36. CGenericSP(): m_p(GetNull()) {}
  37. CGenericSP(pType p): m_p(GetNull()) { _Attach(p); }
  38. ~CGenericSP() { Reset(); }
  39. // follows common smart pointer impl. -
  40. // operators & methods
  41. void Reset()
  42. {
  43. if( GetNull() != m_p )
  44. {
  45. _Delete(m_p);
  46. m_p = GetNull();
  47. }
  48. }
  49. void Attach(pType p)
  50. {
  51. Reset();
  52. m_p = (p ? p : GetNull());
  53. }
  54. pType Detach()
  55. {
  56. pType p = GetNull();
  57. if( GetNull() != m_p )
  58. {
  59. p = m_p;
  60. m_p = GetNull();
  61. }
  62. return p;
  63. }
  64. template <class AS_TYPE>
  65. AS_TYPE GetPtrAs() const
  66. {
  67. return (GetNull() == m_p) ? reinterpret_cast<AS_TYPE>(NULL) : reinterpret_cast<AS_TYPE>(m_p);
  68. }
  69. pType GetPtr() const
  70. {
  71. return GetPtrAs<pType>();
  72. }
  73. pType* GetPPT()
  74. {
  75. return static_cast<pType*>(&m_p);
  76. }
  77. pCType* GetPPCT()
  78. {
  79. return const_cast<pCType*>(&m_p);
  80. }
  81. void** GetPPV()
  82. {
  83. return reinterpret_cast<void**>(&m_p);
  84. }
  85. operator pType() const
  86. {
  87. return GetPtr();
  88. }
  89. T& operator*() const
  90. {
  91. ASSERT(GetNull() != m_p);
  92. return *m_p;
  93. }
  94. pType* operator&()
  95. {
  96. ASSERT(GetNull() == m_p);
  97. return GetPPT();
  98. }
  99. pType operator->() const
  100. {
  101. ASSERT(GetNull() != m_p);
  102. return (pType)m_p;
  103. }
  104. pType operator=(pType p)
  105. {
  106. _Attach(p);
  107. return m_p;
  108. }
  109. pType operator=(const int i)
  110. {
  111. // this operator is only for NULL assignment
  112. ASSERT(INT2PTR(i, pType) == NULL || INT2PTR(i, pType) == GetNull());
  113. Attach(INT2PTR(i, pType));
  114. return m_p;
  115. }
  116. bool operator!() const
  117. {
  118. return (GetNull() == m_p);
  119. }
  120. bool operator<(pType p) const
  121. {
  122. return (m_p < p);
  123. }
  124. bool operator==(pType p) const
  125. {
  126. return (m_p == p);
  127. }
  128. protected:
  129. pType m_p;
  130. // those will be declared protected, so people won't use them directly
  131. CGenericSP(CGenericSP<T, inheritorClass, pType, null, pCType> &sp): m_p(GetNull())
  132. {
  133. _Attach(sp);
  134. }
  135. void Attach(CGenericSP<T, inheritorClass, pType, null, pCType> &sp)
  136. {
  137. static_cast<inheritorClass*>(this)->Attach(static_cast<pType>(sp));
  138. sp.Detach();
  139. }
  140. pType operator=(CGenericSP<T, inheritorClass, pType, null, pCType> &sp)
  141. {
  142. _Attach(sp);
  143. return m_p;
  144. }
  145. // NULL support, use these to check for/assign NULL in inheritors
  146. pType GetNull() const { return reinterpret_cast<pType>(null); }
  147. bool IsNull(pType p) const { return GetNull() == p; }
  148. bool IsntNull(pType p) const { return GetNull() != p; }
  149. private:
  150. void _Attach(pType p)
  151. {
  152. // give a chance to inheritors to override the attach
  153. static_cast<inheritorClass*>(this)->Attach(p);
  154. }
  155. void _Attach(CGenericSP<T, inheritorClass, pType, null, pCType> &sp)
  156. {
  157. // give a chance to inheritors to override the attach
  158. static_cast<inheritorClass*>(this)->Attach(sp);
  159. }
  160. void _Delete(pType p)
  161. {
  162. // the inheritor class defines static member called Delete(pType p)
  163. // to destroy the object.
  164. if( GetNull() != p )
  165. {
  166. #pragma prefast(suppress:307, "This is a known prefast bug fixed in version 1.2 (PREfast bug 616)")
  167. inheritorClass::Delete(p);
  168. }
  169. }
  170. };
  171. // declares standard default contructor, copy constructor, attach
  172. // contructor and assignment operators (they can't be inherited as constructors can't)
  173. // for the CGenericSP class in an inheritor class.
  174. #define DECLARE_GENERICSMARTPTR_CONSTRUCT(T, className) \
  175. private: \
  176. className(className &sp): CGenericSP< T, className >(sp) { } \
  177. T* operator=(className &sp) \
  178. { return CGenericSP< T, className >::operator =(sp); } \
  179. public: \
  180. className() { } \
  181. className(T *p): CGenericSP< T, className >(p) { } \
  182. T* operator=(T *p) \
  183. { return CGenericSP< T, className >::operator =(p); } \
  184. T* operator=(const int i) \
  185. { return CGenericSP< T, className >::operator =(i); } \
  186. #define DECLARE_GENERICSMARTPTR_CONSTRUCT1(T, className, pType) \
  187. private: \
  188. className(className &sp): CGenericSP<T, className, pType>(sp) { } \
  189. pType operator=(className &sp) \
  190. { return CGenericSP<T, className, pType>::operator =(sp); } \
  191. public: \
  192. className() { } \
  193. className(pType p): CGenericSP<T, className, pType>(p) { } \
  194. pType operator=(pType p) \
  195. { return CGenericSP<T, className, pType>::operator =(p); } \
  196. pType operator=(const int i) \
  197. { return CGenericSP<T, className, pType>::operator =(i); } \
  198. #define DECLARE_GENERICSMARTPTR_CONSTRUCT2(T, className, pType, null) \
  199. private: \
  200. className(className &sp): CGenericSP<T, className, pType, null>(sp) { } \
  201. pType operator=(className &sp) \
  202. { return CGenericSP<T, className, pType, null>::operator =(sp); } \
  203. public: \
  204. className() { } \
  205. className(pType p): CGenericSP<T, className, pType, null>(p) { } \
  206. pType operator=(pType p) \
  207. { return CGenericSP<T, className, pType, null>::operator =(p); } \
  208. pType operator=(const int i) \
  209. { return CGenericSP<T, className, pType, null>::operator =(i); } \
  210. ////////////////////////////////////////////////
  211. ////////// AUTO POINTERS ///////////////////////
  212. ////////////////////////////////////////////////
  213. ////////////////////////////////////////////////
  214. //
  215. // class CAutoPtr
  216. //
  217. // simple auto-pointer
  218. // uses delete operator to free memory
  219. //
  220. template <class T>
  221. class CAutoPtr: public CGenericSP< T, CAutoPtr<T> >
  222. {
  223. public:
  224. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtr<T>)
  225. static void Delete(T *p) { delete p; }
  226. };
  227. ////////////////////////////////////////////////
  228. //
  229. // class CAutoPtrArray
  230. //
  231. // simple auto-pointer allocated as array
  232. // uses delete[] operator to free memory
  233. //
  234. template <class T>
  235. class CAutoPtrArray: public CGenericSP< T, CAutoPtrArray<T> >
  236. {
  237. public:
  238. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrArray<T>)
  239. static void Delete(T *p) { delete[] p; }
  240. };
  241. ////////////////////////////////////////////////
  242. //
  243. // class CAutoPtrCRT
  244. //
  245. // simple CRT auto-pointer - allocated with malloc/calloc
  246. // uses free to free the memory
  247. //
  248. template <class T>
  249. class CAutoPtrCRT: public CGenericSP< T, CAutoPtrCRT<T> >
  250. {
  251. public:
  252. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrCRT<T>)
  253. static void Delete(T *p) { free(p); }
  254. };
  255. ////////////////////////////////////////////////
  256. //
  257. // class CAutoPtrSpl
  258. //
  259. // simple spooler auto-pointer -
  260. // uses FreeMem to free memory
  261. //
  262. template <class T>
  263. class CAutoPtrSpl: public CGenericSP< T, CAutoPtrSpl<T> >
  264. {
  265. public:
  266. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrSpl<T>)
  267. static void Delete(T *p) { FreeMem(p); }
  268. };
  269. ////////////////////////////////////////////////
  270. //
  271. // class CAutoPtrBSTR
  272. //
  273. // simple BSTR auto-pointer -
  274. // SysAllocString/SysFreeString
  275. //
  276. class CAutoPtrBSTR: public CGenericSP<BSTR, CAutoPtrBSTR, BSTR>
  277. {
  278. public:
  279. DECLARE_GENERICSMARTPTR_CONSTRUCT1(BSTR, CAutoPtrBSTR, BSTR)
  280. static void Delete(BSTR p) { SysFreeString(p); }
  281. };
  282. ////////////////////////////////////////////////
  283. //
  284. // class CAutoPtrCOM
  285. //
  286. // simple smart COM pointer
  287. //
  288. template <class T>
  289. class CAutoPtrCOM: public CGenericSP< T, CAutoPtrCOM<T> >
  290. {
  291. public:
  292. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrCOM<T>)
  293. static void Delete(T *p) { p->Release(); }
  294. };
  295. ////////////////////////////////////////////////
  296. //
  297. // class CRefPtrCOM
  298. //
  299. // referenced smart COM pointer (ATL style)
  300. // with improvements for robustness
  301. //
  302. template <class T>
  303. class CRefPtrCOM: public CGenericSP< T, CRefPtrCOM<T> >
  304. {
  305. void _AddRefAttach(T *p);
  306. public:
  307. // special case all these
  308. CRefPtrCOM() { }
  309. CRefPtrCOM(const CGenericSP< T, CRefPtrCOM<T> > &sp): CGenericSP< T, CRefPtrCOM<T> >(sp) { }
  310. T* operator=(const CRefPtrCOM<T> &sp) { return CGenericSP< T, CRefPtrCOM<T> >::operator =(sp); }
  311. T* operator=(const int i) { return CGenericSP< T, CRefPtrCOM<T> >::operator =(i); }
  312. // overloaded stuff
  313. void Attach(const CRefPtrCOM<T> &sp) { _AddRefAttach(static_cast<T*>(sp)); }
  314. static void Delete(T *p) { p->Release(); }
  315. // use these functions instead of operators (more clear)
  316. HRESULT CopyFrom(T *p); // AddRef p and assign to this
  317. HRESULT CopyTo(T **ppObj); // AddRef this and assign to ppObj
  318. HRESULT TransferTo(T **ppObj); // assign this to ppObj and assign NULL to this
  319. HRESULT Adopt(T *p); // take ownership of p
  320. private:
  321. // disable contruction, assignment operator & attach from
  322. // a raw pointer - it's not clear what exactly you want:
  323. // to copy (AddRef) the object or to take ownership - use
  324. // the functions above to make clear
  325. void Attach(T* p);
  326. CRefPtrCOM(T *p);
  327. T* operator=(T *p);
  328. };
  329. ////////////////////////////////////////////////
  330. //
  331. // class CAutoPtrShell
  332. //
  333. // smart shell auto pointer -
  334. // uses shell IMalloc to free memory
  335. //
  336. template <class T>
  337. class CAutoPtrShell: public CGenericSP< T, CAutoPtrShell<T> >
  338. {
  339. public:
  340. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrShell<T>)
  341. static void Delete(T *p)
  342. {
  343. CAutoPtrCOM<IMalloc> spShellMalloc;
  344. if( SUCCEEDED(SHGetMalloc(&spShellMalloc)) )
  345. {
  346. spShellMalloc->Free(p);
  347. }
  348. }
  349. };
  350. ////////////////////////////////////////////////
  351. //
  352. // class CAutoPtrPIDL
  353. //
  354. // smart shell ID list ptr - LPCITEMIDLIST, LPITEMIDLIST.
  355. //
  356. typedef CAutoPtrShell<ITEMIDLIST> CAutoPtrPIDL;
  357. ////////////////////////////////////////////////
  358. ////////// AUTO HANDLES ////////////////////////
  359. ////////////////////////////////////////////////
  360. ////////////////////////////////////////////////
  361. //
  362. // class CAutoHandleNT
  363. //
  364. // NT kernel object handle (closed with CloseHandle)
  365. //
  366. class CAutoHandleNT: public CGenericSP<HANDLE, CAutoHandleNT, HANDLE>
  367. {
  368. public:
  369. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HANDLE, CAutoHandleNT, HANDLE)
  370. static void Delete(HANDLE h) { VERIFY(CloseHandle(h)); }
  371. };
  372. ////////////////////////////////////////////////
  373. //
  374. // class CAutoHandleHLOCAL
  375. //
  376. // NT local heap handle (closed with LocalFree)
  377. //
  378. class CAutoHandleHLOCAL: public CGenericSP<HLOCAL, CAutoHandleHLOCAL, HLOCAL>
  379. {
  380. public:
  381. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HLOCAL, CAutoHandleHLOCAL, HLOCAL)
  382. static void Delete(HLOCAL h) { VERIFY(NULL == LocalFree(h)); }
  383. };
  384. ////////////////////////////////////////////////
  385. //
  386. // class CAutoHandleHGLOBAL
  387. //
  388. // NT global heap handle (closed with GlobalFree)
  389. //
  390. class CAutoHandleHGLOBAL: public CGenericSP<HGLOBAL, CAutoHandleHGLOBAL, HGLOBAL>
  391. {
  392. public:
  393. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HGLOBAL, CAutoHandleHGLOBAL, HGLOBAL)
  394. static void Delete(HGLOBAL h) { VERIFY(NULL == GlobalFree(h)); }
  395. };
  396. ////////////////////////////////////////////////
  397. //
  398. // class CAutoHandlePrinter
  399. //
  400. // auto printer handle
  401. //
  402. class CAutoHandlePrinter: public CGenericSP<HANDLE, CAutoHandlePrinter, HANDLE>
  403. {
  404. public:
  405. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HANDLE, CAutoHandlePrinter, HANDLE)
  406. static void Delete(HANDLE h) { CHECK(ClosePrinter(h)); }
  407. };
  408. ////////////////////////////////////////////////
  409. //
  410. // class CAutoHandlePrinterNotify
  411. //
  412. // printer notifications handle -
  413. // Find[Firse/Next/Close]PrinterChangeNotification()
  414. //
  415. class CAutoHandlePrinterNotify: public CGenericSP<HANDLE, CAutoHandlePrinterNotify, HANDLE, -1>
  416. {
  417. public:
  418. DECLARE_GENERICSMARTPTR_CONSTRUCT2(HANDLE, CAutoHandlePrinterNotify, HANDLE, -1)
  419. static void Delete(HANDLE h) { CHECK(FindClosePrinterChangeNotification(h)); }
  420. };
  421. ////////////////////////////////////////////////
  422. //
  423. // class CAutoPtrPrinterNotify
  424. //
  425. // printer notifications memory - spooler should free it.
  426. // Find[Firse/Next/Close]PrinterChangeNotification()
  427. //
  428. class CAutoPtrPrinterNotify: public CGenericSP<PRINTER_NOTIFY_INFO, CAutoPtrPrinterNotify>
  429. {
  430. public:
  431. DECLARE_GENERICSMARTPTR_CONSTRUCT(PRINTER_NOTIFY_INFO, CAutoPtrPrinterNotify)
  432. static void Delete(PRINTER_NOTIFY_INFO *p) { CHECK(FreePrinterNotifyInfo(p)); }
  433. };
  434. ////////////////////////////////////////////////
  435. //
  436. // class CAutoHandleGDI
  437. //
  438. // GDI auto handle (WindowsNT GDI handle wrapper)
  439. //
  440. template <class T>
  441. class CAutoHandleGDI: public CGenericSP< T, CAutoHandleGDI<T>, T >
  442. {
  443. public:
  444. DECLARE_GENERICSMARTPTR_CONSTRUCT1(T, CAutoHandleGDI<T>, T)
  445. static void Delete(T hGDIObj) { VERIFY(DeleteObject(hGDIObj)); }
  446. };
  447. // GDI auto handles
  448. typedef CAutoHandleGDI<HPEN> CAutoHandlePen;
  449. typedef CAutoHandleGDI<HBRUSH> CAutoHandleBrush;
  450. typedef CAutoHandleGDI<HFONT> CAutoHandleFont;
  451. typedef CAutoHandleGDI<HBITMAP> CAutoHandleBitmap;
  452. // etc...
  453. ////////////////////////////////////////////////
  454. //
  455. // class CAutoHandleCursor
  456. //
  457. // auto handle for HCURSOR
  458. //
  459. class CAutoHandleCursor: public CGenericSP<HCURSOR, CAutoHandleCursor, HCURSOR>
  460. {
  461. public:
  462. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HCURSOR, CAutoHandleCursor, HCURSOR)
  463. static void Delete(HCURSOR h) { VERIFY(DestroyCursor(h)); }
  464. };
  465. ////////////////////////////////////////////////
  466. //
  467. // class CAutoHandleIcon
  468. //
  469. // auto handle for HICON
  470. //
  471. class CAutoHandleIcon: public CGenericSP<HICON, CAutoHandleIcon, HICON>
  472. {
  473. public:
  474. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HICON, CAutoHandleIcon, HICON)
  475. static void Delete(HICON h) { VERIFY(DestroyIcon(h)); }
  476. };
  477. ////////////////////////////////////////////////
  478. //
  479. // class CAutoHandleMenu
  480. //
  481. // auto handle for HMENU
  482. //
  483. class CAutoHandleMenu: public CGenericSP<HMENU, CAutoHandleMenu, HMENU>
  484. {
  485. public:
  486. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HMENU, CAutoHandleMenu, HMENU)
  487. static void Delete(HMENU h) { VERIFY(DestroyMenu(h)); }
  488. };
  489. ////////////////////////////////////////////////
  490. //
  491. // class CAutoHandleAccel
  492. //
  493. // auto handle for HACCEL
  494. //
  495. class CAutoHandleAccel: public CGenericSP<HACCEL, CAutoHandleAccel, HACCEL>
  496. {
  497. public:
  498. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HACCEL, CAutoHandleAccel, HACCEL)
  499. static void Delete(HACCEL h) { DestroyAcceleratorTable(h); }
  500. };
  501. #ifdef _INC_COMCTRLP
  502. ////////////////////////////////////////////////
  503. //
  504. // class CAutoHandleHDSA
  505. //
  506. // auto handle for shell HDSA
  507. // (dynamic structure arrays)
  508. //
  509. class CAutoHandleHDSA: public CGenericSP<HDSA, CAutoHandleHDSA, HDSA>
  510. {
  511. public:
  512. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HDSA, CAutoHandleHDSA, HDSA)
  513. static void Delete(HDSA h) { VERIFY(DSA_Destroy(h)); }
  514. };
  515. ////////////////////////////////////////////////
  516. //
  517. // class CAutoHandleMRU
  518. //
  519. // auto handle for MRU (shell common controls)
  520. // CreateMRUList/FreeMRUList
  521. //
  522. class CAutoHandleMRU: public CGenericSP<HANDLE, CAutoHandleMRU, HANDLE>
  523. {
  524. public:
  525. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HANDLE, CAutoHandleMRU, HANDLE)
  526. static void Delete(HANDLE h) { FreeMRUList(h); }
  527. };
  528. #endif // _INC_COMCTRLP
  529. ////////////////////////////////////////////////
  530. //
  531. // class CAutoHandleHKEY
  532. //
  533. // auto handle for a Windows registry key (HKEY)
  534. // RegCreateKeyEx/RegOpenKeyEx/RegCloseKey
  535. //
  536. class CAutoHandleHKEY: public CGenericSP<HKEY, CAutoHandleHKEY, HKEY>
  537. {
  538. public:
  539. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HKEY, CAutoHandleHKEY, HKEY)
  540. static void Delete(HKEY h) { VERIFY(ERROR_SUCCESS == RegCloseKey(h)); }
  541. };
  542. ////////////////////////////////////////////////
  543. //
  544. // class CAutoHandleHMODULE
  545. //
  546. // auto handle for a HMODULE
  547. // LoadLibrary/FreeLibrary
  548. //
  549. class CAutoHandleHMODULE: public CGenericSP<HMODULE, CAutoHandleHMODULE, HMODULE>
  550. {
  551. public:
  552. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HMODULE, CAutoHandleHMODULE, HMODULE)
  553. static void Delete(HMODULE h) { VERIFY(FreeLibrary(h)); }
  554. };
  555. // include the implementation of the template classes here
  556. #include "gensph.inl"
  557. #endif // endif _GENSPH_H_