windows-nt/Source/XPSP1/NT/base/win32/fusion/inc/fusionhandle.h

790 lines
22 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) Microsoft Corporation
Module Name:
FusionHandle.h
Abstract:
Simple exception safe wrappers of Win32 "handle" types, defining "handle" loosely.
CFusionFile
CDynamicLinkLibrary
CFindFile (should be named CFindFileHandle, see NVseeLibIo::CFindFile vs. NVseeLibIo::CFindFileHandle
CFindFile includes a WIN32_FIND_DATA, CFindFileHandle does not.)
CFileMapping
CMappedViewOfFile
CRegKey
See also:
NVseeLibReg::CRegKey
NVseeLibIo::CFusionFile
NVseeLibIo::CFileMapping
NVseeLibIo::CMappedViewOfFile
NVseeLibIo::CFindFullPath
NVseeLibModule::CDynamicLinkLibrary
etc.
Author:
Jay Krell (a-JayK, JayKrell) May 2000
Revision History:
--*/
#pragma once
#include "fusiontrace.h"
#include "fusionbuffer.h"
#include "wtypes.h"
#include "wincrypt.h"
template <void* const* invalidValue, typename Closer>
class CHandleTemplate
{
public:
// void* instead of HANDLE to fudge views
// HANDLE is void*
CHandleTemplate(const void* handle = *invalidValue);
~CHandleTemplate();
BOOL Win32Close();
void* Detach();
void operator=(const void*);
operator void*() const;
operator const void*() const;
// private
class CSmartPointerPointerOrDumbPointerPointer
{
public:
CSmartPointerPointerOrDumbPointerPointer(CHandleTemplate* p) : m(p) { }
operator CHandleTemplate*() { return m; }
operator void**() { /*assert((**m).m_handle == *invalidValue);*/ return &(*m).m_handle; }
operator HKEY*() { /*assert((**m).m_handle == *invalidValue);*/
//compiler bug? m->operator HKEY(); // only allow this to compile for CFusionRegKey
//static_cast<HKEY>(*m);
static_cast<CRegKey*>(m);
return reinterpret_cast<HKEY*>(operator void**()); }
operator HCRYPTHASH*() {
static_cast<CCryptHash*>(m);
return reinterpret_cast<HCRYPTHASH*>(operator void**()); }
CHandleTemplate* m;
};
CSmartPointerPointerOrDumbPointerPointer operator&() { return CSmartPointerPointerOrDumbPointerPointer(this); }
void* m_handle;
static void* GetInvalidValue() { return *invalidValue; }
bool IsValid() const { return m_handle != *invalidValue; }
private:
CHandleTemplate(const CHandleTemplate&); // deliberately not implemented
void operator=(const CHandleTemplate&); // deliberately not implemented
};
__declspec(selectany) extern void* const hInvalidValue = INVALID_HANDLE_VALUE;
__declspec(selectany) extern void* const hNull = NULL;
/* This closes a Win32 event log handle for writing. */
class COperatorDeregisterEventSource
{
public: BOOL operator()(void* handle) const;
};
/* This closes a Win32 event log handle for reading. */
class COperatorCloseEventLog
{
public: BOOL operator()(void* handle) const;
};
/* This closes file, event, mutex, semaphore, etc. kernel objects */
class COperatorCloseHandle
{
public: BOOL operator()(void* handle) const;
};
//
// Closes HCRYPTHASH objects
//
class COperatorCloseCryptHash
{
public: BOOL operator()(void* handle) const;
};
/* this closes FindFirstFile/FindNextFile */
class COperatorFindClose
{
public: BOOL operator()(void* handle) const;
};
/* this closes MapViewOfFile */
class COperatorUnmapViewOfFile
{
public: BOOL operator()(void* handle) const;
};
/* this closes FreeLibrary */
class COperatorFreeLibrary
{
public: BOOL operator()(void* handle) const;
};
/* this closes CreateActCtx/AddRefActCtx */
class COperatorReleaseActCtx
{
public: BOOL operator()(void* handle) const;
};
#include "fusionreg.h"
class CEvent : public CHandleTemplate<&hNull, COperatorCloseHandle>
{
private:
typedef CHandleTemplate<&hNull, COperatorCloseHandle> Base;
public:
CEvent(void* handle = NULL) : Base(handle) { }
BOOL Win32CreateEvent(BOOL ManualReset, BOOL InitialState, PCWSTR Name = NULL);
void operator=(void* v) { Base::operator=(v); }
private:
CEvent(const CEvent &); // intentionally not implemented
void operator =(const CEvent &); // intentionally not implemented
};
class CThread : public CHandleTemplate<&hNull, COperatorCloseHandle>
{
private:
typedef CHandleTemplate<&hNull, COperatorCloseHandle> Base;
public:
CThread(void* handle = NULL) : Base(handle) { }
BOOL Win32CreateThread(LPTHREAD_START_ROUTINE StartAddress, LPVOID Parameter, DWORD Flags = 0, LPDWORD ThreadId = NULL);
void operator=(void* v) { Base::operator=(v); }
private:
CThread(const CThread &); // intentionally not implemented
void operator =(const CThread &); // intentionally not implemented
};
class CFindFile : public CHandleTemplate<&hInvalidValue, COperatorFindClose>
{
private:
typedef CHandleTemplate<&hInvalidValue, COperatorFindClose> Base;
public:
CFindFile(void* handle = INVALID_HANDLE_VALUE) : Base(handle) { }
HRESULT HrFindFirstFile(PCSTR nameOrWildcard, WIN32_FIND_DATAA*);
HRESULT HrFindFirstFile(PCWSTR nameOrWildcard, WIN32_FIND_DATAW*);
BOOL Win32FindFirstFile( PCSTR nameOrWildcard, WIN32_FIND_DATAA*);
BOOL Win32FindFirstFile(PCWSTR nameOrWildcard, WIN32_FIND_DATAW*);
void operator=(void* v) { Base::operator=(v); }
private:
CFindFile(const CFindFile &); // intentionally not implemented
void operator =(const CFindFile &); // intentionally not implemented
};
class CFusionFile : public CHandleTemplate<&hInvalidValue, COperatorCloseHandle>
{
private:
typedef CHandleTemplate<&hInvalidValue, COperatorCloseHandle> Base;
public:
CFusionFile(void* handle = INVALID_HANDLE_VALUE) : Base(handle) { }
HRESULT HrCreateFile( PCSTR name, DWORD access, DWORD share, DWORD openOrCreate);
HRESULT HrCreateFile(PCWSTR name, DWORD access, DWORD share, DWORD openOrCreate);
BOOL Win32CreateFile( PCSTR name, DWORD access, DWORD share, DWORD openOrCreate);
BOOL Win32CreateFile(PCWSTR name, DWORD access, DWORD share, DWORD openOrCreate);
BOOL Win32GetSize(ULONGLONG &rulSize) const;
void operator=(void* v) { Base::operator=(v); }
private:
CFusionFile(const CFusionFile &); // intentionally not implemented
void operator =(const CFusionFile &); // intentionally not implemented
};
class CFileMapping : public CHandleTemplate<&hNull, COperatorCloseHandle>
{
private:
typedef CHandleTemplate<&hNull, COperatorCloseHandle> Base;
public:
CFileMapping(void* handle = NULL) : Base(handle) { }
HRESULT HrCreateFileMapping(void* file, DWORD flProtect, ULONGLONG maximumSize=0, PCWSTR name=0);
BOOL Win32CreateFileMapping(void* file, DWORD flProtect, ULONGLONG maximumSize=0, PCWSTR name=0);
void operator=(void* v) { Base::operator=(v); }
private:
CFileMapping(const CFileMapping &); // intentionally not implemented
void operator =(const CFileMapping &); // intentionally not implemented
};
class CCryptHash : public CHandleTemplate<&hNull, COperatorCloseCryptHash>
{
private:
typedef CHandleTemplate<&hNull, COperatorCloseCryptHash> Base;
public:
CCryptHash( HCRYPTHASH hash = NULL ) : Base((void*)hash) { }
operator HCRYPTHASH() { return (HCRYPTHASH)(Base::operator void*()); }
void operator=(HCRYPTHASH hash) {
ASSERT_NTC(!IsValid());
m_handle = (void*)hash;
}
private:
CCryptHash( const CCryptHash & );
CCryptHash &operator=( const CCryptHash & );
};
class CMappedViewOfFile : public CHandleTemplate<&hNull, COperatorUnmapViewOfFile>
{
private:
typedef CHandleTemplate<&hNull, COperatorUnmapViewOfFile> Base;
public:
CMappedViewOfFile(void* handle = NULL) : Base(handle) { }
HRESULT HrMapViewOfFile(void* fileMapping, DWORD access, ULONGLONG offset=0, SIZE_T size=0);
BOOL Win32MapViewOfFile(void* fileMapping, DWORD access, ULONGLONG offset=0, SIZE_T size=0);
void operator=(void* v) { Base::operator=(v); }
operator void*() { return Base::operator void*(); }
private:
CMappedViewOfFile(const CMappedViewOfFile &); // intentionally not implemented
void operator =(const CMappedViewOfFile &); // intentionally not implemented
operator void*() const; // intentionally not implemented
};
class CDynamicLinkLibrary : public CHandleTemplate<&hNull, COperatorFreeLibrary>
{
private:
typedef CHandleTemplate<&hNull, COperatorFreeLibrary> Base;
public:
CDynamicLinkLibrary(void* handle = NULL) : Base(handle) { }
BOOL Win32LoadLibrary(PCWSTR file, DWORD flags = 0);
template <typename PointerToFunction>
bool Win32GetProcAddress(PCSTR procName, PointerToFunction* ppfn)
{
return (*ppfn = reinterpret_cast<PointerToFunction>(::GetProcAddress(*this, procName))) != NULL;
}
operator HMODULE() { return reinterpret_cast<HMODULE>(operator void*()); }
HMODULE Detach() { return reinterpret_cast<HMODULE>(Base::Detach()); }
void operator=(void* v) { Base::operator=(v); }
private:
CDynamicLinkLibrary(const CDynamicLinkLibrary &); // intentionally not implemented
void operator =(const CDynamicLinkLibrary &); // intentionally not implemented
};
class CFusionActCtxHandle : public CHandleTemplate<&hInvalidValue, COperatorReleaseActCtx>
{
private:
typedef CHandleTemplate<&hInvalidValue, COperatorReleaseActCtx> Base;
public:
CFusionActCtxHandle(void* handle = INVALID_HANDLE_VALUE) : Base(handle) { }
BOOL Win32Create(PCACTCTXW);
void operator=(void* v) { Base::operator=(v); }
private:
CFusionActCtxHandle(const CFusionActCtxHandle &); // intentionally not implemented
void operator =(const CFusionActCtxHandle &); // intentionally not implemented
};
class CFusionActCtxScope
{
protected:
BOOL m_fSuccess;
ULONG_PTR m_ulCookie;
public:
CFusionActCtxScope();
~CFusionActCtxScope();
BOOL Win32Activate(HANDLE hActCtx);
private:
CFusionActCtxScope(const CFusionActCtxScope &); // intentionally not implemented
void operator =(const CFusionActCtxScope &); // intentionally not implemented
};
/*--------------------------------------------------------------------------
CFindFile
--------------------------------------------------------------------------*/
inline BOOL
CFindFile::Win32FindFirstFile(
PCSTR nameOrWildcard,
WIN32_FIND_DATAA *data
)
{
BOOL fSuccess = FALSE;
FN_TRACE_WIN32(fSuccess);
HANDLE hTemp = ::FindFirstFileA(nameOrWildcard, data);
if (hTemp == INVALID_HANDLE_VALUE)
{
goto Exit;
}
(*this) = hTemp;
fSuccess = TRUE;
Exit:
return fSuccess;
}
inline BOOL
CFindFile::Win32FindFirstFile(
PCWSTR nameOrWildcard,
WIN32_FIND_DATAW *data
)
{
BOOL fSuccess = FALSE;
FN_TRACE_WIN32(fSuccess);
HANDLE hTemp = ::FindFirstFileW(nameOrWildcard, data);
if (hTemp == INVALID_HANDLE_VALUE)
{
goto Exit;
}
(*this) = hTemp;
fSuccess = TRUE;
Exit:
return fSuccess;
}
inline
HRESULT
CFindFile::HrFindFirstFile(
PCSTR nameOrWildcard,
WIN32_FIND_DATAA *data
)
{
HRESULT hr = HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR);
FN_TRACE_HR(hr);
IFW32FALSE_EXIT(this->Win32FindFirstFile(nameOrWildcard, data));
hr = NOERROR;
Exit:
return hr;
}
inline
HRESULT
CFindFile::HrFindFirstFile(PCWSTR nameOrWildcard, WIN32_FIND_DATAW* data)
{
HRESULT hr = HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR);
FN_TRACE_HR(hr);
IFW32FALSE_EXIT(this->Win32FindFirstFile(nameOrWildcard, data));
hr = NOERROR;
Exit:
return hr;
}
/*--------------------------------------------------------------------------
CFusionFile
--------------------------------------------------------------------------*/
inline BOOL
CFusionFile::Win32CreateFile(
PCSTR name,
DWORD access,
DWORD share,
DWORD openOrCreate
)
{
FN_PROLOG_WIN32
HANDLE hTemp;
IFW32INVALIDHANDLE_ORIGINATE_AND_EXIT(
hTemp = ::CreateFileA(name, access, share, NULL, openOrCreate, FILE_ATTRIBUTE_NORMAL, NULL));
operator=(hTemp);
FN_EPILOG
}
inline BOOL
CFusionFile::Win32CreateFile(
PCWSTR name,
DWORD access,
DWORD share,
DWORD openOrCreate
)
{
FN_PROLOG_WIN32
HANDLE hTemp;
IFW32INVALIDHANDLE_ORIGINATE_AND_EXIT(
hTemp = ::CreateFileW(name, access, share, NULL, openOrCreate, FILE_ATTRIBUTE_NORMAL, NULL));
operator=(hTemp);
FN_EPILOG
}
inline HRESULT CFusionFile::HrCreateFile(PCSTR name, DWORD access, DWORD share, DWORD openOrCreate)
{
if (!this->Win32CreateFile(name, access, share, openOrCreate))
return HRESULT_FROM_WIN32(::FusionpGetLastWin32Error());
return NOERROR;
}
inline HRESULT CFusionFile::HrCreateFile(PCWSTR name, DWORD access, DWORD share, DWORD openOrCreate)
{
if (!this->Win32CreateFile(name, access, share, openOrCreate))
return HRESULT_FROM_WIN32(::FusionpGetLastWin32Error());
return NOERROR;
}
inline BOOL
CFusionFile::Win32GetSize(ULONGLONG &rulSize) const
{
DWORD highPart = 0;
DWORD lastError = NO_ERROR;
DWORD lowPart = ::GetFileSize(m_handle, &highPart);
if (lowPart == INVALID_FILE_SIZE && (lastError = ::FusionpGetLastWin32Error()) != NO_ERROR)
{
TRACE_WIN32_FAILURE_ORIGINATION(GetFileSize);
return FALSE;
}
ULARGE_INTEGER liSize;
liSize.LowPart = lowPart;
liSize.HighPart = highPart;
rulSize = liSize.QuadPart;
return TRUE;
}
/*--------------------------------------------------------------------------
CFileMapping
--------------------------------------------------------------------------*/
inline HRESULT
CFileMapping::HrCreateFileMapping(void* file, DWORD flProtect, ULONGLONG maximumSize, PCWSTR name)
{
LARGE_INTEGER liMaximumSize;
liMaximumSize.QuadPart = maximumSize;
HANDLE hTemp = ::CreateFileMappingW(file, NULL, flProtect, liMaximumSize.HighPart, liMaximumSize.LowPart, name);
if (hTemp == NULL)
{
TRACE_WIN32_FAILURE_ORIGINATION(CreateFileMapping);
return HRESULT_FROM_WIN32(::FusionpGetLastWin32Error());
}
operator=(hTemp);
return S_OK;
}
inline BOOL
CFileMapping::Win32CreateFileMapping(
void* file,
DWORD flProtect,
ULONGLONG maximumSize,
PCWSTR name
)
{
return SUCCEEDED(this->HrCreateFileMapping(file, flProtect, maximumSize, name));
}
/*--------------------------------------------------------------------------
CMappedViewOfFile
--------------------------------------------------------------------------*/
inline HRESULT
CMappedViewOfFile::HrMapViewOfFile(
void* fileMapping,
DWORD access,
ULONGLONG offset,
SIZE_T size
)
{
ULARGE_INTEGER liOffset;
liOffset.QuadPart = offset;
void* pvTemp = ::MapViewOfFile(fileMapping, access, liOffset.HighPart, liOffset.LowPart, size);
if (pvTemp == NULL)
{
TRACE_WIN32_FAILURE_ORIGINATION(MapViewOfFile);
return HRESULT_FROM_WIN32(::FusionpGetLastWin32Error());
}
(*this) = pvTemp;
return S_OK;
}
inline BOOL
CMappedViewOfFile::Win32MapViewOfFile(void* fileMapping, DWORD access, ULONGLONG offset, SIZE_T size)
{
return SUCCEEDED(this->HrMapViewOfFile(fileMapping, access, offset, size));
}
/*--------------------------------------------------------------------------
CEvent
--------------------------------------------------------------------------*/
inline BOOL CEvent::Win32CreateEvent(BOOL ManualReset, BOOL InitialState, PCWSTR Name)
{
HANDLE Temp = ::CreateEventW(NULL, ManualReset, InitialState, Name);
if (Temp == NULL)
{
TRACE_WIN32_FAILURE_ORIGINATION(CreateEventW);
return FALSE;
}
(*this) = Temp;
return TRUE;
}
/*--------------------------------------------------------------------------
CThread
--------------------------------------------------------------------------*/
inline BOOL
CThread::Win32CreateThread(
LPTHREAD_START_ROUTINE StartAddress,
LPVOID Parameter,
DWORD Flags,
LPDWORD ThreadId
)
{
DWORD LocalThreadId;
if (ThreadId == NULL)
ThreadId = &LocalThreadId;
HANDLE Temp = ::CreateThread(NULL, 0, StartAddress, Parameter, Flags, ThreadId);
if (Temp == NULL)
{
TRACE_WIN32_FAILURE_ORIGINATION(CreateThread);
return FALSE;
}
(*this) = Temp;
return TRUE;
}
/*--------------------------------------------------------------------------
CDynamicLinkLibrary
--------------------------------------------------------------------------*/
inline BOOL
CDynamicLinkLibrary::Win32LoadLibrary(
PCWSTR file,
DWORD flags
)
{
void* temp = ::LoadLibraryExW(file, NULL, flags);
if (temp == NULL)
{
TRACE_WIN32_FAILURE_ORIGINATION(LoadLibraryExW);
return FALSE;
}
(*this) = temp;
return TRUE;
}
/*--------------------------------------------------------------------------
CFusionActCtxHandle
--------------------------------------------------------------------------*/
inline BOOL
CFusionActCtxHandle::Win32Create(
PCACTCTXW pActCtx
)
{
typedef HANDLE (WINAPI* PFN)(PCACTCTXW pActCtx);
static PFN pfn;
if (pfn == NULL)
{
HMODULE hmodKernel32 = ::GetModuleHandleW(L"Kernel32.dll");
if (hmodKernel32 != NULL)
{
pfn = reinterpret_cast<PFN>(::GetProcAddress(hmodKernel32, "CreateActCtxW"));
if (pfn == NULL)
TRACE_WIN32_FAILURE_ORIGINATION(GetProcAddress);
}
else
TRACE_WIN32_FAILURE_ORIGINATION(GetModuleHandleW);
if (pfn == NULL)
return FALSE;
}
void* temp = (*pfn)(pActCtx);
if (temp == INVALID_HANDLE_VALUE)
{
TRACE_WIN32_FAILURE_ORIGINATION(CreateActCtxW);
return FALSE;
}
(*this) = temp;
return TRUE;
}
inline BOOL COperatorReleaseActCtx::operator()(HANDLE hActCtx) const
{
typedef BOOL (WINAPI* PFN)(HANDLE);
static PFN pfn;
if (pfn == NULL)
{
HMODULE hmodKernel32 = ::GetModuleHandleW(L"Kernel32.dll");
if (hmodKernel32 != NULL)
{
pfn = reinterpret_cast<PFN>(::GetProcAddress(hmodKernel32, "ReleaseActCtx"));
if (pfn == NULL)
TRACE_WIN32_FAILURE_ORIGINATION(GetProcAddress);
}
else
{
TRACE_WIN32_FAILURE_ORIGINATION(GetModuleHandleW);
}
if (pfn == NULL)
return FALSE;
}
return pfn(hActCtx);
}
/*--------------------------------------------------------------------------
CFusionActCtxScope
--------------------------------------------------------------------------*/
inline CFusionActCtxScope::CFusionActCtxScope() : m_fSuccess(FALSE) { }
inline BOOL CFusionActCtxScope::Win32Activate(HANDLE hActCtx)
{
typedef BOOL (WINAPI* PFN)(HANDLE hActCtx, ULONG_PTR* lpCookie);
static PFN pfn;
if (pfn == NULL)
{
HMODULE hmodKernel32 = ::GetModuleHandleW(L"Kernel32.dll");
if (hmodKernel32 != NULL)
{
pfn = reinterpret_cast<PFN>(GetProcAddress(hmodKernel32, "ActivateActCtx"));
if (pfn == NULL)
TRACE_WIN32_FAILURE_ORIGINATION(GetProcAddress);
}
else
{
TRACE_WIN32_FAILURE_ORIGINATION(GetModuleHandleW);
}
if (pfn == NULL)
return FALSE;
}
return (m_fSuccess = pfn(hActCtx, &m_ulCookie));
}
inline CFusionActCtxScope::~CFusionActCtxScope()
{
if (m_fSuccess)
{
CSxsPreserveLastError ple;
m_fSuccess = FALSE;
typedef BOOL (WINAPI* PFN)(DWORD dwFlags, ULONG_PTR ulCookie);
static PFN pfn;
if (pfn == NULL)
{
HMODULE hmodKernel32 = GetModuleHandleW(L"Kernel32.dll");
if (hmodKernel32 != NULL)
{
pfn = reinterpret_cast<PFN>(GetProcAddress(hmodKernel32, "DeactivateActCtx"));
if (pfn == NULL)
TRACE_WIN32_FAILURE_ORIGINATION(GetProcAddress);
}
else
{
TRACE_WIN32_FAILURE_ORIGINATION(GetModuleHandleW);
}
if (pfn == NULL)
{
ple.Restore();
return;
}
}
(*pfn)(0, m_ulCookie);
ple.Restore();
}
}
/*--------------------------------------------------------------------------
COperator*
--------------------------------------------------------------------------*/
inline BOOL COperatorCloseHandle::operator()(void* handle) const { return ::CloseHandle(handle); }
inline BOOL COperatorFindClose::operator()(void* handle) const { return ::FindClose(handle); }
inline BOOL COperatorUnmapViewOfFile::operator()(void* handle) const { return ::UnmapViewOfFile(handle); }
inline BOOL COperatorCloseEventLog::operator()(void* handle) const { return ::CloseEventLog(handle); }
inline BOOL COperatorDeregisterEventSource::operator()(void* handle) const { return ::DeregisterEventSource(handle); }
inline BOOL COperatorFreeLibrary::operator()(void* handle) const { return ::FreeLibrary(reinterpret_cast<HMODULE>(handle)); }
inline BOOL COperatorCloseCryptHash::operator()(void* handle) const { return ::CryptDestroyHash(reinterpret_cast<HCRYPTHASH>(handle)); };
/*--------------------------------------------------------------------------
CHandleTemplate
--------------------------------------------------------------------------*/
template <void* const* invalidValue, typename Closer>
CHandleTemplate<invalidValue, Closer>::CHandleTemplate(const void* handle)
: m_handle(const_cast<void*>(handle))
{
}
template <void* const* invalidValue, typename Closer>
void* CHandleTemplate<invalidValue, Closer>::Detach()
{
void* handle = m_handle;
m_handle = *invalidValue;
return handle;
}
template <void* const* invalidValue, typename Closer>
void CHandleTemplate<invalidValue, Closer>::operator=(const void* handle)
{
if (handle != m_handle)
{
void *SavedHandle = m_handle;
m_handle = const_cast<void*>(handle);
if (SavedHandle != *invalidValue)
{
Closer close;
// a bug waiting to happen to customers
VERIFY_NTC(close(SavedHandle));
}
}
}
template <void* const* invalidValue, typename Closer>
BOOL CHandleTemplate<invalidValue, Closer>::Win32Close()
{
void* handle = Detach();
if (handle != *invalidValue)
{
Closer close;
return close(handle);
}
return TRUE;
}
template <void* const* invalidValue, typename Closer>
CHandleTemplate<invalidValue, Closer>::~CHandleTemplate()
{
CSxsPreserveLastError ple;
(void) this->Win32Close();
ple.Restore();
}
template <void* const* invalidValue, typename Closer>
CHandleTemplate<invalidValue, Closer>::operator void*() const
{
return m_handle;
}
template <void* const* invalidValue, typename Closer>
CHandleTemplate<invalidValue, Closer>::operator const void*() const
{
return m_handle;
}
/*--------------------------------------------------------------------------
end of file
--------------------------------------------------------------------------*/