系统错误 0x5:CreateFileMapping()

Posted

技术标签:

【中文标题】系统错误 0x5:CreateFileMapping()【英文标题】:System Error 0x5: CreateFileMapping() 【发布时间】:2011-04-29 06:55:09 【问题描述】:

我希望使用命名共享内存实现IPC。

为此,其中一个步骤是使用 CreateFileMapping() 获取 映射内存对象 的句柄。

我完全按照 MSDN 网站的建议:http://msdn.microsoft.com/en-us/library/aa366551(v=VS.85).aspx:

hFileMappingHandle = CreateFileMapping
    (
        INVALID_HANDLE_VALUE,      // use paging file
        NULL,                      // default security 
        PAGE_READWRITE,            // read/write access
        0,            // maximum object size (high-order DWORD) 
        256,            // maximum object size (low-order DWORD)  
        "Global\\MyFileMappingObject"          // name of mapping object
    ); 
DWORD dwError = GetLastError();

但是,返回的句柄始终是0x0,返回的系统错误代码是:0x5 (Access Denied.)

仅需要命名内存共享(不是文件共享)。 Windows 7 x64 位操作系统 管理员的可用用户权限 开发的应用程序:64 位插件应用程序(.dll)

有没有人有同样的经历,求解决方法?我使用 MSDN 站点作为参考,所以我不认为代码有问题。

【问题讨论】:

不确定是不是这个原因,但你不需要将最大对象大小设置为内存页的倍数(4096字节)吗? 嗨 Eugene,不,问题是我没有设置 SeCreateGlobalPriviledge。 【参考方案1】:

这是一个非常古老的问题,标记为已回答。但是通过相同的 MSDN 文章并基于它构建示例,我能够在没有任何特殊权限的情况下成功。

只需去掉名称中的“Global\”部分即可。令人惊讶的是,对于信号量和事件,它不能以这种方式工作,您将得到“0x2 ERROR_FILE_NOT_FOUND”。但是对于内存映射共享内存它工作得很好。我能够在服务器上创建读/写共享内存,并在客户端上打开它。

【讨论】:

【参考方案2】:

使用安全属性和 DACL。 示例:

ZeroMemory(&attributes, sizeof(attributes));
attributes.nLength = sizeof(attributes);
ConvertStringSecurityDescriptorToSecurityDescriptorA(
            "D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GWGR;;;IU)",
            SDDL_REVISION_1,
            &attributes.lpSecurityDescriptor,
            NULL);
hMapObject = CreateFileMappingA(
            INVALID_HANDLE_VALUE,
            &attributes,
            PAGE_READWRITE,
            0,
            1024,
            "mySMobject");

【讨论】:

【参考方案3】:

关于全局命名空间的文档中对终端服务的引用有点误导,因为这意味着您只有在遇到异常情况时才需要担心这一点。

事实上,IIS 和系统服务都在会话 0 中运行,而第一个/唯一登录的用户在会话 1 中运行 - 因此您必须使用全局命名空间在 IIS 或服务与普通程序之间进行通信。

【讨论】:

【参考方案4】:

默认情况下,管理员、服务和网络服务具有 SeCreateGlobalPrivilege。不过,您必须记住,Windows7/Vista 不会以管理员身份运行所有内容。因此,使用“以管理员身份启动”使“全局\”适用于您的应用程序。如果您正在调试,请以管理员身份启动 Visual Studio。

【讨论】:

非常感谢!默认情况下,Windows 10 下的 Visual Studio 不是管理员。那是我的问题。 如果我们想为没有管理员权限的用户使用 CreateFileMapping 怎么办?【参考方案5】:

要创建全局文件映射,您需要SeCreateGlobalPrivilege 权限 - 您有吗?拒绝访问意味着这是一个权限问题,当然。

【讨论】:

嗨史蒂夫,这是我的问题。谢谢你。我现在以不同的方式解决了这个问题,但是如果我想设置权限,可以在我的应用程序中以编程方式完成吗? 您可以使用AdjustTokenPrivileges 执行此操作,如下所示:msdn.microsoft.com/en-us/library/aa446619(v=VS.85).aspx。令牌句柄来自OpenProcessToken,必须使用(至少)TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY 调用【参考方案6】:

您似乎没有足够的权限。

来自 MSDN:

在 来自会话其他的全局命名空间 比会话零需要 SeCreateGlobalPrivilege 特权。为了 更多信息,请参阅内核对象 命名空间。

...

文件映射对象的创建 在全局命名空间中,通过使用 CreateFileMapping,来自会话 除了会话零以外 特权操作。因为这, 任意运行的应用程序 远程桌面会话主机(RD 会话主机)服务器会话必须有 SeCreateGlobalPrivilege 在中启用 为了创建一个文件映射对象 在全局命名空间中成功。 权限检查仅限于 创建文件映射对象,以及 不适用于打开现有的 那些。例如,如果一个服务或 系统创建一个文件映射对象, 在任何会话中运行的任何进程都可以 访问该文件映射对象 前提是用户拥有 必要的访问权限。

【讨论】:

嗨,尤金,这正是我的问题。我从映射对象的名称中删除了前缀“Global\\”,显然这解决了问题。我不打算处理终端服务,因此该解决方案现在应该可以接受。我阅读了有关 SeCreateGlobalPriviledge 的文档,但我不清楚是否可以由应用程序本身分配权限,或者我是否必须从 Windows 资源管理器中手动调整权限? 权限由启动应用程序的用户帐户定义。您可以尝试使用此处讨论的 AdjustTokenPrivilege 函数:delphi.about.com/b/2008/09/26/…,但这并不能保证结果。一般来说,尝试搜索SeCreateGlobalPrivilege,结果包含一些有趣的信息来源

以上是关于系统错误 0x5:CreateFileMapping()的主要内容,如果未能解决你的问题,请参考以下文章

Maven nexus 安装nexus : wrapper | OpenSCManager failed - 拒绝访问。 (0x5)

GlobalAddAtom() 在 Win7 上返回 0 和 GetLastError = 0x5,适用于 XP

无法注册DLL/OCX:regsvr32 failed with exit code 0x5

win10下将Activemq安装为系统服务

未初始化的读取和不可寻址的访问错误

Mac配置gdb的一些问题