admin 管理员组文章数量: 887007
在尝试运行《竹林蹊径 深入浅出Windows驱动开发》的第一个例子-HelloDRIVER时,在XP下没有问题,但在Win7下却发生蓝屏,蓝屏发生点在于卸载函数DriverUnload。
先看看卸载驱动的代码
VOID DriverUnload (
__in PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT deviceObject;
UNICODE_STRING linkName;
KdPrint(("Enter HelloDRIVER DriverUnload!\n"));
deviceObject = DriverObject->DeviceObject;
while(NULL != deviceObject)
{
PDEVICE_EXTENSION deviceExtesion =
(PDEVICE_EXTENSION)deviceObject->DeviceExtension;
// 删除符号链接与设备
linkName = deviceExtesion->SymbolicLink;
IoDeleteSymbolicLink(&linkName);
deviceObject = deviceObject->NextDevice;
IoDeleteDevice(deviceExtesion->DeviceObject);
}
KdPrint(("End of HelloDRIVER DriverUnload!\n"));
}
很通用的卸载驱动例程,按道理是不会出现问题的,从dump文件进行进一步分析,定位到deviceObject = deviceObject->NextDevice;这一句蓝屏,复制操作会导致蓝屏?什么鬼,再看下调用堆栈 原来还没到赋值语句,在处于IoDeleteSymbolicLink阶段就发生蓝屏了,于是就断点调试看下IoDeleteSymbolicLink的参数linkName是否正常,一调试发现memory can't access, 为什么会出现内存不可访问,于是追溯到DriverEntry,下面看下这个函数里面做了什么操作
NTSTATUS DriverEntry (
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
PDEVICE_OBJECT deviceObject;
PDEVICE_EXTENSION deviceExtension;
UNICODE_STRING symbolicLink;
UNICODE_STRING deviceName;
ULONG i;
KdPrint(("Enter HelloDRIVER DriverEntry!\n"));
UNREFERENCED_PARAMETER(RegistryPath);
RtlInitUnicodeString(&deviceName, L"\\Device\\HelloDRIVER");
// 处理派遣例程
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = DefaultDispatch;
}
DriverObject->DriverUnload = DriverUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DefaultDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DefaultDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = DefaultDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = DefaultDispatch;
// 创建设备
status = IoCreateDevice( DriverObject,
sizeof(DEVICE_EXTENSION),
&deviceName,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
&deviceObject);
if(!NT_SUCCESS(status))
{
return status;
}
deviceObject->Flags = DO_BUFFERED_IO;
deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
deviceExtension->DeviceObject = deviceObject;
deviceExtension->DeviceName = deviceName;
RtlInitUnicodeString(&symbolicLink, L"\\??\\HelloDRIVER");
deviceExtension->SymbolicLink = symbolicLink;
// 创建符号链接
status = IoCreateSymbolicLink(&symbolicLink, &deviceName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(deviceObject);
return status;
}
KdPrint(("End of HelloDRIVER DriverEntry!\n"));
return status;
}
重点在于这两句
RtlInitUnicodeString(&symbolicLink, L"\\??\\HelloDRIVER");
deviceExtension->SymbolicLink = symbolicLink;
在网上查找资料RtlInitUnicodeString并没有动态分配内存,而是指向应用,而由于
#pragma alloc_text(INIT, DriverEntry)
DriverEntry函数是运行完后就退出内存,所以 RtlInitUnicodeString(&deviceName, L"\\Device\\HelloDRIVER");这个赋值方式不可靠。
解决方案:
在头文件或者函数外声明一个全局变量来存储符号链接,如
WCHAR linkNameBuffer[] = L"\\??\\HelloDRIVER";
然后再在函数内
RtlInitUnicodeString(&symbolicLink, linkNameBuffer);
即可解决读取符号链接不可访问的问题。
总结:
1.Win7会出现蓝屏,而XP不会,可能涉及到IoDeleteSymbolicLink里面的实现,会判断字符串的合法性问题
2.INIT和PAGE的区别,在驱动加载入口函数要注意字符串变量的生命周期
3.学会利用windbg进行调试分析
版权声明:本文标题:关于《竹林蹊径 深入浅出Windows驱动开发》第一个例子在Win7下蓝屏 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1734803591h1670673.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论