reactos/sdk/lib/atl/atlfile.h

282 lines
6.7 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS ATL
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: ATL File implementation
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
*/
#pragma once
#include <atlbase.h>
namespace ATL
{
//class CAtlFile: TODO
// public CHandle
//{
//};
//class CAtlTemporaryFile TODO
//{
//};
class CAtlFileMappingBase
{
private:
void* m_pData;
SIZE_T m_nMappingSize;
HANDLE m_hMapping;
ULARGE_INTEGER m_nOffset;
DWORD m_dwViewDesiredAccess;
public:
CAtlFileMappingBase() throw()
:m_pData(NULL)
,m_nMappingSize(0)
,m_hMapping(NULL)
,m_dwViewDesiredAccess(0)
{
m_nOffset.QuadPart = 0;
}
~CAtlFileMappingBase() throw()
{
Unmap();
}
CAtlFileMappingBase(CAtlFileMappingBase& orig)
{
HRESULT hr;
m_pData = NULL;
m_nMappingSize = 0;
m_hMapping = NULL;
m_dwViewDesiredAccess = 0;
m_nOffset.QuadPart = 0;
hr = CopyFrom(orig);
if (FAILED(hr))
AtlThrow(hr);
}
CAtlFileMappingBase& operator=(CAtlFileMappingBase& orig)
{
HRESULT hr;
hr = CopyFrom(orig);
if (FAILED(hr))
AtlThrow(hr);
return *this;
}
HRESULT CopyFrom(CAtlFileMappingBase& orig) throw()
{
HRESULT hr = S_OK;
if (&orig == this)
return S_OK;
ATLASSERT(m_pData == NULL);
ATLASSERT(m_hMapping == NULL);
ATLASSERT(orig.m_pData != NULL);
m_nMappingSize = orig.m_nMappingSize;
m_nOffset.QuadPart = orig.m_nOffset.QuadPart;
m_dwViewDesiredAccess = orig.m_dwViewDesiredAccess;
if (::DuplicateHandle(GetCurrentProcess(), orig.m_hMapping, GetCurrentProcess(), &m_hMapping, 0, TRUE, DUPLICATE_SAME_ACCESS))
{
m_pData = ::MapViewOfFile(m_hMapping, m_dwViewDesiredAccess, m_nOffset.HighPart, m_nOffset.LowPart, m_nMappingSize);
if (!m_pData)
{
hr = AtlHresultFromLastError();
::CloseHandle(m_hMapping);
m_hMapping = NULL;
}
}
else
{
hr = AtlHresultFromLastError();
}
return hr;
}
HRESULT MapFile(
HANDLE hFile,
SIZE_T nMappingSize = 0,
ULONGLONG nOffset = 0,
DWORD dwMappingProtection = PAGE_READONLY,
DWORD dwViewDesiredAccess = FILE_MAP_READ) throw()
{
HRESULT hr = S_OK;
ULARGE_INTEGER FileSize;
ATLASSERT(hFile != INVALID_HANDLE_VALUE);
ATLASSERT(m_pData == NULL);
ATLASSERT(m_hMapping == NULL);
FileSize.LowPart = ::GetFileSize(hFile, &FileSize.HighPart);
FileSize.QuadPart = nMappingSize > FileSize.QuadPart ? nMappingSize : FileSize.QuadPart;
m_hMapping = ::CreateFileMapping(hFile, NULL, dwMappingProtection, FileSize.HighPart, FileSize.LowPart, 0);
if (m_hMapping)
{
m_nMappingSize = nMappingSize == 0 ? (SIZE_T)(FileSize.QuadPart - nOffset) : nMappingSize;
m_nOffset.QuadPart = nOffset;
m_dwViewDesiredAccess = dwViewDesiredAccess;
m_pData = ::MapViewOfFile(m_hMapping, m_dwViewDesiredAccess, m_nOffset.HighPart, m_nOffset.LowPart, m_nMappingSize);
if (!m_pData)
{
hr = AtlHresultFromLastError();
::CloseHandle(m_hMapping);
m_hMapping = NULL;
}
}
else
{
hr = AtlHresultFromLastError();
}
return hr;
}
HRESULT MapSharedMem(
SIZE_T nMappingSize,
LPCTSTR szName,
BOOL* pbAlreadyExisted = NULL,
LPSECURITY_ATTRIBUTES lpsa = NULL,
DWORD dwMappingProtection = PAGE_READWRITE,
DWORD dwViewDesiredAccess = FILE_MAP_ALL_ACCESS) throw()
{
HRESULT hr = S_OK;
ULARGE_INTEGER Size;
ATLASSERT(nMappingSize > 0);
ATLASSERT(szName != NULL);
ATLASSERT(m_pData == NULL);
ATLASSERT(m_hMapping == NULL);
m_nMappingSize = nMappingSize;
m_dwViewDesiredAccess = dwViewDesiredAccess;
m_nOffset.QuadPart = 0;
Size.QuadPart = nMappingSize;
m_hMapping = ::CreateFileMapping(NULL, lpsa, dwMappingProtection, Size.HighPart, Size.LowPart, szName);
if (m_hMapping != NULL)
{
if (pbAlreadyExisted)
*pbAlreadyExisted = GetLastError() == ERROR_ALREADY_EXISTS;
m_pData = ::MapViewOfFile(m_hMapping, dwViewDesiredAccess, m_nOffset.HighPart, m_nOffset.LowPart, m_nMappingSize);
if (!m_pData)
{
hr = AtlHresultFromLastError();
::CloseHandle(m_hMapping);
m_hMapping = NULL;
}
}
else
{
hr = AtlHresultFromLastError();
}
return hr;
}
HRESULT OpenMapping(
LPCTSTR szName,
SIZE_T nMappingSize,
ULONGLONG nOffset = 0,
DWORD dwViewDesiredAccess = FILE_MAP_ALL_ACCESS) throw()
{
HRESULT hr = S_OK;
ATLASSERT(szName != NULL);
ATLASSERT(m_pData == NULL);
ATLASSERT(m_hMapping == NULL);
m_nMappingSize = nMappingSize;
m_dwViewDesiredAccess = dwViewDesiredAccess;
m_nOffset.QuadPart = nOffset;
m_hMapping = ::OpenFileMapping(m_dwViewDesiredAccess, FALSE, szName);
if (m_hMapping)
{
m_pData = ::MapViewOfFile(m_hMapping, dwViewDesiredAccess, m_nOffset.HighPart, m_nOffset.LowPart, m_nMappingSize);
if (!m_pData)
{
hr = AtlHresultFromLastError();
::CloseHandle(m_hMapping);
m_hMapping = NULL;
}
}
else
{
hr = AtlHresultFromLastError();
}
return hr;
}
HRESULT Unmap() throw()
{
HRESULT hr = S_OK;
if (m_pData)
{
if (!::UnmapViewOfFile(m_pData))
hr = AtlHresultFromLastError();
m_pData = NULL;
}
if (m_hMapping)
{
// If we already had an error, do not overwrite it
if (!::CloseHandle(m_hMapping) && SUCCEEDED(hr))
hr = AtlHresultFromLastError();
m_hMapping = NULL;
}
return hr;
}
void* GetData() const throw()
{
return m_pData;
}
HANDLE GetHandle() throw ()
{
return m_hMapping;
}
SIZE_T GetMappingSize() throw()
{
return m_nMappingSize;
}
};
template <typename T = char>
class CAtlFileMapping:
public CAtlFileMappingBase
{
public:
operator T*() const throw()
{
return reinterpret_cast<T*>(GetData());
}
};
}