2013-04-16 3 views
6

Ich bin mit WinAPIs MapViewOfFile-Funktion auf diese Situation gestoßen. Eine Internetsuche hat keine offensichtlichen Korrekturen ergeben, deshalb werde ich hier mein Problem und meine Lösung teilen.Warum schlägt MapViewOfFile mit ERROR_ACCESS_DENIED fehl?

Betrachten Sie das folgende Snippet:

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 einem besonderen Fall CreateFileMapping erfolgreich einen Griff zurückkehrte. GetLastError wurde ERROR_ALREADY_EXISTS zurückgegeben, also created == false. Nun gibt der Aufruf an MapViewOfFile unter Verwendung derselben Größe, die ich an CreateFileMapping übergab, NULL zurück und GetLastError gibt 0x05 zurück: ERROR_ACCESS_DENIED. Der Prozess wurde mit Administratorrechten ausgeführt.

Die MSDN-Dokumentation erwähnt keinen Grund wirklich, warum diese Situation auftreten würde. Warum funktioniert CreateFileMapping erfolgreich, aber MapViewOfFile scheitern?

Antwort

7

Ich bin sicher, es gibt viele Gründe, warum ERROR_ACCESS_DENIED von einem Anruf an MapViewOfFile auftreten konnte. In meiner besonderen Situation war es aufgrund der size Argument.

Der Hinweis ist in der Tatsache, dass created == false. Es zeigt, dass das Objekt "Global\\Object_Name" bereits erstellt wurde. Aus irgendeinem Grund initialisierte der Erstellungsanruf den Abschnitt mit einer kleineren Größe. Für den Fall, der wie ein Versehen aussieht, wird der zweite Aufruf an CreateFileMapping Ihnen gerne ein Handle für das bereits vorhandene Objekt geben, auch wenn Sie nach einem größeren Mapping gefragt haben.

Der Aufruf an MapViewOfFile schlägt jetzt fehl, da es eine Ansicht anfordert, die größer als der tatsächliche Abschnitt ist.

Wenn Sie also in einer ähnlichen Situation sind, in der der zweite Anruf bei MapViewOfFile fehlschlägt, überprüfen Sie die Größe, die Sie zuordnen möchten.

Es könnte sein, dass das zweite Projekt mit einer anderen Strukturausrichtung kompiliert wird, was dazu führt, dass der Operator sizeof() andere Werte bestimmt, oder eine andere größenbestimmende Funktion verhält sich nicht wie erwartet.

6

Nach einer Menge leiden, fand ich schließlich, was diesen Fehler in meiner Anwendung verursacht, falls jemand anderes mit dem gleichen zu kämpfen hat, ist das Problem nicht mit der MapViewOfFile-Methode, sondern mit dem CreateFileMapping, die Größe des createFileMapping sollte die Größe der Datei und nicht die Größe des zu lesenden Elements sein. Wenn Sie die Größe nicht kennen, dann sollte sie 0 sein. Dies gilt nicht für MapViewOfFile, da der zu übergebende Wert die Länge von der Block, den Sie lesen/schreiben möchten.

Ihr Code Arbeits wird wie folgt aussehen:

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

A nur darum, diese hier zu dokumentieren, was ich fand, ist leider hart für diesen Fehler zu suchen, wenn Sie nicht wissen, was es verursacht. Ich hoffe, das spart ein paar Stunden für jemand anderen.