DRIVER_OBJECT結構體
每個驅動程式對象代表了一個載入了的核心模式驅動程式映像.這個驅動對象就是以DRIVER_OBJECT結構體的形式存在的.這個驅動對象的指針從驅動程式的DriverEntry函式或AddDevice函式的參數傳入的.
typedef struct _DRIVER_OBJECT {
CSHORT Type;
CSHORT Size;
//
// The following links all of the devices created by a single driver
// together on a list, and the Flags word provides an extensible flag
// location for driver objects.
//
PDEVICE_OBJECT DeviceObject;
ULONG Flags;
//
// The following section describes where the driver is loaded. The count
// field is used to count the number of times the driver has had its
// registered reinitialization routine invoked.
//
PVOID DriverStart;
ULONG DriverSize;
PVOID DriverSection;
PDRIVER_EXTENSION DriverExtension;
//
// The driver name field is used by the error log thread
// determine the name of the driver that an I/O request is/was bound.
//
UNICODE_STRING DriverName;
//
// The following section is for registry support. Thise is a pointer
// to the path to the hardware information in the registry
//
PUNICODE_STRING HardwareDatabase;
//
// The following section contains the optional pointer to an array of
// alternate entry points to a driver for "fast I/O" support. Fast I/O
// is performed by invoking the driver routine directly with separate
// parameters, rather than using the standard IRP call mechanism. Note
// that these functions may only be used for synchronous I/O, and when
// the file is cached.
//
PFAST_IO_DISPATCH FastIoDispatch;
//
// The following section describes the entry points to this particular
// driver. Note that the major function dispatch table must be the last
// field in the object so that it remains extensible.
//
PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo;
PDRIVER_UNLOAD DriverUnload;
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
} DRIVER_OBJECT;
typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; // ntndis
結構體成員
DeviceObject
指向驅動程式創建的設備對象。這個驅動程式調用IoCreateDevice的時候會自動賦予正確的設備對象指針。
每個驅動程式會有一個或多個設備對象。其中,每個設備對象都有一個指針指向下一個驅動對象,最後一個設備對象指向空。此處的 DeviceObject指向驅動對象的第一個設備對象。通過 DeviceObject,就可以遍歷驅動對象里的所有設備對象。設備對象是由程式設計師自己創建的,而非作業系統完成,在驅動被卸載的時候,遍歷每個設備對象,並將其刪除。
HardwareDatabase
HardwareDatabase記錄的是設備的硬體資料庫名,這裡同樣用 Unicode字元串記錄。該字元串一般為HKEY_LOCAL_MACHINE\Hardware\DESCRIPTION\System,是一個註冊表路徑。
FastIoDispatch
檔案驅動中用到的派遣函式。指向這個驅動程式的FastIO入口點定義的一個結構。這個成員只能通過FSDs和網路傳輸驅動來使用。
DriverInit
指向DriverEntry函式的,這是通過IO管理器來建立的。
DriverStartIo
記錄 StartIO例程的函式地址,用於串列化操作,如果一個驅動程式沒有StartIo函式,這個成員將是NULL。
DriverUnload
指定驅動卸載時所用的回調函式地址,如果驅動程式沒有卸載函式,這個成員將是NULL。
MajorFunction[IRP_MJ_NUM+1]
指向驅動程式的DispatchXXX函式指針的數組。每個驅動程式至少要設定一個DispatchXXX函式指針在這個數組裡來處理這個驅動程式IRP請求包。任何一個驅動程式可以設定和IRP_MJ_XXX代碼一樣多的DispatchXXX來處理IRP請求包.每個DispatchXXX結構如下:
NTSTATUS DispatchXXX(IN PDEVICE_OBJECT DeviceObjec, IN PIRP Irp);
頭檔案
這個結構定義在wdm.h和ntddk.h裡面.應該包含wdm.h或ntddk.h
說明
每個核心模式驅動程式初始化函式的名字應該是DriverEntry,所以系統將自動載入驅動程式的入口函式.如果入口函式的名字是別的話,這個驅動程式的開發者必須在連結時定義初始化函式的名字;否則作業系統或Io管理器不能定位驅動程式入口地址.
一個驅動程式必須設定它的DispatchXXX入口地址在這個驅動對象里,換句話說,就是在驅動載入的時候傳給驅動對象的MajorFunction成員.一個設備驅動程式必須設定一個或多個DispatchXXX入口地址在MajorFunction成員里,使得IRP_MJ_XXX類型的IRP請求包可以給驅動程式處理.驅動程式處理完IRP之後應該傳給下一個驅動程式.至於更多的關於IRP_MJ_XXX的設定及類型,請 看MSDN的IRP Function Codes and IOCTLS.
DriverEntry函式也設定驅動程式的StartIo函式和卸載函式的入口點在驅動對象里.
HardwareDatabase字元串能在驅動程式載入的時候從註冊表的得到硬體信息.這個字元串是唯讀的.
從DriverEntry的參數裡輸入的註冊表路徑指向HKEY_LOCAL_MACHINE\system\CurrentControlSet\Services\”驅動程式的名字編碼”.這個字元串是唯讀的.