문제

나는 이미 다른 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 : 그러나 이것은 순전히 데모 레벨 코드입니다. 예를 들어, 각 공유 객체의 이름은 일반적으로 다른 프로그램과 우발적으로 충돌하는 것을 보장하기 위해 안내 문자열을 포함해야합니다. 또한이 코드가 유용한 것을 달성하지 못한다는 사소한 세부 사항은 말할 것도없이 상당한 오류 검사를 건너 뛰었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top