#include <windows.h>
#include <stdio.h>
#include <conio.h>

#define BUF_SIZE 256

TCHAR *firstString="1.Teststring"; 
TCHAR *secondString="2.Teststring"; 

HANDLE hMapFile;
LPCTSTR pBuf;

char *createSegmentName(char *szFileName)
{
   static TCHAR s[MAX_PATH];
   strcpy(s,"Global\\");
   strcat(s,szFileName);
   TCHAR *p = s+7;
   for (; *p != '\0'; p++) {
    if (*p == '/' || *p == '\\' || *p == ' ' || *p == ':')
        *p = '_';
   }    
//   printf("shared segment name %s\n",s);
   return s;
}    

int createSharedSegment(TCHAR *szFileName)
{
   HANDLE hFile;
   
   hFile = CreateFile(szFileName,  // file to open
                       GENERIC_READ,          // open for reading
                       FILE_SHARE_READ,       // share for reading
                       NULL,                  // default security
                       OPEN_EXISTING,         // existing file only
                       FILE_ATTRIBUTE_NORMAL, // normal file
                       NULL);                 // no attr. template

   hMapFile = CreateFileMapping(
                 hFile, //INVALID_HANDLE_VALUE,    // use paging file
                 NULL,                    // default security 
                 PAGE_READONLY, //PAGE_READWRITE,          // read/write access
                 0,                       // max. object size 
                 BUF_SIZE,                // buffer size  
                 createSegmentName(szFileName));  // name of mapping object
 
   if (hMapFile == NULL) 
   { 
      printf("Could not create file mapping object (%d).\n", 
             GetLastError());
      return 1;
   }
   pBuf = (LPTSTR) MapViewOfFile(hMapFile,   // handle to map object
                        FILE_MAP_READ,//FILE_MAP_ALL_ACCESS, // read/write permission
                        0,                   
                        0,                   
                        BUF_SIZE);           
 
   CloseHandle(hFile);
   if (pBuf == NULL) 
   { 
      printf("Could not map view of file (%d).\n", 
             GetLastError()); 
      return 2;
   }
   
   return 0;
}

int openSharedSegment(TCHAR *szFileName)
{

   hMapFile = OpenFileMapping(
                   FILE_MAP_READ,//FILE_MAP_ALL_ACCESS,   // read/write access
                   FALSE,                 // do not inherit the name
                   createSegmentName(szFileName)); // name of mapping object 
 
   if (hMapFile == NULL) 
   { 
      if (GetLastError() == ERROR_FILE_NOT_FOUND)
      {
        printf("Could not open file mapping, try to create it.\n");
        return createSharedSegment(szFileName); 
      }
      printf("Could not open file mapping object (%d).\n", 
             GetLastError());
      return 1;
   } 
 
   pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object
               FILE_MAP_READ,//FILE_MAP_ALL_ACCESS,  // read/write permission
               0,                    
               0,                    
               BUF_SIZE);                   
 
   if (pBuf == NULL) 
   { 
      printf("Could not map view of file (%d).\n", 
             GetLastError()); 
      return 2;
   }
   return 0;
}

void closeSegment()
{
    
   UnmapViewOfFile(pBuf);

   CloseHandle(hMapFile);
}


bool checkSegmentData()
{
   TCHAR szMsg[1024];

   CopyMemory((PVOID)szMsg, (PVOID)(pBuf), 0x40);
   if (strcmp(szMsg,firstString))
      printf("Error: first data differs: %s\n",szMsg,firstString);

   CopyMemory((PVOID)szMsg, (PVOID)(pBuf+0x40), 0x40);
   if (strcmp(szMsg,secondString))
      printf("Error: first data differs: %s\n",szMsg,firstString);
   return true;
}

int main()
{
   char *fileName = CMAKE_SOURCE_DIR "/ksycoca4";
   //fileName = "ksycoca4";
   if (openSharedSegment(fileName))
        return 1;
 
   checkSegmentData();
   
   
   printf("press char to finish\n");
   _getch();

   checkSegmentData();

    closeSegment();
 
   return 0;
}

