// 2002/07/05
// awzzz
 
// SFMMem.h: interface for the CSFMServer class.
//
//
 
#if !defined(AFX_SFMSERVER_H__2D76A439_6388_4B07_AE7A_C82F458642ED__INCLUDED_)
#define AFX_SFMSERVER_H__2D76A439_6388_4B07_AE7A_C82F458642ED__INCLUDED_
 
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
 
#define DEFAULT_FILENAME    NULL
#define DEFAULT_MAPNAME     "TestShareMemory"
#define DEFAULT_MAPSIZE     (0x0FFF + 1)
 
// Shared FileMap Server
// 使用说明
// 1.
// 创建CSFMServer对象
// CSFMServer(char *szFileName, char *szMapName, DWORD dwSize);
// Create(char *szFileName, char *szMapName, DWORD dwSize);
// 参数1:NULL或指定的文件(将创建或打开并读写/麻烦)
// 参数2:要创建的共享内存对象名
// 参数3:要创建的共享内存对象大小
// 2.
// 本地使用内存
// LPVOID GetBuffer()
// 返回共享内存地址
//
// 自动销毁
class CSFMServer  
    {
    public:
        CSFMServer();
        virtual ~CSFMServer();
        CSFMServer(char *szFileName, char *szMapName, DWORD dwSize);
        HANDLE  m_hMutex;
    protected:
        HANDLE  m_hFile;
        HANDLE  m_hFileMap;
        LPVOID  m_lpFileMapBuffer;
        string  m_strMutexName;
 
        char    *m_pFileName;
        char    *m_pMapName;
        DWORD   m_dwSize;
 
        int     m_iCreateFlag;
 
    private:
        void Init();
        void Destory();
 
    public:
        void Create(char *szFileName, char *szMapName, DWORD dwSize);
        LPVOID GetBuffer();
        DWORD GetSize();
    };
 
// Shared FileMap Client
// 使用说明
// 1.
// 创建CSFMClient对象
// CSFMClient(DWORD dwAccess, char *szMapName);
// Open(DWORD dwAccess, char *szMapName);
// 参数1:共享内存对象访问方式(FILE_MAP_READ|FILE_MAP_WRITE)
// 参数2:共享内存对象名
// 2.
// 本地使用内存
// LPVOID GetBuffer()
// 返回共享内存地址
//
// 自动销毁
class CSFMClient  
    {
    public:
        CSFMClient();
        virtual ~CSFMClient();
        CSFMClient(DWORD dwAccess, char *szMapName,DWORD size);
        HANDLE  m_hMutex;
    protected:
        HANDLE  m_hFileMap;
        LPVOID  m_lpFileMapBuffer;      
        string  m_strMutexName;
 
        char    *m_pMapName;
        DWORD   m_dwSize;//共享缓冲区的大小
        int     m_iOpenFlag;
 
    private:
        void Init();
        void Destory();
 
    public:
        void Open(DWORD dwAccess, char *szMapName);
        LPVOID GetBuffer();
        DWORD GetSize();
    };
 
#endif // !defined(AFX_SFMSERVER_H__2D76A439_6388_4B07_AE7A_C82F458642ED__INCLUDED_)
 
 
 
 
// SFMMem.cpp: implementation of the CSFMServer class.
//
//
 
#include "stdafx.h"
#include "SFMMem.h"
 
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
 
/
// Construction/Destruction(服务器端,创建共享缓冲区,共享缓冲区读取写入数据)
/
 
CSFMServer::CSFMServer()
    {
    Init();
    //创建共享缓冲区
    Create(DEFAULT_FILENAME, DEFAULT_MAPNAME, DEFAULT_MAPSIZE);
    }
 
CSFMServer::~CSFMServer()
    {
    Destory();
    }
 
CSFMServer::CSFMServer(char *szFileName, char *szMapName, DWORD dwSize)
    {
    Init();
    //创建共享缓冲区
    Create(szFileName, szMapName, dwSize);
    //Create(DEFAULT_FILENAME, DEFAULT_MAPNAME, DEFAULT_MAPSIZE);
    }
 
