Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.04.2013, 02:32   #1
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию File Mapping

Посмотрел все, что поиск по форуму дал на "File Mapping", но решения так и не нашел. У меня проблема вот в чем: нужно создать буфер для обменна данными между несколькими процессами. Когда главный процес создает и проецирует файл в область памяти, то он может производить и чтение и запись. А вот подчиненные процесы могут делать только чтение. При таком раскладе как у меня(см. код ниже) подчиненный процес, который пытается сделать отображение получает NULL, а GetLastError дает 0x05 - доступ запрещен.

вот код главного процесса:
Код:
#include <windows.h>
#include "filemapping.h"

int main(int argc, char** argv){
	int buffer_size = 512;

	HANDLE hFileMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, buffer_size, FILEMAP_NAME);
	if(hFileMap == NULL){
		fprintf(stderr, "Can't open memory mapped file. Error code: %lu\n", GetLastError());
		return 1;
	}

	PBYTE pbMapView = (PBYTE)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, buffer_size);
	if(pbMapView == NULL){
		fprintf(stderr, "Can't map view of file. Error code: %lu\n", GetLastError());
		return 1;
	}

	printf("Press Enter to continue...\n");
	getchar();

	char buf[60] = "master___";

	memcpy(buf, pbMapView, 9);
	printf("Read buffer data: '%s'\n", buf);

	printf("Press Enter to continue...\n");
	getchar();

	UnmapViewOfFile(pbMapView);
	CloseHandle(hFileMap);
	printf("Map handles closed\n");
	return 0;
}
filemapping.h содержит всего две макроподстановки:
Код:
#define FILEMAP_NAME "mmf_test"
#define FILE_NAME "C:\\MMFTest.dat"
и соотвественно код подчиненного процеса:
Код:
#include <windows.h>
#include "filemapping.h"

int main(int argc, char** argv){
	printf("Generator Process Running\n");

	HANDLE hFileMap = OpenFileMappingA(PAGE_READWRITE, FALSE, FILEMAP_NAME);
	if(hFileMap == NULL){
		fprintf(stderr, "Can't open memory mapped file. Error code: %lu\n", GetLastError());
		return 1;
	}
	PBYTE pbMapView = (PBYTE)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if(pbMapView == NULL){
		// тут я и получаю ERROR_ACCESS_DENIED
		fprintf(stderr, "Can't map view of file. Error code: %lu\n", GetLastError());
		return 1;
	}

	char buf[60] = "slave____";
	memcpy(pbMapView, buf, 9);
	FlushViewOfFile(pbMapView, 0);
	printf("Buffer data writen\n");

	printf("Press Enter to continue...\n");
	getchar();

	UnmapViewOfFile(pbMapView);
	CloseHandle(hFileMap);

	printf("Generator Process Done\n");
	return 0;
}
подскажите в чем проблема? почему нельзя сделать мап с доступом на запись, только на чтение?

Последний раз редактировалось lowercase; 16.04.2013 в 02:35.
lowercase вне форума Ответить с цитированием
Старый 16.04.2013, 07:55   #2
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Вообще-то это нормальная ситуация, когда совместно используемые данные может писать, максимум, один процесс.
Что Вас не устраивает?
Если нужен двусторонний обмен, используйте два разных файла.
s-andriano вне форума Ответить с цитированием
Старый 16.04.2013, 11:54   #3
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Два процесса спокойно могут писать в одну и ту же память. Другое дело, что они с там будут делать...

Вопрос, почему в одном MapViewOfFile() указывается размер а в другом нет?
Далее, оба процесса под одной учетной записью или нет? Если один администратор а другой обычный могут быть проблемы, хотя я лично никогда не пробовал такой вариант.
waleri вне форума Ответить с цитированием
Старый 16.04.2013, 12:23   #4
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

во втором случае указан 0 потому, что в описании указано
Цитата:
If this parameter is 0 (zero), the mapping extends from the specified offset to the end of the file mapping.
или это не правильно?

да. все процессы запускаються от имени администратора.
lowercase вне форума Ответить с цитированием
Старый 16.04.2013, 16:48   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от lowercase Посмотреть сообщение
или это не правильно?
Если чесно, то не знаю. Я всегда в таких ситуациях указывал размер. Долго ли попробовать...
waleri вне форума Ответить с цитированием
Старый 16.04.2013, 17:53   #6
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

Не так уж и долго как кажется. Просто размер буфера задается только в главном процесе. Это я его только для тестирования сразу в buffer_size установил. Оно работает, если подчиненный процесс сделает вызов MapViewOfFile c флагом FILE_MAP_READ или FILE_MAP_COPY. То есть, от главного процесса принимаются данные - работает нормально. Но мне нужна знапись из подчененного, которая при вызове MapViewOfFile с флагом FILE_MAP_WRITE(FILE_MAP_ALL_ACCESS) почему не дает ожидаемого результата.

Последний раз редактировалось lowercase; 16.04.2013 в 21:02.
lowercase вне форума Ответить с цитированием
Старый 16.04.2013, 18:00   #7
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

Не знаю на сколько это поможет. Но всетаки отмечу, что доступ к отражению файла в памяти будет монопольным - в один момент времени только один процесс может производить чтение или запись. Остальные ждут. Буду синхронизировать с помощью мютексов. Но мне сейчас главное сделать возможным чтение и запись данных в буфер из любого процесса.

Последний раз редактировалось lowercase; 16.04.2013 в 21:03.
lowercase вне форума Ответить с цитированием
Старый 17.04.2013, 01:35   #8
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

вот же банальщина - не ту константу передал в OpenFileMapping. вместо PAGE_READWRITE надо FILE_MAP_ALL_ACCESS.
с ума сойти можно: два дня не мог понять в чем проблема. весьма веселые грабли!
случайно наткнулся на статью Создание именованной, совместно используемой памяти которая решила все мои беды (ну почти все)

Последний раз редактировалось lowercase; 17.04.2013 в 01:38.
lowercase вне форума Ответить с цитированием
Старый 17.04.2013, 06:54   #9
vadimych
Форумчанин
 
Регистрация: 16.01.2011
Сообщений: 325
По умолчанию

lowercase, да все уже давно поняли, что проблемы у Вас из-за того, что передаёте ноль последним параметром MapViewOfFile.
vadimych вне форума Ответить с цитированием
Старый 17.04.2013, 09:18   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

кстати, второй процесс тоже может делать CreateFileMapping().
Это удобно, когда порядок запуска процессов не определен.
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
В чём разница между unit, header file, cpp file? TwiX Общие вопросы C/C++ 6 29.04.2012 19:49
file mapping как с ним работать? CodeNOT Win Api 2 01.03.2012 10:12
Как работать с file mapping? castanic Win Api 7 12.11.2011 12:39
File Mapping Gambler Win Api 1 13.08.2010 11:40
Свой PORT MAPPING (NAT) exploys Работа с сетью в Delphi 0 05.06.2010 01:24