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.

957 lines
53 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation.
  4. //
  5. // File: safepnt.hxx
  6. //
  7. // Contents: Safe pointers to interfaces and to memory
  8. //
  9. // Classes:
  10. //
  11. // Functions:
  12. //
  13. // History: 03-Mar-93 KevinRo Created
  14. // 07-Jul-94 MikeSe Rationalised with smartp.hxx
  15. // 19-Jul-94 KirtD Added SAFE_XXX_HANDLE
  16. // 03-Aug-93 DrewB/AdamS Added Set/Attach/Detach
  17. // 16-Oct-93 DrewB Added non-Cairo support
  18. //
  19. // Notes:
  20. //
  21. // This file contains a set of macros that define safe pointers to various
  22. // classes of memory. Memory that is reference counted (such as interfaces),
  23. // memory allocated using MemAlloc/MemFree, and memory allocated from
  24. // the local heap. The classes handle both pointers to structures and memory
  25. // by having versions that include the -> operator, or not.
  26. //
  27. //--------------------------------------------------------------------------
  28. #ifndef _SAFEPNT_HXX_
  29. #define _SAFEPNT_HXX_
  30. #include <except.hxx>
  31. #include <debnot.h>
  32. //+-------------------------------------------------------------------------
  33. //
  34. // The basic usage for all of these macros is:
  35. //
  36. // SAFE_xxx_PTR( NameOfSafePointerClass, TypeOfDataPointedTo)
  37. //
  38. // Each invocation of such macro declares a new class of the specified name
  39. // whose only member variable is a pointer (called the captured pointer)
  40. // to the specified type, and whose behaviour is largely indistiguishable from
  41. // a regular pointer to that type, except that it is leak-free (if used
  42. // correctly).
  43. //
  44. // For example, SAFE_INTERFACE_PTR( SafeUnknown, IUnknown)
  45. // SAFE_HEAP_MEMPTR( SafeWCHARPtr, WCHAR )
  46. //
  47. // The captured pointer is generally acquired during construction of the
  48. // safe pointer class, and acquisition may include invoking an operation on
  49. // the captured pointer.
  50. //
  51. // In addition, the pointer may be captured by being the output of a function
  52. // call. This is the only intended purpose of the & operator provided by
  53. // the safe pointer class.
  54. //
  55. // When the safe pointer instance go out of scope (either normally or as
  56. // the result of an exception), the captured pointer is "freed" by invoking
  57. // an appropriate operation on it.
  58. //
  59. // The captured pointer may be passed on elsewhere using the Transfer method
  60. // in which case destruction of the safe pointer becomes a nop. In particular
  61. // this can be used to tranfer the captured pointer from one safe pointer to
  62. // another, viz:
  63. //
  64. // sp1.Transfer ( &sp2 );
  65. //
  66. // The Transfer method is implemented in such a way that an exception on the
  67. // output pointer will not result in a leak.
  68. //
  69. // Safe pointers are intended to be used as resource containers. To that end,
  70. // the list of operators available is intentionally short. However, based on
  71. // experience, safe pointers can be used in most places that a normal
  72. // pointer would be used. The exception is that safe pointers do not allow
  73. // for arithmetic operations. For example:
  74. //
  75. // SpWCHARPtr spwz(new WCHAR[10]);
  76. //
  77. // spwz++; // Not allowed, since the pointer would change.
  78. //
  79. // wcscpy(spwz,L"Test"); // This is OK
  80. //
  81. //--------------------------------------------------------------------------
  82. //+-------------------------------------------------------------------------
  83. //
  84. // Macro: SAFE_INTERFACE_PTR
  85. //
  86. // Purpose: Safe pointer to any interface that supports AddRef/Release
  87. //
  88. // Notes: This works for classes that define AddRef/Release, or for
  89. // Cairole interfaces. It is not necessary that the class
  90. // be a derivative of IUnknown, so long as it supports
  91. // AddRef and Release methods which have the same semantics as
  92. // those in IUnknown.
  93. //
  94. // The constructor takes a parameter which specifies whether
  95. // the captured pointer should be AddRef'd, defaulting to TRUE.
  96. //
  97. // The Copy function creates a valid additional copy of
  98. // the captured pointer (following the AddRef/Release protocol)
  99. // so can be used to hand out copies from a safe pointer declared
  100. // as a member of some other class.
  101. //
  102. //--------------------------------------------------------------------------
  103. #define SAFE_INTERFACE_PTR(SpName,SpType) \
  104. class SpName INHERIT_UNWIND_IF_CAIRO \
  105. { \
  106. INLINE_UNWIND(SpName) \
  107. public: \
  108. \
  109. inline SpName ( SpType * pinter=NULL,BOOL fInc=TRUE) \
  110. : _p ( pinter ) \
  111. { \
  112. if (fInc && (_p != NULL)) \
  113. { \
  114. _p->AddRef(); \
  115. } \
  116. END_CONSTRUCTION (SpName) \
  117. } \
  118. \
  119. inline ~##SpName () \
  120. { \
  121. if (_p != NULL) \
  122. { \
  123. _p->Release(); \
  124. _p = NULL; \
  125. } \
  126. } \
  127. \
  128. inline void Transfer ( SpType **pxtmp) \
  129. { \
  130. *pxtmp = _p; \
  131. _p = NULL; \
  132. } \
  133. inline void Copy ( SpType **pxtmp) \
  134. { \
  135. *pxtmp = _p; \
  136. if (_p != NULL) \
  137. _p->AddRef(); \
  138. } \
  139. inline void Set(SpType* p, BOOL fInc = TRUE) \
  140. { \
  141. if (_p) \
  142. { \
  143. _p->Release(); \
  144. } \
  145. _p = p; \
  146. if (fInc && _p) \
  147. { \
  148. _p->AddRef(); \
  149. } \
  150. } \
  151. inline void Attach(SpType* p) \
  152. { \
  153. Win4Assert(_p == NULL); \
  154. _p = p; \
  155. } \
  156. inline void Detach(void) \
  157. { \
  158. _p = NULL; \
  159. } \
  160. \
  161. inline SpType * operator-> () { return _p; } \
  162. inline SpType& operator * () { return *_p; } \
  163. inline operator SpType *() { return _p; } \
  164. inline SpType ** operator &() \
  165. { \
  166. Win4Assert ( _p == NULL ); \
  167. return &_p; \
  168. } \
  169. \
  170. inline SpType *Self(void) { return _p; } \
  171. \
  172. private: \
  173. SpType * _p; \
  174. inline void operator = (const SpName &) {;} \
  175. inline SpName ( const SpName &){;} \
  176. };
  177. //+-------------------------------------------------------------------------
  178. //
  179. // Macro: TRANSFER_INTERFACE
  180. //
  181. // Purpose: Transfers a specific interface from a safe object to an
  182. // interface pointer. Simple Transfer doesn't always work right
  183. // for safe objects that implement multiple interfaces; this
  184. // macro must be used
  185. //
  186. // Usage:
  187. // IStorage *pstg;
  188. // SafeFoo sfoo;
  189. // TRANSFER_INTERFACE(sfoo, IStorage, &pstg)
  190. //
  191. //--------------------------------------------------------------------------
  192. #define TRANSFER_INTERFACE(smart, iface, ppiface) \
  193. (*(ppiface) = (iface *)((smart).Self()), (smart).Detach())
  194. //+-------------------------------------------------------------------------
  195. //
  196. // Macro: SAFE_MEMALLOC_PTR
  197. //
  198. // Purpose: Pointer to memory created by MemAlloc. Supports the
  199. // -> operator. Can point to a structure.
  200. //
  201. //--------------------------------------------------------------------------
  202. // Cairo only
  203. #if WIN32 == 300
  204. #define SAFE_MEMALLOC_PTR(SpName,SpType) \
  205. class SpName INHERIT_UNWIND_IF_CAIRO \
  206. { \
  207. INLINE_UNWIND(SpName) \
  208. public: \
  209. inline SpName ( SpType * pinter=NULL) \
  210. : _p ( pinter ) \
  211. { \
  212. END_CONSTRUCTION (SpName) \
  213. } \
  214. \
  215. inline ~##SpName () \
  216. { \
  217. MemFree(_p); \
  218. _p = NULL; \
  219. } \
  220. inline void Transfer ( SpType **pxtmp) \
  221. { \
  222. *pxtmp = _p; \
  223. _p = NULL; \
  224. } \
  225. inline void Set(SpType* p) \
  226. { \
  227. MemFree(_p); \
  228. _p = p; \
  229. } \
  230. inline void Attach(SpType* p) \
  231. { \
  232. Win4Assert(_p == NULL); \
  233. _p = p; \
  234. } \
  235. inline void Detach(void) \
  236. { \
  237. _p = NULL; \
  238. } \
  239. \
  240. inline SpType * operator-> () { return _p; } \
  241. inline SpType & operator * () { return *_p; } \
  242. inline operator SpType *() { return _p; } \
  243. inline SpType ** operator &() \
  244. { \
  245. Win4Assert ( _p == NULL ); \
  246. return &_p; \
  247. } \
  248. \
  249. private: \
  250. SpType * _p; \
  251. inline void operator = (const SpName &) {;} \
  252. inline SpName ( const SpName &){;} \
  253. };
  254. //+-------------------------------------------------------------------------
  255. //
  256. // Macro: SAFE_MEMALLOC_MEMPTR
  257. //
  258. // Purpose: Pointer to memory created by MemAlloc. This class does
  259. // not supply a -> operator. Therefore, structure or class
  260. // members are not available.
  261. //
  262. //--------------------------------------------------------------------------
  263. #define SAFE_MEMALLOC_MEMPTR(SpName,SpType) \
  264. class SpName INHERIT_UNWIND_IF_CAIRO \
  265. { \
  266. INLINE_UNWIND(SpName) \
  267. public: \
  268. inline SpName ( SpType * pinter=NULL) \
  269. : _p ( pinter ) \
  270. { \
  271. END_CONSTRUCTION (SpName) \
  272. } \
  273. \
  274. inline ~##SpName () \
  275. { \
  276. MemFree(_p); \
  277. _p = NULL; \
  278. } \
  279. inline void Transfer ( SpType **pxtmp) \
  280. { \
  281. *pxtmp = _p; \
  282. _p = NULL; \
  283. } \
  284. inline void Set(SpType* p) \
  285. { \
  286. MemFree(_p); \
  287. _p = p; \
  288. } \
  289. inline void Attach(SpType* p) \
  290. { \
  291. Win4Assert(_p == NULL); \
  292. _p = p; \
  293. } \
  294. inline void Detach(void) \
  295. { \
  296. _p = NULL; \
  297. } \
  298. \
  299. inline SpType & operator * () { return *_p; } \
  300. inline operator SpType *() { return _p; } \
  301. inline SpType ** operator &() \
  302. { \
  303. Win4Assert ( _p == NULL ); \
  304. return &_p; \
  305. } \
  306. \
  307. private: \
  308. SpType * _p; \
  309. inline void operator = (const SpName &) {;} \
  310. inline SpName ( const SpName &){;} \
  311. };
  312. #endif // Cairo
  313. //+-------------------------------------------------------------------------
  314. //
  315. // Macro: SAFE_COMEMALLOC_PTR
  316. //
  317. // Purpose: Pointer to memory created by COMEMALLOC. Supports the
  318. // -> operator. Can point to a structure.
  319. //
  320. //--------------------------------------------------------------------------
  321. #define SAFE_COMEMALLOC_PTR(SpName,SpType) \
  322. class SpName INHERIT_UNWIND_IF_CAIRO \
  323. { \
  324. INLINE_UNWIND(SpName) \
  325. public: \
  326. inline SpName ( SpType * pinter=NULL) \
  327. : _p ( pinter ) \
  328. { \
  329. END_CONSTRUCTION (SpName) \
  330. } \
  331. \
  332. inline ~##SpName () \
  333. { \
  334. CoMemFree(_p); \
  335. _p = NULL; \
  336. } \
  337. inline void Transfer ( SpType **pxtmp) \
  338. { \
  339. *pxtmp = _p; \
  340. _p = NULL; \
  341. } \
  342. inline void Set(SpType* p) \
  343. { \
  344. CoMemFree(_p); \
  345. _p = p; \
  346. } \
  347. inline void Attach(SpType* p) \
  348. { \
  349. Win4Assert(_p == NULL); \
  350. _p = p; \
  351. } \
  352. inline void Detach(void) \
  353. { \
  354. _p = NULL; \
  355. } \
  356. \
  357. inline SpType * operator-> () { return _p; } \
  358. inline SpType & operator * () { return *_p; } \
  359. inline operator SpType *() { return _p; } \
  360. inline SpType ** operator &() \
  361. { \
  362. Win4Assert ( _p == NULL ); \
  363. return &_p; \
  364. } \
  365. \
  366. private: \
  367. SpType * _p; \
  368. inline void operator = (const SpName &) {;} \
  369. inline SpName ( const SpName &){;} \
  370. };
  371. //+-------------------------------------------------------------------------
  372. //
  373. // Macro: SAFE_COMEMALLOC_MEMPTR
  374. //
  375. // Purpose: Pointer to memory created by COMEMALLOC. This class does
  376. // not supply a -> operator. Therefore, structure or class
  377. // members are not available.
  378. //
  379. //--------------------------------------------------------------------------
  380. #define SAFE_COMEMALLOC_MEMPTR(SpName,SpType) \
  381. class SpName INHERIT_UNWIND_IF_CAIRO \
  382. { \
  383. INLINE_UNWIND(SpName) \
  384. public: \
  385. inline SpName ( SpType * pinter=NULL) \
  386. : _p ( pinter ) \
  387. { \
  388. END_CONSTRUCTION (SpName) \
  389. } \
  390. \
  391. inline ~##SpName () \
  392. { \
  393. CoMemFree(_p); \
  394. _p = NULL; \
  395. } \
  396. inline void Transfer ( SpType **pxtmp) \
  397. { \
  398. *pxtmp = _p; \
  399. _p = NULL; \
  400. } \
  401. inline void Set(SpType* p) \
  402. { \
  403. CoMemFree(_p); \
  404. _p = p; \
  405. } \
  406. inline void Attach(SpType* p) \
  407. { \
  408. Win4Assert(_p == NULL); \
  409. _p = p; \
  410. } \
  411. inline void Detach(void) \
  412. { \
  413. _p = NULL; \
  414. } \
  415. \
  416. inline SpType & operator * () { return *_p; } \
  417. inline operator SpType *() { return _p; } \
  418. inline SpType ** operator &() \
  419. { \
  420. Win4Assert ( _p == NULL ); \
  421. return &_p; \
  422. } \
  423. \
  424. private: \
  425. SpType * _p; \
  426. inline void operator = (const SpName &) {;} \
  427. inline SpName ( const SpName &){;} \
  428. };
  429. //+-------------------------------------------------------------------------
  430. //
  431. // Macro: SAFE_HEAP_PTR
  432. //
  433. // Purpose: Pointer to memory created by operator new. Supports the
  434. // -> operator. Can point to a structure.
  435. //
  436. //--------------------------------------------------------------------------
  437. #define SAFE_HEAP_PTR(SpName,SpType) \
  438. class SpName INHERIT_UNWIND_IF_CAIRO \
  439. { \
  440. INLINE_UNWIND(SpName) \
  441. public: \
  442. inline SpName ( SpType * pinter=NULL) \
  443. : _p ( pinter ) \
  444. { \
  445. END_CONSTRUCTION (SpName) \
  446. } \
  447. \
  448. inline ~##SpName () \
  449. { \
  450. delete _p; \
  451. _p = NULL; \
  452. } \
  453. inline void Transfer ( SpType **pxtmp) \
  454. { \
  455. *pxtmp = _p; \
  456. _p = NULL; \
  457. } \
  458. inline void Set(SpType* p) \
  459. { \
  460. delete _p; \
  461. _p = p; \
  462. } \
  463. inline void Attach(SpType* p) \
  464. { \
  465. Win4Assert(_p == NULL); \
  466. _p = p; \
  467. } \
  468. inline void Detach(void) \
  469. { \
  470. _p = NULL; \
  471. } \
  472. \
  473. inline SpType * operator-> () { return _p; } \
  474. inline SpType & operator * () { return *_p; } \
  475. inline operator SpType *() { return _p; } \
  476. inline SpType ** operator &() \
  477. { \
  478. Win4Assert ( _p == NULL ); \
  479. return &_p; \
  480. } \
  481. \
  482. private: \
  483. SpType * _p; \
  484. inline void operator = (const SpName &) {;} \
  485. inline SpName ( const SpName &){;} \
  486. };
  487. //+-------------------------------------------------------------------------
  488. //
  489. // Macro: SAFE_HEAP_MEMPTR
  490. //
  491. // Purpose: Pointer to memory created by operator new. This class does
  492. // not supply a -> operator. Therefore, structure or class
  493. // members are not available.
  494. //
  495. //--------------------------------------------------------------------------
  496. #define SAFE_HEAP_MEMPTR(SpName,SpType) \
  497. class SpName INHERIT_UNWIND_IF_CAIRO \
  498. { \
  499. INLINE_UNWIND(SpName) \
  500. public: \
  501. inline SpName ( SpType * pinter=NULL) \
  502. : _p ( pinter ) \
  503. { \
  504. END_CONSTRUCTION (SpName) \
  505. } \
  506. \
  507. inline ~##SpName () \
  508. { \
  509. delete _p; \
  510. _p = NULL; \
  511. } \
  512. inline void Transfer ( SpType **pxtmp) \
  513. { \
  514. *pxtmp = _p; \
  515. _p = NULL; \
  516. } \
  517. inline void Set(SpType* p) \
  518. { \
  519. delete _p; \
  520. _p = p; \
  521. } \
  522. inline void Attach(SpType* p) \
  523. { \
  524. Win4Assert(_p == NULL); \
  525. _p = p; \
  526. } \
  527. inline void Detach(void) \
  528. { \
  529. _p = NULL; \
  530. } \
  531. \
  532. inline SpType & operator * () { return *_p; } \
  533. inline operator SpType *() { return _p; } \
  534. inline SpType ** operator &() \
  535. { \
  536. Win4Assert ( _p == NULL ); \
  537. return &_p; \
  538. } \
  539. \
  540. private: \
  541. SpType * _p; \
  542. inline void operator = (const SpName &) {;} \
  543. inline SpName ( const SpName &){;} \
  544. };
  545. //+-------------------------------------------------------------------------
  546. //
  547. // Macro: SAFE_XXX_HANDLE
  548. //
  549. // Purpose: Smart resource to a WIN 32, WIN 32 Find or NT HANDLE.
  550. //
  551. // Usage: SAFE_WIN32_HANDLE(XWIN32Handle)
  552. // SAFE_WIN32FIND_HANDLE(XWIN32FindHandle)
  553. // SAFE_NT_HANDLE(XNtHandle)
  554. //
  555. //--------------------------------------------------------------------------
  556. #ifdef WIN32
  557. #define SAFE_WIN32_HANDLE(ShName) \
  558. \
  559. class ShName INHERIT_UNWIND_IF_CAIRO \
  560. { \
  561. INLINE_UNWIND(ShName) \
  562. public: \
  563. \
  564. inline ShName (HANDLE handle = NULL) \
  565. : _handle(handle) \
  566. { \
  567. END_CONSTRUCTION(ShName) \
  568. } \
  569. \
  570. inline ~##ShName () \
  571. { \
  572. if ((_handle != INVALID_HANDLE_VALUE) && (_handle != NULL)) \
  573. { \
  574. CloseHandle(_handle); \
  575. } \
  576. } \
  577. \
  578. inline void Transfer(HANDLE *phandle) \
  579. { \
  580. *phandle = _handle; \
  581. _handle = NULL; \
  582. } \
  583. inline void Set(HANDLE h) \
  584. { \
  585. if (_handle != INVALID_HANDLE_VALUE && _handle != NULL) \
  586. { \
  587. CloseHandle(_handle); \
  588. } \
  589. _handle = h; \
  590. } \
  591. inline void Attach(HANDLE h) \
  592. { \
  593. Win4Assert(_handle == NULL); \
  594. _handle = h; \
  595. } \
  596. inline void Detach(void) \
  597. { \
  598. _handle = NULL; \
  599. } \
  600. \
  601. inline operator HANDLE () \
  602. { \
  603. return(_handle); \
  604. } \
  605. \
  606. inline HANDLE operator= (HANDLE handle) \
  607. { \
  608. Set(handle); \
  609. return(_handle); \
  610. } \
  611. \
  612. inline BOOL operator==(HANDLE handle) \
  613. { \
  614. if (_handle == handle) \
  615. { \
  616. return(TRUE); \
  617. } \
  618. return(FALSE); \
  619. } \
  620. \
  621. inline HANDLE *operator&() \
  622. { \
  623. Win4Assert((_handle==NULL) || (_handle==INVALID_HANDLE_VALUE));\
  624. return(&_handle); \
  625. } \
  626. \
  627. private: \
  628. \
  629. HANDLE _handle; \
  630. \
  631. inline VOID operator= (const ShName &) {;} \
  632. inline ShName (const ShName &) {;} \
  633. \
  634. };
  635. #define SAFE_WIN32FIND_HANDLE(ShName) \
  636. \
  637. class ShName INHERIT_UNWIND_IF_CAIRO \
  638. { \
  639. INLINE_UNWIND(ShName) \
  640. public: \
  641. \
  642. inline ShName (HANDLE handle = NULL) \
  643. : _handle(handle) \
  644. { \
  645. END_CONSTRUCTION(ShName) \
  646. } \
  647. \
  648. inline ~##ShName () \
  649. { \
  650. if ((_handle != INVALID_HANDLE_VALUE) && (_handle != NULL)) \
  651. { \
  652. FindClose(_handle); \
  653. } \
  654. } \
  655. \
  656. inline void Transfer(HANDLE *phandle) \
  657. { \
  658. *phandle = _handle; \
  659. _handle = NULL; \
  660. } \
  661. inline void Set(HANDLE h) \
  662. { \
  663. if (_handle != INVALID_HANDLE_VALUE && _handle != NULL) \
  664. { \
  665. FindClose(_handle); \
  666. } \
  667. _handle = h; \
  668. } \
  669. inline void Attach(HANDLE h) \
  670. { \
  671. Win4Assert(_handle == NULL); \
  672. _handle = h; \
  673. } \
  674. inline void Detach(void) \
  675. { \
  676. _handle = NULL; \
  677. } \
  678. \
  679. inline operator HANDLE () \
  680. { \
  681. return(_handle); \
  682. } \
  683. \
  684. inline HANDLE operator= (HANDLE handle) \
  685. { \
  686. Set(handle); \
  687. return(_handle); \
  688. } \
  689. \
  690. inline BOOL operator==(HANDLE handle) \
  691. { \
  692. if (_handle == handle) \
  693. { \
  694. return(TRUE); \
  695. } \
  696. return(FALSE); \
  697. } \
  698. \
  699. inline HANDLE *operator&() \
  700. { \
  701. Win4Assert((_handle==NULL) || (_handle==INVALID_HANDLE_VALUE));\
  702. return(&_handle); \
  703. } \
  704. \
  705. private: \
  706. \
  707. HANDLE _handle; \
  708. \
  709. inline VOID operator= (const ShName &) {;} \
  710. inline ShName (const ShName &) {;} \
  711. \
  712. };
  713. #endif // WIN32
  714. // Only available on NT platforms
  715. #if WIN32 == 100 || WIN32 == 300
  716. #define SAFE_NT_HANDLE(ShName) \
  717. \
  718. class ShName INHERIT_UNWIND_IF_CAIRO \
  719. { \
  720. INLINE_UNWIND(ShName) \
  721. public: \
  722. \
  723. inline ShName (HANDLE handle = NULL) \
  724. : _handle(handle) \
  725. { \
  726. END_CONSTRUCTION(ShName) \
  727. } \
  728. \
  729. inline ~##ShName () \
  730. { \
  731. if ((_handle != INVALID_HANDLE_VALUE) && (_handle != NULL)) \
  732. { \
  733. NtClose(_handle); \
  734. } \
  735. } \
  736. \
  737. inline void Transfer(HANDLE *phandle) \
  738. { \
  739. *phandle = _handle; \
  740. _handle = NULL; \
  741. } \
  742. inline void Set(HANDLE h) \
  743. { \
  744. if (_handle != INVALID_HANDLE_VALUE && _handle != NULL) \
  745. { \
  746. NtClose(_handle); \
  747. } \
  748. _handle = h; \
  749. } \
  750. inline void Attach(HANDLE h) \
  751. { \
  752. Win4Assert(_handle == NULL); \
  753. _handle = h; \
  754. } \
  755. inline void Detach(void) \
  756. { \
  757. _handle = NULL; \
  758. } \
  759. \
  760. inline operator HANDLE () \
  761. { \
  762. return(_handle); \
  763. } \
  764. \
  765. inline HANDLE operator= (HANDLE handle) \
  766. { \
  767. Set(handle); \
  768. return(_handle); \
  769. } \
  770. \
  771. inline BOOL operator==(HANDLE handle) \
  772. { \
  773. if (_handle == handle) \
  774. { \
  775. return(TRUE); \
  776. } \
  777. return(FALSE); \
  778. } \
  779. \
  780. inline HANDLE *operator&() \
  781. { \
  782. Win4Assert((_handle==NULL) || (_handle==INVALID_HANDLE_VALUE));\
  783. return(&_handle); \
  784. } \
  785. \
  786. private: \
  787. \
  788. HANDLE _handle; \
  789. \
  790. inline VOID operator= (const ShName &) {;} \
  791. inline ShName (const ShName &) {;} \
  792. \
  793. };
  794. #define SAFE_NT_HANDLE_NO_UNWIND(ShName) \
  795. \
  796. class ShName \
  797. { \
  798. public: \
  799. \
  800. inline ShName (HANDLE handle = NULL) \
  801. : _handle(handle) \
  802. { \
  803. } \
  804. \
  805. inline ~##ShName () \
  806. { \
  807. if ((_handle != INVALID_HANDLE_VALUE) && (_handle != NULL)) \
  808. { \
  809. NtClose(_handle); \
  810. } \
  811. } \
  812. \
  813. inline void Transfer(HANDLE *phandle) \
  814. { \
  815. *phandle = _handle; \
  816. _handle = NULL; \
  817. } \
  818. inline void Set(HANDLE h) \
  819. { \
  820. if (_handle != INVALID_HANDLE_VALUE && _handle != NULL) \
  821. { \
  822. NtClose(_handle); \
  823. } \
  824. _handle = h; \
  825. } \
  826. inline void Attach(HANDLE h) \
  827. { \
  828. Win4Assert(_handle == NULL); \
  829. _handle = h; \
  830. } \
  831. inline void Detach(void) \
  832. { \
  833. _handle = NULL; \
  834. } \
  835. \
  836. inline operator HANDLE () \
  837. { \
  838. return(_handle); \
  839. } \
  840. \
  841. inline HANDLE operator= (HANDLE handle) \
  842. { \
  843. Set(handle); \
  844. return(_handle); \
  845. } \
  846. \
  847. inline BOOL operator==(HANDLE handle) \
  848. { \
  849. if (_handle == handle) \
  850. { \
  851. return(TRUE); \
  852. } \
  853. return(FALSE); \
  854. } \
  855. \
  856. inline HANDLE *operator&() \
  857. { \
  858. Win4Assert((_handle==NULL) || (_handle==INVALID_HANDLE_VALUE));\
  859. return(&_handle); \
  860. } \
  861. \
  862. private: \
  863. \
  864. HANDLE _handle; \
  865. \
  866. inline VOID operator= (const ShName &) {;} \
  867. inline ShName (const ShName &) {;} \
  868. \
  869. };
  870. #endif // NT platforms
  871. //+-------------------------------------------------------------------------
  872. //
  873. // UNWINDABLE_WRAPPER allows you to declare an unwindable wrapper class
  874. // for an existing class to make it exception safe
  875. //
  876. // class Foo;
  877. // UNWINDABLE_WRAPPER(SafeCFoo, CFoo);
  878. //
  879. // UNWINDABLE_WRAPPER_ARGS is an alternate form that allows arguments to
  880. // the constructor
  881. //
  882. // class Foo;
  883. // Foo::Foo(int foo);
  884. // UNWINDABLE_WRAPPER_ARGS(SafeCFoo, CFoo, (int foo), (foo));
  885. //
  886. //--------------------------------------------------------------------------
  887. // Cairo only
  888. #if WIN32 == 300
  889. #define UNWINDABLE_WRAPPER(UwName, Class) \
  890. class UwName : INHERIT_UNWIND, public Class \
  891. { \
  892. INLINE_UNWIND(UwName) \
  893. public: \
  894. inline UwName(void) \
  895. { \
  896. END_CONSTRUCTION(UwName); \
  897. } \
  898. inline ~##UwName(void) \
  899. { \
  900. } \
  901. }
  902. #define UNWINDABLE_WRAPPER_ARGS(UwName, Class, CtorDecl, CtorArgs) \
  903. class UwName : INHERIT_UNWIND, public Class \
  904. { \
  905. INLINE_UNWIND(UwName) \
  906. public: \
  907. inline UwName CtorDecl : Class CtorArgs \
  908. { \
  909. END_CONSTRUCTION(UwName); \
  910. } \
  911. inline ~##UwName(void) \
  912. { \
  913. } \
  914. }
  915. #endif // Cairo only
  916. #endif // _SAFEPNT_HXX_