I wish to implement IPC using Named Shared Memory.
To do this, one of the steps is getting a handle to a Mapping Memory Object, using CreateFileMapping().
I do it exactly as MSDN website reccommends: http://msdn.microsoft.com/en-us/library/aa366551(v=VS.85).aspx:
hFileMappingHandle = CreateFileMapping
(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
256, // maximum object size (low-order DWORD)
"GlobalMyFileMappingObject" // name of mapping object
);
DWORD dwError = GetLastError();
However, the handle returned is always 0x0, and the System Error Code returned is: 0x5 (Access Denied.)
- Only Named Memory Sharing desired (not file sharing).
- Windows 7 x64 bit OS
- Administrator’s user rights available
- Developed Application: 64bit Plug-In application (.dll)
Does anybody have the same experience, and a way to fix it, please? I use MSDN site as my reference, so I to not think, there is problem in the code.
Я использую учебник по эта ссылка MSDN реализовать способ передачи данных от одного процесса к другому. Хотя мне посоветовали предыдущий вопрос Чтобы использовать методы Pipe, из-за определенных ограничений у меня нет другого выбора, кроме как использовать метод CreateFileMapping.
Теперь мне удалось создать два отдельных проекта оконных форм в одном решении, и, отредактировав некоторые свойства, обе формы загружаются одновременно.
Кроме того, мне удалось внедрить код, приведенный в образце MSDN, в первую (Производитель) и вторую (Потребитель) программы без каких-либо ошибок компиляции.
Проблема, с которой я столкнулся сейчас, заключается в том, что когда я запускаю первую программу и пытаюсь создать дескриптор сопоставленного файла, мне выдается сообщение об ошибке, в котором говорится, что это не удалось, и я не понимаю, почему это происходит.
Я добавил файлы кода производителя и потребителя, чтобы продемонстрировать, что я пытаюсь сделать.
Производитель:
#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("GlobalMyFileMappingObject");
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("GlobalMyFileMappingObject");
//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
//
Это ни в коем случае не аккуратно и не окончательно, но это только начало, спасибо за любую помощь.
Изменить: ошибка

Edit2: вывод

