简体   繁体   English

MapViewOfFile在32位和64位进程之间共享

[英]MapViewOfFile shared between 32bit and 64bit processes

I'm trying to use MapViewOfFile in a 64 bit process on a file that is already mapped to memory of another 32 bit process. 我正在尝试在64位进程中对已经映射到另一个32位进程的内存的文件使用MapViewOfFile。 It fails and gives me an "access denied" error. 它失败并给我一个“访问被拒绝”错误。 Is this a known Windows limitation or am I doing something wrong? 这是一个已知的Windows限制还是我做错了什么? Same code works fine with 2 32bit processes. 相同的代码适用于2个32位进程。

The code sort of looks like this: 代码排序如下:

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

When you call CreateFile in the 32-bit application, you're passing 0 for the sharing parameter, which means no sharing is allowed. 当您在32位应用程序中调用CreateFile时,您将为共享参数传递0 ,这意味着不允许共享。 Changing that to FILE_SHARE_READ | FiLE_SHARE_WRITE 将其更改为FILE_SHARE_READ | FiLE_SHARE_WRITE FILE_SHARE_READ | FiLE_SHARE_WRITE would probably be a step in the right direction. FILE_SHARE_READ | FiLE_SHARE_WRITE可能是朝着正确方向迈出的一步。

Edit: I just whipped together a demo that works (at least for me): 编辑:我只是鞭打了一个有效的演示(至少对我而言):

#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;
}

Any combination of 32- or 64-bit executables seems to work fine. 32位或64位可执行文件的任何组合似乎都可以正常工作。

Edit2: Note, however, that this is purely demo-level code. 编辑2:但请注意,这是纯粹的演示级代码。 Just for example, the name of each shared object should normally contain a GUID-string to ensure against accidental collision with other programs. 例如,每个共享对象的名称通常应包含GUID字符串,以确保不会与其他程序意外冲突。 I've also skipped quite a bit of error checking, not to mention the minor detail that this code doesn't accomplish anything useful. 我也跳过了相当多的错误检查,更不用说这段代码没有完成任何有用的细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM