packetie
packetie

Reputation: 5059

strange error on shared memory for windows 7

Trying to learn some basics on shared memory for windows 7. I created the following based on an example, it compiles fine, when I run it as

c:\temp> a.exe  tmp.txt 85

It didn't produced 10 bytes from the file as I expected, instead, it just printed 10 null bytes. Any idea why?

Thanks

==============here is the test program=============

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


int _tmain(int argc, char *argv[])
{
   HANDLE hMapFile;
   LPCTSTR pBuf;
    //printf("argv[1] %s\n", argv[1]); exit(0);
   hMapFile = CreateFileMapping(
                 INVALID_HANDLE_VALUE,    // use paging file
                 NULL,                    // default security
                 PAGE_READONLY,          // read/write access
                 0,                       // maximum object size (high-order DWORD)
                 atoi(argv[2]),            // maximum object size (low-order DWORD)
                 argv[1]);                 // name of mapping object

   if (hMapFile == NULL)
   {
      _tprintf(TEXT("Could not create file mapping object (%d).\n"),
             GetLastError());
      return 1;
   }
   pBuf = (LPTSTR) MapViewOfFile(hMapFile,   // handle to map object
                        FILE_MAP_READ,     // read/write permission
                        0,
                        0,
                        atoi(argv[2]));  //BUF_SIZE);

   if (pBuf == NULL)
   {
      _tprintf(TEXT("Could not map view of file (%d).\n"),
             GetLastError());

       CloseHandle(hMapFile);

      return 1;
   }
    int i;
    for (i=0; i<10; i++) {
        printf("%02x ", pBuf[i]);
    }
    printf("\n");
    return 0;
}*

Upvotes: 0

Views: 216

Answers (1)

superultranova
superultranova

Reputation: 1314

You are printing empty memory, which is why you are seeing nulls. You have to put something in the memory to have something other than zeros. As you can see on the MapViewOfFile documentation, mapped views of the pagefile are always initialized to contain only zeros.

You've correctly allocated a read only section in memory, backed by the page file. You won't be able to write to it, because it is read only. However, if you were to make it writable, you'd be able to write some bytes into memory, and then read them back.

Conversely, you could use an existing file to back the mapping, and assuming the file wasn't empty, you would be able to read bytes from that file. It looks like, based on that arguments you invoke the program with, you are trying to map tmp.txt. If that is the case, you need to open that file using CreateFile and then pass the resulting HANDLE as the first parameter to CreateFileMapping. Once you do that, the output should match the contents of the file.

The code below assumes a 64bit system and an all ASCII filename. It also doesn't clean up resources from CreateFileA, CreateFileMappingA or MapViewOfFile.

void map_file(const char * fname) {
    HANDLE file = CreateFileA(fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (file == INVALID_HANDLE_VALUE) {
        throw runtime_error("Unable to open file");
    }

    LARGE_INTEGER file_size = {0};
    if (!GetFileSizeEx(file, &file_size)) {
        throw runtime_error("Unable to get file size");
    }

    if (file_size.QuadPart == 0) {
        throw runtime_error("File cannot be empty");
    }

    HANDLE mapping = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
    if (mapping == nullptr) {
        throw runtime_error("Unable to map file");
    }

    uint8_t * view = (uint8_t *) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, (size_t) file_size.QuadPart);
    if (view == nullptr) {
        throw runtime_error("Unable to map view of file");
    }

    // do something with 'view'
}

Upvotes: 2

Related Questions