CFileMappingHelper.h
#pragma once
#include
#include
#include
#include
CFileMappingHelper.cpp
#include "CFileMappingHelper.h"
typedef struct _FILE_MAPPING_DATA
{
DWORD dwCapacity = 0; //最大容量
DWORD dwPid = 0; //进程ID
DWORD dwSize = 0; //数据大小
BYTE Data[0]; //数据内容
}FILE_MAPPING_DATA, * PFILE_MAPPING_DATA;
CFileMappingHelper::CFileMappingHelper()
:
m_hFileMapping(nullptr),
m_hData(nullptr),
m_hMutex(nullptr),
m_bInit(false)
{
}
CFileMappingHelper::~CFileMappingHelper()
{
Uninitialize();
}
bool CFileMappingHelper::Initialize(
LPCTSTR strName/* = nullptr*/,
LPCTSTR strMutex/* = nullptr*/,
DWORD dwSize/* = 4096*/
)
{
SECURITY_ATTRIBUTES sa = { 0 };
SECURITY_DESCRIPTOR sd = { 0 };
bool isSuccess = false;
bool isFirstCreate = false;
if (m_bInit)
{
return true;
}
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;
(void)::InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
(void)::SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
do
{
m_hMutex = ::CreateMutex(&sa, FALSE, strMutex);
if (nullptr == m_hMutex)
{
break;
}
m_hFileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, dwSize + sizeof(FILE_MAPPING_DATA), strName);
if (nullptr == m_hFileMapping)
{
break;
}
if ((nullptr != m_hFileMapping) && (ERROR_ALREADY_EXISTS != ::GetLastError()))
{
isFirstCreate = true;
}
m_hData = (LPTSTR)::MapViewOfFile(m_hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (nullptr == m_hData)
{
break;
}
//首次创建, 设置信息
if (isFirstCreate)
{
PFILE_MAPPING_DATA pData = reinterpret_cast(m_hData);
pData->dwCapacity = dwSize;
pData->dwPid = ::GetCurrentProcessId();
}
isSuccess = true;
} while (false);
if (!isSuccess)
{
Uninitialize();
}
m_bInit = isSuccess;
return isSuccess;
}
void CFileMappingHelper::Uninitialize()
{
if (false == m_bInit)
{
return;
}
if (m_hData)
{
::UnmapViewOfFile(m_hData);
m_hData = nullptr;
}
if (m_hFileMapping)
{
::CloseHandle(m_hFileMapping);
m_hFileMapping = nullptr;
}
if (m_hMutex)
{
::CloseHandle(m_hMutex);
m_hMutex = nullptr;
}
m_bInit = false;
}
bool CFileMappingHelper::IsInitialized() const
{
return m_bInit;
}
bool CFileMappingHelper::Write(LPCVOID lpData, DWORD dwSize)
{
bool isSuccess = false;
DWORD dwWait = WAIT_OBJECT_0;
if ((nullptr == m_hMutex) || (nullptr == m_hData) || (nullptr == lpData) || (0 == dwSize))
{
return false;
}
PFILE_MAPPING_DATA pData = reinterpret_cast(m_hData);
do
{
dwWait = ::WaitForSingleObject(m_hMutex, INFINITE);
if (WAIT_OBJECT_0 != dwWait)
{
break;
}
if (dwSize <= pData->dwCapacity)
{
::memcpy_s(pData->Data, pData->dwCapacity, lpData, dwSize);
pData->dwSize = dwSize;
isSuccess = true;
}
} while (false);
::ReleaseMutex(m_hMutex);
return isSuccess;
}
bool CFileMappingHelper::Read(LPVOID lpData, DWORD dwSize, LPDWORD lpBytesRead/* = nullptr*/)
{
bool isSuccess = false;
DWORD dwWait = WAIT_OBJECT_0;
if ((nullptr == m_hMutex) || (nullptr == m_hData) || (nullptr == lpData) || (0 == dwSize))
{
return false;
}
PFILE_MAPPING_DATA pData = reinterpret_cast(m_hData);
do
{
dwWait = ::WaitForSingleObject(m_hMutex, INFINITE);
if (WAIT_OBJECT_0 != dwWait)
{
break;
}
if (dwSize <= (pData->dwCapacity))
{
::memcpy_s(lpData, dwSize, pData->Data, pData->dwSize);
if (nullptr != lpBytesRead)
{
*lpBytesRead = pData->dwSize;
}
isSuccess = true;
}
} while (false);
::ReleaseMutex(m_hMutex);
return isSuccess;
}
DWORD CFileMappingHelper::GetCapacity() const
{
if ((nullptr == m_hMutex) || (nullptr == m_hData))
{
return 0;
}
PFILE_MAPPING_DATA pData = reinterpret_cast(m_hData);
return pData->dwCapacity;
}