IRP_MN_QUERY_STOP_DEVICE and CancelAll

Hello all.

I have a question about canceling pending IRPs in IRP_MN_QUERY_STOP_DEVICE handler. Should I cancel all pending IRPs in this handler? As far as I understand, I shouldn’t, but I saw examples that do that. To be concrete I ask about USB device driver that passes URBs to the lower driver. I suppose that lower driver answers the question if it is Ok to stop the device right now and I have to reject and cancel all pending IRPs after IRP_MN_STOP_DEVICE handler executed successfully, but what about IRP_MN_QUERY_STOP_DEVICE?


Thanking In Advance,
Mikae.

Do nothing on query stop. On the real stop, wait for all io you have sent down the stack to complete or cancel as necessary. Do not cancel all io sent to your driver. The stop should be transparent to the sender. Again, kmdf takes care of all of this.

d

debt from my phone

-----Original Message-----
From: xxxxx@yahoo.com
Sent: Saturday, August 27, 2011 2:38 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] IRP_MN_QUERY_STOP_DEVICE and CancelAll

Hello all.

I have a question about canceling pending IRPs in IRP_MN_QUERY_STOP_DEVICE handler. Should I cancel all pending IRPs in this handler? As far as I understand, I shouldn’t, but I saw examples that do that. To be concrete I ask about USB device driver that passes URBs to the lower driver. I suppose that lower driver answers the question if it is Ok to stop the device right now and I have to reject and cancel all pending IRPs after IRP_MN_STOP_DEVICE handler executed successfully, but what about IRP_MN_QUERY_STOP_DEVICE?


Thanking In Advance,
Mikae.


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

Ok, I understood about IRPs sent to lower driver, but didn’t understand “Do not cancel all io sent to your driver. The stop should be transparent to the sender.” What should I do with IRPs that are sent to my driver? Just to hold them until the device is stopped and continue when it is started again?

It looks like that my next book about drivers should something about WDF :).

Correct. Hold on to them and start processing them when the restart is sent

d

debt from my phone

-----Original Message-----
From: xxxxx@yahoo.com
Sent: Sunday, August 28, 2011 5:05 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] IRP_MN_QUERY_STOP_DEVICE and CancelAll

Ok, I understood about IRPs sent to lower driver, but didn’t understand “Do not cancel all io sent to your driver. The stop should be transparent to the sender.” What should I do with IRPs that are sent to my driver? Just to hold them until the device is stopped and continue when it is started again?


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

Ok. So as far as I understand it is better to implement two queues: on for ‘sent-to-next-driver’ IRPs and one for ‘sent-to-my-driver’. I have to do something like this:

NTSTATUS IrpMjCreate(…)
{
if (pDeviceExtension ->State == STOPPED)
{
InsertHoldOnQueue(pIrp);
IoMarkIrpPending(pIrp);
status = STATUS_PENDING;
}

return status;
}

NTSTATUS IrpMjStartDevice(…)
{
ForwardSynchronously(…);

while(IsListEmpty(&pDeviceExtension ->ListHoldOnIrps))
{
pIrp = RemoveHoldOnQueue(…);
MajorFunction = GetMajorFunction(pIrp);
pDeviceExtenstion ->pDriverObject ->MajorFunctionMajorFunction;
}
}

Synchronization omitted for clarity.

You have to manage it that way. This is the same logic you need to handle power down/up as well.

d

debt from my phone

-----Original Message-----
From: xxxxx@yahoo.com
Sent: Sunday, August 28, 2011 8:59 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] IRP_MN_QUERY_STOP_DEVICE and CancelAll

Ok. So as far as I understand it is better to implement two queues: on for ‘sent-to-next-driver’ IRPs and one for ‘sent-to-my-driver’. I have to do something like this:

NTSTATUS IrpMjCreate(…)
{
if (pDeviceExtension ->State == STOPPED)
{
InsertHoldOnQueue(pIrp);
IoMarkIrpPending(pIrp);
status = STATUS_PENDING;
}

return status;
}

NTSTATUS IrpMjStartDevice(…)
{
ForwardSynchronously(…);

while(IsListEmpty(&pDeviceExtension ->ListHoldOnIrps))
{
pIrp = RemoveHoldOnQueue(…);
MajorFunction = GetMajorFunction(pIrp);
pDeviceExtenstion ->pDriverObject ->MajorFunctionMajorFunction;
}
}

Synchronization omitted for clarity.


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

And one more question a little bit another question: will device that sets Capabilities ->SurpriseRemovalOK = TRUE in IRP_MN_QUERY_CAPABILITES completion routine get IRP_MN_STOP_DEVICE notification? Strange, I set this parameter and I don’t get IRP_MN_STOP_DEVICE in my handler. Or I do something wrong? Thank you.

They are not tied together. How are you getting a pnp stop sent to your device?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Sunday, August 28, 2011 3:38 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] IRP_MN_QUERY_STOP_DEVICE and CancelAll

And one more question a little bit another question: will device that sets Capabilities ->SurpriseRemovalOK = TRUE in IRP_MN_QUERY_CAPABILITES completion routine get IRP_MN_STOP_DEVICE notification? Strange, I set this parameter and I don’t get IRP_MN_STOP_DEVICE in my handler. Or I do something wrong? Thank you.


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

Here goes my code of PnP handler:

NTSTATUS IrpMjPnP(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
NTSTATUS status;
KIRQL Irql;
PDEVICE_EXTENSION pDeviceExtension;
PIO_STACK_LOCATION pStackLocation;

pDeviceExtension = pDeviceObject ->DeviceExtension;

pStackLocation = IoGetCurrentIrpStackLocation(pIrp);

status = STATUS_SUCCESS;

KeAcquireSpinLock(&pDeviceExtension ->Lock, &Irql);

if ((pDeviceExtension ->State == DEVICE_REMOVED || pDeviceExtension ->State == DEVICE_SURPRISE_REMOVAL) &&
!(pDeviceExtension ->State == DEVICE_SURPRISE_REMOVAL && pStackLocation ->MinorFunction == IRP_MN_REMOVE_DEVICE))
{
status = STATUS_DELETE_PENDING;
}

KeReleaseSpinLock(&pDeviceExtension ->Lock, Irql);

if (!NT_SUCCESS(status))
{
CompletePnPRequest(pIrp, status);
}
else
{
status = IoAcquireRemoveLock(&pDeviceExtension ->RemoveLock, pIrp);

if (status != STATUS_SUCCESS)
{
CompletePnPRequest(pIrp, status);
}
else
{
switch(pStackLocation ->MinorFunction)
{
case IRP_MN_START_DEVICE:
status = IrpMnStartDevice(pDeviceObject, pIrp);
break;
case IRP_MN_STOP_DEVICE:
status = IrpMnStopDevice(pDeviceObject, pIrp);
break;
case IRP_MN_QUERY_CAPABILITIES:
status = IrpMnQueryCapabilities(pDeviceObject, pIrp);
break;
default:
status = DefaultPnpHandler(pDeviceObject, pIrp);
break;
}

if (pStackLocation ->MinorFunction != IRP_MN_REMOVE_DEVICE)
{
IoReleaseRemoveLock(&pDeviceExtension ->RemoveLock, pIrp);
}
}
}

return status;
}

It is very alphs version. I put a breakpoint on IrpMnStopDevice and it is not triggered. I tried only once (it was late evening), I have to try it again today. Also I don’t know how to start the device since it disappears from menu after stopping.

You are not allowed to fail pnp state changing irps (query is ok) like you are doing. If the device is disappearing, I think you are confusing stop with remove. From what menu is the device disappearing from?

Let me say this one last tile. You are wasting your time in a pretty dramatic way. If you use kmdf, you would be focusing on your he and whatever value the driver is adding. Instead, you are creating a mess of code, that once you get kind of stable, you will be very afraid to change in the future

d

debt from my phone

-----Original Message-----
From: xxxxx@yahoo.com
Sent: Monday, August 29, 2011 3:52 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] IRP_MN_QUERY_STOP_DEVICE and CancelAll

Here goes my code of PnP handler:

