Ошибка при использовании CreateFileMapping - C - PullRequest
1 голос
/ 15 апреля 2010

Я использую учебник по по этой ссылке MSDN , чтобы реализовать способ передачи данных из одного процесса в другой. Хотя в более раннем вопросе мне посоветовали использовать методы Pipe, из-за определенных ограничений у меня нет другого выбора, кроме как использовать метод CreateFileMapping.

Теперь мне удалось создать два отдельных проекта формы окна в одном решении и отредактировать некоторые свойства, которые загружают обе формы одновременно.

Кроме того, мне удалось внедрить код, приведенный в примере MSDN, в первую (Producer) и вторую (Consumer) программы без каких-либо ошибок компиляции.

Проблема, с которой я столкнулся сейчас, заключается в том, что когда я запускаю первую программу и пытаюсь создать дескриптор для сопоставленного файла, мне сообщают об ошибке, которая говорит о том, что это не удалось, и я не понимаю, почему это происходит.

Я добавил файлы кода как для продюсера, так и для потребителя, чтобы продемонстрировать, что я пытаюсь сделать.

Производитель

#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
//

Потребитель

#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
//

Это ни в коем случае не аккуратно и окончательно, но это только начало, спасибо за любую помощь.

Редактировать: Ошибка

Error Image

Редактировать2: Вывод

Output Image

Ответы [ 6 ]

3 голосов
/ 02 мая 2012

Убедитесь, что глобальное имя уникально; это можно сделать с помощью инструмента с именем Process Explorer.

Если не уникально, это обычно приводит к ошибке с кодом ошибки 6 (дескриптор неверен) при вызове CreateFileMappinng

  1. Загрузка Process Explorer из SysInternals
  2. Запустить Process Explorer
  3. Запустите приложение до точки останова непосредственно перед ошибкой CreateFileMapping ()
  4. Поиск MyFileMappingObject с использованием Find (Ctrl-F)
  5. Если что-то появится, например, еще одна FileMap, Mutex и т. Д., Рассмотрите более уникальное имя и убедитесь, что ваше приложение не является тем, которое его создает.

Примечание: Рассмотрите возможность присвоения имени FileMapping с помощью GUID (Файл -> Инструменты> Создать GUID) в Visual Studio

3 голосов
/ 15 апреля 2010

У меня работает ваш код для продюсера. Какую версию Windows вы используете? В более новых версиях (таких как Vista и 7) существуют дополнительные ограничения безопасности при доступе к общей памяти. В статье MSDN, на которую вы ссылались выше, есть примечание об этом, в котором говорится, что вы должны быть администратором для создания объектов глобальной общей памяти в Windows Vista / 7.

Вам также следует вызвать GetLastError (), чтобы узнать, какой код ошибки действительно возвращается из CreateFileMapping (), что может помочь в определении основной причины проблемы.

1 голос
/ 17 ноября 2012

Может быть, мы узнали из того же материала / примеров в прошлом.У меня была такая же проблема после перехода с XP на Windows 7:

NULL Возвращаемое значение дескриптора и GetLastError () = 5.

ERROR_ACCESS_DENIED
    5 (0x5)
    Access is denied.

Коды системных ошибок (0-499): http://msdn.microsoft.com/en-us/library/ms681382.aspx

Я использовал lpName с обратными слешами, как в примере Microsoft с http://msdn.microsoft.com/en-us/library/windows/desktop/aa366537.aspx, который вы опубликовали выше.После изменения имени объекта сопоставления файлов (lpName) с «Global \ MyFileMappingObject» на «GlobalMyFileMappingObject» функция CreateFileMapping снова работает в Windows 7 без других изменений.

«Имя может иметьпрефикс «Global \» или «Local \» для явного создания объекта в глобальном или сеансовом пространстве имен. Остальная часть имени может содержать любой символ, кроме символа обратной косой черты ('\'). Создание объекта сопоставления файловв глобальном пространстве имен из сеанса, отличного от нулевого сеанса, требуется SeCreateGlobalPrivilege привилегия . Для получения дополнительной информации см. Пространства имен объекта ядра".

Это не просто смена имени!Если вам нужен доступ к глобальному пространству имен, то вам нужно пойти по пути SeCreateGlobalPrivilege .

1 голос
/ 26 июля 2010

В коде для производителя _getch () также предназначен для неконсольного приложения?

0 голосов
/ 01 декабря 2015

под Windows 7 Я нашел:

OpenFileMapping(FILE_MAP_ALL_ACCESS, ...);

Вызывает проблемы с:

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

Попробуйте:

OpenFileMappingA(SECTION_MAP_WRITE | SECTION_MAP_READ,...);
0 голосов
/ 24 августа 2011

Попробуйте изменить «Global \ MyFileMappingObject» на «MyFileMappingObject»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...