Windows驱动开发 - 派遣函数
生活随笔
收集整理的這篇文章主要介紹了
Windows驱动开发 - 派遣函数
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一 派遣函數(shù)
驅(qū)動程序的主要功能是負(fù)責(zé)處理I/O請求。
其中大部分I/O請求是在派遣函數(shù)中處理的。
用戶模式下所有對驅(qū)動程序的I/O請求,全部由操作系統(tǒng)轉(zhuǎn)化為一個叫做IRP的數(shù)據(jù)結(jié)構(gòu),不同的IRP數(shù)據(jù)會被“派遣”到不同的派遣函數(shù)中。
?
二 IRP與派遣函數(shù)
?
IRP的全稱是輸入輸出請求包。
其部分結(jié)構(gòu)如下:
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;當(dāng)然,此結(jié)構(gòu)是微軟定義的;字段含義參見驅(qū)動開發(fā)相關(guān)資料;
?
三 簡單示例代碼
?
在驅(qū)動入口函數(shù) DriverEntry 中注冊派遣函數(shù)的代碼如下:
? ? ?//設(shè)置派遣函數(shù)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;
對派遣函數(shù)做簡單的處理
這個派遣函數(shù)僅僅是設(shè)置了IRP的完成狀態(tài),并通過IoCompleteReques結(jié)束請求。
?
總結(jié)
以上是生活随笔為你收集整理的Windows驱动开发 - 派遣函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win 驱动编程 - 内核里操作注册表
- 下一篇: NC命令行作为服务端、客户端以及win3