Installing a driver for a specific device - winapi

I would like to install a custom driver for a specific device in my machine programmatically:
The driver comes as an .inf file (with some other files as well).
The device is one of two identical network adapters in my computer.
As far as I know the only way to achieve this goal is to use the Microsoft Setup API. From reading the documentation I would assume that I need to perform two steps:
Use "DiInstallDriver" to install my .inf-based driver into the driver store (see https://learn.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-diinstalldrivera).
Use "DiInstallDevice" to apply my driver to the device (see https://learn.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-diinstalldevice).
Would this be the correct/easiest way to do this?
If so, here's a follow up question: DiInstallDevice requires two parameters which I don't know how to acquire:
DeviceInfoData: this should point to the network adapter I want to modify. How do I get this?
DriverInfoData: this should probably point to the driver I installed in step 1? How do I get this?
PS: Doing all this manually is uper easy: Open device manager, right-click the network adapter, select 'Update driver', choose .imf file from disk -> done!
But in this case I need to do it programmatically.
PPS: DevCon is not an option. It only allows to exchange the driver based on an Hardware ID. And that ID is the same for both of my network adapters (since they are exactly identical). So it would change the driver both devices.

You don’t need to call two methods, DiInstallDriver not only preinstalls a driver in the driver store, but also installs the driver on devices present in the system that the driver supports.
You can refer to the following documents: Functions that Simplify Driver Installation
It seems that UpdateDriverForPlugAndPlayDevices is the simplest way.
For DiInstallDevice, this function should only be use if both of the following are true:
The application incorporates more than one device instance of the same type, that is, all the device instances have the same hardware IDs and compatible IDs.
The application requires that device-instance-specific drivers be installed on the device instances.
UpdateDriverForPlugAndPlayDevices or DiInstallDriver is the
simplest way for an installation application to install a new driver
that is the best match for devices in the system. ... The basic operation
of UpdateDriverForPlugAndPlayDevices is similar to the operation of
DiInstallDriver. However UpdateDriverForPlugAndPlayDevices
supports additional installation options.
You can specify the HardwareId of network adapter for the UpdateDriverForPlugAndPlayDevices. If you want to install your .inf driver no matter what a better driver already exists on your computer, you also need to specify InstallFlags as INSTALLFLAG_FORCE.(Caution: Forcing the installation of the driver can result in replacing a more compatible or newer driver with a less compatible or older driver.)

Related

Change installed device driver

I am trying to change the installed driver for a device using SetupAPI. The driver is already present on the PC, just not currently selected.
More specifically, I am trying undo the installation of a third-party driver for a USB composite device, and install the default windows driver instead.
I already got it almost working like this: First, find the device using
SetupDiGetClassDevs
SetupDiEnumDeviceInfo
SetupDiGetDeviceInstanceId
to find the device.
Next, find the default USB composite device driver I want to install using
SetupDiBuildDriverInfoList
SetupDiEnumDriverInfo
SetupDiGetDriverInfoDetail
Once I found the driver, I call
SetupDiSetSelectedDriver
SetupDiInstallDevice
This actually does switch the driver back, as can be observed in device manager.
However, the third party driver put the device into its own group/category, and this change is not undone when using my approach.
Manually selecting the standard USB composite device driver in the device manager does restore the device category back to USB Controllers, which is why I think my driver installation process is incomplete. What might I be missing?
Turns out the working installation sequence is
SetupDiSetSelectedDevice
SetupDiSetSelectedDriver
InstallSelectedDriver // From newdev.dll, not in a public header

Remove incorrect binding of composite device to custom driver

Our latest WHQL'ed custom driver has an incorrect entry for one of our upcoming product. The upcoming product is composite device and our WHQL'ed driver has an entry which matches the device ID for the composite device instead of the individual interfaces.
When the new device is connected to machines which have the WHQL'ed driver, the device gets binded to our driver and not to Windows Generic Parent Driver (usbccgp.sys). This prevents the interfaces in the device from being listed.
We could manually fix this by uninstalling the driver for the device and making it to bind to usbccgp.sys driver. In Vista and higher versions, we could delete the driver binaries at the time of uninstall. But there is no direct way to completely delete the driver binaries in XP. This makes it very difficult to cleanly uninstall the driver
Can this be fixed using an uninstaller? What is the best way to fix the affected machine in an automated way?
Download the Windows Driver Development Kit (Win DDK) and locate the devcon.exe executable for your architecture. Then, from an elevated command prompt:
devcon.exe find =usb
To list all of your current devices.
devcon.exe -r remove =usb *YOUR_HARDWARE_ID*
Will complete disassociate the device and driver from the target machine. If you have trouble getting the hardware id you can blow away all your USB drivers and let Windows auto-detect them after reboot.
devcon.exe -r remove =usb *
Extreme, yes. Effective, yes. We work with virtual comm ports all day and our test machines often experience your same issue. This technique has yet to fail.

Finding the graphics card device ID without drivers installed

I need to create an automated process in which a script detects the graphics card type on first boot, then installs the appropriate drivers, which will be included in the image, before performing the next steps. The target platform is Win XP Pro.
I came across some WMI code which can get hardware information but since it uses a PNPSignedDriver class I would presume that it requires drivers to be installed before it can detect the device.
I can't use devcon, as it isn't redistributable. Am I right in assuming that WMI cannot help me here, and if so what are my other options?
Thanks,
Bill.
WMI does seem to be the way to do this, as found here. I will confirm after testing.
EDIT - Not sure if this is possible, WMI can only get the name of the display adapter not the device ID of the card, and before the drivers are installed this is something generic like "Video Controller (VGA)". I will update this page if I find a way.

Make driver load automatically when USB device is inserted

I'm using a Limited User account under Windows XP, and I'm having a bit of trouble getting my Adaptoid (the most coveted N64 controller -> USB adapter, because of it's support for sending raw N64 controller commands + the fact that it's been discontinued) to work smoothly: as installed, the included software requires Administrator privileges to load the driver.
Presumably, it is possible to arrange for the driver to be loaded automatically when the Adaptoid is inserted by adding some stuff to the INF file for the driver (wishna1.inf):
the question is, what stuff?
(It would also suit me just as well if the driver could be automatically loaded when anything attempted to open \Device\Wish_NA1, or even to have it automatically loaded at every boot, really, but doing it on insertion seems like the right way.)
Note: I do have access to an administrative account, it's just that I prefer not to have to use it day-to-day.
First of all, let's clarify that a USB device has a Plug & Play driver on Windows 2000 and higher, so services start modes are irrelevant. The driver will have an entry as a "service" in the registry, but its start mode is irrelevant here.
Let's split the problem into two parts:
Installing driver for the device: This requires administrative privileges. This happens when you insert a USB device into a port for the first time. Windows goes over your .INF files to find one that matches your hardware. If the driver is WHQL-certified, it'll load automatically. Otherwise, you'd see the dreaded Add New Hardware wizard. If you're running as admin, a few clicks on Next should be enough to install it. Otherwise, better have that Administrator password ready.
Loading the driver for the device: Once the device is installed, the driver will be loaded each time this device is inserted into this USB port without requiring any additional user intervention. Ever noticed how a USB printer, camera or disk drive load much faster the second time you plug it in? That's because that's just loading, without installing.
From looking at the .INF, it looks valid. Also, it's not WHQL-certified, so you'd have to install it manually.
I'm assuming when you insert the Adaptoid, you get an Add New Hardware wizard. If you point it manually to the installation directory, does the Adaptoid install and function? Does it appear in the Device Manager?
P.S. USB devices which have a serial number are an exception. They're installed once for all USB ports. Those devices are rather uncommon, though.

Rescan device tree for hardware changes during Driver installation

I'm using InstallShield to install my application, a driver and a service.
I need to install the plug-N-play driver only if it's hardware ID was found in the device manager. The driver installation is done using DPInst.exe.
My problem, is that a user can sometimes manually uninstall the driver (After it was installed or even uninstall the "Unknown driver" under "Other devices") and then I can't find the hardware ID in the device tree, although the device is plugged.
If I rescan the device tree during installation using CM_Reenumerate_DevNode_Ex (The code equivalent of "Scan for new hardware"), I can find the hardware ID but this brings up the "Found new hardware wizard".
Is there anyway to rescan the device tree but suppress the "Found new hardware wizard" or to avoid rescanning but still making sure my device hardware ID is present in the system?
I'm writing a new answer since we already have too many comments on my older one, and its content was based on a small misunderstanding of the situation.
The actual problem, as I understand it now, is the "Add new hardware" wizard that pops-up when rescanning for devices, before installing your driver. Unfortunately, this wizard pops-up whenever no suitable driver is found to handle a new device in the system, so in order to overcome it, the only option is to make sure that such a driver exists in the system. This leads to two possible solutions that I can see:
Go for a software first installation, and make sure that your driver is suitable for the device (the inf is well formed, and you have WHQL signing). As far I understand, this is not an option, because you do not want to install the driver on machines that don't have the device connected (I would love to hear why).
Make sure that some other driver in the system is suitable to handle it. In that case you need to choose one of the built-in drivers (one that wouldn't wreak havoc if it were to act as a function driver for your device), and give your device a matching compatible ID - one that would cause the built-in driver to be found suitable. This way you will not have to wait for the user after re-scanning for devices, but depending on your device, finding a fitting built-in driver might be impossible.
It sounds like you're going about it the wrong way. If you have an MSI based installation, why not use DIFxApp instead of DPInst?
As for the "Found new hardware" wizard, you'll need two things here:
Make sure that your inf file is correct (so that your driver is associated with the hardware id)
Get a WHQL signature from MS. This step is needed for XP, as untrusted drivers will not be automatically assigned to devices. With Vista and 7 you can digitally sign the driver yourself, but you'll get a warning during installation, asking the user whether he/she wishes to trust this publisher (you).

Resources