2013-04-16 15 views
6

Mi sono imbattuto in questa situazione con la funzione MapViewOfFile di WinAPI. Una ricerca su Internet non ha evidenziato alcuna correzione apparente, quindi condividerò qui il mio problema e la mia soluzione.Perché MapViewOfFile non riesce con ERROR_ACCESS_DENIED?

Si consideri il seguente frammento di codice:

const char *name = "Global\\Object_Name"; 
unsigned long size = get_object_size(); 

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE, 
            NULL, 
            PAGE_READWRITE, 
            0, 
            size, 
            name); 

if (!handle || handle == INVALID_HANDLE_VALUE) 
    exit(GetLastError()); 

bool created = GetLastError() == 0; 

void *block = MapViewOfFile(handle, 
          FILE_MAP_ALL_ACCESS, 
          0, 
          0, 
          size); 

if (block == NULL) 
    exit(GetLastError()); 

In un caso particolare, CreateFileMapping stava tornando con successo una maniglia. GetLastError restituiva ERROR_ALREADY_EXISTS, quindi created == false. Ora, la chiamata a MapViewOfFile, utilizzando la stessa dimensione che ho passato a CreateFileMapping, restituisce NULL e GetLastError restituisce 0x05: ERROR_ACCESS_DENIED. Il processo era in esecuzione con i privilegi di amministratore.

La documentazione MSDN non indica in realtà alcun motivo per cui si verificherebbe questa situazione. Quindi, perché CreateFileMapping ha esito positivo, ma MapViewOfFile non riesce?

risposta

7

Sono sicuro che ci sono molti motivi per cui ERROR_ACCESS_DENIED potrebbe verificarsi da una chiamata a MapViewOfFile. Nella mia situazione particolare, era dovuto all'argomento size.

Il suggerimento è nel fatto che created == false. Mostra che l'oggetto "Global\\Object_Name" è già stato creato. Per qualsiasi motivo, la chiamata di creazione ha inizializzato la sezione con una dimensione più piccola. Per quello che sembra una svista, la seconda chiamata a CreateFileMapping ti darà felicemente un handle per l'oggetto già esistente, anche se hai chiesto una mappatura più grande.

La chiamata a MapViewOfFile non riesce, perché richiede una vista più grande della sezione effettiva.

Quindi, se ci si trova in una situazione simile in cui la seconda chiamata a MapViewOfFile non riesce, controllare la dimensione che si sta tentando di mappare.

Potrebbe essere che il secondo progetto si stia compilando con un diverso allineamento della struttura, risultando nell'operatore sizeof() che determina valori diversi, o qualche altra funzione che determina la dimensione non si comporta come previsto.

6

Dopo un sacco di sofferenza, ho finalmente trovato ciò che stava causando questo errore nella mia applicazione, nel caso in cui qualcun altro stia lottando con lo stesso, il problema non è con il metodo MapViewOfFile, ma con CreateFileMapping, la dimensione del createFileMapping dovrebbe essere la dimensione del file, non la dimensione dell'elemento da leggere, se non si conosce la dimensione allora dovrebbe essere 0, questo non si applica a MapViewOfFile come valore da passare come dimensione è la lunghezza di il blocco che vuoi leggere/scrivere.

tuo lavoro codice sarà simile a questa:

const char *name = "Global\\Object_Name"; 
unsigned long size = get_object_size(); 

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE, 
            NULL, 
            PAGE_READWRITE, 
            0, 
            0, 
            name); 

if (!handle || handle == INVALID_HANDLE_VALUE) 
    exit(GetLastError()); 

bool created = GetLastError() == 0; 

void *block = MapViewOfFile(handle, 
          FILE_MAP_ALL_ACCESS, 
          0, 
          0, 
          size); 

if (block == NULL) 
    exit(GetLastError()); 

Un solo mettere questo qui per documentare quello che ho trovato, purtroppo, è difficile per la ricerca di questo errore quando non si sa quali sono le cause. Spero che questo salvi un paio d'ore a qualcun altro.

Problemi correlati