2013-04-16 109 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が正常にハンドルを返していました:

は、次のスニペットを考えてみましょう。 GetLastErrorERROR_ALREADY_EXISTSを返すので、created == falseです。今、に渡したのと同じサイズを使用してMapViewOfFileを呼び出すと、NULLGetLastErrorが返されます。0x05ERROR_ACCESS_DENIEDが返されます。プロセスは管理者権限で実行されていました。

MSDNのドキュメントでは、このような状況が発生する理由は実際には言及されていません。だからCreateFileMappingは成功しますが、MapViewOfFileは失敗しますか?

答えて

7

ERROR_ACCESS_DENIEDMapViewOfFileへの呼び出しから発生する可能性がある理由はたくさんあります。私の特別な状況では、それはsize引数のためでした。

ヒントは、実際にはcreated == falseです。これはオブジェクト"Global\\Object_Name"が既に作成されていることを示しています。何らかの理由で、呼び出しを作成すると、サイズの小さいセクションが初期化されました。見落としのように見えますが、CreateFileMappingへの2回目の呼び出しは、より大きなマッピングを依頼したとしても、既に存在するオブジェクトへのハンドルを提供します。

MapViewOfFileの呼び出しは、実際のセクションよりも大きなビューを要求しているため、失敗します。

したがって、MapViewOfFileへの2回目の呼び出しに失敗した同様の状況にある場合は、マップしようとしているサイズを確認してください。

sizeof()演算子が異なる値を決定する結果になるか、または他のサイズ決定関数が期待どおりに動作しないという結果になることがあります。

6

多くの苦労の末、アプリケーションでこのエラーの原因となっていたものが見つかりました。他の誰かが同じ問題を抱えている場合、問題はMapViewOfFileメソッドではなく、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()); 

Aはちょうど私が見つけたもの文書化するためにここにこれを入れて、残念ながら、このエラーを検索するのは難しいです。私はこれが他の人に2時間を節約することを願っています。

関連する問題