How to call DriverStartIo directly

Hi,

I am sending an SRB using IoCallDriver to a disk driver. After some examination I see that the Irp is being queued and then DriverObject->DriverStartIo (which is ScsiPortStartIo in my case) is being called to process the Irp.

Is there a way to directly call DriverObject->DriverStartIo function from my driver (around the queue)?

I have now replaced the IoCallDriver call with these three lines:

//
// Must be at DISPATCH_LEVEL
//
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);

DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);

KeLowerIrql(OldIrql);

… but I get a BSOD :frowning:

Can I directly call the DriverStartIo or should I perform some additional actions first? Should the Irp be changed in some way so that the DriverStartIo accepts it? What am I doing wrong?

Help is much appreciated.

Regards,
Erik

You should not do this. One of the features of StartIo is it can be
specified to be one request at a time. IIRC that is how the SCSIPort
handles it. So your direct call is violating all the assumed
synchronization of the routine.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

-----Original Message-----
From: xxxxx@surfright.nl [mailto:xxxxx@surfright.nl]
Posted At: Friday, June 04, 2010 6:21 PM
Posted To: ntdev
Conversation: How to call DriverStartIo directly
Subject: How to call DriverStartIo directly

Hi,

I am sending an SRB using IoCallDriver to a disk driver. After some
examination I see that the Irp is being queued and then DriverObject-
>DriverStartIo (which is ScsiPortStartIo in my case) is being called
to
process the Irp.

Is there a way to directly call DriverObject->DriverStartIo function
from my
driver (around the queue)?

I have now replaced the IoCallDriver call with these three lines:

//
// Must be at DISPATCH_LEVEL
//
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);

DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);

KeLowerIrql(OldIrql);

… but I get a BSOD :frowning:

Can I directly call the DriverStartIo or should I perform some
additional
actions first? Should the Irp be changed in some way so that the
DriverStartIo
accepts it? What am I doing wrong?

Help is much appreciated.

Regards,
Erik

__________ Information from ESET Smart Security, version of virus
signature
database 5173 (20100604) __________

The message was checked by ESET Smart Security.

http://www.eset.com

If you like to hack, you should really disassemble IoStartPacket, IoStartNextPacket(ByKey) and IoCancelIrp(optional reading). You will understand why you should not do that.

Calvin

Rather than ask what you’re doing wrong, which is trying to call that
function directly and therefore doing an end-run around ScsiPort, tell us
what you want to do. If you want to stay a miniport under ScsiPort you
cannot do that. You only alternative would be to write your own port driver,
which would mean your about 20 years behind ScsiPort in debug and
reliability.

Gary G. Little
H (952) 223-1349
C (952) 454-4629
xxxxx@comcast.net

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@surfright.nl
Sent: Friday, June 04, 2010 5:21 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] How to call DriverStartIo directly

Hi,

I am sending an SRB using IoCallDriver to a disk driver. After some
examination I see that the Irp is being queued and then
DriverObject->DriverStartIo (which is ScsiPortStartIo in my case) is being
called to process the Irp.

Is there a way to directly call DriverObject->DriverStartIo function from my
driver (around the queue)?

I have now replaced the IoCallDriver call with these three lines:

//
// Must be at DISPATCH_LEVEL
//
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);

DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);

KeLowerIrql(OldIrql);

… but I get a BSOD :frowning:

Can I directly call the DriverStartIo or should I perform some additional
actions first? Should the Irp be changed in some way so that the
DriverStartIo accepts it? What am I doing wrong?

Help is much appreciated.

Regards,
Erik


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

__________ Information from ESET Smart Security, version of virus signature
database 5173 (20100604) __________

The message was checked by ESET Smart Security.

http://www.eset.com

__________ Information from ESET Smart Security, version of virus signature
database 5173 (20100604) __________

The message was checked by ESET Smart Security.

http://www.eset.com

> You only alternative would be to write your own

port driver, which would mean your about 20 years
behind ScsiPort in debug and reliability.

scsiport is amazingly buggy even today given that it has 20yr of mileage. And a feature-poor model. Too bad it’s the only option for wxp and wxp refuses to die anytime soon.

Now Calvin, I didn’t say SCSIPORT was bug free, I said any new driver that
hits the bricks today has a ton of catching up to do to be as good as
SCSIPORT. At Seagate we did that for diagnostic purposes, providing our own
port driver. When they laid me off 18 months ago it was working across
several adapters, but even after 5 years it was FAR from bug free.

Gary G. Little
H (952) 223-1349
C (952) 454-4629
xxxxx@comcast.net

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.ca
Sent: Friday, June 04, 2010 9:28 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] How to call DriverStartIo directly

You only alternative would be to write your own port driver, which
would mean your about 20 years behind ScsiPort in debug and
reliability.

scsiport is amazingly buggy even today given that it has 20yr of mileage.
And a feature-poor model. Too bad it’s the only option for wxp and wxp
refuses to die anytime soon.


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

“Don Burn” wrote in message news:xxxxx@ntdev…
> You should not do this. One of the features of StartIo is it can be
> specified to be one request at a time. IIRC that is how the SCSIPort
> handles it. So your direct call is violating all the assumed
> synchronization of the routine.

After reading about StartIo here:
http://www.osronline.com/ddkx/kmarch/irps_61bb.htm

