C++共享内存封装类

来源:互联网 发布:淘宝店家 编辑:程序博客网 时间:2024/06/05 20:39

头文件

/******************************************************************++  File Name :   FFMClass.h++  Description: 共享內存類---------------------------------------------------------------++  Author:  Fei ZhaoDong++  Create time: 2004/3/25 上午 10:00:00++  Version:     1.1++  Modifier:  ++  Activities:    ++  Update List: 2004/3/30 下午 02:59:45*******************************************************************/// FFMClass.h: interface for the CFFMClass.////////////////////////////////////////////////////////////////////////#ifndef FZD_FFMCLASS_H#define FZD_FFMCLASS_H//#include <Winbase.h>#include <aclapi.h>//////////////////////////////////////////////////////////////////////// Macro definition// 以下為共享內存定義#define DEFAULT_FILENAME NULL    // 默認的文件名#define DEFAULT_MAPNAME  "Local//_FZD_MAP_"   // 默認的共享內存名#define DEFAULT_MAPSIZE  (0xFFFF + 1)  // 默認的共享內存大小const DWORD NETRGUSER_CFM_CODE = 0x1211DBFF; // 校驗碼, 用於命令數據const DWORD NETRGUSER_CMD_NONE = 0;   // 初始化指令碼, 無指令// 以下為錯誤碼定義#define ERROR_LEN    256    // 錯誤描述長度#define ERROR_INVALID_CMDCODE 0xE00001FF  // 已經存在完全一樣的共享內存#define ERROR_NO_MAPFILE             0xE00002FF  // 未分配共享內存文件#define ERROR_INVALID_CFMCODE 0xE00003FF  // 校驗碼不匹配//////////////////////////////////////////////////////////////////////// 內存文件格式定義#pragma pack(1)// 用於存儲命令數據的內存文件格式typedef struct _tagDATA_HEADER{DWORD dwConfirmCode; // 校驗碼DWORD nCommandCode;  // 指令識別碼DWORD dwDataSize;  // 數據的大小BYTE  dwReserved[19]; // 保留BYTE  bInfo[1];   // 數據起始地址_tagDATA_HEADER(){dwConfirmCode = NETRGUSER_CFM_CODE;nCommandCode = NETRGUSER_CMD_NONE;dwDataSize = 0;ZeroMemory(dwReserved, 19);ZeroMemory(bInfo, 1);}}DATA_HEADER, *LPDATA_HEADER;typedef DWORD (WINAPI *PSetEntriesInAcl)(ULONG, PEXPLICIT_ACCESS, PACL, PACL*);// 用於存儲應答數據的共享內存文件格式 (暫不用)typedef struct _tagANS_HEADER{}ANS_HEADER, *LPANS_HEADER;#pragma pack()//////////////////////////////////////////////////////////////////////// 類定義,共享內存服務端class CFFMServer  {public:CFFMServer();virtual ~CFFMServer();CFFMServer(char *szFileName, char *szMapName, DWORD dwSize);protected:PSetEntriesInAcl m_fnpSetEntriesInAcl;HANDLE m_hFile;   // 映射文件句柄HANDLE m_hFileMap;   // 內存文件句柄LPVOID m_lpFileMapBuffer; // 緩衝區指針char *m_pFileName;  // 映射文件名char *m_pMapName;  // 內存文件名DWORD m_dwSize;   // 緩衝區大小BOOL m_bCreateFlag;  // 是否已創建共享內存DWORD   m_dwLastError;  // 錯誤代碼private:void _Init();    // 初始化參數BOOL _IsWinNTLater();  // 判斷當前操作系統public:BOOL Create(char *szFileName = DEFAULT_FILENAME,char *szMapName = DEFAULT_MAPNAME,DWORD dwSize = DEFAULT_MAPSIZE); // 新建共享內存LPVOID GetBuffer();      // 獲取內存文件指針DWORD GetSize();      // 獲取內存文件大小void Destory();       // 銷毀已有的共享內存BOOL WriteCmdData(      // 寫入命令數據DWORD nCommandCode,DWORD dwDataSize,const LPVOID pBuf);};//////////////////////////////////////////////////////////////////////// 類定義,共享內存客戶端class CFFMClient  {public:CFFMClient();virtual ~CFFMClient();CFFMClient(DWORD dwAccess, char *szMapName, DWORD dwSize);protected:HANDLE m_hFileMap;   // 內存文件句柄LPVOID m_lpFileMapBuffer; // 內存文件指針char *m_pMapName;  // 內存文件名DWORD m_dwSize;   // 緩衝區大小BOOL m_bOpenFlag;  // 是否已經打開了一個內存文件DWORD   m_dwLastError;  // 錯誤代碼private:void _Init();    // 初始化參數public:BOOL Open(DWORD dwAccess = FILE_MAP_READ | FILE_MAP_WRITE,char *szMapName = DEFAULT_MAPNAME,DWORD dwSize = 0);      // 打開一個內存文件LPVOID GetBuffer();       // 獲取當前內存文件的指針void Destory();        // 關閉當前對內存文件的訪問DWORD GetSize();      // 獲取內存文件大小BOOL GetCmdDataSize(DWORD *pDataSize);  // 讀取命令數據大小BOOL ReadCmdData(       // 讀取命令數據DWORD dwCommandCode,DWORD dwBufSize,LPVOID pOutBuf);BOOL WriteCmdData(      // 寫入命令數據DWORD memSize, DWORD nCommandCode,DWORD dwDataSize,const LPVOID pBuf);};#endif // FZD_FFMCLASS_H

