Win7: Replacing a driver without reboot - windows-7

I'm debugging an audio driver under Windows 7. When I need to replace it with an updated version, I have to reboot the system because a copy of current driver under DriverStore is locked despite the fact that the driver is unloaded. Is there a way to avoid rebooting? It was possible on XP...

Do you tried to stop driver with devcon.exe utility (an old version can be downloaded also in http://support.microsoft.com/kb/311272, a new version you find under C:\WinDDK\7600.16385.1\tools\devcon\i386 after intalling of WDK)? Do you examine which processed use your driver (for example with respect of Process Explorer http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx)? If you describes your problem more exactly I could try to help you.

Related

Prevent custom windows kernel driver backup from running

I have a custom windows kernel driver I have compiled. I sign it with a test cert, create the cat file from the cdf, stamp the inx into a inf file, then load it with pnputil. I then create a software device with SwDeviceCreate so the OS will pair my driver and the driver. This works fine.
The problem is if i screw up something in the compilation and get something like an error code 39 (viewable in device manager), I do not see that error. Instead the OS seems to try to fix the error by loading the previously working version of the driver. In order to see that error, I have to purge the driver and device using pnputil /d oem42.inf along with a pnputil /remove-device, then restart my PC, that seems to fix the issue. This is difficult because it means i have to restart my PC every time i run a test. I know crashing a kernel driver can cause a panic anyway and cause me to restart, but there seems to be instances where this is not the case and the OS tries to rectify the issue without me (as it probably should).
So my question is this. Is there a way to completely purge my driver without a complete restart in-between installations/tests so I can correctly break it. I know I am suppose to use another machine and remote debug kernel drivers, but i do not have access to another machine right now that can support windows 11.

Using netcfg to remove an NDIS LWF doesn't remove it from the driver store?

When i try to remove my NDIS LWF using netcfg -u, i notice that it doesn't remove it from the driver store (can be seen with pnputil /enum-drivers).
This is causing problem because on some Windows 10 machines, if we uninstall the previous version of our NDIS LWF and install the new one using netcfg, for some unknown reason the old inf is still used to install it! And i assume its because the inf still has the same componentID? We are updating the INF file in order to attach to some virtual adapters that we previously couldn't attach. Note that this doesn't happen in Windows 7, and we can install the new one without any problem.
So my questions are:
Why is Windows still using the previous INF from driver store when we try to install the new updated driver that has a different INF?
What is the proper way to fully remove the previous NDIS LWF, including from driver store? If we need to use pnputil to fully remove it from driver store, then what is the proper way of finding the OEM number, considering that pnputil -d requires an OEM number?
Right, as you've noticed, netcfg.exe -i is not the exact opposite of netcfg.exe -u.
Installation does these steps:
Install the INF you provided with -l to the driver store (SetupCopyOEMInf)
Call INetCfgClassSetup::Install to:
Query PNP for the "best match" for the componentId you provided with -i (SetupDiBuildDriverInfoList, SetupDiSelectBestCompatDrv)
Run all the sections in the INF (AddReg, AddService, etc)
Register a LWF/Protocol/TDI driver with the system using info in the Ndi registry key
Uninstall does these steps:
Call INetCfgComponent::DeInstall to:
Deregister your LWF/Protocol/TDI driver with the system
Run the special .Remove section of the INF (which, hopefully, contains a DelReg, DelService to undo everything done during install step #2.2)
(The descriptions above ignore the driver refcount system (aka OBO_TOKEN), since it isn't often used — most drivers just use a single refcount. If you exclusively use netcfg.exe to manage your driver, then you too can ignore refcounts.)
You might be wondering: why is this so very less-than-awesome? The backstory here is that netcfg.exe was never really meant to be a general-purpose tool for 3rd party software to manage their drivers. It was only meant to be used internally, for the drivers that are built into the OS (ms_tcpip etc). The assumption was that 3rd party driver installers would want to call proper APIs like INetCfg, not CreateProcess some executable and screen-scrape the output. So netcfg.exe was only built up to be the minimum needed for our internal needs. In particular, very little attention was paid to uninstall, since built-in drivers are rarely uninstalled. (Likewise, argument parsing is inflexible, the help text is not helpful, and the error handling is not robust.)
Starting in Windows 10, built-in drivers are no longer installed using netcfg.exe, so the OS itself doesn't need netcfg.exe at all anymore. But by then, 3rd party products had discovered it and taken a dependency on it, so we couldn't just remove netcfg.exe anymore. Ah well.
Why is Windows still using the previous INF from driver store when we try to install the new updated driver that has a different INF?
This is a common gotcha. Note that, during install, steps #1 and #2 have no association between them. You could install a printer INF and a LWF at the same time — netcfg.exe -l foo.inf -i bar makes no effort whatsoever to ensure that the "best" component selected in step #2.2 actually came from the INF installed in step #1.
In order to ensure that the driver you want is the "best" driver, you have to ensure that your favored driver wins the PNP driver selection algorithm. I've personally been bitten by this because I didn't bump the DriverVer line during development iterations. Make sure you increment DriverVer every time you change the driver.
What is the proper way to fully remove the previous NDIS LWF, including from driver store? If we need to use pnputil to fully remove it from driver store, then what is the proper way of finding the OEM number, considering that pnputil -d requires an OEM number?
Honestly, if you want to do everything really correctly, I suggest avoiding netcfg.exe entirely. Use the underlying INetCfg APIs instead. Then your installer will have to manage the driver (SetupCopyOEMInf / SetupUninstallOEMInf).
You aren't losing much by ditching netcfg.exe and calling INetCfg yourself. netcfg.exe doesn't do anything particularly fancy with INetCfg: its own implementation is nearly exactly taken from this sample code. If you start with that and slap a call to SetupCopyOEMInf on top, you'll pretty much be at parity with netcfg.exe already. From there, you can improve it with more robust INF uninstall. You can even write some code to inventory all the INFs with your componentId, to make sure there aren't stale copies of your INF hiding around.
You still have to make that leap of trust from installing an INF to hoping that INetCfgClassSetup::Install thinks your recently-installed INF is the "best" INF. But if you've removed every other INF with that componentId, then you can be certain that the sole remaining INF must be the best match.

Disabling an input device (keyboard, mouse) which is used in current session

I'm developing a filter driver which works on top of an input device. Notably I'm testing it on my development machine (and yes, I know this is a bad idea).
On Windows XP whenever I needed to reload the filter driver, I'd just execute a batch file that would disable-enable the relevant devices through devcon, thus cause my filter driver to unload and reload.
However, on Windows 7 there seems to be a specific measure built against disabling the input device which your session is using. The option simply becomes unavailable in the Device Manager and even devcon no longer works. It does work from a remote desktop session, along with the kernel debug print "Trying to disable physical device not enabled in this session." (which hints that something explicit is allowing me to do this).
Is there a way to disable this functionality of Windows 7? Or perhaps a workaround you can offer to run my disable-enable batch file from an unrelated session?
Using Sysinternals psexec to run dpinst.exe works around this limitation. (Not sure why, since the DpInst UI is still being displayed.)

Trouble installing sample portio driver from winDDK

I am currently trying to build an application, that will talk to the super IO chip using port IO. As part of that, I am trying to develop a kernel-mode windows driver that I can contact, and which will do the IO for me. I have therefore downloaded the Windows Driver Kit v7.1.0, build 7600.16385.1, and I am trying to compile and install the sample portio driver, which is provided by WDK, since it seems to be quite close to what I need.
I have compiled the driver in both free and checked x86 XP build environments. This works fine, but when I try to install the resulting driver, using the provided instructions - which basically just amount to using the Add Hardware Wizard, and then supplying the files manually - I get the following error:
-The following hardware was installed: Sample PortIO Driver (KMDF)
-The software for this device is now installed, but may not work correctly
-Windows cannot load the driver for this hardware. The driver may be corrupted or missing. (Code 39)
So, I see two explanations: corrupted or missing. Missing, as far as I can tell, given my environment variables and .inf file, would mean that the generated .sys file is not in c:\windows\system32\drivers, but when I look there, the file is there.
So that would mean that the file is corrupted. Given that I haven't touched the driver code, and that I have found others with the same problem, it doesn't seem to be a problem with my compilation, but rather with the code itself, or some common combination of machine type and code. But I may be wrong.
Does anybody have any suggestions on how to solve this?
I would recommend enabling SetupAPI logging as described in the following document from Microsoft:
http://www.microsoft.com/whdc/archive/setupapilog.mspx
For Windows 7, the log files are split up as described here:
http://support.microsoft.com/kb/927521
You may be able to isolate the problem with the additional information in the SetupAPI logs.

How to prevent Windows from caching Com Class info?

Windows 7 is caching some of the COM class information. Older OSs didn't do this. After the OS looks up theHKCU\Software\Classes\CLSID\{GUID}\LocalServer32 value, it caches the value, and doesn't look it up again.
When we update our software, we place the new updates in a different directory, and then update the HKCU\Software\Classes\CLSID\{GUID}\LocalServer32 value to reflect the new path. The next time the software runs, it will use the latest files if running under older Windows OSs. However, on Windows 7, it will continue to use the older file, until the OS is rebooted.
I ran process monitor, and discovered that under Windows 7, it never reads the registry key again, after the first read. On older OSs, it reads that key every time.
My question is: Is there any way to force Windows 7 to re-read the LocalServer32 information from the HKCU hive each time a new out of proc COM object is created?
I have only been able to solve this problem by...
1: Stopping the Process
2: explicitly unregistering using regsvr32 the library ( or exename /unregserver)
3: Registering the new component
4: Starting the process back up.
I would suspect that it is the Un Reg part that is failing for you. If you are just changing the registry key directly then you should call RegSvr32 /u instead.
Also make sure the new directory location is the current directory when you call RegSvr32.
Note that I have always stopped the process and then unregistered, this is probably a significant detail.
As this is a top result in Google for this narrow-ish problem, I thought it would be valuable to add my troubleshooting outcome for this problem.
I found this response on SO: C# : How to change windows registry and take effect immediately
And linked solution from that answer: Registry Watcher C#
Both of which seem viable options for managing changed keys without forcing a reboot. For us (like the OP) this was when installing updates. For us (possibly unlike the OP) this is infrequent and we decided the effort to implement and test a fix as described was outweighed by the simple solution of requiring a reboot: a process Windows users have come to expect with installing software anyway.

Resources