一、数据类型
1.字符串
typedef struct _UNICODE_STRING{
USHORT Length;
//字符串的长度(所占的字节数)
USHORT MaxinumLength;
//字符串缓冲区的长度(所能占的最大字节数)
PWSTR Buffer;
//字符串缓冲区(字符串的地址,也即指针)
}UNICODE_STRING *PUNICODE_STRING
//(c语言中
* 是指针运算符.
*p表示指针变量p所指向的变量的值.即p中存储的内存地址 所存储的变量的值.
such as
定义一个指针变量p时,如 int *p; 表示定义了一个指向整型变量的指针变量p.)
2.打印字符串
#include <ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT driver)
{
DbgPrint("first:Our driver is unloading...\r\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
//#if DBG
//_asm int 3
//#endif
//DbgPrint("first:Hello,my salary!");
UNICODE_STRING str=RTL_CONSTANT_STRING(L"first:Hello, my first string!");
DbgPrint("%wZ\r\n",&str);
DbgPrint("Type:%d,Size:%d,\r\n",driver->Type,driver->Size);
DbgPrint("DriverName:%wZ\r\n",&driver->DriverName);
DbgPrint("HarewareDatabase:%wZ\r\n",driver->HardwareDatabase);
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
字符串”first:Hello, my first string”前面的 L 是C/C++语言规定的宽字符字面量标识,不是long类型。是对应wchar_t这种字符数据的,不是char。后者是1byte字符,前者是2byte字符,即Unicode-16编码字符.
一、重要的数据结构
1.驱动对象(内核模块的基本结构,提供身份信息,告诉windows提供哪些功能)
typedef struct _DRIVER_OBJECT {
//类型和大小
CSHORT Type;
CSHORT Size;
//设备对象链表的开始
PDEVICE_OBJECT DeviceObject;
//在内核空间中的开始地址和大小
PVOID DriverStart;
ULONG DriverSize;
//驱动的名字
UNICODE_STRING DriverName;
//快速IO分发函数
PFAST_IO_DISPATCH FastIoDispatch;
//卸载函数
PDRIVER_UNLOAD DriverUnload;
//普通分发函数
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
}DRIVER_OBJECT;
2.设备对象
设备对象(DO)是唯一可以接受消息的实体,IRP都是发给设备对象的.
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
_DEVICE_OBJECT{
//类型和大小
CSHORT Type;
CSHORT Size;
//引用计数
ULONG ReferenceCount;
//本设备所属的驱动对象
struct _DRIVER_OBJECT *DriverObject;
//下个设备对象,一个驱动对象中有n个设备,这些设备用这个指针连起来作为一个单向的链表
struct _DEVICE_OBJECT *NextDevice;
//设备类型
DEVICE_TYPE DeviceType;
//IRP栈的大小
HAR StackSize;.
}DEVICE_OBJECT;
3.一个典型的分发函数
请求(irp)被驱动对象的分发函数捕获
//device:请求的目标设备 irp:请求的指针
NTSUATUS MyDispatch(PDRIVER_OBJECT device,PIRP irp);
4.IRP
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
_IRP
{
//类型和大小
CSHORT Type;
CSHORT Size;
//内存描述符链表指针,在这里用来描述一个缓冲区,一个内核请求一般都需要一个缓冲区
PMDL MdlAddress;
//SystemBuffer是比MdlAddress简单的缓冲区表达方式,用哪一种取决IO请求的方式
union{
struct _IRP *MasterIrp;
__volatile LONG IrpCount;
PVOID SystemBuffer;
}AssociatedTrp;
//io状态,存放请求完成的返回状况
IO_STATUS_BLOCK IoStatus;
//IRP栈空间大小
CHAR StackCount;
//IRP当前栈空间
CHAR CurrentLocation;
//用来取消一个未决请求的函数
__volatile PDRIVER_CANCEL CancelRoutine;
//另一个缓冲区的表示方法
PVOID UserBuffer;
union{
//发出请求的线程
PETHREAD thread;
struct{
LIST_ENTRY listEntry;
union{
//一个栈空间元素(记录请求参数变化)
struct _IO_STACK_LOCATION *CurrentStackLocation;
};
};
} Overlay;
} Tail;
}IRP, *PIRP;
//IRP的指针 PIRP或者IRP*