一个驱动程序的源代码Driver.cpp,接上篇
来源:互联网 发布:大数据行业研究报告 编辑:程序博客网 时间:2024/04/30 18:02
/***************************
*文件名称: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
- 一个驱动程序的源代码Driver.cpp,接上篇
- 一个驱动程序头文件Driver.h
- 猜夫妻全部源代码(接上一个猜夫妻)
- Driver.cpp
- 用JDBC连接Vertica数据库后插入一行数据的例子源代码(接上篇)
- 接上篇的setmax.c
- 接上篇 FILE的读写
- 最小二乘法的新体(接上篇)
- 创建JDBC驱动程序Driver的路径变量
- windows driver 驱动程序我的下载地址
- 接上篇
- 接上篇...........
- 使用 AngularJS 开发一个大规模的单页应用(SPA)-接上篇
- 接上篇: radembedded错误的修改
- (接上篇)详解XML的DTD
- 接上篇简单的Memcache应用
- 利用jdbc做的一个简单系统(接上一篇)
- Device Driver 驱动程序
- 什么是VPN?
- JavaScript写的简单排序
- getBytes 和 getString
- 关于 ADO.NET连接池
- 王爽汇编 第六章包含多个段的程序 作业
- 一个驱动程序的源代码Driver.cpp,接上篇
- 第一天
- 自动化测试 - RFT系列教程8:最复杂的控件:TABLE(一) 校验(读取)表格的内容
- 链接库总结 收藏
- 利用手机号码GPS卫星追踪你的他
- 华硕笔试: 基础知识
- SWFUpload上传组件使用问题总结
- 图的操作
- 去掉.svn文件夹