#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#pragma comment(lib, "user32.lib")
#include "SMcore.h"

extern "C"
{
  static HANDLE hMapFile;
  static LPCTSTR pMappedData;
  static bool first_time_access;
  static bool is_shared_memory_already_initialized;

 //------------------------------------------

   int MapSharedMemory(const char *sm_name, int sm_length, HANDLE *hMapFile_aux, LPCTSTR *pMappedData_aux)
   {
	TCHAR *SharedMemoryName;

	 const size_t cSize = strlen(sm_name)+1;
     wchar_t* wc = new wchar_t[cSize];
     mbstowcs (wc, sm_name, cSize);
	 SharedMemoryName = wc;

	*hMapFile_aux = OpenFileMapping(
                   FILE_MAP_ALL_ACCESS,   // read/write access
                   FALSE,                 // do not inherit the name
                   SharedMemoryName);               // name of mapping object
 
   	if (*hMapFile_aux == NULL)
	  {
	   _tprintf(TEXT("Could not open file mapping object (%d).\n"),
             GetLastError());
      return 0;
	 }
	
	*pMappedData_aux = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object
               FILE_MAP_ALL_ACCESS,  // read/write permission
               0,
               0,
               sm_length);
  	if (*pMappedData_aux == NULL)
	{
      _tprintf(TEXT("Could not map view of file (%d).\n"),
             GetLastError());

      CloseHandle(hMapFile);

      return 0;
	 }

	return 1;
   }

   //------------------------------------------

   int UnmapSharedMemory(HANDLE hMapFile, LPCTSTR pMappedData)
   {
	 UnmapViewOfFile(pMappedData);
	 CloseHandle(hMapFile);
	 return 1;
   }

   //------------------------------------------

   int create_shared_memory(const char *sm_name, int sm_length)
   {
	 TCHAR *SharedMemoryName;

	 const size_t cSize = strlen(sm_name)+1;
     wchar_t* wc = new wchar_t[cSize];
     mbstowcs (wc, sm_name, cSize);
	 SharedMemoryName = wc;
	 hMapFile = CreateFileMapping(
                 INVALID_HANDLE_VALUE,    // use paging file
                 NULL,                    // default security
                 PAGE_READWRITE,          // read/write access
                 0,                       // maximum object size (high-order DWORD)
                 sm_length,                // maximum object size (low-order DWORD)
                 SharedMemoryName);                 // name of mapping object

	if (hMapFile == NULL)
	 {
		_tprintf(TEXT("ERROR!!! int CreateSharedMemory() - Could not create file mapping object (%d).\n"),
             GetLastError());
		return 0;
	 }
	 pMappedData = (LPTSTR) MapViewOfFile(hMapFile,   // handle to map object
                        FILE_MAP_ALL_ACCESS, // read/write permission
                        0,
                        0,
                        sm_length);

	 if (pMappedData == NULL)
	 {
      _tprintf(TEXT("ERROR!!! int CreateSharedMemory() - Could not map view of file (%d).\n"),
             GetLastError());

       CloseHandle(hMapFile);

      return 0;
	 }
	 first_time_access = true;
	 is_shared_memory_already_initialized = true;
	 return 1;
     }

   //------------------------------------------

     void copy_data_to_shared_memory(const void *shared_data_aux, int size_shared_data)
     {
	   CopyMemory((PVOID)pMappedData, shared_data_aux, size_shared_data);
     }
   }