435 lines
16 KiB
C++
435 lines
16 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2000-2001 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// NameUtil.cpp
|
|
//
|
|
// Description:
|
|
// Name resolution utility.
|
|
//
|
|
// Maintained By:
|
|
// Galen Barbee (GalenB) 28-NOV-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pch.h"
|
|
#include "nameutil.h"
|
|
|
|
#include <initguid.h>
|
|
|
|
// {6968D735-ADBB-4748-A36E-7CEE0FE21116}
|
|
DEFINE_GUID( TASKID_Minor_Multiple_DNS_Records_Found,
|
|
0x6968d735, 0xadbb, 0x4748, 0xa3, 0x6e, 0x7c, 0xee, 0xf, 0xe2, 0x11, 0x16);
|
|
|
|
// {D86FAAD9-2514-451e-B359-435AF35E6038}
|
|
DEFINE_GUID( TASKID_Minor_FQDN_DNS_Binding_Succeeded,
|
|
0xd86faad9, 0x2514, 0x451e, 0xb3, 0x59, 0x43, 0x5a, 0xf3, 0x5e, 0x60, 0x38);
|
|
|
|
// {B2359972-F6B8-433d-949B-DB1CEE009321}
|
|
DEFINE_GUID( TASKID_Minor_FQDN_DNS_Binding_Failed,
|
|
0xb2359972, 0xf6b8, 0x433d, 0x94, 0x9b, 0xdb, 0x1c, 0xee, 0x0, 0x93, 0x21);
|
|
|
|
// {2FF4B2F0-800C-44db-9131-F60B30F76CB4}
|
|
DEFINE_GUID( TASKID_Minor_NETBIOS_Binding_Failed,
|
|
0x2ff4b2f0, 0x800c, 0x44db, 0x91, 0x31, 0xf6, 0xb, 0x30, 0xf7, 0x6c, 0xb4);
|
|
|
|
// {D40532E1-9286-4dbd-A559-B62DCC218929}
|
|
DEFINE_GUID( TASKID_Minor_NETBIOS_Binding_Succeeded,
|
|
0xd40532e1, 0x9286, 0x4dbd, 0xa5, 0x59, 0xb6, 0x2d, 0xcc, 0x21, 0x89, 0x29);
|
|
|
|
// {D0AB3284-8F62-4f55-8938-DA6A583604E0}
|
|
DEFINE_GUID( TASKID_Minor_NETBIOS_Name_Conversion_Succeeded,
|
|
0xd0ab3284, 0x8f62, 0x4f55, 0x89, 0x38, 0xda, 0x6a, 0x58, 0x36, 0x4, 0xe0);
|
|
|
|
// {66F8E4AA-DF71-4973-A4A3-115EB6FE9986}
|
|
DEFINE_GUID( TASKID_Minor_NETBIOS_Name_Conversion_Failed,
|
|
0x66f8e4aa, 0xdf71, 0x4973, 0xa4, 0xa3, 0x11, 0x5e, 0xb6, 0xfe, 0x99, 0x86);
|
|
|
|
// {5F18ED71-07EC-46d3-ADB9-71F1C7794DB2}
|
|
DEFINE_GUID( TASKID_Minor_NETBIOS_Reset_Failed,
|
|
0x5f18ed71, 0x7ec, 0x46d3, 0xad, 0xb9, 0x71, 0xf1, 0xc7, 0x79, 0x4d, 0xb2);
|
|
|
|
// {A6DCB5E1-1FDF-4c94-ADBA-EE18F72B8197}
|
|
DEFINE_GUID( TASKID_Minor_NETBIOS_LanaEnum_Failed,
|
|
0xa6dcb5e1, 0x1fdf, 0x4c94, 0xad, 0xba, 0xee, 0x18, 0xf7, 0x2b, 0x81, 0x97);
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// HRESULT
|
|
// HrCreateBinding(
|
|
// IClusCfgCallback * pcccbIn,
|
|
// CLSID * pclsidLogIn,
|
|
// BSTR bstrNameIn,
|
|
// BSTR * pbstrBindingOut
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
HrCreateBinding(
|
|
IClusCfgCallback * pcccbIn,
|
|
const CLSID * pclsidLogIn,
|
|
BSTR bstrNameIn,
|
|
BSTR * pbstrBindingOut
|
|
)
|
|
{
|
|
TraceFunc1( "bstrNameIn = '%ws'", bstrNameIn );
|
|
|
|
DNS_STATUS status;
|
|
DWORD cch;
|
|
BOOL bRet;
|
|
bool fMadeNetBIOSName = false;
|
|
WCHAR szNetBIOSName[ MAX_COMPUTERNAME_LENGTH + 1 ];
|
|
UCHAR rgucNameBufer[ sizeof( FIND_NAME_HEADER ) + sizeof( FIND_NAME_BUFFER ) ];
|
|
NCB ncb;
|
|
LANA_ENUM leLanaEnum;
|
|
UCHAR idx;
|
|
|
|
FIND_NAME_HEADER * pfnh = (FIND_NAME_HEADER *) &rgucNameBufer[ 0 ];
|
|
FIND_NAME_BUFFER * pfnb = (FIND_NAME_BUFFER *) &rgucNameBufer[ sizeof( FIND_NAME_HEADER ) ];
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
PDNS_RECORD pResults = NULL;
|
|
|
|
BSTR bstrNotification = NULL;
|
|
BSTR bstrNetBiosName = NULL;
|
|
|
|
Assert( bstrNameIn != NULL );
|
|
Assert( pbstrBindingOut != NULL );
|
|
Assert( *pbstrBindingOut == NULL );
|
|
|
|
status = DnsQuery( bstrNameIn, DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &pResults, NULL );
|
|
if ( status == ERROR_SUCCESS )
|
|
{
|
|
LPSTR pszIP;
|
|
|
|
pszIP = inet_ntoa( * (struct in_addr *) &pResults->Data.A.IpAddress );
|
|
|
|
*pbstrBindingOut = TraceSysAllocStringLen( NULL, (UINT) strlen( pszIP ) + 1 );
|
|
if ( *pbstrBindingOut == NULL )
|
|
goto OutOfMemory;
|
|
|
|
mbstowcs( *pbstrBindingOut, pszIP, strlen( pszIP ) + 1 );
|
|
|
|
if ( pResults->pNext != NULL )
|
|
{
|
|
if ( pcccbIn != NULL )
|
|
{
|
|
THR( HrFormatStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_MULTIPLE_DNS_RECORDS_FOUND, &bstrNotification, bstrNameIn ) );
|
|
|
|
hr = THR( pcccbIn->SendStatusReport( bstrNameIn,
|
|
*pclsidLogIn,
|
|
TASKID_Minor_Multiple_DNS_Records_Found,
|
|
0,
|
|
1,
|
|
1,
|
|
S_FALSE,
|
|
bstrNotification,
|
|
NULL,
|
|
NULL
|
|
) );
|
|
// ignore error
|
|
}
|
|
}
|
|
|
|
if ( pcccbIn != NULL )
|
|
{
|
|
THR( HrFormatStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_FQDN_DNS_BINDING_SUCCEEDED, &bstrNotification, bstrNameIn, *pbstrBindingOut ) );
|
|
|
|
hr = THR( pcccbIn->SendStatusReport( bstrNameIn,
|
|
*pclsidLogIn,
|
|
TASKID_Minor_FQDN_DNS_Binding_Succeeded,
|
|
0,
|
|
1,
|
|
1,
|
|
S_OK,
|
|
bstrNotification,
|
|
NULL,
|
|
NULL
|
|
) );
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
goto Cleanup; // done!
|
|
} // if: DnsQuery() succeeded
|
|
else if ( status == DNS_ERROR_RCODE_NAME_ERROR )
|
|
{
|
|
if ( pcccbIn != NULL )
|
|
{
|
|
THR( HrFormatStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_FQDN_DNS_BINDING_FAILED, &bstrNotification, bstrNameIn ) );
|
|
|
|
hr = THR( pcccbIn->SendStatusReport( bstrNameIn,
|
|
TASKID_Major_Client_And_Server_Log,
|
|
TASKID_Minor_FQDN_DNS_Binding_Failed,
|
|
0,
|
|
1,
|
|
1,
|
|
MAKE_HRESULT( 0, FACILITY_WIN32, status ),
|
|
bstrNotification,
|
|
NULL,
|
|
NULL
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
}
|
|
|
|
cch = ARRAYSIZE( szNetBIOSName );
|
|
Assert( cch == MAX_COMPUTERNAME_LENGTH + 1 );
|
|
bRet = DnsHostnameToComputerName( bstrNameIn, szNetBIOSName, &cch );
|
|
if ( !bRet )
|
|
{
|
|
hr = MAKE_HRESULT( 0, FACILITY_WIN32, TW32( GetLastError() ) );
|
|
|
|
if ( pcccbIn != NULL )
|
|
{
|
|
THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_NETBIOS_NAME_CONVERSION_FAILED, &bstrNotification ) );
|
|
|
|
hr = THR( pcccbIn->SendStatusReport( bstrNameIn,
|
|
*pclsidLogIn,
|
|
TASKID_Minor_NETBIOS_Name_Conversion_Failed,
|
|
0,
|
|
1,
|
|
1,
|
|
hr,
|
|
bstrNotification,
|
|
NULL,
|
|
NULL
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
}
|
|
|
|
goto SkipNetBios;
|
|
}
|
|
|
|
bstrNetBiosName = TraceSysAllocString( szNetBIOSName );
|
|
if ( bstrNetBiosName == NULL )
|
|
goto OutOfMemory;
|
|
|
|
if ( pcccbIn != NULL )
|
|
{
|
|
THR( HrFormatStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_NETBIOS_NAME_CONVERSION_SUCCEEDED, &bstrNotification, bstrNameIn, bstrNetBiosName ) );
|
|
|
|
hr = THR( pcccbIn->SendStatusReport( bstrNameIn,
|
|
TASKID_Major_Client_And_Server_Log,
|
|
TASKID_Minor_NETBIOS_Name_Conversion_Succeeded,
|
|
0,
|
|
1,
|
|
1,
|
|
S_OK,
|
|
bstrNotification,
|
|
NULL,
|
|
NULL
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Try to find the name using NetBIOS.
|
|
//
|
|
|
|
ZeroMemory( &ncb, sizeof( ncb ) );
|
|
|
|
//
|
|
// Enumerate the network adapters
|
|
//
|
|
ncb.ncb_command = NCBENUM; // Enumerate LANA nums (wait)
|
|
ncb.ncb_buffer = (PUCHAR) &leLanaEnum;
|
|
ncb.ncb_length = sizeof( LANA_ENUM );
|
|
|
|
Netbios( &ncb );
|
|
if ( ncb.ncb_retcode != NRC_GOODRET )
|
|
{
|
|
hr = MAKE_HRESULT( 0, FACILITY_NULL, ncb.ncb_retcode );
|
|
|
|
if ( pcccbIn != NULL )
|
|
{
|
|
THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_NETBIOS_LANAENUM_FAILED, &bstrNotification ) );
|
|
|
|
hr = THR( pcccbIn->SendStatusReport( bstrNameIn,
|
|
TASKID_Major_Client_And_Server_Log,
|
|
TASKID_Minor_NETBIOS_LanaEnum_Failed,
|
|
0,
|
|
1,
|
|
1,
|
|
hr,
|
|
bstrNotification,
|
|
NULL,
|
|
NULL
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
goto SkipNetBios;
|
|
} // if:
|
|
|
|
//
|
|
// Reset each adapter and try to find the name.
|
|
//
|
|
for ( idx = 0; idx < leLanaEnum.length; idx++ )
|
|
{
|
|
//
|
|
// Reset the adapter
|
|
//
|
|
ncb.ncb_command = NCBRESET;
|
|
ncb.ncb_lana_num = leLanaEnum.lana[ idx ];
|
|
|
|
Netbios( &ncb );
|
|
if ( ncb.ncb_retcode != NRC_GOODRET )
|
|
{
|
|
hr = MAKE_HRESULT( 0, FACILITY_NULL, ncb.ncb_retcode );
|
|
|
|
if ( pcccbIn != NULL )
|
|
{
|
|
THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_NETBIOS_RESET_FAILED, &bstrNotification ) );
|
|
|
|
hr = THR( pcccbIn->SendStatusReport( bstrNameIn,
|
|
TASKID_Major_Client_And_Server_Log,
|
|
TASKID_Minor_NETBIOS_Reset_Failed,
|
|
0,
|
|
1,
|
|
1,
|
|
hr,
|
|
bstrNotification,
|
|
NULL,
|
|
NULL
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Continue with the next adapter.
|
|
//
|
|
continue;
|
|
}
|
|
|
|
ncb.ncb_command = NCBFINDNAME;
|
|
ncb.ncb_buffer = rgucNameBufer;
|
|
ncb.ncb_length = sizeof( rgucNameBufer );
|
|
|
|
pfnh->node_count = 1;
|
|
|
|
// Fill with spaces
|
|
memset( ncb.ncb_callname, 32, sizeof( ncb.ncb_callname ) );
|
|
|
|
wcstombs( (CHAR *) ncb.ncb_callname, szNetBIOSName, wcslen( szNetBIOSName ) );
|
|
|
|
Netbios( &ncb );
|
|
|
|
if ( ncb.ncb_retcode == NRC_GOODRET )
|
|
{
|
|
LPSTR pszIP;
|
|
struct in_addr sin;
|
|
|
|
sin.S_un.S_addr = *((u_long UNALIGNED *) &pfnb->source_addr[ 2 ]);
|
|
|
|
pszIP = inet_ntoa( sin );
|
|
|
|
*pbstrBindingOut = TraceSysAllocStringLen( NULL, (UINT) strlen( pszIP ) + 1 );
|
|
if ( *pbstrBindingOut == NULL )
|
|
goto OutOfMemory;
|
|
|
|
mbstowcs( *pbstrBindingOut, pszIP, strlen( pszIP ) + 1 );
|
|
|
|
if ( pcccbIn != NULL )
|
|
{
|
|
THR( HrFormatStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_NETBIOS_BINDING_SUCCEEDED, &bstrNotification, bstrNetBiosName, *pbstrBindingOut ) );
|
|
|
|
hr = THR( pcccbIn->SendStatusReport( bstrNameIn,
|
|
*pclsidLogIn,
|
|
TASKID_Minor_NETBIOS_Binding_Succeeded,
|
|
0,
|
|
1,
|
|
1,
|
|
S_OK,
|
|
bstrNotification,
|
|
NULL,
|
|
NULL
|
|
) );
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
fMadeNetBIOSName = true;
|
|
break; // done!
|
|
}
|
|
|
|
hr = MAKE_HRESULT( 0, FACILITY_NULL, ncb.ncb_retcode );
|
|
|
|
if ( pcccbIn != NULL )
|
|
{
|
|
THR( HrFormatStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_NETBIOS_BINDING_FAILED, &bstrNotification, bstrNameIn ) );
|
|
|
|
hr = THR( pcccbIn->SendStatusReport( bstrNameIn,
|
|
TASKID_Major_Client_And_Server_Log,
|
|
TASKID_Minor_NETBIOS_Binding_Failed,
|
|
0,
|
|
1,
|
|
1,
|
|
hr,
|
|
bstrNotification,
|
|
NULL,
|
|
NULL
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
} // if:
|
|
} // for:
|
|
|
|
if ( fMadeNetBIOSName )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
} // else if:
|
|
else
|
|
{
|
|
TW32( status );
|
|
} // else:
|
|
|
|
SkipNetBios:
|
|
//
|
|
// If all else fails, use the name and attempt to bind to it.
|
|
//
|
|
|
|
*pbstrBindingOut = TraceSysAllocString( bstrNameIn );
|
|
if ( *pbstrBindingOut == NULL )
|
|
goto OutOfMemory;
|
|
|
|
hr = S_FALSE;
|
|
goto Cleanup;
|
|
|
|
Cleanup:
|
|
#ifdef DEBUG
|
|
if ( FAILED( hr ) )
|
|
{
|
|
Assert( *pbstrBindingOut == NULL );
|
|
}
|
|
#endif
|
|
|
|
TraceSysFreeString( bstrNotification );
|
|
TraceSysFreeString( bstrNetBiosName );
|
|
|
|
if ( pResults != NULL )
|
|
{
|
|
DnsRecordListFree( pResults, DnsFreeRecordListDeep );
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
OutOfMemory:
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
|
|
} //*** HrCreateBinding
|