Deregistering a device object

In an NDIS miniport driver, what should one do when MiniportHalt() is called
while a user-mode application still uses its handle to a device object
created by the driver?

According to MSDN “When NdisMRegisterDevice is called, there cannot be any
outstanding user-mode open operations on the device object being deleted. If
there are, a system error occurs.”

Are you trying to synchronize MiniportHalt with processing I/O control calls
that you receive on a device object created using NdisMRegisterDevice? If
so, then the rules are similar to using remove locks in standard WDM
drivers. So just use the WDM remove lock. Long story short:

typedef struct _YOUR_ADAPTER_CONTEXT {

IO_REMOVE_LOCK RemoveLock;

} YOUR_ADAPTER_CONTEXT, *PYOUR_ADAPTER_CONTEXT;

//
// Dispatch routine for device object registered using NdisMRegisterDevice
//
NTSTATUS
DispatchControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
NTSTATUS Status;
PYOUR_ADAPTER_CONTEXT AdapterContext;

AdapterContext = FindAdapterContext(…);
Status = IoAcquireRemoveLock(&AdapterContext->RemoveLock, Irp);

if (!NT_SUCCESS(Status)) {
// MiniportHalt has started, and is blocked in a call to
// IoReleaseRemoveLockAndWait.
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}

… process IRP (possibly async) …

IoReleaseRemoveLock(&AdapterContext->RemoveLock, Irp);
ReleaseAdapterContext(AdapterContext);

Status = …;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}

MiniportInitialize(…)
{
IoInitializeRemoveLock(&AdapterContext->RemoveLock, …);
}

MiniportHalt(…)
{
Status = IoAcquireRemoveLock(&AdapterContext->RemoveLock, NULL);
ASSERT(NT_SUCCESS(Status));
IoReleaseRemoveLockAndWait(&AdapterContext->RemoveLock, NULL);

… other stuff …
… at this point, it is impossible to receive further I/O controls

}

The IoReleaseRemoveLockAndWait function marks the remove lock as “removed –
do not allow IoAcquireRemoveLock to succeed”, then blocks the calling thread
until all calls to IoAcquireRemoveLock are balanced by calls to
IoReleaseRemoveLock.

That takes care of synchronizing those two paths, so you won’t crash (at
least not due to this). However, if you are concerned about being able to
unload your device driver when the user-mode app still has a handle open to
your standalone device object, then you may have some difficulties. I’m not
sure if/how NDIS properly supports query remove on the standalone device
(the NdisMRegisterDevice device, not the miniport device). The docs on
NdisMRegisterDevice aren’t too clear on that.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of S?ren Dreijer
Sent: Wednesday, March 15, 2006 10:19 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Deregistering a device object

In an NDIS miniport driver, what should one do when MiniportHalt() is called
while a user-mode application still uses its handle to a device object
created by the driver?

According to MSDN “When NdisMRegisterDevice is called, there cannot be any
outstanding user-mode open operations on the device object being deleted. If
there are, a system error occurs.”


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

I currently use flags in the adapter context to determine if the driver is
shutting down.

However, if you are concerned about being able to
unload your device driver when the user-mode app still has a handle open
to
your standalone device object, then you may have some difficulties. I’m
not
sure if/how NDIS properly supports query remove on the standalone device
(the NdisMRegisterDevice device, not the miniport device). The docs on
NdisMRegisterDevice aren’t too clear on that.

Erm, so what should I do? I mean, if a user hasn’t closed a device handle,
what can I do when the driver is shutting down? I’m currently experiencing a
bugcheck in such cases when calling NdisMDeregisterDevice() …

“Arlie Davis” wrote in message
news:xxxxx@ntdev…
Are you trying to synchronize MiniportHalt with processing I/O control calls
that you receive on a device object created using NdisMRegisterDevice? If
so, then the rules are similar to using remove locks in standard WDM
drivers. So just use the WDM remove lock. Long story short:

typedef struct _YOUR_ADAPTER_CONTEXT {

IO_REMOVE_LOCK RemoveLock;

} YOUR_ADAPTER_CONTEXT, *PYOUR_ADAPTER_CONTEXT;

//
// Dispatch routine for device object registered using NdisMRegisterDevice
//
NTSTATUS
DispatchControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
NTSTATUS Status;
PYOUR_ADAPTER_CONTEXT AdapterContext;

AdapterContext = FindAdapterContext(…);
Status = IoAcquireRemoveLock(&AdapterContext->RemoveLock, Irp);