- Remove From My Forums
-
Question
-
Hello all,
I have just simply call the CreateFileMapping with INVALID_HANDLE_VALUE
m_hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,&secAttr,PAGE_READWRITE,0,sizeof(MAPPING),SZ_MAPPING_NAME);
To close the Mapping file, I call the function CloseHandle(m_hMapfile)
I see that it close successfully with GetLastError()=0 when I stop my application, but then I start my application again, it seems that the mapping file was not closed since I see that GetLastError()=183 ( ERROR_ALREADY_EXISTS).
I didn’t create any mappingofView for this file mapping at all. I just want to test for creating of mapping file.
Anyone know that reason? Please advise.
Thanks.
Я хочу реализовать IPC с использованием именованной общей памяти.
Чтобы сделать это, одним из шагов является получение дескриптора объекта Mapping Memory, используя CreateFileMapping().
Я делаю это точно, как веб-сайт MSDN reccommends: http://msdn.microsoft.com/en-us/library/aa366551(v=VS.85).aspx:
hFileMappingHandle = CreateFileMapping
(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
256, // maximum object size (low-order DWORD)
"GlobalMyFileMappingObject" // name of mapping object
);
DWORD dwError = GetLastError();
Однако возвращенный дескриптор всегда 0x0, а возвращаемый системный код ошибки: 0x5 (Access Denied.)
- Только Доступ к именам памяти (не общий доступ к файлам).
- операционная система Windows 7 x64
- Доступные права администратора
- Разработанное приложение: приложение с 64-битным подключаемым модулем (. dll)
Есть ли у кого-то такой же опыт и способ его исправить? Я использую сайт MSDN в качестве ссылки, поэтому я не думаю, что в коде есть проблемы.
Ответ 1
Похоже, у вас недостаточно привилегий.
Из MSDN:
Создание объекта сопоставления файлов в глобальное пространство имен из сеанса другое чем нулевой сеанс Привилегия SeCreateGlobalPrivilege. Для Дополнительная информация, см. Объект ядра Пространства имен.
…
Создание объекта сопоставления файлов в глобальном пространстве имен, используя CreateFileMapping из сеанса кроме нуля сеанса, является привилегированная работа. Из-за этого, приложение, выполняемое произвольным Узел сеанса удаленных рабочих столов (RD Session Host) должен иметь Функция SeCreateGlobalPrivilege включена в для создания объекта сопоставления файлов в глобальном пространстве имен. Проверка привилегий ограничивается создание объектов сопоставления файлов и не распространяется на открытие существующих из них. Например, если служба или система создает объект сопоставления файлов, любой процесс, выполняющийся в любом сеансе, может доступ к этому файло-картографическому объекту при условии, что пользователь имеет необходимый доступ.
Ответ 2
Администраторы, службы и сетевые службы по умолчанию имеют SeCreateGlobalPrivilege. Вы должны помнить, что Windows7/Vista не запускает все как admin. Поэтому используйте «Начать как администратор», чтобы сделать «Global» работу для вашего приложения. Если вы отлаживаете, запустите Visual Studio также как администратор.
Ответ 3
Чтобы создавать глобальные сопоставления файлов, вам нужна привилегия SeCreateGlobalPrivilege — есть ли у вас это? Отказано в доступе, это означает, что это проблема с разрешениями.
Ответ 4
Ссылка на службы терминалов в документации о глобальном пространстве имен немного вводит в заблуждение, так как это подразумевает, что вам нужно только беспокоиться об этом, если у вас есть необычная ситуация.
Фактически, как IIS, так и системные службы запускаются в сеансе нуль, а первый/единственный пользователь должен запускать сеансы в сеансе 1 — поэтому вы должны использовать глобальное пространство имен для связи между IIS или службой и обычной программой.
Есть такой код:
#include <windows.h>
#include <stdio.h>
#include <string.h>
void main()
{
int i,l;
HANDLE s,h;
char *buffer;
char buf[]="abcdefghijklmno";
char tow[]="Text, writed to memory";
if ((h=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,1024,"mem"))==NULL)
{
printf("Can't create file mappingn");
}
printf("Handle: %dn",h);
if ((buffer=MapViewOfFile(h,FILE_MAP_WRITE | FILE_MAP_READ,0,0,1024))==NULL)
{
printf("Can't MapViewOfFilen");
}
s=CreateMutex(NULL,1,"sem");
Sleep(10000);
printf("Write to buffer first timen");
for (i=0;i<strlen(tow)+1;i++) buffer[i]=tow[i];
if (ReleaseMutex(s)) {printf("Release mutexn");}
printf("From buffer: %sn",buffer);
printf("Write to buffer second timen");
for (i=0;i<3;i++)
{
printf("Writed: %cn",buf[i]);
buffer[i*400]=buf[i];
}
Sleep(10000);
CloseHandle(s);
CloseHandle(h);
}
При его выполнении вот такой результат:
Что нужно убрать/добавить чтобы код заработал? GetLastError() выдает 6.
- Remove From My Forums
-
Question
-
I have this code that has been generously supplied by the user RLWA32. The following is the top of the file, a fraction. I changed the function name because I need to call it from another file.
int Sending_To_SSD() { // Create a 0 byte, empty file HANDLE hFile = CreateFile(_T("SphHarm.dat"), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { _tprintf_s(_T("CreateFile failed with error %dn"), GetLastError()); return 1; } DWORD dwMaxSize = MAX_FLOATS * sizeof(float); HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwMaxSize, NULL); if (!hMap) { _tprintf_s(_T("CreateFileMapping failed with error %dn"), GetLastError()); return 1; } // map the entire file into the view float* pfArray = (float*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (!pfArray) { _tprintf_s(_T("MapViewOfFile failed with error %dn"), GetLastError()); return 1; }I also did a little surgery, removed comments and a printf statement. I wonder why the map file cannot be created? Thanks, — MyCatAlex
-
Edited by
Sunday, April 12, 2020 6:51 PM
-
Edited by
Answers
-
Try writing a byte to the file after CreateFile succeeds but before you call CreateFileMapping.
For example,
BYTE buf = ''; DWORD dwWritten = 0; WriteFile(hFile, &buf, sizeof buf, &dwWritten, NULL);
I’m wondering if CreateFileMapping behaves differently when the file to be mapped resides on an SSD that is not using the NTFS file system.
-
Marked as answer by
MyCatAlex
Sunday, April 12, 2020 11:07 PM
-
Marked as answer by
-
-
Edited by
WayneAKing
Sunday, April 12, 2020 10:58 PM -
Marked as answer by
MyCatAlex
Sunday, April 12, 2020 11:07 PM
-
Edited by
I wish to implement IPC using Named Shared Memory.
To do this, one of the steps is getting a handle to a Mapping Memory Object, using CreateFileMapping().
I do it exactly as MSDN website reccommends: http://msdn.microsoft.com/en-us/library/aa366551(v=VS.85).aspx:
hFileMappingHandle = CreateFileMapping
(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
256, // maximum object size (low-order DWORD)
"Global\MyFileMappingObject" // name of mapping object
);
DWORD dwError = GetLastError();
However, the handle returned is always 0x0, and the System Error Code returned is: 0x5 (Access Denied.)
- Only Named Memory Sharing desired (not file sharing).
- Windows 7 x64 bit OS
- Administrator’s user rights available
- Developed Application: 64bit Plug-In application (.dll)
Does anybody have the same experience, and a way to fix it, please? I use MSDN site as my reference, so I to not think, there is problem in the code.
Код ошибки CreateFileMapping 8. Недостаточно памяти для обработки этой команды. Я пытаюсь создать сопоставление файлов с 4 ГБ (0xFFFFFFFF) на 64-битной Win10 Visual C ++.
#define UBS_MEM_SIZE 0xffffffff
HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr,
PAGE_READWRITE, HIWORD(UBS_MEM_SIZE), LOWORD(UBS_MEM_SIZE),
TEXT("dllmemfilemap"));
Как я могу решить эту проблему «ОШИБКА 8»?
1
Решение
CreateFileMapping(..., HIWORD(UBS_MEM_SIZE), LOWORD(UBS_MEM_SIZE), ...)
Макросы LO / HIWORD генерируют WORD, 16-битное значение. Вы запрашиваете отображенный в памяти файл 0xffff0000ffff. Это 282 терабайта. Текущие процессоры x64 ограничены 48-битным виртуальным адресом, максимальный размер которого составляет 8 терабайт. Так что да, ошибка 8 (ERROR_NOT_ENOUGH_MEMORY) вполне ожидаема.
Не используйте эти макросы. Вы можете использовать LARGE_INTEGER в качестве альтернативы:
LARGE_INTEGER size;
size.QuadPart = UBS_MEM_SIZE;
HANDLE hMapObject = CreateFileMapping(..., size.HighPart, size.LowPart, ...);
4
Другие решения
HIWORD а также LOWORD макросы предназначены для извлечения старших и младших 16-битных слов из 32-битных DWORD, CreateFileMappingс другой стороны, ожидает двух DWORDs вместе составляют 64-битное целое число без знака, которое является размером объекта сопоставления.
И то и другое HIWORD(UBS_MEM_SIZE) а также LOWORD(UBS_MEM_SIZE) Уступать 0xffff (две 16-битные половины), которые затем преобразуются в 32-битные целые числа без знака (что и ожидает функция).
Итак, что вы на самом деле делаете, так это запрашиваете отображение размера файла 0x0000ffff0000ffff, Это больше чем 255 TB, Так как вы используете INVALID_HANDLE_VALUEэто должно быть подкреплено ОЗУ или файлом системной страницы; Я сомневаюсь, что у вас есть так много там
Если UBS_MEM_SIZE всегда 32-битный, вы можете просто использовать
HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr,
PAGE_READWRITE, 0, UBS_MEM_SIZE,
TEXT("dllmemfilemap"));
Если вам действительно нужно обрабатывать размеры более 4 GBВы можете сделать что-то вроде этого:
HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
static_cast<DWORD>(UBS_MEM_SIZE >> 32), static_cast<DWORD>(UBS_MEM_SIZE),
TEXT("dllmemfilemap"));
Удостовериться UBS_MEM_SIZE на самом деле имеет тип больше 32-битного (даже если его значение может быть меньше этого), так как в противном случае сдвиг на 32 бита — неопределенное поведение в C ++. Итак, если вы хотите использовать второй вариант выше с вашим начальным значением, это должно быть что-то вроде
#define UBS_MEM_SIZE 0xFFFFFFFFull
(Кстати, используйте const…)
Чтобы сделать его более безопасным, я бы обернул вызов примерно так:
inline HANDLE MyCreateMapping(unsigned long long size, LPCTSTR name)
{
return CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
static_cast<DWORD>(size >> 32), static_cast<DWORD>(size), name);
}
Таким образом, вам не нужно запоминать хитрые детали о битах, сдвигах и размерах целочисленных типов.
3
