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