windows-nt/Source/XPSP1/NT/ds/dns/dnsapi/dnsapi.c
2020-09-26 16:20:57 +08:00

762 lines
13 KiB
C

/*++
Copyright (c) 1996-2000 Microsoft Corporation
Module Name:
dnsapi.c
Abstract:
Domain Name System (DNS) API
Dnsapi.dll infrastructure (init, shutdown, etc)
Routines to access DNS resolver
Author:
GlennC 22-Jan-1997
Revision History:
Jim Gilroy (jamesg) March 2000 cleanup
--*/
#include "local.h"
#include <lmcons.h>
#define DNS_NET_FAILURE_CACHE_TIME 30 // Seconds
//
// Global Definitions
//
//
// Globals
//
CRITICAL_SECTION g_RegistrationListCS;
CRITICAL_SECTION g_RegistrationThreadCS;
CRITICAL_SECTION g_QueueCS;
CRITICAL_SECTION g_NetFailureCS;
DWORD g_NetFailureTime;
DNS_STATUS g_NetFailureStatus;
IP_ADDRESS g_LastDNSServerUpdated = 0;
//
// Local Function Prototypes
//
BOOL
DnsInitialize(
VOID
);
VOID
DnsCleanup(
VOID
);
VOID
ClearDnsCacheEntry_A (
IN LPSTR,
IN WORD );
VOID
ClearDnsCacheEntry_W (
IN LPWSTR,
IN WORD );
VOID
FreeRpcIpAddressList(
IN PDNS_IP_ADDR_LIST );
//
// System public Network Information
//
// The dnsapi.dll interface is in config.c
//
PDNS_NETWORK_INFORMATION
CreateNetworkInformation(
IN DWORD cAdapterCount
)
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
PDNS_NETWORK_INFORMATION pNetworkInfo = NULL;
DWORD dwAdapterListBufLen = sizeof( DNS_NETWORK_INFORMATION ) -
sizeof( PDNS_ADAPTER_INFORMATION ) +
( sizeof( PDNS_ADAPTER_INFORMATION ) *
cAdapterCount );
pNetworkInfo = (PDNS_NETWORK_INFORMATION) ALLOCATE_HEAP_ZERO(
dwAdapterListBufLen );
return pNetworkInfo;
}
PDNS_SEARCH_INFORMATION
CreateSearchInformation(
IN DWORD cNameCount,
IN LPSTR pszName
)
{
PDNS_SEARCH_INFORMATION pSearchInfo = NULL;
DWORD dwSearchInfoBufLen = sizeof( DNS_SEARCH_INFORMATION ) -
sizeof( LPSTR ) +
( sizeof( LPSTR ) *
cNameCount );
if ( ( cNameCount == 0 ) && ( ! pszName ) )
{
return NULL;
}
pSearchInfo =
(PDNS_SEARCH_INFORMATION) ALLOCATE_HEAP_ZERO( dwSearchInfoBufLen );
if ( ! pSearchInfo )
{
return NULL;
}
if ( pszName )
{
pSearchInfo->pszPrimaryDomainName = Dns_NameCopyAllocate(
pszName,
0,
DnsCharSetUtf8,
DnsCharSetUtf8 );
if ( ! pSearchInfo->pszPrimaryDomainName )
{
FREE_HEAP( pSearchInfo );
return NULL;
}
}
return pSearchInfo;
}
PDNS_SEARCH_INFORMATION
CreateSearchInformationCopyFromList(
IN PSEARCH_LIST pSearchList
)
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
PDNS_SEARCH_INFORMATION pSearchInformation;
DWORD iter;
if ( ! pSearchList )
{
return NULL;
}
pSearchInformation = CreateSearchInformation(
pSearchList->NameCount,
pSearchList->pszDomainOrZoneName );
if ( ! pSearchInformation )
{
return NULL;
}
for ( iter = 0; iter < pSearchList->NameCount; iter++ )
{
if ( pSearchList->SearchNameArray[iter].pszName )
{
pSearchInformation->aSearchListNames[iter] =
Dns_NameCopyAllocate(
pSearchList->SearchNameArray[iter].pszName,
0,
DnsCharSetUtf8,
DnsCharSetUtf8 );
}
if ( pSearchInformation->aSearchListNames[iter] )
{
pSearchInformation->cNameCount++;
}
}
return pSearchInformation;
}
PDNS_ADAPTER_INFORMATION
CreateAdapterInformation(
IN DWORD cServerCount,
IN DWORD dwFlags,
IN LPSTR pszDomain,
IN LPSTR pszGuidName
)
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
PDNS_ADAPTER_INFORMATION pAdapter = NULL;
DWORD dwAdapterInfoBufLen = sizeof( DNS_ADAPTER_INFORMATION ) -
sizeof( DNS_SERVER_INFORMATION ) +
( sizeof( DNS_SERVER_INFORMATION ) *
cServerCount );
pAdapter = (PDNS_ADAPTER_INFORMATION)
ALLOCATE_HEAP_ZERO( dwAdapterInfoBufLen );
if ( ! pAdapter )
{
return NULL;
}
pAdapter->InfoFlags = dwFlags;
pAdapter->cServerCount = 0;
if ( pszDomain )
{
pAdapter->pszDomain = Dns_NameCopyAllocate(
pszDomain,
0,
DnsCharSetUtf8,
DnsCharSetUtf8 );
}
if ( pszGuidName )
{
pAdapter->pszAdapterGuidName = Dns_NameCopyAllocate(
pszGuidName,
0,
DnsCharSetUtf8,
DnsCharSetUtf8 );
}
return pAdapter;
}
PDNS_ADAPTER_INFORMATION
CreateAdapterInformationCopyFromList(
IN PDNS_ADAPTER pAdapter
)
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
PDNS_ADAPTER_INFORMATION pAdapterInformation;
DWORD iter;
if ( ! pAdapter )
{
return NULL;
}
pAdapterInformation = CreateAdapterInformation(
pAdapter->ServerCount,
pAdapter->InfoFlags,
pAdapter->pszAdapterDomain,
pAdapter->pszAdapterGuidName );
if ( ! pAdapterInformation )
{
return NULL;
}
pAdapterInformation->pIPAddresses =
Dns_CreateIpArrayCopy( pAdapter->pAdapterIPAddresses );
pAdapterInformation->pIPSubnetMasks =
Dns_CreateIpArrayCopy( pAdapter->pAdapterIPSubnetMasks );
for ( iter = 0; iter < pAdapter->ServerCount; iter++ )
{
pAdapterInformation->aipServers[iter].ipAddress =
pAdapter->ServerArray[iter].IpAddress;
pAdapterInformation->aipServers[iter].Priority =
pAdapter->ServerArray[iter].Priority;
}
pAdapterInformation->cServerCount = pAdapter->ServerCount;
return pAdapterInformation ;
}
PDNS_NETWORK_INFORMATION
WINAPI
GetNetworkInformation(
VOID )
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
PDNS_NETINFO pNetInfo = GetNetworkInfo();
DWORD iter;
PDNS_NETWORK_INFORMATION pNetworkInformation = NULL;
if ( !pNetInfo )
{
return NULL;
}
//
// create Network Information of desired size
// then copy entire structure
//
pNetworkInformation = CreateNetworkInformation( pNetInfo->AdapterCount );
if ( ! pNetworkInformation )
{
goto Done;
}
pNetworkInformation->pSearchInformation =
CreateSearchInformationCopyFromList( pNetInfo->pSearchList );
for ( iter = 0; iter < pNetInfo->AdapterCount; iter++ )
{
pNetworkInformation->aAdapterInfoList[iter] =
CreateAdapterInformationCopyFromList( pNetInfo->AdapterArray[iter] );
if ( pNetworkInformation->aAdapterInfoList[iter] )
{
pNetworkInformation->cAdapterCount += 1;
}
}
Done:
NetInfo_Free( pNetInfo );
return pNetworkInformation;
}
PDNS_SEARCH_INFORMATION
WINAPI
GetSearchInformation(
VOID )
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
PDNS_NETINFO pNetInfo = GetNetworkInfo();
PDNS_SEARCH_INFORMATION pSearchInformation = NULL;
if ( !pNetInfo )
{
return NULL;
}
pSearchInformation = CreateSearchInformationCopyFromList(
pNetInfo->pSearchList );
NetInfo_Free( pNetInfo );
return pSearchInformation;
}
VOID
WINAPI
FreeAdapterInformation(
IN PDNS_ADAPTER_INFORMATION pAdapterInformation
)
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
if ( pAdapterInformation )
{
if ( pAdapterInformation->pszAdapterGuidName )
{
FREE_HEAP( pAdapterInformation->pszAdapterGuidName );
}
if ( pAdapterInformation->pszDomain )
{
FREE_HEAP( pAdapterInformation->pszDomain );
}
if ( pAdapterInformation->pIPAddresses )
{
FREE_HEAP( pAdapterInformation->pIPAddresses );
}
if ( pAdapterInformation->pIPSubnetMasks )
{
FREE_HEAP( pAdapterInformation->pIPSubnetMasks );
}
FREE_HEAP( pAdapterInformation );
}
}
VOID
WINAPI
FreeSearchInformation(
IN PDNS_SEARCH_INFORMATION pSearchInformation
)
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
DWORD iter;
if ( pSearchInformation )
{
if ( pSearchInformation->pszPrimaryDomainName )
{
FREE_HEAP( pSearchInformation->pszPrimaryDomainName );
}
for ( iter = 0; iter < pSearchInformation->cNameCount; iter++ )
{
if ( pSearchInformation->aSearchListNames[iter] )
{
FREE_HEAP( pSearchInformation->aSearchListNames[iter] );
}
}
FREE_HEAP( pSearchInformation );
}
}
VOID
WINAPI
FreeNetworkInformation(
IN PDNS_NETWORK_INFORMATION pNetworkInformation
)
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
DWORD iter;
if ( pNetworkInformation )
{
FreeSearchInformation( pNetworkInformation->pSearchInformation );
for ( iter = 0; iter < pNetworkInformation->cAdapterCount; iter++ )
{
FreeAdapterInformation( pNetworkInformation ->
aAdapterInfoList[iter] );
}
FREE_HEAP( pNetworkInformation );
}
}
//
// Net failure caching
//
BOOL
IsKnownNetFailure(
VOID
)
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
BOOL flag = FALSE;
DNSDBG( TRACE, ( "IsKnownNetFailure()\n" ));
EnterCriticalSection( &g_NetFailureCS );
if ( g_NetFailureStatus )
{
if ( g_NetFailureTime < Dns_GetCurrentTimeInSeconds() )
{
g_NetFailureTime = 0;
g_NetFailureStatus = ERROR_SUCCESS;
flag = FALSE;
}
else
{
SetLastError( g_NetFailureStatus );
flag = TRUE;
}
}
LeaveCriticalSection( &g_NetFailureCS );
return flag;
}
VOID
SetKnownNetFailure(
IN DNS_STATUS Status
)
/*++
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
{
DNSDBG( TRACE, ( "SetKnownNetFailure()\n" ));
EnterCriticalSection( &g_NetFailureCS );
g_NetFailureTime = Dns_GetCurrentTimeInSeconds() +
DNS_NET_FAILURE_CACHE_TIME;
g_NetFailureStatus = Status;
LeaveCriticalSection( &g_NetFailureCS );
}
BOOL
WINAPI
DnsGetCacheDataTable(
OUT PDNS_CACHE_TABLE * ppTable
)
/*++
Routine Description:
Get cache data table.
Arguments:
ppTable -- address to receive ptr to cache data table
Return Value:
ERROR_SUCCES if successful.
Error code on failure.
--*/
{
DNS_STATUS status = ERROR_SUCCESS;
DWORD rpcStatus = ERROR_SUCCESS;
PDNS_RPC_CACHE_TABLE pcacheTable = NULL;
DNSDBG( TRACE, ( "DnsGetCacheDataTable()\n" ));
if ( ! ppTable )
{
return FALSE;
}
#if DNSBUILDOLD
if ( g_IsWin9X )
{
return FALSE;
}
#endif
RpcTryExcept
{
status = CRrReadCache( NULL, &pcacheTable );
}
RpcExcept( DNS_RPC_EXCEPTION_FILTER )
{
status = RpcExceptionCode();
}
RpcEndExcept
// set out param
*ppTable = (PDNS_CACHE_TABLE) pcacheTable;
#if DBG
if ( status != ERROR_SUCCESS )
{
DNSDBG( RPC, (
"DnsGetCacheDataTable() status = %d\n",
status ));
}
#endif
return( pcacheTable && status == ERROR_SUCCESS );
}
BOOL
IsLocalIpAddress(
IN IP_ADDRESS IpAddress
)
//
// DCR_FIX: this has no customers other than debug code in update.c
//
// If wanted this API it should be remoteable -- we could avoid alloc
// and include IP6
//
{
BOOL bfound = FALSE;
PIP_ARRAY ipList = Dns_GetLocalIpAddressArray();
DWORD iter;
if ( !ipList )
{
return bfound;
}
//
// check if IpAddress is in local list
//
for ( iter = 0; iter < ipList->AddrCount; iter++ )
{
if ( IpAddress == ipList->AddrArray[iter] )
{
bfound = TRUE;
}
}
FREE_HEAP( ipList );
return bfound;
}
//
// End dnsapi.c
//