Frage

Ich versuche MapViewOfFile in einem 64-Bit-Prozess auf einer Datei zu verwenden, die bereits in dem Speicher eines anderen 32-Bit-Prozesses abgebildet wird. Es schlägt fehl, und gibt mir ein „Zugriff verweigert“ -Fehler. Ist das eine bekannte Windows-Einschränkung oder bin ich etwas falsch? Gleicher Code funktioniert gut mit 2 32bit Prozessen.

Der Code Art sieht wie folgt aus:

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); 
War es hilfreich?

Lösung

Wenn Sie Createfile in der 32-Bit-Anwendung aufrufen, vorbei sind Sie 0 für den Austausch Parameter, was bedeutet, keine gemeinsame Nutzung erlaubt ist. Ändern dass FILE_SHARE_READ | FiLE_SHARE_WRITE wäre wahrscheinlich ein Schritt in die richtige Richtung sein.

Edit: Ich habe gepeitscht zusammen ein Demo, das funktioniert (zumindest für mich):

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

Jede Kombination von 32- oder 64-Bit-Programmen scheint zu funktionieren.

Edit2: Beachten Sie jedoch, dass dies rein Demo-Level-Code. Nur zum Beispiel, sollte der Name jeden gemeinsamen Objekt normalerweise eine GUID-Zeichenfolge enthält gegen zufällige Kollision mit anderen Programmen zu gewährleisten. Ich habe übersprungen auch einiges an Fehlerprüfung, nicht das kleinste Detail zu erwähnen, dass dieser Code erreicht nichts nützlich.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top