/****************************************************************** ++ File Name : FFMClass.h ++ Description: 共享內(nèi)存類 --------------------------------------------------------------- ++ 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 <aclapi.h> ////////////////////////////////////////////////////////////////////// // Macro definition // 以下為共享內(nèi)存定義 #define DEFAULT_FILENAME NULL // 默認的文件名 #define DEFAULT_MAPNAME "_FZD_MAP_" // 默認的共享內(nèi)存名 #define DEFAULT_MAPSIZE (0xFFFF + 1) // 默認的共享內(nèi)存大小 const DWORD NETRGUSER_CFM_CODE = 0x1211DBFF; // 校驗碼, 用於命令數(shù)據(jù) const DWORD NETRGUSER_CMD_NONE = 0; // 初始化指令碼, 無指令 // 以下為錯誤碼定義 #define ERROR_LEN 256 // 錯誤描述長度 #define ERROR_INVALID_CMDCODE 0xE00001FF // 已經(jīng)存在完全一樣的共享內(nèi)存 #define ERROR_NO_MAPFILE 0xE00002FF // 未分配共享內(nèi)存文件 #define ERROR_INVALID_CFMCODE 0xE00003FF // 校驗碼不匹配 ////////////////////////////////////////////////////////////////////// // 內(nèi)存文件格式定義 #pragma pack(1) // 用於存儲命令數(shù)據(jù)的內(nèi)存文件格式 typedef struct _tagDATA_HEADER { DWORD dwConfirmCode; // 校驗碼 DWORD nCommandCode; // 指令識別碼 DWORD dwDataSize; // 數(shù)據(jù)的大小 BYTE dwReserved[19]; // 保留 BYTE bInfo[1]; // 數(shù)據(jù)起始地址 _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*); // 用於存儲應答數(shù)據(jù)的共享內(nèi)存文件格式 (暫不用) typedef struct _tagANS_HEADER { }ANS_HEADER, *LPANS_HEADER; #pragma pack() ////////////////////////////////////////////////////////////////////// // 類定義,共享內(nèi)存服務端 class CFFMServer { public: CFFMServer(); virtual ~CFFMServer(); CFFMServer(char *szFileName, char *szMapName, DWORD dwSize); protected: PSetEntriesInAcl m_fnpSetEntriesInAcl; HANDLE m_hFile; // 映射文件句柄 HANDLE m_hFileMap; // 內(nèi)存文件句柄 LPVOID m_lpFileMapBuffer; // 緩衝區(qū)指針 char *m_pFileName; // 映射文件名 char *m_pMapName; // 內(nèi)存文件名 DWORD m_dwSize; // 緩衝區(qū)大小 BOOL m_bCreateFlag; // 是否已創(chuàng)建共享內(nèi)存 DWORD m_dwLastError; // 錯誤代碼 private: void _Init(); // 初始化參數(shù) BOOL _IsWinNTLater(); // 判斷當前操作系統(tǒng) public: BOOL Create(char *szFileName = DEFAULT_FILENAME, char *szMapName = DEFAULT_MAPNAME, DWORD dwSize = DEFAULT_MAPSIZE); // 新建共享內(nèi)存 LPVOID GetBuffer(); // 獲取內(nèi)存文件指針 DWORD GetSize(); // 獲取內(nèi)存文件大小 void Destory(); // 銷毀已有的共享內(nèi)存 BOOL WriteCmdData( // 寫入命令數(shù)據(jù) DWORD nCommandCode, DWORD dwDataSize, const LPVOID pBuf); }; ////////////////////////////////////////////////////////////////////// // 類定義,共享內(nèi)存客戶端 class CFFMClient { public: CFFMClient(); virtual ~CFFMClient(); CFFMClient(DWORD dwAccess, char *szMapName, DWORD dwSize); protected: HANDLE m_hFileMap; // 內(nèi)存文件句柄 LPVOID m_lpFileMapBuffer; // 內(nèi)存文件指針 char *m_pMapName; // 內(nèi)存文件名 BOOL m_bOpenFlag; // 是否已經(jīng)打開了一個內(nèi)存文件 DWORD m_dwLastError; // 錯誤代碼 private: void _Init(); // 初始化參數(shù) public: BOOL Open(DWORD dwAccess = FILE_MAP_READ, char *szMapName = DEFAULT_MAPNAME, DWORD dwSize = 0); // 打開一個內(nèi)存文件 LPVOID GetBuffer(); // 獲取當前內(nèi)存文件的指針 void Destory(); // 關閉當前對內(nèi)存文件的訪問 BOOL GetCmdDataSize(DWORD *pDataSize); // 讀取命令數(shù)據(jù)大小 BOOL ReadCmdData( // 讀取命令數(shù)據(jù) DWORD dwCommandCode, DWORD dwBufSize, LPVOID pOutBuf); }; #endif // FZD_FFMCLASS_H
/****************************************************************** ++ File Name : FFMClass.cpp ++ Description: 共享內(nèi)存類 --------------------------------------------------------------- ++ 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> ////////////////////////////////////////////////////////////////////// // CFFMServer ////////////////////////////////////////////////////////////////////// CFFMServer::CFFMServer() { m_dwLastError = 0; m_fnpSetEntriesInAcl = NULL; _Init(); } CFFMServer::~CFFMServer() { Destory(); } CFFMServer::CFFMServer(char *szFileName, char *szMapName, DWORD dwSize) { // 以自定義設置創(chuàng)建共享內(nèi)存塊 _Init(); Create(szFileName, szMapName, dwSize); } // 初始化各個參數(shù) 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以上操作系統(tǒng) 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; } // 釋放當前共享內(nèi)存,並重新初始化參數(shù) 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(); } // 創(chuàng)建共享內(nèi)存塊 BOOL CFFMServer::Create(char *szFileName, char *szMapName, DWORD dwSize) { // 釋放已有的共享內(nèi)存塊 if (m_bCreateFlag) { Destory(); } // 拷貝各個參數(shù) 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; } // 以下創(chuàng)建共享內(nèi)存 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 { // 默認情況下,在頁面文件中創(chuàng)建共享內(nèi)存 m_hFile = INVALID_HANDLE_VALUE; } if (_IsWinNTLater()) { // Set DACL const int NUM_ACES = 2; // number if ACEs int DACL // evryone -- read // creator -- full access // 初始化參數(shù) PSID pEveryoneSID = NULL; // everyone群組SID PSID pCreatorSID = NULL; // creator群組SID PACL pFileMapACL = NULL; // 準備新內(nèi)存文件的DACL PSECURITY_DESCRIPTOR pSD = NULL; // 內(nèi)存文件的SD SECURITY_ATTRIBUTES saFileMap; // 內(nèi)存文件的SA EXPLICIT_ACCESS ea[NUM_ACES]; // 外部訪問結構 BOOL bHasErr = FALSE; // 返回值 // 以下創(chuàng)建SID SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; SID_IDENTIFIER_AUTHORITY SIDAuthCreator = SECURITY_CREATOR_SID_AUTHORITY; // Evryone if (!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) { bHasErr = TRUE; goto Finish; } // Creator if (!AllocateAndInitializeSid(&SIDAuthCreator, 1, SECURITY_CREATOR_OWNER_RID, 0, 0, 0, 0, 0, 0, 0, &pCreatorSID)) { bHasErr = TRUE; goto Finish; } // 填充ACE ZeroMemory(&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; // 創(chuàng)建並填充ACL if(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; } // 創(chuàng)建並初始化SD pSD = (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; } // 設置SA saFileMap.nLength = sizeof(SECURITY_ATTRIBUTES); saFileMap.bInheritHandle = FALSE; saFileMap.lpSecurityDescriptor = pSD; // 創(chuàng)建共享內(nèi)存文件 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); } if (pFileMapACL != NULL) { LocalFree(pFileMapACL); } if (pEveryoneSID != NULL) { FreeSid(pEveryoneSID); } if (pCreatorSID != NULL) { FreeSid(pCreatorSID); } if (bHasErr) { m_dwLastError = GetLastError(); return FALSE; } } else { // 創(chuàng)建共享內(nèi)存文件 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; } // 獲取內(nèi)存文件指針 LPVOID CFFMServer::GetBuffer() { return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL); } // 獲取內(nèi)存文件大小 DWORD CFFMServer::GetSize() { return m_dwSize; } BOOL CFFMServer::WriteCmdData(DWORD nCommandCode, DWORD dwDataSize, const LPVOID pBuf) { // 檢驗數(shù)據(jù)的合理性 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; } // 填寫數(shù)據(jù)結構 // 文件頭 DATA_HEADER dataHeader; dataHeader.nCommandCode = nCommandCode; dataHeader.dwDataSize = dwDataSize; ZeroMemory(GetBuffer(), GetSize()); memcpy(GetBuffer(), &dataHeader, sizeof(DATA_HEADER)); // 數(shù)據(jù)塊 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(); } } // 初始化參數(shù) void CFFMClient::_Init() { m_hFileMap = NULL; m_lpFileMapBuffer = NULL; m_pMapName = NULL; m_bOpenFlag = FALSE; } // 關閉當前對內(nèi)存文件的訪問 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(); } // 打開一個內(nèi)存文件 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; } // 獲取當前內(nèi)存文件的指針 LPVOID CFFMClient::GetBuffer() { return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL); } // 讀取命令數(shù)據(jù)大小 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; } // 讀取命令數(shù)據(jù) 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); // 拷貝數(shù)據(jù)到緩衝區(qū) memcpy(pOutBuf, pHeader->bInfo, pHeader->dwDataSize); return TRUE; }
|