NT式驱动程序的基本结构

NT式驱动程序的基本结构:


驱动对象:每个驱动程序会有唯一的驱动对象与之对应,这个驱动对象时在驱动加载的时候,被内核中的对象管理程序所创建的,由内核中的IO管理器进行加载。
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.
    //
/*DeviceObject是设备对象的链表,设备对象由程序员创建的,驱动卸载的时候遍历每一个设备对象,将其删除。*/
    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字符串,格式为\Driver\[驱动名称]*/
    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;/*记录StartIO例程的函数地址,用于串行化操作*/
    PDRIVER_UNLOAD DriverUnload;/*驱动卸载时所用的回调函数地址*/
    PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];/*记录着一个函数指针数组,每一个指针指向一个函数,每个函数就是处理IRP的派遣函数。*/


} DRIVER_OBJECT;
typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; 




设备对象:每个驱动程序会创建一个或多个设备对象,用DEVICE_OBJECT数据结构体表示,每个设备对象都会有一个指针指向下一个设备对象,形成一个设备链,第一个设备由DRIVER_OBJECT结构体中指明。


typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT {
    CSHORT Type;
    USHORT Size;
    LONG ReferenceCount;
    struct _DRIVER_OBJECT *DriverObject;/*指向驱动程序中的驱动对象,同一个驱动程序对象中的设备指向统一的驱动对象*/
    struct _DEVICE_OBJECT *NextDevice;/*指向下一个设备对象,下一个对象是指同一个驱动程序创建的若干设备对象*/
    struct _DEVICE_OBJECT *AttachedDevice;/*指向下一个设备对象,这里指的是,若有更高一层的驱动附件到这个驱动的时候,AttachedDevice指向的是那个更高一层的驱动的设备对象*/
    struct _IRP *CurrentIrp;/*使用StartIO例程的时候,指向的是当前IRP结构*/
    PIO_TIMER Timer;
    ULONG Flags;                                // See above:  DO_...
/*
#define DO_BUFFERED_IO 0x00000004 // 读写操作使用缓冲方式(系统复制缓冲区)访问用户模式数据  
#define DO_EXCLUSIVE 0x00000008 //一次只允许一个线程打开设备句柄   
#define DO_DIRECT_IO 0x00000010 //读写操作使用直接方式(内存描述符表)访问用户模式数据       
#define DO_DEVICE_INITIALIZING 0x00000080 //设备正在初始化
#define DO_POWER_PAGABLE 0x00002000 //必须在PASSIVE_LEVEL级别上处理IRP_MJ_PNP请求
#define DO_POWER_INRUSH 0x00004000 //设备上电期间需要大量电流


*/
    ULONG Characteristics;                      // See ntioapi:  FILE_...
    __volatile PVPB Vpb;
    PVOID DeviceExtension;/*设备扩展对象,记录的是设备自己特殊定义的结构体,尽量避免使用全局变量*/
    DEVICE_TYPE DeviceType;/*指明设备类型,当制作虚拟设备时,应选择FILE_DEVICE_UNKNOWN*/
    CCHAR StackSize;/*在多层驱动的情况下,驱动与驱动之间会形成类似堆栈的结构,IRP会依次从最高层传递到最底层。该值记录堆栈的层数*/
    union {
        LIST_ENTRY ListEntry;
        WAIT_CONTEXT_BLOCK Wcb;
    } Queue;
    ULONG AlignmentRequirement;/*设备在大容量传输的时候,需要内存对齐,以保证传输速度*/
    KDEVICE_QUEUE DeviceQueue;
    KDPC Dpc;


    //
    //  The following field is for exclusive use by the filesystem to keep
    //  track of the number of Fsp threads currently using the device
    //


    ULONG ActiveThreadCount;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    KEVENT DeviceLock;


    USHORT SectorSize;
    USHORT Spare1;


    struct _DEVOBJ_EXTENSION  *DeviceObjectExtension;
    PVOID  Reserved;


} DEVICE_OBJECT;


typedef struct _DEVICE_OBJECT *PDEVICE_OBJECT; 




UNICODE结构体:宽字符集,每个字符占16位
//
// Unicode strings are counted 16-bit character strings. If they are
// NULL terminated, Length does not include trailing NULL.
//
typedef struct _UNICODE_STRING {
    USHORT Length;//记录字符串长度,若有N个字符,则此数值为N*2
    USHORT MaximumLength;//记录容纳字符串的最大长度,
#ifdef MIDL_PASS
    [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
    __field_bcount_part(MaximumLength, Length) PWCH   Buffer; //记录字符串的指针
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;


NTSTATUS:32位无符号长整型,0~0X7FFFFFFF被认为是正确的状态,0X80000000~0XFFFFFFFF被认为是错误的状态。使用宏NT_SUCCESS来检测状态是否正确。


//创建设备
NTSTATUS  IoCreateDevice(
    IN PDRIVER_OBJECT  DriverObject,/*驱动对象的指针*/
    IN ULONG  DeviceExtensionSize,/*指定设备扩展的大小,IO管理器根据此数值在内存中创建设备扩展,并和驱动对象关联(驱动对象能找到是哪个设备对象的扩展对象吧)*/
    IN PUNICODE_STRING  DeviceName  OPTIONAL,/*设备对象的名字*/
    IN DEVICE_TYPE  DeviceType,/**/
    IN ULONG  DeviceCharacteristics,/*设备对象的特制,一般为FILE_DEVICE_SECURE_OPEN*/
    IN BOOLEAN  Exclusive,/*设置设备对象是否在内核模式下使用,一般设置为TRUE*/
    OUT PDEVICE_OBJECT  *DeviceObject/*IO管理器负责创建这个设备对象,此参数表示返回的创建设备对象的指针*/
    );

//创建设备连接名
NTSTATUS   IoCreateSymbolicLink(
    IN PUNICODE_STRING  SymbolicLinkName,//设备连接名
    IN PUNICODE_STRING  DeviceName //设备名
    );









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值