Leaked source code of windows server 2003
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.
 
 
 
 
 
 

261 lines
8.2 KiB

/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2002 Microsoft Corporation
//
// Module Name:
// GetComputerNameSrc.cpp
//
// Description:
// Getting and setting the computer name.
//
// Maintained By:
// Galen Barbee (GalenB) 31-MAR-2000
//
// Revision History:
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
// #include <Pch.h> // should be included by includer of this file
#include <StrSafe.h> // in case it isn't included by header file
/////////////////////////////////////////////////////////////////////////////
//++
//
// HrGetComputerName
//
// Description:
// Get name of the computer on which this object is present.
//
// Arguments:
// cnfIn
// Code representing type of information to return.
//
// pbstrComputerNameOut
// Buffer pointer for returning the computer or domain name.
// Caller must deallocate this buffer using TraceSysFreeString.
//
// fBestEffortIn
// TRUE = Attempt to return something even if DC is unavailable.
// FALSE = Return all failures.
//
// Return Value:
// S_OK
// Success.
//
// Remarks:
// DsGetDCName is used to get the domain name instead of just letting
// GetComputerNameEx get it so that pre-Windows 2000 domains can be
// supported. In a pre-Windows 2000 domain, GetComputerNameEx will not
// return an FQDN or a domain name if that is what has been request.
// To support this scenario, this routine gets the domain name using
// DsGetDCName, gets the hostname label, then constructs the final name
// using <computername>.<DomainName>.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
WINAPI
HrGetComputerName(
COMPUTER_NAME_FORMAT cnfIn
, BSTR * pbstrComputerNameOut
, BOOL fBestEffortIn
)
{
TraceFunc( "" );
HRESULT hr = S_OK;
DWORD sc;
size_t cchComputerName = 0;
size_t cchBuffer = 0;
BSTR bstrComputerName = NULL;
BOOL fAppendDomain = FALSE;
BOOL fSuccess;
PDOMAIN_CONTROLLER_INFO pdci = NULL;
if ( pbstrComputerNameOut == NULL )
{
hr = THR( E_POINTER );
goto Cleanup;
} // if:
*pbstrComputerNameOut = NULL;
//
// Only get the domain name when there is a reason to get the domain name.
//
if ( ( cnfIn == ComputerNameDnsFullyQualified )
|| ( cnfIn == ComputerNamePhysicalDnsFullyQualified )
|| ( cnfIn == ComputerNameDnsDomain )
|| ( cnfIn == ComputerNamePhysicalDnsDomain )
)
{
//
// DsGetDcName will give us access to a usable domain name, regardless of whether we are
// currently in a W2k or a NT4 domain. On W2k and above, it will return a DNS domain name,
// on NT4 it will return a NetBIOS name.
//
sc = DsGetDcName(
NULL // ComputerName
, NULL // DomainName
, NULL // DomainGuid
, NULL // SiteName
, DS_DIRECTORY_SERVICE_PREFERRED
, &pdci
);
if ( ( sc == ERROR_NO_SUCH_DOMAIN )
&& ( fBestEffortIn )
)
{
fAppendDomain = FALSE;
} // if: can't reach a DC
else if ( sc != ERROR_SUCCESS )
{
TW32( sc );
hr = HRESULT_FROM_WIN32( sc );
goto Cleanup;
} // else if: DsGetDcName failed
else
{
//
// This handles the case when we are a member of a legacy (pre-W2k) Domain.
// In this case, both FQDN and DnsDomain will not receive useful data from GetComputerNameEx.
// What we actually want to get is <computername>.<DomainName> in every case.
//
switch ( cnfIn )
{
case ComputerNameDnsFullyQualified:
cnfIn = ComputerNameDnsHostname;
break;
case ComputerNamePhysicalDnsFullyQualified:
cnfIn = ComputerNamePhysicalDnsHostname;
break;
case ComputerNameDnsDomain:
case ComputerNamePhysicalDnsDomain:
*pbstrComputerNameOut = TraceSysAllocString( pdci->DomainName );
if ( *pbstrComputerNameOut == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
goto Cleanup;
} // switch: computer name format
fAppendDomain = TRUE;
} // else: DC contacted successfully
} // if: computer name format requires domain name
else
{
fAppendDomain = FALSE;
} // else: computer name format does not require domain name
//
// Get the computer name. First get the size of the output buffer,
// allocate a buffer, then get the name itself.
//
cchComputerName = 0;
fSuccess = GetComputerNameExW( cnfIn, NULL, reinterpret_cast< DWORD * >( &cchComputerName ) );
if ( fSuccess == FALSE )
{
cchBuffer = cchComputerName + 1;
//
// If error not buffer to small, we're done.
//
sc = GetLastError();
if ( sc != ERROR_MORE_DATA )
{
TW32( sc );
hr = HRESULT_FROM_WIN32( sc );
LogMsg( "GetComputerNameEx failed. sc = %1!#08x!", sc );
goto Cleanup;
} // if: error other than buffer too small
//
// Add on size of domain name and period separator.
//
if ( fAppendDomain )
{
// Add space for the domain name and the period separator.
cchBuffer += wcslen( pdci->DomainName ) + 1;
} // if: appending domain name to computer name
//
// Allocate the output buffer.
//
bstrComputerName = TraceSysAllocStringLen( L"", static_cast< unsigned int >( cchBuffer ) );
if ( bstrComputerName == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if: error allocating buffer for name
//
// Get the computer name into the output buffer.
//
fSuccess = GetComputerNameExW( cnfIn, bstrComputerName, reinterpret_cast< DWORD * >( &cchComputerName ) );
if ( fSuccess == FALSE )
{
sc = TW32( GetLastError() );
hr = HRESULT_FROM_WIN32( sc );
LogMsg( "GetComputerNameEx failed. sc = %1!#08x!", sc );
goto Cleanup;
} // if: error getting the computer name
//
// Append the period separator and domain name onto the computer name.
//
if ( fAppendDomain )
{
// Append a dot (.) and the domain name after the computer name.
hr = THR( StringCchCatW( bstrComputerName, cchBuffer, L"." ) );
if ( SUCCEEDED( hr ) )
{
hr = THR( StringCchCatW( bstrComputerName, cchBuffer, pdci->DomainName ) );
}
if ( FAILED( hr ) )
{
LogMsg( "Error concatenating domain name, hr = %1!#08x!", hr );
goto Cleanup;
}
} // if: appending domain name to computer name
//
// Set output buffer pointer.
//
*pbstrComputerNameOut = bstrComputerName;
bstrComputerName = NULL;
} // if: error getting computer name
else
{
AssertMsg( fSuccess == FALSE, "Expected GetComputerNameEx to fail with null buffer" );
} // else: GetComputerNameEx didn't fail as expected
Cleanup:
TraceSysFreeString( bstrComputerName );
if ( pdci != NULL )
{
NetApiBufferFree( pdci );
} // if:
HRETURN( hr );
} //*** HrGetComputerName