1. 驱动对象(DRIVER_OBJECT)
typedef struct _DRIVER_OBJECT {
CSHORT Type; // 结构体类型,驱动对象固定为4
CSHORT Size; // 结构体大小
PDEVICE_OBJECT DeviceObject; // 指向当前驱动所拥有的第一个设备对象
ULONG Flags; // ??
PVOID DriverStart; // 驱动加载在系统内存中的位置
ULONG DriverSize; // 驱动加载在系统内存中的大小
PVOID DriverSection; // ??
PDRIVER_EXTENSION DriverExtension; // 指向驱动的扩展,DriverEntry内设置其AddDevice成员变量
UNICODE_STRING DriverName; // 驱动的名称,一般为"\Driver\服务名称"
PUNICODE_STRING HardwareDatabase; // 注册表中硬件数据库键名
PFAST_IO_DISPATCH FastIoDispatch; // 记录FastIO入口点,仅仅用于文件和网络传输系统中
PDRIVER_INITIALIZE DriverInit; // DriverEntry函数的入口点
PDRIVER_STARTIO DriverStartIo; // 记录StartIO例程的入口点,由DriverEntry设置
PDRIVER_UNLOAD DriverUnload; // 记录卸载驱动时会调用的回调函数地址,由DriverEntry设置
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; // IRP调度表,由DriverEntry设置驱动要处理哪些IRP回调
} DRIVER_OBJECT, *PDRIVER_OBJECT;
2. 设备对象(DEVICE_OBJECT)
typedef struct _DEVICE_OBJECT {
CSHORT Type; // 结构体类型,设备对象固定为3
USHORT Size; // 结构体大小
LONG ReferenceCount; // 此设备对象相关联的设备,被打开的句柄数,由IO管理器管理
struct _DRIVER_OBJECT *DriverObject; // 此设备对象所属于的驱动对象,即DriverEntry的入参
struct _DEVICE_OBJECT *NextDevice; // 同属于驱动对象的下一个设备对象,创建顺序为仅仅挨着此设备对象创建
struct _DEVICE_OBJECT *AttachedDevice; // 附加到此设备上的设备对象,通常是筛选器驱动程序的设备对象
struct _IRP *CurrentIrp; // StartIO相关,指向当前StartIO正在处理的IRP
PIO_TIMER Timer; // 指向此设备对象的计时器对象,IO管理器将每秒调用一次计时器对象中的例程
ULONG Flags; // 此设备相关的标志位
ULONG Characteristics; // 此设备的属性
__volatile PVPB Vpb; // 指向此设备对象的volume参数块
PVOID DeviceExtension; // 设备扩展,可由程序员自定义
DEVICE_TYPE DeviceType; // 此设备的设备类型,IoCreateDevice和IoCreateDeviceSecure时设置
CCHAR StackSize; // IRP从此发送到最下层设备经过的层数
union {
LIST_ENTRY ListEntry;
WAIT_CONTEXT_BLOCK Wcb;
} Queue; // IO管理器内部使用,用于在需要时对设备对象进行排队
ULONG AlignmentRequirement; // 指定设备的数据传输要求,大容量传输时,需要进行数据对齐保证效率
KDEVICE_QUEUE DeviceQueue; // 此设备对象的设备队列对象
KDPC Dpc; // 此设备对象的延迟过程调用 (DPC) 设备对象
ULONG ActiveThreadCount; // 保留,供将来使用
PSECURITY_DESCRIPTOR SecurityDescriptor; // 此设备对象的设备安全描述符(创建设备时指定,或ZwSetSecurityObject修改)
KEVENT DeviceLock; // 由IO管理器分配的同步事件对象,用于IO管理器与文件系统驱动之间的同步
USHORT SectorSize; // 如果设备对象表示卷,则指定卷的扇区大小,否则为0
USHORT Spare1; // 预留给系统使用
struct _DEVOBJ_EXTENSION *DeviceObjectExtension; // 指向由 i/o 管理器和 PnP 管理器用来存储有关设备状态的信息的设备对象扩展
PVOID Reserved; // 预留给系统使用
} DEVICE_OBJECT, *PDEVICE_OBJECT;
3. IRP
typedef struct _IRP {
CSHORT Type; //结构体类型
USHORT Size; //结构体大小
PMDL MdlAddress; //Mdl传递缓冲区的一种传递方法(地址映射传递)
ULONG Flags;
union {
struct _IRP *MasterIrp;
__volatile LONG IrpCount;
PVOID SystemBuffer; //IRP传递缓冲区的一种传递方法(缓冲区拷贝传递)
} AssociatedIrp;
LIST_ENTRY ThreadListEntry;
IO_STATUS_BLOCK IoStatus; //IO状态,存放IRP完成的结果
KPROCESSOR_MODE RequestorMode;
BOOLEAN PendingReturned;
CHAR StackCount; //IRP当前栈空间大小
CHAR CurrentLocation; //IRP当前栈空间
BOOLEAN Cancel;
KIRQL CancelIrql;
CCHAR ApcEnvironment;
UCHAR AllocationFlags;
union {
PIO_STATUS_BLOCK UserIosb;
PVOID IoRingContext;
};
PKEVENT UserEvent;
union {
struct {
union {
PIO_APC_ROUTINE UserApcRoutine;
PVOID IssuingProcess;
};
union {
PVOID UserApcContext;
#if ...
_IORING_OBJECT *IoRing;
#else
struct _IORING_OBJECT *IoRing;
#endif
};
} AsynchronousParameters;
LARGE_INTEGER AllocationSize;
} Overlay;
__volatile PDRIVER_CANCEL CancelRoutine; //IRP的取消例程,取消IRP时调用
PVOID UserBuffer; //IRP传递缓冲区的一种传递方法(直接传递)
union {
struct {
union {
KDEVICE_QUEUE_ENTRY DeviceQueueEntry;
struct {
PVOID DriverContext[4];
};
};
PETHREAD Thread; //发出这个请求的线程
PCHAR AuxiliaryBuffer;
struct {
LIST_ENTRY ListEntry;
union {
struct _IO_STACK_LOCATION *CurrentStackLocation; //IRP的栈空间元素
ULONG PacketType;
};
};
PFILE_OBJECT OriginalFileObject;
} Overlay;
KAPC Apc;
PVOID CompletionKey;
} Tail;
} IRP;
4. FILE_OBJECT
typedef struct _FILE_OBJECT {
CSHORT Type; //结构体类型
CSHORT Size; //结构体大小
PDEVICE_OBJECT DeviceObject; //指向目的物理或虚拟设备对象
PVPB Vpb; //目的设备对象相关联的挂载卷的VPB
PVOID FsContext;
PVOID FsContext2;
PSECTION_OBJECT_POINTERS SectionObjectPointer;
PVOID PrivateCacheMap;
NTSTATUS FinalStatus;
struct _FILE_OBJECT *RelatedFileObject; //Create请求时,表示FileName相对的设备
BOOLEAN LockOperation; //是否该文件对象曾被用于调用过字节范围锁
BOOLEAN DeletePending; //标志该文件流应当被删除
BOOLEAN ReadAccess; //文件打开时带有读权限
BOOLEAN WriteAccess; //文件打开时带有写权限
BOOLEAN DeleteAccess; //文件打开时带有删除权限
BOOLEAN SharedRead; //文件打开时共享出了读权限
BOOLEAN SharedWrite; //文件打开时共享出了写权限
BOOLEAN SharedDelete; //文件打开时共享出了删除权限
ULONG Flags;
UNICODE_STRING FileName; //要打开的文件、卷、物理设备的字符串
LARGE_INTEGER CurrentByteOffset; //文件流的当前指针位置
__volatile ULONG Waiters; //用于同步操作,指示等待使用该文件对象进行IO操作的线程数量
__volatile ULONG Busy; //用于同步操作,指示当前文件对象正在处理中
PVOID LastLock;
KEVENT Lock;
KEVENT Event; //用于等待该文件对象,异步IO
__volatile PIO_COMPLETION_CONTEXT CompletionContext; //完成一个IRP时,发送一个消息到本地过程调用端口LPC
KSPIN_LOCK IrpListLock;
LIST_ENTRY IrpList;
__volatile PVOID FileObjectExtension;
} FILE_OBJECT, *PFILE_OBJECT;
DeviceObject
、VPB
由IO管理器在发送create请求给文件系统驱动之前初始化
FsContext
、FsContext2
、SectionObjectPointer
、PrivateCacheMap
由文件系统驱动和缓存管理器进行初始化和维护,IO管理器不维护这些域中的内容,但是IO管理器会检查和使用FsContext域的内容
FileName
:由IO管理器进行初始化表示要打开的文件、卷或物理设备的字符串,可以是相对路径也可以是绝对路径。相对路径名在RelatedFileObject域的非空值来表示。
RelatedFileObject
:只有在create请求的时候才是有效的,其余时候是未定义的
CurrentByteOffset
:由文件系统进行维护,仅用于被以同步方式打开的文件对象。指向文件流的当前指针位置,该指针在成功完成读写操作时进行更新
CompletionContext
:由IO管理器进行使用,在完成一个IRP的时候,发送一个消息到本地过程调用(LPC)端口
DeletePending
:由文件系统维护,在文件系统收到一个要求删除该文件流的IRP后,设置该字段
LockOperation
:如果拥有该文件对象的线程在文件打开的时候至少调用过一次字节范围锁,那么该字段将被IO管理器设为TRUE
ReadAccess
、WriteAccess
、DeleteAccess
、SharedRead
、SharedWrite
、SharedDelete
:由IO管理器进行维护,表示文件是怎样打开的,随后的特定类型的打开会被允许,还是会被返回STATUS_SHARING_VIOLATION拒绝。IO管理器内部提供了一个例程名叫IoCheckShareAccess
用于维护和使用这些状态,通常被文件系统驱动所使用。
Busys
、Waiters
:用户打开文件时要求同步执行时,Flags会被IO管理器设置FO_SYNCHRONOUS_FLAGS标志,此时IO管理器为了实现同步序列化的功能,Busy指示文件对象正在被处理中,Waiters指示等待该文件对象执行IO操作的线程数量
Event
:由IO管理器进行维护,用于异步IO。线程可以要求异步IO,然后等待这个IO操作完成,也即等待文件对象变为有信号状态,因为文件对象也是一个可等待对象。在文件对象开始进行一个IO操作时被IO管理器设置为无信号状态,当IO操作完成时被设置为有信号状态。