-2

I'm on windows using c++ and making a simple method to communicate between two processes

the first process creates the mapped memory , writes the first message in it and duplicate the handle for the other process (the mapped memory is unnamed) the code is like this :

hMapped = CreateFileMappingA(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 1000, "my_shared_memory");
if (!hMapped)
{
    cout << "[!] failed to create the shared mapped memory with error : " << GetLastError() << endl;
    getchar();
}
char *shared_buffer = (char*)MapViewOfFile(hMapped, FILE_MAP_ALL_ACCESS, 0, 0, mapped_memory_size);

then the other process gets the handle , opens a view and retrieve the first buffer written

it then loops and checks every 6 seconds for the new writing operations and deal with it

I write from the first process as this :

std::lock_guard<std::mutex> lock(mtx);
RtlSecureZeroMemory(shared_buffer, mapped_memory_size);
shared_buffer[0] = 'n'; // it's a hint for the other process
memcpy(shared_buffer + 1, this->stuff.get_data().c_str(), this->stuff.get_data().size() + 1);

but the buffer isn't updated for the second process it is the first buffer

this is the code in the second process :

HANDLE shared_memory = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "my_shared_memory");
char *shared_buffer = (char*)MapViewOfFile(shared_memory, FILE_MAP_ALL_ACCESS, 0, 0, 1000);

utils::command_line_parser cmd_parser;
cmd_parser.parse(std::string((char*)shared_buffer + 1));
if (!cmd_parser.valid()) { // I get that they are valid and I verify that
    printf("failed to parse the arguments !");
    return TRUE;
}
while(true)
{
    Sleep(6000);
    // CloseHandle(shared_memory);
    // shared_memory = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "my_shared_memory");
    // shared_buffer = (char*)MapViewOfFile(shared_memory, FILE_MAP_ALL_ACCESS, 0, 0, 1000);
    MessageBoxA(0, (char*)shared_buffer, "message", 0);
    char res = shared_buffer[0];
    switch (res)
    {
    case 'q' :
        // do some stuff
    case 'n' :
        // do some stuff
        break;
    default:
        break;
    }
  • Comments archived [moved to chat](https://chat.stackoverflow.com/rooms/189029/discussion-on-question-by-developer1321-the-shared-mapped-memory-between-two-pro). –  Feb 25 '19 at 23:50

1 Answers1

1

Here's an example of a named shared memory application that seems to work with Visual Studio 2015. The application can be run as either a writer into the memory area or a reader from the memory area depending on the command line argument specified.

Looking at the documentation from Microsoft, it looks like to share a handle requires process forking. CreateFileMappingA function and from your original posting and question that does not appear to be what you are doing.

Multiple processes can share a view of the same file by either using a single shared file mapping object or creating separate file mapping objects backed by the same file. A single file mapping object can be shared by multiple processes through inheriting the handle at process creation, duplicating the handle, or opening the file mapping object by name. For more information, see the CreateProcess, DuplicateHandle and OpenFileMapping functions.

In the following example using a named shared memory area, I started with the source code of the example in CreateFileMapping, MapViewOfFile, handle leaking c++ however being lazy I just made a single source file, Windows Console Application, that I could start up as two different processes with different behavior.

Source code file that is used to execute in two different ways:

#include "stdafx.h"

#include <conio.h>
#include <iostream>

#define BUF_SIZE 256
TCHAR szName[] = TEXT("MyFileMappingObject");

int main(int argc, char **argv)
{
    HANDLE hMapFile;
    LPCTSTR pBuf;
    int     iInstance = 0;
    TCHAR szMsgFmt[] = TEXT("Message from first process %d.");

    if (argc > 1) {
        iInstance = atoi(argv[1]);
    }
    hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,    // use paging file
        NULL,                    // default security
        PAGE_READWRITE,          // read/write access
        0,                       // maximum object size (high-order DWORD)
        BUF_SIZE,                // maximum object size (low-order DWORD)
        szName);                 // name of mapping object

    DWORD lastError = GetLastError();
    if (hMapFile == NULL)
    {
        _tprintf(TEXT("Could not create file mapping object (%d).\n"),
            GetLastError());
        std::cin.get();
        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);

        std::cin.get();
        return 1;
    }


    for (int i = 1; i < 4; i++) {
        if (iInstance > 0) {
            MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK);
        }
        else {
            TCHAR szMsg[128] = { 0 };
            wsprintf (szMsg, szMsgFmt, i);
            std::cout << "Copying text into shared memory " << i << std::endl;
            CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
            std::cout << "Waiting " << std::endl;
            _getch();
        }
    }
    CloseHandle(hMapFile);


    UnmapViewOfFile(pBuf);
    return 0;
}

Batch file 1 and batch file 2 to run same executable as two different processes.

shared_mem

pause

and

shared_mem  1

pause

and the modified stdafx.h include file.

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#include "targetver.h"

#include <Windows.h>
#include <WinUser.h>
#include <stdio.h>
#include <tchar.h>



// TODO: reference additional headers your program requires here

Compile the application source file and then run the first bat file which will start up and put some text into the shared memory area and then wait. Next run the second bat file which will read the text from the shared memory area.

What I saw is if you if you click the Ok button on the displayed dialog from the second bat file, you will see the same message again.

However if you then go to the window of the first bat file and press the enter key to generate the next message then go back to the dialog generated by the second bat file, you will see that it will read the updated string.

This is all using a named shared file. Didn't try with the shared memory handle.

Richard Chambers
  • 16,643
  • 4
  • 81
  • 106