Search code examples
cwinapimemory-mapped-files

Named shared memory Windows api c++


I am trying to share some data between 2 processes. The first writes the data in mapped file and the second reads it.

Here's my code so far:

First process:

    #include "stdafx.h"
    #include <Windows.h>
    #include <tlhelp32.h>
    #include <tchar.h>
    #include<stdio.h>

    #define BUF_SIZE 256

    int _tmain(int argc, _TCHAR* argv[]) {
    TCHAR szName[] = TEXT("Global\\MyFileMappingObject");
    LPTSTR szMsg = TEXT("MESS");

    HANDLE tokenH;
    TOKEN_PRIVILEGES tp;
    LUID luid;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenH)) {
        printf("OpenProcessToken error: %u\n", GetLastError());
        return FALSE;
    }
    if (!LookupPrivilegeValue(NULL, SE_CREATE_GLOBAL_NAME, &luid)) {
        printf("LookupPrivilegeValue error: %u\n", GetLastError());
        return FALSE;
    }
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if (!AdjustTokenPrivileges(tokenH, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) {
        printf("AdjustTokenPrivileges error: %u\n", GetLastError());
        return FALSE;
    }
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    {
        printf("The token does not have the specified privilege. \n");
        return FALSE;
    }
    CloseHandle(tokenH);

    HANDLE hMapFile;
    LPCTSTR pBuf;
    hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,  
        NULL,                    
        PAGE_READWRITE,        
        0,                      
        BUF_SIZE,                
        szName);
    if (hMapFile == NULL)
    {
        _tprintf(TEXT("Could not create file mapping object (%d).\n"),
        GetLastError());
        return 1;
    }
    pBuf = (LPTSTR)MapViewOfFile(hMapFile,   
        FILE_MAP_ALL_ACCESS,
        0,
        0,
        BUF_SIZE);

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

        CloseHandle(hMapFile);

        return 1;
    }
    CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
    UnmapViewOfFile(pBuf);
    printf("Done\n");
    CloseHandle(hMapFile);
    return 0;
}

Second process:

#include "stdafx.h"
#include <Windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")

#define BUF_SIZE 256

int _tmain(int argc, _TCHAR* argv[])
{
    TCHAR szName[] = TEXT("Global\\MyFileMappingObject");
    HANDLE tokenH;
    TOKEN_PRIVILEGES tp;
    LUID luid;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenH);
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
        printf("LookupPrivilegeValue error: %u\n", GetLastError());
        return FALSE;
    }
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if (!AdjustTokenPrivileges(tokenH, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) {
        printf("AdjustTokenPrivileges error: %u\n", GetLastError());
        return FALSE;
    }
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    {
        printf("The token does not have the specified privilege. \n");
        return FALSE;
    }
    CloseHandle(tokenH);

    HANDLE hMapFile;
    LPCTSTR pBuf;
    hMapFile = OpenFileMapping(
        FILE_MAP_ALL_ACCESS,   // read/write 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 = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
        FILE_MAP_ALL_ACCESS,  // read/write permission
        0,
        0,
        BUF_SIZE);

    if (pBuf == NULL)
    {
        _tprintf(TEXT("Could not map view of file (%d).\n"),
            GetLastError());
        CloseHandle(hMapFile);
        return 1;
    }
    MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK);
    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);
    return 0;
}

The first process manages to write its data (I don't receive any error message and get the "Done" message), but the problem is with the the second process. After "OpenFileMapping", I get from getLastError the code 2 which is for non-existent file. I run both processes as administrator.


Solution

  • Error 2 is ERROR_FILE_NOT_FOUND, which means the named mapping object does not exist at the time OpenFileMapping() is called.

    In order to share a named kernel object between processes, both processes need to be running at the same time. Like other named kernel objects (events, mutexes, etc), a mapping object has a reference count associated with it, where each open handle increments the reference count. After all handles are closed, the object is destroyed.

    So, when the first app unmaps its view and closes its handle to the mapping object, the object will be destroyed if the second app does not already have its own handle open to the same mapping object. Thus the object will not exist when the second app tries to open it.