void CSFMServer::Init()
    {
    m_hFile = NULL;
    m_hFileMap = NULL;
    m_lpFileMapBuffer = NULL;
 
    m_pFileName = NULL;
    m_pMapName = NULL;
    m_dwSize = 0;
 
    m_iCreateFlag = 0;
    }
 
void CSFMServer::Destory()
    {
    if (m_lpFileMapBuffer)
        {
        if (!UnmapViewOfFile(m_lpFileMapBuffer))
            {
            printf("Server UnmapViewOfFile失败!rn");
            }       
        m_lpFileMapBuffer = NULL;
        }
 
    if (m_hFileMap)
        {
        if (!CloseHandle(m_hFileMap))
            {
            printf("Server CloseHandle  关闭映射文件句柄失败!rn");
            }
        m_hFileMap = NULL;
        }
 
    if (m_hFile && m_hFile != INVALID_HANDLE_VALUE)
        {
        if (!CloseHandle(m_hFile))
            {
            printf("Server CloseHandle 关闭互斥体句柄失败!rn");
            }       
        m_hFile = NULL;
        }
 
    if (m_pFileName)
        {
        free(m_pFileName);
        m_pFileName = NULL;
        }
 
    if (m_pMapName)
        {
        free(m_pMapName);
        m_pMapName = NULL;
        }
    Init();
    }
//创建共享缓冲区
void CSFMServer::Create(char *szFileName, char *szMapName, DWORD dwSize)
    {
    if (m_iCreateFlag)
        {
        Destory();
        }
    if (szFileName)
        {
        m_pFileName = _strdup(szFileName);
        }
    else
        {
        m_pFileName = NULL;
        }
    if (szMapName)
        {
        m_pMapName = _strdup(szMapName);
        m_strMutexName=szMapName;
        m_strMutexName+="mutex";
        }
    else
        {
        m_pMapName = _strdup(DEFAULT_MAPNAME);
        m_strMutexName=DEFAULT_MAPNAME;
        m_strMutexName+="mutex";
        }
    if (dwSize > 0)
        {
        m_dwSize = dwSize;
        }
    else
        {
        m_dwSize = DEFAULT_MAPSIZE;
        }
    if (m_pFileName)
        {
        // file
        m_hFile = CreateFile(
            m_pFileName,
            GENERIC_READ|GENERIC_WRITE,
            FILE_SHARE_READ|FILE_SHARE_WRITE,
            NULL,
            OPEN_ALWAYS,//OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL
            );
        }
    else
        {
        // system
        m_hFile = (HANDLE)0xFFFFFFFF;
        }
    DWORD error;
    //OutputDebugString((LPCSTR)m_hFile);
    //error=GetLastError();
    if (m_hFile)
        {
        m_hFileMap = CreateFileMapping(
            m_hFile,
            NULL,
            PAGE_READWRITE,
            0,
            m_dwSize,
            m_pMapName
            );
        //OutputDebugString((LPCSTR)m_hFile);
        //使只有一个CSFMServer对象能操作内存对象(郝兴峰修改)
        if (m_hFileMap != NULL)
            {
            error=GetLastError();
            if ( ERROR_ALREADY_EXISTS == error)//如果已经存在了,就不要创建操作了。
                {               
                m_hMutex=OpenMutex(SYNCHRONIZE,FALSE,m_strMutexName.c_str());
                }   
            else
                {
                m_hMutex=CreateMutex(NULL,FALSE,m_strMutexName.c_str());
                }       
            }
        else
            {
            printf("Server CreateFileMapping失败!rn");
            }
        }
    else
        {
        printf("Server CreateFile 失败!rn");
        }
    if (m_hFileMap)
        {
        m_lpFileMapBuffer = MapViewOfFile(
            m_hFileMap,
            FILE_MAP_ALL_ACCESS,//FILE_MAP_WRITE|FILE_MAP_READ,
            0,
            0,
            0//m_dwSize改成0,在这里把它改为0,和读取写入的程序一样。郝兴峰修改09.11.13
            );
        if (NULL==m_lpFileMapBuffer)
            {
            printf("Server MapViewOfFile 失败!rn");
            }
        }
    memset(m_lpFileMapBuffer,'',m_dwSize);//设置共享内存中的数据为0
    m_iCreateFlag = 1;
    }
