c# - Programmatically create/destroy network bridges with .NET on Windows 7 -
i trying programmatically create , destroy network bridge on windows 7.
technologically love stay within .net 4 realm (pinvokes fine, ofc), utilizing c++ option.
research far turned configuration, netsh
-commands the route go. however, there seems no option spin new bridge them.
investigating this program uses inetcfg
apis, appears program or, more specifically, apis, not able (again) build new bridge.
if can contribute solving problem, kind of appreciated.
[update:] seems newtork bridges implemented using driver binds both devices. cannot yet make of information, still appreciated.
i've found solution works both bridge service , bridge adapter driver. don't use updatedriverforplugandplaydevices
devcon i'm using diinstalldevice
instead.
however, installing drivers first time in non interactive mode (without user interaction) not possible. because there no corresponding .cat files builtin bridge .inf files. neither updatedriverforplugandplaydevices
nor diinstalldevice
nor diinstalldriver
intended manual driver installation .inf file contained in %systemroot%\inf not yet in %systemroot%\system32\driverstore.
the files should on distribution media or in vendor-created directory, not in system location such %systemroot%\inf
all of mentioned installation methods create oem copy of .inf file , install in driver store. because oem copy not part of driver store, windows show prompt dialog , ask user interaction either force installing driver or canceling. subsequent driver installations possible without user interaction way. preinstalled drivers (see pnputil -a) can installed in non interactive mode.
so solution:
- first device entry in hklm\system\currentcontrolset\enum\root created given hardware id device name (ms_bridge, ms_bridgemp) of
setupdicreatedeviceinfo
- the hardware id assigned
setupdisetdeviceregistryproperty
- the driver list builded given single .inf file of
setupdisetdeviceinstallparams
- enumerating , preselecting driver
setupdisetselecteddriver
- registering device
setupdicallclassinstaller(dif_registerdevice...)
- installing
diinstalldevice
this 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 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 drivers 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 device entry in \root\enum\ removed... setupdiremovedevice(deviceinfoset, &deviceinfodata); } } //setupsetnoninteractivemode(previousmode); setupdidestroydeviceinfolist(deviceinfoset); return hr; }
todo's: find way install bridge drivers within %systemroot%\inf without creating oem copies , without user interaction.
you can gain read/write access subversion repository @ sourceforge
any additional information or suggestion improvement appreciated! please feel free checkout/modify 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 , microsoft virtual wifi adapter bridge. if bridge not installed yet, installed first.
bridgeutil.exe /detach 1
detaches adapter id 1 bridge.
to see list of bridgeable adapters, call bridgeutil.exe without arguments.
Comments
Post a Comment