Windows Driver Model >> Pascal >> Synchronization
Event
參考資訊:
1. Source Code
Event依照其名字就可以知道,它是一種等待事件觸發的同步機制,司徒在此範例使用最基本的用法,由一個Thread設定Event,其餘Thread則是等待該Event被觸發,在Event的用法上,除了可以手動設定(NotificationEvent)之外,也可以設定成自動Reset機制(SynchronizationEvent),詳細部份可以參考MSDN,使用步驟如下:
1. KeInitializeEvent()
2. KeWaitForSingleObject()
3. KeSetEvent()
main.pas
unit main; interface uses DDDK; const MAX_THREAD = 3; DEV_NAME = '\Device\MyDriver'; SYM_NAME = '\DosDevices\MyDriver'; function _DriverEntry(pOurDriver:PDRIVER_OBJECT; pOurRegistry:PUNICODE_STRING):NTSTATUS; stdcall; implementation var myEvent: KEVENT; pNextDevice: PDEVICE_OBJECT; procedure MyThread(pParam:Pointer); stdcall; var tt: LARGE_INTEGER; begin case(ULONG(pParam)) of 0: begin tt.HighPart:= tt.HighPart or -1; tt.LowPart:= ULONG(-10000000); DbgPrint('Thread%d, Sleeping', [ULONG(pParam)]); KeDelayExecutionThread(KernelMode, FALSE, @tt); DbgPrint('Thread%d, SetEvent', [ULONG(pParam)]); KeSetEvent(@myEvent, IO_NO_INCREMENT, FALSE); end; else begin DbgPrint('Thread%d, Waiting', [ULONG(pParam)]); KeWaitForSingleObject(@myEvent, Executive, KernelMode, FALSE, Nil); DbgPrint('Thread%d, Complete', [ULONG(pParam)]); end; end; PsTerminateSystemThread(STATUS_SUCCESS); end; procedure Unload(pOurDriver:PDRIVER_OBJECT); stdcall; begin end; function IrpPnp(pOurDevice:PDEVICE_OBJECT; pIrp:PIRP):NTSTATUS; stdcall; var psk: PIO_STACK_LOCATION; suSymName: UNICODE_STRING; begin psk:= IoGetCurrentIrpStackLocation(pIrp); if psk^.MinorFunction = IRP_MN_REMOVE_DEVICE then begin RtlInitUnicodeString(@suSymName, SYM_NAME); IoDetachDevice(pNextDevice); IoDeleteDevice(pOurDevice); IoDeleteSymbolicLink(@suSymName); end; IoSkipCurrentIrpStackLocation(pIrp); Result:= IoCallDriver(pNextDevice, pIrp); end; function AddDevice(pOurDriver:PDRIVER_OBJECT; pPhyDevice:PDEVICE_OBJECT):NTSTATUS; stdcall; var suDevName: UNICODE_STRING; suSymName: UNICODE_STRING; pOurDevice: PDEVICE_OBJECT; begin RtlInitUnicodeString(@suDevName, DEV_NAME); RtlInitUnicodeString(@suSymName, SYM_NAME); IoCreateDevice(pOurDriver, 0, @suDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, pOurDevice); pNextDevice:= IoAttachDeviceToDeviceStack(pOurDevice, pPhyDevice); pOurDevice^.Flags:= pOurDevice^.Flags or DO_BUFFERED_IO; pOurDevice^.Flags:= pOurDevice^.Flags and not DO_DEVICE_INITIALIZING; Result:= IoCreateSymbolicLink(@suSymName, @suDevName); end; function _DriverEntry(pOurDriver:PDRIVER_OBJECT; pOurRegistry:PUNICODE_STRING):NTSTATUS; stdcall; var cc: ULONG; hThread: Handle; status: NTSTATUS; begin pOurDriver^.MajorFunction[IRP_MJ_PNP]:= @IrpPnp; pOurDriver^.DriverExtension^.AddDevice:=@AddDevice; pOurDriver^.DriverUnload:=@Unload; KeInitializeEvent(@myEvent, NotificationEvent, FALSE); for cc:=0 to (MAX_THREAD-1) do begin status:= PsCreateSystemThread(@hThread, THREAD_ALL_ACCESS, Nil, Handle(-1), Nil, MyThread, Pointer(cc)); if NT_SUCCESS(status) then begin ZwClose(hThread); end; end; Result:=STATUS_SUCCESS; end; end.
DriverEntry()產生3個Thread,第一個Thread延遲一秒後設定Event,其餘Thread做等待的動作
結果