Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting... Please check out the Community Guidelines in the
Announcements and Administration Category, below.

SCSI, Storage lower filter create new SRB and IRP

I have got the below code from one of the Older Thread,

Hello all,

In my last thread "how to intercept SRBs?" I was successful in installing the
lower storage filter driver above Storport and being able to intercept SRBs
thanks to the help from the community.

I am now trying to create a new SRB to test task management function handling in
Miniport (SRB_FUNCTION_ABORT_COMMAND). Here is the code on how I am creating the
new SRB and IRP and forwarding and completing the request:

//In KMDF IRP_MJ_INTERNAL_DEVICE_CONTROL handles SCSI requests
NTSTATUS fltrSCSI(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) {

Stack = IoGetCurrentIrpStackLocation(pIrp);
SRBvar = Stack->Parameters.Scsi.Srb;

...

switch(pCdb->CDB10.OperationCode) {

case SCSIOP_READ:

AbortSRB = (PSCSI_REQUEST_BLOCK)ExAllocatePoolWithTag(NonPagedPool,
sizeof(SCSI_REQUEST_BLOCK), '1say');

if(AbortSRB == NULL) {

DbgPrintEx(0,0,__FUNCTION__ ": FAILURE IN ALLOCATING ABORT SRB
STRUCTURE\n");
}

else {

DbgPrintEx(0,0,__FUNCTION__ ": SUCCESS IN ALLOCATING ABORT SRB
STRUCTURE\n");
}

RtlZeroMemory(AbortSRB, sizeof(SCSI_REQUEST_BLOCK));

//According to msdn the following are the valid members for abort
AbortSRB->Function = SRB_FUNCTION_ABORT_COMMAND;
AbortSRB->TargetId = SRBvar->TargetId;
AbortSRB->PathId = SRBvar->PathId;
AbortSRB->Lun = SRBvar->Lun;
AbortSRB->NextSrb = SRBvar;

MakeAsyncReq(pDevObj, AbortSRB); //Create a new IRP with the abort
SRB to be sent down

...
}

//Make Async Request for an IRP containing an Abort SRB
NTSTATUS MakeAsyncReq(PDEVICE_OBJECT pDevObj, PSCSI_REQUEST_BLOCK AbortSRB) {

PIRP TaskIRP = NULL;
PIO_STACK_LOCATION nextStack= NULL;
PDEVICE_EXTENSION pDevExt = NULL;
KEVENT event;
NTSTATUS status;
IO_STATUS_BLOCK ioStatus;
pDevExt = (PDEVICE_EXTENSION) pDevObj->DeviceExtension;

KeInitializeEvent(&event, NotificationEvent, FALSE);

TaskIRP = IoAllocateIrp (pDevExt->pTarget->StackSize+1, FALSE);

if (TaskIRP == NULL) {

DbgPrintEx(0,0, __FUNCTION__ ": Failure in allocating TaskIRP\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
else {

DbgPrintEx(0,0, __FUNCTION__ ": Successfully created new TaskIRP\n");
}

nextStack = IoGetNextIrpStackLocation(TaskIRP);

nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.Scsi.Srb = AbortSRB;
AbortSRB->OriginalRequest = TaskIRP;

IoSetCompletionRoutine(TaskIRP, TaskMangComplete, NULL, TRUE, TRUE, TRUE);

TaskIRP->UserIosb = &ioStatus;
TaskIRP->UserEvent = &event;

IoMarkIrpPending(TaskIRP);

status = IoCallDriver(pDevExt->pTarget, TaskIRP);

if (status == STATUS_PENDING) {

DbgPrintEx(0,0, __FUNCTION__ "LOWER DRIVER RETURNED PENDING FOR ABORT
REQUEST!\n");
(VOID) KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = ioStatus.Status;
}

return status;

}

//IO completion routine for the Abort request
NTSTATUS TaskMangComplete(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp,
_In_reads_opt_(_Inexpressible_("Varies")) PVOID Context) {

PSCSI_REQUEST_BLOCK SRB;
PIO_STACK_LOCATION stack;
UNREFERENCED_PARAMETER(pDevObj);
UNREFERENCED_PARAMETER(Context);

stack = IoGetCurrentIrpStackLocation(pIrp);
SRB = stack->Parameters.Scsi.Srb;

if(SRB == NULL) {

DbgPrintEx(0,0, __FUNCTION__ "ABORT SRB IS INVALID!!!\n");
}

KeSetEvent(pIrp->UserEvent, IO_NO_INCREMENT, FALSE);

IoFreeIrp(pIrp);


//Since IRP was created by filter driver we need to return this value in order
to prevent the IO manager from completing the IRP up the driver stack
return STATUS_MORE_PROCESSING_REQUIRED;
}

The problem I am facing is that when i send the new IRP with the new SRB down to
Storport it does not forward it down to Miniport. In my completion routine for
the new IRP the memory for the SRB is invalid (null) even though before I call
the lower driver the SRB is not NULL. I am at a loss here on why this is
happening, the code is based on templates from msdn and resources on this site.
If anyone has any inputs or see anything wrong in my logic on why Storport
returns my request with a null SRB I would really appreciate it

Thanks for the help,

Yassir M.

Comments

  • And the Reply from Girish for the above issue is as follows,

    Based on my previous experiments, I believe SRB_FUNCTION_ABORT_COMMAND is an
    un-supported request in the Storport context (although I do not find any
    documentation indicating so). Ideally, this is reported as part of the the
    SrbStatus during the completion routine, which brings us to the next part of
    your question. You need to set up your current stack location as well with the
    SRB pointer before issuing the request down.

    Girish.
  • Could you please anyone help me what does Girish mean by the below statement,

    "You need to set up your current stack location as well with the
    SRB pointer before issuing the request down"

    and what is the corresponding code changes has to be done in the above code to fulfill the solution suggegted by Girish.

    I am bit new to driver development and any quick help will be highly appreciated
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!