您的位置:首页 > 其它

WDM式驱动的基本结构

2013-12-05 16:54 363 查看
1.对于WDM驱动程序来说,一般都是基于分层。也就是说,完成一个设备操作,至少要由两个驱动设备共同完成一个是物理设备对象(Physical Device Object)PDO,另一个是功能设备对象(Function Device Object)FDO。关系是附加与被附加的关系。当PC插入某个设备的时,PDO会自动创建。确切的说,是由总线驱动创建的。PDO不能单独操作设备,需要配合FDO一起使用。系统会提示检查到新设备,需要安装配合FDO一起使用。系统会提示检测到新设备,要求安装驱动程序。需要安装的驱动程序指的就是WDM程序,此驱动程序创建FDO,并附加到PDO之上。

以下是WDM代码框架

#include <wdm.h>
NTSTATUS MyWDMAddDevice(PDRIVER_OBJECT pDriverObj,
PDEVICE_OBJECT pPhysicalDevObj);
void MyUnLoad(PDRIVER_OBJECT pDriverObj);
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT fdo;
PDEVICE_OBJECT pNextDo;
UNICODE_STRING ustrDevName;//name of DO
UNICODE_STRING ustrLinkName;//name of linkSymbol
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
/*
1.增加了AddDevice函数的设置,这是WDM和NT的不同点
2.因为NT是主动加载设备的,也就是驱动一旦加载就创建设备
而WDM驱动是被动加载驱动,操作系统必须加载PDO以后,调用AddDevice
AddDevice负责创建FDO,并且附加到PDO之上

3.创建设备不在这个函数里面,而在AddDevice
4.必须加入IRP_MJ_PNP 派遣回调函数。IRP_MJ_PNP 主要负责计算机中即插即用的处理
在WDM里加入很多即插即用的处理
*/
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj,
PUNICODE_STRING pRegPath)
{

_asm int 3;
pDriverObj=pDriverObj;
pRegPath=pRegPath;
DbgPrint("DriverEntry Enter");
//设置AddDevice函数
//Pointer to the driver extension. The only accessible member of the
//driver extension is DriverExtension->AddDevice, into which a driver's
//DriverEntry routine stores the driver's AddDevice routine
pDriverObj->DriverExtension->AddDevice=MyWDMAddDevice;

//设置各个IRP请求函数
/*pDriverObj->MajorFunction[IRP_MJ_PNP]=;
pDriverObj->MajorFunction[IRP_MJ_CREATE]=;
pDriverObj->MajorFunction[IRP_MJ_READ];
pDriverObj->MajorFunction[IRP_MJ_WRITE];*/

//设置卸载routine
pDriverObj->DriverUnload=MyUnLoad;
return STATUS_SUCCESS;

}
NTSTATUS MyWDMAddDevice(PDRIVER_OBJECT pDriverObj,
PDEVICE_OBJECT pPhysicalDevObj)
{
PAGED_CODE();//只有在check版本中有效中断请求超过APC_LEVEL时,会产生一个断言
DbgPrint("Enter AddDevice");
NTSTATUS status;
PDEVICE_OBJECT fdo;
UNICODE_STRING devName;

RtlInitUnicodeString(&devName,L"\\Device\\MyWdmDev");
//Create DO
status=IoCreateDevice(pDriverObj,
sizeof(DEVICE_EXTENSION),
&devName,
FILE_DEVICE_UNKNOWN,
0,
false,
&fdo);

if(!NT_SUCCESS(status))
return status;
//得到设备扩展

PDEVICE_EXTENSION pDevEx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

//fdo 附加到 pdo
//通过设备扩展记录FDO下层的设备
pDevEx->pNextDo=IoAttachDeviceToDeviceStack(fdo,pPhysicalDevObj);

UNICODE_STRING symLinkName;

RtlInitUnicodeString(&symLinkName,L"\\??\\symLinkWDM");
//用设备扩展记录DO 和符号链接

pDevEx->ustrLinkName=symLinkName;
pDevEx->ustrDevName=devName;

//创建符号链接
status=IoCreateSymbolicLink(&symLinkName,&devName);

if(!NT_SUCCESS(status))
{

IoDeleteDevice(fdo);
return status;
}

fdo->Flags|=DO_BUFFERED_IO|DO_POWER_PAGABLE;

//保证出示化完毕
fdo->Flags&=~DO_DEVICE_INITIALIZING;

DbgPrint("Leave AddDevice");

return STATUS_SUCCESS;
}
/*
在NT式驱动中,DriveUnload主要负责做删除设备和取消符号链接。而在
WDM驱动中,这部分操作被IRP_MN_REMOVE_DEVICE IRP 的处理函数所负责。
如果在DRiverEntry中有 申请内存操作,可以在此函数回收。
*/
void MyUnLoad(PDRIVER_OBJECT pDriverObj)
{
pDriverObj=pDriverObj;

DbgPrint("Enter UnLoad");
DbgPrint("Leave UnLoad");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: