我在磁盘驱动程序上开发了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()