NDIS Miniport Driver Hangs on Disable in Windows 2012R2

I wrote an NDIS 6.20 Miniport driver that has worked well for several years on Windows 7 and 2012. Recently I tried to install it on Windows 2012 R2. It installed successfully, but it hangs Device Manager when I try to disable it. Log output shows that Windows 2012 calls my driver’s MiniportHalt and Unload callbacks. Unfortunately, 2012 R2 calls MiniportHalt which returns normally, and then never calls Unload. At that point, it is possible to kill DeviceManager, but the machine will not reboot normally. It requires a hardware reset.

I read online where Windows might not call DriverUnload if there was an outstanding IRP or DeviceObject reference. I commented out most of the code in my driver to test this theory. At this point, my driver has very little active code left. Now it only does the following:

  1. Call NdisMRegisterMiniportDriver
  2. Allocate memory for adapter instance and add to global list
  3. Call NdisMSetMiniportAttributes to set registration and general attributes
  4. Fail every SendNetBufferLists request
  5. In MiniportHalt, remove adapter instance from global list and free memory
  6. If DriverUnload is called, then call NdisMDeregisterMiniportDriver

Unfortunately, step 6 does not occur on 2012 R2.

I applied all important Windows updates to the 2012 R2 machine. I didn’t see any relevant changes between NDIS 6.20 and 6.30, but I changed the version numbers on my driver anyway. I switched build tools from WDK 8.1 to WDK 10. None of these steps fixed the problem.

I did find these warnings in the setupapi.dev.log file, but it did install and it’s not clear how this is related to hanging on disable:

sto: {DRIVERSTORE IMPORT VALIDATE} 13:27:41.131
sig: {_VERIFY_FILE_SIGNATURE} 13:27:41.147
sig: Key = mydriver.inf
sig: FilePath = C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.inf
sig: Catalog = C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.cat
! sig: Verifying file against specific (valid) catalog failed! (0x800b0109)
! sig: Error 0x800b0109: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.
sig: {_VERIFY_FILE_SIGNATURE exit(0x800b0109)} 13:27:41.209
sig: {_VERIFY_FILE_SIGNATURE} 13:27:41.209
sig: Key = mydriver.inf
sig: FilePath = C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.inf
sig: Catalog = C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.cat
sig: Success: File is signed in Authenticode™ catalog.
sig: Error 0xe0000242: The publisher of an Authenticode™ signed catalog has not yet been established as trusted.
sig: {_VERIFY_FILE_SIGNATURE exit(0xe0000242)} 13:27:41.209
! sig: Driver package signer is unknown, but user trusts signer.
sto: {DRIVERSTORE IMPORT VALIDATE: exit(0x00000000)} 13:27:44.069
sig: Signer Score = 0x0F000000

I created a user-mode dump file of Device Manager once it hung. The top of the call stack is:

ntdll!NtDeviceIoControlFile+0xa C/C++/ASM
KERNELBASE!DeviceIoControl+0x121 C/C++/ASM
kernel32!DeviceIoControlImplementation+0x80 C/C++/ASM
cfgmgr32!Local_CM_Disable_DevNode+0xb8 C/C++/ASM
cfgmgr32!CM_Disable_DevNode+0xbf C/C++/ASM
cfgmgr32!CM_Disable_DevNode_Ex+0x5c C/C++/ASM
devobj!DevObjChangeState+0x4f6 C/C++/ASM
setupapi!SetupDiChangeState+0x872 C/C++/ASM
setupapi!_SetupDiCallClassInstaller+0x101b C/C++/ASM
setupapi!SetupDiCallClassInstaller+0x59 C/C++/ASM
devmgr!CDevice::EnableDisableDevice+0x1d7 C/C++/ASM
devmgr!CResultView::MenuCommand+0x1b9 C/C++/ASM
devmgr!CFolder::MenuCommand+0xbe C/C++/ASM
devmgr!CComponent::Command+0xa4 C/C++/ASM
mmcndmgr!IExtendContextMenuWrapper::Command+0xd2 C/C++/ASM
mmcndmgr!CMenuItem::ScExecute+0x236 C/C++/ASM
mmcndmgr!CContextMenu::ExecuteMenuItem+0x8e C/C++/ASM

