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.
 
 
 
 
 
 

720 lines
23 KiB

/*++
Copyright (c) 1996-2001 Microsoft Corporation
Module Name:
dnsutil.c
Abstract:
Domain Name System (DNS) Library
General DNS utilities.
Author:
Jim Gilroy (jamesg) Decemeber 1996
Revision History:
--*/
#include "local.h"
IP4_ADDRESS
Dns_GetNetworkMask(
IN IP4_ADDRESS IpAddr
)
/*++
Routine Description:
Gets network mask for IP address.
Note, this is standard IP network mask for address type,
obviously subnetting is unknown.
Arguments:
IpAddr -- IP to get mask for
Return Value:
Network mask in network byte order.
--*/
{
// note addresses and masks are in netbyte order
// which we are treating as byte flipped and hence
// test the high bits in the low byte
// class A?
if ( ! (0x80 & IpAddr) )
{
return( 0x000000ff );
}
// class B?
if ( ! (0x40 & IpAddr) )
{
return( 0x0000ffff );
}
// then class C
// yes, there's some multicast BS out there, I don't
// believe it requires any special handling
return( 0x00ffffff );
}
BOOL
Dns_AreIp4InSameDefaultNetwork(
IN IP4_ADDRESS IpAddr1,
IN IP4_ADDRESS IpAddr2
)
/*++
Routine Description:
Check if two IP4 addresses are in same default network.
Note: this is strictly DEFAULT network info. It is NOT
a statement of subnet match, but of default network match
which will in general -- but not necessarily -- suggest
the addresses are in a connected network.
Arguments:
IpAddr1 -- first IP
IpAddr2 -- second IP
Return Value:
TRUE if in same default network.
FALSE otherwise.
--*/
{
IP4_ADDRESS mask;
//
// note that due to the default IP classes, the mask
// need only be gotten for ONE IP, because there is no
// way to screen with the WRONG class mask on an IP
// and produce network address that is valid for the
// class
//
mask = Dns_GetNetworkMask( IpAddr1 );
return( (IpAddr1 & mask) == (IpAddr2 & mask) );
}
//
// DNS status\error mappings
//
// DCR: investigate tossing error mappings
// and have all errors in Win32 system
//
typedef struct _DnsStatusStringMap
{
DNS_STATUS Status;
PCHAR String;
}
DNS_STATUS_STRING_MAP;
#define DNS_MAP_END ((DWORD)(-1))
#define DNS_MAP_ENTRY( _ErrorCode ) _ErrorCode, #_ErrorCode
DNS_STATUS_STRING_MAP DnsStatusStringMappings[] =
{
//
// Response codes
//
DNS_ERROR_RCODE_NO_ERROR ,"ERROR_SUCCESS",
DNS_ERROR_RCODE_FORMAT_ERROR ,"RCODE_FORMAT_ERROR",
DNS_ERROR_RCODE_SERVER_FAILURE ,"RCODE_SERVER_FAILURE",
DNS_ERROR_RCODE_NAME_ERROR ,"RCODE_NAME_ERROR",
DNS_ERROR_RCODE_NOT_IMPLEMENTED ,"RCODE_NOT_IMPLEMENTED",
DNS_ERROR_RCODE_REFUSED ,"RCODE_REFUSED",
DNS_ERROR_RCODE_YXDOMAIN ,"RCODE_YXDOMAIN",
DNS_ERROR_RCODE_YXRRSET ,"RCODE_YXRRSET",
DNS_ERROR_RCODE_NXRRSET ,"RCODE_NXRRSET",
DNS_ERROR_RCODE_NOTAUTH ,"RCODE_NOTAUTH",
DNS_ERROR_RCODE_NOTZONE ,"RCODE_NOTZONE",
DNS_ERROR_RCODE_BADSIG ,"RCODE_BADSIG",
DNS_ERROR_RCODE_BADKEY ,"RCODE_BADKEY",
DNS_ERROR_RCODE_BADTIME ,"RCODE_BADTIME",
//
// Packet format
//
DNS_INFO_NO_RECORDS ,"DNS_INFO_NO_RECORDS",
DNS_ERROR_BAD_PACKET ,"DNS_ERROR_BAD_PACKET",
DNS_ERROR_NO_PACKET ,"DNS_ERROR_NO_PACKET",
DNS_ERROR_RCODE ,"DNS_ERROR_RCODE",
DNS_ERROR_UNSECURE_PACKET ,"DNS_ERROR_UNSECURE_PACKET",
//
// General API errors
//
DNS_ERROR_INVALID_NAME ,"ERROR_INVALID_NAME",
DNS_ERROR_INVALID_DATA ,"ERROR_INVALID_DATA",
DNS_ERROR_INVALID_TYPE ,"ERROR_INVALID_TYPE",
DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION ,"DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION",
DNS_ERROR_INVALID_IP_ADDRESS ,"DNS_ERROR_INVALID_IP_ADDRESS",
DNS_ERROR_INVALID_PROPERTY ,"DNS_ERROR_INVALID_PROPERTY",
DNS_ERROR_TRY_AGAIN_LATER ,"DNS_ERROR_TRY_AGAIN_LATER",
DNS_ERROR_NOT_UNIQUE ,"DNS_ERROR_NOT_UNIQUE",
DNS_ERROR_NON_RFC_NAME ,"DNS_ERROR_NON_RFC_NAME",
DNS_STATUS_FQDN ,"DNS_STATUS_FQDN",
DNS_STATUS_DOTTED_NAME ,"DNS_STATUS_DOTTED_NAME",
DNS_STATUS_SINGLE_PART_NAME ,"DNS_STATUS_SINGLE_PART_NAME",
DNS_ERROR_INVALID_NAME_CHAR ,"DNS_ERROR_INVALID_NAME_CHAR",
DNS_ERROR_NUMERIC_NAME ,"DNS_ERROR_NUMERIC_NAME",
DNS_MAP_ENTRY( DNS_ERROR_CANNOT_FIND_ROOT_HINTS ),
DNS_MAP_ENTRY( DNS_ERROR_INCONSISTENT_ROOT_HINTS ),
//
// Server errors
//
DNS_MAP_ENTRY( DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER ),
//
// Zone errors
//
DNS_ERROR_ZONE_DOES_NOT_EXIST ,"DNS_ERROR_ZONE_DOES_NOT_EXIST",
DNS_ERROR_NO_ZONE_INFO ,"DNS_ERROR_NO_ZONE_INFO",
DNS_ERROR_INVALID_ZONE_OPERATION ,"DNS_ERROR_INVALID_ZONE_OPERATION",
DNS_ERROR_ZONE_CONFIGURATION_ERROR ,"DNS_ERROR_ZONE_CONFIGURATION_ERROR",
DNS_ERROR_ZONE_HAS_NO_SOA_RECORD ,"DNS_ERROR_ZONE_HAS_NO_SOA_RECORD",
DNS_ERROR_ZONE_HAS_NO_NS_RECORDS ,"DNS_ERROR_ZONE_HAS_NO_NS_RECORDS",
DNS_ERROR_ZONE_LOCKED ,"DNS_ERROR_ZONE_LOCKED",
DNS_ERROR_ZONE_CREATION_FAILED ,"DNS_ERROR_ZONE_CREATION_FAILED",
DNS_ERROR_ZONE_ALREADY_EXISTS ,"DNS_ERROR_ZONE_ALREADY_EXISTS",
DNS_ERROR_AUTOZONE_ALREADY_EXISTS ,"DNS_ERROR_AUTOZONE_ALREADY_EXISTS",
DNS_ERROR_INVALID_ZONE_TYPE ,"DNS_ERROR_INVALID_ZONE_TYPE",
DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP ,"DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP",
DNS_MAP_ENTRY( DNS_ERROR_ZONE_REQUIRES_MASTER_IP ),
DNS_MAP_ENTRY( DNS_ERROR_ZONE_IS_SHUTDOWN ),
DNS_ERROR_ZONE_NOT_SECONDARY ,"DNS_ERROR_ZONE_NOT_SECONDARY",
DNS_ERROR_NEED_SECONDARY_ADDRESSES ,"DNS_ERROR_NEED_SECONDARY_ADDRESSES",
DNS_ERROR_WINS_INIT_FAILED ,"DNS_ERROR_WINS_INIT_FAILED",
DNS_ERROR_NEED_WINS_SERVERS ,"DNS_ERROR_NEED_WINS_SERVERS",
DNS_ERROR_NBSTAT_INIT_FAILED ,"DNS_ERROR_NBSTAT_INIT_FAILED",
DNS_ERROR_SOA_DELETE_INVALID ,"DNS_ERROR_SOA_DELETE_INVALID",
DNS_MAP_ENTRY( DNS_ERROR_FORWARDER_ALREADY_EXISTS ),
//
// Datafile errors
//
DNS_ERROR_PRIMARY_REQUIRES_DATAFILE ,"DNS_ERROR_PRIMARY_REQUIRES_DATAFILE",
DNS_ERROR_INVALID_DATAFILE_NAME ,"DNS_ERROR_INVALID_DATAFILE_NAME",
DNS_ERROR_DATAFILE_OPEN_FAILURE ,"DNS_ERROR_DATAFILE_OPEN_FAILURE",
DNS_ERROR_FILE_WRITEBACK_FAILED ,"DNS_ERROR_FILE_WRITEBACK_FAILED",
DNS_ERROR_DATAFILE_PARSING ,"DNS_ERROR_DATAFILE_PARSING",
//
// Database errors
//
DNS_ERROR_RECORD_DOES_NOT_EXIST ,"DNS_ERROR_RECORD_DOES_NOT_EXIST",
DNS_ERROR_RECORD_FORMAT ,"DNS_ERROR_RECORD_FORMAT",
DNS_ERROR_NODE_CREATION_FAILED ,"DNS_ERROR_NODE_CREATION_FAILED",
DNS_ERROR_UNKNOWN_RECORD_TYPE ,"DNS_ERROR_UNKNOWN_RECORD_TYPE",
DNS_ERROR_RECORD_TIMED_OUT ,"DNS_ERROR_RECORD_TIMED_OUT",
DNS_ERROR_NAME_NOT_IN_ZONE ,"DNS_ERROR_NAME_NOT_IN_ZONE",
DNS_ERROR_CNAME_LOOP ,"DNS_ERROR_CNAME_LOOP",
DNS_ERROR_NODE_IS_CNAME ,"DNS_ERROR_NODE_IS_CNAME",
DNS_ERROR_CNAME_COLLISION ,"DNS_ERROR_CNAME_COLLISION",
DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT ,"DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT",
DNS_ERROR_RECORD_ALREADY_EXISTS ,"DNS_ERROR_RECORD_ALREADY_EXISTS",
DNS_ERROR_SECONDARY_DATA ,"DNS_ERROR_SECONDARY_DATA",
DNS_ERROR_NO_CREATE_CACHE_DATA ,"DNS_ERROR_NO_CREATE_CACHE_DATA",
DNS_ERROR_NAME_DOES_NOT_EXIST ,"DNS_ERROR_NAME_DOES_NOT_EXIST",
DNS_WARNING_PTR_CREATE_FAILED ,"DNS_WARNING_PTR_CREATE_FAILED",
DNS_WARNING_DOMAIN_UNDELETED ,"DNS_WARNING_DOMAIN_UNDELETED",
DNS_ERROR_DS_UNAVAILABLE ,"DNS_ERROR_DS_UNAVAILABLE",
DNS_ERROR_DS_ZONE_ALREADY_EXISTS ,"DNS_ERROR_DS_ZONE_ALREADY_EXISTS",
DNS_MAP_ENTRY( ERROR_DS_COULDNT_CONTACT_FSMO ),
//
// Operation errors
//
DNS_INFO_AXFR_COMPLETE ,"DNS_INFO_AXFR_COMPLETE",
DNS_ERROR_AXFR ,"DNS_ERROR_AXFR",
DNS_INFO_ADDED_LOCAL_WINS ,"DNS_INFO_ADDED_LOCAL_WINS",
//
// Secure update
//
DNS_STATUS_CONTINUE_NEEDED ,"DNS_STATUS_CONTINUE_NEEDED",
//
// Client setup errors
//
DNS_ERROR_NO_TCPIP ,"DNS_ERROR_NO_TCPIP",
DNS_ERROR_NO_DNS_SERVERS ,"DNS_ERROR_NO_DNS_SERVERS",
//
// Directory partition errors
//
DNS_MAP_ENTRY( DNS_ERROR_DP_DOES_NOT_EXIST ),
DNS_MAP_ENTRY( DNS_ERROR_DP_ALREADY_EXISTS ),
DNS_MAP_ENTRY( DNS_ERROR_DP_NOT_ENLISTED ),
DNS_MAP_ENTRY( DNS_ERROR_DP_ALREADY_ENLISTED ),
DNS_MAP_ENTRY( DNS_ERROR_DP_NOT_AVAILABLE ),
DNS_MAP_ENTRY( DNS_ERROR_DP_FSMO_ERROR ),
//
// Throw in common Win32 errors
//
ERROR_FILE_NOT_FOUND ,"ERROR_FILE_NOT_FOUND",
ERROR_ACCESS_DENIED ,"ERROR_ACCESS_DENIED",
ERROR_NOT_ENOUGH_MEMORY ,"ERROR_NOT_ENOUGH_MEMORY",
ERROR_BAD_FORMAT ,"ERROR_BAD_FORMAT",
ERROR_INVALID_DATA ,"ERROR_INVALID_DATA",
ERROR_OUTOFMEMORY ,"ERROR_OUTOFMEMORY",
ERROR_SHARING_VIOLATION ,"ERROR_SHARING_VIOLATION",
ERROR_NOT_SUPPORTED ,"ERROR_NOT_SUPPORTED",
ERROR_INVALID_PARAMETER ,"ERROR_INVALID_PARAMETER",
ERROR_INVALID_NAME ,"ERROR_INVALID_NAME",
ERROR_BAD_ARGUMENTS ,"ERROR_BAD_ARGUMENTS",
ERROR_BUSY ,"ERROR_BUSY",
ERROR_ALREADY_EXISTS ,"ERROR_ALREADY_EXISTS",
ERROR_LOCKED ,"ERROR_LOCKED",
ERROR_MORE_DATA ,"ERROR_MORE_DATA",
ERROR_INVALID_FLAGS ,"ERROR_INVALID_FLAGS",
ERROR_FILE_INVALID ,"ERROR_FILE_INVALID",
ERROR_TIMEOUT ,"ERROR_TIMEOUT",
//
// RPC errors
//
RPC_S_SERVER_UNAVAILABLE ,"RPC_S_SERVER_UNAVAILABLE",
RPC_S_INVALID_NET_ADDR ,"RPC_S_INVALID_NET_ADDR",
EPT_S_NOT_REGISTERED ,"EPT_S_NOT_REGISTERED",
EPT_S_NOT_REGISTERED ,"EPT_S_NOT_REGISTERED",
DNS_MAP_ENTRY( RPC_S_CALL_CANCELLED ),
//
// others:
//
ERROR_PATH_NOT_FOUND ,"ERROR_PATH_NOT_FOUND",
ERROR_INVALID_ACCESS ,"ERROR_INVALID_ACCESS",
ERROR_INVALID_DRIVE ,"ERROR_INVALID_DRIVE",
ERROR_WRITE_PROTECT ,"ERROR_WRITE_PROTECT",
ERROR_SHARING_VIOLATION ,"ERROR_SHARING_VIOLATION",
ERROR_HANDLE_DISK_FULL ,"ERROR_HANDLE_DISK_FULL",
ERROR_NOT_SUPPORTED ,"ERROR_NOT_SUPPORTED",
ERROR_REM_NOT_LIST ,"ERROR_REM_NOT_LIST",
ERROR_DUP_NAME ,"ERROR_DUP_NAME",
ERROR_NETNAME_DELETED ,"ERROR_NETNAME_DELETED",
ERROR_FILE_EXISTS ,"ERROR_FILE_EXISTS",
ERROR_NET_WRITE_FAULT ,"ERROR_NET_WRITE_FAULT",
ERROR_INVALID_SECURITY_DESCR ,"ERROR_INVALID_SECURITY_DESCR",
//
// winsock
//
WSAEINTR ,"WSAEINTR ",
WSAEBADF ,"WSAEBADF ",
WSAEACCES ,"WSAEACCES ",
WSAEFAULT ,"WSAEFAULT ",
WSAEINVAL ,"WSAEINVAL ",
WSAEMFILE ,"WSAEMFILE ",
WSAEWOULDBLOCK ,"WSAEWOULDBLOCK ",
WSAEINPROGRESS ,"WSAEINPROGRESS ",
WSAEALREADY ,"WSAEALREADY ",
WSAENOTSOCK ,"WSAENOTSOCK ",
WSAEDESTADDRREQ ,"WSAEDESTADDRREQ ",
WSAEMSGSIZE ,"WSAEMSGSIZE ",
WSAEPROTOTYPE ,"WSAEPROTOTYPE ",
WSAENOPROTOOPT ,"WSAENOPROTOOPT ",
WSAEPROTONOSUPPORT ,"WSAEPROTONOSUPPORT ",
WSAESOCKTNOSUPPORT ,"WSAESOCKTNOSUPPORT ",
WSAEOPNOTSUPP ,"WSAEOPNOTSUPP ",
WSAEPFNOSUPPORT ,"WSAEPFNOSUPPORT ",
WSAEAFNOSUPPORT ,"WSAEAFNOSUPPORT ",
WSAEADDRINUSE ,"WSAEADDRINUSE ",
WSAEADDRNOTAVAIL ,"WSAEADDRNOTAVAIL ",
WSAENETDOWN ,"WSAENETDOWN ",
WSAENETUNREACH ,"WSAENETUNREACH ",
WSAENETRESET ,"WSAENETRESET ",
WSAECONNABORTED ,"WSAECONNABORTED ",
WSAECONNRESET ,"WSAECONNRESET ",
WSAENOBUFS ,"WSAENOBUFS ",
WSAEISCONN ,"WSAEISCONN ",
WSAENOTCONN ,"WSAENOTCONN ",
WSAESHUTDOWN ,"WSAESHUTDOWN ",
WSAETOOMANYREFS ,"WSAETOOMANYREFS ",
WSAETIMEDOUT ,"WSAETIMEDOUT ",
WSAECONNREFUSED ,"WSAECONNREFUSED ",
WSAELOOP ,"WSAELOOP ",
WSAENAMETOOLONG ,"WSAENAMETOOLONG ",
WSAEHOSTDOWN ,"WSAEHOSTDOWN ",
WSAEHOSTUNREACH ,"WSAEHOSTUNREACH ",
WSAENOTEMPTY ,"WSAENOTEMPTY ",
WSAEPROCLIM ,"WSAEPROCLIM ",
WSAEUSERS ,"WSAEUSERS ",
WSAEDQUOT ,"WSAEDQUOT ",
WSAESTALE ,"WSAESTALE ",
WSAEREMOTE ,"WSAEREMOTE ",
WSASYSNOTREADY ,"WSASYSNOTREADY ",
WSAVERNOTSUPPORTED ,"WSAVERNOTSUPPORTED ",
WSANOTINITIALISED ,"WSANOTINITIALISED ",
WSAEDISCON ,"WSAEDISCON ",
WSAENOMORE ,"WSAENOMORE ",
WSAECANCELLED ,"WSAECANCELLED ",
WSAEINVALIDPROCTABLE ,"WSAEINVALIDPROCTABLE ",
WSAEINVALIDPROVIDER ,"WSAEINVALIDPROVIDER ",
WSAEPROVIDERFAILEDINIT ,"WSAEPROVIDERFAILEDINIT ",
WSASYSCALLFAILURE ,"WSASYSCALLFAILURE ",
WSASERVICE_NOT_FOUND ,"WSASERVICE_NOT_FOUND ",
WSATYPE_NOT_FOUND ,"WSATYPE_NOT_FOUND ",
WSA_E_NO_MORE ,"WSA_E_NO_MORE ",
WSA_E_CANCELLED ,"WSA_E_CANCELLED ",
WSAEREFUSED ,"WSAEREFUSED ",
WSAHOST_NOT_FOUND ,"WSAHOST_NOT_FOUND ",
WSATRY_AGAIN ,"WSATRY_AGAIN ",
WSANO_RECOVERY ,"WSANO_RECOVERY ",
WSANO_DATA ,"WSANO_DATA ",
WSA_QOS_RECEIVERS ,"WSA_QOS_RECEIVERS ",
WSA_QOS_SENDERS ,"WSA_QOS_SENDERS ",
WSA_QOS_NO_SENDERS ,"WSA_QOS_NO_SENDERS ",
WSA_QOS_NO_RECEIVERS ,"WSA_QOS_NO_RECEIVERS ",
WSA_QOS_REQUEST_CONFIRMED ,"WSA_QOS_REQUEST_CONFIRMED ",
WSA_QOS_ADMISSION_FAILURE ,"WSA_QOS_ADMISSION_FAILURE ",
WSA_QOS_POLICY_FAILURE ,"WSA_QOS_POLICY_FAILURE ",
WSA_QOS_BAD_STYLE ,"WSA_QOS_BAD_STYLE ",
WSA_QOS_BAD_OBJECT ,"WSA_QOS_BAD_OBJECT ",
WSA_QOS_TRAFFIC_CTRL_ERROR ,"WSA_QOS_TRAFFIC_CTRL_ERROR ",
WSA_QOS_GENERIC_ERROR ,"WSA_QOS_GENERIC_ERROR ",
WSA_QOS_ESERVICETYPE ,"WSA_QOS_ESERVICETYPE ",
WSA_QOS_EFLOWSPEC ,"WSA_QOS_EFLOWSPEC ",
WSA_QOS_EPROVSPECBUF ,"WSA_QOS_EPROVSPECBUF ",
WSA_QOS_EFILTERSTYLE ,"WSA_QOS_EFILTERSTYLE ",
WSA_QOS_EFILTERTYPE ,"WSA_QOS_EFILTERTYPE ",
WSA_QOS_EFILTERCOUNT ,"WSA_QOS_EFILTERCOUNT ",
WSA_QOS_EOBJLENGTH ,"WSA_QOS_EOBJLENGTH ",
WSA_QOS_EFLOWCOUNT ,"WSA_QOS_EFLOWCOUNT ",
WSA_QOS_EUNKOWNPSOBJ ,"WSA_QOS_EUNKOWNPSOBJ ",
WSA_QOS_EPOLICYOBJ ,"WSA_QOS_EPOLICYOBJ ",
WSA_QOS_EFLOWDESC ,"WSA_QOS_EFLOWDESC ",
WSA_QOS_EPSFLOWSPEC ,"WSA_QOS_EPSFLOWSPEC ",
WSA_QOS_EPSFILTERSPEC ,"WSA_QOS_EPSFILTERSPEC ",
WSA_QOS_ESDMODEOBJ ,"WSA_QOS_ESDMODEOBJ ",
WSA_QOS_ESHAPERATEOBJ ,"WSA_QOS_ESHAPERATEOBJ ",
WSA_QOS_RESERVED_PETYPE ,"WSA_QOS_RESERVED_PETYPE ",
//
// RPC errors
//
RPC_S_SERVER_TOO_BUSY ,"RPC_S_SERVER_TOO_BUSY ",
DNS_MAP_END ,"UNKNOWN",
};
PCHAR
_fastcall
Dns_StatusString(
IN DNS_STATUS Status
)
/*++
Routine Description:
Map DNS error code to status string.
Arguments:
Status -- status code to check
Return Value:
DNS error string for error code.
--*/
{
INT i = 0;
DNS_STATUS mappedStatus;
while ( 1 )
{
mappedStatus = DnsStatusStringMappings[i].Status;
if ( mappedStatus == Status || mappedStatus == DNS_MAP_END )
{
return( DnsStatusStringMappings[i].String );
}
i++;
}
DNS_ASSERT( FALSE );
return( NULL ); // make compiler happy
}
DNS_STATUS
_fastcall
Dns_MapRcodeToStatus(
IN BYTE ResponseCode
)
/*++
Routine Description:
Map response code to DNS error code.
Arguments:
ResponseCode - response code to get error for
Return Value:
DNS error code for response code.
--*/
{
if ( !ResponseCode )
{
return( ERROR_SUCCESS );
}
else
{
return( DNS_ERROR_MASK + ((DWORD) ResponseCode) );
}
}
BYTE
_fastcall
Dns_IsStatusRcode(
IN DNS_STATUS Status
)
/*++
Routine Description:
Determine if status is RCODE and if so return it.
Arguments:
Status -- status code to check
Return Value:
Response code corresponding to status, if found.
Zero otherwise.
--*/
{
if ( Status >= DNS_ERROR_RCODE_FORMAT_ERROR &&
Status <= DNS_ERROR_RCODE_LAST )
{
return( (BYTE) (DNS_ERROR_MASK ^ Status) );
}
else
{
return( 0 );
}
}
DNS_STATUS
Dns_CreateTypeArrayFromMultiTypeString(
IN LPSTR pchMultiTypeString,
OUT INT * piTypeCount,
OUT PWORD * ppwTypeArray
)
/*++
Routine Description:
Allocates an array of types from a string containing DNS types
in numeric and/or string format separated by whitespace.
Arguments:
pBuffer -- string buffer with list of numeric or alpha types
piTypeCount -- number of types parsed written here
ppwTypeArray -- ptr to allocated array of types written here
this ptr must be freed even if the number of types returned
is zero
Return Value:
ERROR_SUCCESS
--*/
{
PCHAR psz;
DWORD argc;
PCHAR argv[ 50 ];
DWORD idx;
ASSERT( pchMultiTypeString );
ASSERT( piTypeCount );
ASSERT( ppwTypeArray );
*piTypeCount = 0;
//
// Allocate array: be cheap and assume max # of types in string
// is twice the length of the string, e.g. "1 2 3 4 5".
//
*ppwTypeArray = ALLOCATE_HEAP(
( strlen( pchMultiTypeString ) / 2 + 2 ) * sizeof( WORD ) );
if ( !*ppwTypeArray )
{
return DNS_ERROR_NO_MEMORY;
}
//
// Parse the string.
//
argc = Dns_TokenizeStringA(
pchMultiTypeString,
argv,
sizeof( argv ) / sizeof( PCHAR ) );
for ( idx = 0; idx < argc; ++idx )
{
if ( isdigit( argv[ idx ][ 0 ] ) )
{
( *ppwTypeArray )[ *piTypeCount ] =
( WORD ) strtol( argv[ idx ], NULL, 0 );
}
else
{
( *ppwTypeArray )[ *piTypeCount ] = Dns_RecordTypeForName(
argv[ idx ],
0 ); // string length
}
if ( ( *ppwTypeArray )[ *piTypeCount ] != 0 )
{
++*piTypeCount;
}
}
return ERROR_SUCCESS;
} // Dns_CreateTypeArrayFromMultiTypeString
LPSTR
Dns_CreateMultiTypeStringFromTypeArray(
IN INT iTypeCount,
IN PWORD ppwTypeArray,
IN CHAR chSeparator OPTIONAL
)
/*++
Routine Description:
Allocate a string and write the types in the array in string format
separated by the specified separator or by a space char.
Arguments:
iTypeCount -- number of types in the array
ppwTypeArray -- ptr to array of types
chSeparator -- string separator or zero for the default separator
Return Value:
ERROR_SUCCESS
--*/
{
LPSTR pszTypes;
INT idx;
LPSTR psz;
ASSERT( ppwTypeArray );
//
// Allocate array: be cheap and assume 10 chars per element.
//
psz = pszTypes = ALLOCATE_HEAP( iTypeCount * 10 * sizeof( CHAR ) );
if ( !psz )
{
return NULL;
}
//
// Output type strings.
//
for ( idx = 0; idx < iTypeCount; ++idx )
{
PCHAR pszThisType;
pszThisType = Dns_RecordStringForType( ppwTypeArray[ idx ] );
if ( !pszThisType )
{
continue;
}
strcpy( psz, pszThisType );
psz += strlen( pszThisType );
*psz++ = chSeparator ? chSeparator : ' ';
}
*psz = '\0'; // NULL terminate the string
return pszTypes;
} // Dns_CreateMultiTypeStringFromTypeArray
//
// End dnsutil.c
//