#include <windows.h>
#include "mil.h"
#include "../MbufSharedMemory.h"
#ifdef __cplusplus
extern "C"
{
#endif
void MFTYPE SlaveAllocSharedMemory(MIL_ID Func);
void * MFTYPE SharedMemoryOperation(MIL_INT ControlFlag, MIL_CONST_TEXT_PTR SharedBufferName, MIL_INT64 SharedBufferSize,
MIL_UINT64 *PtrToSharedBufferHandle, char **PtrToSharedBufferPtr);
void MFTYPE SlaveFreeSharedMemory(MIL_ID Func);
#ifdef __cplusplus
}
#endif
static MIL_UINT64 CreateSharedMemory(MIL_CONST_TEXT_PTR SharedBufferName, MIL_INT64 SharedBufferSize, void ** MapPtr);
static MIL_UINT64 OpenSharedMemory(MIL_CONST_TEXT_PTR SharedBufferName, MIL_INT64 SharedBufferSize, void ** MapPtr);
static void FreeSharedMemory(MIL_UINT64 SharedBufferHandle, void* MapPtr);
void MFTYPE SlaveAllocSharedMemory(MIL_ID Func)
{
MIL_ID MilSystem;
MIL_INT SizeBand, SizeX, SizeY, Type, DataFormat, ControlFlag, PitchByte;
MIL_INT SharedBufferNameLength;
MIL_CONST_TEXT_PTR SharedBufferName;
MIL_UINT64 *SharedBufferHandlePtr;
MIL_ID *SharedBufferMilIdPtr;
MIL_INT SharedBufferBandSize;
char *SharedBufferPtr, *SharedBufferBandPtr[3];
MfuncParamValueMilId(Func, 1, &MilSystem);
MfuncParamValueMilInt(Func, 2, &SizeBand);
MfuncParamValueMilInt(Func, 3, &SizeX);
MfuncParamValueMilInt(Func, 4, &SizeY);
MfuncParamValueMilInt(Func, 5, &Type);
MfuncParamValueMilInt(Func, 6, &DataFormat);
MfuncParamValueMilInt(Func, 7, &ControlFlag);
MfuncParamValueMilInt(Func, 8, &PitchByte);
MfuncParamValueMilInt(Func, 9, &SharedBufferNameLength);
MfuncParamValueConstMilText(Func, 10, &SharedBufferName);
MfuncParamValueArrayMilUint64(Func, 11, &SharedBufferHandlePtr);
MfuncParamValueArrayMilId(Func, 12, &SharedBufferMilIdPtr);
if ((ControlFlag == SHARED_MEMORY_ALLOCATE) || (ControlFlag == SHARED_MEMORY_CREATE))
{
SharedMemoryOperation(ControlFlag, SharedBufferName, SizeBand*PitchByte*SizeY,
SharedBufferHandlePtr, &SharedBufferPtr);
if (SharedBufferPtr != M_NULL)
{
if (DataFormat & M_PLANAR)
{
SharedBufferBandSize = PitchByte*SizeY;
for (int n=0; n<SizeBand; n++)
SharedBufferBandPtr[n] = SharedBufferPtr+(n*SharedBufferBandSize);
}
else
{
SharedBufferBandPtr[0] = SharedBufferPtr;
}
MbufCreateColor(MilSystem, SizeBand, SizeX, SizeY, Type, DataFormat,
M_HOST_ADDRESS + M_PITCH_BYTE, PitchByte, (void **)&SharedBufferBandPtr, SharedBufferMilIdPtr);
}
else
{
MfuncErrorReport(Func,M_FUNC_ERROR+ALLOC_SHARED_MEMORY_MAPPING_FILE_ERROR_CODE,
MIL_TEXT("Shared Memory Operation: Could not create file mapping."), M_NULL, M_NULL, M_NULL);
}
}
}
void MFTYPE SlaveFreeSharedMemory(MIL_ID Func)
{
MIL_UINT64 SharedBufferHandle;
MIL_ID SharedBufferMilId;
char *SharedBufferPtr;
MfuncParamValueMilUint64(Func, 1, &SharedBufferHandle);
MfuncParamValueMilId(Func, 2, &SharedBufferMilId);
MbufInquire(SharedBufferMilId, M_HOST_ADDRESS, &SharedBufferPtr);
MbufFree(SharedBufferMilId);
SharedMemoryOperation(SHARED_MEMORY_FREE, NULL, NULL, &SharedBufferHandle, &SharedBufferPtr);
}
void * MFTYPE SharedMemoryOperation(MIL_INT ControlFlag,
MIL_CONST_TEXT_PTR SharedBufferName,
MIL_INT64 SharedBufferSize,
MIL_UINT64 *PtrToSharedBufferHandle,
char **PtrToSharedBufferPtr)
{
*PtrToSharedBufferHandle = NULL;
*PtrToSharedBufferPtr = NULL;
if ((ControlFlag == SHARED_MEMORY_ALLOCATE) || (ControlFlag == SHARED_MEMORY_CREATE))
{
if (ControlFlag == SHARED_MEMORY_ALLOCATE)
{
*PtrToSharedBufferHandle = CreateSharedMemory(SharedBufferName, SharedBufferSize, (void**) PtrToSharedBufferPtr);
}
else if (ControlFlag == SHARED_MEMORY_CREATE)
{
*PtrToSharedBufferHandle = OpenSharedMemory(SharedBufferName, SharedBufferSize, (void**)PtrToSharedBufferPtr);
}
if (*PtrToSharedBufferHandle == M_NULL)
{
MIL_TEXT_CHAR ErrCode[32];
MosSprintf(ErrCode, 32, MIL_TEXT("%lu"), GetLastError());
MfuncErrorReport(M_DEFAULT, M_FUNC_ERROR + 1,
MIL_TEXT("Shared Memory Operation: Could not create file mapping object."), ErrCode, M_NULL, M_NULL);
return M_NULL;
}
if (*PtrToSharedBufferPtr == NULL)
{
MIL_TEXT_CHAR ErrCode[32];
MosSprintf(ErrCode, 32, MIL_TEXT("%lu"), GetLastError());
MfuncErrorReport(M_DEFAULT, M_FUNC_ERROR + 2,
MIL_TEXT("Shared Memory Operation: Could not map view of file."), ErrCode, M_NULL, M_NULL);
FreeSharedMemory(*PtrToSharedBufferHandle, M_NULL);
return NULL;
}
}
else if(ControlFlag == SHARED_MEMORY_FREE)
{
FreeSharedMemory(*PtrToSharedBufferHandle, *PtrToSharedBufferPtr);
*PtrToSharedBufferPtr = NULL;
*PtrToSharedBufferHandle = NULL;
}
return *PtrToSharedBufferPtr;
}
MIL_UINT64 CreateSharedMemory(MIL_CONST_TEXT_PTR SharedBufferName, MIL_INT64 SharedBufferSize, void ** MapPtr)
{
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = TRUE;
HANDLE SharedMemHandle = M_NULL;
MIL_INT NameLength = MosStrlen(SharedBufferName);
MIL_TEXT_PTR TempName = new MIL_TEXT_CHAR[NameLength + 10];
MosSprintf(TempName, NameLength + 10, MIL_TEXT("Global\\%s"), SharedBufferName);
SharedMemHandle = CreateFileMapping(
INVALID_HANDLE_VALUE,
&sa,
PAGE_READWRITE,
(long) (SharedBufferSize >> 32),
(long) SharedBufferSize,
TempName);
if (SharedMemHandle == M_NULL)
{
MosSprintf(TempName, NameLength + 10, MIL_TEXT("Local\\%s"), SharedBufferName);
SharedMemHandle = CreateFileMapping(
INVALID_HANDLE_VALUE,
&sa,
PAGE_READWRITE,
(long) (SharedBufferSize >> 32),
(long) SharedBufferSize,
TempName);
}
delete [] TempName;
TempName = M_NULL;
if (MapPtr != M_NULL)
{
*MapPtr = M_NULL;
if (SharedMemHandle != M_NULL)
{
*MapPtr = MapViewOfFile(SharedMemHandle,
FILE_MAP_ALL_ACCESS,
0, 0, (size_t) SharedBufferSize);
}
}
return (MIL_UINT) SharedMemHandle;
}
MIL_UINT64 OpenSharedMemory(MIL_CONST_TEXT_PTR SharedBufferName, MIL_INT64 SharedBufferSize, void ** MapPtr)
{
HANDLE SharedMemHandle = M_NULL;
MIL_INT NameLength = MosStrlen(SharedBufferName);
MIL_TEXT_PTR TempName = new MIL_TEXT_CHAR[NameLength + 10];
MosSprintf(TempName, NameLength + 10, MIL_TEXT("Global\\%s"), SharedBufferName);
SharedMemHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS,
FALSE,
TempName);
if (SharedMemHandle == M_NULL)
{
MosSprintf(TempName, NameLength + 10, MIL_TEXT("Local\\%s"), SharedBufferName);
SharedMemHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS,
FALSE,
TempName);
}
delete [] TempName;
TempName = M_NULL;
if (MapPtr != M_NULL)
{
*MapPtr = M_NULL;
if (SharedMemHandle != M_NULL)
{
*MapPtr = MapViewOfFile(SharedMemHandle,
FILE_MAP_ALL_ACCESS,
0, 0, (size_t) SharedBufferSize);
}
}
return (MIL_UINT) SharedMemHandle;
}
void FreeSharedMemory(MIL_UINT64 SharedBufferHandle, void* MapPtr)
{
if (MapPtr != M_NULL)
UnmapViewOfFile(MapPtr);
if (SharedBufferHandle != M_NULL)
CloseHandle((HANDLE) SharedBufferHandle);
}