加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

如何判断Windows内核事件对象是自动重置还是手动重置?

发布时间:2020-12-14 01:56:15 所属栏目:Windows 来源:网络整理
导读:Windows允许创建(命名) Event objects. 一个事件(Windows中的同步原语)可以是自动重置类型(在这种情况下是could say it’s kind of a semaphore),也可以是手动重置类型,在这种情况下,它会一直保持设置,直到有人重置它为止. 现在,从docs CreateEvent,OpenEven
Windows允许创建(命名) Event objects.

一个事件(Windows中的同步原语)可以是自动重置类型(在这种情况下是could say it’s kind of a semaphore),也可以是手动重置类型,在这种情况下,它会一直保持设置,直到有人重置它为止.

现在,从docs CreateEvent,OpenEvent,SetEvent等,一旦事件被创建,似乎无法确定它是自动重置还是重置.

我处于这种情况,其中一个进程创建一个命名的事件,第二个进程必须对此事件进行操作(它将传递名称,然后打开事件并最终发出信号).由于事件应始终是手动重置事件,因为整个事情都有意义,我本来希望在第二个过程中添加一个检查以确保它是一个手动重置事件.有没有办法检查这个?

(是的,在我的情况下,它更像是一个很好的东西,因为如果任何代码创建一个自动重置事件然后将它传递给这个过程,那么它将是一个错误.但是错误发生了,如果发生了错误,那就更好了.我可以发现它们.)

解决方法

没有记录的方法可以做到这一点,但如果你冒险进入无证的土地,实际上并不难. (出于您的目的,这应该没问题,因为它不会真正影响您的程序的功能.)

您需要做的第一件事是弄清楚给您的句柄是否是一个事件.你使用NtQueryObject.此功能记录在此处:http://msdn.microsoft.com/en-us/library/bb432383(v=vs.85).aspx.它附带了本机API的通常附带条款,它可能会在不另行通知的情况下消失或更改.部分示例:

#include <winternl.h>

typedef NTSTATUS (NTAPI * PFN_NtQueryObject)(
    HANDLE Handle,OBJECT_INFORMATION_CLASS ObjectInformationClass,PVOID ObjectInformation,ULONG ObjectInformationLength,PULONG ReturnLength );

HMODULE ntdll = GetModuleHandle( L"ntdll.dll" );

auto NtQueryObject = (PFN_NtQueryObject)GetProcAddress( ntdll,"NtQueryObject" );

NTSTATUS result = NtQueryObject(
    eventHandle,ObjectTypeInformation,buffer,length,&length );

这将为您提供PUBLIC_OBJECT_TYPE_INFORMATION结构.如果对象实际上是一个事件,则TypeName字段将为“Event”.

接下来,调用NtQueryEvent来获取事件的类型.所有这些都完全没有记录.

typedef enum _EVENT_INFORMATION_CLASS {
    EventBasicInformation
} EVENT_INFORMATION_CLASS,*PEVENT_INFORMATION_CLASS;

typedef enum _EVENT_TYPE {
    NotificationEvent,SynchronizationEvent
} EVENT_TYPE,*PEVENT_TYPE;

typedef struct _EVENT_BASIC_INFORMATION {
  EVENT_TYPE              EventType;
  LONG                    EventState;
} EVENT_BASIC_INFORMATION,*PEVENT_BASIC_INFORMATION;

typedef NTSTATUS (NTAPI * PFN_NtQueryEvent)(
    HANDLE EventHandle,EVENT_INFORMATION_CLASS EventInformationClass,PVOID EventInformation,ULONG EventInformationLength,PULONG ReturnLength );

auto NtQueryEvent = (PFN_NtQueryEvent)GetProcAddress( ntdll,"NtQueryEvent" );

EVENT_BASIC_INFORMATION info;
ULONG length = sizeof( info );

NTSTATUS result = NtQueryEvent(
    eventHandle,EventBasicInformation,&info,&length );

现在,只需检查信息中的EventType字段即可. “NotificationEvent”表示手动复位,“SynchronizationEvent”表示自动复位.

如果你想知道我如何计算出第二部分,我没有.信息来自:http://undocumented.ntinternals.net/.请负责任地使用!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读