Thread: Using CreateFileMapping - Displaying Data

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    7

    Exclamation Using CreateFileMapping - Displaying Data

    Hello,

    I am trying to pass data from one active process to another, so far I have managed to get both processes to communicate with each other however the message that is shown by the second process does not resemble the message from the first process.

    I have a feeling it has something to do with the conversions i'm using but for the life of me I can't work out where the problem lies.

    I have added the code for the Producer (Create/Sends data) and the Consumer (Reads/Displays) as well as a screenshot of the debugger in action.

    The code is based on the sample given just below:

    Creating Named Shared Memory (Windows)



    Producer:

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    
    
    //File header definitions
    #define IDM_FILE_ROLLDICE 1
    #define IDM_FILE_QUIT 2
    #define BUF_SIZE 256
    
    TCHAR szName[]=TEXT("Global\\MyFileMappingObject");
        TCHAR szMsg[]=TEXT("Message from first process!");
    
    void AddMenus(HWND);
    LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
    
    ////Standard windows stuff - omitted to save space.
    
    //////////////////////
    // WINDOWS FUNCTION //
    //////////////////////
    LRESULT CALLBACK WindowFunc(HWND hMainWindow, UINT message, 
                                WPARAM wParam, LPARAM lParam)
    {
        WCHAR buffer[256];
        LPCWSTR pBuf;
    
        struct DiceData storage;
        HANDLE hMapFile;
    
        switch(message)    
        {
        case WM_CREATE:
            {
    
                // Create Menus
                AddMenus(hMainWindow);
            }
    
            break;
        case WM_COMMAND:
            // Intercept menu choices
            switch(LOWORD(wParam))
            {
            case IDM_FILE_ROLLDICE:
                {
                    //Roll dice and store results in variable
                    //storage = RollDice();
    
                    ////Copy results to buffer
                    //swprintf(buffer,255,L"Dice 1: %d, Dice 2: %d",storage.dice1,storage.dice2);
    
                    ////Show via message box
                    //MessageBox(hMainWindow,buffer,L"Dice Result",MB_OK);
    
                    hMapFile = CreateFileMapping(
                     (HANDLE)0xFFFFFFFF,    // 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
    
       if (hMapFile == NULL) 
       { 
          MessageBox(hMainWindow,L"Could not create file mapping object",L"Error",NULL);
          return 1;
       }
       pBuf = (LPCWSTR) MapViewOfFile(hMapFile,   // handle to map object
                            FILE_MAP_ALL_ACCESS, // read/write permission
                            0,                   
                            0,                   
                            BUF_SIZE);           
    
       if (pBuf == NULL) 
       { 
          MessageBox(hMainWindow,L"Could not map view of file",L"Error",NULL);
    
           CloseHandle(hMapFile);
    
          return 1;
       }
    
    
       CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
        _getch();
    
       //UnmapViewOfFile(pBuf);
    
       //CloseHandle(hMapFile);
    
                }
                break;
    
            case IDM_FILE_QUIT:
                SendMessage(hMainWindow, WM_CLOSE, 0, 0);
                break;
            }
            break;
    
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        }
        return DefWindowProc(hMainWindow, message, wParam, lParam);
    }
    
    //
    //Setup menus
    //

    Consumer:

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    
    //File header definitions
    #define IDM_FILE_QUIT 1
    #define IDM_FILE_POLL 2
    
    #define BUF_SIZE 256
    TCHAR szName[]=TEXT("Global\\MyFileMappingObject");
    
    
    //Prototypes
    void AddMenus(HWND);
    LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
    
    //More standard windows creation, again omitted.
    
    //////////////////////
    // WINDOWS FUNCTION //
    //////////////////////
    LRESULT CALLBACK WindowFunc(HWND hMainWindow, UINT message, 
                                WPARAM wParam, LPARAM lParam)
    {
    
    
        HANDLE hMapFile;
        LPCWSTR pBuf;
    
        switch(message)    
        {
        case WM_CREATE:
            {
    
                // Create Menus
                AddMenus(hMainWindow);
                break;
            }
    
        case WM_COMMAND:
            {
                // Intercept menu choices
                switch(LOWORD(wParam))
                {
                case IDM_FILE_POLL:
                    {
                        hMapFile = OpenFileMapping(
                            FILE_MAP_ALL_ACCESS,   // read/write access
                            FALSE,                 // do not inherit the name
                            szName);               // name of mapping object 
    
                        if (hMapFile == NULL) 
                        { 
                            MessageBox(hMainWindow,L"Could not open file mapping object",L"Error",NULL);
                            return 1;
                        } 
    
                        pBuf = (LPCWSTR) MapViewOfFile(hMapFile, // handle to map object
                            FILE_MAP_ALL_ACCESS,  // read/write permission
                            0,                    
                            0,                    
                            BUF_SIZE);                   
    
                        if (pBuf == NULL) 
                        { 
                            MessageBox(hMainWindow,L"Could not map view of file",L"Error",NULL); 
    
                            CloseHandle(hMapFile);
    
                            return 1;
                        }
    
                        MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK);
    
                        UnmapViewOfFile(pBuf);
    
                        CloseHandle(hMapFile);
    
                        break;
                    }
    
    
    
    
                case IDM_FILE_QUIT:
                    SendMessage(hMainWindow, WM_CLOSE, 0, 0);
                    break;
                }
                break;
            }
    
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                break;
            }
        }
        return DefWindowProc(hMainWindow, message, wParam, lParam);
    }
    
    //
    //Setup menus
    //

    Debugger:

    http://i113.photobucket.com/albums/n...Untitled-3.jpg


    Thank you for the help!

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Is "M" also all you see in the message box? You seem to be using wide chars consistently throughout, so that seems unlikely to be a problem. Can you walk through the file from the consumer side? (I.e., if you print out pBuf[1], pBuf[2], etc., what do you get?)

  3. #3
    Registered User
    Join Date
    Apr 2010
    Posts
    7
    The message box shows the "Process2" caption fine, i've stepped through it in the debugger and it's showing the value of pBuf to be "0x000b0000".

    I'm sorry I don't understand what you mean by "(I.e., if you print out pBuf[1], pBuf[2], etc., what do you get?)", it's not an array.

    Sorry for my lack of understanding, I primarily use C#.

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by AnkleSpankle View Post
    I'm sorry I don't understand what you mean by "(I.e., if you print out pBuf[1], pBuf[2], etc., what do you get?)", it's not an array.
    pBuf is a pointer to a char array and can be indexed as a char array.

    You are getting the first character of the expected response 'M'.

    So we want to see what the rest of the pBuf holds (ie is pBuf[1] == 'e', etc).

    Try copying the contents of pBuf to a char array (or a cast it to one) to see if the rest of the expected message is there (and the issue is how you are displaying it).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  5. #5
    Registered User
    Join Date
    Apr 2010
    Posts
    7
    Ah I looked at the message I am trying to send and it does indeed start with an "M".

    I've built another solution with the MSDN snippet and it works fine, however when I put it side by side with mine I've noticed something different between the two pBuf's

    http://i113.photobucket.com/albums/n...Untitled-4.jpg

    Note: I've fixed the problem of them being different types but it's still not working properly, I have no idea what to do next. Also for some reason if I have the MSDN sample running at the same time as my own it works fine. That makes no sense atall.
    Last edited by AnkleSpankle; 04-17-2010 at 12:24 PM.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you close the "file" in the producer, does that help?

  7. #7
    Registered User
    Join Date
    Apr 2010
    Posts
    7
    Quote Originally Posted by tabstop View Post
    If you close the "file" in the producer, does that help?
    How do you mean close the file? As in UnmapViewOfFile? If so then it makes no difference.

    I can't understand how one program can make an affect on another.

    Edit:

    After further investigation it almost seems that my own application is somehow reading the other applications memory by accident. If I "poll" for the message without even sending it via the producer window, it still gets the message which must mean it's reading it from the other (MSDN) process, this would also explain why it only works properly when I run the MSDN sample first.

    I still don't understand why this happens, how to stop it and how to fix it, this is possibly the strangest thing I've come across.

    Edit 2: Solution

    I had mistakenly forgot to add the
    Code:
    #include <tchar.h>
    header to both files, after adding them the application worked as it should and showed the full message.
    If an admin could add this to my question for other users I'd appreciate it, it won't let me edit the initial post.

    Thank you for all the help.
    Last edited by AnkleSpankle; 04-17-2010 at 02:58 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. xor linked list
    By adramalech in forum C Programming
    Replies: 23
    Last Post: 10-14-2008, 10:13 AM
  2. Replies: 3
    Last Post: 04-18-2008, 10:06 AM
  3. question about a working linked list
    By cold_dog in forum C++ Programming
    Replies: 23
    Last Post: 09-13-2006, 01:00 AM
  4. Replies: 4
    Last Post: 06-14-2005, 05:45 AM
  5. All u wanted to know about data types&more
    By SAMSAM in forum Windows Programming
    Replies: 6
    Last Post: 03-11-2003, 03:22 PM

Tags for this Thread