I am trying to programmatically create and destroy a network bridge on Windows 7.
Technologically I would love to stay within the .Net 4 realm (PInvokes are fine, ofc), but utilizing C++ is an option.
My research so far turned up that for configuration, netsh
-commands are the route to go. However, there seems to be no option to actually spin up a new bridge with them.
I am currently investigating this program that uses the INetCfg
APIs, but it appears that the program or, more specifically, the APIs, are not able to (again) build a new bridge.
If anyone can contribute to solving the problem, any kind of help is greatly appreciated.
[Update:] It seems that newtork bridges are implemented using a driver which then binds to both devices. I cannot yet make much of that information, so still any help is appreciated.
-
AFAIK it is not possible to have multiple network bridges on Windows. – dsi Jul 11 '13 at 10:53
-
1Thanks for your comment. I was not aware of that restriction; however, it has no effect on the problem. It is really just one bridge that I care about, and I would delete it before recreating it so this restriction doesn't interfere. – Janis F Jul 11 '13 at 12:24
5 Answers
I've found a solution that works for both bridge service and bridge adapter driver. I don't use UpdateDriverForPlugAndPlayDevices
like devcon but I'm using DiInstallDevice
instead.
However, installing the 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 the builtin bridge .inf files. Neither UpdateDriverForPlugAndPlayDevices
nor DiInstallDevice
nor DiInstallDriver
is intended for manual driver installation where .inf file is already contained in %SystemRoot%\inf but not yet in %SystemRoot%\System32\DriverStore.
The files should be on the distribution media or in a vendor-created directory, not in a system location such as %SystemRoot%\inf
All of the mentioned installation methods will create a OEM copy of the .inf file and will install it in driver store. Because this OEM copy is initially not part of the driver store, windows will show a prompt dialog and ask for user interaction either force installing the driver or canceling. Subsequent driver installations is possible without any user interaction by the way. Also preinstalled drivers (see pnputil -a) can be installed in non interactive mode.
So this is my solution:
- First a device entry in HKLM\System\CurrentControlSet\Enum\Root is created with the given hardware id as device name (ms_bridge, ms_bridgemp) with the help of
SetupDiCreateDeviceInfo
- The hardware id is assigned with
SetupDiSetDeviceRegistryProperty
- The driver list is builded by exactly the given single .inf file with the help of
SetupDiSetDeviceInstallParams
- Enumerating and preselecting driver with
SetupDiSetSelectedDriver
- Registering device with
SetupDiCallClassInstaller(DIF_REGISTERDEVICE...)
- Installing with
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);
}
// Use first best driver (since specified by inf file)
if (SetupDiEnumDriverInfo(DeviceInfoSet, &DeviceInfoData, SPDIT_COMPATDRIVER, 0, &DriverInfoData)) {
SetupDiSetSelectedDriver(DeviceInfoSet, &DeviceInfoData, &DriverInfoData);
}
if (SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData) == FALSE) {
Hr = HRESULT_FROM_SETUPAPI(GetLastError());
}
// TODO: Allow non interactive mode for drivers already contained in %SystemRoot%\inf directory
//BOOL PreviousMode = SetupSetNonInteractiveMode(TRUE);
if (Hr == S_OK) {
if (DiInstallDevice(nullptr, DeviceInfoSet, &DeviceInfoData, &DriverInfoData, 0, nullptr) == FALSE) {
Hr = HRESULT_FROM_SETUPAPI(GetLastError());
// Ensure that the device entry in \ROOT\ENUM\ will be removed...
SetupDiRemoveDevice(DeviceInfoSet, &DeviceInfoData);
}
}
//SetupSetNonInteractiveMode(PreviousMode);
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return Hr;
}
Todo's: Find a way to install this bridge drivers from within %SystemRoot%\inf without creating OEM copies and without any user interaction.
You can gain read/write access to subversion repository at Sourceforge
Any additional information or suggestion for improvement is appreciated! Everyone please feel free to checkout/modify the code.
Basic commands:
- bridgeutil.exe /install
- bridgeutil.exe /uninstall
- bridgeutil.exe /attach
- bridgeutil.exe /detach
Examples:
bridgeutil.exe /attach "PCI\VEN_10EC&DEV_8169" /attach {5d624f94-8850-40c3-a3fa-a4fd2080baf3}\vwifimp
Attaches each Realtek 8169 Network Interface Cards and Microsoft Virtual Wifi Adapter to bridge. If the bridge is not installed yet, it will be installed first.
bridgeutil.exe /detach 1
Detaches adapter with id 1 from bridge.
To see a list of bridgeable adapters, just call bridgeutil.exe without any arguments.

