今天说一下NT驱动程序的基本结构。说到这,不得不说一下驱动程序中两个基本的结构体。
1.基本结构
驱动对象结构 DRIVER_OBJECT ,定义如下
typedef struct _DRIVER_OBJECT
{
CSHORT Type;
CSHORT Size;
PDEVICE_OBJECT DeviceObject;//设备对象,每个驱动程序可以创建多个设备对象
ULONG Flags;
PVOID DriverStart;
ULONG DriverSize;
PVOID DriverSection;(即为PsLoadedModuleList的地址,利用它可以枚举系统中所有驱动模块)
PRIVER_EXTENSION DriverExtension;
UNICODE_STRING DriverName; //驱动程序的名字,该字符串一般为“\Driver\[驱动程序名称]”
PUNICODE_STRING HardwareDatabase;//设备的硬件数据库键名
PFAST_IO_DISPATCH FastIoDispatch;//记录StartIo例程的函数地址
PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo; //驱动卸载时所调用的回调函数地址
PDRIVER_UNLOAD DriverUnload;
PDRIVER_DISPATCH MajorFunction[28];
}DRIVER_OBJECT, *PDRIVER_OBJECT;
DDK 中有对于一些域的说明
[00] IRP_MJ_CREATE
[01] IRP_MJ_CREATE_NAMED_PIPE
[02] IRP_MJ_CLOSE
[03] IRP_MJ_READ
[04] IRP_MJ_WRITE
[05] IRP_MJ_QUERY_INFORMATION
[06] IRP_MJ_SET_INFORMATION
[07] IRP_MJ_QUERY_EA
[08] IRP_MJ_SET_EA
[09] IRP_MJ_FLUSH_BUFFERS
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION
[0b] IRP_MJ_SET_VOLUME_INFORMATION
[0c] IRP_MJ_DIRECTORY_CONTROL
[0d] IRP_MJ_FILE_SYSTEM_CONTROL
[0e] IRP_MJ_DEVICE_CONTROL
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL
[10] IRP_MJ_SHUTDOWN
[11] IRP_MJ_LOCK_CONTROL
[12] IRP_MJ_CLEANUP
[13] IRP_MJ_CREATE_MAILSLOT
[14] IRP_MJ_QUERY_SECURITY
[15] IRP_MJ_SET_SECURITY
[16] IRP_MJ_POWER
[17] IRP_MJ_SYSTEM_CONTROL
[18] IRP_MJ_DEVICE_CHANGE
[19] IRP_MJ_QUERY_QUOTA
[1a] IRP_MJ_SET_QUOTA
[1b] IRP_MJ_PNP
设备对象结构 DEVICE_OBJECT ,定义如下
typedef struct _DEVICE_OBJECT
{
。。。。
struct _DRIVER_OBJECT *DriverObject;//指向驱动程序中的驱动对象
struct _DEVICE_OBJECT *NextDevice;//指向下一个设备对象
struct _DEVICE_OBJECT *AttachedDevice//指向下一个设备对象,更高一层的设备
struct _IRP *CurrentIrp;
struct _IO_TIMER *Timer;
ULONG Flags;
。。。。
struct _DEVOBJ_EXTENSION *DeviceObjectExtension;//设备的扩展对象
。。。。。
}DEVICE_OBJECT, *PDEVICE_OBJECT;
设备扩展时程序员自定义的,简单定义如下:
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT pDevice; //通过pDevice指向设备对象
UNICODE_STRING ustrDeviceName;//设备名称
UNICODE_STRING ustrSymLinkName;//符号链接名
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
2.驱动入口函数。
NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath)
{
DbgPrint("Enter DriverEntry!");
// do something
return STATUS_SUCCESS;
}
3.创建设备。
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
UNICODE_STRING symLinkName;
UNICODE_STRING devName;
RtlInitUnicodeString(&devName, L"\\Device\\MyDDKDevice1");
status = IoCreateDevice( pDriverObject,//传入的驱动对象
0, //设备扩展的大小
&devName, //设备对象的名字
FILE_DEVICE_UNKNOWN,//设备类型
0, //设备对象的特征
TRUE, //设备对象是否内核模式下使用,一般为TRUE
&pDevObj //返回创建对象的地址
);
if (!NT_SUCCESS(status))
{
return status;
}
pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDK");
status = IoCreateSymbolicLink(&symLinkName, &devName);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
return STATUS_SUCCESS;
}
4.删除设备
删除设备对象的函数:VOID IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject);
删除符号链接的函数:NTSTATUS IoDeleteSymbolicLink(IN PUNICODE_STRING SymbolicLinkName);
5.一个实例
#include "ntddk.h"
VOID OnUnload(IN PDRIVER_OBJECT DriverObject )
{
DbgPrint("OnUnload called!");
}
NTSTATUS CreateDevice( IN PDRIVER_OBJECT pDriverObject);
NTSTATUS CreateDevice2( IN PDRIVER_OBJECT pDriverObject);
VOID Dump(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath)
{
NTSTATUS status;
theDriverObject->DriverUnload = OnUnload;
DbgPrint("Enter DriverEntry!");
status = CreateDevice(theDriverObject);
if (!NT_SUCCESS(status))
{
return status;
}
status = CreateDevice2(theDriverObject);
if (!NT_SUCCESS(status))
{
return status;
}
Dump(theDriverObject);
return STATUS_SUCCESS;
}
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
UNICODE_STRING symLinkName;
UNICODE_STRING devName;
RtlInitUnicodeString(&devName, L"\\Device\\MyDDKDevice1");
status = IoCreateDevice( pDriverObject,
0,
&devName,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
&pDevObj);
if (!NT_SUCCESS(status))
{
return status;
}
pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDK");
status = IoCreateSymbolicLink(&symLinkName, &devName);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
return STATUS_SUCCESS;
}
NTSTATUS CreateDevice2(IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
UNICODE_STRING symLinkName;
UNICODE_STRING devName;
RtlInitUnicodeString(&devName, L"\\Device\\MyDDKDevice2");
status = IoCreateDevice( pDriverObject,
0,
&devName,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
&pDevObj);
if (!NT_SUCCESS(status))
{
return status;
}
pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDK2");
status = IoCreateSymbolicLink(&symLinkName, &devName);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
return STATUS_SUCCESS;
}
void Dump(IN PDRIVER_OBJECT pDriverObject)
{
int i=1;
PDEVICE_OBJECT pDevice;
DbgPrint("-------------------------------------\n");
DbgPrint("Begin Dump....\n");
DbgPrint("Driver Address:%0X%08X\n", pDriverObject);
DbgPrint("Driver Name:%S\n", pDriverObject->DriverName.Buffer);
DbgPrint("Driver first device:%0X%08X\n", pDriverObject->DeviceObject);
pDevice = pDriverObject->DeviceObject;
for (; pDevice != NULL; pDevice = pDevice->NextDevice)
{
DbgPrint("the %d device\n", i++);
}
DbgPrint("Dump over...\n");
DbgPrint("-------------------------------------\n");
}
阅读(2668) | 评论(0) | 转发(0) |