896 lines
19 KiB
C
896 lines
19 KiB
C
/*++
|
||
|
||
Copyright (c) 2000-2001 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
hostfile.c
|
||
|
||
Abstract:
|
||
|
||
Read host file data.
|
||
|
||
Author:
|
||
|
||
Jim Gilroy (jamesg) October 2000
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
#include "local.h"
|
||
|
||
// sockreg.h includes "etc" directory file opens
|
||
// sockreg.h is NT file so must define NTSTATUS first
|
||
|
||
#ifndef NTSTATUS
|
||
#define NTSTATUS LONG
|
||
#endif
|
||
|
||
#include <sockreg.h>
|
||
|
||
//
|
||
// Host file defs
|
||
// Note, HOST_FILE_INFO blob defined in dnsapip.h
|
||
//
|
||
|
||
#define HOST_FILE_PATH_LENGTH (MAX_PATH + sizeof("\\hosts") + 1)
|
||
|
||
//
|
||
// Host file record TTL
|
||
// (use a week)
|
||
//
|
||
|
||
#define HOSTFILE_RECORD_TTL (604800)
|
||
|
||
|
||
|
||
|
||
BOOL
|
||
Dns_OpenHostFile(
|
||
IN OUT PHOST_FILE_INFO pHostInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Open hosts file or rewind existing file to beginning.
|
||
|
||
Arguments:
|
||
|
||
pHostInfo - ptr to host info;
|
||
|
||
hFile - must be NULL if file not previously opened
|
||
otherwise hFile is assumed to be existing FILE pointer
|
||
|
||
pszFileName - NULL to open "hosts" file
|
||
otherwise is name of file to open
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
CHAR hostFileNameBuffer[ HOST_FILE_PATH_LENGTH ];
|
||
|
||
DNSDBG( TRACE, (
|
||
"Dns_OpenHostFile()\n" ));
|
||
|
||
//
|
||
// open host file OR rewind if already open
|
||
//
|
||
|
||
if ( pHostInfo->hFile == NULL )
|
||
{
|
||
PSTR pnameFile = pHostInfo->pszFileName;
|
||
|
||
if ( !pnameFile )
|
||
{
|
||
pnameFile = "hosts";
|
||
}
|
||
|
||
pHostInfo->hFile = SockOpenNetworkDataBase(
|
||
pnameFile,
|
||
hostFileNameBuffer,
|
||
HOST_FILE_PATH_LENGTH,
|
||
"r" );
|
||
}
|
||
else
|
||
{
|
||
rewind( pHostInfo->hFile );
|
||
}
|
||
|
||
return ( pHostInfo->hFile ? TRUE : FALSE );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
Dns_CloseHostFile(
|
||
IN OUT PHOST_FILE_INFO pHostInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Close hosts file.
|
||
|
||
Arguments:
|
||
|
||
pHostInfo -- ptr to host info; hFile assumed to contain file pointer
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
DNSDBG( TRACE, (
|
||
"Dns_CloseHostFile()\n" ));
|
||
|
||
if ( pHostInfo->hFile )
|
||
{
|
||
fclose( pHostInfo->hFile );
|
||
pHostInfo->hFile = NULL;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
BuildHostfileRecords(
|
||
IN OUT PHOST_FILE_INFO pHostInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build records from hostfile line.
|
||
|
||
Arguments:
|
||
|
||
pHostInfo -- ptr to host info
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful.
|
||
FALSE on error.
|
||
|
||
--*/
|
||
{
|
||
DNS_LIST aliasList;
|
||
PCHAR * paliasEntry;
|
||
PCHAR palias;
|
||
PDNS_RECORD prr;
|
||
|
||
DNSDBG( TRACE, (
|
||
"BuildHostfileRecords()\n" ));
|
||
|
||
//
|
||
// create all the records
|
||
// - A or AAAA for name
|
||
// - CNAMEs for aliases
|
||
// - PTR
|
||
//
|
||
// for hosts file records
|
||
// - section == ANSWER
|
||
// - hostsfile flag set
|
||
//
|
||
|
||
prr = Dns_CreateForwardRecord(
|
||
pHostInfo->pHostName,
|
||
& pHostInfo->Ip,
|
||
HOSTFILE_RECORD_TTL,
|
||
DnsCharSetAnsi,
|
||
DnsCharSetUnicode );
|
||
|
||
pHostInfo->pForwardRR = prr;
|
||
if ( prr )
|
||
{
|
||
SET_RR_HOSTS_FILE( prr );
|
||
prr->Flags.S.Section = DnsSectionAnswer;
|
||
}
|
||
|
||
//
|
||
// build aliases into list of CNAME records
|
||
// - append forward lookup answer with each CNAME
|
||
//
|
||
|
||
DNS_LIST_STRUCT_INIT( aliasList );
|
||
|
||
for( paliasEntry = pHostInfo->AliasArray;
|
||
palias = *paliasEntry;
|
||
paliasEntry++ )
|
||
{
|
||
PDNS_RECORD prrForward = pHostInfo->pForwardRR;
|
||
PDNS_RECORD prrAnswer;
|
||
|
||
DNSDBG( INIT, (
|
||
"Building for alias %s for hostname %s\n",
|
||
palias,
|
||
pHostInfo->pHostName ));
|
||
|
||
prr = Dns_CreatePtrTypeRecord(
|
||
palias,
|
||
TRUE, // make name copy
|
||
pHostInfo->pHostName,
|
||
DNS_TYPE_CNAME,
|
||
HOSTFILE_RECORD_TTL,
|
||
DnsCharSetAnsi,
|
||
DnsCharSetUnicode );
|
||
if ( prr )
|
||
{
|
||
SET_RR_HOSTS_FILE( prr );
|
||
prr->Flags.S.Section = DnsSectionAnswer;
|
||
DNS_LIST_STRUCT_ADD( aliasList, prr );
|
||
|
||
// append forward record
|
||
|
||
if ( prrForward &&
|
||
(prrAnswer = Dns_RecordCopy_W(prrForward)) )
|
||
{
|
||
DNS_LIST_STRUCT_ADD( aliasList, prrAnswer );
|
||
}
|
||
}
|
||
}
|
||
|
||
pHostInfo->pAliasRR = aliasList.pFirst;
|
||
|
||
//
|
||
// PTR points only to name
|
||
//
|
||
|
||
prr = Dns_CreatePtrRecordEx(
|
||
& pHostInfo->Ip,
|
||
pHostInfo->pHostName, // target name
|
||
HOSTFILE_RECORD_TTL,
|
||
DnsCharSetAnsi,
|
||
DnsCharSetUnicode );
|
||
|
||
pHostInfo->pReverseRR = prr;
|
||
if ( prr )
|
||
{
|
||
SET_RR_HOSTS_FILE( prr );
|
||
prr->Flags.S.Section = DnsSectionAnswer;
|
||
}
|
||
|
||
IF_DNSDBG( QUERY )
|
||
{
|
||
DnsDbg_RecordSet(
|
||
"HostFile forward record:",
|
||
pHostInfo->pForwardRR );
|
||
|
||
DnsDbg_RecordSet(
|
||
"HostFile reverse record:",
|
||
pHostInfo->pReverseRR );
|
||
|
||
if ( pHostInfo->pAliasRR )
|
||
{
|
||
DnsDbg_RecordSet(
|
||
"HostFile alias records:",
|
||
pHostInfo->pAliasRR );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
TokenizeHostFileLine(
|
||
IN OUT PHOST_FILE_INFO pHostInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Reads an entry from hosts file.
|
||
|
||
Arguments:
|
||
|
||
pHostInfo -- ptr to host info;
|
||
if hFile is NULL, first attempts host file open
|
||
other fields are filled with info from next hostfile line
|
||
|
||
Return Value:
|
||
|
||
TRUE if successfully tokenized line.
|
||
FALSE on empty or bad line
|
||
|
||
--*/
|
||
{
|
||
PCHAR pch;
|
||
PCHAR ptoken;
|
||
DWORD countAlias = 0;
|
||
DWORD count = 0;
|
||
|
||
DNSDBG( TRACE, ( "TokenizeHostFileLine()\n" ));
|
||
|
||
//
|
||
// tokenize line
|
||
//
|
||
|
||
pch = pHostInfo->HostLineBuf;
|
||
|
||
while( pch )
|
||
{
|
||
// strip leading whitespace
|
||
|
||
while( *pch == ' ' || *pch == '\t' )
|
||
{
|
||
pch++;
|
||
}
|
||
ptoken = pch;
|
||
|
||
//
|
||
// NULL terminate token
|
||
// - NULL pch serves as signal to stop after this token
|
||
//
|
||
|
||
pch = strpbrk( pch, " \t#\n\r" );
|
||
if ( pch != NULL )
|
||
{
|
||
// empty (zero-length) token => done now
|
||
|
||
if ( pch == ptoken )
|
||
{
|
||
break;
|
||
}
|
||
|
||
// terminated by whitespace -- may be another token
|
||
|
||
if ( *pch == ' ' || *pch == '\t' )
|
||
{
|
||
*pch++ = '\0';
|
||
}
|
||
|
||
// terminated by EOL -- no more tokens
|
||
|
||
else // #\r\n
|
||
{
|
||
*pch = '\0';
|
||
pch = NULL;
|
||
}
|
||
}
|
||
count++;
|
||
|
||
//
|
||
// save address, name or alias
|
||
//
|
||
|
||
if ( count == 1 )
|
||
{
|
||
pHostInfo->pAddrString = ptoken;
|
||
}
|
||
else if ( count == 2 )
|
||
{
|
||
pHostInfo->pHostName = ptoken;
|
||
}
|
||
else
|
||
{
|
||
if ( countAlias >= MAXALIASES )
|
||
{
|
||
break;
|
||
}
|
||
pHostInfo->AliasArray[ countAlias++ ] = ptoken;
|
||
}
|
||
}
|
||
|
||
// NULL terminate alias array
|
||
|
||
pHostInfo->AliasArray[ countAlias ] = NULL;
|
||
|
||
IF_DNSDBG( INIT )
|
||
{
|
||
if ( count >= 2 )
|
||
{
|
||
PSTR palias;
|
||
|
||
DnsDbg_Printf(
|
||
"Parsed host file line:\n"
|
||
"\tAddress = %s\n"
|
||
"\tHostname = %s\n",
|
||
pHostInfo->pAddrString,
|
||
pHostInfo->pHostName );
|
||
|
||
countAlias = 0;
|
||
while ( palias = pHostInfo->AliasArray[countAlias] )
|
||
{
|
||
DnsDbg_Printf(
|
||
"\tAlias = %s\n",
|
||
palias );
|
||
countAlias++;
|
||
}
|
||
}
|
||
}
|
||
|
||
return( count >= 2 );
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
Dns_ReadHostFileLine(
|
||
IN OUT PHOST_FILE_INFO pHostInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Reads an entry from hosts file.
|
||
|
||
Arguments:
|
||
|
||
pHostInfo -- ptr to host info;
|
||
if hFile is NULL, first attempts host file open
|
||
other fields are filled with info from next hostfile line
|
||
|
||
Return Value:
|
||
|
||
TRUE if successfully reads a host entry.
|
||
FALSE if on EOF or no hosts file found.
|
||
|
||
--*/
|
||
{
|
||
IP4_ADDRESS ip4;
|
||
DNS_IP6_ADDRESS ip6;
|
||
|
||
DNSDBG( TRACE, (
|
||
"Dns_ReadHostFileLine()\n" ));
|
||
|
||
//
|
||
// open hosts file if not open
|
||
//
|
||
|
||
if ( pHostInfo->hFile == NULL )
|
||
{
|
||
Dns_OpenHostFile( pHostInfo );
|
||
if ( pHostInfo->hFile == NULL )
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
//
|
||
// loop until successfully read IP address
|
||
//
|
||
|
||
while( 1 )
|
||
{
|
||
// setup for next line
|
||
|
||
pHostInfo->pForwardRR = NULL;
|
||
pHostInfo->pReverseRR = NULL;
|
||
pHostInfo->pAliasRR = NULL;
|
||
|
||
// read line, quit on EOF
|
||
|
||
if ( ! fgets(
|
||
pHostInfo->HostLineBuf,
|
||
sizeof(pHostInfo->HostLineBuf) - 1,
|
||
pHostInfo->hFile ) )
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
// tokenize line
|
||
|
||
if ( !TokenizeHostFileLine( pHostInfo ) )
|
||
{
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// read address
|
||
// - try IP4
|
||
// - try IP6
|
||
// - otherwise skip
|
||
//
|
||
|
||
ip4 = inet_addr( pHostInfo->pAddrString );
|
||
|
||
if ( ip4 != INADDR_NONE ||
|
||
_strnicmp( "255.255.255.255", pHostInfo->pAddrString, 15 ) == 0 )
|
||
{
|
||
IPUNION_SET_IP4( &pHostInfo->Ip, ip4 );
|
||
break;
|
||
}
|
||
|
||
// not valid IP4 -- check IP6
|
||
|
||
if ( Dns_Ip6StringToAddress_A(
|
||
& ip6,
|
||
pHostInfo->pAddrString
|
||
) )
|
||
{
|
||
IPUNION_SET_IP6( &pHostInfo->Ip, ip6 );
|
||
break;
|
||
}
|
||
|
||
// invalid address, ignore line
|
||
|
||
DNSDBG( INIT, (
|
||
"Error parsing host file address %s\n",
|
||
pHostInfo->pAddrString ));
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// build records for line if desired
|
||
//
|
||
|
||
if ( pHostInfo->fBuildRecords )
|
||
{
|
||
BuildHostfileRecords( pHostInfo );
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
QueryHostFile(
|
||
IN OUT PQUERY_BLOB pBlob
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Lookup query in host file.
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
TRUE if found host file entry.
|
||
FALSE otherwise.
|
||
|
||
--*/
|
||
{
|
||
HOST_FILE_INFO hostInfo;
|
||
BOOL fip6 = FALSE;
|
||
BOOL fptr = FALSE;
|
||
IP_UNION ipUnion;
|
||
WORD wtype;
|
||
WORD buildType;
|
||
PCHAR pcnameHost = NULL;
|
||
PDNS_RECORD prrAlias = NULL;
|
||
PDNS_RECORD prr = NULL;
|
||
DNS_LIST forwardList;
|
||
DWORD bufLength;
|
||
PSTR pnameAnsi = (PCHAR) pBlob->NameBufferWide;
|
||
|
||
|
||
DNSDBG( INIT, ( "QueryHostFile()\n" ));
|
||
|
||
//
|
||
// determine if host file type
|
||
//
|
||
|
||
wtype = pBlob->wType;
|
||
|
||
if ( wtype == DNS_TYPE_A ||
|
||
wtype == DNS_TYPE_PTR ||
|
||
wtype == DNS_TYPE_ALL )
|
||
{
|
||
// no op
|
||
}
|
||
else if ( wtype == DNS_TYPE_AAAA )
|
||
{
|
||
fip6 = TRUE;
|
||
}
|
||
else
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// open hosts file -- if fails, we're done
|
||
//
|
||
|
||
RtlZeroMemory(
|
||
&hostInfo,
|
||
sizeof(hostInfo) );
|
||
|
||
if ( !Dns_OpenHostFile( &hostInfo ) )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
|
||
//
|
||
// convert name to ANSI
|
||
// - validate and select IP4\IP6 for PTR
|
||
//
|
||
|
||
bufLength = DNS_MAX_NAME_BUFFER_LENGTH;
|
||
|
||
if ( ! Dns_NameCopy(
|
||
pnameAnsi,
|
||
& bufLength,
|
||
pBlob->pNameWire,
|
||
0,
|
||
DnsCharSetWire,
|
||
DnsCharSetAnsi ) )
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// reverse name check
|
||
// - validate and select IP 4\6
|
||
// - PTR lookup MUST be valid reverse name
|
||
// - ALL may be reverse name
|
||
//
|
||
|
||
if ( wtype == DNS_TYPE_PTR ||
|
||
wtype == DNS_TYPE_ALL )
|
||
{
|
||
DWORD bufferLength = sizeof(IP6_ADDRESS);
|
||
BOOL family = 0;
|
||
|
||
if ( Dns_ReverseNameToAddress_A(
|
||
(PCHAR) & ipUnion.Addr,
|
||
& bufferLength,
|
||
pnameAnsi,
|
||
& family // either address type
|
||
) )
|
||
{
|
||
fptr = TRUE;
|
||
ipUnion.IsIp6 = (family == AF_INET6);
|
||
}
|
||
else if ( wtype == DNS_TYPE_PTR )
|
||
{
|
||
// bad reverse name
|
||
goto Cleanup;
|
||
}
|
||
}
|
||
|
||
//
|
||
// forward build type
|
||
// - matches query type
|
||
// - EXCEPT all which currently builds
|
||
// AAAA for IP6, A for IP4
|
||
//
|
||
|
||
if ( !fptr )
|
||
{
|
||
buildType = wtype;
|
||
DNS_LIST_STRUCT_INIT( forwardList );
|
||
}
|
||
|
||
//
|
||
// read entries from host file until exhausted
|
||
// - cache A record for each name and alias
|
||
// - cache PTR to name
|
||
//
|
||
|
||
while ( Dns_ReadHostFileLine( &hostInfo ) )
|
||
{
|
||
//
|
||
// reverse
|
||
// - match IP
|
||
// - success is terminal as reverse mapping is one-to-one
|
||
//
|
||
// DCR_QUESTION: parse hosts for multiple reverse mappings?
|
||
//
|
||
|
||
if ( fptr )
|
||
{
|
||
// DCR: extract as genericIP comparison
|
||
|
||
if ( ! Dns_EqualIpUnion( &ipUnion, &hostInfo.Ip ) )
|
||
{
|
||
continue;
|
||
}
|
||
|
||
// create RR
|
||
// - don't need to use IP conversion version
|
||
// as we already have reverse lookup name
|
||
|
||
DNSDBG( QUERY, (
|
||
"Build PTR record for name %s to %s\n",
|
||
pnameAnsi,
|
||
hostInfo.pHostName ));
|
||
|
||
prr = Dns_CreatePtrTypeRecord(
|
||
pnameAnsi,
|
||
TRUE, // copy name
|
||
hostInfo.pHostName,
|
||
DNS_TYPE_PTR,
|
||
HOSTFILE_RECORD_TTL,
|
||
DnsCharSetAnsi,
|
||
DnsCharSetUnicode );
|
||
|
||
if ( !prr )
|
||
{
|
||
SetLastError( DNS_ERROR_NO_MEMORY );
|
||
}
|
||
break;
|
||
}
|
||
|
||
//
|
||
// forward lookup
|
||
//
|
||
|
||
else
|
||
{
|
||
PCHAR pnameHost;
|
||
|
||
// type ALL builds on any match
|
||
// - build type appropriate for IP
|
||
//
|
||
// other query types must match address type
|
||
|
||
if ( wtype == DNS_TYPE_ALL )
|
||
{
|
||
buildType = IPUNION_IS_IP6(&hostInfo.Ip)
|
||
? DNS_TYPE_AAAA
|
||
: DNS_TYPE_A;
|
||
}
|
||
else if ( fip6 != IPUNION_IS_IP6(&hostInfo.Ip) )
|
||
{
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// check name match
|
||
//
|
||
// DCR: use unicode name? or UTF8 name directly
|
||
|
||
pnameHost = NULL;
|
||
|
||
if ( Dns_NameCompare_A(
|
||
hostInfo.pHostName,
|
||
pnameAnsi ) )
|
||
{
|
||
pnameHost = pnameAnsi;
|
||
}
|
||
|
||
//
|
||
// check match to previous CNAME
|
||
//
|
||
|
||
else if ( pcnameHost )
|
||
{
|
||
if ( Dns_NameCompare_A(
|
||
hostInfo.pHostName,
|
||
pcnameHost ) )
|
||
{
|
||
pnameHost = pcnameHost;
|
||
}
|
||
}
|
||
|
||
//
|
||
// aliases
|
||
//
|
||
// DCR_QUESTION: build aliases even if name hit?
|
||
//
|
||
// currently:
|
||
// - don't allow alias if already have direct record
|
||
// - limit to one alias (CNAME)
|
||
//
|
||
// if find alias:
|
||
// - build CNAME record
|
||
// - save CNAME target (in ANSI for faster compares)
|
||
// - check CNAME target for subsequent address records (above)
|
||
//
|
||
|
||
else if ( IS_DNS_LIST_STRUCT_EMPTY( forwardList )
|
||
&&
|
||
!prrAlias )
|
||
{
|
||
PCHAR * paliasEntry;
|
||
PCHAR palias;
|
||
|
||
for( paliasEntry = hostInfo.AliasArray;
|
||
palias = *paliasEntry;
|
||
paliasEntry++ )
|
||
{
|
||
if ( Dns_NameCompare_A(
|
||
palias,
|
||
pnameAnsi ) )
|
||
{
|
||
DNSDBG( QUERY, (
|
||
"Build CNAME record for name %s to CNAME %s\n",
|
||
pnameAnsi,
|
||
hostInfo.pHostName ));
|
||
|
||
prrAlias = Dns_CreatePtrTypeRecord(
|
||
pnameAnsi,
|
||
TRUE, // copy name
|
||
hostInfo.pHostName,
|
||
DNS_TYPE_CNAME,
|
||
HOSTFILE_RECORD_TTL,
|
||
DnsCharSetAnsi,
|
||
DnsCharSetUnicode );
|
||
|
||
if ( prrAlias )
|
||
{
|
||
pcnameHost = Dns_NameCopyAllocate(
|
||
hostInfo.pHostName,
|
||
0,
|
||
DnsCharSetAnsi,
|
||
DnsCharSetAnsi );
|
||
|
||
pnameHost = pcnameHost;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// add address record for this hostline
|
||
|
||
if ( pnameHost )
|
||
{
|
||
DNSDBG( QUERY, (
|
||
"Build address record for name %s\n",
|
||
pnameHost ));
|
||
|
||
prr = Dns_CreateForwardRecord(
|
||
pnameHost,
|
||
& hostInfo.Ip,
|
||
HOSTFILE_RECORD_TTL,
|
||
DnsCharSetAnsi,
|
||
DnsCharSetUnicode );
|
||
if ( prr )
|
||
{
|
||
DNS_LIST_STRUCT_ADD( forwardList, prr );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// build response
|
||
//
|
||
// DCR: new multiple section response
|
||
//
|
||
|
||
if ( !fptr )
|
||
{
|
||
prr = forwardList.pFirst;
|
||
if ( prrAlias )
|
||
{
|
||
prrAlias->pNext = prr;
|
||
prr = prrAlias;
|
||
}
|
||
}
|
||
|
||
IF_DNSDBG( QUERY )
|
||
{
|
||
DnsDbg_RecordSet(
|
||
"HostFile Answers:",
|
||
prr );
|
||
}
|
||
pBlob->pRecords = prr;
|
||
|
||
|
||
Cleanup:
|
||
|
||
//
|
||
// cleanup
|
||
//
|
||
|
||
Dns_CloseHostFile( &hostInfo );
|
||
|
||
if ( pcnameHost )
|
||
{
|
||
FREE_HEAP( pcnameHost );
|
||
}
|
||
|
||
DNSDBG( TRACE, (
|
||
"Leave QueryHostFile() -> %d\n"
|
||
"\tprr = %p\n",
|
||
prr ? TRUE : FALSE,
|
||
prr ));
|
||
|
||
return( prr ? TRUE : FALSE );
|
||
}
|
||
|
||
//
|
||
// End hostfile.c
|
||
//
|