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.
 
 
 
 
 
 

4127 lines
94 KiB

/*++
Copyright (c) 1996-2001 Microsoft Corporation
Module Name:
dnslib.h
Abstract:
Domain Name System (DNS) Library
DNS Library Routines -- Main Header File
Author:
Jim Gilroy (jamesg) December 7, 1996
Revision History:
--*/
#ifndef _DNSLIB_INCLUDED_
#define _DNSLIB_INCLUDED_
#include <windns.h>
#include <dnsapi.h>
#ifndef MIDL_PASS
#include <rpc.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
//
// Handy alignment and rounding macros
//
#define WORD_ALIGN(ptr) ((PVOID) ((UINT_PTR)((PBYTE)ptr + 1) & ~(UINT_PTR)1))
#define DWORD_ALIGN(ptr) ((PVOID) ((UINT_PTR)((PBYTE)ptr + 3) & ~(UINT_PTR)3))
#define QWORD_ALIGN(ptr) ((PVOID) ((UINT_PTR)((PBYTE)ptr + 7) & ~(UINT_PTR)7))
#ifdef WIN64
#define POINTER_ALIGN(ptr) QWORD_ALIGN(ptr)
#else
#define POINTER_ALIGN(ptr) DWORD_ALIGN(ptr)
#endif
#define WORD_ALIGN_DWORD(dw) (((DWORD)dw + 1) & ~(DWORD)1)
#define DWORD_ALIGN_DWORD(dw) (((DWORD)dw + 3) & ~(DWORD)3)
#define QWORD_ALIGN_DWORD(dw) (((DWORD)dw + 7) & ~(DWORD)7)
#ifdef WIN64
#define POINTER_ALIGN_DWORD(dw) QWORD_ALIGN_DWORD(dw)
#else
#define POINTER_ALIGN_DWORD(dw) DWORD_ALIGN_DWORD(dw)
#endif
//
// Useful type defs
//
#define PGUID LPGUID
#define PADDRINFO LPADDRINFO
//
// Until converted must define PDNS_NAME
//
// Note: PDNS_NAME is NOT really a LPTSTR.
// Rather it's the definition of a field that can be
// either an PWSTR or PSTR depending on some other field.
//
#ifdef UNICODE
typedef PWSTR PDNS_NAME;
#else
typedef PSTR PDNS_NAME;
#endif
//
// Inline byte flipping
//
#ifndef MIDL_PASS
__inline
WORD
inline_word_flip(
IN WORD Word
)
{
return ( (Word << 8) | (Word >> 8) );
}
#define inline_htons(w) inline_word_flip(w)
#define inline_ntohs(w) inline_word_flip(w)
__inline
DWORD
inline_dword_flip(
IN DWORD Dword
)
{
return ( ((Dword << 8) & 0x00ff0000) |
(Dword << 24) |
((Dword >> 8) & 0x0000ff00) |
(Dword >> 24) );
}
#define inline_htonl(d) inline_dword_flip(d)
#define inline_ntohl(d) inline_dword_flip(d)
#endif MIDL_PASS
//
// Flat buffer definition
//
// Note: using INT for sizes so that we can push BytesLeft negative
// and use routines to determine REQUIRED space, even when no
// buffer or buf too small.
//
typedef struct _FLATBUF
{
PBYTE pBuffer;
PBYTE pEnd;
PBYTE pCurrent;
INT Size;
INT BytesLeft;
}
FLATBUF, *PFLATBUF;
//
// Flat buffer routines -- argument versions
//
// These versions have the actual code so that we can
// easily use this stuff with existing code that has
// independent pCurrent and BytesLeft variables.
//
// FLATBUF structure versions just call these inline.
//
#ifndef MIDL_PASS
PBYTE
FlatBuf_Arg_Reserve(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN DWORD Size,
IN DWORD Alignment
);
PBYTE
FlatBuf_Arg_WriteString(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN PSTR pString,
IN BOOL fUnicode
);
PBYTE
FlatBuf_Arg_CopyMemory(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN PVOID pMemory,
IN DWORD Length,
IN DWORD Alignment
);
__inline
PBYTE
FlatBuf_Arg_ReserveAlignPointer(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
ppCurrent,
pBytesLeft,
Size,
sizeof(PVOID) );
}
__inline
PBYTE
FlatBuf_Arg_ReserveAlignQword(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
ppCurrent,
pBytesLeft,
Size,
sizeof(QWORD) );
}
__inline
PBYTE
FlatBuf_Arg_ReserveAlignDword(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
ppCurrent,
pBytesLeft,
Size,
sizeof(DWORD) );
}
__inline
PBYTE
FlatBuf_Arg_ReserveAlignWord(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
ppCurrent,
pBytesLeft,
Size,
sizeof(WORD) );
}
__inline
PBYTE
FlatBuf_Arg_ReserveAlignByte(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
ppCurrent,
pBytesLeft,
Size,
0 );
}
PBYTE
__inline
FlatBuf_Arg_WriteString_A(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN PSTR pString
)
{
return FlatBuf_Arg_WriteString(
ppCurrent,
pBytesLeft,
pString,
FALSE // not unicode
);
}
PBYTE
__inline
FlatBuf_Arg_WriteString_W(
IN OUT PBYTE * ppCurrent,
IN OUT PINT pBytesLeft,
IN PWSTR pString
)
{
return FlatBuf_Arg_WriteString(
ppCurrent,
pBytesLeft,
(PSTR) pString,
TRUE // unicode
);
}
//
// Flat buffer routines -- structure versions
//
VOID
FlatBuf_Init(
IN OUT PFLATBUF pFlatBuf,
IN PBYTE pBuffer,
IN INT Size
);
__inline
PBYTE
FlatBuf_Reserve(
IN OUT PFLATBUF pBuf,
IN DWORD Size,
IN DWORD Alignment
)
{
return FlatBuf_Arg_Reserve(
& pBuf->pCurrent,
& pBuf->BytesLeft,
Size,
Alignment );
}
__inline
PBYTE
FlatBuf_ReserveAlignPointer(
IN OUT PFLATBUF pBuf,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
& pBuf->pCurrent,
& pBuf->BytesLeft,
Size,
sizeof(PVOID) );
}
__inline
PBYTE
FlatBuf_ReserveAlignQword(
IN OUT PFLATBUF pBuf,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
& pBuf->pCurrent,
& pBuf->BytesLeft,
Size,
sizeof(QWORD) );
}
__inline
PBYTE
FlatBuf_ReserveAlignDword(
IN OUT PFLATBUF pBuf,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
& pBuf->pCurrent,
& pBuf->BytesLeft,
Size,
sizeof(DWORD) );
}
__inline
PBYTE
FlatBuf_ReserveAlignWord(
IN OUT PFLATBUF pBuf,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
& pBuf->pCurrent,
& pBuf->BytesLeft,
Size,
sizeof(WORD) );
}
__inline
PBYTE
FlatBuf_ReserveAlignByte(
IN OUT PFLATBUF pBuf,
IN DWORD Size
)
{
return FlatBuf_Arg_Reserve(
& pBuf->pCurrent,
& pBuf->BytesLeft,
Size,
0 );
}
PBYTE
__inline
FlatBuf_WriteString(
IN OUT PFLATBUF pBuf,
IN PSTR pString,
IN BOOL fUnicode
)
{
return FlatBuf_Arg_WriteString(
& pBuf->pCurrent,
& pBuf->BytesLeft,
pString,
fUnicode
);
}
PBYTE
__inline
FlatBuf_WriteString_A(
IN OUT PFLATBUF pBuf,
IN PSTR pString
)
{
return FlatBuf_Arg_WriteString(
& pBuf->pCurrent,
& pBuf->BytesLeft,
pString,
FALSE // not unicode
);
}
PBYTE
__inline
FlatBuf_WriteString_W(
IN OUT PFLATBUF pBuf,
IN PWSTR pString
)
{
return FlatBuf_Arg_WriteString(
& pBuf->pCurrent,
& pBuf->BytesLeft,
(PSTR) pString,
TRUE // unicode
);
}
PBYTE
__inline
FlatBuf_CopyMemory(
IN OUT PFLATBUF pBuf,
IN PVOID pMemory,
IN DWORD Length,
IN DWORD Alignment
)
{
return FlatBuf_Arg_CopyMemory(
& pBuf->pCurrent,
& pBuf->BytesLeft,
pMemory,
Length,
Alignment );
}
#endif // not MIDL_PASS
//
// Read unaligned value from given position in packet
//
#define READ_PACKET_HOST_DWORD(pch) \
FlipUnalignedDword( pch )
#define READ_PACKET_NET_DWORD(pch) \
( *(UNALIGNED DWORD *)(pch) )
#define READ_PACKET_HOST_WORD(pch) \
FlipUnalignedWord( pch )
#define READ_PACKET_NET_WORD(pch) \
( *(UNALIGNED WORD *)(pch) )
//
// Private DNS_RECORD Flag field structure definition and macros
//
// Note: don't add to this list -- private stuff in dnslibp.h
//
typedef struct _DnsRecordLibFlags
{
DWORD Section : 2;
DWORD Delete : 1;
DWORD CharSet : 2;
DWORD Unused : 6;
DWORD Matched : 1;
DWORD FreeData : 1;
DWORD FreeOwner : 1;
DWORD Reserved : 18;
}
DNSRECLIB_FLAGS, *PDNSRECLIB_FLAGS;
#define PFLAGS( pRecord ) ((PDNSRECLIB_FLAGS)&pRecord->Flags.DW)
#define FLAG_Section( pRecord ) (PFLAGS( pRecord )->Section)
#define FLAG_Delete( pRecord ) (PFLAGS( pRecord )->Delete)
#define FLAG_CharSet( pRecord ) (PFLAGS( pRecord )->CharSet)
#define FLAG_FreeData( pRecord ) (PFLAGS( pRecord )->FreeData)
#define FLAG_FreeOwner( pRecord ) (PFLAGS( pRecord )->FreeOwner)
#define FLAG_Matched( pRecord ) (PFLAGS( pRecord )->Matched)
#define SET_FREE_OWNER(pRR) (FLAG_FreeOwner(pRR) = TRUE)
#define SET_FREE_DATA(pRR) (FLAG_FreeData(pRR) = TRUE)
#define SET_RR_MATCHED(pRR) (FLAG_Matched(pRR) = TRUE)
#define CLEAR_FREE_OWNER(pRR) (FLAG_FreeOwner(pRR) = FALSE)
#define CLEAR_FREE_DATA(pRR) (FLAG_FreeData(pRR) = FALSE)
#define CLEAR_RR_MATCHED(pRR) (FLAG_Matched(pRR) = FALSE)
#define IS_FREE_OWNER(pRR) (FLAG_FreeOwner(pRR))
#define IS_FREE_DATA(pRR) (FLAG_FreeData(pRR))
#define IS_RR_MATCHED(pRR) (FLAG_Matched(pRR))
#define IS_ANSWER_RR(pRR) (FLAG_Section(pRR) == DNSREC_ANSWER)
#define IS_AUTHORITY_RR(pRR) (FLAG_Section(pRR) == DNSREC_AUTHORITY)
#define IS_ADDITIONAL_RR(pRR) (FLAG_Section(pRR) == DNSREC_ADDITIONAL)
//
// Converting RCODEs to\from DNS errors.
//
#define DNS_ERROR_FROM_RCODE(rcode) ((rcode)+DNS_ERROR_RESPONSE_CODES_BASE)
#define DNS_RCODE_FROM_ERROR(err) ((err)-DNS_ERROR_RESPONSE_CODES_BASE)
//
// Record character sets
//
// Currently supports records in three character sets
// - unicode
// - ANSI
// - UTF8
//
// Unicode and ANSI are supported through external DNSAPI interfaces.
// UTF8 is not (at least offcially).
//
// However, internally unicode and UTF8 are used for caching, reading
// to and writing from packet.
//
// All DNS_RECORD structs created by our code, are tagged with a
// character set type in the flags CharSet field.
//
//
// A couple of handy macros:
//
#define RECORD_CHARSET(pRR) \
( (DNS_CHARSET) (pRR)->Flags.S.CharSet )
#define IS_UNICODE_RECORD(pRR) \
( (DNS_CHARSET) (pRR)->Flags.S.CharSet == DnsCharSetUnicode )
//
// Quick buffer size determination
//
// Strings are read from the wire into dotted UTF8 format.
// Strings are in UTF8 in RPC buffers.
//
// Goal here is to quickly determine adequate buffer size,
// slight overallocation is not critical.
//
// Currently supporting only UTF8 or Unicode, however, if later
// support direct ANSI conversion that's ok too, as ANSI will
// no (to my knowledge) use more space than UTF8.
//
#define STR_BUF_SIZE_GIVEN_UTF8_LEN( Utf8Length, CharSet ) \
( ((CharSet)==DnsCharSetUnicode) ? ((Utf8Length)+1)*2 : (Utf8Length)+1 )
//
// Default locale for string comparison and case mappings
//
// Sublang: US English (0x04) Lang: English (0x09)
//
#define DNS_DEFAULT_LOCALE (0x0409)
//
// IP4 array utilities (iparray.c)
//
// Note some of these require memory allocation, see note
// on memory allocation below.
//
#define DNS_NET_ORDER_LOOPBACK (0x0100007f)
// NT5-autonet is 169.254.x.y
#define AUTONET_MASK (0x0000ffff)
#define AUTONET_NET (0x0000fea9)
#define DNS_IS_AUTONET_IP(ip) ( ((ip) & AUTONET_MASK) == AUTONET_NET )
#define DNS_IPARRAY_CLEAN_ZERO (0x00000001)
#define DNS_IPARRAY_CLEAN_LOOPBACK (0x00000002)
#define DNS_IPARRAY_CLEAN_AUTONET (0x00000010)
//
// Simple IP address array routines
//
PIP4_ADDRESS
Dns_CreateIpAddressArrayCopy(
IN PIP4_ADDRESS aipAddress,
IN DWORD cipAddress
);
BOOL
Dns_ValidateIpAddressArray(
IN PIP4_ADDRESS aipAddress,
IN DWORD cipAddress,
IN DWORD dwFlag
);
//
// IP4_ARRAY datatype routines
//
PIP4_ARRAY
Dns_CreateIpArray(
IN DWORD cAddrCount
);
DWORD
Dns_SizeofIpArray(
IN PIP4_ARRAY pIpArray
);
PIP4_ARRAY
Dns_BuildIpArray(
IN DWORD cAddrCount,
IN PIP4_ADDRESS pipAddrs
);
PIP4_ARRAY
Dns_CopyAndExpandIpArray(
IN PIP4_ARRAY pIpArray,
IN DWORD ExpandCount,
IN BOOL fDeleteExisting
);
PIP4_ARRAY
Dns_CreateIpArrayCopy(
IN PIP4_ARRAY pIpArray
);
BOOL
Dns_IsAddressInIpArray(
IN PIP4_ARRAY pIpArray,
IN IP4_ADDRESS IpAddress
);
BOOL
Dns_AddIpToIpArray(
IN OUT PIP4_ARRAY pIpArray,
IN IP4_ADDRESS IpNew
);
VOID
Dns_ClearIpArray(
IN OUT PIP4_ARRAY pIpArray
);
VOID
Dns_ReverseOrderOfIpArray(
IN OUT PIP4_ARRAY pIpArray
);
BOOL
Dns_CheckAndMakeIpArraySubset(
IN OUT PIP4_ARRAY pIpArraySub,
IN PIP4_ARRAY pIpArraySuper
);
INT
WINAPI
Dns_ClearIpFromIpArray(
IN OUT PIP4_ARRAY pIpArray,
IN IP4_ADDRESS IpDelete
);
INT
WINAPI
Dns_DeleteIpFromIpArray(
IN OUT PIP4_ARRAY pIpArray,
IN IP4_ADDRESS IpDelete
);
#define Dns_RemoveZerosFromIpArray(pArray) \
Dns_DeleteIpFromIpArray( (pArray), 0 )
INT
WINAPI
Dns_CleanIpArray(
IN OUT PIP4_ARRAY pIpArray,
IN DWORD Flag
);
BOOL
Dns_AreIpArraysEqual(
IN PIP4_ARRAY pIpArray1,
IN PIP4_ARRAY pIpArray2
);
BOOL
Dns_AreIpArraysSimilar(
IN PIP4_ARRAY pIpArray1,
IN PIP4_ARRAY pIpArray2
);
DNS_STATUS
WINAPI
Dns_DiffOfIpArrays(
IN PIP4_ARRAY pIpArray1,
IN PIP4_ARRAY pIpArray2,
OUT PIP4_ARRAY* ppOnlyIn1,
OUT PIP4_ARRAY* ppOnlyIn2,
OUT PIP4_ARRAY* ppIntersect
);
BOOL
WINAPI
Dns_IsIntersectionOfIpArrays(
IN PIP4_ARRAY pIpArray1,
IN PIP4_ARRAY pIpArray2
);
DNS_STATUS
WINAPI
Dns_UnionOfIpArrays(
IN PIP4_ARRAY pIpArray1,
IN PIP4_ARRAY pIpArray2,
OUT PIP4_ARRAY* ppUnion
);
#define Dns_IntersectionOfIpArrays(p1, p2, ppInt) \
Dns_DiffOfIpArrays( (p1), (p2), NULL, NULL, (ppInt) )
DNS_STATUS
Dns_CreateIpArrayFromMultiIpString(
IN PSTR pchMultiIpString,
OUT PIP4_ARRAY* ppIpArray
);
PSTR
Dns_CreateMultiIpStringFromIpArray(
IN PIP4_ARRAY pIpArray,
IN CHAR chSeparator OPTIONAL
);
//
// Type list array routines
//
DNS_STATUS
Dns_CreateTypeArrayFromMultiTypeString(
IN PSTR pchMultiTypeString,
OUT INT * piTypeCount,
OUT PWORD * ppwTypeArray
);
PSTR
Dns_CreateMultiTypeStringFromTypeArray(
IN INT iTypeCount,
IN PWORD ppwTypeArray,
IN CHAR chSeparator OPTIONAL
);
//
// IP6 stuff
//
#ifndef DEFINED_IP6_ARRAY
typedef struct _Ip6Array
{
DWORD MaxCount;
DWORD AddrCount;
#ifdef MIDL_PASS
[size_is(MaxCount)] IP6_ADDRESS AddrArray[];
#else
IP6_ADDRESS AddrArray[1];
#endif
}
IP6_ARRAY, *PIP6_ARRAY;
#define DEFINED_IP6_ARRAY 1
#endif
//
// General utilities
//
//
// Wrap free, multi-thread safe seconds timer (timer.c)
//
VOID
Dns_InitializeSecondsTimer(
VOID
);
DWORD
Dns_GetCurrentTimeInSeconds(
VOID
);
//
// Tokenizer
//
DWORD
Dns_TokenizeStringA(
IN OUT PSTR pBuffer,
OUT PCHAR * Argv,
IN DWORD MaxArgs
);
DWORD
Dns_TokenizeStringW(
IN OUT PWSTR pBuffer,
OUT PWCHAR * Argv,
IN DWORD MaxArgs
);
//
// IP interfaces on local machine (iplist.c)
//
#define DNS_MAX_NAME_SERVERS (50)
#define DNS_MAX_IP_INTERFACE_COUNT (10000)
PIP4_ARRAY
Dns_GetLocalIpAddressArray(
VOID
);
//
// NetInfo structures
//
// WARNING: Do NOT use these!
//
// These are internal dnsapi.dll structures. They are only
// included here for backward compatibility with previous
// code (netdiag) which incorrectly used these.
//
// If you code with them you will inevitably wake up broken
// down the road.
//
#if 0
#ifndef MIDL_PASS
typedef struct
{
DNS_STATUS Status;
DWORD Priority;
// Address is now DNS_ADDR
// Preserve IP4 field by putting it in correct place
union
{
struct
{
DWORD Pad0;
IP4_ADDRESS IpAddress;
};
DNS_ADDR Address;
};
}
DNSLIB_SERVER_INFO, *PDNSLIB_SERVER_INFO;
typedef struct
{
PWSTR pszAdapterGuidName;
PWSTR pwsAdapterDomain;
PWSTR pszAdapterDomain;
PVOID pLocalAddrs;
PVOID pServerArray;
DWORD InterfaceIndex;
DWORD InterfaceIndex6;
DWORD InfoFlags;
DWORD Status;
DWORD ReturnFlags;
DWORD ServerIndex;
DWORD cServerCount;
DWORD cTotalListSize;
//DNSLIB_SERVER_INFO ServerArray[1];
}
DNSLIB_ADAPTER, *PDNSLIB_ADAPTER;
#define DNS_MAX_SEARCH_LIST_ENTRIES (50)
typedef struct
{
PWSTR pszName;
DWORD Flags;
}
DNSLIB_SEARCH_NAME, *PDNSLIB_SEARCH_NAME;
typedef struct
{
PWSTR pszDomainOrZoneName;
DWORD cNameCount; // Zero for FAZ result
DWORD cTotalListSize; // Zero for FAZ result
DWORD CurrentName; // 0 for pszDomainOrZoneName
// 1 for first name in array below
// 2 for second name in array below
// ...
DNSLIB_SEARCH_NAME SearchNameArray[1];
}
DNSLIB_SEARCH_LIST, *PDNSLIB_SEARCH_LIST;
typedef struct
{
PWSTR pwsDomainName;
PWSTR pszDomainName;
PWSTR pszHostName;
PDNSLIB_SEARCH_LIST pSearchList;
DWORD TimeStamp;
DWORD InfoFlags;
DWORD Tag;
DWORD ReturnFlags;
DWORD cAdapterCount;
DWORD cTotalListSize;
DNSLIB_ADAPTER AdapterArray[1];
}
DNSLIB_NETINFO, *PDNSLIB_NETINFO;
//
// Do NOT use these defs internally
//
#ifdef USE_DNSLIB_NETINFO
typedef DNSLIB_SERVER_INFO DNS_SERVER_INFO, *PDNS_SERVER_INFO;
typedef DNSLIB_ADAPTER DNS_ADAPTER, *PDNS_ADAPTER;
typedef DNSLIB_SEARCH_NAME SEARCH_NAME, *PSEARCH_NAME;
typedef DNSLIB_SEARCH_LIST SEARCH_LIST, *PSEARCH_LIST;
typedef DNSLIB_NETINFO DNS_NETINFO, *PDNS_NETINFO;
#endif // not USE_DNSLIB_NETINFO
#endif // not MIDL_PASS
#endif // ifdef'd out
//
// General DNS utilities (dnsutil.c)
//
IP4_ADDRESS
Dns_GetNetworkMask(
IN IP4_ADDRESS IpAddress
);
PSTR
_fastcall
Dns_StatusString(
IN DNS_STATUS Status
);
#define Dns_StatusToErrorString_A(status) Dns_StatusString(status)
DNS_STATUS
_fastcall
Dns_MapRcodeToStatus(
IN BYTE ResponseCode
);
BYTE
_fastcall
Dns_IsStatusRcode(
IN DNS_STATUS Status
);
//
// Name utilities (name.c)
//
PSTR
_fastcall
Dns_GetDomainName(
IN PCSTR pszName
);
PWSTR
_fastcall
Dns_GetDomainName_W(
IN PCWSTR pwsName
);
PCHAR
_fastcall
Dns_GetTldForName(
IN PCSTR pszName
);
BOOL
_fastcall
Dns_IsNameShort(
IN PCSTR pszName
);
BOOL
_fastcall
Dns_IsNameFQDN(
IN PCSTR pszName
);
DNS_STATUS
Dns_ValidateAndCategorizeDnsNameEx(
IN PCHAR pchName,
IN DWORD cchNameLength,
OUT PDWORD pLabelCount
);
#define Dns_ValidateAndCategorizeDnsName(p,c) \
Dns_ValidateAndCategorizeDnsNameEx((p),(c),NULL)
DWORD
Dns_NameLabelCount(
IN PCSTR pszName
);
#define DNS_NAME_UNKNOWN 0x00000000
#define DNS_NAME_IS_FQDN 0x00000001
#define DNS_NAME_SINGLE_LABEL 0x00000010
#define DNS_NAME_MULTI_LABEL 0x00000100
DWORD
_fastcall
Dns_GetNameAttributes(
IN PCSTR pszName
);
//
// Packet create\read\write (packet.c)
//
//
// UDP packet buffer
//
// 1472 is the maximum ethernet IP\UDP payload size
// without causing fragmentation, use as default buffer
//
#define DNS_MAX_UDP_PACKET_BUFFER_LENGTH (1472)
// parsing RR
// convenient to get WIRE records into aligned\host order format
typedef struct _DNS_PARSED_RR
{
PCHAR pchName;
PCHAR pchRR;
PCHAR pchData;
PCHAR pchNextRR;
// note from here on down mimics wire record
WORD Type;
WORD Class;
DWORD Ttl;
WORD DataLength;
}
DNS_PARSED_RR, *PDNS_PARSED_RR;
//
// DNS Server Message Info structure
//
// This is structure in which requests are held while being
// processed by the DNS server.
//
typedef struct _DnsMessageBuf
{
LIST_ENTRY ListEntry; // for queuing
//
// Addressing
//
SOCKET Socket4;
SOCKET Socket6;
//16/32
DNS_ADDR RemoteAddress;
//32/48
SOCKET Socket;
//
// Basic packet info
//
DWORD BufferLength; // total length of buffer
PCHAR pBufferEnd; // ptr to byte after buffer
PBYTE pCurrent; // current location in buffer
PWORD pCurrentCountField; // current count field being written
//
// Current lookup info
//
DWORD Timeout; // recv timeout
DWORD QueryTime; // time of original query
WORD wTypeCurrent; // type of query being done
WORD wOffsetCurrent;
//
// Queuing
//
WORD wQueuingXid; // match XID to response
DWORD QueuingTime; // time queued
DWORD ExpireTime; // queue timeout
//
// Basic packet flags
//
BOOLEAN fTcp;
BOOLEAN fSwapped; // header in net order
BOOLEAN fMessageComplete; // complete message received
BOOLEAN fConvertUnicode; // convert to unicode
BOOLEAN fSocketKeepalive; // keep socket alive
BOOLEAN fLastSendOpt; // last send contained OPT
//
// TCP message reception
//
PCHAR pchRecv; // ptr to next pos in message
//
// End of message before OPT addition
//
PCHAR pPreOptEnd;
//
// WARNING !
//
// Message length MUST
// - be a WORD type
// - immediately preceed message itself
// for proper send/recv of TCP messages.
//
// Use pointers above to DWORD (or QWORD) align, then recv bytes to push
// message length against MessageHead. Note, that DNS_HEADER contains
// only WORDs as it's largest element and so should chummy up even on
// WORD boundary. DWORD boundary should be very safe.
//
WORD BytesToReceive;
WORD MessageLength;
//
// DNS Message itself
//
DNS_HEADER MessageHead;
//
// Question and RR section
//
// This simply provides some coding simplicity in accessing
// this section given MESSAGE_INFO structure.
//
CHAR MessageBody[1];
}
DNS_MSG_BUF, *PDNS_MSG_BUF;
#define SIZEOF_MSG_BUF_OVERHEAD (sizeof(DNS_MSG_BUF) - sizeof(DNS_HEADER) - 1)
#define DNS_MESSAGE_END(pMsg) \
((PCHAR)&(pMsg)->MessageHead + (pMsg)->MessageLength)
#define DNS_MESSAGE_OFFSET( pMsg, p ) \
((PCHAR)(p) - (PCHAR)(&(pMsg)->MessageHead))
#define DNS_MESSAGE_CURRENT_OFFSET( pMsg ) \
DNS_MESSAGE_OFFSET( (pMsg), (pMsg)->pCurrent )
// Sockaddr combined length
#define DNS_MESSAGE_REMOTE_ADDRESS_AND_LENGTH_
//
// Handy for packet setup
//
#define CLEAR_DNS_HEADER_FLAGS_AND_XID( pHead ) ( *(PDWORD)(pHead) = 0 )
PDNS_MSG_BUF
Dns_AllocateMsgBuf(
IN WORD wBufferLength OPTIONAL
);
VOID
Dns_InitializeMsgBuf(
IN OUT PDNS_MSG_BUF pMsg
);
PDNS_MSG_BUF
Dns_BuildPacket(
IN PDNS_HEADER pHeader,
IN BOOL fNoHeaderCounts,
IN PDNS_NAME pszQuestionName,
IN WORD wQuestionType,
IN PDNS_RECORD pRecord,
IN DWORD dwFlags,
IN BOOL fUpdatePacket
);
PCHAR
_fastcall
Dns_WriteDottedNameToPacket(
IN OUT PCHAR pch,
IN PCHAR pchStop,
IN PSTR pszName,
IN PSTR pszDomain, OPTIONAL
IN WORD wDomainOffset, OPTIONAL
IN BOOL fUnicodeName
);
PCHAR
_fastcall
Dns_WriteStringToPacket(
IN OUT PCHAR pch,
IN PCHAR pchStop,
IN PSTR pszString,
IN BOOL fUnicodeString
);
PCHAR
Dns_WriteQuestionToMessage(
IN OUT PDNS_MSG_BUF pMsg,
IN PDNS_NAME pszName,
IN WORD wType,
IN BOOL fUnicodeName
);
DNS_STATUS
Dns_WriteRecordStructureToMessage(
IN OUT PDNS_MSG_BUF pMsg,
IN WORD wType,
IN WORD wClass,
IN DWORD dwTtl,
IN WORD wDataLength
);
PCHAR
Dns_WriteRecordStructureToPacketEx(
IN OUT PCHAR pchBuf,
IN WORD wType,
IN WORD wClass,
IN DWORD dwTtl,
IN WORD wDataLength
);
DNS_STATUS
Dns_WriteRecordStructureToPacket(
IN OUT PCHAR pchBuf,
IN PDNS_RECORD pRecord,
IN BOOL fUpdatePacket
);
VOID
Dns_SetRecordDatalength(
IN OUT PDNS_WIRE_RECORD pRecord,
IN WORD wDataLength
);
DNS_STATUS
Dns_AddRecordsToMessage(
IN OUT PDNS_MSG_BUF pMsg,
IN PDNS_RECORD pRecord,
IN BOOL fUpdateMessage
);
PCHAR
_fastcall
Dns_SkipPacketName(
IN PCHAR pch,
IN PCHAR pchEnd
);
BOOL
Dns_IsSamePacketQuestion(
IN PDNS_MSG_BUF pMsg1,
IN PDNS_MSG_BUF pMsg2
);
PCHAR
_fastcall
Dns_SkipPacketRecord(
IN PCHAR pchRecord,
IN PCHAR pchMsgEnd
);
PCHAR
Dns_SkipToRecord(
IN PDNS_HEADER pMsgHead,
IN PCHAR pMsgEnd,
IN INT iCount
);
PCHAR
Dns_ReadRecordStructureFromPacket(
IN PCHAR pchPacket,
IN PCHAR pchMsgEnd,
IN OUT PDNS_PARSED_RR pParsedRR
);
DNS_STATUS
Dns_ExtractRecordsFromMessage(
IN PDNS_MSG_BUF pMsg,
IN BOOL fUnicode,
OUT PDNS_RECORD * ppRecord
);
DNS_STATUS
Dns_ExtractRecordsFromBuffer(
IN PDNS_MESSAGE_BUFFER pDnsBuffer,
IN WORD wMessageLength,
IN BOOL fUnicode,
OUT PDNS_RECORD * ppRecord
);
void
Dns_NormalizeAllRecordTtls(
IN PDNS_RECORD pRecord
);
PCHAR
_fastcall
Dns_ReadPacketName(
IN OUT PCHAR pchNameBuffer,
OUT PWORD pwNameLength,
IN OUT PWORD pwNameOffset, OPTIONAL
OUT PBOOL pfNameSameAsPrevious, OPTIONAL
IN PCHAR pchName,
IN PCHAR pchStart,
IN PCHAR pchEnd
);
PCHAR
_fastcall
Dns_ReadPacketNameAllocate(
IN OUT PCHAR * ppchName,
OUT PWORD pwNameLength,
IN OUT PWORD pwPrevNameOffset, OPTIONAL
OUT PBOOL pfNameSameAsPrevious, OPTIONAL
IN PCHAR pchPacketName,
IN PCHAR pchStart,
IN PCHAR pchEnd
);
WORD
Dns_GetRandomXid(
IN PVOID pSeed
);
//
// Socket setup (socket.c)
//
//
// these two routines really don't belong here -- system stuff should be elsewhere
//
DNS_STATUS
Dns_InitializeWinsock(
VOID
);
VOID
Dns_CleanupWinsock(
VOID
);
SOCKET
Dns_CreateSocket(
IN INT SockType,
IN IP4_ADDRESS ipAddress,
IN USHORT Port
);
VOID
Dns_CloseSocket(
IN SOCKET Socket
);
VOID
Dns_CloseConnection(
IN SOCKET Socket
);
DNS_STATUS
Dns_SetupGlobalAsyncSocket(
VOID
);
//
// Query (query.c)
//
//
// Flags to DnsQuery
//
// These are in addition to public flags in dnsapi.h
// They must all be in the reserved section defined by
// DNS_QUERY_RESERVED
//
// Unicode i\o
#define DNSQUERY_UNICODE_NAME (0x01000000)
#define DNSQUERY_UNICODE_OUT (0x02000000)
#define DNSQUERY_NO_SERVER_RECORDS (0x04000000)
#define DNSQUERY_NULL_LOCAL (0x04000000)
// DNS server query
#define DNS_SERVER_QUERY_NAME (L"..DnsServers")
//
// Screen DNSAPI_INTERNAL use for everything with NETINFO
// these must be defined (where used) internally using good def.
//
#ifdef DNSLIB_NETINFO
//
// Raw packet send and recv (send.c)
//
DNS_STATUS
Dns_SendAndRecvUdp(
IN OUT PDNS_MSG_BUF pMsgSend,
OUT PDNS_MSG_BUF pMsgRecv,
IN DWORD dwFlags,
IN PIP4_ARRAY aipServers,
IN OUT PDNS_NETINFO pAdapterInfo
);
DNS_STATUS
Dns_SendAndRecvTcp(
IN OUT PDNS_MSG_BUF pMsgSend,
OUT PDNS_MSG_BUF pMsgRecv,
IN PIP4_ARRAY aipServers,
IN OUT PDNS_NETINFO pAdapterInfo
);
DNS_STATUS
Dns_SendAndRecv(
IN OUT PDNS_MSG_BUF pMsgSend,
OUT PDNS_MSG_BUF * ppMsgRecv,
OUT PDNS_RECORD * ppResponseRecords,
IN DWORD dwFlags,
IN PIP4_ARRAY aipServers,
IN OUT PDNS_NETINFO pAdapterInfo
);
//
// End non-internal only DNS_NETINFO with external def
//
#endif // not DNSLIB_NETINFO
DNS_STATUS
Dns_SendEx(
IN OUT PDNS_MSG_BUF pMsg,
IN IP4_ADDRESS SendIp, OPTIONAL
IN BOOL fNoOpt
);
#define Dns_Send( pMsg ) Dns_SendEx( (pMsg), 0, 0 )
DNS_STATUS
Dns_Recv(
IN OUT PDNS_MSG_BUF pMsg
);
DNS_STATUS
Dns_RecvUdp(
IN OUT PDNS_MSG_BUF pMsg
);
DNS_STATUS
Dns_OpenTcpConnectionAndSend(
IN OUT PDNS_MSG_BUF pMsg,
IN IP4_ADDRESS ipServer,
IN BOOL fBlocking
);
DNS_STATUS
Dns_RecvTcp(
IN OUT PDNS_MSG_BUF pMsg
);
VOID
Dns_InitializeMsgRemoteSockaddr(
IN OUT PDNS_MSG_BUF pMsg,
IN IP4_ADDRESS IpAddress
);
VOID
Dns_InitQueryTimeouts(
VOID
);
//
// Dynamic update (update.c)
//
PCHAR
Dns_WriteNoDataUpdateRecordToMessage(
IN PCHAR pch,
IN PCHAR pchStop,
IN WORD wClass,
IN WORD wType
);
PCHAR
Dns_WriteDataUpdateRecordToMessage(
IN PCHAR pch,
IN PCHAR pchStop,
IN WORD wClass,
IN WORD wType,
IN DWORD dwTtl,
IN WORD wDataLength
);
PDNS_MSG_BUF
Dns_BuildHostUpdateMessage(
IN OUT PDNS_MSG_BUF pMsg,
IN PSTR pszZone,
IN PSTR pszName,
IN PIP4_ARRAY aipAddresses,
IN DWORD dwTtl
);
PDNS_RECORD
Dns_HostUpdateRRSet(
IN PSTR pszHostName,
IN PIP4_ARRAY aipAddrs,
IN DWORD dwTtl
);
DNS_STATUS
Dns_UpdateHostAddrs(
IN PSTR pszName,
IN PIP4_ARRAY aipAddresses,
IN PIP4_ARRAY aipServers,
IN DWORD dwTtl
);
DNS_STATUS
Dns_UpdateHostAddrsOld(
IN PSTR pszName,
IN PIP4_ARRAY aipAddresses,
IN PIP4_ARRAY aipServers,
IN DWORD dwTtl
);
DNS_STATUS
Dns_UpdateLibEx(
IN PDNS_RECORD pRecord,
IN DWORD dwFlags,
IN PDNS_NAME pszZone,
IN PDNS_NAME pszServerName,
IN PIP4_ARRAY aipServers,
IN HANDLE hCreds, OPTIONAL
OUT PDNS_MSG_BUF * ppMsgRecv OPTIONAL
);
//
// RenDom stuff
//
// Record verification table
//
typedef struct _DnsVerifyTable
{
DWORD RecordCount;
PDNS_RECORD pRecordList;
PIP6_ARRAY pServerArray;
PBOOL pVerifyArray;
}
DNS_VERIFY_TABLE, *PDNS_VERIFY_TABLE;
DNS_STATUS
Dns_VerifyRecords(
IN OUT PDNS_VERIFY_TABLE pTable
);
//
// Record verification table for rendom
//
// Implementation note:
// Using pointers here for server\bool arrays here instead
// of open array of server count. The reason is to allow dynamic
// allocation of the lists by the API if it FAZes to find to
// zone\servers to target.
// The server IPs and bools could be combined in another
// structure, but that doesn't seem to add much and makes
// use of the existing IP array stuff more difficult.
//
typedef struct _DnsRendomEntry
{
PSTR pDcName;
// could have this in unicode
//PWSTR pDcName;
PDNS_RECORD pRecord;
PIP6_ARRAY pServerArray;
PBOOL pVerifyArray;
}
DNS_RENDOM_ENTRY, *PDNS_RENDOM_ENTRY;
#define DNS_RENDOM_VERIFY_WITH_FAZ (0x00000001)
#define DNS_RENDOM_VERIFY_WITH_LIST (0x00000002)
typedef struct _DnsZoneServerList
{
PSTR pZoneName;
// could have this in unicode
//PWSTR pZoneName;
PIP6_ARRAY pServerArray;
}
DNS_ZONE_SERVER_LIST, *PDNS_ZONE_SERVER_LIST;
DNS_STATUS
Dns_VerifyRendomDcRecords(
IN OUT PDNS_RENDOM_ENTRY pTable,
IN PDNS_ZONE_SERVER_LIST pZoneServList, OPTIONAL
IN DWORD Flag
);
//
// List build
//
// pFirst points to first element in list.
// pLast points to last element in list.
//
// This builds a list for element types which have a pNext field
// as their first structure member.
//
typedef struct _Dns_List
{
PVOID pFirst;
PVOID pLast;
}
DNS_LIST, *PDNS_LIST;
//
// To init pFirst is NULL.
// But pLast points at the location of the pFirst pointer -- essentially
// treating the DNS_LIST as an element and pFirst as its next ptr.
//
// During an add, the address given in pLast, is set with the new element,
// equivalent to setting pLast's pNext field. Then pLast is reset to point
// at a new element.
//
// When the first element is added to the list, pLast is pointing at the
// DNS_LIST structure itself, so pFirst (as a dummy pNext) is set with
// the ptr to the first element.
//
// This works ONLY for elements which have a pNext field as the first
// structure member.
//
#define DNS_LIST_INIT( pList ) \
{ \
PDNS_LIST _plist = (pList); \
_plist->pFirst = NULL; \
_plist->pLast = (_plist); \
}
#define DNS_LIST_ADD( pList, pnew ) \
{ \
PDNS_LIST _plist = (pList); \
PVOID _pnew = (pnew); \
*(PVOID*)(_plist->pLast) = _pnew; \
_plist->pLast = _pnew; \
}
#define IS_DNS_LIST_EMPTY( pList ) \
( (pList)->pFirst == NULL )
//
// DNS_LIST as structure macros
//
// Faster when function contains DNS_LIST structure itself and
// NO SIDE EFFECTS will be present in call.
//
#define DNS_LIST_STRUCT_INIT( List ) \
{ \
List.pFirst = NULL; \
List.pLast = &List; \
}
#define DNS_LIST_STRUCT_ADD( List, pnew ) \
{ \
*(PVOID*)(List.pLast) = (PVOID)pnew; \
List.pLast = (PVOID)pnew; \
}
#define IS_DNS_LIST_STRUCT_EMPTY( List ) \
( List.pFirst == NULL )
//
// Record building (rralloc.c)
//
PDNS_RECORD
WINAPI
Dns_AllocateRecord(
IN WORD wBufferLength
);
VOID
WINAPI
Dns_RecordFree(
IN OUT PDNS_RECORD pRecord
);
#if 1
// Old BS with flag -- kill when all fixed up
VOID
WINAPI
Dns_RecordListFreeEx(
IN OUT PDNS_RECORD pRRList,
IN BOOL fFreeOwner
);
#define Dns_RecordListFree(p, f) Dns_RecordListFreeEx(p, f)
#else // new version
VOID
WINAPI
Dns_RecordListFree(
IN OUT PDNS_RECORD pRRList
);
#endif
PDNS_RECORD
Dns_RecordSetDetach(
IN OUT PDNS_RECORD pRRList
);
PDNS_RECORD
WINAPI
Dns_RecordListAppend(
IN OUT PDNS_RECORD pHeadList,
IN PDNS_RECORD pTailList
);
DWORD
Dns_RecordListCount(
IN PDNS_RECORD pRRList,
IN WORD wType
);
//
// Record build from data strings (rrbuild.c)
//
PDNS_RECORD
Dns_RecordBuild_A(
IN OUT PDNS_RRSET pRRSet,
IN PSTR pszOwner,
IN WORD wType,
IN BOOL fAdd,
IN UCHAR Section,
IN INT Argc,
IN PCHAR * Argv
);
PDNS_RECORD
Dns_RecordBuild_W(
IN OUT PDNS_RRSET pRRSet,
IN PWSTR pszOwner,
IN WORD wType,
IN BOOL fAdd,
IN UCHAR Section,
IN INT Argc,
IN PWCHAR * Argv
);
//
// Record to\from string functions.
//
DNS_STATUS
Dns_WriteRecordToString(
OUT PCHAR pBuffer,
IN DWORD BufferLength,
IN PDNS_RECORD pRecord,
IN DNS_CHARSET CharSet,
IN DWORD Flags
);
PDNS_RECORD
Dns_CreateRecordFromString(
IN PSTR pString,
IN DNS_CHARSET CharSet,
IN DWORD Flags
);
//
// Record set manipulation
//
//
// Record Compare
//
// Note: these routines will NOT do proper unicode compare, unless
// records have the fUnicode flag set.
//
BOOL
WINAPI
Dns_RecordCompare(
IN PDNS_RECORD pRecord1,
IN PDNS_RECORD pRecord2
);
BOOL
WINAPI
Dns_RecordSetCompare(
IN OUT PDNS_RECORD pRR1,
IN OUT PDNS_RECORD pRR2,
OUT PDNS_RECORD * ppDiff1, OPTIONAL
OUT PDNS_RECORD * ppDiff2 OPTIONAL
);
typedef enum _DnsSetCompareResult
{
DnsSetCompareError = (-1),
DnsSetCompareIdentical,
DnsSetCompareNoOverlap,
DnsSetCompareOneSubsetOfTwo,
DnsSetCompareTwoSubsetOfOne,
DnsSetCompareIntersection
}
DNS_SET_COMPARE_RESULT;
DNS_SET_COMPARE_RESULT
WINAPI
Dns_RecordSetCompareEx(
IN OUT PDNS_RECORD pRR1,
IN OUT PDNS_RECORD pRR2,
OUT PDNS_RECORD * ppDiff1, OPTIONAL
OUT PDNS_RECORD * ppDiff2 OPTIONAL
);
BOOL
WINAPI
Dns_RecordSetCompareForIntersection(
IN OUT PDNS_RECORD pRR1,
IN OUT PDNS_RECORD pRR2
);
//
// Record set prioritization (rrsort.c)
//
BOOL
Dns_CompareIpAddresses(
IN IP4_ADDRESS addr1,
IN IP4_ADDRESS addr2,
IN IP4_ADDRESS subnetMask
);
//
// DNS Name compare
//
BOOL
Dns_NameCompare_A(
IN PCSTR pName1,
IN PCSTR pName2
);
BOOL
Dns_NameCompare_W(
IN PCWSTR pName1,
IN PCWSTR pName2
);
BOOL
Dns_NameCompare_UTF8(
IN PCSTR pName1,
IN PCSTR pName2
);
BOOL
Dns_NameComparePrivate(
IN PCSTR pName1,
IN PCSTR pName2,
IN DNS_CHARSET CharSet
);
//
// Advanced name comparison
// Includes hierarchial name relationship.
//
DNS_NAME_COMPARE_STATUS
Dns_NameCompareEx(
IN LPCSTR pszNameLeft,
IN LPCSTR pszNameRight,
IN DWORD dwReserved,
IN DNS_CHARSET CharSet
);
//
// Record Copy
//
PDNS_RECORD
WINAPI
Dns_RecordCopyEx(
IN PDNS_RECORD pRecord,
IN DNS_CHARSET CharSetIn,
IN DNS_CHARSET CharSetOut
);
//
// RR Set copy
//
PDNS_RECORD
WINAPI
Dns_RecordSetCopyEx(
IN PDNS_RECORD pRR,
IN DNS_CHARSET CharSetIn,
IN DNS_CHARSET CharSetOut
);
//
// Record \ type routines
//
//
// Resource record type\name mapping table
//
typedef struct
{
PCHAR pszTypeName; // type string (used in database files)
WORD wType; // type in host byte order
}
TYPE_NAME_TABLE;
extern TYPE_NAME_TABLE TypeTable[];
//
// Max record name length, allows upcasing of incoming labels
// to optimize comparisons
//
#define MAX_RECORD_NAME_LENGTH (8)
//
// Record type specific sizes
//
#define WKS_MAX_PORT (1024) // max well known service port
#define WKS_MAX_BITMASK_LENGTH (128) // 1024bits / 8bits/byte
#define SIZEOF_A6_ADDRESS_SUFFIX_LENGTH 16
#define SIZEOF_SOA_FIXED_DATA (5 * sizeof(DWORD))
#define SIZEOF_MX_FIXED_DATA (sizeof(WORD))
#define SIZEOF_WKS_FIXED_DATA (SIZEOF_IP4_ADDRESS+ sizeof(BYTE))
#define SIZEOF_KEY_FIXED_DATA (sizeof(DWORD))
#define SIZEOF_SIG_FIXED_DATA (4 * sizeof(DWORD) + sizeof(WORD))
#define SIZEOF_NXT_FIXED_DATA (0)
#define SIZEOF_LOC_FIXED_DATA (4 * sizeof(DWORD))
#define SIZEOF_SRV_FIXED_DATA (3 * sizeof(WORD))
#define SIZEOF_A6_FIXED_DATA (1 + SIZEOF_A6_ADDRESS_SUFFIX_LENGTH)
#define SIZEOF_TKEY_FIXED_DATA (2 * sizeof(DWORD) + 4 * sizeof(WORD))
#define SIZEOF_TSIG_PRE_SIG_FIXED_DATA (2 * sizeof(DWORD) + sizeof(WORD))
#define SIZEOF_TSIG_POST_SIG_FIXED_DATA (3 * sizeof(WORD))
#define SIZEOF_TSIG_FIXED_DATA (2 * sizeof(DWORD) + 4 * sizeof(WORD))
#define SIZEOF_WINS_FIXED_DATA (4 * sizeof(DWORD))
#define SIZEOF_NBSTAT_FIXED_DATA (3 * sizeof(DWORD))
//
// Record type routines
// These ones are of possible public interest and exposed in dnsapi.dll
//
BOOL
_fastcall
Dns_IsAMailboxType(
IN WORD wType
);
WORD
Dns_RecordTypeForNameA(
IN PCHAR pszName,
IN INT cchNameLength
);
WORD
Dns_RecordTypeForNameW(
IN PWCHAR pchName,
IN INT cchNameLength
);
#define Dns_RecordTypeForName(p,c) Dns_RecordTypeForNameA((p),(c))
BOOL
Dns_WriteStringForType_A(
OUT PCHAR pBuffer,
IN WORD wType
);
BOOL
Dns_WriteStringForType_W(
OUT PWCHAR pBuffer,
IN WORD wType
);
PCHAR
Dns_RecordStringForType(
IN WORD wType
);
PCHAR
Dns_RecordStringForWritableType(
IN WORD wType
);
//
// Record type specific stuff
//
BOOL
Dns_IsStringCountValidForTextType(
IN WORD wType,
IN WORD StringCount
);
//
// ATMA conversions
//
DWORD
Dns_AtmaAddressLengthForAddressString(
IN PCHAR pchString,
IN DWORD dwStringLength
);
DNS_STATUS
Dns_AtmaStringToAddress(
OUT PBYTE pAddress,
IN OUT PDWORD pdwAddrLength,
IN PCHAR pchString,
IN DWORD dwStringLength
);
PCHAR
Dns_AtmaAddressToString(
OUT PCHAR pchString,
IN UCHAR AddrType,
IN PBYTE pAddress,
IN DWORD dwAddrLength
);
//
// DNSSEC SIG and KEY routines
//
// Max key is 4096 bit giving 512 byte length.
//
// Max string representation is actually 33% larger as each three byte (24bit)
// block contains four base64 characters.
#define DNS_MAX_KEY_LENGTH (512)
#define DNS_MAX_KEY_STRING_LENGTH (685)
WORD
Dns_KeyRecordFlagForString(
IN PCHAR pchName,
IN INT cchNameLength
);
PCHAR
Dns_KeyRecordFlagString(
IN DWORD dwFlag,
IN OUT PCHAR pchFlag
);
UCHAR
Dns_KeyRecordProtocolForString(
IN PCHAR pchName,
IN INT cchNameLength
);
PCHAR
Dns_GetKeyProtocolString(
IN UCHAR uchProtocol
);
UCHAR
Dns_SecurityAlgorithmForString(
IN PCHAR pchName,
IN INT cchNameLength
);
PCHAR
Dns_GetDnssecAlgorithmString(
IN UCHAR uchAlgorithm
);
UCHAR
Dns_SecurityBase64CharToBits(
IN CHAR ch64
);
DNS_STATUS
Dns_SecurityBase64StringToKey(
OUT PBYTE pKey,
OUT PDWORD pKeyLength,
IN PCHAR pchString,
IN DWORD cchLength
);
PCHAR
Dns_SecurityKeyToBase64String(
IN PBYTE pKey,
IN DWORD KeyLength,
OUT PCHAR pchBuffer
);
LONG
Dns_ParseSigTime(
IN PCHAR pchString,
IN INT cchLength
);
PCHAR
Dns_SigTimeString(
IN LONG SigTime,
OUT PCHAR pchBuffer
);
//
// WINS \ WINS-R types detection
//
#define IS_WINS_TYPE(type) (((type) & 0xfffc) == 0xff00)
//
// MS WINS mapping flags
//
// return on invalid WINS flag
#define DNS_WINS_FLAG_ERROR (-1)
// max length of WINS flags
// pass buffer at least this big
#define WINS_FLAG_MAX_LENGTH (80)
DWORD
Dns_WinsRecordFlagForString(
IN PCHAR pchName,
IN INT cchNameLength
);
PCHAR
Dns_WinsRecordFlagString(
IN DWORD dwFlag,
IN OUT PCHAR pchFlag
);
//
// must sit here until PDNS_RECORD defined in public dns.h header
//
DNS_STATUS
Dns_RecordWriteFileString(
IN PDNS_RECORD pRecord,
IN PSTR pszZoneName,
IN DWORD dwDefaultTtl OPTIONAL
);
//
// IP Address to\from string utilities (straddr.c)
//
//
// String to Address
//
BOOL
Dns_Ip4StringToAddress_W(
OUT PIP4_ADDRESS pIp4Addr,
IN PCWSTR pwString
);
BOOL
Dns_Ip4StringToAddress_A(
OUT PIP4_ADDRESS pIp4Addr,
IN PCSTR pString
);
BOOL
Dns_Ip6StringToAddress_A(
OUT PIP6_ADDRESS pIp6Addr,
IN PCSTR pString
);
BOOL
Dns_Ip6StringToAddress_W(
OUT PIP6_ADDRESS pIp6Addr,
IN PCWSTR pwString
);
//
// Combined IP4\IP6 string to address
//
BOOL
Dns_StringToAddress_W(
OUT PCHAR pAddrBuf,
IN OUT PDWORD pBufLength,
IN PCWSTR pString,
IN OUT PDWORD pAddrFamily
);
BOOL
Dns_StringToAddress_A(
OUT PCHAR pAddrBuf,
IN OUT PDWORD pBufLength,
IN PCSTR pString,
IN OUT PDWORD pAddrFamily
);
//
// Address to string
//
PWCHAR
Dns_Ip6AddressToString_W(
OUT PWCHAR pwString,
IN PIP6_ADDRESS pIp6Addr
);
PCHAR
Dns_Ip6AddressToString_A(
OUT PCHAR pchString,
IN PIP6_ADDRESS pIp6Addr
);
PWCHAR
Dns_Ip4AddressToString_W(
OUT PWCHAR pwString,
IN PIP4_ADDRESS pIp4Addr
);
PCHAR
Dns_Ip4AddressToString_A(
OUT PCHAR pString,
IN PIP4_ADDRESS pIp4Addr
);
//
// Address to string -- combined
//
PCHAR
Dns_AddressToString_A(
OUT PCHAR pchString,
IN OUT PDWORD pStringLength,
IN PBYTE pAddr,
IN DWORD AddrLength,
IN DWORD AddrFamily
);
//
// Reverse lookup address-to-name IP4
//
PCHAR
Dns_Ip4AddressToReverseName_A(
OUT PCHAR pBuffer,
IN IP4_ADDRESS IpAddr
);
PWCHAR
Dns_Ip4AddressToReverseName_W(
OUT PWCHAR pBuffer,
IN IP4_ADDRESS IpAddr
);
PCHAR
Dns_Ip4AddressToReverseNameAlloc_A(
IN IP4_ADDRESS IpAddr
);
PWCHAR
Dns_Ip4AddressToReverseNameAlloc_W(
IN IP4_ADDRESS IpAddr
);
//
// Reverse lookup address-to-name IP6
//
PCHAR
Dns_Ip6AddressToReverseName_A(
OUT PCHAR pBuffer,
IN IP6_ADDRESS Ip6Addr
);
PWCHAR
Dns_Ip6AddressToReverseName_W(
OUT PWCHAR pBuffer,
IN IP6_ADDRESS Ip6Addr
);
PCHAR
Dns_Ip6AddressToReverseNameAlloc_A(
IN IP6_ADDRESS Ip6Addr
);
PWCHAR
Dns_Ip6AddressToReverseNameAlloc_W(
IN IP6_ADDRESS Ip6Addr
);
//
// Reverse lookup name-to-address
//
BOOL
Dns_Ip4ReverseNameToAddress_A(
OUT PIP4_ADDRESS pIp4Addr,
IN PCSTR pszName
);
BOOL
Dns_Ip4ReverseNameToAddress_W(
OUT PIP4_ADDRESS pIp4Addr,
IN PCWSTR pwsName
);
BOOL
Dns_Ip6ReverseNameToAddress_A(
OUT PIP6_ADDRESS pIp6Addr,
IN PCSTR pszName
);
BOOL
Dns_Ip6ReverseNameToAddress_W(
OUT PIP6_ADDRESS pIp6Addr,
IN PCWSTR pwsName
);
//
// Combined IP4\IP6 reverse lookup name-to-address
//
BOOL
Dns_ReverseNameToAddress_W(
OUT PCHAR pAddrBuf,
IN OUT PDWORD pBufLength,
IN PCWSTR pString,
IN OUT PDWORD pAddrFamily
);
BOOL
Dns_ReverseNameToAddress_A(
OUT PCHAR pAddrBuf,
IN OUT PDWORD pBufLength,
IN PCSTR pString,
IN OUT PDWORD pAddrFamily
);
//
// String utilities (string.c)
//
// Note some of these require memory allocation, see note
// on memory allocation below.
//
// Flags are defined in dnsapi.h
//
//#define DNS_ALLOW_RFC_NAMES_ONLY (0)
//#define DNS_ALLOW_NONRFC_NAMES (0x00000001)
//#define DNS_ALLOW_MULTIBYTE_NAMES (0x00000002)
//#define DNS_ALLOW_ALL_NAMES (0x00000003)
//
// Unicode name buffer length.
// Non-type specific routines below take buffer counts in bytes.
// Unicode buffers of max name length have twice the bytes.
//
#define DNS_MAX_NAME_BUFFER_LENGTH_UNICODE (2 * DNS_MAX_NAME_BUFFER_LENGTH)
//
// Macros to simplify UTF8 conversions
//
// UTF8 is simply a representation of unicode that maps one-to-one
// for the ASCII space.
// Unicode UTF8
// ------- ----
// < 0x80 (128) -> use low byte (one-to-one mapping)
// < 0x07ff -> two chars
// > 0x07ff -> three chars
//
#define UTF8_1ST_OF_2 0xc0 // 110x xxxx
#define UTF8_1ST_OF_3 0xe0 // 1110 xxxx
#define UTF8_TRAIL 0x80 // 10xx xxxx
#define UTF8_2_MAX 0x07ff // max unicode character representable in
// in two byte UTF8
//
// Explicitly UTF8 string
//
typedef PSTR PU8STR;
PSTR
Dns_CreateStringCopy(
IN PCHAR pchString,
IN DWORD cchString
);
DWORD
Dns_GetBufferLengthForStringCopy(
IN PCHAR pchString,
IN DWORD cchString,
IN DNS_CHARSET CharSetIn,
IN DNS_CHARSET CharSetOut
);
DWORD
Dns_StringCopy(
OUT PBYTE pBuffer,
IN OUT PDWORD pdwBufLength,
IN PCHAR pchString,
IN DWORD cchString,
IN DNS_CHARSET CharSetIn,
IN DNS_CHARSET CharSetOut
);
PVOID
Dns_StringCopyAllocate(
IN PCHAR pchString,
IN DWORD cchString,
IN DNS_CHARSET CharSetIn,
IN DNS_CHARSET CharSetOut
);
#define Dns_StringCopyAllocate_W( p, c ) \
( (PWCHAR) Dns_StringCopyAllocate( \
(PCHAR) (p), \
(c), \
DnsCharSetUnicode, \
DnsCharSetUnicode ) )
#define Dns_StringCopyAllocate_A( p, c ) \
( (PCHAR) Dns_StringCopyAllocate( \
(p), \
(c), \
DnsCharSetUtf8, \
DnsCharSetUtf8 ) )
PSTR
Dns_CreateStringCopy_A(
IN PCSTR pwsString
);
PWSTR
Dns_CreateStringCopy_W(
IN PCWSTR pwsString
);
PWSTR
Dns_CreateConcatenatedString_W(
IN PCWSTR * pStringArray
);
PWSTR
Dns_GetResourceString(
IN DWORD dwStringId,
IN PWSTR pwszBuffer,
IN DWORD cbBuffer
);
INT
wcsicmp_ThatWorks(
IN PWSTR pString1,
IN PWSTR pString2
);
//
// Special DNS name string functions
//
#define Dns_GetBufferLengthForNameCopy(a,b,c,d)\
Dns_GetBufferLengthForStringCopy((a),(b),(c),(d))
#define Dns_NameCopy(a,b,c,d,e,f) \
Dns_StringCopy(a,b,c,d,e,f)
#define Dns_NameCopyAllocate(a,b,c,d) \
Dns_StringCopyAllocate(a,b,c,d)
//
// Name validation (string.c)
//
DNS_STATUS
Dns_ValidateName_UTF8(
IN LPCSTR pszName,
IN DNS_NAME_FORMAT Format
);
DNS_STATUS
Dns_ValidateName_W(
IN LPCWSTR pwszName,
IN DNS_NAME_FORMAT Format
);
DNS_STATUS
Dns_ValidateName_A(
IN LPCSTR pszName,
IN DNS_NAME_FORMAT Format
);
DNS_STATUS
Dns_ValidateDnsString_UTF8(
IN LPCSTR pszName
);
DNS_STATUS
Dns_ValidateDnsString_W(
IN LPCWSTR pszName
);
PSTR
Dns_CreateStandardDnsNameCopy(
IN PCHAR pchName,
IN DWORD cchName,
IN DWORD dwFlag
);
//
// UTF8 conversions (utf8.c)
//
DNS_STATUS
_fastcall
Dns_ValidateUtf8Byte(
IN BYTE chUtf8,
IN OUT PDWORD pdwTrailCount
);
DWORD
_fastcall
Dns_UnicodeToUtf8(
IN PWCHAR pwUnicode,
IN DWORD cchUnicode,
OUT PCHAR pchResult,
IN DWORD cchResult
);
DWORD
_fastcall
Dns_Utf8ToUnicode(
IN PCHAR pchUtf8,
IN DWORD cchUtf8,
OUT PWCHAR pwResult,
IN DWORD cwResult
);
DWORD
Dns_Utf8ToOrFromAnsi(
OUT PCHAR pchResult,
IN DWORD cchResult,
IN PCHAR pchIn,
IN DWORD cchIn,
IN DNS_CHARSET InCharSet,
IN DNS_CHARSET OutCharSet
);
DWORD
Dns_AnsiToUtf8(
IN PCHAR pchAnsi,
IN DWORD cchAnsi,
OUT PCHAR pchResult,
IN DWORD cchResult
);
DWORD
Dns_Utf8ToAnsi(
IN PCHAR pchUtf8,
IN DWORD cchUtf8,
OUT PCHAR pchResult,
IN DWORD cchResult
);
BOOL
_fastcall
Dns_IsStringAscii(
IN PSTR pszString
);
BOOL
_fastcall
Dns_IsStringAsciiEx(
IN PCHAR pchString,
IN DWORD cchString
);
BOOL
_fastcall
Dns_IsWideStringAscii(
IN PWSTR pwsString
);
//
// Resource record dispatch tables
//
// Resource record tables are indexed by type for standard types
// These define limits on tables.
//
// Currently indexing out to RR 40, so that we'll handle any new RR types
// out this far without interfering with WINS stuff.
//
#define MAX_SELF_INDEXED_TYPE (48)
//
// Mappings for non-self indexed types
//
// Note: these are presented here for information purposes only!
//
// Always call Dns_RecordTableIndexForType(wType) to get correct index.
//
#define TKEY_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 1)
#define TSIG_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 2)
#define WINS_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 3)
#define WINSR_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 4)
// End of actual record types.
// Query type indexes may extend beyond this index.
#define MAX_RECORD_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 4)
//
// Generic indexer for both regular and extended (non-self-indexing) types
//
#define INDEX_FOR_TYPE(type) Dns_RecordTableIndexForType(type)
//
// Type to index mapping
//
WORD
Dns_RecordTableIndexForType(
IN WORD wType
);
//
// Generic print routine
//
// All our print routines will take the real print routine
// as a parameter. This routine must have "sprintf-like"
// or "fprintf-like" semantics. In other words a context,
// format and variable number of arguments.
//
// Note the context argument is effectively a PVOID --
// different routines will have different contexts. The
// explicit definition is to enforce strong type checking
// so a call without a context is caught on compile.
//
typedef struct _DnsPrintContext
{
PVOID pvDummy;
DWORD Dummy;
}
PRINT_CONTEXT, *PPRINT_CONTEXT;
typedef VOID (* PRINT_ROUTINE)(
PPRINT_CONTEXT,
CHAR*,
... );
//
// RnR utilities
//
DWORD
Dns_RnrLupFlagForString(
IN PCHAR pchName,
IN INT cchNameLength
);
PCHAR
Dns_GetRnrLupFlagString(
IN DWORD dwFlag
);
DWORD
Dns_RnrNameSpaceIdForString(
IN PCHAR pchName,
IN INT cchNameLength
);
DWORD
Dns_RnrNameSpaceIdForStringW(
IN PWSTR pwsName
);
PCHAR
Dns_GetRnrNameSpaceIdString(
IN DWORD dwFlag
);
//
// Hostent utilities
//
BOOL
Hostent_IsSupportedAddrType(
IN WORD wType
);
DWORD
Hostent_Size(
IN PHOSTENT pHostent,
IN DNS_CHARSET CharSetExisting,
IN DNS_CHARSET CharSetTarget,
IN PDWORD pAliasCount,
IN PDWORD pAddrCount
);
PHOSTENT
Hostent_Copy(
IN OUT PBYTE * ppBuffer,
IN OUT PINT pBufferSize,
OUT PINT pHostentSize,
IN PHOSTENT pHostent,
IN DNS_CHARSET CharSetIn,
IN DNS_CHARSET CharSetTarget,
IN BOOL fOffsets,
IN BOOL fAlloc
);
DWORD
Hostent_WriteIp4Addrs(
IN OUT PHOSTENT pHostent,
OUT PCHAR pAddrBuf,
IN DWORD MaxBufCount,
IN PIP4_ADDRESS Ip4Array,
IN DWORD ArrayCount,
IN BOOL fScreenZero
);
DWORD
Hostent_WriteLocalIp4Array(
IN OUT PHOSTENT pHostent,
OUT PCHAR pAddrBuf,
IN DWORD MaxBufCount,
IN PIP4_ARRAY pIpArray
);
BOOL
Hostent_IsAddressInHostent(
IN OUT PHOSTENT pHostent,
IN PCHAR pAddr,
IN DWORD AddrLength,
IN INT Family OPTIONAL
);
BOOL
Hostent_IsIp4AddressInHostent(
IN OUT PHOSTENT pHostent,
IN IP4_ADDRESS Ip4Addr
);
//
// Hostent Object
//
typedef struct _HostentBlob
{
PHOSTENT pHostent;
// flags
BOOL fAllocatedBlob;
BOOL fAllocatedBuf;
// buffer allocated
PCHAR pBuffer;
DWORD BufferLength;
DWORD AvailLength;
PCHAR pAvailBuffer;
// buffer in build
PCHAR pCurrent;
DWORD BytesLeft;
// sizing info
DWORD MaxAliasCount;
DWORD MaxAddrCount;
// hostent building
DWORD AliasCount;
DWORD AddrCount;
BOOL fWroteName;
DNS_CHARSET CharSet;
BOOL fUnicode;
}
HOSTENT_BLOB, *PHOSTENT_BLOB;
typedef struct _HostentInitRequest
{
INT AddrFamily;
WORD wType;
DWORD AddrCount;
BOOL fUnicode;
DNS_CHARSET CharSet;
DWORD NameLength;
PBYTE pName;
DWORD AliasCount;
DWORD AliasNameLength;
}
HOSTENT_INIT, *PHOSTENT_INIT;
DNS_STATUS
HostentBlob_Create(
IN OUT PHOSTENT_BLOB * ppBlob,
IN PHOSTENT_INIT pReq
);
PHOSTENT_BLOB
HostentBlob_CreateAttachExisting(
IN PHOSTENT pHostent,
IN BOOL fUnicode
);
VOID
HostentBlob_Free(
IN OUT PHOSTENT_BLOB pBlob
);
DNS_STATUS
HostentBlob_WriteAddress(
IN OUT PHOSTENT_BLOB pBlob,
IN PVOID pAddress,
IN DWORD AddrSize,
IN DWORD AddrType
);
DNS_STATUS
HostentBlob_WriteAddressArray(
IN OUT PHOSTENT_BLOB pBlob,
IN PVOID pAddrArray,
IN DWORD AddrCount,
IN DWORD AddrSize,
IN DWORD AddrType
);
DNS_STATUS
HostentBlob_WriteNameOrAlias(
IN OUT PHOSTENT_BLOB pBlob,
IN PSTR pszName,
IN BOOL fAlias,
IN BOOL fUnicode
);
DNS_STATUS
HostentBlob_WriteRecords(
IN OUT PHOSTENT_BLOB pBlob,
IN PDNS_RECORD pRecords,
IN BOOL fWriteName
);
// Special hostents
PHOSTENT_BLOB
Hostent_Localhost(
IN INT AddrFamily
);
DNS_STATUS
HostentBlob_CreateFromIpArray(
IN OUT PHOSTENT_BLOB * ppBlob,
IN INT AddrFamily,
IN INT AddrSize,
IN INT AddrCount,
IN PCHAR pArray,
IN PSTR pName,
IN BOOL fUnicode
);
DNS_STATUS
HostentBlob_CreateLocal(
IN OUT PHOSTENT_BLOB * ppBlob,
IN INT AddrFamily,
IN BOOL fLoopback,
IN BOOL fZero,
IN BOOL fHostnameOnly
);
// Query for hostent
PHOSTENT_BLOB
HostentBlob_Query(
IN PWSTR pwsName,
IN WORD wType,
IN DWORD Flags,
IN OUT PVOID * ppMsg, OPTIONAL
IN INT AddrFamily OPTIONAL
);
//
// Sockaddr blob stuff (for RnR)
//
typedef DNS_SOCKADDR_RESULTS SABLOB, *PSABLOB;
PSABLOB
SaBlob_Create(
IN DWORD AddrCount
);
VOID
SaBlob_Free(
IN OUT PSABLOB pBlob
);
DNS_STATUS
SaBlob_WriteNameOrAlias(
IN OUT PSABLOB pBlob,
IN PWSTR pszName,
IN BOOL fAlias
);
PSABLOB
SaBlob_CreateFromIp4(
IN PWSTR pName,
IN DWORD AddrCount,
IN PIP4_ADDRESS pIpArray
);
PSABLOB
SaBlob_Query(
IN PWSTR pwsName,
IN WORD wType,
IN DWORD Flags,
IN OUT PVOID * ppMsg, OPTIONAL
IN INT AddrFamily OPTIONAL
);
PHOSTENT
SaBlob_CreateHostent(
IN OUT PBYTE * ppBuffer,
IN OUT PINT pBufferSize,
OUT PINT pHostentSize,
IN PSABLOB pBlob,
IN DNS_CHARSET CharSetTarget,
IN BOOL fOffsets,
IN BOOL fAlloc
);
//
// Memory allocation
//
// Some DNS library functions -- including the IP array and string utils
// -- allocate memory. This memory allocation defaults to routines that
// use LocalAlloc, LocalReAlloc, LocalFree. If you desire alternative
// memory allocation mechanisms, use this function to override the DNS
// library defaults. All memory allocated by the DNS library, should
// then be freed by the corresponding function.
//
typedef PVOID (* DNSLIB_ALLOC_FUNCTION)();
typedef PVOID (* DNSLIB_REALLOC_FUNCTION)();
typedef VOID (* DNSLIB_FREE_FUNCTION)();
VOID
Dns_LibHeapReset(
IN DNSLIB_ALLOC_FUNCTION pAlloc,
IN DNSLIB_REALLOC_FUNCTION pRealloc,
IN DNSLIB_FREE_FUNCTION pFree
);
//
// These routines call the currently registered allocation functions
// whether default or reset through Dns_ApiHeapReset()
//
PVOID
Dns_Alloc(
IN INT iSize
);
PVOID
Dns_AllocZero(
IN INT iSize
);
PVOID
Dns_Realloc(
IN OUT PVOID pMem,
IN INT iSize
);
VOID
Dns_Free(
IN OUT PVOID pMem
);
PVOID
Dns_AllocMemCopy(
IN PVOID pMem,
IN INT iSize
);
//
// DNS Test build
//
// Allow imbedding of extra info in IP4 arrays to pass to DnsQuery routines.
//
#ifdef DNSTEST_BUILD
typedef struct _DnsImbeddedExtra
{
DWORD Tag;
PDNS_EXTRA_INFO pExtraInfo;
}
DNS_IMBEDDED_EXTRA_INFO, *PDNS_IMBEDDED_EXTRA_INFO;
#define DNS_IMBEDDED_EXTRA_INFO_TAG (0xfedc1234)
#endif
//
// Print routines (print.c)
//
// Print routines below use any printf() like function to print.
// this is typedef that function must match.
//
//
// Print Locking
//
VOID
DnsPrint_InitLocking(
IN PCRITICAL_SECTION pLock
);
VOID
DnsPrint_Lock(
VOID
);
VOID
DnsPrint_Unlock(
VOID
);
#define Dns_PrintInitLocking(a) DnsPrint_InitLocking(a)
#define Dns_PrintLock() DnsPrint_Lock()
#define Dns_PrintUnlock() DnsPrint_Unlock()
//
// Print routines for general types and structures
//
VOID
DnsPrint_String(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader, OPTIONAL
IN PSTR pszString,
IN BOOL fUnicode,
IN PSTR pszTrailer OPTIONAL
);
VOID
DnsPrint_StringCharSet(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader, OPTIONAL
IN PSTR pszString,
IN DNS_CHARSET CharSet,
IN PSTR pszTrailer OPTIONAL
);
VOID
DnsPrint_Utf8StringBytes(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PCHAR pUtf8,
IN DWORD Length
);
VOID
DnsPrint_UnicodeStringBytes(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PWCHAR pUnicode,
IN DWORD Length
);
VOID
DnsPrint_StringArray(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PSTR * StringArray,
IN DWORD Count, OPTIONAL
IN BOOL fUnicode
);
VOID
DnsPrint_Argv(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN CHAR ** Argv,
IN DWORD Argc, OPTIONAL
IN BOOL fUnicode
);
VOID
DnsPrint_DwordArray(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PSTR pszName,
IN DWORD dwCount,
IN PDWORD adwArray
);
VOID
DnsPrint_Ip4AddressArray(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PSTR pszName,
IN DWORD dwIpAddrCount,
IN PIP4_ADDRESS pIpAddrs
);
VOID
DnsPrint_Ip4Array(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PSTR pszName,
IN PIP4_ARRAY pIpArray
);
VOID
DnsPrint_Ip6Address(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PIP6_ADDRESS pIp6Address,
IN PSTR pszTrailer
);
VOID
DnsPrint_Ip6Array(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PSTR pszName,
IN PIP6_ARRAY pIpArray
);
VOID
DnsPrint_Guid(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PGUID pGuid
);
//
// Winsock \ RnR types and structures
//
VOID
DnsPrint_FdSet(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN struct fd_set * pFdSet
);
VOID
DnsPrint_Hostent(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PHOSTENT pHostent,
IN BOOL fUnicode
);
VOID
DnsPrint_Sockaddr(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN DWORD Indent,
IN PSOCKADDR pSockaddr,
IN INT iSockaddrLength
);
#ifdef _WINSOCK2API_
VOID
DnsPrint_SocketAddress(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN DWORD Indent,
IN PSOCKET_ADDRESS pSocketAddress
);
VOID
DnsPrint_CsAddr(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN DWORD Indent,
IN PCSADDR_INFO pCsAddrInfo
);
VOID
DnsPrint_AfProtocolsArray(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PAFPROTOCOLS pProtocolArray,
IN DWORD ProtocolCount
);
VOID
DnsPrint_WsaQuerySet(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN LPWSAQUERYSET pQuerySet,
IN BOOL fUnicode
);
VOID
DnsPrint_WsaNsClassInfo(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PWSANSCLASSINFO pInfo,
IN BOOL fUnicode
);
VOID
DnsPrint_WsaServiceClassInfo(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN LPWSASERVICECLASSINFO pInfo,
IN BOOL fUnicode
);
#endif
#ifdef _WS2TCPIP_H_
VOID
DnsPrint_AddrInfoEx(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN DWORD Indent,
IN PADDRINFO pAddrInfo,
IN BOOL fUnicode
);
VOID
DnsPrint_AddrInfoListEx(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN DWORD Indent,
IN PADDRINFO pAddrInfo,
IN BOOL fUnicode
);
// ANSI ADDRINFO
#define DnsPrint_AddrInfo( pr, c, h, i, pa ) \
DnsPrint_AddrInfoEx( pr, c, h, i, pa, FALSE )
#define DnsPrint_AddrInfoList( pr, c, h, i, pa ) \
DnsPrint_AddrInfoListEx( pr, c, h, i, pa, FALSE )
// Unicode ADDRINFOW
#define DnsPrint_AddrInfoW( pr, c, h, i, pa ) \
DnsPrint_AddrInfoEx( pr, c, h, i, pa, TRUE )
#define DnsPrint_AddrInfoListW( pr, c, h, i, pa ) \
DnsPrint_AddrInfoListEx( pr, c, h, i, pa, TRUE )
#endif
#ifdef IP_TYPES_INCLUDED
VOID
DnsPrint_IpAdapterAddress(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PVOID pAddr,
IN BOOL fUnicast,
IN BOOL fPrintList
);
VOID
DnsPrint_IpAdapterList(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PIP_ADAPTER_ADDRESSES pAdapt,
IN BOOL fPrintAddressLists,
IN BOOL fPrintList
);
#endif
//
// Print routines for DNS types and structures
//
VOID
DnsPrint_DnsAddrLine(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PDNS_ADDR pAddr,
IN PSTR pszTrailer
);
VOID
DnsPrint_DnsAddr(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN DWORD Indent,
IN PDNS_ADDR pAddr
);
VOID
DnsPrint_DnsAddrArray(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PSTR pszName,
IN PDNS_ADDR_ARRAY pArray
);
VOID
DnsPrint_Message(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PDNS_MSG_BUF pMsg
);
VOID
DnsPrint_MessageNoContext(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PDNS_HEADER pMsgHead,
IN WORD wLength
);
INT
DnsPrint_PacketName(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader, OPTIONAL
IN PBYTE pMsgName,
IN PDNS_HEADER pMsgHead, OPTIONAL
IN PBYTE pMsgEnd, OPTIONAL
IN PSTR pszTrailer OPTIONAL
);
INT
DnsPrint_PacketRecord(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PDNS_WIRE_RECORD pMsgRR,
IN PDNS_HEADER pMsgHead, OPTIONAL
IN PBYTE pMsgEnd OPTIONAL
);
VOID
DnsPrint_ParsedRecord(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PDNS_PARSED_RR pParsedRR
);
VOID
DnsPrint_RawOctets(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PSTR pszLineHeader,
IN PCHAR pchData,
IN DWORD dwLength
);
VOID
DnsPrint_ParsedMessage(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PDNS_PARSED_MESSAGE pParsed
);
VOID
DnsPrint_HostentBlob(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PHOSTENT_BLOB pBlob
);
VOID
DnsPrint_SaBlob(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PSABLOB pBlob
);
//
// Print to string
//
#define GUID_STRING_BUFFER_LENGTH (80)
DWORD
DnsStringPrint_Guid(
OUT PCHAR pBuffer,
IN PGUID pGuid
);
DWORD
DnsStringPrint_RawOctets(
OUT PCHAR pBuffer,
IN PCHAR pchData,
IN DWORD dwLength,
IN PSTR pszLineHeader,
IN DWORD dwLineLength
);
//
// Print related utilities
//
INT
Dns_WriteFormattedSystemTimeToBuffer(
OUT PCHAR pBuffer,
IN PSYSTEMTIME pSystemTime
);
INT
Dns_WritePacketNameToBuffer(
OUT PCHAR pBuffer,
OUT PCHAR * ppBufferOut,
IN PBYTE pMsgName,
IN PDNS_HEADER pMsgHead, OPTIONAL
IN PBYTE pMsgEnd OPTIONAL
);
PCHAR
Dns_ResponseCodeString(
IN INT ResponseCode
);
PCHAR
Dns_ResponseCodeExplanationString(
IN INT ResponseCode
);
PCHAR
Dns_KeyFlagString(
IN OUT PCHAR pszBuff,
IN WORD flags
);
PCHAR
Dns_OpcodeString(
IN INT Opcode
);
CHAR
Dns_OpcodeCharacter(
IN INT Opcode
);
PCHAR
Dns_SectionNameString(
IN INT iSection,
IN INT iOpcode
);
//
// Record printing (rrprint.c)
//
VOID
DnsPrint_Record(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PDNS_RECORD pRecord,
IN PDNS_RECORD pPreviousRecord OPTIONAL
);
VOID
DnsPrint_RecordSet(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pContext,
IN PSTR pszHeader,
IN PDNS_RECORD pRecord
);
//
// Macros to get correct string type (utf8\unicode) for printing.
//
// Empty string for simple switching of UTF-8/Unicode print
extern DWORD DnsEmptyString;
#define pDnsEmptyString ( (PSTR) &DnsEmptyString )
#define pDnsEmptyWideString ( (PWSTR) &DnsEmptyString )
#define DNSSTRING_UTF8( fUnicode, String ) \
( (fUnicode) ? pDnsEmptyString : (PSTR)(String) )
#define DNSSTRING_ANSI( fUnicode, String ) \
( (fUnicode) ? pDnsEmptyString : (PSTR)(String) )
#define DNSSTRING_WIDE( fUnicode, String ) \
( (fUnicode) ? (PWSTR)(String) : pDnsEmptyWideString )
#define RECSTRING_UTF8( pRR, String ) \
DNSSTRING_UTF8( IS_UNICODE_RECORD(pRR), (String) )
#define RECSTRING_WIDE( pRR, String ) \
DNSSTRING_WIDE( IS_UNICODE_RECORD(pRR), (String) )
#define PRINT_STRING_WIDE_CHARSET( String, CharSet ) \
( ((CharSet)==DnsCharSetUnicode) ? (PWSTR)(String) : pDnsEmptyWideString )
#define PRINT_STRING_ANSI_CHARSET( String, CharSet ) \
( ((CharSet)==DnsCharSetUnicode) ? pDnsEmptyString : (PSTR)(String) )
//
// Debugging
//
// Debug routines.
//
VOID
Dns_StartDebugEx(
IN DWORD DebugFlag,
IN PSTR pszFlagFile,
IN OUT PDWORD pdwExternalFlag,
IN PSTR pszLogFile,
IN DWORD WrapSize,
IN BOOL fUseGlobalFile,
IN BOOL fUseGlobalFlag,
IN BOOL fSetGlobals
);
VOID
Dns_StartDebug(
IN DWORD DebugFlag,
IN PSTR pszFlagFile,
IN OUT PDWORD pdwExternalFlag,
IN PSTR pszLogFile,
IN DWORD WrapSize
);
VOID
Dns_EndDebug(
VOID
);
VOID
Dns_Assert(
IN PSTR pszFile,
IN INT LineNo,
IN PSTR pszExpr
);
VOID
DnsDbg_PrintfToDebugger(
IN PSTR Format,
...
);
VOID
DnsDbg_Printf(
IN PSTR Format,
...
);
VOID
DnsDbg_PrintRoutine(
IN OUT PPRINT_CONTEXT pContext,
IN PSTR Format,
...
);
VOID
DnsDbg_Flush(
VOID
);
VOID
DnsDbg_WrapLogFile(
VOID
);
VOID
DnsDbg_CSEnter(
IN PCRITICAL_SECTION pLock,
IN PSTR pszLockName,
IN PSTR pszFile,
IN INT LineNo
);
VOID
DnsDbg_CSLeave(
IN PCRITICAL_SECTION pLock,
IN PSTR pszLockName,
IN PSTR pszFile,
IN INT LineNo
);
//
// Debug flag test
//
// We make the test against a pointer here which allows library
// client application to point at a flag that may be dynamically
// reset.
//
extern PDWORD pDnsDebugFlag;
#define IS_DNSDBG_ON(flag) (*pDnsDebugFlag & DNS_DBG_ ## flag)
//
// Debugging Bit Flags
//
// These flags control gross output and are the same for all users
//
#define DNS_DBG_BREAKPOINTS 0x00000001
#define DNS_DBG_DEBUGGER 0x00000002
#define DNS_DBG_FILE 0x00000004
#define DNS_DBG_EVENTLOG 0x00000008
#define DNS_DBG_EXCEPT 0x00000008
#define DNS_DBG_TIMESTAMP 0x10000000
#define DNS_DBG_CONSOLE 0x20000000
#define DNS_DBG_START_BREAK 0x40000000
#define DNS_DBG_FLUSH 0x80000000
#define DNS_DBG_ANY 0xffffffff
#define DNS_DBG_ALL 0xffffffff
#define DNS_DBG_OFF (0x0)
//
// Flags specific to library
//
#define DNS_DBG_IPARRAY 0x00000020
#define DNS_DBG_INIT 0x00000040
#define DNS_DBG_REGISTRY 0x00000040
#define DNS_DBG_SOCKET 0x00000040
#define DNS_DBG_WRITE 0x00000080
#define DNS_DBG_READ 0x00000080
#define DNS_DBG_RPC 0x00000100
#define DNS_DBG_STUB 0x00000100
#define DNS_DBG_RECV 0x00000200
#define DNS_DBG_SEND 0x00000400
#define DNS_DBG_TCP 0x00000800
#define DNS_DBG_TRACE 0x00001000
#define DNS_DBG_UPDATE 0x00002000
#define DNS_DBG_FAZ 0x00002000
#define DNS_DBG_SECURITY 0x00004000
#define DNS_DBG_QUERY 0x00008000
#define DNS_DBG_HEAP 0x00010000
#define DNS_DBG_HEAPDBG 0x00020000
#define DNS_DBG_NETINFO 0x00040000
#define DNS_DBG_RNR 0x00080000
#define DNS_DBG_HOSTENT 0x00080000
#define DNS_DBG_SABLOB 0x00080000
//
// High output detail debugging
//
#define DNS_DBG_RECURSE2 0x00100000
#define DNS_DBG_UPDATE2 0x00200000
#define DNS_DBG_SECURITY2 0x00400000
#define DNS_DBG_RPC2 0x01000000
#define DNS_DBG_STUB2 0x01000000
#define DNS_DBG_INIT2 0x01000000
#define DNS_DBG_NETINFO2 0x01000000
#define DNS_DBG_PARSE2 0x01000000
#define DNS_DBG_LOOKUP2 0x02000000
#define DNS_DBG_WRITE2 0x04000000
#define DNS_DBG_READ2 0x04000000
#define DNS_DBG_LOCK 0x08000000
#define DNS_DBG_LOCKS 0x08000000
#define DNS_DBG_STRING 0x10000000
#define DNS_DBG_HEAP2 0x10000000
#define DNS_DBG_HEAP_CHECK 0x10000000
//
// Debug macros
//
// Macros that include debug code in debug versions only,
// these macro are NULL for retail versions.
//
#if DBG
#define STATIC
#define DNS_PRINT(_a_) ( DnsDbg_Printf _a_ )
#define DnsPrintfPtrToFunc DnsDbg_PrintRoutine
#define IF_DNSDBG(flag) if ( IS_DNSDBG_ON(flag) )
#define ELSE_IF_DNSDBG(flag) else if ( IS_DNSDBG_ON(flag) )
#define ELSE else
#define DNSDBG(flag, _printlist_) \
IF_DNSDBG( flag ) \
{ \
( DnsDbg_Printf _printlist_ ); \
}
// protect debug prints with print lock
#define DnsDbg_Lock() DnsPrint_Lock()
#define DnsDbg_Unlock() DnsPrint_Unlock()
//
// Probe
//
#define PROBE(p) (*p)
//
// Assert Macros
//
#define DNS_ASSERT( expr ) \
{ \
if ( !(expr) ) \
{ \
Dns_Assert( __FILE__, __LINE__, # expr ); \
} \
}
#define TEST_ASSERT( expr ) DNS_ASSERT( expr )
#define FAIL( msg ) \
{ \
DNS_PRINT(( "FAILURE: %s\n", msg )); \
DNS_ASSERT( FALSE ); \
}
//
// Asserts on trailing else
//
#define ELSE_ASSERT( expr ) \
else \
{ \
DNS_ASSERT( expr ); \
}
#define ELSE_ASSERT_FALSE \
else \
{ \
DNS_ASSERT( FALSE );\
}
#define ELSE_FAIL( msg ) \
else \
{ \
FAIL( msg ); \
}
//
// Assert and print message
//
#define DNS_MSG_ASSERT( pMsg, expr ) \
{ \
if ( !(expr) ) \
{ \
debug_MessageBuffer( "FAILED MESSAGE:", (pMsg) ); \
Dns_Assert( __FILE__, __LINE__, # expr ); \
} \
}
//
// Debug types and structures
//
#define DnsPR DnsDbg_PrintRoutine
#define DnsDbg_String(a,b,c,d) DnsPrint_String(DnsPR,NULL,a,b,c,d)
#define DnsDbg_UnicodeStringBytes(a,b,c) DnsPrint_UnicodeStringBytes(DnsPR,NULL,a,b,c)
#define DnsDbg_Utf8StringBytes(a,b,c) DnsPrint_Utf8StringBytes(DnsPR,NULL,a,b,c)
#define DnsDbg_StringArray(a,b,c,d) DnsPrint_StringArray(DnsPR,NULL,a,b,c,d)
#define DnsDbg_Argv(a,b,c,d) DnsPrint_Argv(DnsPR,NULL,a,b,c,d)
#define DnsDbg_DwordArray(a,b,c,d) DnsPrint_DwordArray(DnsPR,NULL,a,b,c,d)
#define DnsDbg_Ip4AddressArray(a,b,c,d) DnsPrint_Ip4AddressArray(DnsPR,NULL,a,b,c,d)
#define DnsDbg_Ip4Array(a,b,c) DnsPrint_Ip4Array(DnsPR,NULL,a,b,c)
#define DnsDbg_Ip6Address(a,b,c) DnsPrint_Ip6Address(DnsPR,NULL,a,b,c)
#define DnsDbg_Ip6Array(a,b,c) DnsPrint_Ip6Array(DnsPR,NULL,a,b,c)
#define DnsDbg_Guid(a,b) DnsPrint_Guid(DnsPR,NULL,a,b)
#define DnsDbg_FdSet(a,b) DnsPrint_FdSet(DnsPR,NULL,a,b)
#define DnsDbg_Sockaddr(a,b,c) DnsPrint_Sockaddr(DnsPR,NULL,a,0,b,c)
#define DnsDbg_SocketAddress(a,b) DnsPrint_SocketAddress(DnsPR,NULL,a,0,b)
#define DnsDbg_CsAddr(a,b) DnsPrint_CsAddr(DnsPR,NULL,a,0,b)
#define DnsDbg_AfProtocolsArray(a,b,c) DnsPrint_AfProtocolsArray(DnsPR,NULL,a,b,c)
#define DnsDbg_WsaQuerySet(a,b,c) DnsPrint_WsaQuerySet(DnsPR,NULL,a,b,c)
#define DnsDbg_WsaNsClassInfo(a,b,c) DnsPrint_WsaNsClassInfo(DnsPR,NULL,a,b,c)
#define DnsDbg_WsaServiceClassInfo(a,b,c) DnsPrint_WsaServiceClassInfo(DnsPR,NULL,a,b,c)
#define DnsDbg_Hostent(a,b,c) DnsPrint_Hostent(DnsPR,NULL,a,b,c)
#define DnsDbg_AddrInfo(a,b) DnsPrint_AddrInfo(DnsPR,NULL,a,0,b)
#define DnsDbg_HostentBlob(a,b) DnsPrint_HostentBlob(DnsPR,NULL,a,b)
#define DnsDbg_SaBlob(a,b) DnsPrint_SaBlob(DnsPR,NULL,a,b)
#define DnsDbg_IpAdapterAddress(a,b,c,d) DnsPrint_IpAdapterAddress(DnsPR,NULL,a,b,c,d)
#define DnsDbg_IpAdapterList(a,b,c,d) DnsPrint_IpAdapterList(DnsPR,NULL,a,b,c,d)
#define DnsDbg_DnsAddrLine(a,b,c) DnsPrint_DnsAddrLine(DnsPR,NULL,a,b,c)
#define DnsDbg_DnsAddr(a,b) DnsPrint_DnsAddr(DnsPR,NULL,a,0,b)
#define DnsDbg_DnsAddrArray(a,b,c) DnsPrint_DnsAddrArray(DnsPR,NULL,a,b,c)
#define DnsDbg_DnsMessage(a,b) DnsPrint_DnsMessage(DnsPR,NULL,a,b)
#define DnsDbg_Message(a,b) DnsPrint_Message(DnsPR,NULL,a,b)
#define DnsDbg_MessageNoContext(a,b,c) DnsPrint_MessageNoContext(DnsPR,NULL,a,b,c)
#define DnsDbg_Compression(a,b) DnsPrint_Compression(DnsPR,NULL,a,b)
#define DnsDbg_PacketRecord(a,b,c,d) DnsPrint_PacketRecord(DnsPR,NULL,a,b,c,d)
#define DnsDbg_PacketName(a,b,c,d,e) DnsPrint_PacketName(DnsPR,NULL,a,b,c,d,e)
#define DnsDbg_ParsedMessage(a,b) DnsPrint_ParsedMessage(DnsPR,NULL,(a),(b))
#define DnsDbg_RawOctets(a,b,c,d) DnsPrint_RawOctets(DnsPR,NULL,a,b,c,d)
#define DnsDbg_Record(a,b) DnsPrint_Record(DnsPR,NULL,a,b,NULL)
#define DnsDbg_RecordSet(a,b) DnsPrint_RecordSet(DnsPR,NULL,a,b)
//
// Non-Debug
//
#else
#define STATIC static
//
// Define away debugging operations
//
#define IF_DNSDBG(a) if (0)
#define ELSE_IF_DNSDBG(a) if (0)
#define ELSE if (0)
#define DNSDBG(flag, _printlist_)
#define DNS_PRINT(_printlist_)
#define DnsDbg_Lock()
#define DnsDbg_Unlock()
#define DnsDbg_CSEnter(a,b,c,d)
#define DnsDbg_CSLeave(a,b,c,d)
#define DnsDbg_String(a,b,c,d)
#define DnsDbg_UnicodeStringBytes(a,b,c)
#define DnsDbg_Utf8StringBytes(a,b,c)
#define DnsDbg_DwordArray(a,b,c,d)
#define DnsDbg_StringArray(a,b,c,d)
#define DnsDbg_Argv(a,b,c,d)
#define DnsDbg_Ip4AddressArray(a,b,c,d)
#define DnsDbg_Ip4Array(a,b,c)
#define DnsDbg_Ip6Address(a,b,c)
#define DnsDbg_Ip6Array(a,b,c)
#define DnsDbg_Guid(a,b)
#define DnsDbg_FdSet(a,b)
#define DnsDbg_Sockaddr(a,b,c)
#define DnsDbg_SocketAddress(a,b)
#define DnsDbg_CsAddr(a,b)
#define DnsDbg_AfProtocolsArray(a,b,c)
#define DnsDbg_WsaQuerySet(a,b,c)
#define DnsDbg_WsaNsClassInfo(a,b,c)
#define DnsDbg_WsaServiceClassInfo(a,b,c)
#define DnsDbg_Hostent(a,b,c)
#define DnsDbg_AddrInfo(a,b)
#define DnsDbg_HostentBlob(a,b)
#define DnsDbg_SaBlob(a,b)
#define DnsDbg_IpAdapterAddress(a,b,c,d)
#define DnsDbg_IpAdapterList(a,b,c,d)
#define DnsDbg_DnsAddrLine(a,b,c)
#define DnsDbg_DnsAddr(a,b)
#define DnsDbg_DnsAddrArray(a,b,c)
#define DnsDbg_DnsMessage(a,b)
#define DnsDbg_Message(a,b)
#define DnsDbg_MessageNoContext(a,b,c)
#define DnsDbg_Compression(a,b)
#define DnsDbg_PacketRecord(a,b,c,d)
#define DnsDbg_PacketName(a,b,c,d,e)
#define DnsDbg_ParsedMessage(a,b)
#define DnsDbg_RawOctets(a,b,c,d)
#define DnsDbg_Record(a,b)
#define DnsDbg_RecordSet(a,b)
// backcompat special on sockaddr
#define DnsDbg_SockaddrIn(a,b,c)
//
// Handle complilation of DnsPrintf used as passed parameter to
// print routines
//
#define DnsPrintfPtrToFunc printf
//
// Eliminate ASSERTs in retail product
//
#define DNS_ASSERT( expr )
#define TEST_ASSERT( expr )
#define ELSE_ASSERT( expr )
#define ELSE_ASSERT_FALSE
#define DNS_MSG_ASSERT( expr, pMsg )
#define FAIL( msg )
#define ELSE_FAIL( msg )
#define PROBE(p)
#endif // non-DBG
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // _DNSLIB_INCLUDED_