NTSTATUS IrpMjPnP(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
NTSTATUS status;
KIRQL Irql;
PDEVICE_EXTENSION pDeviceExtension;
PIO_STACK_LOCATION pStackLocation;

pDeviceExtension = pDeviceObject ->DeviceExtension;

pStackLocation = IoGetCurrentIrpStackLocation(pIrp);

status = STATUS_SUCCESS;

KeAcquireSpinLock(&pDeviceExtension ->Lock, &Irql);

if ((pDeviceExtension ->State == DEVICE_REMOVED || pDeviceExtension ->State == DEVICE_SURPRISE_REMOVAL) &&
!(pDeviceExtension ->State == DEVICE_SURPRISE_REMOVAL && pStackLocation ->MinorFunction == IRP_MN_REMOVE_DEVICE))
{
status = STATUS_DELETE_PENDING;
}

KeReleaseSpinLock(&pDeviceExtension ->Lock, Irql);

if (!NT_SUCCESS(status))
{
CompletePnPRequest(pIrp, status);
}
else
{
status = IoAcquireRemoveLock(&pDeviceExtension ->RemoveLock, pIrp);

if (status != STATUS_SUCCESS)
{
CompletePnPRequest(pIrp, status);
}
else
{
switch(pStackLocation ->MinorFunction)
{
case IRP_MN_START_DEVICE:
status = IrpMnStartDevice(pDeviceObject, pIrp);
break;
case IRP_MN_STOP_DEVICE:
status = IrpMnStopDevice(pDeviceObject, pIrp);
break;
case IRP_MN_QUERY_CAPABILITIES:
status = IrpMnQueryCapabilities(pDeviceObject, pIrp);
break;
default:
status = DefaultPnpHandler(pDeviceObject, pIrp);
break;
}

if (pStackLocation ->MinorFunction != IRP_MN_REMOVE_DEVICE)
{
IoReleaseRemoveLock(&pDeviceExtension ->RemoveLock, pIrp);
}
}
}

return status;
}

It is very alphs version. I put a breakpoint on IrpMnStopDevice and it is not triggered. I tried only once (it was late evening), I have to try it again today. Also I don’t know how to start the device since it disappears from menu after stopping.


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

>You are not allowed to fail pnp state changing irps (query is ok) like you are
doing.

What should I do in the case I can’t acquire remove lock in PnP handler?

If the device is disappearing, I think you are confusing stop with
remove. From what menu is the device disappearing from?

I think it was ‘Stop’ button. But I’ll check today when I will be at computer with the driver.

Let me say this one last tile. You are wasting your time in a pretty dramatic
way. If you use kmdf, you would be focusing on your he and whatever value the
driver is adding. Instead, you are creating a mess of code, that once you get
kind of stable, you will be very afraid to change in the future

Ok, let me explain why I do it. Some guys asked me to write a driver. I said that it would be better if they find someone who knows KMDF, since I only WDM-beginner. They said: “Ok, let’s write WDM driver”. I said: “Probably I will fail, since the deadline is very soon”. They said: “Let’s try”. So this is kind of my goal – to make a driver that is reliable. Let it be hard to change something in the driver, but it will work. After the deadline I can rewrite it as KMDF driver. Also this is my baptism of fire. It is always painful, but I want to get results.

A newbie wdm guy is a newbie kmdf guy. Kmdf was geared for the beginner, what led you to think wdm would be easier to learn than kmdf ? You would have been much farther along with kmdf by now . I hope your driver is not going to be given out to anyone as a product. The only thing worse than a wdm driver is one written under time pressure to get it done quickly, there will be fundamental concepts in the driver that will not be fully tested

d

debt from my phone

-----Original Message-----
From: xxxxx@yahoo.com
Sent: Monday, August 29, 2011 9:11 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] IRP_MN_QUERY_STOP_DEVICE and CancelAll

You are not allowed to fail pnp state changing irps (query is ok) like you are
doing.

What should I do in the case I can’t acquire remove lock in PnP handler?

If the device is disappearing, I think you are confusing stop with
remove. From what menu is the device disappearing from?

I think it was ‘Stop’ button. But I’ll check today when I will be at computer with the driver.

Let me say this one last tile. You are wasting your time in a pretty dramatic
way. If you use kmdf, you would be focusing on your he and whatever value the
driver is adding. Instead, you are creating a mess of code, that once you get
kind of stable, you will be very afraid to change in the future

Ok, let me explain why I do it. Some guys asked me to write a driver. I said that it would be better if they find someone who knows KMDF, since I only WDM-beginner. They said: “Ok, let’s write WDM driver”. I said: “Probably I will fail, since the deadline is very soon”. They said: “Let’s try”. So this is kind of my goal – to make a driver that is reliable. Let it be hard to change something in the driver, but it will work. After the deadline I can rewrite it as KMDF driver. Also this is my baptism of fire. It is always painful, but I want to get results.


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

Do not hold IRPs if your device was never started. If you do, you may never get REMOVE_DEVICE.

Doron, I didn’t know about KMDF when I started WDM. And I have no time no to learn new things now. Anyway, knowing what stands behind libraries is a good idea.

