日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows驱动开发 - 派遣函数

發布時間:2025/4/14 windows 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows驱动开发 - 派遣函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一 派遣函數

驅動程序的主要功能是負責處理I/O請求。
其中大部分I/O請求是在派遣函數中處理的。
用戶模式下所有對驅動程序的I/O請求,全部由操作系統轉化為一個叫做IRP的數據結構,不同的IRP數據會被“派遣”到不同的派遣函數中。

?

二 IRP與派遣函數

?

IRP的全稱是輸入輸出請求包。

其部分結構如下:

typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _IRP {CSHORT Type;USHORT Size;//// Define the common fields used to control the IRP.////// Define a pointer to the Memory Descriptor List (MDL) for this I/O// request. ?This field is only used if the I/O is "direct I/O".//PMDL MdlAddress;//// Flags word - used to remember various flags.//ULONG Flags;//// The following union is used for one of three purposes://// ? ?1. This IRP is an associated IRP. ?The field is a pointer to a master// ? ? ? IRP.//// ? ?2. This is the master IRP. ?The field is the count of the number of// ? ? ? IRPs which must complete (associated IRPs) before the master can// ? ? ? complete.//// ? ?3. This operation is being buffered and the field is the address of// ? ? ? the system space buffer.//union {struct _IRP *MasterIrp;__volatile LONG IrpCount;PVOID SystemBuffer;} AssociatedIrp;//// Thread list entry - allows queueing the IRP to the thread pending I/O// request packet list.//LIST_ENTRY ThreadListEntry;//// I/O status - final status of operation.//IO_STATUS_BLOCK IoStatus;//// Requestor mode - mode of the original requestor of this operation.//KPROCESSOR_MODE RequestorMode;//// Pending returned - TRUE if pending was initially returned as the// status for this packet.//BOOLEAN PendingReturned;//// Stack state information.//CHAR StackCount;CHAR CurrentLocation;//// Cancel - packet has been canceled.//BOOLEAN Cancel;//// Cancel Irql - Irql at which the cancel spinlock was acquired.//KIRQL CancelIrql;//// ApcEnvironment - Used to save the APC environment at the time that the// packet was initialized.//CCHAR ApcEnvironment;//// Allocation control flags.//UCHAR AllocationFlags;//// User parameters.//PIO_STATUS_BLOCK UserIosb;PKEVENT UserEvent;union {struct {union {PIO_APC_ROUTINE UserApcRoutine;PVOID IssuingProcess;};PVOID UserApcContext;} AsynchronousParameters;LARGE_INTEGER AllocationSize;} Overlay;//// CancelRoutine - Used to contain the address of a cancel routine supplied// by a device driver when the IRP is in a cancelable state.//__volatile PDRIVER_CANCEL CancelRoutine;//// Note that the UserBuffer parameter is outside of the stack so that I/O// completion can copy data back into the user's address space without// having to know exactly which service was being invoked. ?The length// of the copy is stored in the second half of the I/O status block. If// the UserBuffer field is NULL, then no copy is performed.//PVOID UserBuffer;//// Kernel structures//// The following section contains kernel structures which the IRP needs// in order to place various work information in kernel controller system// queues. ?Because the size and alignment cannot be controlled, they are// placed here at the end so they just hang off and do not affect the// alignment of other fields in the IRP.//union {struct {union {//// DeviceQueueEntry - The device queue entry field is used to// queue the IRP to the device driver device queue.//KDEVICE_QUEUE_ENTRY DeviceQueueEntry;struct {//// The following are available to the driver to use in// whatever manner is desired, while the driver owns the// packet.//PVOID DriverContext[4];} ;} ;//// Thread - pointer to caller's Thread Control Block.//PETHREAD Thread;//// Auxiliary buffer - pointer to any auxiliary buffer that is// required to pass information to a driver that is not contained// in a normal buffer.//PCHAR AuxiliaryBuffer;//// The following unnamed structure must be exactly identical// to the unnamed structure used in the minipacket header used// for completion queue entries.//struct {//// List entry - used to queue the packet to completion queue, among// others.//LIST_ENTRY ListEntry;union {//// Current stack location - contains a pointer to the current// IO_STACK_LOCATION structure in the IRP stack. ?This field// should never be directly accessed by drivers. ?They should// use the standard functions.//struct _IO_STACK_LOCATION *CurrentStackLocation;//// Minipacket type.//ULONG PacketType;};};//// Original file object - pointer to the original file object// that was used to open the file. ?This field is owned by the// I/O system and should not be used by any other drivers.//PFILE_OBJECT OriginalFileObject;} Overlay;//// APC - This APC control block is used for the special kernel APC as// well as for the caller's APC, if one was specified in the original// argument list. ?If so, then the APC is reused for the normal APC for// whatever mode the caller was in and the "special" routine that is// invoked before the APC gets control simply deallocates the IRP.//KAPC Apc;//// CompletionKey - This is the key that is used to distinguish// individual I/O operations initiated on a single file handle.//PVOID CompletionKey;} Tail;} IRP;

當然,此結構是微軟定義的;字段含義參見驅動開發相關資料;

?

三 簡單示例代碼

?

在驅動入口函數 DriverEntry 中注冊派遣函數的代碼如下:

? ? ?//設置派遣函數pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HelloDDKDispatchRoutin;


對派遣函數做簡單的處理

NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)?{KdPrint(("Enter HelloDDKDispatchRoutin\n"));PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);UCHAR type = stack->MajorFunction; ......NTSTATUS status = STATUS_SUCCESS;// 完成IRPpIrp->IoStatus.Status = status;pIrp->IoStatus.Information = 0; ? ?// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("Leave HelloDDKDispatchRoutin\n"));return status; }

這個派遣函數僅僅是設置了IRP的完成狀態,并通過IoCompleteReques結束請求。
?

總結

以上是生活随笔為你收集整理的Windows驱动开发 - 派遣函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。