windows-nt/Source/XPSP1/NT/net/config/samples/bindview/netcfgapi.cpp
2020-09-26 16:20:57 +08:00

764 lines
18 KiB
C++

//+---------------------------------------------------------------------------
//
// 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 sucess, otherwise an error code.
//
// Notes:
//
HRESULT HrGetINetCfg (IN BOOL fGetWriteLock,
IN LPCWSTR lpszAppName,
OUT INetCfg** ppnc,
OUT 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 sucess, 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 sucess, 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[_MAX_DRIVE];
WCHAR Dir[_MAX_DIR];
WCHAR DirWithDrive[_MAX_DRIVE+_MAX_DIR];
//
// 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 ) {
//
// Get the path where the INF file is.
//
_wsplitpath( lpszInfFullPath, Drive, Dir, NULL, NULL );
wcscpy( DirWithDrive, Drive );
wcscat( DirWithDrive, 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();
}
}
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 sucess, 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 sucess, 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 sucess, 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 sucess, 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 sucess, 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: 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 sucess, 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 sucess, 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 sucess, 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 sucess, 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 sucess, 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 sucess, 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;
}