OLD | NEW |
(Empty) | |
| 1 /** |
| 2 * \file handle.h The "install session" is the context for all custom installati
on behavior. |
| 3 */ |
| 4 |
| 5 #ifndef HANDLE_H |
| 6 #define HANDLE_H |
| 7 |
| 8 #include "windows.h" |
| 9 #include "msi.h" |
| 10 |
| 11 //------------------------------------------------------- |
| 12 // msi_handle |
| 13 //------------------------------------------------------- |
| 14 /** |
| 15 * Disambiguation class holding an MSIHANDLE. |
| 16 * |
| 17 * We need constructors for Record that accept both handles and record counts. |
| 18 * Since the underlying type of a handle is integral, without its own type these
constructors are ambiguous. |
| 19 */ |
| 20 class msi_handle |
| 21 { |
| 22 MSIHANDLE _handle ; |
| 23 |
| 24 public: |
| 25 /** |
| 26 * Ordinary constructor is explicit to avoid inadvertent conversions. |
| 27 */ |
| 28 explicit msi_handle( MSIHANDLE handle ) |
| 29 : _handle( handle ) |
| 30 {} |
| 31 |
| 32 operator MSIHANDLE() |
| 33 { |
| 34 return _handle ; |
| 35 } |
| 36 } ; |
| 37 |
| 38 //------------------------------------------------------- |
| 39 // Handle Policies |
| 40 //------------------------------------------------------- |
| 41 /** |
| 42 * Policy class that indicates that a raw handle may not be zero. |
| 43 */ |
| 44 template< class T > |
| 45 struct Disallow_Null |
| 46 { |
| 47 inline static bool prohibited_always() { return true ; } |
| 48 inline static bool prohibited_from_outside() { return true ; } |
| 49 } ; |
| 50 |
| 51 /** |
| 52 * Policy class that indicates that a raw handle may be zero only when construct
ed internally. |
| 53 */ |
| 54 template< class T > |
| 55 struct Special_Null |
| 56 { |
| 57 inline static bool prohibited_always() { return false ; } |
| 58 inline static bool prohibited_from_outside() { return true ; } |
| 59 } ; |
| 60 |
| 61 /** |
| 62 * Policy class that indicates that a raw handle is permitted to be zero. |
| 63 */ |
| 64 template< class T > |
| 65 struct Allow_Null |
| 66 { |
| 67 inline static bool prohibited_always() { return false ; } |
| 68 inline static bool prohibited_from_outside() { return false ; } |
| 69 } ; |
| 70 |
| 71 /** |
| 72 * Policy class that does not close a file handle when it goes out of scope |
| 73 */ |
| 74 template< class T > |
| 75 class No_Destruction |
| 76 { |
| 77 public: |
| 78 inline static void close( T handle ) {} ; |
| 79 } ; |
| 80 |
| 81 /** |
| 82 * Policy class that does not close a file handle when it goes out of scope |
| 83 */ |
| 84 template< class T > |
| 85 class MSI_Generic_Destruction |
| 86 { |
| 87 public: |
| 88 inline static void close( T handle ) |
| 89 { |
| 90 MsiCloseHandle( handle ) ; |
| 91 } ; |
| 92 } ; |
| 93 |
| 94 |
| 95 //------------------------------------------------------- |
| 96 // Handle |
| 97 //------------------------------------------------------- |
| 98 /** |
| 99 * Raw handle is the base class for the generic handle. |
| 100 * |
| 101 * Raw handles always allow null, so that generic handles may allow or disallow
them as they please. |
| 102 */ |
| 103 template< class T > |
| 104 class handle_raw |
| 105 { |
| 106 protected: |
| 107 /** |
| 108 * The underlying handle. |
| 109 * |
| 110 * This is the only data member of the class. |
| 111 * Everything else is for life cycle and type conversion. |
| 112 */ |
| 113 T _handle ; |
| 114 |
| 115 /** |
| 116 * Basic constructor is protected to cede creation policy entirely to subclass
es. |
| 117 */ |
| 118 handle_raw( T _handle ) |
| 119 : _handle( _handle ) |
| 120 {} |
| 121 |
| 122 public: |
| 123 /** |
| 124 * Conversion operator to underlying handle type. |
| 125 */ |
| 126 operator T() |
| 127 { |
| 128 return _handle ; |
| 129 } |
| 130 |
| 131 struct null_handle_error |
| 132 : public std::runtime_error |
| 133 { |
| 134 null_handle_error() |
| 135 : std::runtime_error( "May not initialize with null handle" ) |
| 136 {} |
| 137 } ; |
| 138 } ; |
| 139 |
| 140 /* |
| 141 * Handle class |
| 142 */ |
| 143 template< |
| 144 class T, |
| 145 template <class> class Null_Policy, |
| 146 template <class> class Destruction_Policy = No_Destruction |
| 147 > |
| 148 class handle |
| 149 : public handle_raw< T > |
| 150 { |
| 151 protected: |
| 152 /** |
| 153 * Tag class for null record constructor |
| 154 */ |
| 155 class null_t {} ; |
| 156 |
| 157 /** |
| 158 * Null handle constructor initializes its handle to zero. |
| 159 * |
| 160 * The null record constructor avoids the ordinary check that an external hand
le not be zero. |
| 161 * It's declared protected so that it's not ordinarily visible. |
| 162 * To use this constructor, derive from it and add a friend declaration. |
| 163 */ |
| 164 handle( null_t ) |
| 165 : handle_raw( 0 ) |
| 166 { |
| 167 if ( Null_Policy< T >::prohibited_always() ) |
| 168 { |
| 169 throw null_handle_error() ; |
| 170 } |
| 171 } |
| 172 |
| 173 public: |
| 174 /** |
| 175 * Ordinary constructor. |
| 176 * |
| 177 * A check for a non-zero handle compiles in conditionally based on the Null_P
olicy. |
| 178 */ |
| 179 handle( T _handle ) |
| 180 : handle_raw( _handle ) |
| 181 { |
| 182 if ( Null_Policy< T >::prohibited_from_outside() && _handle == 0 ) |
| 183 { |
| 184 throw null_handle_error() ; |
| 185 } |
| 186 } |
| 187 |
| 188 /** |
| 189 * Destructor |
| 190 * |
| 191 * The check for a non-zero handle compiles out conditionally based on Null_Po
licy. |
| 192 * The specific function used to close the handle is given by the Destruction_
Policy. |
| 193 */ |
| 194 ~handle() |
| 195 { |
| 196 if ( Null_Policy< T >::prohibited_always() || ( _handle != 0 ) ) { |
| 197 Destruction_Policy< T >::close( _handle ) ; |
| 198 } |
| 199 } |
| 200 |
| 201 } ; |
| 202 |
| 203 #endif |
OLD | NEW |