269 lines
7.9 KiB
C
269 lines
7.9 KiB
C
|
#pragma once
|
||
|
|
||
|
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();
|
||
|
void Close();
|
||
|
void* Detach();
|
||
|
void operator=(const void*);
|
||
|
|
||
|
operator void*();
|
||
|
operator const void*() const;
|
||
|
|
||
|
void* m_handle;
|
||
|
|
||
|
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;
|
||
|
|
||
|
class COperatorDeregisterEventSource
|
||
|
{
|
||
|
public: void operator()(void* handle) const;
|
||
|
};
|
||
|
|
||
|
class COperatorCloseEventLog
|
||
|
{
|
||
|
public: void operator()(void* handle) const;
|
||
|
};
|
||
|
|
||
|
class COperatorCloseHandle
|
||
|
{
|
||
|
public: void operator()(void* handle) const;
|
||
|
};
|
||
|
|
||
|
class COperatorFindClose
|
||
|
{
|
||
|
public: void operator()(void* handle) const;
|
||
|
};
|
||
|
|
||
|
class COperatorUnmapViewOfFile
|
||
|
{
|
||
|
public: void operator()(void* handle) const;
|
||
|
};
|
||
|
|
||
|
class COperatorRegCloseKey
|
||
|
{
|
||
|
public: void operator()(void* handle) const;
|
||
|
};
|
||
|
|
||
|
class CFindFile : public CHandleTemplate<&hInvalidValue, COperatorFindClose>
|
||
|
{
|
||
|
private:
|
||
|
typedef CHandleTemplate<&hInvalidValue, COperatorFindClose> Base;
|
||
|
public:
|
||
|
CFindFile() { }
|
||
|
CFindFile(void* handle) : Base(handle) { }
|
||
|
CFindFile(PCSTR nameOrWildcard, WIN32_FIND_DATA*);
|
||
|
HRESULT HrCreate(PCSTR nameOrWildcard, WIN32_FIND_DATA*);
|
||
|
void VCreate(PCSTR nameOrWildcard, WIN32_FIND_DATA*);
|
||
|
void operator=(void* v) { Base::operator=(v); }
|
||
|
};
|
||
|
|
||
|
class CFusionFile : public CHandleTemplate<&hInvalidValue, COperatorCloseHandle>
|
||
|
{
|
||
|
private:
|
||
|
typedef CHandleTemplate<&hInvalidValue, COperatorCloseHandle> Base;
|
||
|
public:
|
||
|
CFusionFile() { }
|
||
|
CFusionFile(void* handle) : Base(handle) { }
|
||
|
CFusionFile(PCSTR name, DWORD access, DWORD share, DWORD openOrCreate);
|
||
|
HRESULT HrCreate(PCSTR name, DWORD access, DWORD share, DWORD openOrCreate);
|
||
|
void VCreate(PCSTR name, DWORD access, DWORD share, DWORD openOrCreate);
|
||
|
__int64 GetSize() const;
|
||
|
void operator=(void* v) { Base::operator=(v); }
|
||
|
};
|
||
|
|
||
|
class CFileMapping : public CHandleTemplate<&hNull, COperatorCloseHandle>
|
||
|
{
|
||
|
private:
|
||
|
typedef CHandleTemplate<&hNull, COperatorCloseHandle> Base;
|
||
|
public:
|
||
|
CFileMapping() { }
|
||
|
CFileMapping(void* handle) : Base(handle) { }
|
||
|
CFileMapping(void* file, DWORD flProtect, __int64 maximumSize=0, PCSTR name=0);
|
||
|
void VCreate(void* file, DWORD flProtect, __int64 maximumSize=0, PCSTR name=0);
|
||
|
HRESULT HrCreate(void* file, DWORD flProtect, __int64 maximumSize=0, PCSTR name=0);
|
||
|
void operator=(void* v) { Base::operator=(v); }
|
||
|
};
|
||
|
|
||
|
class CMappedViewOfFile : public CHandleTemplate<&hNull, COperatorUnmapViewOfFile>
|
||
|
{
|
||
|
private:
|
||
|
typedef CHandleTemplate<&hNull, COperatorUnmapViewOfFile> Base;
|
||
|
public:
|
||
|
CMappedViewOfFile() { }
|
||
|
CMappedViewOfFile(void* handle) : Base(handle) { }
|
||
|
CMappedViewOfFile(void* fileMapping, DWORD access, __int64 offset=0, SIZE_T size=0);
|
||
|
void VCreate(void* fileMapping, DWORD access, __int64 offset=0, SIZE_T size=0);
|
||
|
HRESULT HrCreate(void* fileMapping, DWORD access, __int64 offset=0, SIZE_T size=0);
|
||
|
void operator=(void* v) { Base::operator=(v); }
|
||
|
};
|
||
|
|
||
|
/*--------------------------------------------------------------------------
|
||
|
--------------------------------------------------------------------------*/
|
||
|
|
||
|
inline CFindFile::CFindFile(PCSTR nameOrWildcard, WIN32_FIND_DATA* data)
|
||
|
: Base(INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
VCreate(nameOrWildcard, data);
|
||
|
}
|
||
|
|
||
|
inline HRESULT CFindFile::HrCreate(PCSTR nameOrWildcard, WIN32_FIND_DATA* data)
|
||
|
{
|
||
|
HANDLE hTemp = FindFirstFile(nameOrWildcard, data);
|
||
|
if (hTemp == INVALID_HANDLE_VALUE)
|
||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||
|
operator=(hTemp);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
inline void CFindFile::VCreate(PCSTR nameOrWildcard, WIN32_FIND_DATA* data)
|
||
|
{
|
||
|
CheckHresult(HrCreate(nameOrWildcard, data));
|
||
|
}
|
||
|
|
||
|
inline HRESULT CFusionFile::HrCreate(PCSTR name, DWORD access, DWORD share, DWORD openOrCreate)
|
||
|
{
|
||
|
HANDLE hTemp = CreateFile(name, access, share, NULL, openOrCreate, FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
if (hTemp == INVALID_HANDLE_VALUE)
|
||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||
|
operator=(hTemp);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
inline CFusionFile::CFusionFile(PCSTR name, DWORD access, DWORD share, DWORD openOrCreate)
|
||
|
: Base(INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
VCreate(name, access, share, openOrCreate);
|
||
|
}
|
||
|
|
||
|
inline VOID CFusionFile::VCreate(PCSTR name, DWORD access, DWORD share, DWORD openOrCreate)
|
||
|
{
|
||
|
CheckHresult(HrCreate(name, access, share, openOrCreate));
|
||
|
}
|
||
|
|
||
|
inline __int64 CFusionFile::GetSize() const
|
||
|
{
|
||
|
DWORD highPart = 0;
|
||
|
DWORD lastError = NO_ERROR;
|
||
|
DWORD lowPart = GetFileSize(m_handle, &highPart);
|
||
|
if (lowPart == INVALID_FILE_SIZE && (lastError = GetLastError()) != NO_ERROR)
|
||
|
{
|
||
|
ThrowHresult(HRESULT_FROM_WIN32(lastError));
|
||
|
}
|
||
|
LARGE_INTEGER liSize;
|
||
|
liSize.LowPart = lowPart;
|
||
|
liSize.HighPart = highPart;
|
||
|
return liSize.QuadPart;
|
||
|
}
|
||
|
|
||
|
inline HRESULT CFileMapping::HrCreate(void* file, DWORD flProtect, __int64 maximumSize, PCSTR name)
|
||
|
{
|
||
|
LARGE_INTEGER liMaximumSize;
|
||
|
liMaximumSize.QuadPart = maximumSize;
|
||
|
HANDLE hTemp = CreateFileMapping(file, NULL, flProtect, liMaximumSize.HighPart, liMaximumSize.LowPart, name);
|
||
|
if (hTemp == NULL)
|
||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||
|
Base::operator=(hTemp);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
inline CFileMapping::CFileMapping(void* file, DWORD flProtect, __int64 maximumSize, PCSTR name)
|
||
|
: Base(NULL)
|
||
|
{
|
||
|
VCreate(file, flProtect, maximumSize, name);
|
||
|
}
|
||
|
|
||
|
inline void CFileMapping::VCreate(void* file, DWORD flProtect, __int64 maximumSize, PCSTR name)
|
||
|
{
|
||
|
CheckHresult(HrCreate(file, flProtect, maximumSize, name));
|
||
|
}
|
||
|
|
||
|
inline CMappedViewOfFile::CMappedViewOfFile(void* fileMapping, DWORD access, __int64 offset, SIZE_T size)
|
||
|
: Base(NULL)
|
||
|
{
|
||
|
VCreate(fileMapping, access, offset, size);
|
||
|
}
|
||
|
|
||
|
inline void CMappedViewOfFile::VCreate(void* fileMapping, DWORD access, __int64 offset, SIZE_T size)
|
||
|
{
|
||
|
CheckHresult(HrCreate(fileMapping, access, offset, size));
|
||
|
}
|
||
|
|
||
|
inline HRESULT CMappedViewOfFile::HrCreate(void* fileMapping, DWORD access, __int64 offset, SIZE_T size)
|
||
|
{
|
||
|
LARGE_INTEGER liOffset;
|
||
|
liOffset.QuadPart = offset;
|
||
|
|
||
|
void* pvTemp = MapViewOfFile(fileMapping, access, liOffset.HighPart, liOffset.LowPart, size);
|
||
|
if (pvTemp == NULL)
|
||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||
|
Base::operator=(pvTemp);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
inline void COperatorCloseHandle::operator()(void* handle) const { CloseHandle(handle); }
|
||
|
inline void COperatorFindClose::operator()(void* handle) const { FindClose(handle); }
|
||
|
inline void COperatorUnmapViewOfFile::operator()(void* handle) const { UnmapViewOfFile(handle); }
|
||
|
inline void COperatorRegCloseKey::operator()(void* handle) const { RegCloseKey(reinterpret_cast<HKEY>(handle)); }
|
||
|
inline void COperatorCloseEventLog::operator()(void* handle) const { CloseEventLog(handle); }
|
||
|
inline void COperatorDeregisterEventSource::operator()(void* handle) const { DeregisterEventSource(handle); }
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
m_handle = const_cast<void*>(handle);
|
||
|
}
|
||
|
|
||
|
template <void* const* invalidValue, typename Closer>
|
||
|
void CHandleTemplate<invalidValue, Closer>::Close()
|
||
|
{
|
||
|
void* handle = Detach();
|
||
|
if (handle != *invalidValue)
|
||
|
{
|
||
|
Closer close;
|
||
|
close(handle);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template <void* const* invalidValue, typename Closer>
|
||
|
CHandleTemplate<invalidValue, Closer>::~CHandleTemplate()
|
||
|
{
|
||
|
Close();
|
||
|
}
|
||
|
|
||
|
template <void* const* invalidValue, typename Closer>
|
||
|
CHandleTemplate<invalidValue, Closer>::operator void*()
|
||
|
{
|
||
|
return m_handle;
|
||
|
}
|
||
|
|
||
|
template <void* const* invalidValue, typename Closer>
|
||
|
CHandleTemplate<invalidValue, Closer>::operator const void*() const
|
||
|
{
|
||
|
return m_handle;
|
||
|
}
|