CFileMappingHelper.h
#pragma once
#include <wtypesbase.h>
#include <vector>
#include <string>
#include <map>
#include <tchar.h>
#pragma warning(disable:4200)
#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif
class CFileMappingHelper
{
public:
CFileMappingHelper();
~CFileMappingHelper();
//删除拷贝构造与赋值重载
CFileMappingHelper(const CFileMappingHelper&) = delete;
CFileMappingHelper& operator = (const CFileMappingHelper&) = delete;
//
// @brief: 初始化一个文件映射
// @param: strName 文件映射名
// @param: strMutex 互斥锁名
// @param: dwSize 缓冲大小
// @ret: bool
bool Initialize(
LPCTSTR strName = nullptr,
LPCTSTR strMutex = nullptr,
DWORD dwSize = 4096
);
//
// @brief: 反初始化
// @param: 无
// @ret: void
void Uninitialize();
//
// @brief: 是否已初始化
// @param: 无
// @ret: bool 初始化与否
bool IsInitialized() const;
//
// @brief: 获取文件映射容量
// @ret: DWORD 文件映射容量
DWORD GetCapacity() const;
//
// @brief: 写入文件映射
// @param: lpData 要写入数据
// @param: dwSize 写入长度
// @ret: bool 操作成功与否
bool Write(LPCVOID lpData, DWORD dwSize);
//
// @brief: 读取文件映射
// @param: lpData 读入的缓冲
// @param: dwSize 缓冲长度
// @param: lpBytesRead 成功读取的长度
// @ret: bool 操作成功与否
bool Read(LPVOID lpData, DWORD dwSize, LPDWORD lpBytesRead = nullptr);
private:
HANDLE m_hFileMapping = nullptr;
LPTSTR m_hData = nullptr;
HANDLE m_hMutex = nullptr;
bool m_bInit = false;
};
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<PFILE_MAPPING_DATA>(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<PFILE_MAPPING_DATA>(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<PFILE_MAPPING_DATA>(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<PFILE_MAPPING_DATA>(m_hData);
return pData->dwCapacity;
}