//获取共享缓冲区的首指针
LPVOID CSFMServer::GetBuffer()
    {
    return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL);
    }
//获取共享缓冲区的大小
DWORD CSFMServer::GetSize()
    {
    return m_dwSize;
    }
 

// Construction/Destruction (客户端,打开共享缓冲区,读取写入共享缓冲区的数据)

 
CSFMClient::CSFMClient()
    {
    Init();
    //打开共享缓冲区
    Open(FILE_MAP_ALL_ACCESS, DEFAULT_MAPNAME);
    }
 
CSFMClient::~CSFMClient()
    {
    Destory();
    }
 
CSFMClient::CSFMClient(DWORD dwAccess, char *szMapName,DWORD isizemap)
    {
    Init();
    m_dwSize=isizemap;
    //打开共享缓冲区
    Open(dwAccess, szMapName);
    }
 
void CSFMClient::Open(DWORD dwAccess, char *szMapName)
    {
    if (m_iOpenFlag)
        Destory();
 
    if (szMapName)
        {
        m_pMapName = _strdup(szMapName);
        m_strMutexName=szMapName;
        m_strMutexName+="mutex";
        }
    else
        {
        m_pMapName = _strdup(DEFAULT_MAPNAME);
        m_strMutexName=DEFAULT_MAPNAME;
        m_strMutexName+="mutex";
        }
    try
        {
 
        m_hFileMap = OpenFileMapping(
            FILE_MAP_ALL_ACCESS,
            FALSE,
            m_pMapName
            );
 
        if (m_hFileMap)
            {
            m_lpFileMapBuffer = MapViewOfFile(
                m_hFileMap,
                FILE_MAP_ALL_ACCESS,
                0,
                0,
                0//hxf修改,把0改成m_dwSize。把m_dwSize改成0,和上面的创建性质一样、郝兴峰,09.11.13
                );
            if (NULL==m_lpFileMapBuffer)
                {
                printf("Client MapViewOfFile失败!rn");
                }
            m_hMutex=OpenMutex(SYNCHRONIZE,FALSE,m_strMutexName.c_str());
            }
        else
            {
            printf("Client OpenFileMapping失败!rn");
            }
        }
 
    catch (exception &e)
        {
        printf("Client MapViewOfFile或者Client OpenFileMapping异常rn");
        printf("%srn",e.what());
        }
    m_iOpenFlag = 1;
    }
 
void CSFMClient::Init()
    {
    m_hFileMap = NULL;
    m_lpFileMapBuffer = NULL;
    m_hMutex=NULL;
 
    m_pMapName = NULL;
    m_dwSize=0;
    m_iOpenFlag = 0;
 
    }
 
void CSFMClient::Destory()
    {
    if (m_lpFileMapBuffer)
        {
        if (!UnmapViewOfFile(m_lpFileMapBuffer))
            {
            printf("Client UnmapViewOfFile 失败!rn");
            }
        m_lpFileMapBuffer = NULL;
        }
 
    if (m_hFileMap)
        {
        if(!CloseHandle(m_hFileMap))
            {
            printf("Client 关闭映射文件句柄失败!rn");
            }
        m_hFileMap = NULL;
        }
    if (m_pMapName)
        {
        free(m_pMapName);
        m_pMapName = NULL;
        }
    if (m_hMutex)
        {
        if (!CloseHandle(m_hMutex))
            {
            printf("Client 关闭互斥体句柄失败!rn");
            }
        m_hMutex=NULL;
        }
    Init();
    }
 
LPVOID CSFMClient::GetBuffer()
    {
    return (m_lpFileMapBuffer)?(m_lpFileMapBuffer):(NULL);
    }
//这里可能有点问题
DWORD CSFMClient::GetSize()
    {
    // unnable use
    return m_dwSize;
    }