实现文件


/******************************************************************++  File Name : FFMClass.cpp++  Description: 共享內存類---------------------------------------------------------------++  Author:  Fei ZhaoDong++  Create time: 2004/3/25 上午 10:00:00++  Version:     1.0++  Modifier:  ++   Activities:    ++  Update List: 2004/3/29 下午 02:59:45*******************************************************************/// FFMClass.cpp: implementation of the CFFMClass.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "FFMClass.h"//#include <aclapi.h>//#include <windows.h>//#include <aclapi.h>//#include <lmerr.h>////#include <stdio.h>//////////////////////////////////////////////////////////////////////// CFFMServer//////////////////////////////////////////////////////////////////////CFFMServer::CFFMServer(){m_dwLastError = 0;m_fnpSetEntriesInAcl = NULL;_Init();}CFFMServer::~CFFMServer(){Destory();}CFFMServer::CFFMServer(char *szFileName, char *szMapName, DWORD dwSize){// 以自定義設置創建共享內存塊_Init();Create(szFileName, szMapName, dwSize);}// 初始化各個參數void CFFMServer::_Init(){m_hFile = NULL;m_hFileMap = NULL;m_lpFileMapBuffer = NULL;m_pFileName = NULL;m_pMapName = NULL;m_dwSize = 0;m_bCreateFlag = FALSE;}// 判斷是否NT4.0以上操作系統BOOL CFFMServer::_IsWinNTLater(){OSVERSIONINFO Ver;BOOL bAbleVersion = FALSE;Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);if (GetVersionEx(&Ver)){if (Ver.dwPlatformId == VER_PLATFORM_WIN32_NT&& Ver.dwMajorVersion >= 4){bAbleVersion = TRUE;}}else{m_dwLastError = GetLastError();}return bAbleVersion;}// 釋放當前共享內存,並重新初始化參數void CFFMServer::Destory(){if (m_lpFileMapBuffer != NULL){UnmapViewOfFile(m_lpFileMapBuffer);m_lpFileMapBuffer = NULL;}if (m_hFileMap != NULL){CloseHandle(m_hFileMap);m_hFileMap = NULL;}if (m_hFile && m_hFile != INVALID_HANDLE_VALUE){CloseHandle(m_hFile);m_hFile = NULL;}if (m_pFileName != NULL){free(m_pFileName);m_pFileName = NULL;}if (m_pMapName != NULL){free(m_pMapName);m_pMapName = NULL;}_Init();}static void FreeSidEx(PSID oSID){try{FreeSid(oSID);}catch(...){}}// 創建共享內存塊BOOL CFFMServer::Create(char *szFileName, char *szMapName, DWORD dwSize){// 釋放已有的共享內存塊if (m_bCreateFlag){Destory();}// 拷貝各個參數if (szFileName){m_pFileName = _strdup(szFileName);}if (szMapName){m_pMapName = _strdup(szMapName);}else{m_pMapName = _strdup(DEFAULT_MAPNAME);}if (dwSize > 0){m_dwSize = dwSize;}else{m_dwSize = DEFAULT_MAPSIZE;}// 以下創建共享內存if (m_pFileName){m_hFile = CreateFile(m_pFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);}else{// 默認情況下,在頁面文件中創建共享內存m_hFile = INVALID_HANDLE_VALUE;}if (_IsWinNTLater()){// Set DACLconst int NUM_ACES = 2;   // number if ACEs int DACL// evryone -- read// creator -- full access// 初始化參數PSID pEveryoneSID        = NULL; // everyone群組SIDPSID pCreatorSID   = NULL; // creator群組SIDPACL pFileMapACL         = NULL; // 準備新內存文件的DACLPSECURITY_DESCRIPTOR  pSD = NULL; // 內存文件的SDSECURITY_ATTRIBUTES   saFileMap; // 內存文件的SAEXPLICIT_ACCESS    ea[NUM_ACES]; // 外部訪問結構 BOOL bHasErr   = FALSE; // 返回值// 以下創建SIDSID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;SID_IDENTIFIER_AUTHORITY SIDAuthCreator = SECURITY_CREATOR_SID_AUTHORITY;// Evryoneif (!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID,0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)){bHasErr = TRUE;goto Finish;}// Creatorif (!AllocateAndInitializeSid(&SIDAuthCreator, 1, SECURITY_CREATOR_OWNER_RID,0, 0, 0, 0, 0, 0, 0, &pCreatorSID)){bHasErr = TRUE;goto Finish;}// 填充ACEZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS));// S-1-1-0 evryone, 唯讀權限ea[0].grfAccessPermissions = GENERIC_READ | GENERIC_WRITE;ea[0].grfAccessMode = SET_ACCESS;ea[0].grfInheritance= NO_INHERITANCE;ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;ea[0].Trustee.ptstrName  = (LPTSTR) pEveryoneSID;// S-1-3-0 creator owner, 完全權限ea[1].grfAccessPermissions = STANDARD_RIGHTS_ALL;ea[1].grfAccessMode = SET_ACCESS;ea[1].grfInheritance= NO_INHERITANCE;ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;ea[1].Trustee.ptstrName  = (LPTSTR) pCreatorSID;// 創建並填充ACLif(NULL == m_fnpSetEntriesInAcl){HINSTANCE hLib = ::LoadLibrary("Advapi32.dll");if(NULL != hLib){m_fnpSetEntriesInAcl = (PSetEntriesInAcl)GetProcAddress(hLib,"SetEntriesInAclA");::FreeLibrary(hLib);hLib = NULL;}}if (ERROR_SUCCESS != m_fnpSetEntriesInAcl(NUM_ACES, ea, NULL, &pFileMapACL)){bHasErr = TRUE;goto Finish;}// 創建並初始化SDpSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (NULL == pSD){bHasErr = TRUE;goto Finish;} if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {bHasErr = TRUE;goto Finish;}// 添加ACL到SD中去if (!SetSecurityDescriptorDacl(pSD,TRUE,     // fDaclPresent flag   pFileMapACL, FALSE))   // not a default DACL {bHasErr = TRUE;goto Finish;}// 設置SAsaFileMap.nLength = sizeof(SECURITY_ATTRIBUTES);saFileMap.bInheritHandle = FALSE;saFileMap.lpSecurityDescriptor = pSD;// 創建共享內存文件if (m_hFile != NULL){m_hFileMap = CreateFileMapping(m_hFile,&saFileMap,PAGE_READWRITE,0,m_dwSize,m_pMapName);if (NULL == m_hFileMap){m_hFileMap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE,TRUE, m_pMapName);if (NULL == m_hFileMap){m_dwLastError = GetLastError(); Destory();goto Finish;}}}Finish://if (pSD != NULL)//{//LocalFree(pSD);//}pSD = NULL;if (pFileMapACL != NULL){LocalFree(pFileMapACL);pFileMapACL = NULL;}if (pEveryoneSID != NULL){FreeSidEx(pEveryoneSID);pEveryoneSID = NULL;}if (pCreatorSID != NULL){FreeSidEx(pCreatorSID);pCreatorSID = NULL;}if (bHasErr) {m_dwLastError = GetLastError();return FALSE;}}else{// 創建共享內存文件if (m_hFile){m_hFileMap = CreateFileMapping(m_hFile,NULL,PAGE_READWRITE,0,m_dwSize,m_pMapName);if (NULL == m_hFileMap){m_dwLastError = GetLastError();Destory();return FALSE;}}}// 映射文件指針到用戶if (m_hFileMap){m_lpFileMapBuffer = MapViewOfFile(m_hFileMap,FILE_MAP_ALL_ACCESS,0,0,m_dwSize);if (NULL == m_lpFileMapBuffer){m_dwLastError = GetLastError();Destory();return FALSE;}}m_bCreateFlag = TRUE;return TRUE;}// 獲取內存文件指針LPVOID CFFMServer::GetBuffer(){return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL);}// 獲取內存文件大小DWORD CFFMServer::GetSize(){return m_dwSize;}BOOL CFFMServer::WriteCmdData(DWORD nCommandCode, DWORD dwDataSize, const LPVOID pBuf){// 檢驗數據的合理性if (NULL == GetBuffer()){m_dwLastError = ERROR_NO_MAPFILE;SetLastError(ERROR_NO_MAPFILE);return FALSE;}if (NETRGUSER_CMD_NONE == nCommandCode){m_dwLastError = ERROR_INVALID_CMDCODE;SetLastError(ERROR_INVALID_CMDCODE);return FALSE;}if (dwDataSize > 0 && pBuf == NULL){m_dwLastError = ERROR_INVALID_USER_BUFFER;SetLastError(ERROR_INVALID_USER_BUFFER);return FALSE;}if (dwDataSize + sizeof(DATA_HEADER) > GetSize()){m_dwLastError = ERROR_BUFFER_OVERFLOW;SetLastError(ERROR_BUFFER_OVERFLOW);return FALSE;}// 填寫數據結構// 文件頭DATA_HEADER dataHeader;dataHeader.nCommandCode = nCommandCode;dataHeader.dwDataSize = dwDataSize;ZeroMemory(GetBuffer(), GetSize());memcpy(GetBuffer(), &dataHeader, sizeof(DATA_HEADER));// 數據塊LPDATA_HEADER pData = (LPDATA_HEADER)GetBuffer();memcpy(pData->bInfo, pBuf, dwDataSize);return TRUE;}//////////////////////////////////////////////////////////////////////// CFFMClient//////////////////////////////////////////////////////////////////////CFFMClient::CFFMClient(){m_dwLastError = 0;_Init();}CFFMClient::~CFFMClient(){Destory();}CFFMClient::CFFMClient(DWORD dwAccess, char *szMapName, DWORD dwSize){_Init();if (!Open(dwAccess, szMapName, dwSize)){Destory();}}// 初始化參數void CFFMClient::_Init(){m_hFileMap = NULL;m_lpFileMapBuffer = NULL;m_pMapName = NULL;m_bOpenFlag = FALSE;}// 關閉當前對內存文件的訪問void CFFMClient::Destory(){if (m_lpFileMapBuffer){UnmapViewOfFile(m_lpFileMapBuffer);m_lpFileMapBuffer = NULL;}if (m_hFileMap){CloseHandle(m_hFileMap);m_hFileMap = NULL;}if (m_pMapName){free(m_pMapName);m_pMapName = NULL;}_Init();}// 打開一個內存文件BOOL CFFMClient::Open(DWORD dwAccess, char *szMapName, DWORD dwSize){if (m_bOpenFlag){Destory();}if (szMapName != NULL){m_pMapName = _strdup(szMapName);}else{m_pMapName = _strdup(DEFAULT_MAPNAME);}m_hFileMap = OpenFileMapping(dwAccess, TRUE, m_pMapName);if (NULL == m_hFileMap){m_dwLastError = GetLastError();Destory();return FALSE;}m_lpFileMapBuffer = MapViewOfFile(m_hFileMap, dwAccess, 0, 0, dwSize);if (NULL == m_lpFileMapBuffer){m_dwLastError = GetLastError();Destory();return FALSE;}m_bOpenFlag = TRUE;return TRUE;}// 獲取當前內存文件的指針LPVOID CFFMClient::GetBuffer(){return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL);}// 讀取命令數據大小BOOL CFFMClient::GetCmdDataSize(DWORD *pDataSize){_ASSERT(pDataSize != NULL);*pDataSize = 0;LPDATA_HEADER pHeader = (LPDATA_HEADER)GetBuffer();if (NULL == pHeader){m_dwLastError = ERROR_NO_MAPFILE;SetLastError(ERROR_NO_MAPFILE);return FALSE;}if (NETRGUSER_CFM_CODE != pHeader->dwConfirmCode){m_dwLastError = ERROR_INVALID_CFMCODE;SetLastError(ERROR_INVALID_CFMCODE);return FALSE;}if (NETRGUSER_CMD_NONE == pHeader->nCommandCode){m_dwLastError = ERROR_INVALID_CMDCODE;SetLastError(ERROR_INVALID_CMDCODE);return FALSE;}*pDataSize = pHeader->dwDataSize;return TRUE;}// 讀取命令數據BOOL CFFMClient::ReadCmdData(DWORD dwCommandCode, DWORD dwBufSize, LPVOID pOutBuf){_ASSERT (pOutBuf != NULL);LPDATA_HEADER pHeader = (LPDATA_HEADER)GetBuffer();if (NULL == pHeader){m_dwLastError = ERROR_NO_MAPFILE;SetLastError(ERROR_NO_MAPFILE);return FALSE;}if (NETRGUSER_CFM_CODE != pHeader->dwConfirmCode){m_dwLastError = ERROR_INVALID_CFMCODE;SetLastError(ERROR_INVALID_CFMCODE);return FALSE;}if (NETRGUSER_CMD_NONE == pHeader->nCommandCode){m_dwLastError = ERROR_INVALID_CMDCODE;SetLastError(ERROR_INVALID_CMDCODE);return FALSE;}if (pHeader->dwDataSize > dwBufSize){m_dwLastError = ERROR_BUFFER_OVERFLOW;SetLastError(ERROR_BUFFER_OVERFLOW);return FALSE;}if (pHeader->nCommandCode != dwCommandCode){m_dwLastError = ERROR_INVALID_CMDCODE;SetLastError(ERROR_INVALID_CMDCODE);return FALSE;}ZeroMemory(pOutBuf, dwBufSize);// 拷貝數據到緩衝區memcpy(pOutBuf, pHeader->bInfo, pHeader->dwDataSize);return TRUE;}BOOL CFFMClient::WriteCmdData(DWORD memSize, DWORD nCommandCode, DWORD dwDataSize, const LPVOID pBuf){if(!memSize)memSize = DEFAULT_MAPSIZE;m_dwSize = memSize;// 檢驗數據的合理性if (NULL == GetBuffer()){m_dwLastError = ERROR_NO_MAPFILE;SetLastError(ERROR_NO_MAPFILE);return FALSE;}if (NETRGUSER_CMD_NONE == nCommandCode){m_dwLastError = ERROR_INVALID_CMDCODE;SetLastError(ERROR_INVALID_CMDCODE);return FALSE;}if (dwDataSize > 0 && pBuf == NULL){m_dwLastError = ERROR_INVALID_USER_BUFFER;SetLastError(ERROR_INVALID_USER_BUFFER);return FALSE;}if (dwDataSize + sizeof(DATA_HEADER) > GetSize()){m_dwLastError = ERROR_BUFFER_OVERFLOW;SetLastError(ERROR_BUFFER_OVERFLOW);return FALSE;}// 填寫數據結構// 文件頭DATA_HEADER dataHeader;dataHeader.nCommandCode = nCommandCode;dataHeader.dwDataSize = dwDataSize;ZeroMemory(GetBuffer(), GetSize());memcpy(GetBuffer(), &dataHeader, sizeof(DATA_HEADER));// 數據塊LPDATA_HEADER pData = (LPDATA_HEADER)GetBuffer();memcpy(pData->bInfo, pBuf, dwDataSize);return TRUE;}// 獲取內存文件大小DWORD CFFMClient::GetSize(){return m_dwSize;}



原创粉丝点击