问题 系统错误0x5:CreateFileMapping()


我希望实施 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(访问被拒绝。)

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

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


2744
2017-10-22 17:00


起源

不确定是什么原因,但是你不需要将最大对象大小设置为内存页面的倍数(4096字节)吗? - Eugene Mayevski 'Allied Bits
嗨尤金,不,问题是我没有设置SeCreateGlobalPriviledge。 - Bunkai.Satori


答案:


看起来你没有足够的权限。

来自MSDN:

在中创建文件映射对象   来自其他会话的全局命名空间   会话零需要   SeCreateGlobalPrivilege特权。对于   更多信息,请参阅内核对象   命名空间。

...

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


8
2017-10-22 17:06



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


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


2
2017-08-15 11:23



非常感谢你!默认情况下,Windows 10下的Visual Studio不是管理员。那是我的问题。 - Gabe Halsmer


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


1
2017-10-22 17:06



嗨,史蒂夫,这是我的问题。谢谢。我现在以不同的方式解决了这个问题,但如果我想设置权限,那么可以从我的应用程序中以编程方式完成吗? - Bunkai.Satori
你可以这样做 AdjustTokenPrivileges 如下图所示: msdn.microsoft.com/en-us/library/aa446619(v=VS.85).aspx。令牌句柄来自 OpenProcessToken 必须使用(至少)调用 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY - Steve Townsend


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

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


0
2017-10-24 12:47