Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

434 lines
16 KiB

//////////////////////////////////////////////////////////////////////////////
//
// 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