Send SCSI srb to physical device in disk filter adddevice routine

Hi all:

I send a SCSI srb request to physical device in disk filter
adddevice routine to read disk data. It works well on xp, but halt on vista,
here is the stack:

80399878 819053bf 845b0668 845b06f0 00000000 nt!KiSwapContext+0x26

803998bc 818a2cf8 845b0668 849ed630 845bdb08 nt!KiSwapThread+0x44f

80399910 82b1f416 80399948 00000000 00000000 nt!KeWaitForSingleObject+0x492

80399960 82b1fb05 849ed630 00000003 00000000 Shield!ReadWriteAtapi+0x2a6
[c:\xtm\driver\shdsys\readwrite.c @ 203]

80399988 82b20a7c 85054850 00000003 00000000 Shield!SHDReadWriteSector+0xc5
[c:\xtm\driver\shdsys\readwrite.c @ 530]

803999b4 82b1a34d 85054850 85054798 00000000 Shield!SHDInitDisk+0x4c
[c:\xtm\driver\shdsys\readwrite.c @ 1615]

803999d0 8185a560 84fce0d0 849ed630 845bdb08 Shield!SHDAddDevice+0x15d
[c:\xtm\driver\shdsys\wdminit.c @ 167]

803999ec 819b70aa 84fce0d0 82b1a1f0 00000006 nt!PpvUtilCallAddDevice+0x19

80399a14 819b0e34 84fce0d0 82b1a1f0 00000004 nt!PnpCallAddDevice+0x7e

80399af0 81993ae5 04000000 850549c0 00000000 nt!PipCallDriverAddDevice+0x477

80399b08 81859a56 81980530 00000000 00000000 nt!PiProcessAddBootDevices+0x4e

80399b44 818598f8 00000000 833ca4d8 849ed630 nt!PnpDeviceActionWorker+0x14c

80399b60 81ba6ac9 849ed630 00000000 00000000 nt!PnpRequestDeviceAction+0x127

80399b84 81993a58 800000d0 80399ba8 85053748
nt!PipAddDevicesToBootDriverWorker+0x21

80399bc8 81ba706c 800000d0 85053748 808117c8
nt!PipApplyFunctionToServiceInstances+0x141

80399c34 81ba9ff1 808117c8 8080f150 00000000
nt!IopInitializeBootDrivers+0x3a4

80399c94 81badcb3 808117c8 845b0990 845b0668 nt!IoInitSystem+0x5af

80399d74 819a6af1 80399dc0 81a23a1c 808117c8
nt!Phase1InitializationDiscard+0xb86

80399d7c 81a23a1c 808117c8 cefdf87e 00000000 nt!Phase1Initialization+0xd

80399dc0 8187ca3e 819a6ae4 808117c8 00000000 nt!PspSystemThreadStartup+0x9d

Code:

NTSTATUS status;

PSCSI_REQUEST_BLOCK srb;

PSENSE_DATA sense;

COMPLETE_CONTEXT_ATAPI ctx;

PIRP irp;

PMDL mdl;

//IO_STATUS_BLOCK isb;

PIO_STACK_LOCATION isl;

PVOID psense;

PRKTHREAD pThread = KeGetCurrentThread();

srb=myalloc(sizeof(SCSI_REQUEST_BLOCK));

if(!srb)

{

return STATUS_INSUFFICIENT_RESOURCES;

}

sense=myalloc(sizeof(SENSE_DATA));

psense=sense;

if(!sense)

{

myfree(srb);

return STATUS_INSUFFICIENT_RESOURCES;

}

RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));

RtlZeroMemory(sense, sizeof(SENSE_DATA));

srb->Length=sizeof(SCSI_REQUEST_BLOCK);

.

srb->SenseInfoBufferLength=sizeof(SENSE_DATA);

if(dwReadOrWrite==IRP_MJ_READ)

srb->SrbFlags=SRB_FLAGS_DATA_IN;

else

srb->SrbFlags=SRB_FLAGS_DATA_OUT;

if(dwReadOrWrite==IRP_MJ_READ)

srb->SrbFlags|=SRB_FLAGS_ADAPTER_CACHE_ENABLE;

srb->SrbFlags|=SRB_FLAGS_DISABLE_AUTOSENSE; .

KeInitializeEvent(&ctx.Event, SynchronizationEvent, FALSE);

ctx.srb = srb;

irp=IoAllocateIrp(pPhysicalDevice->StackSize, FALSE);

mdl=IoAllocateMdl(pBuffer, dwSectorCount<<9, FALSE, FALSE, irp);

