Pregunta

Estoy tratando de utilizar MapViewOfFile en un proceso de 64 bits en un archivo que ya está asignado a la memoria de otro proceso de 32 bits. Se produce un error y me da un "acceso denegado". ¿Es esta una conocida limitación de Windows o estoy haciendo algo mal? Mismo código funciona bien con 2 procesos de 32 bits.

El código de tipo de aspecto siguiente:

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); 
¿Fue útil?

Solución

Cuando se llama a CreateFile en la aplicación de 32 bits, estás pasando 0 para el parámetro de uso compartido, lo que significa que no se permite el uso compartido. Cambiante que a FILE_SHARE_READ | FiLE_SHARE_WRITE probablemente sería un paso en la dirección correcta.

Edit: Acabo de batida juntos una demo que funciona (al menos para mí):

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

Cualquier combinación de 32 o 64 bits ejecutables parece funcionar bien.

Edit2: Tenga en cuenta, sin embargo, que esto es puramente código de nivel de demostración. Sólo por ejemplo, el nombre de cada objeto compartido debe contener normalmente un GUID cuerdas para asegurar contra la colisión accidental con otros programas. También he saltado un poco de comprobación de errores, por no mencionar el pequeño detalle de que este código no se logra nada útil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top