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
587 lines
17 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Dorporation
|
|
|
|
Module Name:
|
|
|
|
Handle.h
|
|
|
|
Abstract:
|
|
|
|
Simple exception safe wrappers of Win32 "handle" types, defining "handle" loosely.
|
|
DFile
|
|
DDynamicLinkLibrary
|
|
DFindFile (should be named DFindFileHandle, see NVseeLibIo::CFindFile vs. NVseeLibIo::CFindFileHandle
|
|
DFindFile includes a WIN32_FIND_DATA, DFindFileHandle does not.)
|
|
DFileMapping
|
|
DMappedViewOfFile
|
|
DRegKey
|
|
See also:
|
|
NVseeLibReg::CRegKey
|
|
NVseeLibIo::CFile
|
|
NVseeLibIo::CFileMapping
|
|
NVseeLibIo::CMappedViewOfFile
|
|
NVseeLibIo::CFindFullPath
|
|
NVseeLibModule::CDynamicLinkLibrary
|
|
etc.
|
|
|
|
Author:
|
|
|
|
Jay Krell (JayKrell) May 2000
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include "windows.h"
|
|
#include "PreserveLastError.h"
|
|
|
|
template <void* const* invalidValue, typename Closer>
|
|
class DHandleTemplate
|
|
{
|
|
public:
|
|
// void* instead of HANDLE to fudge views
|
|
// HANDLE is void*
|
|
DHandleTemplate(const void* handle = *invalidValue);
|
|
~DHandleTemplate();
|
|
BOOL Win32Close();
|
|
void* Detach();
|
|
void operator=(const void*);
|
|
|
|
operator void*() const;
|
|
operator const void*() const;
|
|
|
|
// private
|
|
class DSmartPointerPointerOrDumbPointerPointer
|
|
{
|
|
public:
|
|
DSmartPointerPointerOrDumbPointerPointer(DHandleTemplate* p) : m(p) { }
|
|
operator DHandleTemplate*() { return m; }
|
|
operator void**() { /*assert((**m).m_handle == *invalidValue);*/ return &(*m).m_handle; }
|
|
|
|
DHandleTemplate* m;
|
|
};
|
|
|
|
DSmartPointerPointerOrDumbPointerPointer operator&() { return DSmartPointerPointerOrDumbPointerPointer(this); }
|
|
|
|
void* m_handle;
|
|
|
|
static void* GetInvalidValue() { return *invalidValue; }
|
|
BOOL IsValid() const { return m_handle != *invalidValue; }
|
|
|
|
private:
|
|
DHandleTemplate(const DHandleTemplate&); // deliberately not implemented
|
|
void operator=(const DHandleTemplate&); // deliberately not implemented
|
|
};
|
|
|
|
__declspec(selectany) extern void* const hhInvalidValue = INVALID_HANDLE_VALUE;
|
|
__declspec(selectany) extern void* const hhNull = NULL;
|
|
|
|
/* This closes a Win32 event log handle for writing. */
|
|
class DOperatorDeregisterEventSource
|
|
{
|
|
public: BOOL operator()(void* handle) const;
|
|
};
|
|
|
|
/* This closes a Win32 event log handle for reading. */
|
|
class DOperatorCloseEventLog
|
|
{
|
|
public: BOOL operator()(void* handle) const;
|
|
};
|
|
|
|
/* This closes file, event, mutex, semaphore, etc. kernel objects */
|
|
class DOperatorCloseHandle
|
|
{
|
|
public: BOOL operator()(void* handle) const;
|
|
};
|
|
|
|
//
|
|
// Dloses HCRYPTHASH objects
|
|
//
|
|
class DOperatorCloseCryptHash
|
|
{
|
|
public: BOOL operator()(void* handle) const;
|
|
};
|
|
|
|
/* this closes FindFirstFile/FindNextFile */
|
|
class DOperatorFindClose
|
|
{
|
|
public: BOOL operator()(void* handle) const;
|
|
};
|
|
|
|
/* this closes MapViewOfFile */
|
|
class DOperatorUnmapViewOfFile
|
|
{
|
|
public: BOOL operator()(void* handle) const;
|
|
};
|
|
|
|
/* this closes FreeLibrary */
|
|
class DOperatorFreeLibrary
|
|
{
|
|
public: BOOL operator()(void* handle) const;
|
|
};
|
|
|
|
/* this closes DreateActCtx/AddRefActCtx */
|
|
class DOperatorReleaseActCtx
|
|
{
|
|
public: BOOL operator()(void* handle) const;
|
|
};
|
|
|
|
/* this closes DreateActCtx/AddRefActCtx */
|
|
class DOperatorEndUpdateResource
|
|
{
|
|
public: BOOL operator()(void* handle) const;
|
|
};
|
|
|
|
class DFindFile : public DHandleTemplate<&hhInvalidValue, DOperatorFindClose>
|
|
{
|
|
private:
|
|
typedef DHandleTemplate<&hhInvalidValue, DOperatorFindClose> Base;
|
|
public:
|
|
DFindFile(void* handle = INVALID_HANDLE_VALUE) : Base(handle) { }
|
|
HRESULT HrCreate(PCSTR nameOrWildcard, WIN32_FIND_DATAA*);
|
|
HRESULT HrCreate(PCWSTR nameOrWildcard, WIN32_FIND_DATAW*);
|
|
BOOL Win32Create( PCSTR nameOrWildcard, WIN32_FIND_DATAA*);
|
|
BOOL Win32Create(PCWSTR nameOrWildcard, WIN32_FIND_DATAW*);
|
|
void operator=(void* v) { Base::operator=(v); }
|
|
|
|
private:
|
|
DFindFile(const DFindFile &); // intentionally not implemented
|
|
void operator =(const DFindFile &); // intentionally not implemented
|
|
};
|
|
|
|
// createfile
|
|
class DFile : public DHandleTemplate<&hhInvalidValue, DOperatorCloseHandle>
|
|
{
|
|
private:
|
|
typedef DHandleTemplate<&hhInvalidValue, DOperatorCloseHandle> Base;
|
|
public:
|
|
DFile(void* handle = INVALID_HANDLE_VALUE) : Base(handle) { }
|
|
HRESULT HrCreate( PCSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL);
|
|
HRESULT HrCreate(PCWSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL);
|
|
BOOL Win32Create( PCSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL);
|
|
BOOL Win32Create(PCWSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL);
|
|
BOOL Win32GetSize(ULONGLONG &rulSize) const;
|
|
void operator=(void* v) { Base::operator=(v); }
|
|
|
|
private:
|
|
DFile(const DFile &); // intentionally not implemented
|
|
void operator =(const DFile &); // intentionally not implemented
|
|
};
|
|
|
|
class DFileMapping : public DHandleTemplate<&hhNull, DOperatorCloseHandle>
|
|
{
|
|
private:
|
|
typedef DHandleTemplate<&hhNull, DOperatorCloseHandle> Base;
|
|
public:
|
|
DFileMapping(void* handle = NULL) : Base(handle) { }
|
|
HRESULT HrCreate(void* file, DWORD flProtect, ULONGLONG maximumSize=0, PCWSTR name=0);
|
|
BOOL Win32Create(void* file, DWORD flProtect, ULONGLONG maximumSize=0, PCWSTR name=0);
|
|
void operator=(void* v) { Base::operator=(v); }
|
|
private:
|
|
DFileMapping(const DFileMapping &); // intentionally not implemented
|
|
void operator =(const DFileMapping &); // intentionally not implemented
|
|
};
|
|
|
|
class DMappedViewOfFile : public DHandleTemplate<&hhNull, DOperatorUnmapViewOfFile>
|
|
{
|
|
private:
|
|
typedef DHandleTemplate<&hhNull, DOperatorUnmapViewOfFile> Base;
|
|
public:
|
|
DMappedViewOfFile(void* handle = NULL) : Base(handle) { }
|
|
HRESULT HrCreate(void* fileMapping, DWORD access, ULONGLONG offset=0, size_t size=0);
|
|
BOOL Win32Create(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:
|
|
DMappedViewOfFile(const DMappedViewOfFile &); // intentionally not implemented
|
|
void operator =(const DMappedViewOfFile &); // intentionally not implemented
|
|
operator void*() const; // intentionally not implemented
|
|
};
|
|
|
|
class DDynamicLinkLibrary : public DHandleTemplate<&hhNull, DOperatorFreeLibrary>
|
|
{
|
|
private:
|
|
typedef DHandleTemplate<&hhNull, DOperatorFreeLibrary> Base;
|
|
public:
|
|
DDynamicLinkLibrary(void* handle = NULL) : Base(handle) { }
|
|
|
|
// if you were writing a linker, this would be ambiguous, but
|
|
// otherwise it fits with the the general NT idea that you are
|
|
// initializing an object, not creating a "physical" think (if bits
|
|
// on disk are physical..), like DreateFile
|
|
BOOL Win32Create(PCWSTR file, DWORD flags = 0);
|
|
|
|
template <typename PointerToFunction>
|
|
BOOL GetProcAddress(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:
|
|
DDynamicLinkLibrary(const DDynamicLinkLibrary &); // intentionally not implemented
|
|
void operator =(const DDynamicLinkLibrary &); // intentionally not implemented
|
|
};
|
|
|
|
class DResourceUpdateHandle : public DHandleTemplate<&hhNull, DOperatorEndUpdateResource>
|
|
{
|
|
private:
|
|
typedef DHandleTemplate<&hhNull, DOperatorEndUpdateResource> Base;
|
|
public:
|
|
~DResourceUpdateHandle() { }
|
|
DResourceUpdateHandle(void* handle = NULL) : Base(handle) { }
|
|
BOOL Win32Create(IN PCWSTR FileName, IN BOOL DeleteExistingResources);
|
|
BOOL UpdateResource(
|
|
IN PCWSTR Type,
|
|
IN PCWSTR Name,
|
|
IN WORD Language,
|
|
IN void* Data,
|
|
IN DWORD Size
|
|
);
|
|
BOOL Win32Close(BOOL Discard);
|
|
|
|
void operator=(void* v) { Base::operator=(v); }
|
|
private:
|
|
DResourceUpdateHandle(const DResourceUpdateHandle &); // intentionally not implemented
|
|
void operator =(const DResourceUpdateHandle &); // intentionally not implemented
|
|
};
|
|
|
|
/*--------------------------------------------------------------------------
|
|
DFindFile
|
|
--------------------------------------------------------------------------*/
|
|
|
|
inline BOOL
|
|
DFindFile::Win32Create(
|
|
PCSTR nameOrWildcard,
|
|
WIN32_FIND_DATAA *data
|
|
)
|
|
{
|
|
BOOL fSuccess = false;
|
|
FN_TRACE_WIN32(fSuccess);
|
|
|
|
HANDLE hTemp = ::FindFirstFileA(nameOrWildcard, data);
|
|
if (hTemp == INVALID_HANDLE_VALUE)
|
|
{
|
|
TRACE_WIN32_FAILURE_ORIGINATION(FindFirstFileA);
|
|
goto Exit;
|
|
}
|
|
|
|
(*this) = hTemp;
|
|
|
|
fSuccess = true;
|
|
Exit:
|
|
return fSuccess;
|
|
}
|
|
|
|
inline BOOL
|
|
DFindFile::Win32Create(
|
|
PCWSTR nameOrWildcard,
|
|
WIN32_FIND_DATAW *data
|
|
)
|
|
{
|
|
BOOL fSuccess = FALSE;
|
|
FN_TRACE_WIN32(fSuccess);
|
|
|
|
HANDLE hTemp = ::FindFirstFileW(nameOrWildcard, data);
|
|
if (hTemp == INVALID_HANDLE_VALUE)
|
|
{
|
|
TRACE_WIN32_FAILURE_ORIGINATION(FindFirstFileW);
|
|
goto Exit;
|
|
}
|
|
|
|
(*this) = hTemp;
|
|
|
|
fSuccess = true;
|
|
Exit:
|
|
return fSuccess;
|
|
}
|
|
|
|
inline HRESULT
|
|
DFindFile::HrCreate(
|
|
PCSTR nameOrWildcard,
|
|
WIN32_FIND_DATAA *data
|
|
)
|
|
{
|
|
HRESULT hr = HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR);
|
|
FN_TRACE_HR(hr);
|
|
|
|
IFW32FALSE_EXIT(this->Win32Create(nameOrWildcard, data));
|
|
|
|
hr = NOERROR;
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
inline HRESULT DFindFile::HrCreate(PCWSTR nameOrWildcard, WIN32_FIND_DATAW* data)
|
|
{
|
|
HRESULT hr = HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR);
|
|
FN_TRACE_HR(hr);
|
|
|
|
IFW32FALSE_EXIT(this->Win32Create(nameOrWildcard, data));
|
|
|
|
hr = NOERROR;
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
DFile
|
|
--------------------------------------------------------------------------*/
|
|
|
|
inline BOOL
|
|
DFile::Win32Create(
|
|
PCSTR name,
|
|
DWORD access,
|
|
DWORD share,
|
|
DWORD openOrCreate,
|
|
DWORD flagsAndAttributes
|
|
)
|
|
{
|
|
HANDLE hTemp = ::CreateFileA(name, access, share, NULL, openOrCreate, flagsAndAttributes, NULL);
|
|
if (hTemp == INVALID_HANDLE_VALUE)
|
|
return false;
|
|
operator=(hTemp);
|
|
return true;
|
|
}
|
|
|
|
inline BOOL
|
|
DFile::Win32Create(
|
|
PCWSTR name,
|
|
DWORD access,
|
|
DWORD share,
|
|
DWORD openOrCreate,
|
|
DWORD flagsAndAttributes
|
|
)
|
|
{
|
|
HANDLE hTemp = ::CreateFileW(name, access, share, NULL, openOrCreate, flagsAndAttributes, NULL);
|
|
if (hTemp == INVALID_HANDLE_VALUE)
|
|
return false;
|
|
operator=(hTemp);
|
|
return true;
|
|
}
|
|
|
|
inline HRESULT DFile::HrCreate(PCSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD flagsAndAttributes)
|
|
{
|
|
if (!this->Win32Create(name, access, share, openOrCreate, flagsAndAttributes))
|
|
return HRESULT_FROM_WIN32(::GetLastError());
|
|
return NOERROR;
|
|
}
|
|
|
|
inline HRESULT DFile::HrCreate(PCWSTR name, DWORD access, DWORD share, DWORD openOrCreate, DWORD flagsAndAttributes)
|
|
{
|
|
if (!this->Win32Create(name, access, share, openOrCreate, flagsAndAttributes))
|
|
return HRESULT_FROM_WIN32(::GetLastError());
|
|
return NOERROR;
|
|
}
|
|
|
|
inline BOOL
|
|
DFile::Win32GetSize(ULONGLONG &rulSize) const
|
|
{
|
|
DWORD highPart = 0;
|
|
DWORD lastError = NO_ERROR;
|
|
DWORD lowPart = GetFileSize(m_handle, &highPart);
|
|
if (lowPart == INVALID_FILE_SIZE && (lastError = ::GetLastError()) != NO_ERROR)
|
|
{
|
|
return false;
|
|
}
|
|
ULARGE_INTEGER liSize;
|
|
liSize.LowPart = lowPart;
|
|
liSize.HighPart = highPart;
|
|
rulSize = liSize.QuadPart;
|
|
return true;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
DFileMapping
|
|
--------------------------------------------------------------------------*/
|
|
|
|
inline HRESULT
|
|
DFileMapping::HrCreate(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)
|
|
return HRESULT_FROM_WIN32(::GetLastError());
|
|
operator=(hTemp);
|
|
return S_OK;
|
|
}
|
|
|
|
inline BOOL
|
|
DFileMapping::Win32Create(
|
|
void* file,
|
|
DWORD flProtect,
|
|
ULONGLONG maximumSize,
|
|
PCWSTR name
|
|
)
|
|
{
|
|
return SUCCEEDED(this->HrCreate(file, flProtect, maximumSize, name));
|
|
}
|
|
|
|
inline HRESULT
|
|
DMappedViewOfFile::HrCreate(
|
|
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)
|
|
return HRESULT_FROM_WIN32(::GetLastError());
|
|
|
|
(*this) = pvTemp;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
inline BOOL
|
|
DMappedViewOfFile::Win32Create(void* fileMapping, DWORD access, ULONGLONG offset, size_t size)
|
|
{
|
|
return SUCCEEDED(this->HrCreate(fileMapping, access, offset, size));
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
DDynamicLinkLibrary
|
|
--------------------------------------------------------------------------*/
|
|
inline BOOL
|
|
DDynamicLinkLibrary::Win32Create(
|
|
PCWSTR file,
|
|
DWORD flags
|
|
)
|
|
{
|
|
void* temp = ::LoadLibraryExW(file, NULL, flags);
|
|
if (temp == NULL)
|
|
return false;
|
|
(*this) = temp;
|
|
return true;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
DResourceUpdateHandle
|
|
--------------------------------------------------------------------------*/
|
|
|
|
BOOL
|
|
DResourceUpdateHandle::Win32Create(
|
|
IN PCWSTR FileName,
|
|
IN BOOL DeleteExistingResources
|
|
)
|
|
{
|
|
void* temp = ::BeginUpdateResourceW(FileName, DeleteExistingResources);
|
|
if (temp == NULL)
|
|
return false;
|
|
(*this) = temp;
|
|
return true;
|
|
}
|
|
|
|
BOOL
|
|
DResourceUpdateHandle::UpdateResource(
|
|
IN PCWSTR Type,
|
|
IN PCWSTR Name,
|
|
IN WORD Language,
|
|
IN LPVOID Data,
|
|
IN DWORD Size
|
|
)
|
|
{
|
|
if (!::UpdateResourceW(*this, Type, Name, Language, Data, Size))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
BOOL
|
|
DResourceUpdateHandle::Win32Close(
|
|
BOOL Discard
|
|
)
|
|
{
|
|
void* temp = m_handle;
|
|
m_handle = NULL;
|
|
if (temp != NULL)
|
|
{
|
|
return EndUpdateResource(temp, Discard) ? true : false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
DOperator*
|
|
--------------------------------------------------------------------------*/
|
|
|
|
inline BOOL DOperatorCloseHandle::operator()(void* handle) const { return ::CloseHandle(handle) ? true : false; }
|
|
inline BOOL DOperatorFindClose::operator()(void* handle) const { return ::FindClose(handle) ? true : false; }
|
|
inline BOOL DOperatorUnmapViewOfFile::operator()(void* handle) const { return ::UnmapViewOfFile(handle) ? true : false; }
|
|
inline BOOL DOperatorCloseEventLog::operator()(void* handle) const { return ::CloseEventLog(handle) ? true : false; }
|
|
inline BOOL DOperatorDeregisterEventSource::operator()(void* handle) const { return ::DeregisterEventSource(handle) ? true : false; }
|
|
inline BOOL DOperatorFreeLibrary::operator()(void* handle) const { return ::FreeLibrary(reinterpret_cast<HMODULE>(handle)) ? true : false; }
|
|
//
|
|
// NOTE it takes and unexception Win32Close(true) to commit the results!
|
|
//
|
|
inline BOOL DOperatorEndUpdateResource::operator()(void* handle) const
|
|
{ return ::EndUpdateResourceW(handle, true) ? true : false; }
|
|
|
|
/*--------------------------------------------------------------------------
|
|
DHandleTemplate
|
|
--------------------------------------------------------------------------*/
|
|
|
|
template <void* const* invalidValue, typename Closer>
|
|
DHandleTemplate<invalidValue, Closer>::DHandleTemplate(const void* handle)
|
|
: m_handle(const_cast<void*>(handle))
|
|
{
|
|
}
|
|
|
|
template <void* const* invalidValue, typename Closer>
|
|
void* DHandleTemplate<invalidValue, Closer>::Detach()
|
|
{
|
|
void* handle = m_handle;
|
|
m_handle = *invalidValue;
|
|
return handle;
|
|
}
|
|
|
|
template <void* const* invalidValue, typename Closer>
|
|
void DHandleTemplate<invalidValue, Closer>::operator=(const void* handle)
|
|
{
|
|
m_handle = const_cast<void*>(handle);
|
|
}
|
|
|
|
template <void* const* invalidValue, typename Closer>
|
|
BOOL DHandleTemplate<invalidValue, Closer>::Win32Close()
|
|
{
|
|
void* handle = Detach();
|
|
if (handle != *invalidValue)
|
|
{
|
|
Closer close;
|
|
return close(handle);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template <void* const* invalidValue, typename Closer>
|
|
DHandleTemplate<invalidValue, Closer>::~DHandleTemplate()
|
|
{
|
|
PreserveLastError_t ple;
|
|
(void) this->Win32Close();
|
|
ple.Restore();
|
|
}
|
|
|
|
template <void* const* invalidValue, typename Closer>
|
|
DHandleTemplate<invalidValue, Closer>::operator void*() const
|
|
{
|
|
return m_handle;
|
|
}
|
|
|
|
template <void* const* invalidValue, typename Closer>
|
|
DHandleTemplate<invalidValue, Closer>::operator const void*() const
|
|
{
|
|
return m_handle;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
end of file
|
|
--------------------------------------------------------------------------*/
|