[ATL][ATL_APITEST] Add test + implementation for CAtlFileMapping

This commit is contained in:
Mark Jansen 2019-04-05 23:22:55 +02:00
parent bd75947372
commit 9853cc4d7e
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
10 changed files with 789 additions and 14 deletions

View file

@ -20,10 +20,12 @@
#pragma once
#include "atldef.h"
#include "atlcore.h"
#include "statreg.h"
#include "atlcomcli.h"
#include "atlalloc.h"
#include "atlexcept.h"
#include "comcat.h"
#include "tchar.h"
@ -32,18 +34,6 @@
#pragma warning(disable:4355)
#endif
#ifndef _ATL_PACKING
#define _ATL_PACKING 8
#endif
#ifndef _ATL_FREE_THREADED
#ifndef _ATL_APARTMENT_THREADED
#ifndef _ATL_SINGLE_THREADED
#define _ATL_FREE_THREADED
#endif
#endif
#endif
#ifndef ATLTRY
#define ATLTRY(x) x;
#endif
@ -58,7 +48,6 @@
#define ATL_DEPRECATED __declspec(deprecated)
#endif
#define offsetofclass(base, derived) (reinterpret_cast<DWORD_PTR>(static_cast<base *>(reinterpret_cast<derived *>(_ATL_PACKING))) - _ATL_PACKING)
namespace ATL
{

View file

@ -53,6 +53,12 @@
namespace ATL
{
inline HRESULT AtlHresultFromLastError() throw()
{
DWORD dwError = ::GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
template<class T>
class CComPtr

59
sdk/lib/atl/atldef.h Normal file
View file

@ -0,0 +1,59 @@
/*
* PROJECT: ReactOS ATL
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: ATL Base definitions
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
*/
#pragma once
#define _ATL_PACKING 8
#ifndef AtlThrow
#ifndef _ATL_CUSTOM_THROW
#define AtlThrow(x) ATL::AtlThrowImp(x)
#endif
#endif
#ifndef ATLASSERT
#define ATLASSERT(expr) _ASSERTE(expr)
#endif
// ATLASSUME, ATLENSURE, ATLVERIFY, ...
#ifdef _ATL_DISABLE_NO_VTABLE
#define ATL_NO_VTABLE
#else
#define ATL_NO_VTABLE __declspec(novtable)
#endif
#ifndef ATL_DEPRECATED
#define ATL_DEPRECATED __declspec(deprecated)
#endif
// ATL_NOTHROW, ATL_FORCEINLINE, ATL_NOINLINE
// _ATL, ATL_VER, ATL_FILENAME_VER, ATL_FILENAME_VERNUM, ...
#define offsetofclass(base, derived) (reinterpret_cast<DWORD_PTR>(static_cast<base *>(reinterpret_cast<derived *>(_ATL_PACKING))) - _ATL_PACKING)
#ifndef _ATL_FREE_THREADED
#ifndef _ATL_APARTMENT_THREADED
#ifndef _ATL_SINGLE_THREADED
#define _ATL_FREE_THREADED
#endif
#endif
#endif

View file

@ -9,6 +9,9 @@
#endif
#endif
namespace ATL
{
//FIXME: Enable when RaiseException is marked as NORETURN
//DECLSPEC_NORETURN
@ -37,9 +40,11 @@ inline void AtlThrowImp(HRESULT hr)
}
#ifndef AtlThrow
#define AtlThrow(x) AtlThrowImp(x)
#endif
}; // namespace ATL
#endif

281
sdk/lib/atl/atlfile.h Normal file
View file

@ -0,0 +1,281 @@
/*
* 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, NULL, 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());
}
};
}