I got what you are saying but in many cases i saw that we are not
allocating MDLs explicitely but still we are freeing it. Here are two
cases
********** From Serial.C in DDK samples.
irp = IoBuildAsynchronousFsdRequest(fRead? IRP_MJ_READ: IRP_MJ_WRITE,
DevExt->LowerDevObj,
Buffer,
BuffLen,
&StartingOffset,
NULL);
if (irp != NULL)
{
status = IoAcquireRemoveLock(&DevExt->RemoveLock, irp);
if (NT_SUCCESS(status))
{
IoSetCompletionRoutine(irp,
AsyncReadWriteCompletion,
DevExt,
TRUE,
TRUE,
TRUE);
******** Completion Routine *******
NTSTATUS INTERNAL
AsyncReadWriteCompletion(
IN PDEVICE_OBJECT DevObj,
IN PIRP Irp,
IN PDEVICE_EXTENSION DevExt
)
{
TRACEPROC(“AsyncReadWriteCompletion”, 2)
NTSTATUS status = Irp->IoStatus.Status;
TRACEENTER((“(DevObj=%p,Irp=%p,devext=%p,Status=%x)\n”,
DevObj, Irp, DevExt, status));
if (status == STATUS_CANCELLED)
{
TRACEWARN((“AsyncReadWrite IRP was cancelled.\n”));
}
else if (!NT_SUCCESS(status))
{
TRACEWARN((“AsyncReadWrite irp failed (status=%x).\n”, status));
}
IoReleaseRemoveLock(&DevExt->RemoveLock, Irp);
IoFreeIrp(Irp);
status = STATUS_MORE_PROCESSING_REQUIRED;
TRACEEXIT((“=%x\n”, status));
return status;
} //AsyncReadWriteCompletion
********************************************
In this case I dont see any IoFreeMdl getting called. The buffer here was
not allocated using any MDL function. where as in the other example.
************** From Verfysup.C in DDK samples. ************
Irp = IoBuildAsynchronousFsdRequest( IRP_MJ_WRITE,
Vcb->TargetDeviceObject,
(PVOID)Sector,
WriteLength,
&Offset,
NULL );
if ( Irp == NULL ) {
try_return(NOTHING);
}
//
// Make this operation write-through. It never hurts to try
to be
// safer about this, even though we aren’t logged.
//
SetFlag( IoGetNextIrpStackLocation( Irp )->Flags,
SL_WRITE_THROUGH );
//
// Set up the completion routine
//
IoSetCompletionRoutine( Irp,
FatMarkVolumeCompletionRoutine,
&Event,
TRUE,
TRUE,
TRUE );
…
…
…
// Clean up the Irp and Mdl
//
if (Irp) {
//
// If there is an MDL (or MDLs) associated with this I/O
// request, Free it (them) here. This is accomplished by
// walking the MDL list hanging off of the IRP and
deallocating
// each MDL encountered.
//
while (Irp->MdlAddress != NULL) {
PMDL NextMdl;
NextMdl = Irp->MdlAddress->Next;
MmUnlockPages( Irp->MdlAddress );
IoFreeMdl( Irp->MdlAddress );
Irp->MdlAddress = NextMdl;
}
IoFreeIrp( Irp );
}
********* Completion routine **********
NTSTATUS
FatMarkVolumeCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Contxt
)
{
//
// Set the event so that our call will wake up.
//
KeSetEvent( (PKEVENT)Contxt, 0, FALSE );
UNREFERENCED_PARAMETER( DeviceObject );
UNREFERENCED_PARAMETER( Irp );
return STATUS_MORE_PROCESSING_REQUIRED;
}
**********************************************
In this case the buffer, “sector” was the return value from CcPinRead(…).
Can someone explain why its different in these two places.
Thanks
Brain