views:

361

answers:

1

Hi,

I want to read status information that an application provides via shared memory. I want to use C++ in order to read the content of that named shared memory and then call it with pinvoke from a C#-class.

From the software I know that it has a certain file structure: A struct STATUS_DATA with an array of four structs of SYSTEM_CHARACTERISTICS.

I'm not (yet) familiar with C++, so I tried to follow msdn basically. To find the size of the file to be mapped, I added the sizes of the struct members as to be seen in the code below. This results in a ACCESS DENIED, so I figured, that the result based on the structs is too high. When I use sizeof(STATUS_DATA) (I added the struct to my source), it still ends up in an ACCESS DENIED. If I try something lower, like 1024 Bytes, only thing I can see in pbuf is a <, while debugging.

This is what I got so far:

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

using namespace std;


signed int BUF_SIZE = 4 * (10368 + 16 + 4 + 16 + 4 + 16 + 4 + 1 + 4); // sizeof(STATUS_DATA);
TCHAR szName[]=TEXT("ENGINE_STATUS");

int main()
{
   HANDLE hMapFile;
   unsigned char* pBuf;

   hMapFile = OpenFileMapping(
                   FILE_MAP_READ,    // read access
                   FALSE,                 // do not inherit the name
                   szName);               // name of mapping object 

   if (hMapFile == NULL) 
   { 
      _tprintf(TEXT("Could not open file mapping object (%d).\n"), 
             GetLastError());

      return 1;
   } 

   pBuf = (unsigned char*) MapViewOfFile(hMapFile, // handle to map object
               FILE_MAP_READ,  // read/write permission
               0,                    
               0,                    
               BUF_SIZE); // 1024);                  

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

   CloseHandle(hMapFile);
      return 1;
   }

   UnmapViewOfFile(pBuf);

   CloseHandle(hMapFile);

   return 0;
}

I also made sure that this Shared Mem "is there" by following that hint. Can somebody give me a hint, what I'm missing? Thanks!

+2  A: 

The last parameter to MapViewOfFile (dwNumberOfBytesToMap) must be less than the maximum size specified when the mapping was created. Since we don't know what that size is, it seems fair to assume that BUF_SIZE is exceeding it and 1024 isn't. Specifying 0 for this parameter is an easy way to map the entire file into a single view.

Most (all?) C++ debuggers will assume that a pointer to char is a null-terminated string, so when you try and view the mapped data it will only display up until the first byte that is zero. Depending on what data is in the file mapping, this could well be the second byte, which explains why you aren't seeing much information. You would be better to cast the returned pointer to STATUS_DATA* and viewing the individual members.

In short:

  • Specify zero (0) for dwNumberOfBytesToMap
  • Cast the returned pointer to STATUS_DATA* instead of unsigned char*
Zooba
That's it, thank you!
rdoubleui