2013-04-16 221 views
6

我在WinAPI的MapViewOfFile函數中遇到過這種情況。互聯網搜索沒有出現任何明顯的修復,所以我會在這裏分享我的問題和解決方案。爲什麼MapViewOfFile會因ERROR_ACCESS_DENIED失敗?

考慮下面的代碼片段:

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

在一個特定的情況下,CreateFileMapping成功返回的句柄。 GetLastError正在返回ERROR_ALREADY_EXISTS,所以created == false。現在,調用MapViewOfFile,使用我傳遞給CreateFileMapping相同的大小,返回NULLGetLastError回報0x05ERROR_ACCESS_DENIED。該進程以管理員權限運行。

MSDN文檔並沒有真正提到這種情況發生的原因。那麼爲什麼CreateFileMapping成功,但MapViewOfFile失敗?

回答

7

我敢肯定有原因ERROR_ACCESS_DENIED可以從通話發生MapViewOfFile原因是多方面的。在我的特殊情況下,這是由於size的說法。

提示是在created == false。它顯示對象"Global\\Object_Name"已經創建。無論出於何種原因,創建調用都會以較小的尺寸初始化該部分。對於看起來像是疏忽的事情,即使您要求更大的映射,第二次打電話給CreateFileMapping也會很樂意給您處理已存在的對象。

MapViewOfFile調用現在失敗,因爲它要求一種觀點認爲比實際更大的部分。

所以,如果你在類似的情況下,以MapViewOfFile第二呼叫失敗的時候,請檢查你試圖映射到大小。

可能是由於第二個項目使用不同的結構對齊方式進行編譯,導致sizeof()運算符確定不同的值,或者某些其他尺寸確定函數的行爲不如預期。

6

經過很多苦頭之後,我終於找到了在我的應用程序中導致這個錯誤的原因,以防其他人同樣在掙扎,問題不在於MapViewOfFile方法,而是在於CreateFileMapping, createFileMapping應該是文件的大小,而不是要讀取的元素的大小,如果您不知道大小,那麼它應該是0,這不適用於MapViewOfFile,因爲要傳遞的值的大小是您想要讀/寫的塊。

您的代碼工作將是這樣的:

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

一個只是把這個在這裏記錄我發現了什麼,不幸的是,很難尋找這個錯誤,當你不知道是什麼原因造成的。我希望這可以爲其他人節省幾個小時。

相關問題