OpenEvent/OpenFileMapping因ERROR_ACCESS_DENIED而失败

Mar*_*ryl 6 c# c++ winapi synchronization memory-mapped-files

我正在开发一个开源.NET程序集(WinSCP .NET程序集),它生成一个本机(C++)应用程序并通过事件和文件映射对象与它通信.

程序集使用Process类生成应用程序,没有特殊设置.程序集创建很少的事件(使用EventWaitHandle)和文件映射(使用PInvoked CreateFileMapping),应用程序使用OpenEvent和"打开"这些事件OpenFileMapping.

在大多数情况下它工作正常.但现在我有一个用户使用Windows Server 2008 R2 64位上的ASPX应用程序的程序集.

在他的情况下OpenEvent,OpenFileMapping返回NULLGetLastError返回ERROR_ACCESS_DENIED.

我试图通过显式授予当前用户对事件对象和应用程序代码的必要权限来改进汇编代码,以便EVENT_ALL_ACCESS根据Microsoft Docs示例仅要求真正需要的访问权限(而不是原始访问权限).它没有帮助.所以我甚至懒得为文件映射对象尝试相同的操作.

创建事件的C#代码是:

EventWaitHandleSecurity security = new EventWaitHandleSecurity();

string user = Environment.UserDomainName + "\\" + Environment.UserName;

EventWaitHandleAccessRule rule;
rule =
    new EventWaitHandleAccessRule(
        user, EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify,
        AccessControlType.Allow);
security.AddAccessRule(rule);
rule =
    new EventWaitHandleAccessRule(
        user, EventWaitHandleRights.ChangePermissions, AccessControlType.Deny);
security.AddAccessRule(rule);

new EventWaitHandle(
    false, EventResetMode.AutoReset, name, out createdNew, security);
Run Code Online (Sandbox Code Playgroud)

"打开"事件的C++代码是:

OpenEvent(EVENT_MODIFY_STATE, false, name);
Run Code Online (Sandbox Code Playgroud)

(对于其他事件,访问级别SYNCHRONIZE取决于需要).

有没有人知道是什么原因导致OpenEvent(或CreateFileMapping)中的"访问被拒绝"错误?

小智 1

我的猜测是,该事件是由匿名用户或登录用户创建的,具体取决于网站的设置方式。但子流程是由基本流程用户启动的。可以通过使用进程监视器并查看事件句柄的 acl 来检查创建者是谁。然后查看子进程,看看它以谁的身份运行。
如果是这种情况,那么您可以更新事件的 acl 以包含基本流程。除此之外,您可能仍然需要添加“global”前缀,以确保该事件可以跨用户边界使用。