再来看基于WDM的驱动程序,
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#ifdef__cplusplus
extern"C"
{
#endif
#include<wdm.h>
#ifdef__cplusplus
}
#endif
typedefstruct_DEVICE_EXTENSION
{
PDEVICE_OBJECTfdo;
PDEVICE_OBJECTNextStackDevice;
UNICODE_STRINGustrDeviceName;//设备名
UNICODE_STRINGustrSymLinkName;//符号链接名
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
#definePAGEDCODEcode_seg("PAGE")
#defineLOCKEDCODEcode_seg()
#defineINITCODEcode_seg("INIT")
#definePAGEDDATAdata_seg("PAGE")
#defineLOCKEDDATAdata_seg()
#defineINITDATAdata_seg("INIT")
#definearraysize(p)(sizeof(p)/sizeof((p)[0]))
NTSTATUSHelloWDMAddDevice(INPDRIVER_OBJECTDriverObject,
INPDEVICE_OBJECTPhysicalDeviceObject);
NTSTATUSHelloWDMPnp(INPDEVICE_OBJECTfdo,
INPIRPIrp);
NTSTATUSHelloWDMDispatchRoutine(INPDEVICE_OBJECTfdo,
INPIRPIrp);
voidHelloWDMUnload(INPDRIVER_OBJECTDriverObject);
extern"C"
NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,
INPUNICODE_STRINGRegistryPath);
extern"C"
{
#endif
#include<wdm.h>
#ifdef__cplusplus
}
#endif
typedefstruct_DEVICE_EXTENSION
{
PDEVICE_OBJECTfdo;
PDEVICE_OBJECTNextStackDevice;
UNICODE_STRINGustrDeviceName;//设备名
UNICODE_STRINGustrSymLinkName;//符号链接名
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
#definePAGEDCODEcode_seg("PAGE")
#defineLOCKEDCODEcode_seg()
#defineINITCODEcode_seg("INIT")
#definePAGEDDATAdata_seg("PAGE")
#defineLOCKEDDATAdata_seg()
#defineINITDATAdata_seg("INIT")
#definearraysize(p)(sizeof(p)/sizeof((p)[0]))
NTSTATUSHelloWDMAddDevice(INPDRIVER_OBJECTDriverObject,
INPDEVICE_OBJECTPhysicalDeviceObject);
NTSTATUSHelloWDMPnp(INPDEVICE_OBJECTfdo,
INPIRPIrp);
NTSTATUSHelloWDMDispatchRoutine(INPDEVICE_OBJECTfdo,
INPIRPIrp);
voidHelloWDMUnload(INPDRIVER_OBJECTDriverObject);
extern"C"
NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,
INPUNICODE_STRINGRegistryPath);
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include"HelloWDM.h"
/************************************************************************
*函数名称:DriverEntry
*功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
*参数列表:
pDriverObject:从I/O管理器中传进来的驱动对象
pRegistryPath:驱动程序在注册表的中的路径
*返回值:返回初始化驱动状态
*************************************************************************/
#pragmaINITCODE
extern"C"NTSTATUSDriverEntry(INPDRIVER_OBJECTpDriverObject,
INPUNICODE_STRINGpRegistryPath)
{
KdPrint(("EnterDriverEntry/n"));
pDriverObject->DriverExtension->AddDevice=HelloWDMAddDevice;
pDriverObject->MajorFunction[IRP_MJ_PNP]=HelloWDMPnp;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=
pDriverObject->MajorFunction[IRP_MJ_CREATE]=
pDriverObject->MajorFunction[IRP_MJ_READ]=
pDriverObject->MajorFunction[IRP_MJ_WRITE]=HelloWDMDispatchRoutine;
pDriverObject->DriverUnload=HelloWDMUnload;
KdPrint(("LeaveDriverEntry/n"));
returnSTATUS_SUCCESS;
}
/************************************************************************
*函数名称:HelloWDMAddDevice
*功能描述:添加新设备
*参数列表:
DriverObject:从I/O管理器中传进来的驱动对象
PhysicalDeviceObject:从I/O管理器中传进来的物理设备对象
*返回值:返回添加新设备状态
*************************************************************************/
#pragmaPAGEDCODE
NTSTATUSHelloWDMAddDevice(INPDRIVER_OBJECTDriverObject,
INPDEVICE_OBJECTPhysicalDeviceObject)
{
PAGED_CODE();
KdPrint(("EnterHelloWDMAddDevice/n"));
NTSTATUSstatus;
PDEVICE_OBJECTfdo;
UNICODE_STRINGdevName;
RtlInitUnicodeString(&devName,L"//Device//MyWDMDevice");
status=IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&(UNICODE_STRING)devName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&fdo);
if(!NT_SUCCESS(status))
returnstatus;
PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;
pdx->fdo=fdo;
pdx->NextStackDevice=IoAttachDeviceToDeviceStack(fdo,PhysicalDeviceObject);
UNICODE_STRINGsymLinkName;
RtlInitUnicodeString(&symLinkName,L"//DosDevices//HelloWDM");
pdx->ustrDeviceName=devName;
pdx->ustrSymLinkName=symLinkName;
status=IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName,&(UNICODE_STRING)devName);
if(!NT_SUCCESS(status))
{
IoDeleteSymbolicLink(&pdx->ustrSymLinkName);
status=IoCreateSymbolicLink(&symLinkName,&devName);
if(!NT_SUCCESS(status))
{
returnstatus;
}
}
fdo->Flags|=DO_BUFFERED_IO|DO_POWER_PAGABLE;
fdo->Flags&=~DO_DEVICE_INITIALIZING;
KdPrint(("LeaveHelloWDMAddDevice/n"));
returnSTATUS_SUCCESS;
}
/************************************************************************
*函数名称:DefaultPnpHandler
*功能描述:对PNPIRP进行缺省处理
*参数列表:
pdx:设备对象的扩展
Irp:从IO请求包
*返回值:返回状态
*************************************************************************/
#pragmaPAGEDCODE
NTSTATUSDefaultPnpHandler(PDEVICE_EXTENSIONpdx,PIRPIrp)
{
PAGED_CODE();
KdPrint(("EnterDefaultPnpHandler/n"));
IoSkipCurrentIrpStackLocation(Irp);
KdPrint(("LeaveDefaultPnpHandler/n"));
returnIoCallDriver(pdx->NextStackDevice,Irp);
}
/************************************************************************
*函数名称:HandleRemoveDevice
*功能描述:对IRP_MN_REMOVE_DEVICEIRP进行处理
*参数列表:
fdo:功能设备对象
Irp:从IO请求包
*返回值:返回状态
*************************************************************************/
#pragmaPAGEDCODE
NTSTATUSHandleRemoveDevice(PDEVICE_EXTENSIONpdx,PIRPIrp)
{
PAGED_CODE();
KdPrint(("EnterHandleRemoveDevice/n"));
Irp->IoStatus.Status=STATUS_SUCCESS;
NTSTATUSstatus=DefaultPnpHandler(pdx,Irp);
IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName);
//调用IoDetachDevice()把fdo从设备栈中脱开:
if(pdx->NextStackDevice)
IoDetachDevice(pdx->NextStackDevice);
//删除fdo:
IoDeleteDevice(pdx->fdo);
KdPrint(("LeaveHandleRemoveDevice/n"));
returnstatus;
}
/************************************************************************
*函数名称:HelloWDMPnp
*功能描述:对即插即用IRP进行处理
*参数列表:
fdo:功能设备对象
Irp:从IO请求包
*返回值:返回状态
*************************************************************************/
#pragmaPAGEDCODE
NTSTATUSHelloWDMPnp(INPDEVICE_OBJECTfdo,
INPIRPIrp)
{
PAGED_CODE();
KdPrint(("EnterHelloWDMPnp/n"));
NTSTATUSstatus=STATUS_SUCCESS;
PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATIONstack=IoGetCurrentIrpStackLocation(Irp);
staticNTSTATUS(*fcntab[])(PDEVICE_EXTENSIONpdx,PIRPIrp)=
{
DefaultPnpHandler,//IRP_MN_START_DEVICE
DefaultPnpHandler,//IRP_MN_QUERY_REMOVE_DEVICE
HandleRemoveDevice,//IRP_MN_REMOVE_DEVICE
DefaultPnpHandler,//IRP_MN_CANCEL_REMOVE_DEVICE
DefaultPnpHandler,//IRP_MN_STOP_DEVICE
DefaultPnpHandler,//IRP_MN_QUERY_STOP_DEVICE
DefaultPnpHandler,//IRP_MN_CANCEL_STOP_DEVICE
DefaultPnpHandler,//IRP_MN_QUERY_DEVICE_RELATIONS
DefaultPnpHandler,//IRP_MN_QUERY_INTERFACE
DefaultPnpHandler,//IRP_MN_QUERY_CAPABILITIES
DefaultPnpHandler,//IRP_MN_QUERY_RESOURCES
DefaultPnpHandler,//IRP_MN_QUERY_RESOURCE_REQUIREMENTS
DefaultPnpHandler,//IRP_MN_QUERY_DEVICE_TEXT
DefaultPnpHandler,//IRP_MN_FILTER_RESOURCE_REQUIREMENTS
DefaultPnpHandler,//
DefaultPnpHandler,//IRP_MN_READ_CONFIG
DefaultPnpHandler,//IRP_MN_WRITE_CONFIG
DefaultPnpHandler,//IRP_MN_EJECT
DefaultPnpHandler,//IRP_MN_SET_LOCK
DefaultPnpHandler,//IRP_MN_QUERY_ID
DefaultPnpHandler,//IRP_MN_QUERY_PNP_DEVICE_STATE
DefaultPnpHandler,//IRP_MN_QUERY_BUS_INFORMATION
DefaultPnpHandler,//IRP_MN_DEVICE_USAGE_NOTIFICATION
DefaultPnpHandler,//IRP_MN_SURPRISE_REMOVAL
};
ULONGfcn=stack->MinorFunction;
if(fcn>=arraysize(fcntab))
{//未知的子功能代码
status=DefaultPnpHandler(pdx,Irp);//somefunctionwedon'tknowabout
returnstatus;
}
#ifDBG
staticchar*fcnname[]=
{
"IRP_MN_START_DEVICE",
"IRP_MN_QUERY_REMOVE_DEVICE",
"IRP_MN_REMOVE_DEVICE",
"IRP_MN_CANCEL_REMOVE_DEVICE",
"IRP_MN_STOP_DEVICE",
"IRP_MN_QUERY_STOP_DEVICE",
"IRP_MN_CANCEL_STOP_DEVICE",
"IRP_MN_QUERY_DEVICE_RELATIONS",
"IRP_MN_QUERY_INTERFACE",
"IRP_MN_QUERY_CAPABILITIES",
"IRP_MN_QUERY_RESOURCES",
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
"IRP_MN_QUERY_DEVICE_TEXT",
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
"",
"IRP_MN_READ_CONFIG",
"IRP_MN_WRITE_CONFIG",
"IRP_MN_EJECT",
"IRP_MN_SET_LOCK",
"IRP_MN_QUERY_ID",
"IRP_MN_QUERY_PNP_DEVICE_STATE",
"IRP_MN_QUERY_BUS_INFORMATION",
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
"IRP_MN_SURPRISE_REMOVAL",
};
KdPrint(("PNPRequest(%s)/n",fcnname[fcn]));
#endif//DBG
status=(*fcntab[fcn])(pdx,Irp);
KdPrint(("LeaveHelloWDMPnp/n"));
returnstatus;
}
/************************************************************************
*函数名称:HelloWDMDispatchRoutine
*功能描述:对缺省IRP进行处理
*参数列表:
fdo:功能设备对象
Irp:从IO请求包
*返回值:返回状态
*************************************************************************/
#pragmaPAGEDCODE
NTSTATUSHelloWDMDispatchRoutine(INPDEVICE_OBJECTfdo,
INPIRPIrp)
{
PAGED_CODE();
KdPrint(("EnterHelloWDMDispatchRoutine/n"));
Irp->IoStatus.Status=STATUS_SUCCESS;
Irp->IoStatus.Information=0;//nobytesxfered
IoCompleteRequest(Irp,IO_NO_INCREMENT);
KdPrint(("LeaveHelloWDMDispatchRoutine/n"));
returnSTATUS_SUCCESS;
}
/************************************************************************
*函数名称:HelloWDMUnload
*功能描述:负责驱动程序的卸载操作
*参数列表:
DriverObject:驱动对象
*返回值:返回状态
*************************************************************************/
#pragmaPAGEDCODE
voidHelloWDMUnload(INPDRIVER_OBJECTDriverObject)
{
PAGED_CODE();
KdPrint(("EnterHelloWDMUnload/n"));
KdPrint(("LeaveHelloWDMUnload/n"));
}
同前面一样,编译也是两种方式,第一种用DDK编译,准备两个脚本文件,makefile和Sources,其中Sources有所不同,如下所示:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->TARGETNAME=HelloWDM
TARGETTYPE=DRIVER
DRIVERTYPE=WDM
TARGETPATH=OBJ
INCLUDES=$(BASEDIR)/inc;/
$(BASEDIR)/inc/ddk;/
SOURCES=HelloWDM.cpp/
TARGETTYPE=DRIVER
DRIVERTYPE=WDM
TARGETPATH=OBJ
INCLUDES=$(BASEDIR)/inc;/
$(BASEDIR)/inc/ddk;/
SOURCES=HelloWDM.cpp/
另一种是用VC进行编译,有三点需要注意:
1, 选择c/c++选项卡,将原来的Project Options全删掉,换成下面的:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->/nologo/Gz/MLd/W3/WX/Z7/Od/DWIN32=100/D_X86_=1/DWINVER=0x500/DDBG=1/Fo"MyDriver_Check/"/Fd"MyDriver_Check/"/FD/c
2, 选择Link选项卡,将原来的Project Options全删掉,换成下面的:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->wdm.lib/nologo/base:"0x10000"/stack:0x400000,0x1000/entry:"DriverEntry"/subsystem:console/incremental:no/pdb:"MyDriver_Check/HelloWDM.pdb"/debug/machine:I386/nodefaultlib/out:"MyDriver_Check/HelloWDM.sys"/pdbtype:sept/subsystem:native/driver/SECTION:INIT,D/RELEASE/IGNORE:4078
3, 修改include目录时,加入
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->D:/WINDDK/3790.1830/INC/DDK/WDM/W2K
否则会报错如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->fatalerrorC1083:Cannotopenincludefile:'wdm.h':Nosuchfileordirectory
最后是驱动的安装,WDM驱动的安装需要写一个inf文件,如下所示:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->;---------VersionSection---------------------------------------------------
[Version]
Signature="$CHICAGO$";
Provider=Phinecos_Device
DriverVer=20/2/2000,3.0.0.3
;Ifdevicefitsoneofthestandardclasses,usethenameandGUIDhere,
;otherwisecreateyourowndeviceclassandGUIDasthisexampleshows.
Class=PhinecosDevice
ClassGUID={EF2962F0-0D55-4bff-B8AA-2221EE8A79B0}
;---------SourceDiskNamesandSourceDiskFilesSection-----------------------
;Thesesectionsidentifysourcedisksandfilesforinstallation.Theyare
;shownhereasanexample,butcommentedout.
[SourceDisksNames]
1="HelloWDM",Disk1,,
[SourceDisksFiles]
HelloWDM.sys=1,MyDriver_Check,
;---------ClassInstall/ClassInstall32Section-------------------------------
;Notnecessaryifusingastandardclass
;9XStyle
[ClassInstall]
Addreg=Class_AddReg
;NTStyle
[ClassInstall32]
Addreg=Class_AddReg
[Class_AddReg]
HKR,,,,%DeviceClassName%
HKR,,Icon,,"-5"
;---------DestinationDirsSection-------------------------------------------
[DestinationDirs]
YouMark_Files_Driver=10,System32/Drivers
;---------ManufacturerandModelsSections----------------------------------
[Manufacturer]
%MfgName%=Mfg0
[Mfg0]
;PCIhardwareIdsusetheform
;PCI/VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd
;改成你自己的ID
%DeviceDesc%=YouMark_DDI,PCI/VEN_9999&DEV_9999
;----------DDInstallSections-----------------------------------------------
;---------Windows9X-----------------
;ExperimentationhasshownthatDDInstallrootnamesgreaterthan19characters
;causeproblemsinWindows98
[YouMark_DDI]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_9X_AddReg
[YouMark_9X_AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,HelloWDM.sys
HKR,"Parameters","BreakOnEntry",0x00010001,0
;---------WindowsNT-----------------
[YouMark_DDI.NT]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_NT_AddReg
[YouMark_DDI.NT.Services]
Addservice=HelloWDM,0x00000002,YouMark_AddService
[YouMark_AddService]
DisplayName=%SvcDesc%
ServiceType=1;SERVICE_KERNEL_DRIVER
StartType=3;SERVICE_DEMAND_START
ErrorControl=1;SERVICE_ERROR_NORMAL
ServiceBinary=%10%/System32/Drivers/HelloWDM.sys
[YouMark_NT_AddReg]
HKLM,"System/CurrentControlSet/Services/HelloWDM/Parameters",/
"BreakOnEntry",0x00010001,0
;---------Files(common)-------------
[YouMark_Files_Driver]
HelloWDM.sys
;---------StringsSection---------------------------------------------------
[Strings]
ProviderName="Phinecos."
MfgName="VistaSoft"
DeviceDesc="HelloWorldWDM!"
DeviceClassName="Phinecos_Device"
SvcDesc="Phinecos"
[Version]
Signature="$CHICAGO$";
Provider=Phinecos_Device
DriverVer=20/2/2000,3.0.0.3
;Ifdevicefitsoneofthestandardclasses,usethenameandGUIDhere,
;otherwisecreateyourowndeviceclassandGUIDasthisexampleshows.
Class=PhinecosDevice
ClassGUID={EF2962F0-0D55-4bff-B8AA-2221EE8A79B0}
;---------SourceDiskNamesandSourceDiskFilesSection-----------------------
;Thesesectionsidentifysourcedisksandfilesforinstallation.Theyare
;shownhereasanexample,butcommentedout.
[SourceDisksNames]
1="HelloWDM",Disk1,,
[SourceDisksFiles]
HelloWDM.sys=1,MyDriver_Check,
;---------ClassInstall/ClassInstall32Section-------------------------------
;Notnecessaryifusingastandardclass
;9XStyle
[ClassInstall]
Addreg=Class_AddReg
;NTStyle
[ClassInstall32]
Addreg=Class_AddReg
[Class_AddReg]
HKR,,,,%DeviceClassName%
HKR,,Icon,,"-5"
;---------DestinationDirsSection-------------------------------------------
[DestinationDirs]
YouMark_Files_Driver=10,System32/Drivers
;---------ManufacturerandModelsSections----------------------------------
[Manufacturer]
%MfgName%=Mfg0
[Mfg0]
;PCIhardwareIdsusetheform
;PCI/VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd
;改成你自己的ID
%DeviceDesc%=YouMark_DDI,PCI/VEN_9999&DEV_9999
;----------DDInstallSections-----------------------------------------------
;---------Windows9X-----------------
;ExperimentationhasshownthatDDInstallrootnamesgreaterthan19characters
;causeproblemsinWindows98
[YouMark_DDI]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_9X_AddReg
[YouMark_9X_AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,HelloWDM.sys
HKR,"Parameters","BreakOnEntry",0x00010001,0
;---------WindowsNT-----------------
[YouMark_DDI.NT]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_NT_AddReg
[YouMark_DDI.NT.Services]
Addservice=HelloWDM,0x00000002,YouMark_AddService
[YouMark_AddService]
DisplayName=%SvcDesc%
ServiceType=1;SERVICE_KERNEL_DRIVER
StartType=3;SERVICE_DEMAND_START
ErrorControl=1;SERVICE_ERROR_NORMAL
ServiceBinary=%10%/System32/Drivers/HelloWDM.sys
[YouMark_NT_AddReg]
HKLM,"System/CurrentControlSet/Services/HelloWDM/Parameters",/
"BreakOnEntry",0x00010001,0
;---------Files(common)-------------
[YouMark_Files_Driver]
HelloWDM.sys
;---------StringsSection---------------------------------------------------
[Strings]
ProviderName="Phinecos."
MfgName="VistaSoft"
DeviceDesc="HelloWorldWDM!"
DeviceClassName="Phinecos_Device"
SvcDesc="Phinecos"
这里有两种安装方式,一种是进入“控制面板”,选择添加硬件,加载进inf文件完成安装,如图所示:


另一种可选的安装测试方式是使用Driver Studio中的EzDriverInstaller工具来进行安装,如图所示:
本文介绍了一种基于WDM的驱动程序开发实例,包括关键函数的实现与编译过程,并提供了两种编译方法及驱动安装步骤。
2万+

被折叠的 条评论
为什么被折叠?



