466 lines
11 KiB
C++
466 lines
11 KiB
C++
//+---------------------------------------------------------------------------
|
||
//
|
||
// Microsoft Windows
|
||
// Copyright (C) Microsoft Corporation, 1997 - 2000
|
||
//
|
||
// File: N E T I P. C P P
|
||
//
|
||
// Contents: Routines supporting RAS interoperability
|
||
//
|
||
// Notes:
|
||
//
|
||
// Author: billi 07 03 2001
|
||
//
|
||
// History:
|
||
//
|
||
//----------------------------------------------------------------------------
|
||
|
||
#include <windows.h>
|
||
#include <devguid.h>
|
||
#include <objbase.h>
|
||
#include <setupapi.h>
|
||
#include <stdio.h>
|
||
|
||
#include "netconn.h"
|
||
#include "nconnwrap.h"
|
||
#include "debug.h"
|
||
#include "NetIp.h"
|
||
#include "w9xdhcp.h"
|
||
#include "netip.h"
|
||
#include "util.h"
|
||
#include "registry.h"
|
||
#include "theapp.h"
|
||
|
||
//#define INITGUID
|
||
//#include <guiddef.h>
|
||
//DEFINE_GUID( GUID_DEVCLASS_NET, 0x4d36e972L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
|
||
|
||
|
||
#define CM_DRP_DRIVER (0x0000000A) // Driver REG_SZ property (RW)
|
||
|
||
|
||
#undef NETADAPTER
|
||
|
||
|
||
// Prototype for iphlpapi routine. For some reason, this isn't defined
|
||
// in any header.
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
typedef DWORD (APIENTRY *LPFNSETADAPTERIPADDRESS)(
|
||
LPSTR AdapterName,
|
||
BOOL EnableDHCP,
|
||
ULONG IPAddress,
|
||
ULONG SubnetMask,
|
||
ULONG DefaultGateway
|
||
);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
HRESULT HrInternalGetAdapterInfo(
|
||
PIP_ADAPTER_INFO* ppAdapter
|
||
)
|
||
//+---------------------------------------------------------------------------
|
||
//
|
||
// Function: HrInternalGetAdapterInfo
|
||
//
|
||
// Purpose:
|
||
//
|
||
// Arguments: PIP_ADAPTER_INFO* ppAdapter
|
||
//
|
||
// Returns: HRESULT
|
||
//
|
||
// Author: billi 12/02/01
|
||
//
|
||
// Notes:
|
||
//
|
||
{
|
||
HRESULT hr;
|
||
PIP_ADAPTER_INFO paAdapterInfo = NULL;
|
||
|
||
ASSERT( ppAdapter );
|
||
|
||
if ( NULL == ppAdapter )
|
||
{
|
||
ppAdapter = &paAdapterInfo;
|
||
hr = E_POINTER;
|
||
}
|
||
else
|
||
{
|
||
ULONG uLen = 1024;
|
||
|
||
*ppAdapter = NULL;
|
||
hr = E_FAIL;
|
||
|
||
for ( int i=0; i<2; i++ )
|
||
{
|
||
PIP_ADAPTER_INFO pInfo = (PIP_ADAPTER_INFO)new BYTE[ uLen ];
|
||
|
||
ZeroMemory( pInfo, uLen );
|
||
|
||
if ( NULL != pInfo )
|
||
{
|
||
DWORD dwErr = GetAdaptersInfo( pInfo, &uLen );
|
||
|
||
if ( ERROR_SUCCESS == dwErr )
|
||
{
|
||
hr = S_OK;
|
||
*ppAdapter = pInfo;
|
||
break;
|
||
}
|
||
|
||
delete [] (BYTE *)pInfo;
|
||
}
|
||
else
|
||
{
|
||
hr = E_OUTOFMEMORY;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return hr;
|
||
}
|
||
|
||
/*
|
||
|
||
HRESULT HrOpenDevRegKey(
|
||
const GUID* lpGuid,
|
||
DWORD Node,
|
||
DWORD Scope,
|
||
DWORD HwProfile,
|
||
DWORD KeyType,
|
||
REGSAM samDesired,
|
||
HKEY* phKey
|
||
)
|
||
//+---------------------------------------------------------------------------
|
||
//
|
||
// Function: Hr
|
||
//
|
||
// Purpose:
|
||
//
|
||
// Arguments:
|
||
//
|
||
// Returns: HRESULT
|
||
//
|
||
// Author: billi 12/02/01
|
||
//
|
||
// Notes:
|
||
//
|
||
{
|
||
HRESULT hr = E_INVALIDARG;
|
||
|
||
ASSERT( lpGuid );
|
||
|
||
if ( lpGuid )
|
||
{
|
||
hr = E_POINTER;
|
||
|
||
ASSERT( phKey );
|
||
|
||
if ( phKey )
|
||
{
|
||
// The only way to open a specific device is to get the list of Class "Net" devices
|
||
// and search the list for one with a matching devnode
|
||
|
||
HDEVINFO hDevInfo;
|
||
|
||
*phKey = (HKEY)INVALID_HANDLE_VALUE;
|
||
hr = E_FAIL;
|
||
hDevInfo = SetupDiGetClassDevs( lpGuid, NULL, NULL, DIGCF_DEVICEINTERFACE );
|
||
|
||
if ( INVALID_HANDLE_VALUE != hDevInfo )
|
||
{
|
||
SP_DEVINFO_DATA SpData;
|
||
DWORD i = 0;
|
||
|
||
// Here we walk the list of devices and try to match the devnode handles
|
||
|
||
ZeroMemory( &SpData, sizeof(SP_DEVINFO_DATA) );
|
||
SpData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||
|
||
while ( SetupDiEnumDeviceInfo( hDevInfo, i, &SpData ) )
|
||
{
|
||
if ( Node == SpData.DevInst )
|
||
{
|
||
// Got it!
|
||
|
||
HKEY hKey =
|
||
SetupDiOpenDevRegKey( hDevInfo, &SpData, Scope, HwProfile, KeyType, samDesired );
|
||
|
||
if ( INVALID_HANDLE_VALUE != hKey )
|
||
{
|
||
*phKey = hKey;
|
||
hr = S_OK;
|
||
}
|
||
}
|
||
|
||
i++;
|
||
ZeroMemory( &SpData, sizeof(SP_DEVINFO_DATA) );
|
||
SpData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||
}
|
||
|
||
SetupDiDestroyDeviceInfoList( hDevInfo );
|
||
}
|
||
}
|
||
}
|
||
|
||
return hr;
|
||
}
|
||
*/
|
||
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
|
||
|
||
char*
|
||
HostAddrToIpPsz(
|
||
DWORD dwAddress
|
||
)
|
||
|
||
// Converts IP Address from host by order to string
|
||
|
||
{
|
||
char *pszNewStr = new char[16];
|
||
|
||
if ( pszNewStr )
|
||
{
|
||
sprintf( pszNewStr,
|
||
"%u.%u.%u.%u",
|
||
(dwAddress&0xff),
|
||
((dwAddress>>8)&0x0ff),
|
||
((dwAddress>>16)&0x0ff),
|
||
((dwAddress>>24)&0x0ff) );
|
||
}
|
||
|
||
return pszNewStr;
|
||
}
|
||
|
||
|
||
|
||
BOOLEAN WINAPI IsAdapterDisconnected(
|
||
VOID *pContext
|
||
)
|
||
//+---------------------------------------------------------------------------
|
||
//
|
||
// Function: IsAdapterDisconnected
|
||
//
|
||
// Purpose:
|
||
//
|
||
// Arguments: const NETADAPTER* pNA
|
||
//
|
||
// Returns: HRESULT
|
||
//
|
||
// Author: billi 11/04/01
|
||
//
|
||
// Notes:
|
||
//
|
||
{
|
||
const NETADAPTER* pAdapter = (const NETADAPTER*)pContext;
|
||
BOOLEAN bDisconnected = FALSE;
|
||
|
||
ASSERT( pAdapter );
|
||
|
||
if ( NULL != pAdapter )
|
||
{
|
||
HRESULT hr;
|
||
PIP_ADAPTER_INFO pInfo;
|
||
|
||
hr = HrInternalGetAdapterInfo( &pInfo );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
char* pszName;
|
||
|
||
hr = HrWideCharToMultiByte( pAdapter->szDisplayName, &pszName );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
PIP_ADAPTER_INFO pAdapter = pInfo;
|
||
|
||
while ( pAdapter )
|
||
{
|
||
if ( ( strcmp( pAdapter->AdapterName, pszName ) == 0 ) ||
|
||
( strcmp( pAdapter->Description, pszName ) == 0 ) )
|
||
{
|
||
// If a single matching card returns TRUE then we return TRUE
|
||
|
||
bDisconnected = bDisconnected || IsMediaDisconnected( pAdapter->Index );
|
||
}
|
||
|
||
pAdapter = pAdapter->Next;
|
||
|
||
} // while ( pAdapter )
|
||
|
||
delete [] pszName;
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
delete pInfo;
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
} // if ( NULL != pNA )
|
||
|
||
return bDisconnected;
|
||
}
|
||
|
||
|
||
|
||
HRESULT HrSetAdapterIpAddress(
|
||
const NETADAPTER* pNA,
|
||
ULONG IPAddress,
|
||
ULONG SubnetMask
|
||
)
|
||
//+---------------------------------------------------------------------------
|
||
//
|
||
// Function: HrSetAdapterIpAddress
|
||
//
|
||
// Purpose:
|
||
//
|
||
// Arguments:
|
||
// const NETADAPTER* pNA,
|
||
// BOOL EnableDHCP,
|
||
// ULONG IPAddress,
|
||
// ULONG SubnetMask,
|
||
//
|
||
// Returns: S_OK on success, otherwise an error code
|
||
//
|
||
// Notes:
|
||
//
|
||
{
|
||
HRESULT hr = E_INVALIDARG;
|
||
|
||
ASSERT( pNA );
|
||
|
||
if ( pNA )
|
||
{
|
||
TCHAR* pszAddress = HostAddrToIpPsz( IPAddress );
|
||
TCHAR* pszSubnet = HostAddrToIpPsz( SubnetMask );
|
||
|
||
hr = E_OUTOFMEMORY;
|
||
|
||
if ( pszAddress && pszSubnet )
|
||
{
|
||
HINSTANCE hLibInstance = NULL;
|
||
DWORD dnParent = pNA->devnode;
|
||
DWORD dnChild;
|
||
DWORD cRet = GetChildDevice( &dnChild, dnParent, &hLibInstance, 0 );
|
||
|
||
do
|
||
{
|
||
TCHAR* Buffer = NULL;
|
||
ULONG Length = 0L;
|
||
|
||
if ( STATUS_SUCCESS == cRet )
|
||
cRet = GetDeviceIdA( dnChild, &Buffer, &Length, 0);
|
||
|
||
if ( (STATUS_SUCCESS == cRet) && Buffer && Length && (strstr( Buffer, SZ_PROTOCOL_TCPIPA ) != NULL) )
|
||
{
|
||
char pszSubkey[ MAX_PATH ];
|
||
|
||
Length = MAX_PATH;
|
||
|
||
cRet = GetDevNodeRegistryPropertyA( dnChild, CM_DRP_DRIVER, NULL, pszSubkey, &Length, 0);
|
||
|
||
if ( STATUS_SUCCESS == cRet )
|
||
{
|
||
CRegistry reg;
|
||
char pszDriverKey[ MAX_PATH ];
|
||
|
||
lstrcpy( pszDriverKey, "System\\CurrentControlSet\\Services\\Class\\" );
|
||
lstrcat( pszDriverKey, pszSubkey );
|
||
|
||
if ( reg.OpenKey( HKEY_LOCAL_MACHINE, pszDriverKey, KEY_ALL_ACCESS) )
|
||
{
|
||
if ( reg.SetStringValue( "IPAddress", pszAddress ) &&
|
||
reg.SetStringValue( "IPMask", pszSubnet ) )
|
||
{
|
||
hr = S_OK;
|
||
}
|
||
|
||
reg.CloseKey();
|
||
}
|
||
|
||
} // if ( STATUS_SUCCESS == cRet )
|
||
|
||
} // if ( Buffer && Length && (strcmp( Buffer, SZ_PROTOCOL_TCPIPA ) == 0) )
|
||
|
||
if ( Buffer )
|
||
delete [] Buffer;
|
||
|
||
dnParent = dnChild;
|
||
cRet = GetSiblingDevice( &dnChild, dnParent, hLibInstance, 0 );
|
||
}
|
||
while ( STATUS_SUCCESS == cRet );
|
||
|
||
if ( hLibInstance )
|
||
{
|
||
FreeLibrary( hLibInstance );
|
||
}
|
||
|
||
} // if ( pszAddress && pszSubnet )
|
||
|
||
if ( pszAddress )
|
||
delete [] pszAddress;
|
||
|
||
if ( pszSubnet )
|
||
delete [] pszSubnet;
|
||
|
||
} // if ( pNA )
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT HrEnableDhcp( VOID* pContext, DWORD dwFlags )
|
||
//+---------------------------------------------------------------------------
|
||
//
|
||
// Function: HrEnableDhcpIfLAN
|
||
//
|
||
// Purpose:
|
||
//
|
||
// Arguments: NETADAPTER* pNA
|
||
// DWORD dwFlags
|
||
//
|
||
// Returns: HRESULT
|
||
//
|
||
// Author: billi 29/04/01
|
||
//
|
||
// Notes:
|
||
//
|
||
{
|
||
HRESULT hr = E_INVALIDARG;
|
||
const NETADAPTER* pNA = (const NETADAPTER*)pContext;
|
||
|
||
ASSERT( pNA );
|
||
|
||
if ( NULL != pNA )
|
||
{
|
||
hr = HrSetAdapterIpAddress( pNA, 0, 0 );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
hr = RestartNetAdapter( pNA->devnode );
|
||
}
|
||
|
||
} // if ( NULL != pNA )
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|