1.DRIVER_OBJECT的结构体如下
typedef struct _DRIVER_OBJECT
{
CSHORT Type;
CSHORT Size;
PDEVICE_OBJECT DeviceObject;
ULONG Flags;
PVOID DriverStart;
ULONG DriverSize;
PVOID DriverSection;
PDRIVER_EXTENSION DriverExtension;
UNICODE_STRING DriverName;
PUNICODE_STRING HardwareDataBase;
PFAST_IO_DISPATCH FastIoDispatch;
PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo;
PDRIVER_UNLOAD DriverUnload;
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION];
} DRIVER_OBJECT;
驱动对象使用DRIVER_OBJECT数据结构表示,作为驱动的一个实例被内核加载,并且内核读一个驱动只加载一次一个驱动可能对应多个设备,这些设备组成设备链,其中第一个设备则是在驱动对象的DeviceObject中进行设定的。
2.设备对象
typedef struct _DEVICE_OBJECT {
CSHORT Type;
USHORT Size;
LONG ReferenceCount;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT NextDevice;
PDEVICE_OBJECT AttachedDevice;
PIRP CurrentIrp;
PIO_TIMER Timer;
ULONG Flags;
ULONG Characteristics;
__volatile PVPB Vpb;
PVOID DeviceExtension;
DEVICE_TYPE DeviceType;
CCHAR StackSize;
union {
LIST_ENTRY ListEntry;
WAIT_CONTEXT_BLOCK Wcb;
} Queue;
ULONG AlignmentRequirement;
KDEVICE_QUEUE DeviceQueue;
KDPC Dpc;
ULONG ActiveThreadCount;
PSECURITY_DESCRIPTOR SecurityDescriptor;
KEVENT DeviceLock;
USHORT SectorSize;
USHORT Spare1;
PDEVOBJ_EXTENSION DeviceObjectExtension;
PVOID Reserved;
} DEVICE_OBJECT, *PDEVICE_OBJECT;
设备对象中指明了其驱动对象(DRIVER_OBJECT),和在设备链中的下一个设备(NextObject),以及想要为该设备对象记录的其他信息设备扩展DeviceObjectExtension,
还有一个就是AttachedDevice;他是该设备在设备链中的上层设备,
3.我们在进行过滤驱动时要进行设备绑定,但是如何进行设备绑定呢?这时候就要使用IoAttachDevice了,该函数
PDEVICE_OBJECT IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceObject,IN TargetObject)
SourceObject:将要附加在另一个设备之上的设备,
TargetObject则是被附加的设备,
返回值则是SourceObject设备的下一层设备如果中间没有过滤设备,则直接返回的是TargetObject,当通过IoAttachDeviceObject时,SourceObject中的AttachedDevice会记录
下其上层设备,但是下层去无法知道所以可以使用设备扩展进行记录
4.摘除设备
在进行驱动卸载时,我们要将绑定的设备从设备脸上摘除,这时候利用IoDetachDevice
VOID IoDetachDevice( _Inout_ PDEVICE_OBJECT TargetDevice );
该函数则是将目标设备的上层设备从设备连上进行摘除
5.最后说明下设备名称和符号链接:
其实设备名称是只能使用在核心进程中的名字,如果想要在用户程序中使用,则要使用符号链接,现在说下设备名称和符号链接的限制,一般设备名称是"\Device\DeviceName"
符号链接一般是"\??\SymbolicName"或者"\DosDevice\SymbolicName"通过建立符号链接,我们就可以在用户程序中访问该程序了,但是还是不能直接使用该符号链接
而是"\\\\.\\SymbolicName"
5.NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver,PUNICODE_STRING pReg)
{
}
该函数参数第一项指向了被创建的驱动对象的指针,第二项则是指向设备服务键的名字字符串指针,该字符串的内容一般是"\REGISTRAY\MACHINE\SYSTEM\ControlSet
\Services\[服务名称]"