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.

587 lines
17 KiB

  1. /*++
  2. Copyright (c) Microsoft Dorporation
  3. Module Name:
  4. Handle.h
  5. Abstract:
  6. Simple exception safe wrappers of Win32 "handle" types, defining "handle" loosely.
  7. DFile
  8. DDynamicLinkLibrary
  9. DFindFile (should be named DFindFileHandle, see NVseeLibIo::CFindFile vs. NVseeLibIo::CFindFileHandle
  10. DFindFile includes a WIN32_FIND_DATA, DFindFileHandle does not.)
  11. DFileMapping
  12. DMappedViewOfFile
  13. DRegKey
  14. See also:
  15. NVseeLibReg::CRegKey
  16. NVseeLibIo::CFile
  17. NVseeLibIo::CFileMapping
  18. NVseeLibIo::CMappedViewOfFile
  19. NVseeLibIo::CFindFullPath
  20. NVseeLibModule::CDynamicLinkLibrary
  21. etc.
  22. Author:
  23. Jay Krell (JayKrell) May 2000
  24. Revision History:
  25. --*/
  26. #pragma once
  27. #include <stddef.h>
  28. #include "windows.h"
  29. #include "PreserveLastError.h"
  30. template <void* const* invalidValue, typename Closer>
  31. class DHandleTemplate
  32. {
  33. public:
  34. // void* instead of HANDLE to fudge views
  35. // HANDLE is void*
  36. DHandleTemplate(const void* handle = *invalidValue);
  37. ~DHandleTemplate();
  38. BOOL Win32Close();
  39. void* Detach();
  40. void operator=(const void*);
  41. operator void*() const;
  42. operator const void*() const;
  43. // private
  44. class DSmartPointerPointerOrDumbPointerPointer
  45. {
  46. public:
  47. DSmartPointerPointerOrDumbPointerPointer(DHandleTemplate* p) : m(p) { }
  48. operator DHandleTemplate*() { return m; }
  49. operator void**() { /*assert((**m).m_handle == *invalidValue);*/ return &(*m).m_handle; }
  50. DHandleTemplate* m;
  51. };
  52. DSmartPointerPointerOrDumbPointerPointer operator&() { return DSmartPointerPointerOrDumbPointerPointer(this); }
  53. void* m_handle;
  54. static void* GetInvalidValue() { return *invalidValue; }
  55. BOOL IsValid() const { return m_handle != *invalidValue; }
  56. private:
  57. DHandleTemplate(const DHandleTemplate&); // deliberately not implemented
  58. void operator=(const DHandleTemplate&); // deliberately not implemented
  59. };
  60. __declspec(selectany) extern void* const hhInvalidValue = INVALID_HANDLE_VALUE;
  61. __declspec(selectany) extern void* const hhNull = NULL;
  62. /* This closes a Win32 event log handle for writing. */
  63. class DOperatorDeregisterEventSource
  64. {
  65. public: BOOL operator()(void* handle) const;
  66. };
  67. /* This closes a Win32 event log handle for reading. */
  68. class DOperatorCloseEventLog
  69. {
  70. public: BOOL operator()(void* handle) const;
  71. };
  72. /* This closes file, event, mutex, semaphore, etc. kernel objects */
  73. class DOperatorCloseHandle
  74. {
  75. public: BOOL operator()(void* handle) const;
  76. };
  77. //
  78. // Dloses HCRYPTHASH objects
  79. //
  80. class DOperatorCloseCryptHash
  81. {
  82. public: BOOL operator()(void* handle) const;
  83. };
  84. /* this closes FindFirstFile/FindNextFile */
  85. class DOperatorFindClose
  86. {
  87. public: BOOL operator()(void* handle) const;
  88. };
  89. /* this closes MapViewOfFile */
  90. class DOperatorUnmapViewOfFile
  91. {
  92. public: BOOL operator()(void* handle) const;
  93. };
  94. /* this closes FreeLibrary */
  95. class DOperatorFreeLibrary
  96. {
  97. public: BOOL operator()(void* handle) const;
  98. };
  99. /* this closes DreateActCtx/AddRefActCtx */
  100. class DOperatorReleaseActCtx
  101. {
  102. public: BOOL operator()(void* handle) const;
  103. };
  104. /* this closes DreateActCtx/AddRefActCtx */
  105. class DOperatorEndUpdateResource
  106. {
  107. public: BOOL operator()(void* handle) const;
  108. };
  109. class DFindFile : public DHandleTemplate<&hhInvalidValue, DOperatorFindClose>
  110. {
  111. private:
  112. typedef DHandleTemplate<&hhInvalidValue, DOperatorFindClose> Base;
  113. public:
  114. DFindFile(void* handle = INVALID_HANDLE_VALUE) : Base(handle) { }
  115. HRESULT HrCreate(PCSTR nameOrWildcard, WIN32_FIND_DATAA*);
  116. HRESULT HrCreate(PCWSTR nameOrWildcard, WIN32_FIND_DATAW*);
  117. BOOL Win32Create( PCSTR nameOrWildcard, WIN32_FIND_DATAA*);
  118. BOOL Win32Create(PCWSTR nameOrWildcard, WIN32_FIND_DATAW*);
  119. void operator=(void* v) { Base::operator=(v); }
  120. private:
  121. DFindFile(const DFindFile &); // intentionally not implemented
  122. void operator =(const DFindFile &); // intentionally not implemented
  123. };
  124. // createfile
  125. class DFile : public DHandleTemplate<&hhInvalidValue, DOperatorCloseHandle>
  126. {
  127. private:
  128. typedef DHandleTemplate<&hhInvalidValue, DOperatorCloseHandle> Base;
  129. public:
  130. DFile(void* handle = INVALID_HANDLE_VALUE) : Base(handle) { }
  131. HRESULT HrCreate( PCSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL);
  132. HRESULT HrCreate(PCWSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL);
  133. BOOL Win32Create( PCSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL);
  134. BOOL Win32Create(PCWSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL);
  135. BOOL Win32GetSize(ULONGLONG &rulSize) const;
  136. void operator=(void* v) { Base::operator=(v); }
  137. private:
  138. DFile(const DFile &); // intentionally not implemented
  139. void operator =(const DFile &); // intentionally not implemented
  140. };
  141. class DFileMapping : public DHandleTemplate<&hhNull, DOperatorCloseHandle>
  142. {
  143. private:
  144. typedef DHandleTemplate<&hhNull, DOperatorCloseHandle> Base;
  145. public:
  146. DFileMapping(void* handle = NULL) : Base(handle) { }
  147. HRESULT HrCreate(void* file, DWORD flProtect, ULONGLONG maximumSize=0, PCWSTR name=0);
  148. BOOL Win32Create(void* file, DWORD flProtect, ULONGLONG maximumSize=0, PCWSTR name=0);
  149. void operator=(void* v) { Base::operator=(v); }
  150. private:
  151. DFileMapping(const DFileMapping &); // intentionally not implemented
  152. void operator =(const DFileMapping &); // intentionally not implemented
  153. };
  154. class DMappedViewOfFile : public DHandleTemplate<&hhNull, DOperatorUnmapViewOfFile>
  155. {
  156. private:
  157. typedef DHandleTemplate<&hhNull, DOperatorUnmapViewOfFile> Base;
  158. public:
  159. DMappedViewOfFile(void* handle = NULL) : Base(handle) { }
  160. HRESULT HrCreate(void* fileMapping, DWORD access, ULONGLONG offset=0, size_t size=0);
  161. BOOL Win32Create(void* fileMapping, DWORD access, ULONGLONG offset=0, size_t size=0);
  162. void operator=(void* v) { Base::operator=(v); }
  163. operator void*() { return Base::operator void*(); }
  164. private:
  165. DMappedViewOfFile(const DMappedViewOfFile &); // intentionally not implemented
  166. void operator =(const DMappedViewOfFile &); // intentionally not implemented
  167. operator void*() const; // intentionally not implemented
  168. };
  169. class DDynamicLinkLibrary : public DHandleTemplate<&hhNull, DOperatorFreeLibrary>
  170. {
  171. private:
  172. typedef DHandleTemplate<&hhNull, DOperatorFreeLibrary> Base;
  173. public:
  174. DDynamicLinkLibrary(void* handle = NULL) : Base(handle) { }
  175. // if you were writing a linker, this would be ambiguous, but
  176. // otherwise it fits with the the general NT idea that you are
  177. // initializing an object, not creating a "physical" think (if bits
  178. // on disk are physical..), like DreateFile
  179. BOOL Win32Create(PCWSTR file, DWORD flags = 0);
  180. template <typename PointerToFunction>
  181. BOOL GetProcAddress(PCSTR procName, PointerToFunction* ppfn)
  182. {
  183. return (*ppfn = reinterpret_cast<PointerToFunction>(::GetProcAddress(*this, procName))) != NULL;
  184. }
  185. operator HMODULE() { return reinterpret_cast<HMODULE>(operator void*()); }
  186. HMODULE Detach() { return reinterpret_cast<HMODULE>(Base::Detach()); }
  187. void operator=(void* v) { Base::operator=(v); }
  188. private:
  189. DDynamicLinkLibrary(const DDynamicLinkLibrary &); // intentionally not implemented
  190. void operator =(const DDynamicLinkLibrary &); // intentionally not implemented
  191. };
  192. class DResourceUpdateHandle : public DHandleTemplate<&hhNull, DOperatorEndUpdateResource>
  193. {
  194. private:
  195. typedef DHandleTemplate<&hhNull, DOperatorEndUpdateResource> Base;
  196. public:
  197. ~DResourceUpdateHandle() { }
  198. DResourceUpdateHandle(void* handle = NULL) : Base(handle) { }
  199. BOOL Win32Create(IN PCWSTR FileName, IN BOOL DeleteExistingResources);
  200. BOOL UpdateResource(
  201. IN PCWSTR Type,
  202. IN PCWSTR Name,
  203. IN WORD Language,
  204. IN void* Data,
  205. IN DWORD Size
  206. );
  207. BOOL Win32Close(BOOL Discard);
  208. void operator=(void* v) { Base::operator=(v); }
  209. private:
  210. DResourceUpdateHandle(const DResourceUpdateHandle &); // intentionally not implemented
  211. void operator =(const DResourceUpdateHandle &); // intentionally not implemented
  212. };
  213. /*--------------------------------------------------------------------------
  214. DFindFile
  215. --------------------------------------------------------------------------*/
  216. inline BOOL
  217. DFindFile::Win32Create(
  218. PCSTR nameOrWildcard,
  219. WIN32_FIND_DATAA *data
  220. )
  221. {
  222. BOOL fSuccess = false;
  223. FN_TRACE_WIN32(fSuccess);
  224. HANDLE hTemp = ::FindFirstFileA(nameOrWildcard, data);
  225. if (hTemp == INVALID_HANDLE_VALUE)
  226. {
  227. TRACE_WIN32_FAILURE_ORIGINATION(FindFirstFileA);
  228. goto Exit;
  229. }
  230. (*this) = hTemp;
  231. fSuccess = true;
  232. Exit:
  233. return fSuccess;
  234. }
  235. inline BOOL
  236. DFindFile::Win32Create(
  237. PCWSTR nameOrWildcard,
  238. WIN32_FIND_DATAW *data
  239. )
  240. {
  241. BOOL fSuccess = FALSE;
  242. FN_TRACE_WIN32(fSuccess);
  243. HANDLE hTemp = ::FindFirstFileW(nameOrWildcard, data);
  244. if (hTemp == INVALID_HANDLE_VALUE)
  245. {
  246. TRACE_WIN32_FAILURE_ORIGINATION(FindFirstFileW);
  247. goto Exit;
  248. }
  249. (*this) = hTemp;
  250. fSuccess = true;
  251. Exit:
  252. return fSuccess;
  253. }
  254. inline HRESULT
  255. DFindFile::HrCreate(
  256. PCSTR nameOrWildcard,
  257. WIN32_FIND_DATAA *data
  258. )
  259. {
  260. HRESULT hr = HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR);
  261. FN_TRACE_HR(hr);
  262. IFW32FALSE_EXIT(this->Win32Create(nameOrWildcard, data));
  263. hr = NOERROR;
  264. Exit:
  265. return hr;
  266. }
  267. inline HRESULT DFindFile::HrCreate(PCWSTR nameOrWildcard, WIN32_FIND_DATAW* data)
  268. {
  269. HRESULT hr = HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR);
  270. FN_TRACE_HR(hr);
  271. IFW32FALSE_EXIT(this->Win32Create(nameOrWildcard, data));
  272. hr = NOERROR;
  273. Exit:
  274. return hr;
  275. }
  276. /*--------------------------------------------------------------------------
  277. DFile
  278. --------------------------------------------------------------------------*/
  279. inline BOOL
  280. DFile::Win32Create(
  281. PCSTR name,
  282. DWORD access,
  283. DWORD share,
  284. DWORD openOrCreate,
  285. DWORD flagsAndAttributes
  286. )
  287. {
  288. HANDLE hTemp = ::CreateFileA(name, access, share, NULL, openOrCreate, flagsAndAttributes, NULL);
  289. if (hTemp == INVALID_HANDLE_VALUE)
  290. return false;
  291. operator=(hTemp);
  292. return true;
  293. }
  294. inline BOOL
  295. DFile::Win32Create(
  296. PCWSTR name,
  297. DWORD access,
  298. DWORD share,
  299. DWORD openOrCreate,
  300. DWORD flagsAndAttributes
  301. )
  302. {
  303. HANDLE hTemp = ::CreateFileW(name, access, share, NULL, openOrCreate, flagsAndAttributes, NULL);
  304. if (hTemp == INVALID_HANDLE_VALUE)
  305. return false;
  306. operator=(hTemp);
  307. return true;
  308. }
  309. inline HRESULT DFile::HrCreate(PCSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD flagsAndAttributes)
  310. {
  311. if (!this->Win32Create(name, access, share, openOrCreate, flagsAndAttributes))
  312. return HRESULT_FROM_WIN32(::GetLastError());
  313. return NOERROR;
  314. }
  315. inline HRESULT DFile::HrCreate(PCWSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD flagsAndAttributes)
  316. {
  317. if (!this->Win32Create(name, access, share, openOrCreate, flagsAndAttributes))
  318. return HRESULT_FROM_WIN32(::GetLastError());
  319. return NOERROR;
  320. }
  321. inline BOOL
  322. DFile::Win32GetSize(ULONGLONG &rulSize) const
  323. {
  324. DWORD highPart = 0;
  325. DWORD lastError = NO_ERROR;
  326. DWORD lowPart = GetFileSize(m_handle, &highPart);
  327. if (lowPart == INVALID_FILE_SIZE && (lastError = ::GetLastError()) != NO_ERROR)
  328. {
  329. return false;
  330. }
  331. ULARGE_INTEGER liSize;
  332. liSize.LowPart = lowPart;
  333. liSize.HighPart = highPart;
  334. rulSize = liSize.QuadPart;
  335. return true;
  336. }
  337. /*--------------------------------------------------------------------------
  338. DFileMapping
  339. --------------------------------------------------------------------------*/
  340. inline HRESULT
  341. DFileMapping::HrCreate(void* file, DWORD flProtect, ULONGLONG maximumSize, PCWSTR name)
  342. {
  343. LARGE_INTEGER liMaximumSize;
  344. liMaximumSize.QuadPart = maximumSize;
  345. HANDLE hTemp = ::CreateFileMappingW(file, NULL, flProtect, liMaximumSize.HighPart, liMaximumSize.LowPart, name);
  346. if (hTemp == NULL)
  347. return HRESULT_FROM_WIN32(::GetLastError());
  348. operator=(hTemp);
  349. return S_OK;
  350. }
  351. inline BOOL
  352. DFileMapping::Win32Create(
  353. void* file,
  354. DWORD flProtect,
  355. ULONGLONG maximumSize,
  356. PCWSTR name
  357. )
  358. {
  359. return SUCCEEDED(this->HrCreate(file, flProtect, maximumSize, name));
  360. }
  361. inline HRESULT
  362. DMappedViewOfFile::HrCreate(
  363. void* fileMapping,
  364. DWORD access,
  365. ULONGLONG offset,
  366. size_t size
  367. )
  368. {
  369. ULARGE_INTEGER liOffset;
  370. liOffset.QuadPart = offset;
  371. void* pvTemp = ::MapViewOfFile(fileMapping, access, liOffset.HighPart, liOffset.LowPart, size);
  372. if (pvTemp == NULL)
  373. return HRESULT_FROM_WIN32(::GetLastError());
  374. (*this) = pvTemp;
  375. return S_OK;
  376. }
  377. inline BOOL
  378. DMappedViewOfFile::Win32Create(void* fileMapping, DWORD access, ULONGLONG offset, size_t size)
  379. {
  380. return SUCCEEDED(this->HrCreate(fileMapping, access, offset, size));
  381. }
  382. /*--------------------------------------------------------------------------
  383. DDynamicLinkLibrary
  384. --------------------------------------------------------------------------*/
  385. inline BOOL
  386. DDynamicLinkLibrary::Win32Create(
  387. PCWSTR file,
  388. DWORD flags
  389. )
  390. {
  391. void* temp = ::LoadLibraryExW(file, NULL, flags);
  392. if (temp == NULL)
  393. return false;
  394. (*this) = temp;
  395. return true;
  396. }
  397. /*--------------------------------------------------------------------------
  398. DResourceUpdateHandle
  399. --------------------------------------------------------------------------*/
  400. BOOL
  401. DResourceUpdateHandle::Win32Create(
  402. IN PCWSTR FileName,
  403. IN BOOL DeleteExistingResources
  404. )
  405. {
  406. void* temp = ::BeginUpdateResourceW(FileName, DeleteExistingResources);
  407. if (temp == NULL)
  408. return false;
  409. (*this) = temp;
  410. return true;
  411. }
  412. BOOL
  413. DResourceUpdateHandle::UpdateResource(
  414. IN PCWSTR Type,
  415. IN PCWSTR Name,
  416. IN WORD Language,
  417. IN LPVOID Data,
  418. IN DWORD Size
  419. )
  420. {
  421. if (!::UpdateResourceW(*this, Type, Name, Language, Data, Size))
  422. return false;
  423. return true;
  424. }
  425. BOOL
  426. DResourceUpdateHandle::Win32Close(
  427. BOOL Discard
  428. )
  429. {
  430. void* temp = m_handle;
  431. m_handle = NULL;
  432. if (temp != NULL)
  433. {
  434. return EndUpdateResource(temp, Discard) ? true : false;
  435. }
  436. return true;
  437. }
  438. /*--------------------------------------------------------------------------
  439. DOperator*
  440. --------------------------------------------------------------------------*/
  441. inline BOOL DOperatorCloseHandle::operator()(void* handle) const { return ::CloseHandle(handle) ? true : false; }
  442. inline BOOL DOperatorFindClose::operator()(void* handle) const { return ::FindClose(handle) ? true : false; }
  443. inline BOOL DOperatorUnmapViewOfFile::operator()(void* handle) const { return ::UnmapViewOfFile(handle) ? true : false; }
  444. inline BOOL DOperatorCloseEventLog::operator()(void* handle) const { return ::CloseEventLog(handle) ? true : false; }
  445. inline BOOL DOperatorDeregisterEventSource::operator()(void* handle) const { return ::DeregisterEventSource(handle) ? true : false; }
  446. inline BOOL DOperatorFreeLibrary::operator()(void* handle) const { return ::FreeLibrary(reinterpret_cast<HMODULE>(handle)) ? true : false; }
  447. //
  448. // NOTE it takes and unexception Win32Close(true) to commit the results!
  449. //
  450. inline BOOL DOperatorEndUpdateResource::operator()(void* handle) const
  451. { return ::EndUpdateResourceW(handle, true) ? true : false; }
  452. /*--------------------------------------------------------------------------
  453. DHandleTemplate
  454. --------------------------------------------------------------------------*/
  455. template <void* const* invalidValue, typename Closer>
  456. DHandleTemplate<invalidValue, Closer>::DHandleTemplate(const void* handle)
  457. : m_handle(const_cast<void*>(handle))
  458. {
  459. }
  460. template <void* const* invalidValue, typename Closer>
  461. void* DHandleTemplate<invalidValue, Closer>::Detach()
  462. {
  463. void* handle = m_handle;
  464. m_handle = *invalidValue;
  465. return handle;
  466. }
  467. template <void* const* invalidValue, typename Closer>
  468. void DHandleTemplate<invalidValue, Closer>::operator=(const void* handle)
  469. {
  470. m_handle = const_cast<void*>(handle);
  471. }
  472. template <void* const* invalidValue, typename Closer>
  473. BOOL DHandleTemplate<invalidValue, Closer>::Win32Close()
  474. {
  475. void* handle = Detach();
  476. if (handle != *invalidValue)
  477. {
  478. Closer close;
  479. return close(handle);
  480. }
  481. return true;
  482. }
  483. template <void* const* invalidValue, typename Closer>
  484. DHandleTemplate<invalidValue, Closer>::~DHandleTemplate()
  485. {
  486. PreserveLastError_t ple;
  487. (void) this->Win32Close();
  488. ple.Restore();
  489. }
  490. template <void* const* invalidValue, typename Closer>
  491. DHandleTemplate<invalidValue, Closer>::operator void*() const
  492. {
  493. return m_handle;
  494. }
  495. template <void* const* invalidValue, typename Closer>
  496. DHandleTemplate<invalidValue, Closer>::operator const void*() const
  497. {
  498. return m_handle;
  499. }
  500. /*--------------------------------------------------------------------------
  501. end of file
  502. --------------------------------------------------------------------------*/