So, it looks like Device Manager is waiting on an IOCTL request. I’m not sure exactly what that request might be, or why it would be different in 2012 vs 2012 R2.

At this point, I am out of ideas of where to look and what to try. Does anyone have any suggestions?

Thank you very much in advance.

The errors in the setup log are a red herring, they don’t have anything to
do with the hang.

Other than that, I don’t have any specific guidance on what the problem is.
However, in the interest of investigating the hang try attaching a kernel
debugger and running:

!stacks 2 ndis!

That will show you any threads currently executing in NDIS. There is likely
going to be a thread in the System process waiting for SOMEthing.

I’m not saying that’s going to give you the answer to the problem, but
finding the stuck thread(s) is the first step.

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntdev…

I wrote an NDIS 6.20 Miniport driver that has worked well for several years
on Windows 7 and 2012. Recently I tried to install it on Windows 2012 R2.
It installed successfully, but it hangs Device Manager when I try to disable
it. Log output shows that Windows 2012 calls my driver’s MiniportHalt and
Unload callbacks. Unfortunately, 2012 R2 calls MiniportHalt which returns
normally, and then never calls Unload. At that point, it is possible to
kill DeviceManager, but the machine will not reboot normally. It requires a
hardware reset.

I read online where Windows might not call DriverUnload if there was an
outstanding IRP or DeviceObject reference. I commented out most of the code
in my driver to test this theory. At this point, my driver has very little
active code left. Now it only does the following:

  1. Call NdisMRegisterMiniportDriver
  2. Allocate memory for adapter instance and add to global list
  3. Call NdisMSetMiniportAttributes to set registration and general
    attributes
  4. Fail every SendNetBufferLists request
  5. In MiniportHalt, remove adapter instance from global list and free memory
  6. If DriverUnload is called, then call NdisMDeregisterMiniportDriver

Unfortunately, step 6 does not occur on 2012 R2.

I applied all important Windows updates to the 2012 R2 machine. I didn’t
see any relevant changes between NDIS 6.20 and 6.30, but I changed the
version numbers on my driver anyway. I switched build tools from WDK 8.1 to
WDK 10. None of these steps fixed the problem.

I did find these warnings in the setupapi.dev.log file, but it did install
and it’s not clear how this is related to hanging on disable:

sto: {DRIVERSTORE IMPORT VALIDATE} 13:27:41.131
sig: {_VERIFY_FILE_SIGNATURE} 13:27:41.147
sig: Key = mydriver.inf
sig: FilePath =
C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.inf
sig: Catalog =
C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.cat
! sig: Verifying file against specific (valid)
catalog failed! (0x800b0109)
! sig: Error 0x800b0109: A certificate chain
processed, but terminated in a root certificate which is not trusted by the
trust provider.
sig: {_VERIFY_FILE_SIGNATURE exit(0x800b0109)}
13:27:41.209
sig: {_VERIFY_FILE_SIGNATURE} 13:27:41.209
sig: Key = mydriver.inf
sig: FilePath =
C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.inf
sig: Catalog =
C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.cat
sig: Success: File is signed in
Authenticode™ catalog.
sig: Error 0xe0000242: The publisher of an
Authenticode™ signed catalog has not yet been established as trusted.
sig: {_VERIFY_FILE_SIGNATURE exit(0xe0000242)}
13:27:41.209
! sig: Driver package signer is unknown, but user
trusts signer.
sto: {DRIVERSTORE IMPORT VALIDATE: exit(0x00000000)}
13:27:44.069
sig: Signer Score = 0x0F000000

I created a user-mode dump file of Device Manager once it hung. The top of
the call stack is:

ntdll!NtDeviceIoControlFile+0xa C/C++/ASM
KERNELBASE!DeviceIoControl+0x121 C/C++/ASM
kernel32!DeviceIoControlImplementation+0x80 C/C++/ASM
cfgmgr32!Local_CM_Disable_DevNode+0xb8 C/C++/ASM
cfgmgr32!CM_Disable_DevNode+0xbf C/C++/ASM
cfgmgr32!CM_Disable_DevNode_Ex+0x5c C/C++/ASM
devobj!DevObjChangeState+0x4f6 C/C++/ASM
setupapi!SetupDiChangeState+0x872 C/C++/ASM
setupapi!_SetupDiCallClassInstaller+0x101b C/C++/ASM
setupapi!SetupDiCallClassInstaller+0x59 C/C++/ASM
devmgr!CDevice::EnableDisableDevice+0x1d7 C/C++/ASM
devmgr!CResultView::MenuCommand+0x1b9 C/C++/ASM
devmgr!CFolder::MenuCommand+0xbe C/C++/ASM
devmgr!CComponent::Command+0xa4 C/C++/ASM
mmcndmgr!IExtendContextMenuWrapper::Command+0xd2 C/C++/ASM
mmcndmgr!CMenuItem::ScExecute+0x236 C/C++/ASM
mmcndmgr!CContextMenu::ExecuteMenuItem+0x8e C/C++/ASM

So, it looks like Device Manager is waiting on an IOCTL request. I’m not
sure exactly what that request might be, or why it would be different in
2012 vs 2012 R2.

At this point, I am out of ideas of where to look and what to try. Does
anyone have any suggestions?

Thank you very much in advance.

Try unbinding all protocols and filters from the instance and see if under those conditions it unloads when disabled.

With nothing bound to it you reduce the possibility that something could care enough about it to have an open reference.

It cuts down the list of actors to just your code, NDIS, and PnP.

And when it still hangs (or in your current situation) break in with the debugger and look at what !ndiskd has to say about references to your miniport as well as what references are on the device object and driver object.

Lastly, if DevMgr is hanging then somewhere there is a thread blocked on something. Go look at what that something is.

!stacks 2 ndis!*

Or just look at the output from ndiskd (in advanced mode it runs !stacks to find activity passing through NDIS).

Good Luck,
Dave Cattley

SNoone is as usual deeper into his morning coffee than I am.

Dave Cattley

I live with a tyrannical three year old at who refuses to sleep past 6AM, so
the coffee starts very early around here…

“Dave Cattley” wrote in message news:xxxxx@ntdev…

SNoone is as usual deeper into his morning coffee than I am.

Dave Cattley

Soone is legit.

mm

On Thu, May 12, 2016 at 5:37 AM, Scott Noone wrote:

>
> I live with a tyrannical three year old at who refuses to sleep past 6AM,
> so the coffee starts very early around here…
>
>
> “Dave Cattley” wrote in message news:xxxxx@ntdev…
>
>
> SNoone is as usual deeper into his morning coffee than I am.
>
>
>
> Dave Cattley
>
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

If device manager hangs you are not as far as trying yo unload telge driver, the pnp remove irp not been completed and since it is a state changing irp, it holds the state lock and prevents new state operations (device start, enumeration, system power state change) from occurring.

Sent from my Windows 10 phone

From: xxxxx@yahoo.commailto:xxxxx
Sent: Thursday, May 12, 2016 5:08 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: [ntdev] NDIS Miniport Driver Hangs on Disable in Windows 2012R2

I wrote an NDIS 6.20 Miniport driver that has worked well for several years on Windows 7 and 2012. Recently I tried to install it on Windows 2012 R2. It installed successfully, but it hangs Device Manager when I try to disable it. Log output shows that Windows 2012 calls my driver’s MiniportHalt and Unload callbacks. Unfortunately, 2012 R2 calls MiniportHalt which returns normally, and then never calls Unload. At that point, it is possible to kill DeviceManager, but the machine will not reboot normally. It requires a hardware reset.

I read online where Windows might not call DriverUnload if there was an outstanding IRP or DeviceObject reference. I commented out most of the code in my driver to test this theory. At this point, my driver has very little active code left. Now it only does the following:

1) Call NdisMRegisterMiniportDriver
2) Allocate memory for adapter instance and add to global list
3) Call NdisMSetMiniportAttributes to set registration and general attributes
4) Fail every SendNetBufferLists request
5) In MiniportHalt, remove adapter instance from global list and free memory
6) If DriverUnload is called, then call NdisMDeregisterMiniportDriver

Unfortunately, step 6 does not occur on 2012 R2.

