在映射文件上调用VirtualProtect

时间:2011-03-18 00:49:09

标签: c windows winapi

我正在使用CreateFileMapping和MapViewOfFile函数将文件映射到内存中。在某一点之后,我调用VirtualProtect将其保护从只读更改为读写。此调用失败,GetLastError提供ERROR_INVALID_PARAMETER。

以下是我的代码的简化版本,用于演示此问题。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main() {
    HANDLE fd, md;
    char *addr;
    DWORD old;
    BOOL ok;

    fd = CreateFile("filename", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    md = CreateFileMapping(fd, NULL, PAGE_READWRITE, 0, 100, NULL);
    addr = MapViewOfFile(md, FILE_MAP_READ, 0, 0, 100);
    ok = VirtualProtect(addr, 100, PAGE_READWRITE, &old);
    if (!ok) {
        // we fall into this if block
        DWORD err = GetLastError();
        // this outputs "error protecting: 87"
        printf("error protecting: %u\n", err);
        return 1;
    }
    UnmapViewOfFile(addr);
    CloseHandle(md);
    CloseHandle(fd);
    return 0;
}

我在这里做错了什么?我不允许在包含映射文件的区域上调用VirtualProtect吗?

3 个答案:

答案 0 :(得分:5)

首先使用FILE_MAP_READ |创建视图FILE_MAP_WRITE并使用PAGE_READONLY保护。现在您可以在以后轻松制作PAGE_READWRITE:

addr = MapViewOfFile(md, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 100);
ok = VirtualProtect(addr, 100, PAGE_READONLY, &old);
//...
ok = VirtualProtect(addr, 100, PAGE_READWRITE, &old);

答案 1 :(得分:3)

您的代码中发生的情况是VirtualProtectEx(由您的VirtualProtect调用)失败,错误为 STATUS_SECTION_PROTECTION (0xC000004E) - “某个部分的视图指定与初始视图“的保护不兼容的保护,这似乎是您通过创建具有更严格保护的部分视图(FILE_MAP_READ)所做的事情。

这个主题似乎没有详细记录,所以我认为你最好只遵循汉斯的建议。

答案 2 :(得分:1)

根据http://msdn.microsoft.com/en-us/library/aa366556(v=vs.85).aspx,这应该是合法的。根据VirtualProtect文档,新标志必须与“VirtualAlloc”标志兼容 - 如果转移到“MapViewOfFile”标志,我怀疑你可以收紧但不放松保护。尝试映射readwrite并将保护更改为readonly。