// sharedmem.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "sharedmem.h"
#include "tchar.h"
#include "stdio.h"
extern HANDLE m_hFileMMF, m_pViewMMFFile, hMutex;
class CMutex
{
public:
CMutex()
{
if(!hMutex){
hMutex = CreateMutex(
NULL, // default security attributes
FALSE, // initially not owned
L"Global\\MMFMutex"); // unnamed mutex
}
WaitForSingleObject( hMutex, INFINITE);
}
~CMutex()
{
ReleaseMutex(hMutex);
}
};
void SetRecordCount(int value)
{
TCHAR* record = (TCHAR*)m_pViewMMFFile;
swprintf_s(record, MAX_PATH, L"RECCNT=%d#", value);
}
extern "C" int GetRecordCount()
{
TCHAR* record = (TCHAR*)m_pViewMMFFile;
TCHAR temp[MAX_PATH];
int recordCount = -1;
TCHAR seps[] = L"=#";
TCHAR *token1 = NULL;
TCHAR *next_token1 = NULL;
_tcscpy_s(temp, MAX_PATH, record);
token1 = _tcstok_s ( temp, seps, &next_token1);
if(token1 && _tcscmp(token1, _T("RECCNT")) == 0)
{
token1 = _tcstok_s ( NULL, seps, &next_token1);
recordCount = _ttoi(token1);
}else
{
recordCount = 1;
SetRecordCount(1);
}
return recordCount;
}
int nRecordCount = -1;
void RemoveValue(TCHAR* key)
{
TCHAR* record = (TCHAR*)m_pViewMMFFile;
TCHAR temp[MAX_PATH];
nRecordCount = GetRecordCount();
record+=MAX_PATH;
//Try to look. If found, break out of for loop
//Compact the memory immediately immediately
//If you get time, strongly advice you to do a lazy compaction
bool isRecordFound = false;
int i;
for(i= 1; i< nRecordCount; i++,record+=MAX_PATH)
{
TCHAR seps[] = L"=#";
TCHAR *token1 = NULL;
TCHAR *next_token1 = NULL;
_tcscpy_s(temp, MAX_PATH, record);
token1 = _tcstok_s ( temp, seps, &next_token1);
if(_tcscmp(token1, key) == 0)
{
isRecordFound = true;
break;
}
}
//start moving the records
for(; i< nRecordCount-1; i++, record+=MAX_PATH)
{
TCHAR* nextRecord = record + MAX_PATH;
_tcscpy_s(record, MAX_PATH, nextRecord);
}
}
TCHAR* IfExists(TCHAR* key, TCHAR** value = NULL)
{
TCHAR* record = (TCHAR*)m_pViewMMFFile;
TCHAR temp[MAX_PATH];
nRecordCount = GetRecordCount();
record+=MAX_PATH;
for(int i=1; i< nRecordCount; i++,record+=MAX_PATH)
{
TCHAR seps[] = L"=#";
TCHAR *token1 = NULL;
TCHAR *next_token1 = NULL;
_tcscpy_s(temp, MAX_PATH, record);
token1 = _tcstok_s ( temp, seps, &next_token1);
if(_tcscmp(token1, key) == 0)
{
token1 = _tcstok_s ( NULL, seps, &next_token1);
//return a copy of the value
if(value!=NULL)
{
int len = _tcslen(token1)+1;
*value = new TCHAR(len);
_tcscpy_s(*value, len, token1);
}
return record;
}
}
return NULL;
}
extern "C" TCHAR* GetValue(TCHAR* key)
{
TCHAR* sRetVal = new TCHAR[MAX_PATH];
CMutex mutex;
TCHAR* data = NULL;
if(m_pViewMMFFile)
{
IfExists(key, &data);
}
return data;
}
extern "C" void SetValue(TCHAR* key, TCHAR* value)
{
CMutex mutex;
if(m_pViewMMFFile )
{
if(value == NULL)
{
RemoveValue(key);
}
else
{
TCHAR* data = IfExists(key);
if(data == NULL)
{
data = new TCHAR[MAX_PATH];
swprintf_s(data, MAX_PATH, L"%s=%s#", key, value);
//Add to end of the MMF
TCHAR* record = (TCHAR*)m_pViewMMFFile;
record += MAX_PATH*nRecordCount;
nRecordCount++;
SetRecordCount(nRecordCount);
_tcscpy_s(record, MAX_PATH, data);
delete data;
}
else
{
//Replace existing
swprintf_s(data, MAX_PATH, L"%s=%s#", key, value);
}
}
}
}