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做等待的動作

結果


返回上一頁