windows-nt/Source/XPSP1/NT/shell/ext/hnw/wizard/netip.cpp
2020-09-26 16:20:57 +08:00

807 lines
21 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//+---------------------------------------------------------------------------
//
// 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 "stdafx.h"
#include "Util.h"
#include "TheApp.h"
#include <lmjoin.h>
#include <devguid.h>
#include "NetIp.h"
#include "netutil.h"
HRESULT HrGetHostIpList( char* pszHost, IPAddr* pIpAddress, LPHOSTENT* ppHostEnt )
//+---------------------------------------------------------------------------
//
// Function: HrGetHostIpList
//
// Purpose:
//
// Arguments:
//
// Returns: S_OK on success, otherwise an error code
//
// Notes:
//
{
ASSERT( pszHost );
ASSERT( pIpAddress );
ASSERT( ppHostEnt );
HRESULT hr = E_INVALIDARG;
if ( pIpAddress )
*pIpAddress = INADDR_NONE;
if ( ppHostEnt )
*ppHostEnt = NULL;
if ( pszHost && ( pIpAddress || ppHostEnt ) )
{
hr = E_FAIL;
*pIpAddress = inet_addr( pszHost );
if ( INADDR_NONE == *pIpAddress )
{
LPHOSTENT pHost;
pHost = gethostbyname( pszHost );
if ( pHost && pHost->h_addr_list )
{
#ifdef DBG // checked build
for ( DWORD i=0; pHost->h_addr_list[i]; i++ )
{
char* pszName = (char *)(pHost->h_addr_list[i]) + sizeof(DWORD);
DWORD* pdwAddr = (DWORD *)(pHost->h_addr_list[i]);
struct in_addr in;
in.S_un.S_addr = *pdwAddr;
char* pszAddr = inet_ntoa( in );
TraceMsg(TF_ALWAYS, " Addr[%d] = %S %p %S", i, pszName, pdwAddr, pszAddr );
}
#endif // DBG
if ( pIpAddress )
*pIpAddress = *(IPAddr*)(pHost->h_addr);
if ( ppHostEnt )
*ppHostEnt = pHost;
}
}
if ( INADDR_NONE != *pIpAddress )
{
hr = S_OK;
}
}
TraceMsg(TF_ALWAYS, "HrGetHostIpList = %lx pHostEnt = %lx IpAddress = %lx", hr, *ppHostEnt, *pIpAddress );
return hr;
}
HRESULT HrGetHostIpList( WCHAR* pszwHost, IPAddr* pIpAddress, LPHOSTENT* ppHostEnt )
//+---------------------------------------------------------------------------
//
// Function: HrGetHostIpList
//
// Purpose:
//
// Arguments:
//
// Returns: S_OK on success, otherwise an error code
//
// Notes:
//
{
HRESULT hr;
char* pszHost = NULL;
hr = HrWideCharToMultiByte( pszwHost, &pszHost );
if ( SUCCEEDED(hr) )
{
hr = HrGetHostIpList( pszHost, pIpAddress, ppHostEnt );
delete [] pszHost;
}
return hr;
}
HRESULT HrGetBestAdapter( IPAddr IpAddress, PIP_ADAPTER_INDEX_MAP pAdapter )
//+---------------------------------------------------------------------------
//
// Function: HrGetBestAdapter
//
// Purpose:
//
// Arguments:
//
// Returns: S_OK on success, otherwise an error code
//
// Notes:
//
{
ASSERT( pAdapter );
HRESULT hr = E_FAIL;
TraceMsg(TF_ALWAYS, " %lu:", IpAddress);
DWORD dwBestIfIndex = 0;
DWORD dwErr = GetBestInterface( IpAddress, &dwBestIfIndex );
if ( ERROR_SUCCESS == dwErr )
{
ULONG ulLen = 1024;
for ( int i=0; i<2; i++ )
{
PIP_INTERFACE_INFO pIfTable = (PIP_INTERFACE_INFO)new BYTE[ ulLen ];
if ( NULL != pIfTable )
{
ZeroMemory( pIfTable, ulLen*sizeof(BYTE) );
dwErr = GetInterfaceInfo( pIfTable, &ulLen );
if ( ERROR_SUCCESS == dwErr )
{
for ( LONG j=0L; j<pIfTable->NumAdapters; j++ )
{
TraceMsg(TF_ALWAYS, " %lu %s", pIfTable->Adapter[j].Index, pIfTable->Adapter[j].Name);
if ( pIfTable->Adapter[j].Index == dwBestIfIndex )
{
memcpy( pAdapter, pIfTable->Adapter, sizeof(IP_ADAPTER_INDEX_MAP) );
hr = S_OK;
break;
}
}
}
delete [] (BYTE *)pIfTable;
}
else
{
TraceMsg(TF_ERROR, "new Failed!" );
break;
}
if ( ERROR_INSUFFICIENT_BUFFER != dwErr )
break;
}
}
else
{
TraceMsg(TF_ERROR, "GetBestInterface Failed = %lx", dwErr);
}
TraceMsg(TF_ALWAYS, "HrGetBestAdapter = %lx", hr);
return hr;
}
HRESULT HrCheckForAdapterMatch(
INetConnection* pConnection,
PIP_ADAPTER_INDEX_MAP pAdapter,
BOOL* pfAssociated )
//+---------------------------------------------------------------------------
//
// Function: HrCheckForAdapterMatch
//
// Purpose:
//
// Arguments:
//
// Returns: S_OK on success, otherwise an error code
//
// Notes:
//
{
HRESULT hr;
NETCON_PROPERTIES* pProps;
ASSERT( pConnection );
ASSERT( pAdapter );
ASSERT( pfAssociated );
*pfAssociated = FALSE;
hr = pConnection->GetProperties( &pProps );
if ( SUCCEEDED(hr) )
{
OLECHAR szwGuid[ GUID_LENGTH + 1 ];
if ( StringFromGUID2( pProps->guidId, szwGuid, GUID_LENGTH+1 ) )
{
long index = wcslen( pAdapter->Name ) - wcslen( szwGuid );
ASSERT( 0 <= index );
WCHAR* pszwGuidName = &(pAdapter->Name[index]);
TraceMsg(TF_ALWAYS, " - %s", szwGuid );
TraceMsg(TF_ALWAYS, " - %s", pszwGuidName );
if ( ( wcscmp( szwGuid, pszwGuidName ) == 0 ) )
{
TraceMsg(TF_ALWAYS, " FOUNT IT! %s", pProps->pszwName );
*pfAssociated = TRUE;
}
}
NcFreeNetconProperties( pProps );
}
TraceMsg(TF_ALWAYS, "HrCheckForAdapterMatch = %lx", hr);
return hr;
}
HRESULT HrCheckListForMatch(
INetConnection* pConnection,
IPAddr IpAddress,
LPHOSTENT pHostEnt,
BOOL* pfAssociated )
//+---------------------------------------------------------------------------
//
// Function: HrCheckListForMatch
//
// Purpose:
//
// Arguments:
//
// Returns: S_OK on success, otherwise an error code
//
// Notes:
//
{
// If IpAdress or pHostEnt->h_addr INADDR_NONE then the HRESULT is still successful
HRESULT hr = S_OK;
ASSERT( pConnection );
ASSERT( pfAssociated );
IP_ADAPTER_INDEX_MAP Adapter;
*pfAssociated = FALSE;
if ( NULL != pHostEnt )
{
int i;
for ( i=0; pHostEnt->h_addr_list[i]; i++ )
{
IpAddress = *(IPAddr *)(pHostEnt->h_addr_list[i]);
if ( INADDR_NONE != IpAddress )
{
hr = HrGetBestAdapter( IpAddress, &Adapter );
if ( SUCCEEDED(hr) )
{
hr = HrCheckForAdapterMatch( pConnection, &Adapter, pfAssociated );
if ( *pfAssociated )
break;
}
}
}
}
else
{
if ( INADDR_NONE != IpAddress )
{
// The name was an ip address
hr = HrGetBestAdapter( IpAddress, &Adapter );
if ( SUCCEEDED(hr) )
{
hr = HrCheckForAdapterMatch( pConnection, &Adapter, pfAssociated );
}
}
}
TraceMsg(TF_ALWAYS, "HrCheckListForMatch = %lx", hr);
return hr;
}
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;
}
}
}
TraceMsg(TF_ALWAYS, "HrInternalGetAdapterInfo = %lx Info = %lx", hr, *ppAdapter);
return hr;
}
HRESULT HrGetAdapterInfo(
INetConnection* pConnection,
PIP_ADAPTER_INFO* ppAdapter
)
//+---------------------------------------------------------------------------
//
// Function: HrGetAdapterInfo
//
// Purpose:
//
// Arguments: INetConnection* pConnection
// PIP_ADAPTER_INFO* ppAdapter
//
// Returns: HRESULT
//
// Author: billi 12/02/01
//
// Notes:
//
{
HRESULT hr;
NETCON_PROPERTIES* pProps;
ASSERT( pConnection );
ASSERT( ppAdapter );
*ppAdapter = NULL;
hr = pConnection->GetProperties( &pProps );
if ( SUCCEEDED(hr) )
{
OLECHAR szwGuid[ GUID_LENGTH + 1 ];
hr = E_FAIL; // assume failure
if ( StringFromGUID2( pProps->guidId, szwGuid, GUID_LENGTH+1 ) )
{
char* szGuid = NULL;
hr = HrWideCharToMultiByte( szwGuid, &szGuid );
if ( SUCCEEDED(hr) )
{
PIP_ADAPTER_INFO pInfo;
TraceMsg(TF_ALWAYS, "%S:", szGuid);
hr = HrInternalGetAdapterInfo( &pInfo );
if ( SUCCEEDED(hr) )
{
PIP_ADAPTER_INFO pAdapter = pInfo;
hr = E_FAIL; // Assume the loop fails...
while ( pAdapter )
{
TraceMsg(TF_ALWAYS, " %S", pAdapter->AdapterName);
if ( ( strcmp( szGuid, pAdapter->AdapterName ) == 0 ) )
{
TraceMsg(TF_ALWAYS, " Found It!");
PIP_ADAPTER_INFO pBuf = new IP_ADAPTER_INFO;
if ( NULL != pBuf )
{
memcpy( pBuf, pAdapter, sizeof(IP_ADAPTER_INFO) );
*ppAdapter = pBuf;
hr = S_OK;
break;
}
} // if ( ( strcmp( szGuid, pAdapter->AdapterName ) == 0 ) )
pAdapter = pAdapter->Next;
} // while ( pAdapter )
if ( NULL == *ppAdapter )
{
hr = HrFromWin32Error( ERROR_FILE_NOT_FOUND );
}
delete pInfo;
} // if ( SUCCEEDED(hr) )
delete [] szGuid;
} // if ( SUCCEEDED(hr) )
} // if ( StringFromGUID2( pProps->guidId, szwGuid, GUID_LENGTH+1 ) )
NcFreeNetconProperties( pProps );
} // if ( SUCCEEDED(hr) )
TraceMsg(TF_ALWAYS, "HrGetAdapterInfo = %lx Info = %lx", hr, *ppAdapter);
return hr;
}
HRESULT HrGetHostByAddr(
IPAddr IpAddress,
WCHAR** ppszHost,
PDWORD pdwSize
)
//+---------------------------------------------------------------------------
//
// Function: HrGetHostByAddr
//
// Purpose:
//
// Arguments:
//
// Returns: HRESULT
//
// Author: billi 05/08/01
//
// Notes:
//
{
HRESULT hr = E_INVALIDARG;
if ( ppszHost )
*ppszHost = 0;
if ( pdwSize )
*pdwSize = 0;
if ( INADDR_NONE != IpAddress )
{
LPHOSTENT pHostEnt = gethostbyaddr( (char*)&IpAddress, sizeof(IPAddr), AF_INET );
int iErr = WSAGetLastError();
switch ( iErr )
{
case WSANOTINITIALISED:
case WSAENETDOWN:
case WSANO_RECOVERY:
case WSAEFAULT:
hr = E_FAIL;
break;
case NO_ERROR:
hr = S_OK;
ASSERT( pHostEnt );
break;
case WSAHOST_NOT_FOUND:
default:
hr = S_FALSE;
break;
}
if ( SUCCEEDED(hr) && pHostEnt && pHostEnt->h_name && ppszHost && pdwSize )
{
char* pName = pHostEnt->h_name;
int iLen = strlen( pName ) + 1;
DWORD dwSize = 0;
dwSize = MultiByteToWideChar( CP_ACP, 0, pName, iLen, NULL, 0 );
if ( dwSize > 0 )
{
WCHAR* pszName = new WCHAR[ ++dwSize ];
if ( pszName )
{
if ( MultiByteToWideChar( CP_ACP, 0, pName, iLen, pszName, dwSize ) == 0 )
{
hr = HrFromLastWin32Error();
*ppszHost = 0;
delete [] pszName;
}
else
{
*pdwSize = dwSize;
*ppszHost = pszName;
}
}
else
{
hr = E_OUTOFMEMORY;
}
} // if ( dwSize > 0 )
else
{
TraceMsg(TF_ERROR, " MultiByteToWideChar returned %lx wchars", dwSize );
}
TraceMsg(TF_ALWAYS, " %lx: %S", IpAddress, pHostEnt->h_name, pHostEnt->h_name );
} // if ( SUCCEEDED(hr) && ...
} // if ( INADDR_NONE != IpAddress )
TraceMsg(TF_ALWAYS, "HrGetHostByAddr = %lx", hr);
return hr;
}
HRESULT HrSendArp(
INetConnection* pConnection,
IPAddr DestIp,
PULONG pMacAddr,
PULONG pAddrLen
)
//+---------------------------------------------------------------------------
//
// Function: HrSendArp
//
// Purpose:
//
// Arguments:
//
// Returns: HRESULT
//
// Author: billi 05/08/01
//
// Notes:
//
{
HRESULT hr = E_POINTER;
ASSERT( pMacAddr );
ASSERT( pAddrLen );
if ( pMacAddr ) *pMacAddr = 0L;
if ( pMacAddr && pAddrLen )
{
hr = E_INVALIDARG;
if ( pConnection && ( INADDR_NONE != DestIp ) )
{
PIP_ADAPTER_INFO pAdapter;
hr = HrGetAdapterInfo( pConnection, &pAdapter );
if ( NULL == pAdapter )
{
hr = E_FAIL;
}
if ( SUCCEEDED(hr) )
{
hr = E_FAIL;
// Make sure the target IP address isn't already cached,
// by removing it from the ARP cache if present using the interface index
// determined above.
MIB_IPNETROW IpNetRow;
CHAR HardwareAddress[MAXLEN_PHYSADDR];
ULONG HardwareAddressLength;
ULONG SrcIp;
DWORD dwRet;
SrcIp = inet_addr( pAdapter->IpAddressList.IpAddress.String );
ZeroMemory( &IpNetRow, sizeof(IpNetRow) );
IpNetRow.dwIndex = pAdapter->Index;
IpNetRow.dwPhysAddrLen = MAXLEN_PHYSADDR;
IpNetRow.dwAddr = DestIp;
IpNetRow.dwType = MIB_IPNET_TYPE_INVALID;
dwRet = DeleteIpNetEntry( &IpNetRow );
TraceMsg( TF_ALWAYS, "SendArp: DestIp = %lu SrcIp = %lu Ret = %lx", DestIp, SrcIp, dwRet );
if ( ( INADDR_NONE != SrcIp ) && ( NO_ERROR == dwRet ) )
{
HardwareAddressLength = MAXLEN_PHYSADDR;
if ( SendARP( DestIp, SrcIp, (PULONG)HardwareAddress, &HardwareAddressLength ) == NO_ERROR )
{
hr = S_OK;
if ( HardwareAddressLength < *pAddrLen )
{
*pAddrLen = HardwareAddressLength;
}
memcpy( pMacAddr, HardwareAddress, *pAddrLen );
}
TraceMsg(TF_ALWAYS, "\t%02x %02x %02x %02x %02x %02x Len=%lu",
HardwareAddress[0] & 0x0ff,
HardwareAddress[1] & 0x0ff,
HardwareAddress[2] & 0x0ff,
HardwareAddress[3] & 0x0ff,
HardwareAddress[4] & 0x0ff,
HardwareAddress[5] & 0x0ff,
*pAddrLen);
}
delete pAdapter;
} // if ( SUCCEEDED(hr) )
} // if ( pConnection && ( INADDR_NONE != DestIp ) )
} // if ( pMacAddr && pAddrLen )
TraceMsg( TF_ALWAYS, "HrSendArp = %lx", hr );
return hr;
}
HRESULT HrLookupForIpAddress(
INetConnection* pConnection,
IPAddr IpAddress,
BOOL* pfExists,
WCHAR** ppszHost,
PDWORD pdwSize
)
//+---------------------------------------------------------------------------
//
// Function: HrLookupForIpAddress
//
// Purpose:
//
// Arguments:
//
// Returns: HRESULT
//
// Author: billi 12/02/01
//
// Notes:
//
{
HRESULT hr = E_POINTER;
ASSERT( pfExists );
ASSERT( pConnection );
ASSERT( INADDR_NONE != IpAddress );
if ( ppszHost && *ppszHost ) *ppszHost = NULL;
if ( pdwSize ) *pdwSize = NULL;
if ( pfExists )
{
hr = E_INVALIDARG;
*pfExists = FALSE;
if ( pConnection && ( INADDR_NONE != IpAddress ) )
{
WSADATA WsaData;
int iErr;
iErr = WSAStartup( MAKEWORD(2, 0), &WsaData );
if ( ERROR_SUCCESS == iErr )
{
// This is taking to long and No One is using the host name in the wizard.
// hr = HrGetHostByAddr( IpAddress, ppszHost, pdwSize );
hr = S_OK;
if ( S_OK == hr )
{
CHAR MacAddr[6];
ULONG ulAddrLen = 6L;
hr = HrSendArp( pConnection, IpAddress, (PULONG)MacAddr, &ulAddrLen );
if ( SUCCEEDED(hr) && ulAddrLen )
{
*pfExists = TRUE;
}
}
else if ( S_FALSE == hr )
{
hr = S_OK;
*pfExists = FALSE;
}
WSACleanup();
} // if ( ERROR_SUCCESS == iErr )
else
{
TraceMsg(TF_ERROR, "WSAStartup Failed = %lu", iErr );
hr = E_FAIL;
}
} // if ( pConnection && ( INADDR_NONE != IpAddress ) )
} // if ( pfExists )
TraceMsg(TF_ALWAYS, "HrLookupForIpAddress = %lx, Exists = %lx", hr, *pfExists);
return hr;
}