#include
#include
#include
#include "IPC.h"
//***********************************************
CIPC::CIPC() : m_hFileMap(NULL), m_hMutex(NULL)
{
}
//***********************************************
CIPC::~CIPC()
{
CloseIPCMMF();
Unlock();
}
//***********************************************
bool CIPC::CreateIPCMMF(void)
{
bool bCreated = false;
try
{
if(m_hFileMap != NULL)
return false; // Already created
// Create an in-memory 4KB memory mapped file to share data
m_hFileMap = CreateFileMapping((HANDLE)0xFFFFFFFF,
NULL,
PAGE_READWRITE,
0,
4096,
IPC_SHARED_MMF);
if(m_hFileMap != NULL)
bCreated = true;
}
catch(...) {}
return bCreated;
}
//***********************************************
bool CIPC::OpenIPCMMF(void)
{
bool bOpened = false;
try
{
if(m_hFileMap != NULL)
return true; // Already opened
m_hFileMap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE,
FALSE,
IPC_SHARED_MMF);
if(m_hFileMap != NULL)
bOpened = true;
}
catch(...) {}
return bOpened;
}
//***********************************************
void CIPC::CloseIPCMMF(void)
{
try
{
if(m_hFileMap != NULL)
CloseHandle(m_hFileMap), m_hFileMap = NULL;
}
catch(...) {}
}
//***********************************************
bool CIPC::ReadIPCMMF(LPBYTE pBuf, DWORD &dwBufSize)
{
_ASSERTE(pBuf);
bool bSuccess = true;
try
{
if(m_hFileMap == NULL)
return false;
DWORD dwBaseMMF = (DWORD)MapViewOfFile(m_hFileMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0, 0, 0);
_ASSERTE(dwBaseMMF);
// The first DWORD in the MMF contains the size of the data
DWORD dwSizeofInBuf = dwBufSize;
CopyMemory(&dwBufSize, (LPVOID)dwBaseMMF, sizeof(DWORD));
if(dwSizeofInBuf != 0)
{
if(dwBufSize > dwSizeofInBuf)
bSuccess = false;
else
CopyMemory(pBuf, (LPVOID)(dwBaseMMF + sizeof(DWORD)), dwBufSize);
}
UnmapViewOfFile((LPVOID)dwBaseMMF);
}
catch(...) {}
return bSuccess;
}
//***********************************************
bool CIPC::WriteIPCMMF(const LPBYTE pBuf, const DWORD dwBufSize)
{
_ASSERTE(pBuf);
bool bSuccess = true;
try
{
if(m_hFileMap == NULL)
return false;
DWORD dwBaseMMF = (DWORD)MapViewOfFile(m_hFileMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0, 0, 0);
_ASSERTE(dwBaseMMF);
// The first DWORD in the MMF contains the size of the data
CopyMemory((LPVOID)dwBaseMMF, &dwBufSize, sizeof(DWORD));
CopyMemory((LPVOID)(dwBaseMMF + sizeof(DWORD)), pBuf, dwBufSize);
UnmapViewOfFile((LPVOID)dwBaseMMF);
}
catch(...) {}
return bSuccess;
}
//***********************************************
bool CIPC::Lock(void)
{
bool bLocked = false;
try
{
// First get the handle to the mutex
m_hMutex = CreateMutex(NULL, FALSE, IPC_MUTEX);
if(m_hMutex != NULL)
{
// Wait to get the lock on the mutex
if(WaitForSingleObject(m_hMutex, INFINITE) == WAIT_OBJECT_0)
bLocked = true;
}
}
catch(...) {}
return bLocked;
}
//***********************************************
void CIPC::Unlock(void)
{
try
{
if(m_hMutex != NULL)
{
ReleaseMutex(m_hMutex);
CloseHandle(m_hMutex);
m_hMutex = NULL;
}
}
catch(...) {}
}
void SaveToFile(const char* szFileName,BYTE* szBuffer,int nLen)
{
HANDLE hFile=CreateFile(szFileName,
GENERIC_WRITE|GENERIC_READ,
FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hFile==INVALID_HANDLE_VALUE)return ;
long dwHigh=0;
SetFilePointer(hFile,0,&dwHigh,FILE_END);
DWORD dwlen;
WriteFile(hFile,szBuffer,nLen,&dwlen,NULL);
CloseHandle(hFile);
}
char* __fastcall stristrA(const char* pszMain, const char* pszSub)
{
pszMain; // compiler thinks these are unreferenced because
pszSub; // they are in ecx and edx registers
char* pszTmp1;
char* pszTmp2;
char lowerch, upperch;
if(lstrlen(pszMain)==0||lstrlen(pszSub)==0)return NULL;
// We keep the first character of pszSub in lowerch and upperch (lower and
// upper case). First we loop trying to find a match for this character. Once
// we have found a match, we start with the second character of both pszMain
// and pszSub and walk through both strings doing a CharLower on both
// characters before comparing. If we make it all the way through pszSub with
// matches, then we bail with a pointer to the string's location in pszMain.
_asm {
mov ecx,pszMain
mov edx,pszSub
mov esi, ecx //
mov edi, edx // pszSub
// Check for NULL pointers
test ecx, ecx
je short NoMatch // NULL pointer for pszMain
test edx, edx
je short NoMatch // NULL pointer for pszSub
sub eax, eax
mov al, [edi]
push eax
call DWORD PTR CharLower
mov lowerch, al
push eax
call DWORD PTR CharUpper
mov upperch, al
push edi // increment the second string pointer
call DWORD PTR CharNext
mov edi, eax
mov pszTmp2, edi
mov edi, DWORD PTR CharNext // faster to call through a register
Loop1:
mov al, [esi]
test al, al
je short NoMatch // end of main string, so no match
cmp al, lowerch
je short CheckString // lowercase match?
cmp al, upperch
je short CheckString // upppercase match?
push esi
call edi // Call CharNext to update main string pointer
mov esi, eax
jmp short Loop1
CheckString:
mov pszTmp1, esi // save current pszMain pointer in case its a match
push esi
call edi // first character of both strings match,
mov esi, eax // so move to next pszMain character
mov edi, pszTmp2
mov al, [edi]
jmp short Branch1
Loop3:
push esi
call DWORD PTR CharNext // CharNext to change pszMain pointer
mov esi, eax
push edi
call DWORD PTR CharNext // CharNext to change pszSub pointer
mov edi, eax
mov al, [edi]
Branch1:
test al, al
je short Match // zero in sub string, means we've got a match
cmp al, [esi]
je short Loop3
// Doesn't match, but might be simply a case mismatch. Lower-case both
// characters and compare again
sub ecx, ecx
mov cl, al // character from pszSub
push ecx
call DWORD PTR CharLower
mov cl, al
sub eax, eax
mov al, [esi] // character from pszMain
push ecx // preserve register
push eax
call DWORD PTR CharLower
pop ecx
cmp al, cl
je short Loop3 // we still have a match, keep checking
// No match, put everything back, update pszMain to the next character
// and try again from the top
mov esi, pszTmp1
mov edi, DWORD PTR CharNext
push esi
call edi
mov esi, eax
jmp short Loop1
Match:
mov eax, pszTmp1
jmp short Done // Don't just return -- always let the C portion of the code handle the return
NoMatch:
sub eax, eax
Done:
}
// Note lack of return in the C portion of the code. Return value is always in
// eax register which we have set by the time we get here
}