Hello Everyone,
I am trying to write a simple function that will take an IRP sent to
my filter driver and make a copy of the IRP for each volume I want to write
to. The function then sends each newly allocated IRP down to the next lower
level driver. My problem is that the volumes (drives) that it is writing to
seem to be activated (the light goes on) when I send the IRPs down, yet,
when I use a drive hex editor I find that the information is not being
written to any of the member volumes. The WriteToMember routine is called
from a dispatch routine which supplies it with the original IRP. (The
original IRP is processed from the calling function.) The only volume that
is being written to is the volume that the original IRP is intended for. I
noticed that the debug print statement in MemberCompletionRoutine shows that
the byteoffest and length of the IRP sent to it are each 0 even though I
verified that they are not zero before calling the lower level driver.
However, the debug print statement showing IoStatus.Information in
MemberCompletionRoutine indicates the correct length in bytes of the
transfer.
Does the IRP sent back in a completion routine generally set the
bytelength and byteoffset to 0 after a write operation? Has anyone had
similar problems writing information to lower level drivers?
I am new to device driver writing and I would appreciate any help at
all.
Thank you for your time.
TROUBLED CODE FOLLOWS:
NTSTATUS WriteToMember( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
PDEVICE_OBJECT targetDeviceObject;
PANUBIS_DEVICE_EXTENSION deviceExtension, memberDeviceExtension;
PIO_STACK_LOCATION orgIrpStack;
PIO_STACK_LOCATION nextIrpStack;
PIO_STACK_LOCATION currentIrpStack;
PIRP memberIrp;
NTSTATUS status;
KEVENT Event;
Int i;
IoMarkIrpPending(Irp);
KeInitializeEvent(&Event,NotificationEvent,FALSE);
deviceExtension = DeviceObject->DeviceExtension;
orgIrpStack = IoGetCurrentIrpStackLocation( Irp );
for( i=deviceExtension->NumberMembers-1; i > 0; --i)
{
targetDeviceObject = deviceExtension->Members[i];
memberDeviceExtension =
(PMYDEVICE_EXTENSION)targetDeviceObject->DeviceExtension;
if(memberDeviceExtension->DriveNumber == 0xFFFFFFFF ||
memberDeviceExtension->DriveNumber == 0xFFFFFFFE)
{
KdPrint((“\t\tMember #%d is bad\n”, i));
continue;
}
KeClearEvent(&Event);
memberIrp = IoAllocateIrp(
(CCHAR)(DeviceObject->StackSize+1), FALSE );
if(memberIrp == NULL)
{
KdPrint((“\tSTATUS_INSUFFICIENT_RESOURCES\n”));
return STATUS_INSUFFICIENT_RESOURCES;
}
memberIrp->RequestorMode = Irp->RequestorMode;
memberIrp->Flags = IRP_WRITE_OPERATION;
memberIrp->MdlAddress = Irp->MdlAddress;
IoSetNextIrpStackLocation( memberIrp );
currentIrpStack = IoGetCurrentIrpStackLocation( memberIrp );
currentIrpStack->DeviceObject = targetDeviceObject;
currentIrpStack->Parameters.Write.Key = 99;
nextIrpStack = IoGetNextIrpStackLocation( memberIrp );
nextIrpStack->MajorFunction = orgIrpStack->MajorFunction;
nextIrpStack->MinorFunction = orgIrpStack->MinorFunction;
nextIrpStack->Flags = orgIrpStack->Flags;
nextIrpStack->Control = orgIrpStack->Control;
nextIrpStack->Parameters.Write.Length =
orgIrpStack->Parameters.Write.Length;
nextIrpStack->Parameters.Write.Key = 42;
nextIrpStack->Parameters.Write.ByteOffset =
orgIrpStack->Parameters.Write.ByteOffset;
nextIrpStack->FileObject = orgIrpStack->FileObject;
IoSetCompletionRoutine( memberIrp, MemberCompleteRoutine,
&Event, TRUE, TRUE, TRUE );
status = IoCallDriver( targetDeviceObject, memberIrp );
if( status != STATUS_PENDING )
{
KdPrint((“\t\tUNEXPECTED Result from IoCallDriver.
status=0x%X\n”, status));
}
KeWaitForSingleObject(Event,Executive,KernelMode,FALSE,NULL);
}
return STATUS_PENDING;
}
NTSTATUS MemberCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp, IN PVOID Context)
{
PANUBIS_DEVICE_EXTENSION deviceExtension;
PIO_STACK_LOCATION currentIrpStack;
if(Irp->PendingReturned)
IoMarkIrpPending(Irp);
if(!NT_SUCCESS(Irp->IoStatus.Status))
{
//mark the drive as bad and needs processing
if( DeviceObject != NULL )
{
deviceExtension = DeviceObject->DeviceExtension;
deviceExtension->DriveNumber = 0xFFFFFFFF;
}
}
KdPrint((“Irp->IoStatus.Information=0x%X\n”,
Irp->IoStatus.Information));
KdPrint((" Length=0x%X, ByteOffset=0x%X, Key=%d\n",
currentIrpStack->Parameters.Write.Length,
currentIrpStack->Parameters.Write.ByteOffset,
currentIrpStack->Parameters.Write.Key));
IoFreeIrp(Irp);
if(Context)
{
KeSetEvent(Context,LOW_REALTIME_PRIORITY,FALSE);
}
return STATUS_MORE_PROCESSING_REQUIRED;
}