MapViewoffile은 32 비트와 64 비트 프로세스를 공유했습니다
-
20-09-2019 - |
문제
나는 이미 다른 32 비트 프로세스의 메모리에 이미 매핑 된 파일에서 64 비트 프로세스에서 MapViewoffile을 사용하려고합니다. 실패하고 "액세스 거부"오류를 제공합니다. 이것은 알려진 Windows 제한입니까, 아니면 내가 뭔가 잘못하고 있습니까? 동일한 코드는 2 개의 32 비트 프로세스에서 잘 작동합니다.
코드는 다음과 같습니다.
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szShmName);
if (NULL == hMapFile)
{ /* failed to open - create new (this happens in the 32 bit app) */
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
/* give access to members of administrators group */
BOOL success = ConvertStringSecurityDescriptorToSecurityDescriptor(
"D:(A;OICI;GA;;;BA)",
SDDL_REVISION_1,
&(sa.lpSecurityDescriptor),
NULL);
HANDLE hShmFile = CreateFile(FILE_XXX_SHM,
FILE_ALL_ACCESS, 0,
&sa,
OPEN_ALWAYS, 0, NULL);
hMapFile = CreateFileMapping(hShmFile, &sa, PAGE_READWRITE,
0,
SHM_SIZE,
szShmName);
CloseHandle(hShmFile);
}
// this one fails in 64 bit app
pShm = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, SHM_SIZE);
해결책
32 비트 응용 프로그램에서 CreateFile에 전화하면 0
공유 매개 변수의 경우 공유가 허용되지 않음을 의미합니다. 그것을 변경합니다 FILE_SHARE_READ | FiLE_SHARE_WRITE
아마도 올바른 방향으로 나아가는 단계 일 것입니다.
편집 : 방금 작동하는 데모를 함께 휘젓습니다 (적어도 나를 위해) :
#include <windows.h>
#include <iostream>
static const char map_name[] = "FileMapping1";
static const char event1_name[] = "EventName1";
static const char event2_name[] = "EventName2";
int main() {
HANDLE mapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, map_name);
if (NULL == mapping) {
std::cout << "Calling CreateFile\n";
HANDLE file = CreateFile("MappedFile",
FILE_ALL_ACCESS,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
0,
NULL);
std::cout << "Creating File mapping\n";
mapping = CreateFileMapping(file, NULL, PAGE_READWRITE, 0, 65536, map_name);
std::cout << "Closing file handle\n";
CloseHandle(file);
}
std::cout << "Mapping view of file\n";
char *memory = (char *)MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 65536);
if (memory == NULL) {
std::cerr << "Mapping Failed.\n";
return 1;
}
std::cout << "Mapping succeeded\n";
HANDLE event = CreateEvent(NULL, false, false, event1_name);
if (GetLastError()==ERROR_ALREADY_EXISTS) {
std::cout <<"Waiting to receive string:\n";
WaitForSingleObject(event, INFINITE);
std::cout << "Received: " << memory;
HANDLE event2 = CreateEvent(NULL, false, false, event2_name);
SetEvent(event2);
}
else {
char string[] = "This is the shared string";
std::cout << "Sending string: " << string << "\n";
strncpy(memory, string, sizeof(string));
SetEvent(event);
HANDLE event2 = CreateEvent(NULL, false, false, event2_name);
WaitForSingleObject(event2, INFINITE);
}
return 0;
}
32 또는 64 비트 실행 파일의 조합은 잘 작동하는 것 같습니다.
EDIT2 : 그러나 이것은 순전히 데모 레벨 코드입니다. 예를 들어, 각 공유 객체의 이름은 일반적으로 다른 프로그램과 우발적으로 충돌하는 것을 보장하기 위해 안내 문자열을 포함해야합니다. 또한이 코드가 유용한 것을 달성하지 못한다는 사소한 세부 사항은 말할 것도없이 상당한 오류 검사를 건너 뛰었습니다.
제휴하지 않습니다 StackOverflow