1923 lines
51 KiB
C++
1923 lines
51 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (c) 1997-1999 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// File Name:
|
|
// netreg.cpp
|
|
//
|
|
// Description:
|
|
// This file contains the calls to the Network Component Object interfaces
|
|
// to find out what network clients, services and protocols are installed
|
|
// on the current machine and what their settings are.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#include "netreg.h"
|
|
|
|
//
|
|
// Constants
|
|
//
|
|
|
|
const static INT MAX_GUID_STRING = 40;
|
|
const static INT MAX_NUM_NET_COMPONENTS = 128;
|
|
const static INT BUFFER_SIZE = 4096;
|
|
|
|
//
|
|
// Registry fields used to read settings for network components
|
|
//
|
|
|
|
const static TCHAR REGVAL_DOMAIN[] = _T("Domain");
|
|
const static TCHAR REGVAL_INTERFACES[] = _T("Interfaces");
|
|
const static TCHAR REGVAL_ENABLE_DHCP[] = _T("EnableDHCP");
|
|
const static TCHAR REGVAL_IPADDRESS[] = _T("IPAddress");
|
|
const static TCHAR REGVAL_SUBNETMASK[] = _T("SubnetMask");
|
|
const static TCHAR REGVAL_DEFAULTGATEWAY[] = _T("DefaultGateway");
|
|
const static TCHAR REGVAL_NAMESERVER[] = _T("NameServer");
|
|
const static TCHAR REGVAL_WINS[] = _T("SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters\\Interfaces\\Tcpip_");
|
|
const static TCHAR REGVAL_NAMESERVERLIST[] = _T("NameServerList");
|
|
|
|
const static TCHAR REGKEY_MSCLIENT_LOCATION[] = _T("SOFTWARE\\Microsoft\\Rpc\\NameService");
|
|
const static TCHAR REGVAL_NAME_SERVICE_PROVIDER[] = _T("Protocol");
|
|
const static TCHAR REGVAL_NETWORK_ADDRESS[] = _T("NetworkAddress");
|
|
|
|
const static TCHAR REGVAL_ADAPTERS[] = _T("Adapters");
|
|
const static TCHAR REGVAL_PKT_TYPE[] = _T("PktType");
|
|
const static TCHAR REGVAL_NETWORK_NUMBER[] = _T("NetworkNumber");
|
|
const static TCHAR REGVAL_VIRTUAL_NETWORK_NUMBER[] = _T("VirtualNetworkNumber");
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ReadNetworkRegistrySettings
|
|
//
|
|
// Purpose: In general, this function reads in all the necessary networking
|
|
// settings and sets the internal variables appropriately. This includes
|
|
// determining how many network adapters there are, what
|
|
// client/services/protocols are installed and loading their individual
|
|
// settings.
|
|
//
|
|
// When reads from the registry fail, it just moves on to try and get the
|
|
// next setting. The failed one is just left with its default. In this
|
|
// way if just one registry entry is broken all the other data will be
|
|
// obtained rather than just quiting the function.
|
|
//
|
|
// Arguments: VOID
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
EXTERN_C HRESULT
|
|
ReadNetworkRegistrySettings( VOID )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
INetCfg* pNetCfg = NULL;
|
|
|
|
//
|
|
// Always force a Custom net setting if they are reading from the registry
|
|
// because I don't want to write the code to see if their current net
|
|
// configuration is a typical one (when 99.9% of the time it won't be)
|
|
//
|
|
|
|
NetSettings.iNetworkingMethod = CUSTOM_NETWORKING;
|
|
|
|
hr = InitializeInterfaces( &pNetCfg );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( E_FAIL );
|
|
}
|
|
|
|
hr = GetNetworkAdapterSettings( pNetCfg );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
ReleaseInterfaces( pNetCfg );
|
|
|
|
return( E_FAIL );
|
|
|
|
}
|
|
|
|
//
|
|
// Purposely not catching return values here. Call each one to try and
|
|
// grab as many parameters as we can. If we hit an error just move on
|
|
// and try to grab the next value.
|
|
//
|
|
|
|
GetClientsInstalled( pNetCfg );
|
|
|
|
GetServicesInstalled( pNetCfg );
|
|
|
|
GetProtocolsInstalled( pNetCfg );
|
|
|
|
ReleaseInterfaces( pNetCfg );
|
|
|
|
GetDomainOrWorkgroup();
|
|
|
|
return( S_OK );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetNetworkAdapterSettings
|
|
//
|
|
// Purpose: Determines how many network cards are installed and gets there
|
|
// PnP Ids. It then stores these in the appropriate global variables.
|
|
//
|
|
// Arguments: INetCfg *pNetCfg - pointer to a NetCfg object that is already
|
|
// created and initialized
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
GetNetworkAdapterSettings( INetCfg *pNetCfg )
|
|
{
|
|
|
|
UINT i;
|
|
INetCfgComponent* arrayComp[MAX_NUM_NET_COMPONENTS];
|
|
IEnumNetCfgComponent* pEnum = NULL;
|
|
INetCfgClass* pNetCfgClass = NULL;
|
|
INetCfgComponent* pNetCfgComp = NULL;
|
|
NETWORK_ADAPTER_NODE* pPreviousNode = NULL;
|
|
NETWORK_ADAPTER_NODE* pCurrentNode = NULL;
|
|
HRESULT hr = S_OK;
|
|
DWORD dwCharacteristics = 0;
|
|
ULONG iCount = 0;
|
|
|
|
hr = InitializeComInterface( &GUID_DEVCLASS_NET,
|
|
pNetCfg,
|
|
pNetCfgClass,
|
|
pEnum,
|
|
arrayComp,
|
|
&iCount );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( hr );
|
|
}
|
|
|
|
//
|
|
// delete the entire list of Network Adapters so we can start fresh
|
|
//
|
|
|
|
DeleteList( NetSettings.NetworkAdapterHead );
|
|
|
|
NetSettings.NetworkAdapterHead = NULL;
|
|
|
|
NetSettings.iNumberOfNetworkCards = 0;
|
|
|
|
AssertMsg( iCount <= MAX_NUM_NET_COMPONENTS,
|
|
"Too many network components to work with" );
|
|
|
|
for( i = 0; i < iCount; i++ )
|
|
{
|
|
|
|
pNetCfgComp = arrayComp[i];
|
|
|
|
hr = ChkInterfacePointer( pNetCfgComp, IID_INetCfgComponent );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
|
|
return( hr );
|
|
|
|
}
|
|
|
|
hr = pNetCfgComp->GetCharacteristics( &dwCharacteristics );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
|
|
return( hr );
|
|
|
|
}
|
|
|
|
//
|
|
// If this is a physical adapter
|
|
//
|
|
if( dwCharacteristics & NCF_PHYSICAL )
|
|
{
|
|
|
|
NetSettings.iNumberOfNetworkCards++;
|
|
|
|
hr = SetupAdapter( &pCurrentNode,
|
|
pNetCfgComp );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
|
|
return( hr );
|
|
|
|
}
|
|
|
|
//
|
|
// Adjust pointers to maintain the doubly linked-list
|
|
//
|
|
pCurrentNode->previous = pPreviousNode;
|
|
|
|
if( pPreviousNode != NULL )
|
|
{
|
|
|
|
pPreviousNode->next = pCurrentNode;
|
|
|
|
}
|
|
|
|
pPreviousNode = pCurrentNode;
|
|
|
|
}
|
|
|
|
if( pNetCfgComp )
|
|
{
|
|
|
|
pNetCfgComp->Release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// if there is a network card in this machine, set the current network card
|
|
// to be the first one, else zero out the values
|
|
//
|
|
|
|
if( NetSettings.iNumberOfNetworkCards > 0 )
|
|
{
|
|
|
|
NetSettings.iCurrentNetworkCard = 1;
|
|
NetSettings.pCurrentAdapter = NetSettings.NetworkAdapterHead;
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
NetSettings.iCurrentNetworkCard = 0;
|
|
NetSettings.NetworkAdapterHead = NULL;
|
|
NetSettings.pCurrentAdapter = NULL;
|
|
|
|
}
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
|
|
return( S_OK );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetClientsInstalled
|
|
//
|
|
// Purpose: For each client, it finds out if it is installed on the current
|
|
// system and if it is then it reads its settings from the registry
|
|
//
|
|
// Arguments: INetCfg *pNetCfg - pointer to a NetCfg object that is already
|
|
// created and initialized
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
GetClientsInstalled( INetCfg *pNetCfg )
|
|
{
|
|
|
|
INetCfgComponent* arrayComp[MAX_NUM_NET_COMPONENTS];
|
|
IEnumNetCfgComponent* pEnum = NULL;
|
|
INetCfgClass* pNetCfgClass = NULL;
|
|
INetCfgComponent* pNetCfgComp = NULL;
|
|
|
|
HRESULT hr = S_OK;
|
|
ULONG iCount = 0;
|
|
LPWSTR pszwDisplayName = NULL;
|
|
HKEY hKey;
|
|
UINT i;
|
|
|
|
NETWORK_COMPONENT* pMsClientComponent = NULL;
|
|
NETWORK_COMPONENT* pNetwareComponent = NULL;
|
|
|
|
//
|
|
// Initialize each of the pointers to point into its proper place in the
|
|
// global network component list
|
|
//
|
|
pMsClientComponent = FindNode( MS_CLIENT_POSITION );
|
|
pNetwareComponent = FindNode( NETWARE_CLIENT_POSITION );
|
|
|
|
hr = InitializeComInterface( &GUID_DEVCLASS_NETCLIENT,
|
|
pNetCfg,
|
|
pNetCfgClass,
|
|
pEnum,
|
|
arrayComp,
|
|
&iCount );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( hr );
|
|
}
|
|
|
|
for( i = 0; i < iCount; i++ )
|
|
{
|
|
|
|
pNetCfgComp = arrayComp[i];
|
|
|
|
hr = ChkInterfacePointer( pNetCfgComp,
|
|
IID_INetCfgComponent );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
return( hr );
|
|
|
|
}
|
|
|
|
hr = pNetCfgComp->GetDisplayName( &pszwDisplayName );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
return( hr );
|
|
|
|
}
|
|
|
|
if( lstrcmpi( pMsClientComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// set the component to Installed
|
|
//
|
|
pMsClientComponent->bInstalled = TRUE;
|
|
|
|
hr = pNetCfgComp->OpenParamKey( &hKey );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
return( hr );
|
|
|
|
}
|
|
|
|
//
|
|
// grab Ms Client settings from the registry
|
|
//
|
|
ReadMsClientSettingsFromRegistry( &hKey );
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
}
|
|
else if( lstrcmpi( pNetwareComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// set the component to Installed
|
|
//
|
|
pNetwareComponent->bInstalled = TRUE;
|
|
|
|
hr = pNetCfgComp->OpenParamKey( &hKey );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
return( hr );
|
|
|
|
}
|
|
|
|
//
|
|
// grab Netware settings from the registry
|
|
//
|
|
|
|
ReadNetwareSettingsFromRegistry( &hKey );
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
}
|
|
|
|
CoTaskMemFree( pszwDisplayName );
|
|
|
|
if( pNetCfgComp ) {
|
|
|
|
pNetCfgComp->Release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
|
|
return( S_OK );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetServicesInstalled
|
|
//
|
|
// Purpose: For each service, it finds out if it is installed on the current
|
|
// system and if it is then it sets its component to Installed = TRUE
|
|
//
|
|
// Arguments: INetCfg *pNetCfg - pointer to a NetCfg object that is already
|
|
// created and initialized
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
GetServicesInstalled( INetCfg *pNetCfg )
|
|
{
|
|
|
|
INetCfgComponent* arrayComp[MAX_NUM_NET_COMPONENTS];
|
|
IEnumNetCfgComponent* pEnum = NULL;
|
|
INetCfgClass* pNetCfgClass = NULL;
|
|
INetCfgComponent* pNetCfgComp = NULL;
|
|
LPWSTR pszwDisplayName = NULL;
|
|
HRESULT hr = S_OK;
|
|
ULONG iCount = 0;
|
|
UINT i;
|
|
|
|
NETWORK_COMPONENT* pFilePrintSharingComponent = NULL;
|
|
NETWORK_COMPONENT* pPacketSchedulingComponent = NULL;
|
|
|
|
//
|
|
// Initialize each of the pointers to point into its proper place in the
|
|
// global network component list
|
|
//
|
|
pFilePrintSharingComponent = FindNode( FILE_AND_PRINT_SHARING_POSITION );
|
|
pPacketSchedulingComponent = FindNode( PACKET_SCHEDULING_POSITION );
|
|
|
|
hr = InitializeComInterface( &GUID_DEVCLASS_NETCLIENT,
|
|
pNetCfg,
|
|
pNetCfgClass,
|
|
pEnum,
|
|
arrayComp,
|
|
&iCount );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( hr );
|
|
}
|
|
|
|
for( i = 0; i < iCount; i++ )
|
|
{
|
|
|
|
pNetCfgComp = arrayComp[i];
|
|
|
|
hr = ChkInterfacePointer( pNetCfgComp,
|
|
IID_INetCfgComponent );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
return( hr );
|
|
}
|
|
|
|
hr = pNetCfgComp->GetDisplayName( &pszwDisplayName );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
return( hr );
|
|
}
|
|
|
|
if( lstrcmpi( pFilePrintSharingComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// only have to set the component to Installed, no settings to read
|
|
//
|
|
pFilePrintSharingComponent->bInstalled = TRUE;
|
|
|
|
|
|
}
|
|
else if( lstrcmpi( pPacketSchedulingComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// only have to set the component to Installed, no settings to read
|
|
//
|
|
pPacketSchedulingComponent->bInstalled = TRUE;
|
|
|
|
}
|
|
|
|
CoTaskMemFree( pszwDisplayName );
|
|
|
|
if( pNetCfgComp ) {
|
|
|
|
pNetCfgComp->Release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
|
|
return( S_OK );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetProtocolsInstalled
|
|
//
|
|
// Purpose: For each protocol, it finds out if it is installed on the current
|
|
// system and if it is then it reads its settings from the registry
|
|
//
|
|
// Arguments: INetCfg *pNetCfg - pointer to a NetCfg object that is already
|
|
// created and initialized
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
GetProtocolsInstalled( INetCfg *pNetCfg )
|
|
{
|
|
|
|
INetCfgComponent* arrayComp[MAX_NUM_NET_COMPONENTS];
|
|
IEnumNetCfgComponent* pEnum = NULL;
|
|
INetCfgClass* pNetCfgClass = NULL;
|
|
INetCfgComponent* pNetCfgComp = NULL;
|
|
LPWSTR pszwDisplayName = NULL;
|
|
HKEY hKey = NULL;
|
|
HRESULT hr = S_OK;
|
|
ULONG iCount = 0;
|
|
UINT i;
|
|
|
|
NETWORK_COMPONENT* pTcpipComponent = NULL;
|
|
NETWORK_COMPONENT* pIpxComponent = NULL;
|
|
NETWORK_COMPONENT* pNetBeuiComponent = NULL;
|
|
NETWORK_COMPONENT* pDlcComponent = NULL;
|
|
NETWORK_COMPONENT* pNetworkMonitorComponent = NULL;
|
|
NETWORK_COMPONENT* pAppletalkComponent = NULL;
|
|
|
|
//
|
|
// Initialize each of the pointers to point into its proper place in the
|
|
// global network component list
|
|
//
|
|
pTcpipComponent = FindNode( TCPIP_POSITION );
|
|
pIpxComponent = FindNode( IPX_POSITION );
|
|
pNetBeuiComponent = FindNode( NETBEUI_POSITION );
|
|
pDlcComponent = FindNode( DLC_POSITION );
|
|
pNetworkMonitorComponent = FindNode( NETWORK_MONITOR_AGENT_POSITION );
|
|
pAppletalkComponent = FindNode( APPLETALK_POSITION );
|
|
|
|
hr = InitializeComInterface( &GUID_DEVCLASS_NETTRANS,
|
|
pNetCfg,
|
|
pNetCfgClass,
|
|
pEnum,
|
|
arrayComp,
|
|
&iCount );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( hr );
|
|
}
|
|
|
|
for( i = 0; i < iCount; i++ )
|
|
{
|
|
|
|
pNetCfgComp = arrayComp[i];
|
|
|
|
hr = ChkInterfacePointer( pNetCfgComp,
|
|
IID_INetCfgComponent );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
return( hr );
|
|
|
|
}
|
|
|
|
hr = pNetCfgComp->GetDisplayName( &pszwDisplayName );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
return( hr );
|
|
}
|
|
|
|
if( lstrcmpi( pTcpipComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// set the component to Installed
|
|
//
|
|
pTcpipComponent->bInstalled = TRUE;
|
|
|
|
hr = pNetCfgComp->OpenParamKey( &hKey );
|
|
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
|
|
//
|
|
// grab TCP/IP settings from the registry
|
|
//
|
|
ReadTcpipSettingsFromRegistry( &hKey );
|
|
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
}
|
|
else if( lstrcmpi( pIpxComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// set the component to Installed
|
|
//
|
|
pIpxComponent->bInstalled = TRUE;
|
|
|
|
hr = pNetCfgComp->OpenParamKey( &hKey );
|
|
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
|
|
// grab IPX settings from the registry
|
|
ReadIpxSettingsFromRegistry( &hKey );
|
|
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
}
|
|
else if( lstrcmpi( pNetBeuiComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// only have to set the component to Installed, no settings to read
|
|
//
|
|
pNetBeuiComponent->bInstalled = TRUE;
|
|
|
|
}
|
|
else if( lstrcmpi( pDlcComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// only have to set the component to Installed, no settings to read
|
|
//
|
|
pDlcComponent->bInstalled = TRUE;
|
|
|
|
}
|
|
else if( lstrcmpi( pNetworkMonitorComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// only have to set the component to Installed, no settings to read
|
|
//
|
|
pNetworkMonitorComponent->bInstalled = TRUE;
|
|
|
|
}
|
|
else if( lstrcmpi( pAppletalkComponent->StrComponentName, pszwDisplayName ) == 0 )
|
|
{
|
|
|
|
//
|
|
// set the component to Installed
|
|
//
|
|
pAppletalkComponent->bInstalled = TRUE;
|
|
|
|
hr = pNetCfgComp->OpenParamKey( &hKey );
|
|
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
|
|
// grab Appletalk settings from the registry
|
|
ReadAppletalkSettingsFromRegistry( &hKey );
|
|
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
}
|
|
|
|
CoTaskMemFree( pszwDisplayName );
|
|
|
|
if( pNetCfgComp ) {
|
|
|
|
pNetCfgComp->Release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UninitializeComInterface( pNetCfgClass,
|
|
pEnum );
|
|
|
|
return( S_OK );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetDomainOrWorkgroup
|
|
//
|
|
// Purpose: Find out if this machine is a member of a workgroup or domain and
|
|
// then fill the global structs with the proper name.
|
|
//
|
|
// Arguments: VOID
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
GetDomainOrWorkgroup( VOID )
|
|
{
|
|
|
|
BOOL bDomain = FALSE;
|
|
TCHAR szDomainOrWorkgroup[MAX_WORKGROUP_LENGTH + 1] = _T("");
|
|
|
|
//
|
|
// Get the domain/workgoup
|
|
//
|
|
|
|
if( LSA_SUCCESS( GetDomainMembershipInfo( &bDomain, szDomainOrWorkgroup ) ) )
|
|
{
|
|
|
|
if( bDomain )
|
|
{
|
|
lstrcpyn( NetSettings.DomainName, szDomainOrWorkgroup, AS(NetSettings.DomainName) );
|
|
|
|
NetSettings.bWorkgroup = FALSE;
|
|
}
|
|
else
|
|
{
|
|
lstrcpyn( NetSettings.WorkGroupName, szDomainOrWorkgroup, AS(NetSettings.WorkGroupName) );
|
|
|
|
NetSettings.bWorkgroup = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: SetupAdapter
|
|
//
|
|
// Purpose: Allocates and initializes a new Network adapter struct, then reads
|
|
// the adapter's PnP Id and it's GUID.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
// On failure, the caller of this function is responsible for calling
|
|
// UninitializeComInterface()
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
SetupAdapter( NETWORK_ADAPTER_NODE **ppCurrentNode,
|
|
INetCfgComponent *pNetCfgComp )
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
LPWSTR pszwPnPID = NULL;
|
|
|
|
*ppCurrentNode = (NETWORK_ADAPTER_NODE *)malloc( sizeof( NETWORK_ADAPTER_NODE ) );
|
|
if (*ppCurrentNode == NULL)
|
|
return (E_FAIL);
|
|
|
|
//
|
|
// Initialize all the Network namelists to 0s
|
|
//
|
|
|
|
ZeroOut( *ppCurrentNode );
|
|
|
|
//
|
|
// Set all network card settings to their default values
|
|
//
|
|
|
|
ResetNetworkAdapter( *ppCurrentNode );
|
|
|
|
if( NetSettings.iNumberOfNetworkCards == 1 )
|
|
{
|
|
NetSettings.NetworkAdapterHead = *ppCurrentNode;
|
|
}
|
|
|
|
//
|
|
// Get the Plug and Play Id
|
|
//
|
|
|
|
hr = pNetCfgComp->GetId( &pszwPnPID );
|
|
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
|
|
hr=StringCchCopy( (*ppCurrentNode)->szPlugAndPlayID, AS((*ppCurrentNode)->szPlugAndPlayID), pszwPnPID );
|
|
|
|
CoTaskMemFree( pszwPnPID );
|
|
|
|
}
|
|
|
|
//
|
|
// Get the Guid for this network adapter
|
|
//
|
|
|
|
hr = pNetCfgComp->GetInstanceGuid( &((*ppCurrentNode)->guid) );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
//
|
|
// this call failed so any call to the registry will fail since it
|
|
// needs this guid
|
|
//
|
|
|
|
return( hr );
|
|
|
|
}
|
|
|
|
return( S_OK );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ReadNetwareSettingsFromRegistry
|
|
//
|
|
// Purpose: Read in registry settings on Netware and fill the global structs
|
|
// with the appropriate values
|
|
//
|
|
// Arguments: HKEY *hKey
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
ReadNetwareSettingsFromRegistry( IN HKEY *hKey )
|
|
{
|
|
|
|
REGSAM SecurityAccess = KEY_QUERY_VALUE;
|
|
|
|
// ISSUE-2002/02/28-stelo- write this function
|
|
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ReadMsClientSettingsFromRegistry
|
|
//
|
|
// Purpose: Read in registry settings on MS Client and fill the global structs
|
|
// with the appropriate values
|
|
//
|
|
// Arguments: HKEY *hKey
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
ReadMsClientSettingsFromRegistry( IN HKEY *hKey )
|
|
{
|
|
|
|
HKEY hNameServiceKey = NULL;
|
|
REGSAM SecurityAccess = KEY_QUERY_VALUE;
|
|
DWORD dwSize = 0;
|
|
|
|
TCHAR szBuffer[BUFFER_SIZE];
|
|
|
|
// ISSUE-2002/02/28-stelo- I don't use the hKey passed in. For some reason, the Network
|
|
// component objects don't point to the section of the registry I need
|
|
// to read from. Is this a bug with Network Component Objects?
|
|
|
|
dwSize = sizeof( szBuffer );
|
|
|
|
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
REGKEY_MSCLIENT_LOCATION,
|
|
0,
|
|
SecurityAccess,
|
|
&hNameServiceKey ) != ERROR_SUCCESS )
|
|
{
|
|
|
|
//
|
|
// need this key to read in other MS Client values so bail if we
|
|
// can't get it
|
|
//
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
if( RegQueryValueEx( hNameServiceKey,
|
|
REGVAL_NAME_SERVICE_PROVIDER,
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE) szBuffer,
|
|
&dwSize ) == ERROR_SUCCESS )
|
|
{
|
|
|
|
if ( LSTRCMPI(szBuffer, _T("ncacn_ip_tcp")) == 0 )
|
|
{
|
|
NetSettings.NameServiceProvider = MS_CLIENT_DCE_CELL_DIR_SERVICE;
|
|
|
|
dwSize = sizeof( szBuffer );
|
|
|
|
if( RegQueryValueEx( hNameServiceKey,
|
|
REGVAL_NETWORK_ADDRESS,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) szBuffer,
|
|
&dwSize) == ERROR_SUCCESS )
|
|
{
|
|
|
|
lstrcpyn( NetSettings.szNetworkAddress,
|
|
szBuffer,
|
|
MAX_NETWORK_ADDRESS_LENGTH + 1 );
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
NetSettings.NameServiceProvider = MS_CLIENT_WINDOWS_LOCATOR;
|
|
}
|
|
|
|
}
|
|
|
|
RegCloseKey( hNameServiceKey );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ReadAppletalkSettingsFromRegistry
|
|
//
|
|
// Purpose: Read in registry settings on Appletalk and fill the global structs
|
|
// with the appropriate values
|
|
//
|
|
// Arguments: HKEY *hKey
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
ReadAppletalkSettingsFromRegistry( IN HKEY *hKey )
|
|
{
|
|
|
|
REGSAM SecurityAccess = KEY_QUERY_VALUE;
|
|
|
|
// ISSUE-2002/02/28-stelo- write this function
|
|
|
|
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ReadIpxSettingsFromRegistry
|
|
//
|
|
// Purpose: Read in registry settings on IPX and fill the global structs
|
|
// with the appropriate values
|
|
//
|
|
// Arguments: HKEY *hKey
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
ReadIpxSettingsFromRegistry( IN HKEY *hKey )
|
|
{
|
|
|
|
REGSAM SecurityAccess = KEY_QUERY_VALUE;
|
|
HKEY hIpxAdaptersKey = NULL;
|
|
HKEY hNetworkAdapterKey = NULL;
|
|
DWORD dwSize = 0;
|
|
NETWORK_ADAPTER_NODE *pNetAdapter = NULL;
|
|
|
|
WCHAR szStringGuid[MAX_GUID_STRING];
|
|
|
|
TCHAR szBuffer[BUFFER_SIZE];
|
|
|
|
if( RegOpenKeyEx( *hKey,
|
|
REGVAL_ADAPTERS,
|
|
0,
|
|
SecurityAccess,
|
|
&hIpxAdaptersKey ) != ERROR_SUCCESS )
|
|
{
|
|
|
|
//
|
|
// need this key to read in other IPX values so bail if we can't get it
|
|
//
|
|
return;
|
|
|
|
}
|
|
|
|
dwSize = sizeof( szBuffer );
|
|
|
|
if( RegQueryValueEx( *hKey,
|
|
REGVAL_VIRTUAL_NETWORK_NUMBER,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) szBuffer,
|
|
&dwSize ) == ERROR_SUCCESS )
|
|
{
|
|
|
|
lstrcpyn( NetSettings.szInternalNetworkNumber,
|
|
szBuffer,
|
|
MAX_INTERNAL_NET_NUMBER_LEN + 1 );
|
|
|
|
}
|
|
|
|
//
|
|
// For each Network Adapter, load its IPX settings
|
|
//
|
|
|
|
for( pNetAdapter = NetSettings.NetworkAdapterHead;
|
|
pNetAdapter;
|
|
pNetAdapter = pNetAdapter->next )
|
|
{
|
|
|
|
StringFromGUID2( pNetAdapter->guid,
|
|
szStringGuid,
|
|
StrBuffSize( szStringGuid ) );
|
|
|
|
if( RegOpenKeyEx( hIpxAdaptersKey,
|
|
szStringGuid,
|
|
0,
|
|
SecurityAccess,
|
|
&hNetworkAdapterKey ) == ERROR_SUCCESS )
|
|
{
|
|
|
|
dwSize = sizeof( szBuffer );
|
|
|
|
if( RegQueryValueEx( hNetworkAdapterKey,
|
|
REGVAL_PKT_TYPE,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) szBuffer,
|
|
&dwSize) == ERROR_SUCCESS )
|
|
{
|
|
|
|
lstrcpyn( pNetAdapter->szFrameType, _T("0x"), AS(pNetAdapter->szFrameType) );
|
|
|
|
lstrcatn( pNetAdapter->szFrameType, szBuffer, MAX_FRAMETYPE_LEN );
|
|
|
|
}
|
|
|
|
dwSize = sizeof( szBuffer );
|
|
|
|
if( RegQueryValueEx( hNetworkAdapterKey,
|
|
REGVAL_NETWORK_NUMBER,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) szBuffer,
|
|
&dwSize) == ERROR_SUCCESS )
|
|
{
|
|
|
|
lstrcpyn( pNetAdapter->szNetworkNumber,
|
|
szBuffer,
|
|
MAX_NET_NUMBER_LEN + 1 );
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ReadTcpipSettingsFromRegistry
|
|
//
|
|
// Purpose: Read in registry settings on TCP/IP and fill the global structs
|
|
// with the appropriate values
|
|
//
|
|
// Arguments: HKEY *hKey -
|
|
//
|
|
// Returns: HRESULT returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
ReadTcpipSettingsFromRegistry( IN HKEY *hKey )
|
|
{
|
|
|
|
HKEY hTcpipInterfaceKey = NULL;
|
|
REGSAM SecurityAccess = KEY_QUERY_VALUE;
|
|
|
|
NETWORK_ADAPTER_NODE *pNetAdapter = NULL;
|
|
|
|
if( RegOpenKeyEx( *hKey,
|
|
REGVAL_INTERFACES,
|
|
0,
|
|
SecurityAccess,
|
|
&hTcpipInterfaceKey ) != ERROR_SUCCESS )
|
|
{
|
|
|
|
//
|
|
// need this key to read in all other TCP/IP values so bail if we can't get it
|
|
//
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// For each Network Adapter, load its TCP/IP settings
|
|
//
|
|
|
|
for( pNetAdapter = NetSettings.NetworkAdapterHead;
|
|
pNetAdapter;
|
|
pNetAdapter = pNetAdapter->next )
|
|
{
|
|
|
|
ReadAdapterSpecificTcpipSettings( hTcpipInterfaceKey, pNetAdapter );
|
|
|
|
}
|
|
|
|
// ISSUE-2002/20/28-stelo -not reading in LM Hosts setting
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ReadAdapterSpecificTcpipSettings
|
|
//
|
|
// Purpose: Reads network adapter specific TCP/IP settings and populates the
|
|
// pNetAdapter structure with their values.
|
|
//
|
|
// Arguments:
|
|
// IN HKEY hTcpipInterfaceKey - handle to the TCP/IP settings portion of
|
|
// the registry
|
|
// IN OUT NETWORK_ADAPTER_NODE *pNetAdapter - ptr to structure to load the
|
|
// TCP/IP values into
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
ReadAdapterSpecificTcpipSettings( IN HKEY hTcpipInterfaceKey,
|
|
IN OUT NETWORK_ADAPTER_NODE *pNetAdapter )
|
|
{
|
|
|
|
DWORD dwDHCP = 0;
|
|
DWORD dwSize = 0;
|
|
DWORD dwSize2 = 0;
|
|
REGSAM SecurityAccess = KEY_QUERY_VALUE;
|
|
HKEY hNetworkAdapterKey = NULL;
|
|
LPTSTR lpszBuffer = NULL;
|
|
LPTSTR lpszBuffer2 = NULL;
|
|
TCHAR szStringGuid[MAX_GUID_STRING];
|
|
|
|
//
|
|
// Make sure we can allocate big enough buffers...
|
|
//
|
|
lpszBuffer = (LPTSTR) MALLOC( BUFFER_SIZE * sizeof(TCHAR) );
|
|
if ( !lpszBuffer )
|
|
{
|
|
// Unable to allocate memory... bail!
|
|
return;
|
|
}
|
|
lpszBuffer2 = (LPTSTR) MALLOC( BUFFER_SIZE * sizeof(TCHAR) );
|
|
if ( !lpszBuffer2 )
|
|
{
|
|
// Unable to allocate memory... bail!
|
|
FREE( lpszBuffer );
|
|
return;
|
|
}
|
|
|
|
StringFromGUID2( pNetAdapter->guid,
|
|
szStringGuid,
|
|
StrBuffSize( szStringGuid ) );
|
|
|
|
if( RegOpenKeyEx( hTcpipInterfaceKey,
|
|
szStringGuid,
|
|
0,
|
|
SecurityAccess,
|
|
&hNetworkAdapterKey ) == ERROR_SUCCESS )
|
|
{
|
|
|
|
dwSize = sizeof( dwDHCP );
|
|
|
|
if( RegQueryValueEx( hNetworkAdapterKey,
|
|
REGVAL_ENABLE_DHCP,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) &dwDHCP,
|
|
&dwSize ) == ERROR_SUCCESS )
|
|
{
|
|
|
|
if( dwDHCP == 1 )
|
|
{
|
|
|
|
pNetAdapter->bObtainIPAddressAutomatically = TRUE;
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
pNetAdapter->bObtainIPAddressAutomatically = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( ! pNetAdapter->bObtainIPAddressAutomatically )
|
|
{
|
|
TCHAR *pszIpAddresses;
|
|
TCHAR *pszSubnetAddresses;
|
|
TCHAR *pszGatewayAddresses;
|
|
TCHAR *pszDnsAddresses;
|
|
TCHAR *pszWinsAddresses;
|
|
TCHAR szWinsRegPath[MAX_INILINE_LEN + 1] = _T("");
|
|
HKEY hWinsKey = NULL;
|
|
HRESULT hrCat;
|
|
|
|
dwSize = BUFFER_SIZE * sizeof(TCHAR);
|
|
dwSize2 = BUFFER_SIZE * sizeof(TCHAR);
|
|
|
|
if( (RegQueryValueEx( hNetworkAdapterKey,
|
|
REGVAL_IPADDRESS,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) lpszBuffer,
|
|
&dwSize ) == ERROR_SUCCESS)
|
|
&&
|
|
(RegQueryValueEx( hNetworkAdapterKey,
|
|
REGVAL_SUBNETMASK,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) lpszBuffer2,
|
|
&dwSize2 ) == ERROR_SUCCESS ) )
|
|
{
|
|
|
|
pszIpAddresses = lpszBuffer; // contains the IP Addresses
|
|
pszSubnetAddresses = lpszBuffer2; // contains the Subnet Masks
|
|
|
|
if( *pszIpAddresses != _T('\0') && *pszSubnetAddresses != _T('\0') ) {
|
|
|
|
//
|
|
// Add the IP and Subnet masks to their namelists
|
|
//
|
|
|
|
do
|
|
{
|
|
|
|
TcpipAddNameToNameList( &pNetAdapter->Tcpip_IpAddresses,
|
|
pszIpAddresses );
|
|
|
|
TcpipAddNameToNameList( &pNetAdapter->Tcpip_SubnetMaskAddresses,
|
|
pszSubnetAddresses );
|
|
|
|
} while( GetNextIp( &pszIpAddresses ) && GetNextIp( &pszSubnetAddresses ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dwSize = BUFFER_SIZE * sizeof(TCHAR);
|
|
|
|
if( RegQueryValueEx( hNetworkAdapterKey,
|
|
REGVAL_DEFAULTGATEWAY,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) lpszBuffer,
|
|
&dwSize ) == ERROR_SUCCESS )
|
|
{
|
|
|
|
pszGatewayAddresses = lpszBuffer; // contains the Gateway Addresses
|
|
|
|
if( *pszGatewayAddresses != _T('\0') )
|
|
{
|
|
|
|
//
|
|
// Add the Gateways to its namelist
|
|
//
|
|
|
|
do
|
|
{
|
|
AddNameToNameList( &pNetAdapter->Tcpip_GatewayAddresses,
|
|
pszGatewayAddresses );
|
|
|
|
} while( GetNextIp( &pszGatewayAddresses ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Get the DNS IPs
|
|
//
|
|
dwSize = BUFFER_SIZE * sizeof(TCHAR);
|
|
|
|
if( RegQueryValueEx( hNetworkAdapterKey,
|
|
REGVAL_NAMESERVER,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) lpszBuffer,
|
|
&dwSize ) == ERROR_SUCCESS )
|
|
{
|
|
|
|
pszDnsAddresses = lpszBuffer; // Contains the DNS addresses
|
|
|
|
if( *pszDnsAddresses != _T('\0') )
|
|
{
|
|
|
|
TCHAR szDnsBuffer[MAX_INILINE_LEN + 1];
|
|
|
|
NetSettings.bObtainDNSServerAutomatically = FALSE;
|
|
|
|
//
|
|
// Loop grabbing the DNS IPs and inserting them into
|
|
// its namelist
|
|
//
|
|
|
|
while( GetCommaDelimitedEntry( szDnsBuffer, &pszDnsAddresses ) )
|
|
{
|
|
|
|
TcpipAddNameToNameList( &pNetAdapter->Tcpip_DnsAddresses,
|
|
szDnsBuffer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Get the WINS server list
|
|
//
|
|
// Have to jump to different location in the registry to read
|
|
// the WINS data
|
|
//
|
|
|
|
//
|
|
// Build up the WINS registry path
|
|
//
|
|
|
|
lstrcpyn( szWinsRegPath, REGVAL_WINS, AS(szWinsRegPath) );
|
|
|
|
hrCat=StringCchCat( szWinsRegPath, AS(szWinsRegPath), szStringGuid );
|
|
|
|
//
|
|
// Grab all the WINS values from the registry
|
|
//
|
|
|
|
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
szWinsRegPath,
|
|
0,
|
|
SecurityAccess,
|
|
&hWinsKey ) != ERROR_SUCCESS )
|
|
{
|
|
|
|
//
|
|
// need this key to read in the WINS values so bail if we
|
|
// can't get it
|
|
//
|
|
return;
|
|
|
|
}
|
|
|
|
dwSize = BUFFER_SIZE * sizeof(TCHAR);
|
|
|
|
if( RegQueryValueEx( hWinsKey,
|
|
REGVAL_NAMESERVERLIST,
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE) lpszBuffer,
|
|
&dwSize ) == ERROR_SUCCESS )
|
|
{
|
|
|
|
pszWinsAddresses = lpszBuffer;
|
|
|
|
if( *pszWinsAddresses != _T('\0') )
|
|
{
|
|
|
|
//
|
|
// Add the WINS IPs to the namelist
|
|
//
|
|
do
|
|
{
|
|
|
|
AddNameToNameList( &pNetAdapter->Tcpip_WinsAddresses,
|
|
pszWinsAddresses );
|
|
|
|
} while( GetNextIp( &pszWinsAddresses ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Get the Domain
|
|
//
|
|
dwSize = BUFFER_SIZE * sizeof(TCHAR);
|
|
|
|
if( RegQueryValueEx( hNetworkAdapterKey,
|
|
REGVAL_DOMAIN,
|
|
0,
|
|
NULL,
|
|
(LPBYTE) lpszBuffer,
|
|
&dwSize ) == ERROR_SUCCESS )
|
|
{
|
|
|
|
lstrcpyn( pNetAdapter->szDNSDomainName,
|
|
lpszBuffer,
|
|
MAX_DNS_DOMAIN_LENGTH + 1 );
|
|
|
|
}
|
|
|
|
// ISSUE-2002/20/28-stelo- not reading the NetBiosOption
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetNextIp
|
|
//
|
|
// Purpose: Gets the next string in a multi-NULL terminated string
|
|
//
|
|
// Arguments: TCHAR *ppszString - pointer to the current string
|
|
//
|
|
// Returns: BOOL - TRUE if ppszString points to the IP string
|
|
// FALSE if there are no more IP strings left
|
|
// TCHAR *ppszString - on TRUE, points to the next IP string
|
|
// - on FALSE, points to NULL
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static BOOL
|
|
GetNextIp( IN OUT TCHAR **ppszString )
|
|
{
|
|
|
|
while( **ppszString != _T('\0') )
|
|
{
|
|
(*ppszString)++;
|
|
}
|
|
|
|
//
|
|
// check that Char after the one we are currently looking at to see if it
|
|
// is the true end of the string(s)
|
|
//
|
|
|
|
if( *( (*ppszString) + 1 ) == _T('\0') )
|
|
{
|
|
//
|
|
// 2 NULLs in a row signify there are no more IPs to read
|
|
//
|
|
|
|
return( FALSE );
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Advance one more so we go past the \0 and point to the first char
|
|
// of the new IP address
|
|
//
|
|
|
|
(*ppszString)++;
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetDomainMembershipInfo
|
|
//
|
|
// Purpose: Gets the domain/workgroup for the machine it is running on.
|
|
// Assumes enough space is already allocated in szName for the copy.
|
|
//
|
|
// Arguments: BOOL* bDomainMember - if TRUE, then the contents of szName is a Domain
|
|
// if FALSE, then the contents of szName is a Workgroup
|
|
//
|
|
// Returns: NTSTATUS - returns success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static NTSTATUS
|
|
GetDomainMembershipInfo( OUT BOOL* bDomainMember, OUT TCHAR *szName )
|
|
{
|
|
|
|
NTSTATUS ntstatus;
|
|
POLICY_PRIMARY_DOMAIN_INFO* ppdi;
|
|
LSA_OBJECT_ATTRIBUTES loa;
|
|
LSA_HANDLE hLsa = 0;
|
|
|
|
loa.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
|
|
loa.RootDirectory = NULL;
|
|
loa.ObjectName = NULL;
|
|
loa.Attributes = 0;
|
|
loa.SecurityDescriptor = NULL;
|
|
loa.SecurityQualityOfService = NULL;
|
|
|
|
ntstatus = LsaOpenPolicy( NULL, &loa, POLICY_VIEW_LOCAL_INFORMATION, &hLsa );
|
|
|
|
if( LSA_SUCCESS( ntstatus ) )
|
|
{
|
|
|
|
ntstatus = LsaQueryInformationPolicy( hLsa,
|
|
PolicyPrimaryDomainInformation,
|
|
(VOID **) &ppdi );
|
|
|
|
if( LSA_SUCCESS( ntstatus ) )
|
|
{
|
|
|
|
if( ppdi->Sid > 0 )
|
|
{
|
|
*bDomainMember = TRUE;
|
|
}
|
|
else
|
|
{
|
|
*bDomainMember = FALSE;
|
|
}
|
|
|
|
lstrcpyn( szName, ppdi->Name.Buffer, AS(szName) );
|
|
|
|
}
|
|
|
|
LsaClose( hLsa );
|
|
|
|
}
|
|
|
|
return( ntstatus );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: InitializeComInterface
|
|
//
|
|
// Purpose: Obtains the INetCfgClass interface and enumerates all the
|
|
// components. Handles cleanup of all interfaces if failure
|
|
// returned.
|
|
//
|
|
// Arguments:
|
|
// const GUID* pGuid - pointer to GUID representing the class of
|
|
// components represented by the returned pointer
|
|
// INetCfg* pNetCfg - pointer to initialized INetCfg interface
|
|
// INetCfgClass** ppNetCfgClass - output parameter pointing to
|
|
// the interface requested by the GUID
|
|
// IEnumNetCfgComponent *pEnum - output param that points to an
|
|
// IEnumNetCfgComponent to get to each individual INetCfgComponent
|
|
// INetCfgComponent *arrayComp[MAX_NUM_NET_COMPONENTS] - array of all
|
|
// the INetCfgComponents that correspond to the the given GUID
|
|
// ULONG* pCount - the number of INetCfgComponents in the array
|
|
//
|
|
// Returns: HRESULT - returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
InitializeComInterface( const GUID *pGuid,
|
|
INetCfg *pNetCfg,
|
|
INetCfgClass *pNetCfgClass,
|
|
IEnumNetCfgComponent *pEnum,
|
|
INetCfgComponent *arrayComp[MAX_NUM_NET_COMPONENTS],
|
|
ULONG* pCount )
|
|
{
|
|
|
|
HRESULT hr;
|
|
HRESULT TempHr;
|
|
|
|
//
|
|
// Obtain the INetCfgClass interface pointer
|
|
//
|
|
|
|
hr = GetClass( pGuid,
|
|
pNetCfg,
|
|
&pNetCfgClass );
|
|
|
|
//
|
|
// Check validity of the pointer we got back from GetClass
|
|
//
|
|
|
|
TempHr = ChkInterfacePointer( pNetCfgClass, IID_INetCfgClass );
|
|
|
|
if( FAILED( hr ) || FAILED( TempHr ) )
|
|
{
|
|
|
|
ReleaseInterfaces( pNetCfg );
|
|
|
|
return( E_FAIL );
|
|
|
|
}
|
|
|
|
//
|
|
// Retrieve the enumerator interface
|
|
//
|
|
|
|
hr = pNetCfgClass->EnumComponents( &pEnum );
|
|
|
|
if( FAILED( hr ) ||
|
|
FAILED( ChkInterfacePointer( pEnum, IID_IEnumNetCfgComponent ) ) )
|
|
{
|
|
|
|
if( pNetCfgClass )
|
|
{
|
|
pNetCfgClass->Release();
|
|
}
|
|
|
|
ReleaseInterfaces( pNetCfg );
|
|
|
|
return( E_FAIL );
|
|
|
|
}
|
|
|
|
hr = pEnum->Next( MAX_NUM_NET_COMPONENTS, &arrayComp[0], pCount );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
if( pEnum )
|
|
{
|
|
pEnum->Release();
|
|
}
|
|
|
|
if( pNetCfgClass )
|
|
{
|
|
pNetCfgClass->Release();
|
|
}
|
|
|
|
ReleaseInterfaces( pNetCfg );
|
|
|
|
return( E_FAIL );
|
|
|
|
}
|
|
|
|
return( S_OK );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: UninitializeComInterface
|
|
//
|
|
// Purpose: To release the Net Config object interfaces.
|
|
//
|
|
// Arguments: INetCfgClass *pNetCfgClass - the INetCfgClass to be released
|
|
// IEnumNetCfgComponent *pEnum - the IEnumNetCfgComponent to be released
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
UninitializeComInterface( INetCfgClass *pNetCfgClass,
|
|
IEnumNetCfgComponent *pEnum )
|
|
{
|
|
|
|
if( pNetCfgClass )
|
|
{
|
|
pNetCfgClass->Release();
|
|
}
|
|
|
|
if( pEnum )
|
|
{
|
|
pEnum->Release();
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: InitializeInterfaces
|
|
//
|
|
// Purpose: Initializes COM, creates, and initializes the NetCfg
|
|
//
|
|
// Arguments: INetCfg** ppNetCfg - output param that is the created and
|
|
// initialized INetCfg interface
|
|
//
|
|
// Returns: HRESULT - returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
InitializeInterfaces( INetCfg** ppNetCfg )
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( hr );
|
|
}
|
|
|
|
hr = CreateAndInitNetCfg( ppNetCfg );
|
|
|
|
return( hr );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: CreateAndInitNetCfg
|
|
//
|
|
// Purpose: Instantiate and initalize an INetCfg interface
|
|
//
|
|
// Arguments: INetCfg** ppNetCfg - output parameter that is the initialized
|
|
// INetCfg interface
|
|
//
|
|
// Returns: HRESULT - returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
CreateAndInitNetCfg( INetCfg** ppNetCfg )
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
INetCfg* pNetCfg = NULL;
|
|
|
|
if( ( ppNetCfg == NULL ) ||
|
|
IsBadWritePtr( ppNetCfg, sizeof(ppNetCfg) ) )
|
|
{
|
|
|
|
return( E_INVALIDARG );
|
|
|
|
}
|
|
|
|
*ppNetCfg = NULL;
|
|
|
|
hr = CoCreateInstance( CLSID_CNetCfg,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_INetCfg,
|
|
reinterpret_cast<LPVOID*>(&pNetCfg) );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( hr );
|
|
}
|
|
|
|
*ppNetCfg = pNetCfg;
|
|
|
|
//
|
|
// Initialize the INetCfg object.
|
|
//
|
|
|
|
hr = (*ppNetCfg)->Initialize( NULL );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
|
|
(*ppNetCfg)->Release();
|
|
|
|
CoUninitialize();
|
|
|
|
return( hr );
|
|
|
|
}
|
|
|
|
return( hr );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ReleaseInterfaces
|
|
//
|
|
// Purpose: Uninitializes the NetCfg object and releases the interfaces
|
|
//
|
|
// Arguments: INetCfg* pNetCfg - the INetCfg interface to be released
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
ReleaseInterfaces( INetCfg* pNetCfg )
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Check validity of the pNetCfg interface pointer
|
|
//
|
|
|
|
hr = ChkInterfacePointer( pNetCfg, IID_INetCfg );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if( pNetCfg != NULL )
|
|
{
|
|
pNetCfg->Uninitialize();
|
|
|
|
pNetCfg->Release();
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ChkInterfacePointer
|
|
//
|
|
// Purpose: Checks if an interface pointer is valid and if it can query itself
|
|
//
|
|
// Arguments: IUnknown* pInterface - interface pointer to check
|
|
// REFIID IID_IInterface - the IID of parameter 1
|
|
//
|
|
// Returns: HRESULT - returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
ChkInterfacePointer( IUnknown* pInterface, REFIID IID_IInterface )
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
IUnknown* pResInterface = NULL;
|
|
|
|
if( (pInterface == NULL) || IsBadReadPtr( pInterface, sizeof(pInterface) ) )
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
return( hr );
|
|
}
|
|
|
|
hr = pInterface->QueryInterface( IID_IInterface, (void**)&pResInterface );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( hr );
|
|
}
|
|
|
|
if( pInterface != pResInterface )
|
|
{
|
|
hr = E_FAIL;
|
|
|
|
pResInterface->Release();
|
|
|
|
return( hr );
|
|
}
|
|
|
|
pResInterface->Release();
|
|
|
|
return( S_OK );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetClass
|
|
//
|
|
// Purpose: Retrieves INetCfgClass for the specified pGuid
|
|
//
|
|
// Arguments: const GUID* pGuid - pointer to GUID representing the class of
|
|
// components represented by the returned pointer
|
|
// INetCfg* pNetCfg - pointer to initialized INetCfg interface
|
|
// INetCfgClass** ppNetCfgClass - output parameter pointing to
|
|
// the interface requested by the GUID
|
|
//
|
|
// Returns: HRESULT - returns status of success or failure of the function
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static HRESULT
|
|
GetClass( const GUID* pGuid, INetCfg* pNetCfg, INetCfgClass** ppNetCfgClass )
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
INetCfgClass* pNetCfgClass = NULL;
|
|
|
|
hr = ChkInterfacePointer( pNetCfg, IID_INetCfg );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( E_INVALIDARG );
|
|
}
|
|
|
|
if( IsBadWritePtr( ppNetCfgClass, sizeof(ppNetCfgClass) ) )
|
|
{
|
|
return( E_INVALIDARG );
|
|
}
|
|
|
|
hr = pNetCfg->QueryNetCfgClass( pGuid,
|
|
IID_INetCfgClass,
|
|
(void**)&pNetCfgClass );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return( hr );
|
|
}
|
|
|
|
*ppNetCfgClass = pNetCfgClass;
|
|
|
|
return( hr );
|
|
|
|
}
|