Reputation: 15867
When I open the properties on a network connnection on windows, I see this dialog: Connection_Properties http://www.freeimagehosting.net/uploads/ca7a4d82ea.png
In this dialog, in the check-listbox I can enable or disable options like "File or printer sharing", "client for microsoft networks" or network filter drivers.
My question is: How can I enable/disable these options programatically? I didn't find anything that looks like this in the WMI documentation and I couldn't find any other Win32 API for this. I would prefer a C Win32 API or WMI interface, but a solution using any programming language is welcome. The question is language-agnostic.
Upvotes: 6
Views: 5122
Reputation: 136
To supplement the accepted answer about using the INetCfg interface, here's a working code sample in C++ you can use to turn off the common "File and Printer Sharing for Microsoft Networks" or any other properties (known as services in the code sample as this seems to be how the API refers to them). Since there aren't really any code samples around for how to do this, including in the MS documentation, I figured this would be helpful.
I've commented up each relevant line so it should be easy to follow along with step by step. I've kept error checking to a minimum to keep the code sample short, but know that the vast majority of these functions return some kind of error code if something goes wrong so in your actual program you should check them all.
NOTE: You will have to run your program as administrator.
#include <netcfgx.h> // For INetCfg and related interfaces
#include <devguid.h> // For GUID_DEVCLASS_NETSERVICE
int main()
{
int returnCode = 0;
INetCfg* pNetCfg = NULL;
INetCfgLock* pNetCfgLock = NULL;
LPWSTR client = NULL;
// Setup pulled from INetCfg sample code in the documentation
CoInitialize(NULL);
CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_SERVER, IID_INetCfg, (LPVOID*)&pNetCfg);
pNetCfg->QueryInterface(IID_INetCfgLock, (LPVOID*)&pNetCfgLock);
pNetCfgLock->AcquireWriteLock(5000, L"MY CLIENT", &client);
pNetCfg->Initialize(NULL);
// Enumerate the available network services e.g. IPV4, IPV6, File and Printer Sharing etc.
IEnumNetCfgComponent* pEnumCfgs = NULL;
pNetCfg->EnumComponents(&GUID_DEVCLASS_NETSERVICE, &pEnumCfgs);
// Loop over the services until we find the INetCfgComponent associated with the interface we want to configure
INetCfgComponent* pNetCfgComponent = NULL;
ULONG fetched = 0;
while (pEnumCfgs->Next(1, &pNetCfgComponent, &fetched) == S_OK)
{
// You can print these IDs using std::wcout if you want to see a list of all the services available on your machine
LPWSTR id;
pNetCfgComponent->GetId(&id);
// ms_server is the ID associated with the "File and Printer Sharing for Microsoft Networks" property
// There are more macros for services in netcfgx.h
if (wcscmp(id, NETCFG_SERVICE_CID_MS_SERVER) == 0)
{
break;
}
}
IEnumNetCfgBindingPath* pBindingPathsForService = NULL;
INetCfgComponentBindings* pBindingsForService = NULL;
// Get the bindings for the service
HRESULT hr = pNetCfgComponent->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pBindingsForService);
if (hr == S_OK)
{
// Get binding path enumerator reference.
hr = pBindingsForService->EnumBindingPaths(EBP_BELOW, &pBindingPathsForService);
pBindingsForService->Release();
ULONG ulCount;
pBindingPathsForService->Reset();
// Loop until all the bindings are enumerated and disabled
INetCfgBindingPath* pBindingPathForService = NULL;
while (pBindingPathsForService->Next(1, &pBindingPathForService, &ulCount) == S_OK)
{
// Disable this binding.
hr = pBindingPathForService->Enable(FALSE); // Set to TRUE to enable the binding
if (hr == S_OK)
{
// Save the changes,
pNetCfg->Apply();
}
// Release the interface and set it to NULL.
pBindingPathForService->Release();
pBindingPathForService = NULL;
}
// We have enumerated all the bindings and disabled them. Release the interfaces.
pBindingPathsForService->Release();
}
// Teardown pulled from INetCfg sample code in the documentation
pNetCfg->Apply();
pNetCfg->Uninitialize();
pNetCfgLock->ReleaseWriteLock();
pNetCfg->Release();
CoUninitialize();
return returnCode;
}
It's also worth noting that you can turn off properties for specific network cards. When looping over the bindings enumeration you can enumerate the INetCfgBindingInterfaces for a given INetCfgBindingPath and then get their "lower component". You can check the lower component for a specific display name and ensure you only disable the bindings for the associated component by disabling bindings that match and leaving the others untouched.
To do this you could stitch in a call to a function like this at around line 58 in the first code sample using the result as a condition as to whether to enable/disable the binding:
INetCfgComponent* FindComponentByNameInServiceBinding(INetCfgBindingPath* bindingPathForService, LPWSTR componentName)
{
IEnumNetCfgBindingInterface* pBindingInterfacesEnum;
bindingPathForService->EnumBindingInterfaces(&pBindingInterfacesEnum);
INetCfgComponent* pNicComponent;
ULONG ulFetched;
INetCfgBindingInterface* pBindingInterface;
while (pBindingInterfacesEnum->Next(1, &pBindingInterface, &ulFetched) == S_OK)
{
pBindingInterface->GetLowerComponent(&pNicComponent);
LPWSTR name;
pNicComponent->GetDisplayName(&name);
if (wcscmp(name, componentName) == 0)
{
return pNicComponent;
}
}
return NULL;
}
Hopefully this is helpful to anyone like me who struggled to find concrete examples of how to use the INetCfg interface.
Upvotes: 1
Reputation: 21
For everyone who are kind of new to programming and are still learning, or to people who doesn't have the time to code using the interface INetCfg mentionned by ho1, I found a tool called nvspbind that does exactly this. It can be used to set the correct binding and enable/disable specific bindings on any NIC.
Upvotes: 1
Reputation: 54999
I think INetCfg is what you're looking for:
http://msdn.microsoft.com/en-us/library/ff547694%28VS.85%29.aspx
Edit: Here's a link to a discussion where someone uses INetCfg to disable just File & Printer sharing.
Upvotes: 4