I applied all important Windows updates to the 2012 R2 machine. I didn’t see any relevant changes between NDIS 6.20 and 6.30, but I changed the version numbers on my driver anyway. I switched build tools from WDK 8.1 to WDK 10. None of these steps fixed the problem.

I did find these warnings in the setupapi.dev.log file, but it did install and it’s not clear how this is related to hanging on disable:

sto: {DRIVERSTORE IMPORT VALIDATE} 13:27:41.131
sig: {_VERIFY_FILE_SIGNATURE} 13:27:41.147
sig: Key = mydriver.inf
sig: FilePath = C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.inf
sig: Catalog = C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.cat
! sig: Verifying file against specific (valid) catalog failed! (0x800b0109)
! sig: Error 0x800b0109: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.
sig: {_VERIFY_FILE_SIGNATURE exit(0x800b0109)} 13:27:41.209
sig: {_VERIFY_FILE_SIGNATURE} 13:27:41.209
sig: Key = mydriver.inf
sig: FilePath = C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.inf
sig: Catalog = C:\Windows\System32\DriverStore\Temp{721af17b-01ef-2b4e-999b-ef20a569320a}\mydriver.cat
sig: Success: File is signed in Authenticode™ catalog.
sig: Error 0xe0000242: The publisher of an Authenticode™ signed catalog has not yet been established as trusted.
sig: {_VERIFY_FILE_SIGNATURE exit(0xe0000242)} 13:27:41.209
! sig: Driver package signer is unknown, but user trusts signer.
sto: {DRIVERSTORE IMPORT VALIDATE: exit(0x00000000)} 13:27:44.069
sig: Signer Score = 0x0F000000

I created a user-mode dump file of Device Manager once it hung. The top of the call stack is:

ntdll!NtDeviceIoControlFile+0xa C/C++/ASM
KERNELBASE!DeviceIoControl+0x121 C/C++/ASM
kernel32!DeviceIoControlImplementation+0x80 C/C++/ASM
cfgmgr32!Local_CM_Disable_DevNode+0xb8 C/C++/ASM
cfgmgr32!CM_Disable_DevNode+0xbf C/C++/ASM
cfgmgr32!CM_Disable_DevNode_Ex+0x5c C/C++/ASM
devobj!DevObjChangeState+0x4f6 C/C++/ASM
setupapi!SetupDiChangeState+0x872 C/C++/ASM
setupapi!_SetupDiCallClassInstaller+0x101b C/C++/ASM
setupapi!SetupDiCallClassInstaller+0x59 C/C++/ASM
devmgr!CDevice::EnableDisableDevice+0x1d7 C/C++/ASM
devmgr!CResultView::MenuCommand+0x1b9 C/C++/ASM
devmgr!CFolder::MenuCommand+0xbe C/C++/ASM
devmgr!CComponent::Command+0xa4 C/C++/ASM
mmcndmgr!IExtendContextMenuWrapper::Command+0xd2 C/C++/ASM
mmcndmgr!CMenuItem::ScExecute+0x236 C/C++/ASM
mmcndmgr!CContextMenu::ExecuteMenuItem+0x8e C/C++/ASM

So, it looks like Device Manager is waiting on an IOCTL request. I’m not sure exactly what that request might be, or why it would be different in 2012 vs 2012 R2.

At this point, I am out of ideas of where to look and what to try. Does anyone have any suggestions?

Thank you very much in advance.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx>

Thank you so much for the replies, especially Scott’s hilarious comment about his three year old. I needed a good laugh this morning!

I re-installed my driver, and unbound all protocols from the adapter instance. Then I tried to disable it in DeviceManager and it hung again.

