网站首页 / 软件教程

[用户投稿] Win 64 驱动编程 第五课 HelloWorld卸载例程细化

2018年04月21日 作者 : 深蓝  分类 : 软件教程 浏览: 6335 评论 0

感谢本站用户:shenyizhe 投稿为大家分享。

 

新建 头文件 我这里命名为DriverTest003.h

 

1.png

 

将第四课部分源码分割,放入头文件中

#include<ntddk.h>
#define INITCODE code_reg("INIT") //INIT 内存标识
#define INITCODE code_reg("PAGE") //内存不足时,可以被置换到硬盘的虚拟内存
#pragma INITCODE //代码运行后,就从内存释放


NTSTATUS CreateMyDevice(IN PDRIVER_OBJECT pDriverObject) {

NTSTATUS status;
PDEVICE_OBJECT pDevObj; // 用来返回创建设备

// 创建设备名称
UNICODE_STRING devName;
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&devName, L"\\Device\\StudyDDK_Device"); // 对devName初始化字符串为“\\Device\\StudyDDK_Device”

// RtlInitUnicodeString 参数说明
// DestinationString 需要初始化的指针PUNICODE_STRING
// SourceString 指向一个以空结尾的Unicode字符串常量,用这个字符串来初始化DestinationString

// 创建设备
status = IoCreateDevice(pDriverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);

// IoCreateDevice 参数说明

// DriverObject 为指针调用驱动程序对象。每个驱动程序接收一个参数的指针,并将其返回DriverEntry例程。功能和筛选器驱动程序也可领取的AddDevice例程的驱动程序对象的指针。
// DeviceExtensionSize //0 给_DEVICE_OBJECT.DeviceExtension指定内存空间大小,具体看自己定义结构的大小
// DeviceName 设备名字
// DeviceType 设备类型 这里我们用FILE_DEVICE_UNKNOWN
// DeviceCharacteristics 设备特征信息 一般为0
// Exclusive 是否指定设备为独占 是为TRUE,否为FALSE
// DeviceObject 指针变量接收一个指向新创建的DEVICE_OBJECT结构。用来回传数据

// 返回值
// 调用成功会返回 STATUS_SUCCESS 如果出错会返回下列值
// STATUS_INSUFFICIENT_RESOURCES //资源不足
// STATUS_OBJECT_NAME_EXISTS //指定对象名存在
// STATUS_OBJECT_NAME_COLLISION //对象名有冲突


if (!NT_SUCCESS(status)) {
if (status == STATUS_INSUFFICIENT_RESOURCES) {
KdPrint(("资源不足 !"));
}
if (status == STATUS_OBJECT_NAME_EXISTS) {
KdPrint(("指定对象名存在!"));
}
if (status == STATUS_OBJECT_NAME_COLLISION) {
KdPrint(("对象名有冲突"));
}
KdPrint(("设备创建失败!"));
return status;
}
KdPrint(("设备创建成功!"));

pDevObj->Flags |= DO_BUFFERED_IO;

// 创建符号连接
RtlInitUnicodeString(&symLinkName, L"\\??\\DriverTest003");
status = IoCreateSymbolicLink(&symLinkName, &devName);

// IoCreateSymbolicLink
// 创建一个设备链接。驱动程序虽然有了设备名称,但是这种设备名称只能在内核 态可见,而对于应用程序是不可见的,因此,驱动需要要暴露一个符号链接,该链接指向真正的设备名称
// 参数:
// SymbolicLinkName Unicode字符串指针,是一个用户态可见的名称。
// DeviceName Unicode字符串指针,是驱动程序创建的设备对象名称。
// Return Value 如果符号链接创建成功 返回STATUS_SUCCESS

if (!NT_SUCCESS(status)) {
IoDeleteDevice(pDevObj); //status 等于0 就删除这个设备
// IoDeleteDevice 参数
// DeviceObject PDEVICE_OBJECT类型的指针,指向需要删除的设备对象 无返回值

return status;
}
return STATUS_SUCCESS;

}


VOID DDK_Unload(IN PDRIVER_OBJECT pDriverObject); // 前置说明卸载例程#pragma once

 

 

 

在源码文件中,包含该头文件,源码文件DriverTest003.c如下

 

#include<DriverTest003.h>

#pragma INITCODE
// TYPEDEF LONG NTSTATUS
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING B) {

// KdBreakPiont();
//__debugbreak(); 设置断点

KdPrint(("驱动加载成功...Success!"));

CreateMyDevice(pDriverObject); //创建相应的设备
pDriverObject->DriverUnload = DDK_Unload;

return(1);
}


#pragma PAGECODE

VOID DDK_Unload(IN PDRIVER_OBJECT pDriverObject) {

PDEVICE_OBJECT pDev; // 取得要删除的设备对象
UNICODE_STRING symLinkName;

pDev = pDriverObject->DeviceObject;
IoDeleteDevice(pDev); // 删除设备


RtlInitUnicodeString(&symLinkName, L"\\??\\DriverTest003"); // 取得符号链接的名字
IoDeleteSymbolicLink(&symLinkName); // 删除符号链接

KdPrint(("驱动成功卸载...OK!"));

// 删除所有设备
DbgPrint("卸载成功!");
}

 

 

 

这样我们就完成了驱动的正常卸载了!

 

 

 

联系我们
QQ
1024658
QQ群一
官方QQ群一
eMail
手机能收到
QQ群二
查看更多QQ群
近期评论

About