summaryrefslogtreecommitdiff
path: root/network/config/bindview/NetCfgAPI.cpp
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
committerDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
commit97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch)
tree46f3701832d70b420eb0fc0eb93261f9da45db3f /network/config/bindview/NetCfgAPI.cpp
parentef1905bf1e8825bb31120dfb27e0daf3154d859a (diff)
Initial publish
Diffstat (limited to 'network/config/bindview/NetCfgAPI.cpp')
-rw-r--r--network/config/bindview/NetCfgAPI.cpp878
1 files changed, 878 insertions, 0 deletions
diff --git a/network/config/bindview/NetCfgAPI.cpp b/network/config/bindview/NetCfgAPI.cpp
new file mode 100644
index 00000000..5080bb41
--- /dev/null
+++ b/network/config/bindview/NetCfgAPI.cpp
@@ -0,0 +1,878 @@
+//+---------------------------------------------------------------------------
+//
+// Microsoft Windows
+// Copyright (C) Microsoft Corporation, 2001.
+//
+// File: N E T C F G A P I . C P P
+//
+// Contents: Functions to illustrate INetCfg API
+//
+// Notes:
+//
+// Author: Alok Sinha 15-May-01
+//
+//----------------------------------------------------------------------------
+
+#include "NetCfgAPI.h"
+
+//
+// Function: HrGetINetCfg
+//
+// Purpose: Get a reference to INetCfg.
+//
+// Arguments:
+// fGetWriteLock [in] If TRUE, Write lock.requested.
+// lpszAppName [in] Application name requesting the reference.
+// ppnc [out] Reference to INetCfg.
+// lpszLockedBy [in] Optional. Application who holds the write lock.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrGetINetCfg (IN BOOL fGetWriteLock,
+ IN LPCWSTR lpszAppName,
+ OUT INetCfg** ppnc,
+ _Outptr_opt_result_maybenull_ LPWSTR *lpszLockedBy)
+{
+ INetCfg *pnc = NULL;
+ INetCfgLock *pncLock = NULL;
+ HRESULT hr = S_OK;
+
+ //
+ // Initialize the output parameters.
+ //
+
+ *ppnc = NULL;
+
+ if ( lpszLockedBy )
+ {
+ *lpszLockedBy = NULL;
+ }
+ //
+ // Initialize COM
+ //
+
+ hr = CoInitialize( NULL );
+
+ if ( hr == S_OK ) {
+
+ //
+ // Create the object implementing INetCfg.
+ //
+
+ hr = CoCreateInstance( CLSID_CNetCfg,
+ NULL, CLSCTX_INPROC_SERVER,
+ IID_INetCfg,
+ (void**)&pnc );
+ if ( hr == S_OK ) {
+
+ if ( fGetWriteLock ) {
+
+ //
+ // Get the locking reference
+ //
+
+ hr = pnc->QueryInterface( IID_INetCfgLock,
+ (LPVOID *)&pncLock );
+ if ( hr == S_OK ) {
+
+ //
+ // Attempt to lock the INetCfg for read/write
+ //
+
+ hr = pncLock->AcquireWriteLock( LOCK_TIME_OUT,
+ lpszAppName,
+ lpszLockedBy);
+ if (hr == S_FALSE ) {
+ hr = NETCFG_E_NO_WRITE_LOCK;
+ }
+ }
+ }
+
+ if ( hr == S_OK ) {
+
+ //
+ // Initialize the INetCfg object.
+ //
+
+ hr = pnc->Initialize( NULL );
+
+ if ( hr == S_OK ) {
+ *ppnc = pnc;
+ pnc->AddRef();
+ }
+ else {
+
+ //
+ // Initialize failed, if obtained lock, release it
+ //
+
+ if ( pncLock ) {
+ pncLock->ReleaseWriteLock();
+ }
+ }
+ }
+
+ ReleaseRef( pncLock );
+ ReleaseRef( pnc );
+ }
+
+ //
+ // In case of error, uninitialize COM.
+ //
+
+ if ( hr != S_OK ) {
+ CoUninitialize();
+ }
+ }
+
+ return hr;
+}
+
+//
+// Function: HrReleaseINetCfg
+//
+// Purpose: Get a reference to INetCfg.
+//
+// Arguments:
+// pnc [in] Reference to INetCfg to release.
+// fHasWriteLock [in] If TRUE, reference was held with write lock.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrReleaseINetCfg (IN INetCfg* pnc,
+ IN BOOL fHasWriteLock)
+{
+ INetCfgLock *pncLock = NULL;
+ HRESULT hr = S_OK;
+
+ //
+ // Uninitialize INetCfg
+ //
+
+ hr = pnc->Uninitialize();
+
+ //
+ // If write lock is present, unlock it
+ //
+
+ if ( hr == S_OK && fHasWriteLock ) {
+
+ //
+ // Get the locking reference
+ //
+
+ hr = pnc->QueryInterface( IID_INetCfgLock,
+ (LPVOID *)&pncLock);
+ if ( hr == S_OK ) {
+ hr = pncLock->ReleaseWriteLock();
+ ReleaseRef( pncLock );
+ }
+ }
+
+ ReleaseRef( pnc );
+
+ //
+ // Uninitialize COM.
+ //
+
+ CoUninitialize();
+
+ return hr;
+}
+
+//
+// Function: HrInstallNetComponent
+//
+// Purpose: Install a network component(protocols, clients and services)
+// given its INF file.
+//
+// Arguments:
+// pnc [in] Reference to INetCfg.
+// lpszComponentId [in] PnpID of the network component.
+// pguidClass [in] Class GUID of the network component.
+// lpszInfFullPath [in] INF file to install from.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrInstallNetComponent (IN INetCfg *pnc,
+ IN LPCWSTR lpszComponentId,
+ IN const GUID *pguidClass,
+ IN LPCWSTR lpszInfFullPath)
+{
+ DWORD dwError;
+ HRESULT hr = S_OK;
+ WCHAR* Drive = NULL;
+ WCHAR* Dir = NULL;
+ WCHAR* DirWithDrive = NULL;
+
+ do
+ {
+ //
+ // If full path to INF has been specified, the INF
+ // needs to be copied using Setup API to ensure that any other files
+ // that the primary INF copies will be correctly found by Setup API
+ //
+
+ if ( lpszInfFullPath ) {
+
+ //
+ // Allocate memory to hold the strings
+ //
+ Drive = (WCHAR*)CoTaskMemAlloc(_MAX_DRIVE * sizeof(WCHAR));
+ if (NULL == Drive)
+ {
+ hr = E_OUTOFMEMORY;
+ break;
+ }
+ ZeroMemory(Drive, _MAX_DRIVE * sizeof(WCHAR));
+
+ Dir = (WCHAR*)CoTaskMemAlloc(_MAX_DIR * sizeof(WCHAR));
+ if (NULL == Dir)
+ {
+ hr = E_OUTOFMEMORY;
+ break;
+ }
+ ZeroMemory(Dir, _MAX_DRIVE * sizeof(WCHAR));
+
+ DirWithDrive = (WCHAR*)CoTaskMemAlloc((_MAX_DRIVE + _MAX_DIR) * sizeof(WCHAR));
+ if (NULL == DirWithDrive)
+ {
+ hr = E_OUTOFMEMORY;
+ break;
+ }
+ ZeroMemory(DirWithDrive, (_MAX_DRIVE + _MAX_DIR) * sizeof(WCHAR));
+
+ //
+ // Get the path where the INF file is.
+ //
+
+ _wsplitpath_s ( lpszInfFullPath,
+ Drive,
+ _MAX_DRIVE,
+ Dir,
+ _MAX_DIR,
+ NULL,
+ 0,
+ NULL,
+ 0);
+
+ StringCchCopyW ( DirWithDrive,
+ _MAX_DRIVE + _MAX_DIR,
+ Drive );
+ StringCchCatW ( DirWithDrive,
+ _MAX_DRIVE + _MAX_DIR,
+ Dir );
+
+ //
+ // Copy the INF file and other files referenced in the INF file.
+ //
+
+ if ( !SetupCopyOEMInfW(lpszInfFullPath,
+ DirWithDrive, // Other files are in the
+ // same dir. as primary INF
+ SPOST_PATH, // First param is path to INF
+ 0, // Default copy style
+ NULL, // Name of the INF after
+ // it's copied to %windir%\inf
+ 0, // Max buf. size for the above
+ NULL, // Required size if non-null
+ NULL) ) { // Optionally get the filename
+ // part of Inf name after it is copied.
+ dwError = GetLastError();
+
+ hr = HRESULT_FROM_WIN32( dwError );
+ }
+ }
+
+ if ( S_OK == hr ) {
+
+ //
+ // Install the network component.
+ //
+
+ hr = HrInstallComponent( pnc,
+ lpszComponentId,
+ pguidClass );
+ if ( hr == S_OK ) {
+
+ //
+ // On success, apply the changes
+ //
+
+ hr = pnc->Apply();
+ }
+ }
+
+ #pragma warning(disable:4127) /* Conditional expression is constant */
+ } while (false);
+
+ if (Drive != NULL)
+ {
+ CoTaskMemFree(Drive);
+ Drive = NULL;
+ }
+ if (Dir != NULL)
+ {
+ CoTaskMemFree(Dir);
+ Dir = NULL;
+ }
+ if (DirWithDrive != NULL)
+ {
+ CoTaskMemFree(DirWithDrive);
+ DirWithDrive = NULL;
+ }
+
+ return hr;
+}
+
+//
+// Function: HrInstallComponent
+//
+// Purpose: Install a network component(protocols, clients and services)
+// given its INF file.
+// Arguments:
+// pnc [in] Reference to INetCfg.
+// lpszComponentId [in] PnpID of the network component.
+// pguidClass [in] Class GUID of the network component.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrInstallComponent(IN INetCfg* pnc,
+ IN LPCWSTR szComponentId,
+ IN const GUID* pguidClass)
+{
+ INetCfgClassSetup *pncClassSetup = NULL;
+ INetCfgComponent *pncc = NULL;
+ OBO_TOKEN OboToken;
+ HRESULT hr = S_OK;
+
+ //
+ // OBO_TOKEN specifies on whose behalf this
+ // component is being installed.
+ // Set it to OBO_USER so that szComponentId will be installed
+ // on behalf of the user.
+ //
+
+ ZeroMemory( &OboToken,
+ sizeof(OboToken) );
+ OboToken.Type = OBO_USER;
+
+ //
+ // Get component's setup class reference.
+ //
+
+ hr = pnc->QueryNetCfgClass ( pguidClass,
+ IID_INetCfgClassSetup,
+ (void**)&pncClassSetup );
+ if ( hr == S_OK ) {
+
+ hr = pncClassSetup->Install( szComponentId,
+ &OboToken,
+ 0,
+ 0, // Upgrade from build number.
+ NULL, // Answerfile name
+ NULL, // Answerfile section name
+ &pncc ); // Reference after the component
+ if ( S_OK == hr ) { // is installed.
+
+ //
+ // we don't need to use pncc (INetCfgComponent), release it
+ //
+
+ ReleaseRef( pncc );
+ }
+
+ ReleaseRef( pncClassSetup );
+ }
+
+ return hr;
+}
+
+//
+// Function: HrUninstallNetComponent
+//
+// Purpose: Uninstall a network component(protocols, clients and services).
+//
+// Arguments:
+// pnc [in] Reference to INetCfg.
+// szComponentId [in] PnpID of the network component to uninstall.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrUninstallNetComponent(IN INetCfg* pnc,
+ IN LPCWSTR szComponentId)
+{
+ INetCfgComponent *pncc = NULL;
+ INetCfgClass *pncClass = NULL;
+ INetCfgClassSetup *pncClassSetup = NULL;
+ OBO_TOKEN OboToken;
+ GUID guidClass;
+ HRESULT hr = S_OK;
+
+ //
+ // OBO_TOKEN specifies on whose behalf this
+ // component is being installed.
+ // Set it to OBO_USER so that szComponentId will be installed
+ // on behalf of the user.
+ //
+
+ ZeroMemory( &OboToken,
+ sizeof(OboToken) );
+ OboToken.Type = OBO_USER;
+
+ //
+ // Get the component's reference.
+ //
+
+ hr = pnc->FindComponent( szComponentId,
+ &pncc );
+
+ if (S_OK == hr) {
+
+ //
+ // Get the component's class GUID.
+ //
+
+ hr = pncc->GetClassGuid( &guidClass );
+
+ if ( hr == S_OK ) {
+
+ //
+ // Get component's class reference.
+ //
+
+ hr = pnc->QueryNetCfgClass( &guidClass,
+ IID_INetCfgClass,
+ (void**)&pncClass );
+ if ( hr == S_OK ) {
+
+ //
+ // Get Setup reference.
+ //
+
+ hr = pncClass->QueryInterface( IID_INetCfgClassSetup,
+ (void**)&pncClassSetup );
+ if ( hr == S_OK ) {
+
+ hr = pncClassSetup->DeInstall( pncc,
+ &OboToken,
+ NULL);
+ if ( hr == S_OK ) {
+
+ //
+ // Apply the changes
+ //
+
+ hr = pnc->Apply();
+ }
+
+ ReleaseRef( pncClassSetup );
+ }
+
+ ReleaseRef( pncClass );
+ }
+ }
+
+ ReleaseRef( pncc );
+ }
+
+ return hr;
+}
+
+//
+// Function: HrGetComponentEnum
+//
+// Purpose: Get network component enumerator reference.
+//
+// Arguments:
+// pnc [in] Reference to INetCfg.
+// pguidClass [in] Class GUID of the network component.
+// ppencc [out] Enumerator reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrGetComponentEnum (INetCfg* pnc,
+ IN const GUID* pguidClass,
+ OUT IEnumNetCfgComponent **ppencc)
+{
+ INetCfgClass *pncclass;
+ HRESULT hr;
+
+ *ppencc = NULL;
+
+ //
+ // Get the class reference.
+ //
+
+ hr = pnc->QueryNetCfgClass( pguidClass,
+ IID_INetCfgClass,
+ (PVOID *)&pncclass );
+
+ if ( hr == S_OK ) {
+
+ //
+ // Get the enumerator reference.
+ //
+
+ hr = pncclass->EnumComponents( ppencc );
+
+ //
+ // We don't need the class reference any more.
+ //
+
+ ReleaseRef( pncclass );
+ }
+
+ return hr;
+}
+
+//
+// Function: HrGetFirstComponent
+//
+// Purpose: Enumerates the first network component.
+//
+// Arguments:
+// pencc [in] Component enumerator reference.
+// ppncc [out] Network component reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrGetFirstComponent (IN IEnumNetCfgComponent* pencc,
+ OUT INetCfgComponent **ppncc)
+{
+ HRESULT hr;
+ ULONG ulCount;
+
+ *ppncc = NULL;
+
+ pencc->Reset();
+
+ hr = pencc->Next( 1,
+ ppncc,
+ &ulCount );
+ return hr;
+}
+
+//
+// Function: HrGetNextComponent
+//
+// Purpose: Enumerate the next network component.
+//
+// Arguments:
+// pencc [in] Component enumerator reference.
+// ppncc [out] Network component reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes: The function behaves just like HrGetFirstComponent if
+// it is called right after HrGetComponentEnum.
+//
+//
+
+HRESULT HrGetNextComponent (IN IEnumNetCfgComponent* pencc,
+ OUT INetCfgComponent **ppncc)
+{
+ HRESULT hr;
+ ULONG ulCount;
+
+ *ppncc = NULL;
+
+ hr = pencc->Next( 1,
+ ppncc,
+ &ulCount );
+ return hr;
+}
+
+//
+// Function: HrFindNetComponentByPnpId
+//
+// Purpose: Get network adapter identified by a particular pnp device instance id.
+//
+// Arguments:
+// pncc [in] Network component reference.
+// lpszPnpDevNodeId [in] pnp device instance id.
+// ppncc [out] pointer to network adapter reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrFindNetComponentByPnpId (IN INetCfg *pnc,
+ IN _In_ LPWSTR lpszPnpDevNodeId,
+ OUT INetCfgComponent **ppncc)
+{
+ IEnumNetCfgComponent *pencc;
+ LPWSTR pszPnpId;
+ HRESULT hr;
+ BOOL fFound;
+
+ hr = HrGetComponentEnum( pnc,
+ &GUID_DEVCLASS_NET,
+ &pencc );
+ if ( hr == S_OK ) {
+
+ hr = HrGetFirstComponent( pencc, ppncc );
+ fFound = FALSE;
+ while( hr == S_OK ) {
+ hr = (*ppncc)->GetPnpDevNodeId( &pszPnpId );
+ if ( hr == S_OK ) {
+ fFound = wcscmp( pszPnpId, lpszPnpDevNodeId ) == 0;
+ CoTaskMemFree( pszPnpId );
+ if ( fFound ) {
+ break;
+ }
+ }
+ else {
+ hr = S_OK;
+ }
+
+ ReleaseRef( *ppncc );
+ hr = HrGetNextComponent( pencc, ppncc );
+ }
+
+ ReleaseRef( pencc );
+ }
+
+ return hr;
+}
+
+//
+// Function: HrGetBindingPathEnum
+//
+// Purpose: Get network component's binding path enumerator reference.
+//
+// Arguments:
+// pncc [in] Network component reference.
+// dwBindingType [in] EBP_ABOVE or EBP_BELOW.
+// ppencbp [out] Enumerator reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrGetBindingPathEnum (IN INetCfgComponent *pncc,
+ IN DWORD dwBindingType,
+ OUT IEnumNetCfgBindingPath **ppencbp)
+{
+ INetCfgComponentBindings *pnccb = NULL;
+ HRESULT hr;
+
+ *ppencbp = NULL;
+
+ //
+ // Get component's binding.
+ //
+
+ hr = pncc->QueryInterface( IID_INetCfgComponentBindings,
+ (PVOID *)&pnccb );
+
+ if ( hr == S_OK ) {
+
+ //
+ // Get binding path enumerator reference.
+ //
+
+ hr = pnccb->EnumBindingPaths( dwBindingType,
+ ppencbp );
+
+ ReleaseRef( pnccb );
+ }
+
+ return hr;
+}
+
+//
+// Function: HrGetFirstBindingPath
+//
+// Purpose: Enumerates the first binding path.
+//
+// Arguments:
+// pencc [in] Binding path enumerator reference.
+// ppncc [out] Binding path reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrGetFirstBindingPath (IN IEnumNetCfgBindingPath *pencbp,
+ OUT INetCfgBindingPath **ppncbp)
+{
+ ULONG ulCount;
+ HRESULT hr;
+
+ *ppncbp = NULL;
+
+ pencbp->Reset();
+
+ hr = pencbp->Next( 1,
+ ppncbp,
+ &ulCount );
+
+ return hr;
+}
+
+//
+// Function: HrGetNextBindingPath
+//
+// Purpose: Enumerate the next binding path.
+//
+// Arguments:
+// pencbp [in] Binding path enumerator reference.
+// ppncbp [out] Binding path reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes: The function behaves just like HrGetFirstBindingPath if
+// it is called right after HrGetBindingPathEnum.
+//
+//
+
+HRESULT HrGetNextBindingPath (IN IEnumNetCfgBindingPath *pencbp,
+ OUT INetCfgBindingPath **ppncbp)
+{
+ ULONG ulCount;
+ HRESULT hr;
+
+ *ppncbp = NULL;
+
+ hr = pencbp->Next( 1,
+ ppncbp,
+ &ulCount );
+
+ return hr;
+}
+
+//
+// Function: HrGetBindingInterfaceEnum
+//
+// Purpose: Get binding interface enumerator reference.
+//
+// Arguments:
+// pncbp [in] Binding path reference.
+// ppencbp [out] Enumerator reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrGetBindingInterfaceEnum (IN INetCfgBindingPath *pncbp,
+ OUT IEnumNetCfgBindingInterface **ppencbi)
+{
+ HRESULT hr;
+
+ *ppencbi = NULL;
+
+ hr = pncbp->EnumBindingInterfaces( ppencbi );
+
+ return hr;
+}
+
+//
+// Function: HrGetFirstBindingInterface
+//
+// Purpose: Enumerates the first binding interface.
+//
+// Arguments:
+// pencbi [in] Binding interface enumerator reference.
+// ppncbi [out] Binding interface reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes:
+//
+
+HRESULT HrGetFirstBindingInterface (IN IEnumNetCfgBindingInterface *pencbi,
+ OUT INetCfgBindingInterface **ppncbi)
+{
+ ULONG ulCount;
+ HRESULT hr;
+
+ *ppncbi = NULL;
+
+ pencbi->Reset();
+
+ hr = pencbi->Next( 1,
+ ppncbi,
+ &ulCount );
+
+ return hr;
+}
+
+//
+// Function: HrGetNextBindingInterface
+//
+// Purpose: Enumerate the next binding interface.
+//
+// Arguments:
+// pencbi [in] Binding interface enumerator reference.
+// ppncbi [out] Binding interface reference.
+//
+// Returns: S_OK on success, otherwise an error code.
+//
+// Notes: The function behaves just like HrGetFirstBindingInterface if
+// it is called right after HrGetBindingInterfaceEnum.
+//
+//
+
+HRESULT HrGetNextBindingInterface (IN IEnumNetCfgBindingInterface *pencbi,
+ OUT INetCfgBindingInterface **ppncbi)
+{
+ ULONG ulCount;
+ HRESULT hr;
+
+ *ppncbi = NULL;
+
+ hr = pencbi->Next( 1,
+ ppncbi,
+ &ulCount );
+
+ return hr;
+}
+
+//
+// Function: ReleaseRef
+//
+// Purpose: Release reference.
+//
+// Arguments:
+// punk [in] IUnknown reference to release.
+//
+// Returns: Reference count.
+//
+// Notes:
+//
+
+VOID ReleaseRef (IN IUnknown* punk)
+{
+ if ( punk ) {
+ punk->Release();
+ }
+
+ return;
+}
+