我希望使用命名共享内存实现 IPC。
要做到这一点,其中一个步骤是使用 CreateFileMapping()获取映射内存对象的句柄。
我完全按照MSDN网站的建议:[{3}}:
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(拒绝访问。)
有没有人有同样的经历,还有一种方法可以解决它吗?我使用MSDN网站作为我的参考,所以我不认为,代码中存在问题。
答案 0 :(得分:11)
看起来你没有足够的权限。
来自MSDN:
在。中创建文件映射对象 来自其他会话的全局命名空间 会话零需要 SeCreateGlobalPrivilege特权。对于 更多信息,请参阅内核对象 命名空间。
...
创建文件映射对象 在全局命名空间中,通过使用 来自会话的CreateFileMapping 会话零以外的是 特权行动。因为这, 一个任意运行的应用程序 远程桌面会话主机(RD 会话主机)服务器会话必须具有 启用SeCreateGlobalPrivilege 以创建文件映射对象 在全局命名空间中成功。 特权检查仅限于 创建文件映射对象,以及 不适用于开放现有的 那些。例如,如果是服务或者 系统创建文件映射对象, 任何会话中运行的任何进程都可以 访问该文件映射对象 只要用户拥有 必要的访问。
答案 1 :(得分:2)
默认情况下,管理员,服务和网络服务具有SeCreateGlobalPrivilege。但是你必须记住,Windows7 / Vista不会以管理员身份运行所有内容。因此,使用“以管理员身份启动”使“全局”工作适用于您的应用程序。如果您正在调试,请以管理员身份启动Visual Studio。
答案 2 :(得分:1)
要创建全局文件映射,您需要SeCreateGlobalPrivilege
权限 - 您有吗?访问被拒绝意味着这肯定是权限问题。
答案 3 :(得分:0)
有关全局命名空间的文档中对终端服务的引用有点误导,因为它意味着如果您遇到异常情况,您只需要担心这一点。
事实上,IIS和系统服务都在会话0中运行,并且第一个/唯一用于登录的用户在会话1中运行 - 因此您必须使用全局命名空间在IIS或服务与普通程序之间进行通信。
答案 4 :(得分: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");