Mar*_* Ba 5 windows winapi manualresetevent autoresetevent windows-kernel
Windows允许创建(命名)事件对象.
一个事件(Windows中的同步原语)可以是自动重置类型(在这种情况下你可以说它是一种信号量)或者它可以是手动重置类型,在这种情况下它会保持设置直到有人重置它.
现在,从文档的CreateEvent,OpenEvent,SetEvent的,等它似乎是没有办法确定,一旦事件已经创建,无论是自动复位或maual复位.
我处于这种情况,其中一个进程创建一个命名的事件,第二个进程必须对此事件进行操作(它将传递名称,然后打开事件并最终发出信号).由于事件应始终是手动重置事件,因为整个事情都有意义,我本来希望在第二个过程中添加一个检查以确保它是一个手动重置事件.有没有办法检查这个?
(是的,在我的情况下,它更像是一个很好的东西,因为如果任何代码创建一个自动重置事件然后将它传递给这个过程,那么它将是一个错误.但是错误发生了,如果发生了错误,那就更好了.我可以发现它们.)
没有记录的方法可以做到这一点,但如果你冒险进入无证的土地,实际上并不难.(出于您的目的,这应该没问题,因为它不会真正影响您的程序的功能.)
您需要做的第一件事是弄清楚给您的句柄是否是一个事件.你使用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 );
Run Code Online (Sandbox Code Playgroud)
这将为您提供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,
&length );
Run Code Online (Sandbox Code Playgroud)
现在,只需检查信息中的EventType字段即可."NotificationEvent"表示手动复位,"SynchronizationEvent"表示自动复位.
如果你想知道我如何计算出第二部分,我没有.信息来自这里:http://undocumented.ntinternals.net/.请负责任地使用!