Chinaunix首页 | 论坛 | 博客
  • 博客访问: 623299
  • 博文数量: 127
  • 博客积分: 6136
  • 博客等级: 准将
  • 技术积分: 1461
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 00:32

分类: WINDOWS

2009-12-27 15:54:03

今天说一下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");
}
阅读(2639) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~