Steward
分享是一種喜悅、更是一種幸福
驅動程式 - Kernel Mode Driver Framework (KMDF) - 使用範例 - Pascal (DDDK) - PNP - Use DPC Timer
參考資訊:
https://wasm.in/
http://four-f.narod.ru/
https://github.com/steward-fu/ddk
main.pas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | unit main ; interface uses DDDK ; const DEV_NAME = '\Device\MyDriver' ; SYM_NAME = '\DosDevices\MyDriver' ; IOCTL_START = ( FILE_DEVICE_UNKNOWN shl 16 ) or ( FILE_ANY_ACCESS shl 14 ) or ( $800 shl 2 ) or ( METHOD_BUFFERED ); IOCTL_STOP = ( FILE_DEVICE_UNKNOWN shl 16 ) or ( FILE_ANY_ACCESS shl 14 ) or ( $801 shl 2 ) or ( METHOD_BUFFERED ); function __DriverEntry (pMyDriver : PDRIVER_OBJECT ; pMyRegistry : PUNICODE_STRING ) : NTSTATUS ; stdcall ; implementation var cnt : ULONG ; dpc : TKDpc ; obj : KTIMER ; pDevice : PDEVICE_OBJECT ; procedure OnTimer (Dpc : KDPC ; DeferredContext : Pointer ; SystemArgument1 : Pointer ; SystemArgument2 : Pointer ); stdcall ; begin cnt := cnt + 1 ; DbgPrint ( 'DpcTimer: %d' , [cnt]); end ; procedure IrpFileCreate (myDevice : WDFDEVICE ; myRequest : WDFREQUEST ; myFileObject : WDFFILEOBJECT ); stdcall ; begin DbgPrint ( 'IRP_MJ_CREATE' , []); WdfRequestComplete (myRequest, STATUS_SUCCESS ); end ; procedure IrpFileClose (myFileObject : WDFFILEOBJECT ); stdcall ; begin DbgPrint ( 'IRP_MJ_CLOSE' , []); end ; procedure IrpIOCTL (myQueue : WDFQUEUE ; myRequest : WDFREQUEST ; myOutLen : ULONG ; myInLen : ULONG ; myCode : ULONG ); stdcall ; var tt : LARGE_INTEGER ; begin if myCode = IOCTL_START then begin DbgPrint ( 'IOCTL_START' , []); cnt := 0 ; tt . HighPart := tt . HighPart or - 1 ; tt . LowPart := ULONG (- 10000000 ); KeSetTimerEx (@obj, tt . LowPart, tt . HighPart, 1000 , @dpc); end else if myCode = IOCTL_STOP then begin DbgPrint ( 'IOCTL_STOP' , []); KeCancelTimer (@obj); end ; WdfRequestComplete (myRequest, STATUS_SUCCESS ); end ; function AddDevice (pMyDriver : WDFDRIVER ; pMyDeviceInit : PWDFDEVICE_INIT ) : NTSTATUS ; stdcall ; var device : WDFDEVICE ; io_cfg : WDF_IO_QUEUE_CONFIG ; file_cfg : WDF_FILEOBJECT_CONFIG ; szDevName : UNICODE_STRING ; szSymName : UNICODE_STRING ; begin WdfDeviceInitSetIoType (pMyDeviceInit, WdfDeviceIoBuffered ); WDF_FILEOBJECT_CONFIG_INIT (@file_cfg, @ IrpFileCreate , @ IrpFileClose , Nil ); WdfDeviceInitSetFileObjectConfig (pMyDeviceInit, @file_cfg, WDF_NO_OBJECT_ATTRIBUTES ); RtlInitUnicodeString (@szDevName, DEV_NAME ); RtlInitUnicodeString (@szSymName, SYM_NAME ); WdfDeviceInitAssignName (pMyDeviceInit, @szDevName); WdfDeviceCreate (@pMyDeviceInit, WDF_NO_OBJECT_ATTRIBUTES , @device); WdfDeviceCreateSymbolicLink (device, @szSymName); pDevice := WdfDeviceWdmGetDeviceObject (device); KeInitializeTimer (@obj); KeInitializeDpc (@dpc, OnTimer , pDevice); WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE (@io_cfg, WdfIoQueueDispatchSequential ); io_cfg . EvtIoDeviceControl := @ IrpIOCTL ; Result := WdfIoQueueCreate (device, @io_cfg, WDF_NO_OBJECT_ATTRIBUTES , WDF_NO_HANDLE ); end ; function __DriverEntry (pMyDriver : PDRIVER_OBJECT ; pMyRegistry : PUNICODE_STRING ) : NTSTATUS ; stdcall ; var config : WDF_DRIVER_CONFIG ; begin WDF_DRIVER_CONFIG_INIT (@config, AddDevice ); WdfDriverCreate (pMyDriver, pMyRegistry, WDF_NO_OBJECT_ATTRIBUTES , @config, WDF_NO_HANDLE ); Result := STATUS_SUCCESS ; end ; end . |
app.pas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | program main ; {$APPTYPE CONSOLE} uses forms , dialogs , windows , classes , messages , sysutils , variants , graphics , controls ; const METHOD_BUFFERED = 0 ; METHOD_IN_DIRECT = 1 ; METHOD_OUT_DIRECT = 2 ; METHOD_NEITHER = 3 ; FILE_ANY_ACCESS = 0 ; FILE_DEVICE_UNKNOWN = $22 ; var fd : DWORD ; ret : DWORD ; code : DWORD ; begin fd := CreateFile ( '\\.\MyDriver' , GENERIC_READ or GENERIC_WRITE , FILE_SHARE_READ , Nil , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , 0 ); code := ( FILE_DEVICE_UNKNOWN shl 16 ) or ( FILE_ANY_ACCESS shl 14 ) or ( $800 shl 2 ) or ( METHOD_BUFFERED ); DeviceIoControl (fd, code, Nil , 0 , Nil , 0 , ret , Nil ); Sleep ( 3000 ); code := ( FILE_DEVICE_UNKNOWN shl 16 ) or ( FILE_ANY_ACCESS shl 14 ) or ( $801 shl 2 ) or ( METHOD_BUFFERED ); DeviceIoControl (fd, code, Nil , 0 , Nil , 0 , ret , Nil ); CloseHandle (fd); end . |
完成