irp->MdlAddress=mdl;

if(!mdl){

myfree(srb);

myfree(psense);

IoFreeIrp(irp);

return STATUS_INSUFFICIENT_RESOURCES;

}

MmProbeAndLockPages(mdl,0,(dwReadOrWrite == IRP_MJ_READ ? IoReadAccess
: IoWriteAccess));

srb->OriginalRequest=irp;

irp->Flags=IRP_SYNCHRONOUS_API|IRP_NOCACHE;

irp->Tail.Overlay.Thread=PsGetCurrentThread();

isl=IoGetNextIrpStackLocation(irp);

isl->MajorFunction=IRP_MJ_SCSI;

isl->Parameters.Scsi.Srb=srb;

IoSetCompletionRoutine(irp, IrpCompletionRoutine_ATAPI, &ctx, TRUE,
TRUE, TRUE);

status=IoCallDriver(pPhysicalDevice,irp);

if (status == STATUS_PENDING)

{

KeWaitForSingleObject(&ctx.Event, Executive, KernelMode, FALSE,
NULL); // never return

status = irp->IoStatus.Status;

}

if(srb->SenseInfoBuffer!=psense&&srb->SenseInfoBuffer)

ExFreePool(srb->SenseInfoBuffer);

.

if (status != STATUS_SUCCESS)

{

KdPrint((“ReadWriteAtapi return %x, offset=%x, count=%x
readorwrite=%x\n” ,

status, dwBeginSector, dwSectorCount, dwReadOrWrite));

}

return status;

IocallDriver returns STATUS_PENDING, but the call back set by
IoSetCompleteRoutine is never called. So the wait is never satisfied. Is
storport a little different from scsiport? Is it ready at adddevice?

Regards

Haibo

>

Is storport a little different from scsiport? Is it ready at adddevice?

Vista also has a scsiport support. Why do you want to send SRB to disk
in AddDevice routine? I don’t think disk driver cannot give you a
certain assumption that it’s ready before START_DEVICE PnP IRP complete.

thanks - wayne

I want to read data from disk to decide how will I initialize this disk

Regards
Haibo

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Wayne Gong
Sent: Tuesday, July 07, 2009 12:59 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Send SCSI srb to physical device in disk filter
adddevice routine

Is storport a little different from scsiport? Is it ready at adddevice?

Vista also has a scsiport support. Why do you want to send SRB to disk
in AddDevice routine? I don’t think disk driver cannot give you a
certain assumption that it’s ready before START_DEVICE PnP IRP complete.

thanks - wayne


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> I send a SCSI srb request to physical device in disk filter adddevice routine to read disk data.

AddDevice is too early to send IO requests, try in Post path (completion routine) of MN_START_DEVICE.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

The only SRB you’re allowed to send before the device has been started is SRB_FUNCTION_CLAIM_DEVICE. No other SRB is supported.

-p

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Haibo
Sent: Monday, July 06, 2009 9:48 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Send SCSI srb to physical device in disk filter adddevice routine

Hi all:
I send a SCSI srb request to physical device in disk filter adddevice routine to read disk data. It works well on xp, but halt on vista, here is the stack:

80399878 819053bf 845b0668 845b06f0 00000000 nt!KiSwapContext+0x26
803998bc 818a2cf8 845b0668 849ed630 845bdb08 nt!KiSwapThread+0x44f
80399910 82b1f416 80399948 00000000 00000000 nt!KeWaitForSingleObject+0x492
80399960 82b1fb05 849ed630 00000003 00000000 Shield!ReadWriteAtapi+0x2a6 [c:\xtm\driver\shdsys\readwrite.c @ 203]
80399988 82b20a7c 85054850 00000003 00000000 Shield!SHDReadWriteSector+0xc5 [c:\xtm\driver\shdsys\readwrite.c @ 530]
803999b4 82b1a34d 85054850 85054798 00000000 Shield!SHDInitDisk+0x4c [c:\xtm\driver\shdsys\readwrite.c @ 1615]
803999d0 8185a560 84fce0d0 849ed630 845bdb08 Shield!SHDAddDevice+0x15d [c:\xtm\driver\shdsys\wdminit.c @ 167]
803999ec 819b70aa 84fce0d0 82b1a1f0 00000006 nt!PpvUtilCallAddDevice+0x19
80399a14 819b0e34 84fce0d0 82b1a1f0 00000004 nt!PnpCallAddDevice+0x7e
80399af0 81993ae5 04000000 850549c0 00000000 nt!PipCallDriverAddDevice+0x477
80399b08 81859a56 81980530 00000000 00000000 nt!PiProcessAddBootDevices+0x4e
80399b44 818598f8 00000000 833ca4d8 849ed630 nt!PnpDeviceActionWorker+0x14c
80399b60 81ba6ac9 849ed630 00000000 00000000 nt!PnpRequestDeviceAction+0x127
80399b84 81993a58 800000d0 80399ba8 85053748 nt!PipAddDevicesToBootDriverWorker+0x21
80399bc8 81ba706c 800000d0 85053748 808117c8 nt!PipApplyFunctionToServiceInstances+0x141
80399c34 81ba9ff1 808117c8 8080f150 00000000 nt!IopInitializeBootDrivers+0x3a4
80399c94 81badcb3 808117c8 845b0990 845b0668 nt!IoInitSystem+0x5af
80399d74 819a6af1 80399dc0 81a23a1c 808117c8 nt!Phase1InitializationDiscard+0xb86
80399d7c 81a23a1c 808117c8 cefdf87e 00000000 nt!Phase1Initialization+0xd
80399dc0 8187ca3e 819a6ae4 808117c8 00000000 nt!PspSystemThreadStartup+0x9d