if (!NT_SUCCESS(Status)) {
// MiniportHalt has started, and is blocked in a call to
// IoReleaseRemoveLockAndWait.
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}

… process IRP (possibly async) …

IoReleaseRemoveLock(&AdapterContext->RemoveLock, Irp);
ReleaseAdapterContext(AdapterContext);

Status = …;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}

MiniportInitialize(…)
{
IoInitializeRemoveLock(&AdapterContext->RemoveLock, …);
}

MiniportHalt(…)
{
Status = IoAcquireRemoveLock(&AdapterContext->RemoveLock, NULL);
ASSERT(NT_SUCCESS(Status));
IoReleaseRemoveLockAndWait(&AdapterContext->RemoveLock, NULL);

… other stuff …
… at this point, it is impossible to receive further I/O controls

}

The IoReleaseRemoveLockAndWait function marks the remove lock as “removed –
do not allow IoAcquireRemoveLock to succeed”, then blocks the calling thread
until all calls to IoAcquireRemoveLock are balanced by calls to
IoReleaseRemoveLock.

That takes care of synchronizing those two paths, so you won’t crash (at
least not due to this). However, if you are concerned about being able to
unload your device driver when the user-mode app still has a handle open to
your standalone device object, then you may have some difficulties. I’m not
sure if/how NDIS properly supports query remove on the standalone device
(the NdisMRegisterDevice device, not the miniport device). The docs on
NdisMRegisterDevice aren’t too clear on that.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Søren Dreijer
Sent: Wednesday, March 15, 2006 10:19 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Deregistering a device object

In an NDIS miniport driver, what should one do when MiniportHalt() is called
while a user-mode application still uses its handle to a device object
created by the driver?

According to MSDN “When NdisMRegisterDevice is called, there cannot be any
outstanding user-mode open operations on the device object being deleted. If
there are, a system error occurs.”


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Oh, actually, it seems the bugcheck doesn’t occur when removing the driver,
but when shutting down the user-mode application. Actually, I think I see
the problem now!

“Søren Dreijer” wrote in message news:xxxxx@ntdev…
>I currently use flags in the adapter context to determine if the driver is
>shutting down.
>
>> However, if you are concerned about being able to
>> unload your device driver when the user-mode app still has a handle open
>> to
>> your standalone device object, then you may have some difficulties. I’m
>> not
>> sure if/how NDIS properly supports query remove on the standalone device
>> (the NdisMRegisterDevice device, not the miniport device). The docs on
>> NdisMRegisterDevice aren’t too clear on that.
>
> Erm, so what should I do? I mean, if a user hasn’t closed a device handle,
> what can I do when the driver is shutting down? I’m currently experiencing
> a bugcheck in such cases when calling NdisMDeregisterDevice() …
>
> “Arlie Davis” wrote in message
> news:xxxxx@ntdev…
> Are you trying to synchronize MiniportHalt with processing I/O control
> calls
> that you receive on a device object created using NdisMRegisterDevice? If
> so, then the rules are similar to using remove locks in standard WDM
> drivers. So just use the WDM remove lock. Long story short:
>
>
> typedef struct _YOUR_ADAPTER_CONTEXT {
> …
> IO_REMOVE_LOCK RemoveLock;
> …
> } YOUR_ADAPTER_CONTEXT, *PYOUR_ADAPTER_CONTEXT;
>
> //
> // Dispatch routine for device object registered using NdisMRegisterDevice
> //
> NTSTATUS
> DispatchControl(
> PDEVICE_OBJECT DeviceObject,
> PIRP Irp)
> {
> NTSTATUS Status;
> PYOUR_ADAPTER_CONTEXT AdapterContext;
>
> AdapterContext = FindAdapterContext(…);
> Status = IoAcquireRemoveLock(&AdapterContext->RemoveLock, Irp);
>
> if (!NT_SUCCESS(Status)) {
> // MiniportHalt has started, and is blocked in a call to
> // IoReleaseRemoveLockAndWait.
> Irp->IoStatus.Status = Status;
> IoCompleteRequest(Irp, IO_NO_INCREMENT);
> return Status;
> }
>
> … process IRP (possibly async) …
>
> IoReleaseRemoveLock(&AdapterContext->RemoveLock, Irp);
> ReleaseAdapterContext(AdapterContext);
>
> Status = …;
> Irp->IoStatus.Status = Status;
> IoCompleteRequest(Irp, IO_NO_INCREMENT);
> return Status;
> }
>
> MiniportInitialize(…)
> {
> IoInitializeRemoveLock(&AdapterContext->RemoveLock, …);
> }
>
> MiniportHalt(…)
> {
> Status = IoAcquireRemoveLock(&AdapterContext->RemoveLock, NULL);
> ASSERT(NT_SUCCESS(Status));
> IoReleaseRemoveLockAndWait(&AdapterContext->RemoveLock, NULL);
>
> … other stuff …
> … at this point, it is impossible to receive further I/O controls
> …
> }
>
>
> The IoReleaseRemoveLockAndWait function marks the remove lock as
> “removed –
> do not allow IoAcquireRemoveLock to succeed”, then blocks the calling
> thread
> until all calls to IoAcquireRemoveLock are balanced by calls to
> IoReleaseRemoveLock.
>
> That takes care of synchronizing those two paths, so you won’t crash (at
> least not due to this). However, if you are concerned about being able to
> unload your device driver when the user-mode app still has a handle open
> to
> your standalone device object, then you may have some difficulties. I’m
> not
> sure if/how NDIS properly supports query remove on the standalone device
> (the NdisMRegisterDevice device, not the miniport device). The docs on
> NdisMRegisterDevice aren’t too clear on that.
>
> – arlie
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Søren Dreijer
> Sent: Wednesday, March 15, 2006 10:19 AM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] Deregistering a device object
>
> In an NDIS miniport driver, what should one do when MiniportHalt() is
> called
> while a user-mode application still uses its handle to a device object
> created by the driver?
>
> According to MSDN “When NdisMRegisterDevice is called, there cannot be any
> outstanding user-mode open operations on the device object being deleted.
> If
> there are, a system error occurs.”
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
>
>
>
>

