2019-04-05 21:22:55 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2019-04-19 23:35:39 +00:00
|
|
|
if (::DuplicateHandle(GetCurrentProcess(), orig.m_hMapping, GetCurrentProcess(), &m_hMapping, 0, TRUE, DUPLICATE_SAME_ACCESS))
|
2019-04-05 21:22:55 +00:00
|
|
|
{
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}
|