IoAllocateIrp创建的IRP用IoFreeIrp删除蓝屏的问题
本人在看windows驱动开发技术详解,作者在第十一章提到用IoAllocateIrp内核函数创建IRP时,需要程序员调用IoFreeIrp内核函数删除IRP对象。
下面是驱动程序B调用驱动程序A的一段代码:
驱动B的部分代码:
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverB:Enter B HelloDDKRead\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING DeviceName;
RtlInitUnicodeString( &DeviceName, L"\\Device\\MyDDKDeviceA" );
PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
//得到设备对象指针
ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject);
KdPrint(("DriverB:FileObject:%x\n",FileObject));
KdPrint(("DriverB:DeviceObject:%x\n",DeviceObject));
if (!NT_SUCCESS(ntStatus))
{
KdPrint(("DriverB:IoGetDeviceObjectPointer() 0x%x\n", ntStatus ));
ntStatus = STATUS_UNSUCCESSFUL;
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverB:Leave B HelloDDKRead\n"));
return ntStatus;
}
KEVENT event;
KeInitializeEvent(&event,NotificationEvent,FALSE);
PIRP pNewIrp = IoAllocateIrp(DeviceObject->StackSize,FALSE);
KdPrint(("pNewIrp->UserEvent :%x\n",pNewIrp->UserEvent));
pNewIrp->UserEvent = &event;
IO_STATUS_BLOCK status_block;
pNewIrp->UserIosb = &status_block;
pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
//因为DriverA是BUFFER IO设备
pNewIrp->AssociatedIrp.SystemBuffer = NULL;
KdPrint(("DriverB:pNewIrp:%x\n",pNewIrp));
PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(pNewIrp);
stack->MajorFunction = IRP_MJ_READ;
stack->MinorFunction=IRP_MN_NORMAL;//0
stack->FileObject = FileObject;
//调用DriverA驱动
NTSTATUS status = IoCallDriver(DeviceObject,pNewIrp);
if (status == STATUS_PENDING) {
status = KeWaitForSingleObject(
&event,
Executive,
KernelMode,
FALSE, // Not alertable
NULL);
KdPrint(("STATUS_PENDING\n"));
}
ObDereferenceObject( FileObject );
IoFreeIrp(pNewIrp);//该句有问题!!!!
ntStatus = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverB:Leave B HelloDDKRead\n"));
return ntStatus;
}
驱动A中对相应IRP响应函数先把IRP挂起,然后定时三秒后结束IRP,部分代码如下:
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverA:Enter A HelloDDKRead\n"));
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pDevObj->DeviceExtension;
//将IRP设置为挂起
IoMarkIrpPending(pIrp);
//将挂起的IRP记录下来
pDevExt->currentPendingIRP = pIrp;
//定义3秒后将IRP_MJ_READ的IRP完成
ULONG ulMicroSecond = 3000000;
//将32位整数转化成64位整数
LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10*ulMicroSecond);
KeSetTimer(
&pDevExt->pollingTimer,
timeout,
&pDevExt->pollingDPC );
KdPrint(("DriverA:Leave A HelloDDKRead\n"));
//返回pending状态
return STATUS_PENDING;
}
#pragma LOCKEDCODE
VOID OnTimerDpc( IN PKDPC pDpc,
IN PVOID pContext,
IN PVOID SysArg1,
IN PVOID SysArg2 )
{
PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)pContext;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
PIRP currentPendingIRP = pdx->currentPendingIRP;
KdPrint(("DriverA:complete the Driver A IRP_MJ_READ irp!\n"));
//设置完成状态为STATUS_SUCCESS
currentPendingIRP->IoStatus.Status = STATUS_SUCCESS;
currentPendingIRP->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( currentPendingIRP, IO_NO_INCREMENT );
}
问题是上面驱动B的红色标注的代码IoFreeIrp(pNewIrp);有这行代码会蓝屏,去掉这行代码,程序没有蓝屏错误,张帆的书上没有这行代码,但是配套光盘上面有。查阅ddk帮助,好像说必须设置完成例程用来释放IRP,初学驱动,刚开始看书,完成例程我还没有看到,请各位指点下,解释下为什么蓝屏,多谢。
下面是驱动程序B调用驱动程序A的一段代码:
驱动B的部分代码:
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverB:Enter B HelloDDKRead\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING DeviceName;
RtlInitUnicodeString( &DeviceName, L"\\Device\\MyDDKDeviceA" );
PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
//得到设备对象指针
ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject);
KdPrint(("DriverB:FileObject:%x\n",FileObject));
KdPrint(("DriverB:DeviceObject:%x\n",DeviceObject));
if (!NT_SUCCESS(ntStatus))
{
KdPrint(("DriverB:IoGetDeviceObjectPointer() 0x%x\n", ntStatus ));
ntStatus = STATUS_UNSUCCESSFUL;
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverB:Leave B HelloDDKRead\n"));
return ntStatus;
}
KEVENT event;
KeInitializeEvent(&event,NotificationEvent,FALSE);
PIRP pNewIrp = IoAllocateIrp(DeviceObject->StackSize,FALSE);
KdPrint(("pNewIrp->UserEvent :%x\n",pNewIrp->UserEvent));
pNewIrp->UserEvent = &event;
IO_STATUS_BLOCK status_block;
pNewIrp->UserIosb = &status_block;
pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
//因为DriverA是BUFFER IO设备
pNewIrp->AssociatedIrp.SystemBuffer = NULL;
KdPrint(("DriverB:pNewIrp:%x\n",pNewIrp));
PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(pNewIrp);
stack->MajorFunction = IRP_MJ_READ;
stack->MinorFunction=IRP_MN_NORMAL;//0
stack->FileObject = FileObject;
//调用DriverA驱动
NTSTATUS status = IoCallDriver(DeviceObject,pNewIrp);
if (status == STATUS_PENDING) {
status = KeWaitForSingleObject(
&event,
Executive,
KernelMode,
FALSE, // Not alertable
NULL);
KdPrint(("STATUS_PENDING\n"));
}
ObDereferenceObject( FileObject );
IoFreeIrp(pNewIrp);//该句有问题!!!!
ntStatus = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverB:Leave B HelloDDKRead\n"));
return ntStatus;
}
驱动A中对相应IRP响应函数先把IRP挂起,然后定时三秒后结束IRP,部分代码如下:
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverA:Enter A HelloDDKRead\n"));
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pDevObj->DeviceExtension;
//将IRP设置为挂起
IoMarkIrpPending(pIrp);
//将挂起的IRP记录下来
pDevExt->currentPendingIRP = pIrp;
//定义3秒后将IRP_MJ_READ的IRP完成
ULONG ulMicroSecond = 3000000;
//将32位整数转化成64位整数
LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10*ulMicroSecond);
KeSetTimer(
&pDevExt->pollingTimer,
timeout,
&pDevExt->pollingDPC );
KdPrint(("DriverA:Leave A HelloDDKRead\n"));
//返回pending状态
return STATUS_PENDING;
}
#pragma LOCKEDCODE
VOID OnTimerDpc( IN PKDPC pDpc,
IN PVOID pContext,
IN PVOID SysArg1,
IN PVOID SysArg2 )
{
PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)pContext;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
PIRP currentPendingIRP = pdx->currentPendingIRP;
KdPrint(("DriverA:complete the Driver A IRP_MJ_READ irp!\n"));
//设置完成状态为STATUS_SUCCESS
currentPendingIRP->IoStatus.Status = STATUS_SUCCESS;
currentPendingIRP->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( currentPendingIRP, IO_NO_INCREMENT );
}
问题是上面驱动B的红色标注的代码IoFreeIrp(pNewIrp);有这行代码会蓝屏,去掉这行代码,程序没有蓝屏错误,张帆的书上没有这行代码,但是配套光盘上面有。查阅ddk帮助,好像说必须设置完成例程用来释放IRP,初学驱动,刚开始看书,完成例程我还没有看到,请各位指点下,解释下为什么蓝屏,多谢。
...全文
相关推荐
homework2-mpmc
homework2-mpmc
家庭果园种植管理-入门版-清新雅致.docx
家庭果园种植管理-入门版-清新雅致
年终工作总结-互联网-清新雅致.docx
年终工作总结-互联网-清新雅致
高校如何通过技术转移服务提升成果转化率,助力区域创新发展?.docx
科易网基于40亿+科创知识图谱数据库,深度探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。
明厨亮灶检测数据集17000张yolo格式划分训练和验证集.zip
数据集说明 样本分类输出(中文):cockroach,hairnet,no_gloves,no_hat,rat,with_mask,without_mask,smoke,phone,overflow,garbage,garbage_bin,chef_uniform,chef_hat 样本分类输出(英文):蟑螂,发网,无手套,无帽子,老鼠,有口罩,无口罩,烟雾,电话,溢出,垃圾,垃圾桶,制服,帽子 样本分类输出数量:14 训练集train: 15195个样本 验证集valid: 2785个样本 训练集和验证集样本比例:约5:1 yolo8训练命令行参考:yolo detect train model=yolov8n.pt data=detect_kitchen/data.yaml batch=32 epochs=1 imgsz=640 device=cuda


驱动开发/核心开发
