开发者

Error using CreateFileMapping - C

开发者 https://www.devze.com 2022-12-26 19:04 出处:网络
I am using the tutorial on this MSDN link to implement a way of transferring data from one process to another. Although I was advised in an earlier question to use the Pipe methods, due to certain con

I am using the tutorial on this MSDN link to implement a way of transferring data from one process to another. Although I was advised in an earlier question to use the Pipe methods, due to certain constraints I have no choice but to use the CreateFileMapping method.

Now, i've succesfully managed to make two seperate window form projects within the same solution and by editing some properties both of the forms load at the same time.

Furthermore I have managed to implement the code given in the MSDN sample into the first (Producer) and second (Consumer) program without any compilation errors.

The problem I am having now is when I run the first program and try to create the handle to the mapped file, I am given an error saying it was unsuccesful and I do not understand why this is happening.

I have added both the Producer and Consumer code files to demonstrate what I am trying to do.

Producer:

#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];
    LPCTSTR 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 = (LPTSTR) 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:

#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;
    LPCTSTR 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 = (LPTSTR) 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
//

It's by no means tidy and final but it's just a start, thanks for any help.

Edit: Error

Error using CreateFileMapping - C

Edit2: Output

Error using CreateFileMapping - C


Your code for the producer works for me. What version of Windows are you using? In newer versions (like Vista and 7) there are additional security restrictions placed on accessing shared memory. There is a note about this in the MSDN article you referenced above, saying that you must be an Administrator to create global shared memory objects in Windows Vista/7.

You should also make a call to GetLastError() to see which error code is actually returned from CreateFileMapping(), that may be helpful in determining the root cause of the problem.


Ensure the Global name is unique; this can be done with a tool named Process Explorer.

If not unique, this would typically fail with Error code 6 (The handle is invalid) upon calling CreateFileMappinng

  1. Download Process Explorer from SysInternals
  2. Run Process Explorer
  3. Run your application up to a break point just prior to the CreateFileMapping() failure
  4. Search for MyFileMappingObject using Find (Ctrl-F)
  5. If anything comes up such as another FileMap, Mutex, etc.. consider a more unique name, and ensure your application is not the one creating it.

Note: Consider naming your FileMapping using a GUID (File -> Tools > Create GUID) within Visual Studio


Maybe we learned from the same material/examples in the past. I had the same problem after migrating from XP to Windows 7:

NULL Handle return value and GetLastError() = 5.

ERROR_ACCESS_DENIED
    5 (0x5)
    Access is denied.

System Error Codes (0-499): http://msdn.microsoft.com/en-us/library/ms681382.aspx

I used a lpName with backslashes like in the Microsoft example from http://msdn.microsoft.com/en-us/library/windows/desktop/aa366537.aspx that you posted above. After changing the name of the file mapping object (lpName) from "Global\MyFileMappingObject" to "GlobalMyFileMappingObject", the CreateFileMapping function works again under Windows 7 with no other changes.

"The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The remainder of the name can contain any character except the backslash character ('\'). Creating a file mapping object in the global namespace from a session other than session zero requires the SeCreateGlobalPrivilege privilege. For more information, see Kernel Object Namespaces".

This is not just a name-change! If you need access to the global namespace, then you have to go the SeCreateGlobalPrivilege way.


Under Windows 7 I found:

OpenFileMapping(FILE_MAP_ALL_ACCESS, ...);

Causes issues with:

CreateFileMapping(
                 (HANDLE)0xFFFFFFFF,    // use paging file

Try:

OpenFileMappingA(SECTION_MAP_WRITE | SECTION_MAP_READ,...);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号