|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2001.
//
// File: C O M P O N E N T . C P P
//
// Contents: Functions to illustrate
// o How to enumerate network components.
// o How to install protocols, clients and services.
// o How to uninstall protocols, clients and services.
// o How to bind/unbind network components.
//
// Notes:
//
// Author: Alok Sinha 15-May-01
//
//----------------------------------------------------------------------------
#include "bindview.h"
//
// Function: HandleComponentOperation
//
// Purpose: Do component specific functions.
//
// Arguments:
// hwndOwner [in] Owner window.
// ulSelection [in] Option selected.
// hItem [in] Item selected.
// lParam [in] lParam of the item.
//
// Returns: None.
//
// Notes:
//
VOID HandleComponentOperation (HWND hwndOwner, ULONG ulSelection, HTREEITEM hItem, LPARAM lParam) { switch( ulSelection ) {
case IDI_BIND_TO: case IDI_UNBIND_FROM:
//
// Bind/unbind components.
//
BindUnbindComponents( hwndOwner, hItem, (LPWSTR)lParam, ulSelection == IDI_BIND_TO ); }
return; }
//
// Function: BindUnbindComponents
//
// Purpose: Bind/unbind a network component.
//
// Arguments:
// hwndOwner [in] Owner window.
// hItem [in] Item handle of the network component.
// lpszInfId [in] PnpID of the network component.
// fBindTo [in] if TRUE, bind, otherwise unbind.
//
// Returns: None.
//
// Notes:
//
VOID BindUnbindComponents( HWND hwndOwner, HTREEITEM hItem, LPWSTR lpszInfId, BOOL fBindTo) { BIND_UNBIND_INFO BindUnbind;
BindUnbind.lpszInfId = lpszInfId; BindUnbind.fBindTo = fBindTo;
DialogBoxParam( hInstance, MAKEINTRESOURCE(IDD_BIND_UNBIND), hwndOwner, BindComponentDlg, (LPARAM)&BindUnbind );
return; }
//
// Function: InstallComponent
//
// Purpose: Install a network component.
//
// Arguments:
// hwndDlg [in] Owner window.
// pguidClass [in] Class GUID of type of network component to install.
//
// Returns: S_OK on success, otherwise and error code.
//
// Notes:
//
HRESULT InstallComponent (HWND hwndDlg, const GUID *pguidClass) { INetCfg *pnc; INetCfgClass *pncClass; INetCfgClassSetup *pncClassSetup; LPWSTR lpszApp; OBO_TOKEN obo; HRESULT hr;
//
// Get INetCfg reference.
//
hr = HrGetINetCfg( TRUE, APP_NAME, &pnc, &lpszApp );
if ( hr == S_OK ) {
//
// Get network component's class reference.
//
hr = pnc->QueryNetCfgClass( pguidClass, IID_INetCfgClass, (PVOID *)&pncClass );
if ( hr == S_OK ) {
//
// Get Setup class reference.
//
hr = pncClass->QueryInterface( IID_INetCfgClassSetup, (LPVOID *)&pncClassSetup );
if ( hr == S_OK ) {
ZeroMemory( &obo, sizeof(OBO_TOKEN) );
obo.Type = OBO_USER;
//
// Let the network class installer prompt the user to select
// a network component to install.
//
hr = pncClassSetup->SelectAndInstall( hwndDlg, &obo, NULL );
if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) {
hr = pnc->Apply();
if ( (hr != S_OK) && (hr != NETCFG_S_REBOOT) ) {
ErrMsg( hr, L"Couldn't apply the changes after" L" installing the network component." ); }
} else { if ( hr != HRESULT_FROM_WIN32(ERROR_CANCELLED) ) { ErrMsg( hr, L"Couldn't install the network component." ); } }
ReleaseRef( pncClassSetup ); } else { ErrMsg( hr, L"Couldn't get an interface to setup class." ); }
ReleaseRef( pncClass ); } else { ErrMsg( hr, L"Couldn't get a pointer to class interface." ); }
HrReleaseINetCfg( pnc, TRUE ); } else { if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) { ErrMsg( hr, L"%s currently holds the lock, try later.", lpszApp );
CoTaskMemFree( lpszApp ); } else { ErrMsg( hr, L"Couldn't the get notify object interface." ); } } return hr; }
//
// Function: InstallSpecifiedComponent
//
// Purpose: Install a network component from an INF file.
//
// Arguments:
// lpszInfFile [in] INF file.
// lpszPnpID [in] PnpID of the network component to install.
// pguidClass [in] Class GUID of the network component.
//
// Returns: None.
//
// Notes:
//
HRESULT InstallSpecifiedComponent (LPWSTR lpszInfFile, LPWSTR lpszPnpID, const GUID *pguidClass) { INetCfg *pnc; LPWSTR lpszApp; HRESULT hr;
hr = HrGetINetCfg( TRUE, APP_NAME, &pnc, &lpszApp );
if ( hr == S_OK ) {
//
// Install the network component.
//
hr = HrInstallNetComponent( pnc, lpszPnpID, pguidClass, lpszInfFile ); if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) {
hr = pnc->Apply(); } else { if ( hr != HRESULT_FROM_WIN32(ERROR_CANCELLED) ) { ErrMsg( hr, L"Couldn't install the network component." ); } }
HrReleaseINetCfg( pnc, TRUE ); } else { if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) { ErrMsg( hr, L"%s currently holds the lock, try later.", lpszApp );
CoTaskMemFree( lpszApp ); } else { ErrMsg( hr, L"Couldn't the get notify object interface." ); } }
return hr; }
//
// Function: ListCompToBindUnbind
//
// Purpose: List all the components that are bound or bindable.
//
// Arguments:
// lpszInfId [in] PnpID of the network component.
// uiType [in] Type of network component.
// hwndTree [in] Tree handle in which to list.
// fBound [in] if TRUE, list components that are bound.
//
// Returns: Number of components listed.
//
// Notes:
//
DWORD ListCompToBindUnbind (LPWSTR lpszInfId, UINT uiType, HWND hwndTree, BOOL fBound) { INetCfg *pnc; INetCfgComponent *pncc; IEnumNetCfgComponent *pencc; INetCfgComponentBindings *pnccb; INetCfgComponent *pnccToBindUnbind; LPWSTR lpszApp; DWORD dwCount; HRESULT hr;
dwCount = 0; hr = HrGetINetCfg( TRUE, APP_NAME, &pnc, &lpszApp );
if ( hr == S_OK ) {
//
// Get a reference to the network component selected.
//
hr = pnc->FindComponent( lpszInfId, &pncc );
if ( hr == S_OK ) {
//
// Get Component Enumerator Interface.
//
hr = HrGetComponentEnum( pnc, pguidNetClass[uiType], &pencc ); if ( hr == S_OK ) {
hr = pncc->QueryInterface( IID_INetCfgComponentBindings, (PVOID *)&pnccb ); if ( hr == S_OK ) {
hr = HrGetFirstComponent( pencc, &pnccToBindUnbind );
while( hr == S_OK ) {
hr = pnccb->IsBoundTo( pnccToBindUnbind );
//
// fBound = TRUE ==> Want to list components that are
// bound.
//
if ( fBound ) { if ( hr == S_OK ) { AddToTree( hwndTree, TVI_ROOT, pnccToBindUnbind ); dwCount++; } } else {
//
// fBound = FALSE ==> Want to list components that
// are not bound but are bindable.
//
if ( hr == S_FALSE ) {
hr = pnccb->IsBindableTo( pnccToBindUnbind );
if ( hr == S_OK ) { AddToTree( hwndTree, TVI_ROOT, pnccToBindUnbind ); dwCount++; } } }
ReleaseRef( pnccToBindUnbind );
hr = HrGetNextComponent( pencc, &pnccToBindUnbind ); }
ReleaseRef( pnccb ); } else { ErrMsg( hr, L"Couldn't get the component binding interface " L"of %s.", lpszInfId ); }
ReleaseRef( pencc ); } else { ErrMsg( hr, L"Couldn't get the network component enumerator " L"interface." ); } ReleaseRef( pncc );
} else { ErrMsg( hr, L"Couldn't get an interface pointer to %s.", lpszInfId ); }
HrReleaseINetCfg( pnc, TRUE ); } else { if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) { ErrMsg( hr, L"%s currently holds the lock, try later.", lpszApp );
CoTaskMemFree( lpszApp ); } else { ErrMsg( hr, L"Couldn't get the notify object interface." ); } }
return dwCount; }
//
// Function: BindUnbind
//
// Purpose: Bind/unbind a network component.
//
// Arguments:
// lpszInfId [in] PnpID of the network component to bind/unbind.
// hwndTree [in] Tree handle.
// fBind [in] if TRUE, bind, otherwise unbind.
//
// Returns: TRUE on success.
//
// Notes:
//
BOOL BindUnbind (LPWSTR lpszInfId, HWND hwndTree, BOOL fBind) { INetCfg *pnc; INetCfgComponent *pncc; INetCfgComponentBindings *pnccb; INetCfgComponent *pnccToBindUnbind; LPWSTR lpszApp; HTREEITEM hTreeItem; TVITEMW tvItem; HRESULT hr; BOOL fChange;
hr = HrGetINetCfg( TRUE, APP_NAME, &pnc, &lpszApp );
fChange = FALSE;
if ( hr == S_OK ) {
//
// Get a reference to the network component.
//
hr = pnc->FindComponent( lpszInfId, &pncc ); if ( hr == S_OK ) {
//
// Get a reference to the component's binding.
//
hr = pncc->QueryInterface( IID_INetCfgComponentBindings, (PVOID *)&pnccb ); if ( hr == S_OK ) {
//
// Start with the root item.
//
hTreeItem = TreeView_GetRoot( hwndTree );
//
// Bind/unbind the network component with every component
// that is checked.
//
while ( hTreeItem ) {
ZeroMemory( &tvItem, sizeof(TVITEMW) );
tvItem.hItem = hTreeItem; tvItem.mask = TVIF_PARAM | TVIF_STATE; tvItem.stateMask = TVIS_STATEIMAGEMASK;
if ( TreeView_GetItem(hwndTree, &tvItem) ) {
//
// Is the network component selected?
//
if ( (tvItem.state >> 12) == 2 ) {
//
// Get a reference to the selected component.
//
hr = pnc->FindComponent( (LPWSTR)tvItem.lParam, &pnccToBindUnbind ); if ( hr == S_OK ) {
if ( fBind ) {
//
// Bind the component to the selected component.
//
hr = pnccb->BindTo( pnccToBindUnbind );
if ( !fChange ) { fChange = hr == S_OK; }
if ( hr != S_OK ) { ErrMsg( hr, L"%s couldn't be bound to %s.", lpszInfId, (LPWSTR)tvItem.lParam ); } } else { //
// Unbind the component from the selected component.
//
hr = pnccb->UnbindFrom( pnccToBindUnbind );
if ( !fChange ) { fChange = hr == S_OK; }
if ( hr != S_OK ) { ErrMsg( hr, L"%s couldn't be unbound from %s.", lpszInfId, (LPWSTR)tvItem.lParam ); } }
ReleaseRef( pnccToBindUnbind ); } else { ErrMsg( hr, L"Couldn't get an interface pointer to %s. " L"%s will not be bound to it.", (LPWSTR)tvItem.lParam, lpszInfId ); } } }
//
// Get the next item.
//
hTreeItem = TreeView_GetNextSibling( hwndTree, hTreeItem ); }
ReleaseRef( pnccb ); } else { ErrMsg( hr, L"Couldn't get a binding interface of %s.", lpszInfId ); }
ReleaseRef( pncc ); } else { ErrMsg( hr, L"Couldn't get an interface pointer to %s.", lpszInfId ); }
//
// If one or more network components have been bound/unbound,
// apply the changes.
//
if ( fChange ) { hr = pnc->Apply();
fChange = hr == S_OK; }
HrReleaseINetCfg( pnc, TRUE ); } else { if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) { ErrMsg( hr, L"%s currently holds the lock, try later.", lpszApp );
CoTaskMemFree( lpszApp ); } else { ErrMsg( hr, L"Couldn't get the notify object interface." ); } }
return fChange; }
//
// Function: ListInstalledComponents
//
// Purpose: List installed network components of specific class.
//
// Arguments:
// hwndTree [in] Tree handle in which to list.
// pguidClass [in] Class GUID of the network compoent class.
//
// Returns: None.
//
// Notes:
//
VOID ListInstalledComponents (HWND hwndTree, const GUID *pguidClass) { INetCfg *pnc; IEnumNetCfgComponent *pencc; INetCfgComponent *pncc; LPWSTR lpszApp; HTREEITEM hTreeItem; HRESULT hr;
hr = HrGetINetCfg( FALSE, APP_NAME, &pnc, &lpszApp );
if ( hr == S_OK ) {
//
// Get Component Enumerator Interface.
//
hr = HrGetComponentEnum( pnc, pguidClass, &pencc ); if ( hr == S_OK ) {
hr = HrGetFirstComponent( pencc, &pncc );
while( hr == S_OK ) {
//
// Add an item to the tree for the network component.
//
hTreeItem = AddToTree( hwndTree, TVI_ROOT, pncc );
ReleaseRef( pncc );
hr = HrGetNextComponent( pencc, &pncc ); }
ReleaseRef( pencc ); } else { ErrMsg( hr, L"Failed to get the network component enumerator." ); }
HrReleaseINetCfg( pnc, FALSE ); } else { if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) { ErrMsg( hr, L"%s currently holds the lock, try later.", lpszApp );
CoTaskMemFree( lpszApp ); } else { ErrMsg( hr, L"Couldn't get the notify object interface." ); } }
return; }
//
// Function: UninstallComponent
//
// Purpose: Uninstall a network component.
//
// Arguments:
// lpszInfId [in] PnpID of the network component to uninstall.
//
// Returns: S_OK on success, otherwise an error code.
//
// Notes:
//
HRESULT UninstallComponent (LPWSTR lpszInfId) { INetCfg *pnc; INetCfgComponent *pncc; INetCfgClass *pncClass; INetCfgClassSetup *pncClassSetup; LPWSTR lpszApp; GUID guidClass; OBO_TOKEN obo; HRESULT hr;
hr = HrGetINetCfg( TRUE, APP_NAME, &pnc, &lpszApp );
if ( hr == S_OK ) {
//
// Get a reference to the network component to uninstall.
//
hr = pnc->FindComponent( lpszInfId, &pncc );
if ( hr == S_OK ) {
//
// Get the class GUID.
//
hr = pncc->GetClassGuid( &guidClass );
if ( hr == S_OK ) {
//
// Get a reference to component's class.
//
hr = pnc->QueryNetCfgClass( &guidClass, IID_INetCfgClass, (PVOID *)&pncClass ); if ( hr == S_OK ) {
//
// Get the setup interface.
//
hr = pncClass->QueryInterface( IID_INetCfgClassSetup, (LPVOID *)&pncClassSetup );
if ( hr == S_OK ) {
//
// Uninstall the component.
//
ZeroMemory( &obo, sizeof(OBO_TOKEN) );
obo.Type = OBO_USER;
hr = pncClassSetup->DeInstall( pncc, &obo, NULL ); if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) {
hr = pnc->Apply();
if ( (hr != S_OK) && (hr != NETCFG_S_REBOOT) ) { ErrMsg( hr, L"Couldn't apply the changes after" L" uninstalling %s.", lpszInfId ); } } else { ErrMsg( hr, L"Failed to uninstall %s.", lpszInfId ); }
ReleaseRef( pncClassSetup ); } else { ErrMsg( hr, L"Couldn't get an interface to setup class." ); }
ReleaseRef( pncClass ); } else { ErrMsg( hr, L"Couldn't get a pointer to class interface " L"of %s.", lpszInfId ); } } else { ErrMsg( hr, L"Couldn't get the class guid of %s.", lpszInfId ); }
ReleaseRef( pncc ); } else { ErrMsg( hr, L"Couldn't get an interface pointer to %s.", lpszInfId ); }
HrReleaseINetCfg( pnc, TRUE ); } else { if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) { ErrMsg( hr, L"%s currently holds the lock, try later.", lpszApp );
CoTaskMemFree( lpszApp ); } else { ErrMsg( hr, L"Couldn't get the notify object interface." ); } }
return hr; }
|