17

我希望使用命名共享内存来实现 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 站点作为参考,所以我不认为代码中存在问题。

4

6 回答 6

13

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

来自 MSDN:

从会话零以外的会话在全局命名空间中创建文件映射对象需要 SeCreateGlobalPrivilege 权限。有关详细信息,请参阅内核对象命名空间。

...

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

于 2010-10-22T17:06:25.753 回答
2

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

于 2011-08-15T11:23:09.120 回答
1

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

于 2010-10-22T17:06:39.063 回答
0

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

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

于 2014-10-24T12:47:48.840 回答
0

使用安全属性和 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");
于 2021-08-05T10:27:45.623 回答
0

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

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

于 2021-11-04T22:13:51.503 回答