/***************************
*文件名称:Driver.cpp
***************************/
#include <Driver.h>
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDERIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath)
{
NTSTATUS status;
KdPrint(("Enter DriverEntry/n"));
//注册其他的驱动调用函数入口
pDriverObject->DriverUnload=HelloDDKUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE]=HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_WRITE]=HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ]=HelloDDKDispatchRoutine;
//创建驱动设备对象
status=CreateDevice(pDriverObject);
KdPrint(("DriverEntry end/n"));
return status;
}
/*************************
*函数名:CreateDevice
功能描述:初始化设备对象
*************************/
#pragma INITCODE
NTSTATUS CreateDevice( IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
//创建设备名称
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,L"//Device//MyDDKDevice");
//创建设备
status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0,TRUE,&pDevObj);
if(!NT_SUCCESS(status))
return status;
pDevObj->Flags |=DO_BUFFERED_IO;
pDevExt=(PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice=pDevObj;
pDevExt->ustrDeviceName=devName;
//创建符号链接
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"//??//HelloDDK");
pDevExt->ustrSymLinkName=symLinkName;
status=IoCreateSymbolicLink(&symLinkName,&devName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
return STATUS_SUCCESS;
}
/*************************************
*函数名:HelloDDKUnload
*功能描述:负责驱动程序的卸载操作
************************************/
#pragma PAGEDCODE
VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("Enter DriverUnload/n"));
pNextObj=pDriverObject->DeviceObject;
while (pNextObj!=NULL)
{
PDEVICE_EXTENSION pDevExt=(PDEVICE_EXTENSION) pNextObj->DeviceExtension;
//删除符号链接
UNICODE_STRING pLinkName=pDevExt->ustrSymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pNextObj=pNextObj->NextDevice;
IoDeleteDevice(pDevExt->pDevice);
}
}
/*************************************
*函数名:HelloDDKDispatchRoutine
*功能描述:对读IRP进行处理
************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("Enter HelloDDKDispatchRoutine/n"));
NTSTATUS status=STATUS_SUCCESS;
//完成IRP
pIrp->IoStatus.Status=status;
pIrp->IoStatus.Information=0;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
KdPrint(("Leave HelloDDKDispatchRoutine/n"));
return status;
}
#pragma INITCODE,指明此函数是加载到INIT内存域中,即成功卸载后,可以退出内存。
extern "C" NTSTATUS DriverEntry(IN PDERIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath)
这句代码标志DriverEntry函数的开始,extern "C"修饰,这样在编译时会编译成_DriverEntry@8的符号,否则就会出现链接错误。
KdPrint(("Enter DriverEntry/n"))这句代码中的KdPrint其实是个宏,在调试版本中会被DbgPrint代替,而在发行版本中,则不执行任何操作。
接着看下CreateDevice函数
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,L"//Device//MyDDKDevice");
这两句代码用于构造一个Unicode字符串,此字符串用来存储设备对象的名称。
status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0,TRUE,&pDevObj);
这句代码是用IoCreateDevice函数创建一个设备对象。
pDevObj->Flags |=DO_BUFFERED_IO,这句代码表明此种设备为BUFFERED_IO设备。设备对内存的操作分为两种,BUFFERED_IO和DO_DIRECT_IO。
pDevExt=(PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice=pDevObj;
pDevExt->ustrDeviceName=devName;
上述代码用来填写设备的扩展结构体。
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"//??//HelloDDK");
pDevExt->ustrSymLinkName=symLinkName;
status=IoCreateSymbolicLink(&symLinkName,&devName);
上述代码创建符号链接。虽然驱动程序有了设备名称,但是这种设备名称只能在内核态中可见,而对于应用程序是不可见的。因此,驱动需要一个符号链接,该链接指向真正的设备名称。
卸载驱动例程HelloDDKUnload
pNextObj=pDriverObject->DeviceObject,由驱动对象得到设备对象
UNICODE_STRING pLinkName=pDevExt->ustrSymLinkName;
IoDeleteSymbolicLink(&pLinkName);
这两句代码用于删除符号链接
pNextObj=pNextObj->NextDevice;
IoDeleteDevice(pDevExt->pDevice);
这两句遍历设备对象并删除。
默认派遣例程HelloDDKDispatchRoutine
pIrp->IoStatus.Status=status;
设置IRP的状态为成功
pIrp->IoStatus.Information=0;
设置操作的字节数为0
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
指示完成此IRP