I found a solution that works for both the bridge service and the bridge adapter> . I do not use UpdateDriverForPlugAndPlayDevices as devcon , but instead I use DiInstallDevice .
However, installing drivers for the first time in non-interactive mode (without user interaction) is not possible. This is because there are no corresponding .cat files for embedded .inf files. Neither UpdateDriverForPlugAndPlayDevices , nor DiInstallDevice , nor DiInstallDriver are intended to be installed manually, where the .inf file is already contained in % SystemRoot% \ inf , but is not yet included in % SystemRoot% \ System32 \ DriverStore .
The files must be located on the distribution medium or in a directory created by the provider, and not in a system location such as% SystemRoot% \ inf
All of the installation methods mentioned will create a copy of the OEM .inf file and install it in the driver repository. Since this OEM copy is not initially part of the driver repository, windows will display a prompt dialog and request user interaction to either force the driver to be installed or to cancel it. Subsequent driver installations are possible without any user interaction. Also, pre-installed drivers (see Pnputil -a) can be installed silently.
So this is my solution:
- First, a device entry in HKLM \ System \ CurrentControlSet \ Enum \ Root is created with this equipment identifier as the device name (ms_bridge, ms_bridgemp) using
SetupDiCreateDeviceInfo - Hardware ID assigned by
SetupDiSetDeviceRegistryProperty - The list of drivers is built with this single .inf file using
SetupDiSetDeviceInstallParams - Enumerating and preselecting a driver using
SetupDiSetSelectedDriver - Registering a device using
SetupDiCallClassInstaller(DIF_REGISTERDEVICE...) - Installation using
DiInstallDevice
This is the full code:
HRESULT InstallDriver(const wchar_t* DriverInfFile, const wchar_t* HardwareId) { HRESULT Hr = S_OK; GUID ClassGUID; wchar_t ClassName[MAX_CLASS_NAME_LEN] = {0}; if (SetupDiGetINFClass(DriverInfFile, &ClassGUID, ClassName, sizeof(ClassName) / sizeof(wchar_t), nullptr) == FALSE) { Hr = HRESULT_FROM_SETUPAPI(GetLastError()); return Hr; } HDEVINFO DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID, nullptr); if (DeviceInfoSet == INVALID_HANDLE_VALUE) { Hr = HRESULT_FROM_SETUPAPI(GetLastError()); return Hr; } SP_DEVINFO_DATA DeviceInfoData = { sizeof(SP_DEVINFO_DATA), 0 }; if (SetupDiCreateDeviceInfo(DeviceInfoSet, HardwareId, &ClassGUID, nullptr, nullptr, DICD_GENERATE_ID, &DeviceInfoData) == FALSE) { Hr = HRESULT_FROM_SETUPAPI(GetLastError()); SetupDiDestroyDeviceInfoList(DeviceInfoSet); return Hr; } if (SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE) HardwareId, (DWORD) (wcslen(HardwareId) + 1) * sizeof(wchar_t)) == FALSE) { Hr = HRESULT_FROM_SETUPAPI(GetLastError()); SetupDiDestroyDeviceInfoList(DeviceInfoSet); return Hr; } SP_DEVINSTALL_PARAMS InstallParams = {sizeof(SP_DEVINSTALL_PARAMS), 0}; InstallParams.FlagsEx = DI_FLAGSEX_ALLOWEXCLUDEDDRVS | DI_FLAGSEX_ALWAYSWRITEIDS; InstallParams.Flags = DI_QUIETINSTALL | DI_ENUMSINGLEINF; wcscpy_s(InstallParams.DriverPath, DriverInfFile); if (SetupDiSetDeviceInstallParams(DeviceInfoSet, &DeviceInfoData, &InstallParams) == FALSE) { Hr = HRESULT_FROM_SETUPAPI(GetLastError()); SetupDiDestroyDeviceInfoList(DeviceInfoSet); return Hr; } SP_DRVINFO_DATA DriverInfoData = {sizeof(SP_DRVINFO_DATA), 0}; if (SetupDiBuildDriverInfoList(DeviceInfoSet, &DeviceInfoData, SPDIT_COMPATDRIVER) == FALSE) { Hr = HRESULT_FROM_SETUPAPI(GetLastError()); SetupDiDestroyDriverInfoList(DeviceInfoSet, &DeviceInfoData, SPDIT_COMPATDRIVER); }
Todo: Find a way to install these bridge drivers from % SystemRoot% \ inf without creating OEM copies and without any user interaction.
You can read / write access to the subversion repository at Sourceforge
Any additional information or suggestions for improvements are appreciated! All please feel free to check / change the code.
The main teams :
- bridgeutil.exe / install
- bridgeutil.exe / uninstall
- bridgeutil.exe / attach
- bridgeutil.exe / detach
<strong> Examples:
bridgeutil.exe /attach "PCI\VEN_10EC&DEV_8169" /attach {5d624f94-8850-40c3-a3fa-a4fd2080baf3}\vwifimp
Attaches each Realtek 8169 network interface card and Microsoft Virtual Wifi adapter to connect the bridge. If the bridge is not already installed, it will be installed first.
bridgeutil.exe /detach 1
Disconnects adapter ID 1 from the bridge.
To view a list of bridge adapters, simply call the bridgeutil.exe file without any arguments.