gpt4 book ai didi

c++ - 带有 IRP_MJ_WRITE 的 IoBuildAsynchronousFsdRequest

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:45:29 26 4
gpt4 key购买 nike

我在磁盘驱动程序上开发了一个 WDM 过滤驱动程序。我想发送一个异步请求将数据写入磁盘。当我在WriteDataIRPCompletion 函数中删除writeBuffer 内存时,windows 会崩溃。

我的问题是:如何在不崩溃的情况下安全地释放 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 的完成.不幸的是文档不是很好。在此声明

Before calling IoFreeIrp, an additional step is required to free the buffer for an IRP built by IoBuildAsynchronousFsdRequest if the following are all true:

The buffer was allocated from system memory pool.

但是所有的注意力都在

The Irp->MdlAddress field is non-NULL.

但是我们必须检查 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) after 使用 writeContext->writeBuffer 已经毫无意义和无意义。你真的需要在 WriteToDeviceRoutine()

中检查 context != NULL

关于c++ - 带有 IRP_MJ_WRITE 的 IoBuildAsynchronousFsdRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39635484/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com