… I thought that the StartIo function itself is responsible for its
synchronization. So calling it would not be a problem?!?

wrote in message news:xxxxx@ntdev…
> If you like to hack, you should really disassemble IoStartPacket,
> IoStartNextPacket(ByKey) and IoCancelIrp(optional reading).
> You will understand why you should not do that.

The IoStartPacket either calls the device’s StartIO routine with the Irp or
if the device is busy, it is queued.

Perhaps waiting for the queue to become empty will help?

Or should I strongly think about not doing this at all?

Erik

FYI, I am fighting against a modern rootkit. That is the reason for this
question.

Erik

> I have now replaced the IoCallDriver call with these three lines:

//
// Must be at DISPATCH_LEVEL
//
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
KeLowerIrql(OldIrql);
… but I get a BSOD :frowning:

Simply directly calling DriverStartIo would not work. Without using IoCallDriver, the IRP stack location will not be properly “advanced” for the driver receiving the IRP.

Erik, before call StartIo, as you write:
DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
you need queue this request at device object list by call KeInsertByKeyDeviceQueue or KeInsertDeviceQueue like this

KeInsertByKeyDeviceQueue( &devObj->DeviceQueue,
&Irp->Tail.Overlay.DeviceQueueEntry,
*Key );

or

KeInsertDeviceQueue( &deviceObj->DeviceQueue,
&Irp->Tail.Overlay.DeviceQueueEntry );

Your explanation is perhaps more peculiar than your original post, which was
hugely peculiar. But I’ll play, how is your solution supposed to help you in
your fight against this alleged root kit?

By the way, the general procedure for ‘fighting root kits’ involves offline
repair of the boot disk. Attempting to disinfect a root kit while it is
active from within an online system is a losing game.

Any advice to continue down the path you are on is, in my opinion, vastly
misguided.
Mark Roddy

On Sat, Jun 5, 2010 at 3:54 AM, Erik wrote:

> FYI, I am fighting against a modern rootkit. That is the reason for this
> question.
>
>
> Erik
>
> —
> 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
>

No he does not! you send the irp via iocalldriver. As you see you think you are doing something on behalf of the other driver, you are screwed. It could be in some cases scsiport is going to use start io or when you call startio another processor is executing startio as well and what the driver thought was synchronized code becomes concurrent.

Just send the same IRP the right way. If there is a rootkit in the way, wipe the machine.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yandex.ru
Sent: Saturday, June 05, 2010 6:37 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] How to call DriverStartIo directly

Erik, before call StartIo, as you write:
DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
you need queue this request at device object list by call KeInsertByKeyDeviceQueue or KeInsertDeviceQueue like this

KeInsertByKeyDeviceQueue( &devObj->DeviceQueue,
&Irp->Tail.Overlay.DeviceQueueEntry,
*Key );

or

KeInsertDeviceQueue( &deviceObj->DeviceQueue,
&Irp->Tail.Overlay.DeviceQueueEntry );


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

> Is there a way to directly call DriverObject->DriverStartIo function from my driver (around the queue)?

No for sure.

This routine has major sync requirements (thus the queue), and they are known to the underlying port driver only. The drivers above are just not aware of them.

Note that, for storage stack, you have “bypass frozen queue” and “bypass locked queue” SRB flags.

The first bypasses the queue which is suspended due to timeout/bus reset/some other error on the LUN.

The second bypasses explicit lock queue requests and also the queue locking due to power management - i.e. if D state is > D0.


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

> After reading about StartIo here:

http://www.osronline.com/ddkx/kmarch/irps_61bb.htm

… I thought that the StartIo function itself is responsible for its
synchronization. So calling it would not be a problem?!?

The port+miniport combo is responsible for it.

The drivers above just know nothing about it, so, the very idea of calling the StartIo of the driver below seems bizarre a bit.


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

> scsiport is amazingly buggy even today given that it has 20yr of mileage. And a feature-poor model.

Too bad it’s the only option for wxp and wxp refuses to die anytime soon.

That’s why people were writing full storage ports several years ago.

I.e. PnP bus driver + proper queue support will all these “bypass frozen” and “bypass locked” flags (I think KMDF queues are not suitable for this) + proper IOCTL support + proper naming.


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

> FYI, I am fighting against a modern rootkit.

Hopeless effort. The only proper cure for the rootkits is booting off AV CD and running AV scan in this mode.

But well, your “core wars” with the rootkit in memory will - with very high probability - result in a crash. And, after a crash will repeat, the user will be forced to do at least offline AV scan, if not to do the OS reinstall, which will kill the rootkit :slight_smile:


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

Are you sure modern SCSIPORT/STORPORT use the ancient DevObj->DeviceQueue?


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

wrote in message news:xxxxx@ntdev…
> Erik, before call StartIo, as you write:
> DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
> you need queue this request at device object list by call KeInsertByKeyDeviceQueue or KeInsertDeviceQueue like this
>
> KeInsertByKeyDeviceQueue( &devObj->DeviceQueue,
> &Irp->Tail.Overlay.DeviceQueueEntry,
> *Key );
>
> or
>
> KeInsertDeviceQueue( &deviceObj->DeviceQueue,
> &Irp->Tail.Overlay.DeviceQueueEntry );
>
>
>