By comparing my log files against the steps listed on this page “Removing a NIC” (https://msdn.microsoft.com/en-us/library/windows/hardware/ff570662(v=vs.85).aspx). I see clearly that step 10.c occurs as MiniportPause is called. Next step 11 occurs as NDIS calls my MinportHaltEx callback with NdisHaltDeviceDisabled. Even after returning normally from MiniportHaltEx, I still do not see any log output from my DriverUnload method. I’m not entirely sure whether steps 12 or 13 occurred.

This debugger output shows that the Miniport state as HALTED, and the Device PnP as REMOVED, but the Pnp flag REMOVE_IN_PROGRESS is also set. However, there are still 4 PT_OPENED references, which means a protocol is still attached somehow, right? Below that !stacks 2 ndis! seems to show that it is indeed blocked on the ndisPnPIrpRemoveDevice call.

So, is NDIS blocked on the remove device call because of the 4 protocol references? If so, what’s the next step?

lkd> !ndiskd.miniport ffffe801fa0a31a0

MINIPORT

MyDriver

Ndis handle ffffe801fa0a31a0
Ndis API version v6.30
Adapter context NULL
Miniport driver ffffe801fa10c020 - MyDriver v0.1
Network interface 0

Media type 802.3
Device instance PCI\VEN_1172&DEV_E001&SUBSYS_28015BDE&REV_01\4&14bdce4f&0&0048
Device object ffffe801fa0a3050 More information

STATE

Miniport HALTED
Device PnP REMOVED Show state history
Datapath Normal
Operational status UP
Operational flags [No flags set]
Admin status ADMIN_DOWN
Media Connected
Power D0
References 4 Show detail
Total resets 0
Pending OID None
Flags BUS_MASTER, DEFAULT_PORT_ACTIVATED,
SUPPORTS_MEDIA_SENSE, DOES_NOT_DO_LOOPBACK,
MEDIA_CONNECTED
PnP flags PM_SUPPORTED, REMOVE_IN_PROGRESS, DEVICE_POWER_ENABLED,
REJECT_REQUESTS, HARDWARE_DEVICE, CANCELLED_WAKEUP_TIMER

BINDINGS

Protocol list Driver Open Context
(RDMANDK) ffffe00078bca010 Miniport not ready
(RASPPPOE) ffffe00078d79740 Miniport not ready
(NDISUIO) Not running
(LLTDIO) ffffe00078e6b360 Binding disabled by INetCfg
(RSPNDR) ffffe0007a59dc10 Binding disabled by INetCfg
(TCPIP) ffffe00078a8ac10 Binding disabled by INetCfg
(TCPIP6) ffffe00078a32c10 Binding disabled by INetCfg

Filter list Driver Module Context
(WFP 802.3 MAC Layer LightWeight Filter-0000)
ffffe00078af5a70 Miniport not ready
(QoS Packet Scheduler-0000)
ffffe00078b88460 Binding disabled by INetCfg
(WFP Native MAC Layer LightWeight Filter-0000)
ffffe000789ebd70 Miniport not ready

MORE INFORMATION

Driver handlers Task offloads
Power management PM protocol offloads
Pending OIDs Timers
Pending NBLs
Wake-on-LAN (WoL) Packet filter
Receive queues Receive filtering
RSS NIC switch
Hardware resources Selective suspend
NDIS ports WMI guids

lkd> !ndiskd.miniport ffffe801fa0a31a0 -ref

MINIPORT REFERENCE COUNT

Tag Number of references
PT_OPENED 4

lkd> !stacks 2 ndis!
Proc.Thread .Thread Ticks ThreadState Blocker
4.0000d4 ffffe000787c8400 ffffffc7 Blocked nt!KiSwapContext+0x76
nt!KiSwapThread+0x14e
nt!KiCommitThreadWait+0x129
nt!KeWaitForSingleObject+0x373
NDIS!ndisThreadPoolTimerHandler+0x1f
nt!PspSystemThreadStartup+0x58
nt!KiStartSystemThread+0x16
4.0000d8 ffffe000787c7040 fffee697 Blocked nt!KiSwapContext+0x76
nt!KiSwapThread+0x14e
nt!KiCommitThreadWait+0x129
nt!KeRemoveQueueEx+0x788
nt!KeRemoveQueue+0x21
NDIS!ndisWorkerThread+0x3b
nt!PspSystemThreadStartup+0x58
nt!KiStartSystemThread+0x16
4.0000dc ffffe00078281880 ffffffc7 Blocked nt!KiSwapContext+0x76
nt!KiSwapThread+0x14e
nt!KiCommitThreadWait+0x129
nt!KeWaitForSingleObject+0x373
NDIS!ndisReceiveWorkerThread+0xa8
nt!PspSystemThreadStartup+0x58
nt!KiStartSystemThread+0x16
4.0000e0 ffffe0007827e880 ffffffc7 Blocked nt!KiSwapContext+0x76
nt!KiSwapThread+0x14e
nt!KiCommitThreadWait+0x129
nt!KeWaitForSingleObject+0x373
NDIS!ndisReceiveWorkerThread+0xa8
nt!PspSystemThreadStartup+0x58
nt!KiStartSystemThread+0x16
4.0000e4 ffffe000787c5040 ffffffc7 Blocked nt!KiSwapContext+0x76
nt!KiSwapThread+0x14e
nt!KiCommitThreadWait+0x129
nt!KeWaitForSingleObject+0x373
NDIS!ndisReceiveWorkerThread+0xa8
nt!PspSystemThreadStartup+0x58
nt!KiStartSystemThread+0x16
4.0000e8 ffffe000787c5880 ffffffc7 Blocked nt!KiSwapContext+0x76
nt!KiSwapThread+0x14e
nt!KiCommitThreadWait+0x129
nt!KeWaitForSingleObject+0x373
NDIS!ndisReceiveWorkerThread+0xa8
nt!PspSystemThreadStartup+0x58
nt!KiStartSystemThread+0x16
4.000768 ffffe801fa1b0040 fffee897 Blocked nt!KiSwapContext+0x76
nt!KiSwapThread+0x14e
nt!KiCommitThreadWait+0x129
nt!KeWaitForSingleObject+0x373
NDIS!ndisPnPIrpRemoveDevice+0xa5
NDIS!ndisPnPDispatch+0x1f8
nt!IopSynchronousCall+0xfe
nt!IopRemoveDevice+0xe0
nt!PnpRemoveLockedDeviceNode+0xf2
nt!PnpDeleteLockedDeviceNode+0x4d
nt!PnpDeleteLockedDeviceNodes+0x9a
nt!PnpProcessQueryRemoveAndEject+0x539
nt!PnpProcessTargetDeviceEvent+0x9d
nt!PnpDeviceEventWorker+0x31f
nt!ExpWorkerThread+0x69f
nt!PspSystemThreadStartup+0x58
nt!KiStartSystemThread+0x16

If I understand the debugging output and previous comments correctly, Windows sends the PnP Remove Irp to NDIS, which has not yet completed it, apparently because NDIS is waiting for a synchronization object.

  • What object is NDIS waiting for?
  • Why is this different in Win 2012 vs 2012 R2?
  • What can I change in my NDIS miniport driver to fix this problem?
  • Would some other change fix this problem?

You may be holding (or leaked) packets (NBLs) sent to you.

Interesting suggestion, however I am pretty sure the driver is not currently holding or leaking any NBLs for two reasons. First, I have commented out most of the driver’s functionality to debug this problem. Right now, my driver immediately fails any send request thereby returning the NBLs immediately. Second, after unbinding all the protocols, my driver logs do not show any send requests occurring.

Does anyone know why NDIS is unable to complete the PnP Remove Irp and what I might do to fix it?

>Right now, my driver immediately fails any send request thereby returning the NBLs immediately.

MiniportSendNetBufferLists doesn’t return any status. You need to return the NBLs explicitly.

Ok, to be more precise my current implementation of the SendNetBufferLists callback is effectively:

// Fail the entire list of NBLs
for(Nbl = NetBufferLists; Nbl != NULL; Nbl = NET_BUFFER_LIST_NEXT_NBL(Nbl))
{
NET_BUFFER_LIST_STATUS(Nbl) = NDIS_STATUS_FAILURE;
}

NdisMSendNetBufferListsComplete(Adapter->AdapterHandle,
NetBufferLists,
AtDispatch ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0);

I think that should fail and return all NBLs passed into this function. Does that seem right to you?

Also, my logging suggests that this function never gets called after I unbound the protocols.

We tried it on Windows 2016 Technical Release 5, and it still fails in the same way. Surely I am doing something wrong. Does anyone know what I might be doing wrong, or have any idea how I can find out?

Both Windows 10 and Server 2016 have network stack problems that can cause havoc with NDIS drivers. But it should work with on Server 2012 R2.

Larry C