我在磁盘驱动程序上开发了WDM筛选器驱动程序。我想发送一个异步请求以将数据写入磁盘。当我删除writeBuffer函数中的WriteDataIRPCompletion内存时,窗口将崩溃。

我的问题是:如何安全地释放writeBuffer内存而不会崩溃?

这是我的发送请求代码:

#pragma PAGEDCODE
NTSTATUS WriteToDeviceRoutine() {
    PMYDRIVER_WRITE_CONTEXT context = (PMYDRIVER_WRITE_CONTEXT)ExAllocatePool(NonPagedPool,sizeof(PMYDRIVER_WRITE_CONTEXT));
    context->writeBuffer = new(NonPagedPool) unsigned char[4096];

    PIRP pNewIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE,
         pdx->LowerDeviceObject,
         context->writeBuffer,(wroteRecordNodeCount<<SHIFT_BIT),
         &startingOffset,NULL);
   IoSetCompletionRoutine(pNewIrp,WriteDataIRPCompletion,context,TRUE,TRUE,TRUE);
   IoCallDriver(pdx->LowerDeviceObject,pNewIrp);
}

这是我的完成例程代码:
#pragma LOCKEDCODE
NTSTATUS WriteDataIRPCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP driverIrp,IN PVOID Context) {
   PMDL mdl,nextMdl;
   KdPrint((" WriteDataIRPCompletion \n"));
   PMYDRIVER_WRITE_CONTEXT writeContext = (PMYDRIVER_WRITE_CONTEXT) Context;
   if(driverIrp->MdlAddress!=NULL){
      for(mdl=driverIrp->MdlAddress;mdl!=NULL;mdl = nextMdl) {
         nextMdl = mdl->Next;
         MmUnlockPages(mdl);
         IoFreeMdl(mdl);
         KdPrint(("mdl clear\n"));
     }
     driverIrp->MdlAddress = NULL;
   }
   delete [] writeContext->writeBuffer;
   if(Context)
      ExFreePool(Context);

    KdPrint(("leave WriteDataIRPCompletion \n"));
    return STATUS_CONTINUE_COMPLETION;
}

最佳答案

你在下一行中出错

context = ExAllocatePool(NonPagedPool,sizeof(PMYDRIVER_WRITE_CONTEXT));

什么时候必须
context = ExAllocatePool(NonPagedPool,sizeof(MYDRIVER_WRITE_CONTEXT));

不是sizeof(PMYDRIVER_WRITE_CONTEXT)而是sizeof(MYDRIVER_WRITE_CONTEXT),您分配的不是结构而是指向它的指针。

仅当您的MYDRIVER_WRITE_CONTEXT包含单个字段writeBuffer且没有更多数据时,这不会产生错误。否则,您将覆盖分配的内存(仅是sizeof(PVOID)),这将导致创建错误

以及 IoBuildAsynchronousFsdRequest 的完成。不幸的是文档不是很好。在这里



但随后所有关注



但是,我们必须检查并获取IRP_DEALLOCATE_BUFFER|IRP_BUFFERED_IO,否则,我们可能会泄漏Irp->AssociatedIrp.SystemBuffer。需要下一个代码
if (Irp->Flags & IRP_BUFFERED_IO)
{
    if (Irp->Flags & IRP_INPUT_OPERATION)
    {
        if (!NT_ERROR(Irp->IoStatus.Status) && Irp->IoStatus.Information)
        {
            memcpy( Irp->UserBuffer, Irp->AssociatedIrp.SystemBuffer, Irp->IoStatus.Information );
        }
    }

    if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
    {
        ExFreePool(Irp->AssociatedIrp.SystemBuffer);
        Irp->AssociatedIrp.SystemBuffer = 0;
    }

    Irp->Flags &= ~(IRP_DEALLOCATE_BUFFER|IRP_BUFFERED_IO);
}

并在之后检查if (writeContext) ,使用已经毫无意义且毫无意义的writeContext->writeBuffer。确实您需要在context != NULL中检查WriteToDeviceRoutine()

10-08 12:41