Code:

NTSTATUS status;
PSCSI_REQUEST_BLOCK srb;
PSENSE_DATA sense;
COMPLETE_CONTEXT_ATAPI ctx;
PIRP irp;
PMDL mdl;
//IO_STATUS_BLOCK isb;
PIO_STACK_LOCATION isl;
PVOID psense;

PRKTHREAD pThread = KeGetCurrentThread();

srb=myalloc(sizeof(SCSI_REQUEST_BLOCK));
if(!srb)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

sense=myalloc(sizeof(SENSE_DATA));
psense=sense;
if(!sense)
{
myfree(srb);
return STATUS_INSUFFICIENT_RESOURCES;
}

RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
RtlZeroMemory(sense, sizeof(SENSE_DATA));
srb->Length=sizeof(SCSI_REQUEST_BLOCK);

srb->SenseInfoBufferLength=sizeof(SENSE_DATA);
if(dwReadOrWrite==IRP_MJ_READ)
srb->SrbFlags=SRB_FLAGS_DATA_IN;
else
srb->SrbFlags=SRB_FLAGS_DATA_OUT;

if(dwReadOrWrite==IRP_MJ_READ)
srb->SrbFlags|=SRB_FLAGS_ADAPTER_CACHE_ENABLE;

srb->SrbFlags|=SRB_FLAGS_DISABLE_AUTOSENSE; …
KeInitializeEvent(&ctx.Event, SynchronizationEvent, FALSE);
ctx.srb = srb;
irp=IoAllocateIrp(pPhysicalDevice->StackSize, FALSE);
mdl=IoAllocateMdl(pBuffer, dwSectorCount<<9, FALSE, FALSE, irp);
irp->MdlAddress=mdl;
if(!mdl){
myfree(srb);
myfree(psense);
IoFreeIrp(irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
MmProbeAndLockPages(mdl,0,(dwReadOrWrite == IRP_MJ_READ ? IoReadAccess : IoWriteAccess));
srb->OriginalRequest=irp;
irp->Flags=IRP_SYNCHRONOUS_API|IRP_NOCACHE;
irp->Tail.Overlay.Thread=PsGetCurrentThread();
isl=IoGetNextIrpStackLocation(irp);
isl->MajorFunction=IRP_MJ_SCSI;
isl->Parameters.Scsi.Srb=srb;
IoSetCompletionRoutine(irp, IrpCompletionRoutine_ATAPI, &ctx, TRUE, TRUE, TRUE);
status=IoCallDriver(pPhysicalDevice,irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&ctx.Event, Executive, KernelMode, FALSE, NULL); // never return
status = irp->IoStatus.Status;
}

if(srb->SenseInfoBuffer!=psense&&srb->SenseInfoBuffer)
ExFreePool(srb->SenseInfoBuffer);

if (status != STATUS_SUCCESS)
{
KdPrint((“ReadWriteAtapi return %x, offset=%x, count=%x readorwrite=%x\n” ,
status, dwBeginSector, dwSectorCount, dwReadOrWrite));
}

return status;

IocallDriver returns STATUS_PENDING, but the call back set by IoSetCompleteRoutine is never called. So the wait is never satisfied. Is storport a little different from scsiport? Is it ready at adddevice?

Regards
Haibo


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Haibo wrote:

I want to read data from disk to decide how will I initialize
this disk

Fascinating. How can you read from the disk before it’s initialized?