2010-03-16 4 views
7

이미 다른 32 비트 프로세스의 메모리에 매핑 된 파일의 64 비트 프로세스에서 MapViewOfFile을 사용하려고합니다. 그것은 실패하고 나에게 "접근 거부"오류를 준다. 이 문제는 알려진 Windows 제한 사항입니까 아니면 잘못 되었습니까? 동일한 코드가 2 개의 32 비트 프로세스에서 잘 작동합니다.MapViewOfFile이 32 비트와 64 비트 프로세스간에 공유됩니다.

코드는 일종의 다음과 같습니다 : 32 비트 응용 프로그램에서 CreateFile에를 호출 할 때

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); 
+0

경로가 VirtualStore 디렉터리로 리디렉션되고 있는지 확인 했습니까? 프로세스 모니터가 도움이 될 수 있습니다. – bk1e

답변

9

, 당신은 더 공유가 허용되지 않습니다 의미 공유 매개 변수에 대한 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 비트 실행 파일의 조합은 잘 작동하는 것 같다.

편집 2 : 그러나 이것은 데모 수준의 코드입니다. 예를 들어, 각 공유 객체의 이름에는 일반적으로 다른 프로그램과의 충돌을 방지하기 위해 GUID 문자열이 포함되어야합니다. 또한이 코드가 아무 것도 유용하지 않다는 사소한 세부 사항은 말할 것도없이 오류 검사를 생략했습니다.

+0

Jerry에게 감사드립니다. 흥미 롭습니다. 공유하지 않는 플래그가 CreateFile에만 전달되기 때문에 내 문제라고 생각하지 않습니다. 해당 파일은 즉시 닫혀 적용되지 않아야합니다. 또한 그것은 여러 32 비트 애플 리케이션 간의 공유에 잘 작동하며, 그 중 하나가 64 비트 일 때만 고장납니다. 그래도 코드를 실행하려고합니다. –

+1

나는 그것을 이해했다고 생각합니다. 파일의 크기는 time_t가 64 비트이기 때문에 64 비트 시스템에서 더 큰 구조체의 크기를 기반으로 결정되었으며 우리는 time_t를 32 비트 빌드에서 여전히 32 비트가되도록 강제하고 있습니다. 어떤 이유로 MapViewOfFile의 기존 영역보다 더 큰 영역 크기를 지정하면 액세스가 거부되어 실패합니다. 감사합니다. –