为什么MapViewOfFile失败并出现ERROR_ACCESS_DENIED?

Ant*_*ony 7 c winapi shared-memory

我用WinAPI的MapViewOfFile功能遇到了这种情况.互联网搜索没有发现任何明显的修复,所以我将在这里分享我的问题和解决方案.

请考虑以下代码段:

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());
Run Code Online (Sandbox Code Playgroud)

在一个特定情况下,CreateFileMapping成功返回一个句柄.GetLastError回来了ERROR_ALREADY_EXISTS,所以created == false.现在,MapViewOfFile使用与我传递给的相同大小的调用CreateFileMapping返回NULLGetLastError返回0x05:ERROR_ACCESS_DENIED.该进程以管理员权限运行.

MSDN文档没有真正提到出现这种情况的任何原因.那么为什么CreateFileMapping成功,但MapViewOfFile失败了?

Cro*_*oss 8

在经历了很多苦难之后,我终于找到了导致我的应用程序出现此错误的原因,万一其他人正在努力解决这个问题,问题不在于MapViewOfFile方法,而是使用CreateFileMapping,createFileMapping的大小应该是文件的大小,而不是要读取的元素的大小,如果你不知道大小那么它应该是0,这不适用于MapViewOfFile作为要传递的值,因为size是你想要的块的长度读/写.

您的代码工作方式如下:

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());
Run Code Online (Sandbox Code Playgroud)

只是把它放在这里记录我发现的东西,遗憾的是当你不知道是什么导致它时很难找到这个错误.我希望这可以节省几个小时给别人.


Ant*_*ony 7

我确信有很多理由ERROR_ACCESS_DENIED可以通过电话来发生MapViewOfFile.在我的特殊情况下,这是由于这个size论点.

暗示是这样的事实created == false.它表明该对象"Global\\Object_Name"已经创建.无论出于何种原因,创建调用都会以较小的大小初始化该节.对于看似疏忽的事情CreateFileMapping,即使您要求更大的映射,第二次调用也会愉快地为您提供已存在对象的句柄.

MapViewOfFile现在的调用失败,因为它正在请求一个比实际部分更大的视图.

因此,如果您处于第二次调用MapViewOfFile失败的类似情况,请检查您尝试映射到的大小.

可能是第二个项目正在使用不同的结构对齐进行编译,导致sizeof()操作员确定不同的值,或者某些其他尺寸确定功能的行为不符合预期.