Post the !analyze -v output. If you’re hitting a bluescreen, that should
always be the first place you look, and it is almost always the best thing
to provide to NTDEV if you’re looking for help.

Also, you should be using a remove lock (or some equivalent) to synchronize
access to your adapter contexts. I hope you are not just searching some
global list and returning a pointer, without some means to verify that the
pointer will be valid during the scope of your DispatchControl routine. If
so, then you’ve committed a very basic multithreading bug. That’s why I
provided the remove lock example code.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of S?ren Dreijer
Sent: Wednesday, March 15, 2006 2:33 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Deregistering a device object

I currently use flags in the adapter context to determine if the driver is
shutting down.

However, if you are concerned about being able to unload your device
driver when the user-mode app still has a handle open to your
standalone device object, then you may have some difficulties. I’m
not sure if/how NDIS properly supports query remove on the standalone
device (the NdisMRegisterDevice device, not the miniport device). The
docs on NdisMRegisterDevice aren’t too clear on that.

Erm, so what should I do? I mean, if a user hasn’t closed a device handle,
what can I do when the driver is shutting down? I’m currently experiencing a
bugcheck in such cases when calling NdisMDeregisterDevice() …

> Post the !analyze -v output. If you’re hitting a bluescreen, that should

always be the first place you look, and it is almost always the best thing
to provide to NTDEV if you’re looking for help.

As I wrote in a previous post, I noticed that the bug check didn’t occur
upon removal of the adapter itself, but rather when closing down the
user-mode application. The crash dump pinpointed the exact faulty location.

Also, you should be using a remove lock (or some equivalent) to
synchronize
access to your adapter contexts.

Of course.

“Arlie Davis” wrote in message
news:xxxxx@ntdev…
Post the !analyze -v output. If you’re hitting a bluescreen, that should
always be the first place you look, and it is almost always the best thing
to provide to NTDEV if you’re looking for help.

Also, you should be using a remove lock (or some equivalent) to synchronize
access to your adapter contexts. I hope you are not just searching some
global list and returning a pointer, without some means to verify that the
pointer will be valid during the scope of your DispatchControl routine. If
so, then you’ve committed a very basic multithreading bug. That’s why I
provided the remove lock example code.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Søren Dreijer
Sent: Wednesday, March 15, 2006 2:33 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Deregistering a device object

I currently use flags in the adapter context to determine if the driver is
shutting down.

> However, if you are concerned about being able to unload your device
> driver when the user-mode app still has a handle open to your
> standalone device object, then you may have some difficulties. I’m
> not sure if/how NDIS properly supports query remove on the standalone
> device (the NdisMRegisterDevice device, not the miniport device). The
> docs on NdisMRegisterDevice aren’t too clear on that.

Erm, so what should I do? I mean, if a user hasn’t closed a device handle,
what can I do when the driver is shutting down? I’m currently experiencing a
bugcheck in such cases when calling NdisMDeregisterDevice() …