/****************
* SharedMemory.h
****************/
#pragma once
#include "AtlBase.h"
#include <string>
using namespace std;
class CShareRestrictedSD
{
public:
CShareRestrictedSD();
virtual ~CShareRestrictedSD();
SECURITY_ATTRIBUTES* GetSA();
protected:
PVOID ptr;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
};
class CSharedMemory
{
public:
CSharedMemory();
CSharedMemory(LPCSTR cs);
CSharedMemory(int size);
CSharedMemory(LPCSTR cs,int size);
~CSharedMemory();
public:
void* m_pwData;
string csName;
protected:
HANDLE m_hSharedMemoryFile;
HANDLE m_hMutex;
DWORD dwMaximumSizeHigh;
DWORD dwMaximumSizeLow;
DWORD dwNumberOfBytesToMap;
BOOL m_bInit;
BOOL m_bAlreadyExist;
string csMutexName;
public:
BOOL Init(LPCSTR cs, int size);
BOOL Init(int size, LPCSTR cs);
BOOL Init(int size);
void* GetData();
BOOL AlreadyExists() { return m_bAlreadyExist; }
//Locks the Mem like CSingelLock locker(TRUE,pSyncObj)
//Use:
//{
// CSharedMemory::Locker locker(&MySharedMem);
// Modify(MySharedMem->GetData());
//}
struct Locker
{
Locker(CSharedMemory* sm)
{
m_sm = sm;
m_sm->Lock();
}
Locker(CSharedMemory& sm)
{
m_sm = &sm;
m_sm->Lock();
}
~Locker()
{
m_sm->Unlock();
}
CSharedMemory* m_sm;
};
//Locks the Mem
//Use:
//if (MySharedMem.Lock(100))
//{
// Modify(MySharedMem->GetData());
// MySharedMem.Unlock();
//}
BOOL Lock(DWORD dwMilliSec = INFINITE)
{
if(WaitForSingleObject(m_hMutex,dwMilliSec) == WAIT_OBJECT_0)
return TRUE;
return FALSE;
}
BOOL Unlock(DWORD dwMilliSec = INFINITE)
{
return ReleaseMutex(m_hMutex);
}
};
/****************
* SharedMemory.cpp
****************/
#include "SharedMemory.h"
PVOID BuildRestrictedSD(PSECURITY_DESCRIPTOR pSD)
{
DWORD dwAclLength;
PSID psidEveryone = NULL;
PACL pDACL = NULL;
BOOL bResult = FALSE;
PACCESS_ALLOWED_ACE pACE = NULL;
SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
__try
{
//initialize the security descriptor
if(!InitializeSecurityDescriptor(pSD,SECURITY_DESCRIPTOR_REVISION))
{
printf( "InitializeSecurityDescriptor() failed with error %d/n ",GetLastError());
__leave;
}
//obtain a sid for the Authenticated Users Group
if(!AllocateAndInitializeSid(&siaWorld,1,SECURITY_WORLD_RID,0,0,0,0,0,0,0,&psidEveryone))
{
printf( "AllocateAndInitializeSid() failed with error %d/n ",GetLastError());
__leave;
}
// NOTE:
//
// The Authenticated Users group includes all user accounts that
// have been successfully authenticated by the system. If access
// must be restricted to a specific user or group other than
// Authenticated Users, the SID can be constructed using the
// LookupAccountSid() API based on a user or group name.
// calculate the DACL length
dwAclLength = sizeof(ACL)
//add space for Authenticated Users group ACE
+ sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)
+ GetLengthSid(psidEveryone);
//allocate memory for the DACL
pDACL = (PACL)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwAclLength);
if(!pDACL)
{
printf( "HeapAlloc() failed with error %d/n ",GetLastError());
__leave;
}
//initialize the DACL
if(!InitializeAcl(pDACL,dwAclLength,ACL_REVISION))
{
printf( "InitializeAcl() failed with error %d/n ",GetLastError());
__leave;
}
//add the Authenticated Users group ACE to the DACL with
//GENERIC_READ,GENERIC_WRITE,and GENERIC_EXECUTE access
if(!AddAccessAllowedAce(pDACL,ACL_REVISION,GENERIC_ALL,psidEveryone))
{
printf( "AddAccessAllowedAce() failed with error %d/n",GetLastError());
__leave;
}
//set the DACL in the security descriptor
if(!SetSecurityDescriptorDacl(pSD,TRUE,pDACL,FALSE))
{
printf( "SetSecurityDescriptorDacl() failed with error %d/n ",GetLastError());
__leave;
}
bResult = TRUE;
}
__finally
{
if(psidEveryone) FreeSid(psidEveryone);
}
if(bResult == FALSE)
{
if(pDACL)
HeapFree(GetProcessHeap(),0,pDACL);
pDACL = NULL;
}
return (PVOID)pDACL;
}
//The following function frees memory allocated in the BuildRestrictedSD() function
VOID FreeRestrictedSD(PVOID ptr)
{
if(ptr)
HeapFree(GetProcessHeap(),0,ptr);
return;
}
//CShareRestrictedSD
CShareRestrictedSD::CShareRestrictedSD()
{
ptr=NULL;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;
//build a restricted security descriptor
ptr = BuildRestrictedSD(&sd);
if(!ptr)
{
//TRACE( "BuildRestrictedSD() failed/n ");
}
}
CShareRestrictedSD::~CShareRestrictedSD()
{
if(ptr)
{
FreeRestrictedSD(ptr);
}
}
SECURITY_ATTRIBUTES* CShareRestrictedSD::GetSA()
{
if(ptr)
return &sa;
else
return NULL;
}
//CSharedMemory
CSharedMemory::CSharedMemory()
{
csName = "Global//CQIDCSharedMemory";
m_bInit = FALSE;
m_bAlreadyExist = FALSE;
csMutexName = csName + "Mutex";
}
CSharedMemory::CSharedMemory(LPCSTR cs)
{
csName = cs;
m_bInit = FALSE;
m_bAlreadyExist = FALSE;
csMutexName = csName + "Mutex";
}
CSharedMemory::CSharedMemory(int size)
{
csName = "Global//CQIDCSharedMemory";
m_bInit = FALSE;
m_bAlreadyExist = FALSE;
csMutexName = csName + "Mutex";
Init(size);
}
CSharedMemory::CSharedMemory(LPCSTR cs,int size)
{
csName = cs;
m_bInit = FALSE;
m_bAlreadyExist = FALSE;
csMutexName = csName + "Mutex";
Init(size);
}
CSharedMemory::~CSharedMemory()
{
if(m_bInit)
{
UnmapViewOfFile(m_pwData);
CloseHandle(m_hSharedMemoryFile);
}
}
BOOL CSharedMemory::Init(LPCSTR cs, int size)
{
csName = cs;
m_bAlreadyExist = FALSE;
csMutexName = csName + "Mutex";
return Init(size);
}
BOOL CSharedMemory::Init(int size, LPCSTR cs)
{
csName = cs;
m_bAlreadyExist = FALSE;
csMutexName = csName + "Mutex";
return Init(size);
}
BOOL CSharedMemory::Init(int size)
{
m_hMutex = CreateMutex(NULL,FALSE,csMutexName.c_str());
dwNumberOfBytesToMap = size;
CShareRestrictedSD ShareRestrictedSD;
m_hSharedMemoryFile = CreateFileMapping((HANDLE)0xFFFFFFFF,
ShareRestrictedSD.GetSA(),//NULL
PAGE_READWRITE,
0,
dwNumberOfBytesToMap,
csName.c_str());
if(m_hSharedMemoryFile == NULL)
{
m_bAlreadyExist = FALSE;
m_bInit = FALSE;
return FALSE;
}
else
{
if(GetLastError() == ERROR_ALREADY_EXISTS)
m_bAlreadyExist = TRUE;
}
m_pwData= MapViewOfFile(m_hSharedMemoryFile,
FILE_MAP_ALL_ACCESS,
0,
0,
dwNumberOfBytesToMap);
if(m_pwData == NULL)
{
m_bInit = FALSE;
CloseHandle(m_hSharedMemoryFile);
return FALSE;
}
else
m_bInit = TRUE;
return TRUE;
}
void* CSharedMemory::GetData()
{
if(m_bInit)
return m_pwData;
else
return NULL;
}
/****************
* Usage
****************/
CSharedMemory theSharedMem;
theSharedMem.Init(nLength);
if (theSharedMem.Lock(300))
{
pData = (char*)theSharedMem.GetData();
if(pData != NULL)
{
//operation
}
theSharedMem.Unlock();
}