參考資訊:
https://wasm.in/
http://four-f.narod.ru/
https://github.com/steward-fu/ddk
main.pas
unit main; interface uses DDDK; const MAX_THREAD = 3; MAX_SEMA_LIMIT = 2; MAX_SEMA_COUNT = 2; DEV_NAME = '\Device\MyDriver'; SYM_NAME = '\DosDevices\MyDriver'; function _DriverEntry(pMyDriver : PDRIVER_OBJECT; pMyRegistry : PUNICODE_STRING) : NTSTATUS; stdcall; implementation var mySemaphore : KSEMAPHORE; pNextDevice : PDEVICE_OBJECT; procedure MyThread(pParam : Pointer); stdcall; var tt : LARGE_INTEGER; cc : ULONG; begin tt.HighPart := tt.HighPart or -1; tt.LowPart := ULONG(-10000000); DbgPrint('Thread%d, Acquiring Semaphore', [ULONG(pParam)]); KeWaitForSingleObject(@mySemaphore, Executive, KernelMode, FALSE, nil); DbgPrint('Thread%d, Acquired Semaphore', [ULONG(pParam)]); DbgPrint('Thread%d, Sleeping', [ULONG(pParam)]); KeDelayExecutionThread(KernelMode, FALSE, @tt); DbgPrint('Thread%d, Releasing Semaphore', [ULONG(pParam)]); cc := KeReadStateSemaphore(@mySemaphore); if cc < MAX_SEMA_LIMIT then cc := 1 else cc := 0; KeReleaseSemaphore(@mySemaphore, IO_NO_INCREMENT, cc, FALSE); DbgPrint('Thread%d, Released Semaphore', [ULONG(pParam)]); PsTerminateSystemThread(STATUS_SUCCESS); end; procedure Unload(pMyDriver : PDRIVER_OBJECT); stdcall; begin end; function IrpPnp(pMyDevice : PDEVICE_OBJECT; pIrp : PIRP) : NTSTATUS; stdcall; var pStack : PIO_STACK_LOCATION; suSymName : UNICODE_STRING; begin pStack := IoGetCurrentIrpStackLocation(pIrp); if pStack^.MinorFunction = IRP_MN_REMOVE_DEVICE then begin RtlInitUnicodeString(@suSymName, SYM_NAME); IoDetachDevice(pNextDevice); IoDeleteDevice(pMyDevice); IoDeleteSymbolicLink(@suSymName); IoCompleteRequest(pIrp, IO_NO_INCREMENT); Result := STATUS_SUCCESS; end else begin IoSkipCurrentIrpStackLocation(pIrp); Result := IoCallDriver(pNextDevice, pIrp); end; end; function AddDevice(pMyDriver : PDRIVER_OBJECT; pPhyDevice : PDEVICE_OBJECT) : NTSTATUS; stdcall; var suDevName : UNICODE_STRING; suSymName : UNICODE_STRING; pMyDevice : PDEVICE_OBJECT; begin RtlInitUnicodeString(@suDevName, DEV_NAME); RtlInitUnicodeString(@suSymName, SYM_NAME); IoCreateDevice(pMyDriver, 0, @suDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, pMyDevice); pNextDevice := IoAttachDeviceToDeviceStack(pMyDevice, pPhyDevice); pMyDevice^.Flags := pMyDevice^.Flags or DO_BUFFERED_IO; pMyDevice^.Flags := pMyDevice^.Flags and not DO_DEVICE_INITIALIZING; Result := IoCreateSymbolicLink(@suSymName, @suDevName); end; function _DriverEntry(pMyDriver : PDRIVER_OBJECT; pMyRegistry : PUNICODE_STRING) : NTSTATUS; stdcall; var cc : ULONG; hThread : Handle; status : NTSTATUS; begin pMyDriver^.MajorFunction[IRP_MJ_PNP] := @IrpPnp; pMyDriver^.DriverExtension^.AddDevice := @AddDevice; pMyDriver^.DriverUnload := @Unload; KeInitializeSemaphore(@mySemaphore, MAX_SEMA_COUNT, MAX_SEMA_LIMIT); 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.
完成