- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在磁盘驱动程序上开发了一个 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/
我在磁盘驱动程序上开发了一个 WDM 过滤驱动程序。我想发送一个异步请求将数据写入磁盘。当我在WriteDataIRPCompletion 函数中删除writeBuffer 内存时,windows 会
我是一名优秀的程序员,十分优秀!