Win32 API 事件 - 它在跨不同进程的访问方面都有哪些限制?

Posted

技术标签:

【中文标题】Win32 API 事件 - 它在跨不同进程的访问方面都有哪些限制?【英文标题】:Win32 API Events- What are its limitations in terms of access across different processes?Win32 API 事件 - 它在跨不同进程的访问方面有哪些限制? 【发布时间】:2015-03-26 18:43:06 【问题描述】:

所以,我有一个应用程序连接到一个库,该库处理不同线程中的许多不同任务。

在库的一个线程中,不是库的主线程,一个事件被创建。

但是,当我尝试从使用库本身的应用程序中打开事件时,我总是收到无效的HANDLE

该事件不使用私有命名空间,也没有为 Win32 的内核对象命名空间指定任何选项 - 这是非常默认的。

事实上,这是用于在库线程中创建事件的函数:

CreateEventA(NULL, FALSE, FALSE, eventName);

稍后在同一线程中调用以打开具有以下参数的事件是有效的:

OpenEventA(EVENT_ALL_ACCESS, FALSE, eventName); // returns event without issue

此外,根据MSDN,以下是here:

The creating thread can also specify a name for the event object. Threads in other processes can open a handle to an existing event object by specifying its name in a call to the OpenEvent function.

显然这也不是错误,因为重复了相同的要点here:

The process that creates an object can use the handle returned by the creation function (CreateEvent, CreateMutex, CreateSemaphore, or CreateWaitableTimer).Other processes can open a handle to the object by using its name, or through inheritance or duplication.

我浏览了 MSDN,找到了一些明确说明情况并非如此的内容,但我还没有找到任何内容。

我还可以声明,当在应用程序中查询事件时,我在库的线程中看到了活动的事件——据我所知,这排除了它根本没有被创建的可能性。

有人能解释一下为什么当通过应用程序查询时,事件从 OpenEvent 返回 NULL 吗?

更新

回应@FrerichRaabe:

返回的错误码是2,或者ERROR_FILE_NOT_FOUND

@IInspectable:

有趣;我忘了提到我实际上已经尝试过为事件使用全局命名空间,这显然也不起作用。与上述相同的错误也是返回的内容......

【问题讨论】:

通过Access Control Lists控制访问。除此之外,可以从同一会话中运行的任何进程访问事件。如果事件是在全局命名空间中创建的,则可以从系统中运行的任何进程访问它。 那么,GetLastError()OpenEvent() 返回 null 之后返回什么? 我已经更新了帖子以响应您的两位 cmets。 @IInspectable 我一定会查看 ACL 信息,谢谢。 几乎没有理由认为错误代码不准确。简单的解释是该事件根本不存在。因为您试图在它创建之前打开它,这是线程代码很常见的错误。 【参考方案1】:

您的问题是由 2 个不幸的决定引起的:使用名称中包含非 ASCII 字符的事件,以及调用 API 的 ANSI 版本(由结尾的 A 表示)。

由于系统内部使用 Unicode,所以无论何时调用 ANSI API,字符串参数都会转换为 Unicode。非 ASCII 字符的转换由线程的当前语言环境控制。这解释了为什么在同一线程上调用 OpenEventA 成功,而在另一个线程上调用失败。

要解决此问题,请将对 ANSI API 的调用替换为它们各自的 Unicode 版本 CreateEventWOpenEventW

【讨论】:

【参考方案2】:

它可能是 EVENT_ALL_ACCESS 标志。你真的需要吗? 通常“SYNCHRONIZE | EVENT_MODIFY_STATE”对于事件来说就足够了。

尝试一下并告诉我们。

【讨论】:

那也没用。我还单独尝试了 SYNCHRONIZE 以及 READ_CONTROL。都没有用。 一个进程运行提升而另一个未提升? 错误代码 2 (FILE_NOT_FOUND) 表示未找到该名称。您确定两个调用之间的事件名称相同吗?您没有混淆 ANSI 和 Unicode,是吗? (我注意到您正在使用这些天不寻常的 ANSI API)。另一件事:第一个进程是否运行提升但第二个没有? (我认为您会为此获得 ACCESS_DENIED,但可能不会)

以上是关于Win32 API 事件 - 它在跨不同进程的访问方面都有哪些限制?的主要内容,如果未能解决你的问题,请参考以下文章

线程局部存储的Win32实现

发送/捕获 SIGTERM 的 Win32 API 模拟

等到另一个进程锁定然后解锁 Win32 互斥锁

Delphi遍历进程-Win32API

第二章--Win32程序运行原理 (部分概念及代码讲解)

利用win32 api实现进程通信---通过剪切板