- 2,740
- 1
- 36
- 52
-
Thank you for your thorough answer! I suggest uploading the source to [GitHub](http://www.github.com/). Thanks for sharing! – Janis F Mar 05 '14 at 15:50
-
1No it will not work in Windows 10, at least not with the method described here since Windows 8/8.1/10 bridge driver structure changed. – bkausbk Jun 12 '17 at 07:02
It is actually possible to create and network bridges via the SetupAPI.
Using the DevCon Tool, destroying them is as easy as this...
devcon.exe remove ms_bridgemp
...while building bridges can be done with this command:
devcon.exe install "C:\Windows\inf\netbrdgm.inf" ms_bridgemp
DevCon is open source, so you can dig into the sources to see how it implements those commands (the DevCon Tool is essentially a CLI to the SetupAPI).
Please note: The commands relate to Windows 7. The approach is said to work on XP and I suppose it works on other Windows Versions, too, but the .INF-File might have a different name or the device ID might differ.

- 2,637
- 1
- 25
- 36
-
This does actually install network bridge driver, but there is no way to configure it afterwards AFAIK – dsi Jul 26 '13 at 14:06
-
Actually, there is. You can fire off commands via `netsh` to configure the bridge. Granted, the whole approach is a little hacky, but will serve its purpose. – Janis F Jul 28 '13 at 20:21
-
@Romiox Why does the same procedure no work with the bridge service driver itelf? devcon.exe install "c:\windows\inf\netbrdgs.inf" ms_bridge fails with "no such device instance" or similar. It should also be possible to install this driver the same way. – bkausbk Feb 28 '14 at 07:04
-
@bkausbk I'm sorry, I don't know. It's not exactly easy to find documentation. But if you find an answer, please share. – Janis F Feb 28 '14 at 15:20
After much unsuccessful searching on the Internet I wrote and have been successfully using the following Windows Script Host script "BridgeConnections.vbs" to create a network bridge on Windows XP (this method also works on Windows 7 and Windows 8 with slight modifications). It can be run from the command prompt or from a batch file as follows:
C:\Temp> cscript BridgeConnections.vbs
File BridgeConnections.vbs:
' This VBScript opens the "Network Connections" control panel window,
' sends Ctrl+A ("Select All") and Alt+N ("Advanced" menu) and
' C ("Bridge Connections" menu command) keystrokes to it and then waits
' until the splash window "Please wait while Windows bridges the connections..."
' disappears from the screen
Dim WshShell, Count
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Exec("rundll32.exe shell32.dll,Control_RunDLL ncpa.cpl")
Count = 0
Do While Not WshShell.AppActivate("Network Connections") And Count < 10
Count = Count + 1
WScript.Sleep 1000
WScript.Echo "Waiting for the 'Network Connections' window... " & CStr(Count) & "s"
Loop
WshShell.SendKeys "^(a)"
WshShell.SendKeys "%(n)"
WshShell.SendKeys "c"
Count = 0
Do While Not WshShell.AppActivate("Network Bridge") And Count < 10
Count = Count + 1
WScript.Sleep 1000
WScript.Echo "Waiting for the 'Network Bridge' splash window... " & CStr(Count) & "s"
Loop
Count = 0
Do While WshShell.AppActivate("Network Bridge") And Count < 120
Count = Count + 1
WScript.Sleep 1000
WScript.Echo "Waiting for the 'Network Bridge' splash window to disappear... " & CStr(Count) & "s"
Loop
Likewise one could modify the script to "Delete" the bridge if required (make a single selection with Shift and navigate keys and send a different keystroke command). In my case I only need to bridge all available ethernet adapters from a batch file so the above method works just fine.
In my experience, the "slight" problem with the
devcon.exe install "C:\Windows\inf\netbrdgm.inf" ms_bridgemp
approach posted here earlier is that it would create an empty, "half-backed" bridge with no adapters in it. So you will still have to go to the Windows GUI and "Add" adapters it one by one manually before it becomes really usable.
The only fully automated solution that really works for me it the above script.
To do the same actions from a C++ or C# code without the script you'd need to know and call undocumented Shell Network Interfaces (NETSHELL.DLL) functions which in turn are called by the Explorer Shell when the user initiates the actions via list view item selection and context menu command in the Windows GUI. A C++ sample of calling into the Shell Network Interface for programmatically disabling/enabling a Network Adapter can be seen here. Unfortunately there is no sample yet for creating/removing the Network Bridge adapter. So until it becomes available I'll stick with the script.

- 31
- 2
-
Thanks for your answer. Adding/Removing adapters can be done rather easily in comparison to this hack. I can't give you the source, but I solved that problem by taking a look at the `bindview` sample program published by Microsoft. – Janis F Sep 26 '13 at 22:36
-
Hi Romiox, Yes, I'd really appreciate if you sent me the source code for doing that, that you derived from the bindview sample. Looking forward to receving it! Thanks in advance. – user2811158 Oct 31 '13 at 12:45
-
I really can't give out the source, however I can give you directions: [this](http://code.msdn.microsoft.com/windowshardware/Bindview-ec8f6e0a) is the link to the bindview program. The page also links to the setup it can be compiled with- the code does work with older WDKs, too, though. In the interface, you'll find something along the lines of "bindings". Try to bind the devices via that interface. If you manage to do that, all you need is a few breakpoints and rough understanding of C++ and COM. Good Luck! – Janis F Nov 02 '13 at 15:56
Based on the bindview example, I put up an utilitary called bindbridge, which works as following:
Usage: bindbridge <deviceId> <bind|unbind>
The source can be found at https://github.com/OurGrid/OurVirt/tree/master/tools/win32/bindbridge, and it assumes the bridge device already exists - which can be created with devcon, as per previous answers - and its name to be ms_bridge, what can be easily changed in the sources.
I'm using it to programatically add tap interfaces to the bridge, so my command line is something in the lines of:
bindbridge ROOT\NET\0001 bind

- 31
- 1
-
Awesome, been looking for a way to bridge the "Microsoft Virtual WiFi Miniport Adapter" (created from the "netsh wlan set hostednetwork" command) to anther NIC and this worked! Seems odd that this isn't build into netsh bridge. Is the code in the link mostly from the bindview sample and your code is just the main.cpp? – jkasten Feb 05 '14 at 13:37
-
@jkasten Could you tell me the command line to create a bridge to the Virtual WiFI Miniport Adapter – bkausbk Feb 20 '14 at 08:01
-
Create a bridge with: devcon.exe install "C:\Windows\inf\netbrdgm.inf" ms_bridgemp Download bindbrige here: https://github.com/OurGrid/OurVirt/blob/master/tools/win32/bindbridge/target/bindbridge.exe You will need to find your "
"s for your NICs. There are a few ways to do this but one is use to run "devcon hwids *". "PCI\VEN_...." would be for your real NICs and the "Microsoft Virtual WiFi Miniport Adapter" should look something like "{XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX}\VWIFIMP...". If that doesn't work create a new question on superuser.com since replies are limited in comments. – jkasten Feb 21 '14 at 21:09 -
@jkasten Thank your for that hint. I'm currently creating a specialized bridge tool that correctly binds to bridge and unbind from all other protocols (tcpip, rmcast...) at once like windows is creating a bridge. This will also install/uninstall the bridge driver if necessary and setting the ip address of the bridge adapter at once. I'll provide it as binary (or source) if the tool is completed. – bkausbk Feb 23 '14 at 12:57
It turns out that, unfortunately, there is no documented way of setting up a network bridge.
The code which does that is located inside hnetcfg.dll, and is invoked only by Windows Explorer. It installs bridge driver, and configures bridge interface.
It might be possible to call it yourself (using COM), but that would require reverse engineering and may break on any system update, so I recommend against doing that.

- 586
- 3
- 13
-
That's a little discouraging; thank you, though. Do you have a reference to back that up? – Janis F Jul 12 '13 at 06:39