Alex, I have special state DEVICE_NOT_SET which I handle failing IRP_MJ_CREATE. The question is how to handle states in IRP_MJ_PNP. Doron says that I don’t have to fail state-changing IRPs. I try to understand how to handle acquiring remove lock in this case and why I shouldn’t fail IRPs that are sent to removed devices.

Acquisition of the remock will never fail until you put it into a removed state. It will return an error value only once you have called ioreleaseremovelockandwait

d

debt from my phone

-----Original Message-----
From: xxxxx@yahoo.com
Sent: Monday, August 29, 2011 11:10 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] IRP_MN_QUERY_STOP_DEVICE and CancelAll

Doron, I didn’t know about KMDF when I started WDM. And I have no time no to learn new things now. Anyway, knowing what stands behind libraries is a good idea.

Alex, I have special state DEVICE_NOT_SET which I handle failing IRP_MJ_CREATE. The question is how to handle states in IRP_MJ_PNP. Doron says that I don’t have to fail state-changing IRPs. I try to understand how to handle acquiring remove lock in this case and why I shouldn’t fail IRPs that are sent to removed devices.


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

Yes, I know. I don’t know if it is possible to get IRP_MN_REMOVE_DEVICE (this is where I call to IoReleaseRemoveLockAndWait) and any other IRP_MN_XXX IRP. It looks like I have to acquire remove lock in IRP_MN_XXX functions, not in IRP_MJ_PNP.

All state changing pnp irps are serialized. They are (not definitive list) start, stop, remove, query remove, query stop, surprise removal, query pnp state

d

debt from my phone

-----Original Message-----
From: xxxxx@yahoo.com
Sent: Monday, August 29, 2011 12:11 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] IRP_MN_QUERY_STOP_DEVICE and CancelAll

Yes, I know. I don’t know if it is possible to get IRP_MN_REMOVE_DEVICE (this is where I call to IoReleaseRemoveLockAndWait) and any other IRP_MN_XXX IRP. It looks like I have to acquire remove lock in IRP_MN_XXX functions, not in IRP_MJ_PNP.


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

Ok, hence I don’t need to acquire remove lock for these IRPs since they can’t arrive simultaneously. Where it is possible to get the full list? Well, I was confused by Oney’s code. He suggests the following template for IRP_MJ_PNP handler:

NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp)
{
PDEVICE_EXTENSION pdx =
(PDEVICE_EXTENSION) fdo->DeviceExtension;
NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);

status = (*fcntab[fcn](fdo, Irp);
if (fcn != IRP_MN_REMOVE_DEVICE)
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
}

Also I don’t understand how IoDeleteDevice knows that is is right time to dereference a device. Oney says that it checks AttachedDevice field and if it is not NULL it postpones dereferencing until it becomes NULL. The question is how it knows that it is time to check the field again. But it looks like that I have to reverse IoDeleteDevice later by myself.

P.S. Thank you for patience and explanations. I know a guy that writes drivers in assembler because he doesn’t know C. A lot of people recommend him to learn C, but he doesn’t want or can’t for some reasons. So I am in the same situation now.

You should still use the remlock in this path. You can get pnp irps after remove . The remlock provides state protection against remove , it doesn’t serialize anything

d

debt from my phone

-----Original Message-----
From: xxxxx@yahoo.com
Sent: Tuesday, August 30, 2011 9:44 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] IRP_MN_QUERY_STOP_DEVICE and CancelAll

Ok, hence I don’t need to acquire remove lock for these IRPs since they can’t arrive simultaneously. Where it is possible to get the full list? Well, I was confused by Oney’s code. He suggests the following template for IRP_MJ_PNP handler:

NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp)
{
PDEVICE_EXTENSION pdx =
(PDEVICE_EXTENSION) fdo->DeviceExtension;
NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);

status = (*fcntab[fcn](fdo, Irp);
if (fcn != IRP_MN_REMOVE_DEVICE)
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
}

Also I don’t understand how IoDeleteDevice knows that is is right time to dereference a device. Oney says that it checks AttachedDevice field and if it is not NULL it postpones dereferencing until it becomes NULL. The question is how it knows that it is time to check the field again. But it looks like that I have to reverse IoDeleteDevice later by myself.

P.S. Thank you for patience and explanations. I know a guy that writes drivers in assembler because he doesn’t know C. A lot of people recommend him to learn C, but he doesn’t want or can’t for some reasons. So I am in the same situation now.


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