windows-nt/Source/XPSP1/NT/ds/published/inc/windns.w
2020-09-26 16:20:57 +08:00

1706 lines
40 KiB
OpenEdge ABL
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1996-2000 Microsoft Corporation
Module Name:
windns.h
Abstract:
Domain Name System (DNS)
DNS definitions and DNS API.
Author:
Jim Gilroy (jamesg) December 7, 1996
Glenn Curtis (glennc) January 22, 1997
Revision History:
--*/
#ifndef _WINDNS_INCLUDED_
#define _WINDNS_INCLUDED_
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
//
// Define QWORD -- not yet defined globally
//
typedef unsigned __int64 QWORD;
//
// DNS public types
//
typedef LONG DNS_STATUS, *PDNS_STATUS;
//
// IP Address
//
typedef DWORD IP4_ADDRESS, *PIP4_ADDRESS;
#define SIZEOF_IP4_ADDRESS (4)
#define IP4_ADDRESS_STRING_LENGTH (15)
#define IP4_ADDRESS_STRING_BUFFER_LENGTH (16)
//
// IP Address Array type
//
typedef struct _IP4_ARRAY
{
DWORD AddrCount;
#ifdef MIDL_PASS
[size_is( AddrCount )] IP4_ADDRESS AddrArray[];
#else
IP4_ADDRESS AddrArray[1];
#endif
}
IP4_ARRAY, *PIP4_ARRAY;
//
// IPv6 Address
//
#ifdef MIDL_PASS
typedef struct
{
#ifdef _WIN64
QWORD IP6Qword[2];
#else
DWORD IP6Dword[4];
#endif
}
IP6_ADDRESS, *PIP6_ADDRESS;
#else
typedef union
{
#ifdef _WIN64
QWORD IP6Qword[2];
#endif
DWORD IP6Dword[4];
WORD IP6Word[8];
BYTE IP6Byte[16];
#ifdef IN6_ADDR
IN6_ADDR In6;
#endif
}
IP6_ADDRESS, *PIP6_ADDRESS;
#endif
// Backward compatibility
typedef IP6_ADDRESS DNS_IP6_ADDRESS, *PDNS_IP6_ADDRESS;
//
// IP6 string max is 45 bytes
// - 6 WORDs in colon+hex (5 chars)
// - last DWORD as IP4 (15 chars)
//
#undef IP6_ADDRESS_STRING_LENGTH
#define IP6_ADDRESS_STRING_LENGTH (47)
#define IP6_ADDRESS_STRING_BUFFER_LENGTH (48)
// backcompat
#define IPV6_ADDRESS_STRING_LENGTH IP6_ADDRESS_STRING_LENGTH
//
// Inline byte flipping -- can be done in registers
//
#define INLINE_WORD_FLIP(out, in) \
{ \
WORD _in = (in); \
(out) = (_in << 8) | (_in >> 8); \
}
#define INLINE_HTONS(out, in) INLINE_WORD_FLIP(out, in)
#define INLINE_NTOHS(out, in) INLINE_WORD_FLIP(out, in)
#define INLINE_DWORD_FLIP(out, in) \
{ \
DWORD _in = (in); \
(out) = ((_in << 8) & 0x00ff0000) | \
(_in << 24) | \
((_in >> 8) & 0x0000ff00) | \
(_in >> 24); \
}
#define INLINE_NTOHL(out, in) INLINE_DWORD_FLIP(out, in)
#define INLINE_HTONL(out, in) INLINE_DWORD_FLIP(out, in)
//
// Inline byte flip and write to packet (unaligned)
//
#define INLINE_WRITE_FLIPPED_WORD( pout, in ) \
INLINE_WORD_FLIP( *((UNALIGNED WORD *)(pout)), in )
#define INLINE_WRITE_FLIPPED_DWORD( pout, in ) \
INLINE_DWORD_FLIP( *((UNALIGNED DWORD *)(pout)), in )
//
// Basic DNS definitions
//
//
// DNS port for both UDP and TCP is 53.
//
#define DNS_PORT_HOST_ORDER (0x0035) // port 53
#define DNS_PORT_NET_ORDER (0x3500)
//
// DNS UDP packets no more than 512 bytes
//
#define DNS_RFC_MAX_UDP_PACKET_LENGTH (512)
//
// DNS Names limited to 255, 63 in any one label
//
#define DNS_MAX_NAME_LENGTH (255)
#define DNS_MAX_LABEL_LENGTH (63)
#define DNS_MAX_NAME_BUFFER_LENGTH (256)
#define DNS_MAX_LABEL_BUFFER_LENGTH (64)
//
// Reverse lookup domain names
//
#define DNS_IP4_REVERSE_DOMAIN_STRING ("in-addr.arpa.")
#define DNS_MAX_IP4_REVERSE_NAME_LENGTH \
(IP_ADDRESS_STRING_LENGTH+1+sizeof(DNS_IP4_REVERSE_DOMAIN_STRING))
#define DNS_MAX_IP4_REVERSE_NAME_BUFFER_LENGTH \
(DNS_MAX_IP4_REVERSE_NAME_LENGTH + 1)
#define DNS_IP6_REVERSE_DOMAIN_STRING ("ip6.int.")
#define DNS_MAX_IP6_REVERSE_NAME_LENGTH \
(64+sizeof(DNS_IP6_REVERSE_DOMAIN_STRING))
#define DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH \
(DNS_MAX_IP6_REVERSE_NAME_LENGTH + 1)
// Combined
#define DNS_MAX_REVERSE_NAME_LENGTH \
DNS_MAX_IP6_REVERSE_NAME_LENGTH \
#define DNS_MAX_REVERSE_NAME_BUFFER_LENGTH \
DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH
//
// DNS Text string limited by size representable
// in a single byte length field
#define DNS_MAX_TEXT_STRING_LENGTH (255)
//
// DNS On-The-Wire Structures
//
#pragma pack(1)
//
// DNS Message Header
//
typedef struct _DNS_HEADER
{
WORD Xid;
BYTE RecursionDesired : 1;
BYTE Truncation : 1;
BYTE Authoritative : 1;
BYTE Opcode : 4;
BYTE IsResponse : 1;
BYTE ResponseCode : 4;
BYTE Reserved : 3;
BYTE RecursionAvailable : 1;
WORD QuestionCount;
WORD AnswerCount;
WORD NameServerCount;
WORD AdditionalCount;
}
DNS_HEADER, *PDNS_HEADER;
//
// Flags as WORD
//
#define DNS_HEADER_FLAGS(pHead) ( *((PWORD)(pHead)+1) )
//
// Byte flip DNS header to\from host order.
//
// Note that this does NOT flip flags, as definition above defines
// flags as individual bytes for direct access to net byte order.
//
#define DNS_BYTE_FLIP_HEADER_COUNTS(pHeader) \
{ \
PDNS_HEADER _head = (pHeader); \
INLINE_HTONS(_head->Xid, _head->Xid ); \
INLINE_HTONS(_head->QuestionCount, _head->QuestionCount ); \
INLINE_HTONS(_head->AnswerCount, _head->AnswerCount ); \
INLINE_HTONS(_head->NameServerCount,_head->NameServerCount ); \
INLINE_HTONS(_head->AdditionalCount,_head->AdditionalCount ); \
}
//
// Question name follows header
//
#define DNS_OFFSET_TO_QUESTION_NAME sizeof(DNS_HEADER)
//
// Question immediately follows header so compressed question name
// 0xC000 | sizeof(DNS_HEADER)
#define DNS_COMPRESSED_QUESTION_NAME (0xC00C)
//
// Packet extraction macros
//
#define DNS_QUESTION_NAME_FROM_HEADER( _pHeader_ ) \
( (PCHAR)( (PDNS_HEADER)(_pHeader_) + 1 ) )
#define DNS_ANSWER_FROM_QUESTION( _pQuestion_ ) \
( (PCHAR)( (PDNS_QUESTION)(_pQuestion_) + 1 ) )
//
// DNS Question
//
typedef struct _DNS_WIRE_QUESTION
{
// Preceded by question name
WORD QuestionType;
WORD QuestionClass;
}
DNS_WIRE_QUESTION, *PDNS_WIRE_QUESTION;
//
// DNS Resource Record
//
typedef struct _DNS_WIRE_RECORD
{
// Preceded by record owner name
WORD RecordType;
WORD RecordClass;
DWORD TimeToLive;
WORD DataLength;
// Followed by record data
}
DNS_WIRE_RECORD, *PDNS_WIRE_RECORD;
#pragma pack()
//
// DNS Query Types
//
#define DNS_OPCODE_QUERY 0 // Query
#define DNS_OPCODE_IQUERY 1 // Obsolete: IP to name
#define DNS_OPCODE_SERVER_STATUS 2 // Obsolete: DNS ping
#define DNS_OPCODE_UNKNOWN 3 // Unknown
#define DNS_OPCODE_NOTIFY 4 // Notify
#define DNS_OPCODE_UPDATE 5 // Dynamic Update
//
// DNS response codes.
//
// Sent in the "ResponseCode" field of a DNS_HEADER.
//
#define DNS_RCODE_NOERROR 0
#define DNS_RCODE_FORMERR 1 // Format error
#define DNS_RCODE_SERVFAIL 2 // Server failure
#define DNS_RCODE_NXDOMAIN 3 // Name error
#define DNS_RCODE_NOTIMPL 4 // Not implemented
#define DNS_RCODE_REFUSED 5 // Refused
#define DNS_RCODE_YXDOMAIN 6 // Domain name should not exist
#define DNS_RCODE_YXRRSET 7 // RR set should not exist
#define DNS_RCODE_NXRRSET 8 // RR set does not exist
#define DNS_RCODE_NOTAUTH 9 // Not authoritative for zone
#define DNS_RCODE_NOTZONE 10 // Name is not zone
#define DNS_RCODE_MAX 15
//
// Extended RCODEs
//
#define DNS_RCODE_BADVERS 16 // Bad EDNS version
#define DNS_RCODE_BADSIG 16 // Bad signature
#define DNS_RCODE_BADKEY 17 // Bad key
#define DNS_RCODE_BADTIME 18 // Bad timestamp
//
// Mappings to friendly names
//
#define DNS_RCODE_NO_ERROR DNS_RCODE_NOERROR
#define DNS_RCODE_FORMAT_ERROR DNS_RCODE_FORMERR
#define DNS_RCODE_SERVER_FAILURE DNS_RCODE_SERVFAIL
#define DNS_RCODE_NAME_ERROR DNS_RCODE_NXDOMAIN
#define DNS_RCODE_NOT_IMPLEMENTED DNS_RCODE_NOTIMPL
//
// DNS Classes
//
// Classes are on the wire as WORDs.
//
// _CLASS_ defines in host order.
// _RCLASS_ defines in net byte order.
//
// Generally we'll avoid byte flip and test class in net byte order.
//
#define DNS_CLASS_INTERNET 0x0001 // 1
#define DNS_CLASS_CSNET 0x0002 // 2
#define DNS_CLASS_CHAOS 0x0003 // 3
#define DNS_CLASS_HESIOD 0x0004 // 4
#define DNS_CLASS_NONE 0x00fe // 254
#define DNS_CLASS_ALL 0x00ff // 255
#define DNS_CLASS_ANY 0x00ff // 255
#define DNS_RCLASS_INTERNET 0x0100 // 1
#define DNS_RCLASS_CSNET 0x0200 // 2
#define DNS_RCLASS_CHAOS 0x0300 // 3
#define DNS_RCLASS_HESIOD 0x0400 // 4
#define DNS_RCLASS_NONE 0xfe00 // 254
#define DNS_RCLASS_ALL 0xff00 // 255
#define DNS_RCLASS_ANY 0xff00 // 255
//
// DNS Record Types
//
// _TYPE_ defines are in host byte order.
// _RTYPE_ defines are in net byte order.
//
// Generally always deal with types in host byte order as we index
// resource record functions by type.
//
#define DNS_TYPE_ZERO 0x0000
// RFC 1034/1035
#define DNS_TYPE_A 0x0001 // 1
#define DNS_TYPE_NS 0x0002 // 2
#define DNS_TYPE_MD 0x0003 // 3
#define DNS_TYPE_MF 0x0004 // 4
#define DNS_TYPE_CNAME 0x0005 // 5
#define DNS_TYPE_SOA 0x0006 // 6
#define DNS_TYPE_MB 0x0007 // 7
#define DNS_TYPE_MG 0x0008 // 8
#define DNS_TYPE_MR 0x0009 // 9
#define DNS_TYPE_NULL 0x000a // 10
#define DNS_TYPE_WKS 0x000b // 11
#define DNS_TYPE_PTR 0x000c // 12
#define DNS_TYPE_HINFO 0x000d // 13
#define DNS_TYPE_MINFO 0x000e // 14
#define DNS_TYPE_MX 0x000f // 15
#define DNS_TYPE_TEXT 0x0010 // 16
// RFC 1183
#define DNS_TYPE_RP 0x0011 // 17
#define DNS_TYPE_AFSDB 0x0012 // 18
#define DNS_TYPE_X25 0x0013 // 19
#define DNS_TYPE_ISDN 0x0014 // 20
#define DNS_TYPE_RT 0x0015 // 21
// RFC 1348
#define DNS_TYPE_NSAP 0x0016 // 22
#define DNS_TYPE_NSAPPTR 0x0017 // 23
// RFC 2065 (DNS security)
#define DNS_TYPE_SIG 0x0018 // 24
#define DNS_TYPE_KEY 0x0019 // 25
// RFC 1664 (X.400 mail)
#define DNS_TYPE_PX 0x001a // 26
// RFC 1712 (Geographic position)
#define DNS_TYPE_GPOS 0x001b // 27
// RFC 1886 (IPv6 Address)
#define DNS_TYPE_AAAA 0x001c // 28
// RFC 1876 (Geographic location)
#define DNS_TYPE_LOC 0x001d // 29
// RFC 2065 (Secure negative response)
#define DNS_TYPE_NXT 0x001e // 30
// Patton (Endpoint Identifier)
#define DNS_TYPE_EID 0x001f // 31
// Patton (Nimrod Locator)
#define DNS_TYPE_NIMLOC 0x0020 // 32
// RFC 2052 (Service location)
#define DNS_TYPE_SRV 0x0021 // 33
// ATM Standard something-or-another (ATM Address)
#define DNS_TYPE_ATMA 0x0022 // 34
// RFC 2168 (Naming Authority Pointer)
#define DNS_TYPE_NAPTR 0x0023 // 35
// RFC 2230 (Key Exchanger)
#define DNS_TYPE_KX 0x0024 // 36
// RFC 2538 (CERT)
#define DNS_TYPE_CERT 0x0025 // 37
// A6 Draft (A6)
#define DNS_TYPE_A6 0x0026 // 38
// DNAME Draft (DNAME)
#define DNS_TYPE_DNAME 0x0027 // 39
// Eastlake (Kitchen Sink)
#define DNS_TYPE_SINK 0x0028 // 40
// RFC 2671 (EDNS OPT)
#define DNS_TYPE_OPT 0x0029 // 41
//
// IANA Reserved
//
#define DNS_TYPE_UINFO 0x0064 // 100
#define DNS_TYPE_UID 0x0065 // 101
#define DNS_TYPE_GID 0x0066 // 102
#define DNS_TYPE_UNSPEC 0x0067 // 103
//
// Query only types (1035, 1995)
// - Crawford (ADDRS)
// - TKEY draft (TKEY)
// - TSIG draft (TSIG)
// - RFC 1995 (IXFR)
// - RFC 1035 (AXFR up)
//
#define DNS_TYPE_ADDRS 0x00f8 // 248
#define DNS_TYPE_TKEY 0x00f9 // 249
#define DNS_TYPE_TSIG 0x00fa // 250
#define DNS_TYPE_IXFR 0x00fb // 251
#define DNS_TYPE_AXFR 0x00fc // 252
#define DNS_TYPE_MAILB 0x00fd // 253
#define DNS_TYPE_MAILA 0x00fe // 254
#define DNS_TYPE_ALL 0x00ff // 255
#define DNS_TYPE_ANY 0x00ff // 255
//
// Temp Microsoft types -- use until get IANA approval for real type
//
#define DNS_TYPE_WINS 0xff01 // 64K - 255
#define DNS_TYPE_WINSR 0xff02 // 64K - 254
#define DNS_TYPE_NBSTAT (DNS_TYPE_WINSR)
//
// DNS Record Types -- Net Byte Order
//
#define DNS_RTYPE_A 0x0100 // 1
#define DNS_RTYPE_NS 0x0200 // 2
#define DNS_RTYPE_MD 0x0300 // 3
#define DNS_RTYPE_MF 0x0400 // 4
#define DNS_RTYPE_CNAME 0x0500 // 5
#define DNS_RTYPE_SOA 0x0600 // 6
#define DNS_RTYPE_MB 0x0700 // 7
#define DNS_RTYPE_MG 0x0800 // 8
#define DNS_RTYPE_MR 0x0900 // 9
#define DNS_RTYPE_NULL 0x0a00 // 10
#define DNS_RTYPE_WKS 0x0b00 // 11
#define DNS_RTYPE_PTR 0x0c00 // 12
#define DNS_RTYPE_HINFO 0x0d00 // 13
#define DNS_RTYPE_MINFO 0x0e00 // 14
#define DNS_RTYPE_MX 0x0f00 // 15
#define DNS_RTYPE_TEXT 0x1000 // 16
#define DNS_RTYPE_RP 0x1100 // 17
#define DNS_RTYPE_AFSDB 0x1200 // 18
#define DNS_RTYPE_X25 0x1300 // 19
#define DNS_RTYPE_ISDN 0x1400 // 20
#define DNS_RTYPE_RT 0x1500 // 21
#define DNS_RTYPE_NSAP 0x1600 // 22
#define DNS_RTYPE_NSAPPTR 0x1700 // 23
#define DNS_RTYPE_SIG 0x1800 // 24
#define DNS_RTYPE_KEY 0x1900 // 25
#define DNS_RTYPE_PX 0x1a00 // 26
#define DNS_RTYPE_GPOS 0x1b00 // 27
#define DNS_RTYPE_AAAA 0x1c00 // 28
#define DNS_RTYPE_LOC 0x1d00 // 29
#define DNS_RTYPE_NXT 0x1e00 // 30
#define DNS_RTYPE_EID 0x1f00 // 31
#define DNS_RTYPE_NIMLOC 0x2000 // 32
#define DNS_RTYPE_SRV 0x2100 // 33
#define DNS_RTYPE_ATMA 0x2200 // 34
#define DNS_RTYPE_NAPTR 0x2300 // 35
#define DNS_RTYPE_KX 0x2400 // 36
#define DNS_RTYPE_CERT 0x2500 // 37
#define DNS_RTYPE_A6 0x2600 // 38
#define DNS_RTYPE_DNAME 0x2700 // 39
#define DNS_RTYPE_SINK 0x2800 // 40
#define DNS_RTYPE_OPT 0x2900 // 41
//
// IANA Reserved
//
#define DNS_RTYPE_UINFO 0x6400 // 100
#define DNS_RTYPE_UID 0x6500 // 101
#define DNS_RTYPE_GID 0x6600 // 102
#define DNS_RTYPE_UNSPEC 0x6700 // 103
//
// Query only types
//
#define DNS_RTYPE_TKEY 0xf900 // 249
#define DNS_RTYPE_TSIG 0xfa00 // 250
#define DNS_RTYPE_IXFR 0xfb00 // 251
#define DNS_RTYPE_AXFR 0xfc00 // 252
#define DNS_RTYPE_MAILB 0xfd00 // 253
#define DNS_RTYPE_MAILA 0xfe00 // 254
#define DNS_RTYPE_ALL 0xff00 // 255
#define DNS_RTYPE_ANY 0xff00 // 255
//
// Temp Microsoft types -- use until get IANA approval for real type
//
#define DNS_RTYPE_WINS 0x01ff // 64K - 255
#define DNS_RTYPE_WINSR 0x02ff // 64K - 254
//
// Record type specific definitions
//
//
// ATMA (ATM address type) formats
//
// Define these directly for any environment (ex NT4)
// without winsock2 ATM support (ws2atm.h)
//
#ifndef ATMA_E164
#define DNS_ATMA_FORMAT_E164 1
#define DNS_ATMA_FORMAT_AESA 2
#define DNS_ATMA_MAX_ADDR_LENGTH (20)
#else
#define DNS_ATMA_FORMAT_E164 ATM_E164
#define DNS_ATMA_FORMAT_AESA ATM_AESA
#define DNS_ATMA_MAX_ADDR_LENGTH ATM_ADDR_SIZE
#endif
#define DNS_ATMA_AESA_ADDR_LENGTH (20)
#define DNS_ATMA_MAX_RECORD_LENGTH (DNS_ATMA_MAX_ADDR_LENGTH+1)
//
// DNSSEC defs
//
// DNSSEC algorithms
#define DNSSEC_ALGORITHM_RSAMD5 1
#define DNSSEC_ALGORITHM_NULL 253
#define DNSSEC_ALGORITHM_PRIVATE 254
// DNSSEC KEY protocol table
#define DNSSEC_PROTOCOL_NONE 0
#define DNSSEC_PROTOCOL_TLS 1
#define DNSSEC_PROTOCOL_EMAIL 2
#define DNSSEC_PROTOCOL_DNSSEC 3
#define DNSSEC_PROTOCOL_IPSEC 4
// DNSSEC KEY flag field
#define DNSSEC_KEY_FLAG_NOAUTH 0x0001
#define DNSSEC_KEY_FLAG_NOCONF 0x0002
#define DNSSEC_KEY_FLAG_FLAG2 0x0004
#define DNSSEC_KEY_FLAG_EXTEND 0x0008
#define DNSSEC_KEY_FLAG_
#define DNSSEC_KEY_FLAG_FLAG4 0x0010
#define DNSSEC_KEY_FLAG_FLAG5 0x0020
// bits 6,7 are name type
#define DNSSEC_KEY_FLAG_USER 0x0000
#define DNSSEC_KEY_FLAG_ZONE 0x0040
#define DNSSEC_KEY_FLAG_HOST 0x0080
#define DNSSEC_KEY_FLAG_NTPE3 0x00c0
// bits 8-11 are reserved for future use
#define DNSSEC_KEY_FLAG_FLAG8 0x0100
#define DNSSEC_KEY_FLAG_FLAG9 0x0200
#define DNSSEC_KEY_FLAG_FLAG10 0x0400
#define DNSSEC_KEY_FLAG_FLAG11 0x0800
// bits 12-15 are sig field
#define DNSSEC_KEY_FLAG_SIG0 0x0000
#define DNSSEC_KEY_FLAG_SIG1 0x1000
#define DNSSEC_KEY_FLAG_SIG2 0x2000
#define DNSSEC_KEY_FLAG_SIG3 0x3000
#define DNSSEC_KEY_FLAG_SIG4 0x4000
#define DNSSEC_KEY_FLAG_SIG5 0x5000
#define DNSSEC_KEY_FLAG_SIG6 0x6000
#define DNSSEC_KEY_FLAG_SIG7 0x7000
#define DNSSEC_KEY_FLAG_SIG8 0x8000
#define DNSSEC_KEY_FLAG_SIG9 0x9000
#define DNSSEC_KEY_FLAG_SIG10 0xa000
#define DNSSEC_KEY_FLAG_SIG11 0xb000
#define DNSSEC_KEY_FLAG_SIG12 0xc000
#define DNSSEC_KEY_FLAG_SIG13 0xd000
#define DNSSEC_KEY_FLAG_SIG14 0xe000
#define DNSSEC_KEY_FLAG_SIG15 0xf000
//
// TKEY modes
//
#define DNS_TKEY_MODE_SERVER_ASSIGN 1
#define DNS_TKEY_MODE_DIFFIE_HELLMAN 2
#define DNS_TKEY_MODE_GSS 3
#define DNS_TKEY_MODE_RESOLVER_ASSIGN 4
//
// WINS + NBSTAT flag field
//
#define DNS_WINS_FLAG_SCOPE (0x80000000)
#define DNS_WINS_FLAG_LOCAL (0x00010000)
//
// Helpful checks
//
#define IS_WORD_ALIGNED(p) ( !((UINT_PTR)(p) & (UINT_PTR)1) )
#define IS_DWORD_ALIGNED(p) ( !((UINT_PTR)(p) & (UINT_PTR)3) )
#define IS_QWORD_ALIGNED(p) ( !((UINT_PTR)(p) & (UINT_PTR)7) )
//
// DNS config API
//
//
// Types of DNS configuration info
//
typedef enum
{
// In Win2K
DnsConfigPrimaryDomainName_W,
DnsConfigPrimaryDomainName_A,
DnsConfigPrimaryDomainName_UTF8,
// Not available yet
DnsConfigAdapterDomainName_W,
DnsConfigAdapterDomainName_A,
DnsConfigAdapterDomainName_UTF8,
// In Win2K
DnsConfigDnsServerList,
// Not available yet
DnsConfigSearchList,
DnsConfigAdapterInfo,
// In Win2K
DnsConfigPrimaryHostNameRegistrationEnabled,
DnsConfigAdapterHostNameRegistrationEnabled,
DnsConfigAddressRegistrationMaxCount,
// In WindowsXP
DnsConfigHostName_W,
DnsConfigHostName_A,
DnsConfigHostName_UTF8,
DnsConfigFullHostName_W,
DnsConfigFullHostName_A,
DnsConfigFullHostName_UTF8
}
DNS_CONFIG_TYPE;
//
// Config API flags
//
//
// Causes config info to be allocated with LocalAlloc()
//
#define DNS_CONFIG_FLAG_ALLOC (0x00000001)
DNS_STATUS
WINAPI
DnsQueryConfig(
IN DNS_CONFIG_TYPE Config,
IN DWORD Flag,
IN PWSTR pwsAdapterName,
IN PVOID pReserved,
OUT PVOID pBuffer,
IN OUT PDWORD pBufferLength
);
//
// DNS resource record structure
//
//
// Record data for specific types
//
typedef struct
{
IP4_ADDRESS IpAddress;
}
DNS_A_DATA, *PDNS_A_DATA;
typedef struct
{
LPTSTR pNameHost;
}
DNS_PTR_DATA, *PDNS_PTR_DATA;
typedef struct
{
LPTSTR pNamePrimaryServer;
LPTSTR pNameAdministrator;
DWORD dwSerialNo;
DWORD dwRefresh;
DWORD dwRetry;
DWORD dwExpire;
DWORD dwDefaultTtl;
}
DNS_SOA_DATA, *PDNS_SOA_DATA;
typedef struct
{
LPTSTR pNameMailbox;
LPTSTR pNameErrorsMailbox;
}
DNS_MINFO_DATA, *PDNS_MINFO_DATA;
typedef struct
{
LPTSTR pNameExchange;
WORD wPreference;
WORD Pad; // keep ptrs DWORD aligned
}
DNS_MX_DATA, *PDNS_MX_DATA;
typedef struct
{
DWORD dwStringCount;
#ifdef MIDL_PASS
[size_is(dwStringCount)] LPTSTR pStringArray[];
#else
LPTSTR pStringArray[1];
#endif
}
DNS_TXT_DATA, *PDNS_TXT_DATA;
typedef struct
{
DWORD dwByteCount;
#ifdef MIDL_PASS
[size_is(dwByteCount)] BYTE Data[];
#else
BYTE Data[1];
#endif
}
DNS_NULL_DATA, *PDNS_NULL_DATA;
typedef struct
{
IP4_ADDRESS IpAddress;
UCHAR chProtocol;
BYTE BitMask[1];
}
DNS_WKS_DATA, *PDNS_WKS_DATA;
typedef struct
{
DNS_IP6_ADDRESS Ip6Address;
}
DNS_AAAA_DATA, *PDNS_AAAA_DATA;
typedef struct
{
LPTSTR pNameSigner;
WORD wTypeCovered;
BYTE chAlgorithm;
BYTE chLabelCount;
DWORD dwOriginalTtl;
DWORD dwExpiration;
DWORD dwTimeSigned;
WORD wKeyTag;
WORD Pad; // keep byte field aligned
BYTE Signature[1];
}
DNS_SIG_DATA, *PDNS_SIG_DATA;
typedef struct
{
WORD wFlags;
BYTE chProtocol;
BYTE chAlgorithm;
BYTE Key[1];
}
DNS_KEY_DATA, *PDNS_KEY_DATA;
typedef struct
{
WORD wVersion;
WORD wSize;
WORD wHorPrec;
WORD wVerPrec;
DWORD dwLatitude;
DWORD dwLongitude;
DWORD dwAltitude;
}
DNS_LOC_DATA, *PDNS_LOC_DATA;
typedef struct
{
LPTSTR pNameNext;
WORD wNumTypes;
WORD wTypes[1];
}
DNS_NXT_DATA, *PDNS_NXT_DATA;
typedef struct
{
LPTSTR pNameTarget;
WORD wPriority;
WORD wWeight;
WORD wPort;
WORD Pad; // keep ptrs DWORD aligned
}
DNS_SRV_DATA, *PDNS_SRV_DATA;
typedef struct
{
BYTE AddressType;
BYTE Address[ DNS_ATMA_MAX_ADDR_LENGTH ];
// E164 -- Null terminated string of less than
// DNS_ATMA_MAX_ADDR_LENGTH
//
// For NSAP (AESA) BCD encoding of exactly
// DNS_ATMA_AESA_ADDR_LENGTH
}
DNS_ATMA_DATA, *PDNS_ATMA_DATA;
typedef struct
{
LPTSTR pNameAlgorithm;
PBYTE pAlgorithmPacket;
PBYTE pKey;
PBYTE pOtherData;
DWORD dwCreateTime;
DWORD dwExpireTime;
WORD wMode;
WORD wError;
WORD wKeyLength;
WORD wOtherLength;
UCHAR cAlgNameLength;
BOOL bPacketPointers;
}
DNS_TKEY_DATA, *PDNS_TKEY_DATA;
typedef struct
{
LPTSTR pNameAlgorithm;
PBYTE pAlgorithmPacket;
PBYTE pSignature;
PBYTE pOtherData;
LONGLONG i64CreateTime;
WORD wFudgeTime;
WORD wOriginalXid;
WORD wError;
WORD wSigLength;
WORD wOtherLength;
UCHAR cAlgNameLength;
BOOL bPacketPointers;
}
DNS_TSIG_DATA, *PDNS_TSIG_DATA;
//
// MS only types -- only hit the wire in MS-MS zone transfer
//
typedef struct
{
DWORD dwMappingFlag;
DWORD dwLookupTimeout;
DWORD dwCacheTimeout;
DWORD cWinsServerCount;
IP4_ADDRESS WinsServers[1];
}
DNS_WINS_DATA, *PDNS_WINS_DATA;
typedef struct
{
DWORD dwMappingFlag;
DWORD dwLookupTimeout;
DWORD dwCacheTimeout;
LPTSTR pNameResultDomain;
}
DNS_WINSR_DATA, *PDNS_WINSR_DATA;
//
// Length of non-fixed-length data types
//
#define DNS_TEXT_RECORD_LENGTH(StringCount) \
(FIELD_OFFSET(DNS_TXT_DATA, pStringArray) + ((StringCount) * sizeof(PCHAR)))
#define DNS_NULL_RECORD_LENGTH(ByteCount) \
(FIELD_OFFSET(DNS_NULL_DATA, Data) + (ByteCount))
#define DNS_WKS_RECORD_LENGTH(ByteCount) \
(FIELD_OFFSET(DNS_WKS_DATA, BitMask) + (ByteCount))
#define DNS_WINS_RECORD_LENGTH(IpCount) \
(FIELD_OFFSET(DNS_WINS_DATA, WinsServers) + ((IpCount) * sizeof(IP4_ADDRESS)))
//
// Record flags
//
typedef struct _DnsRecordFlags
{
DWORD Section : 2;
DWORD Delete : 1;
DWORD CharSet : 2;
DWORD Unused : 3;
DWORD Reserved : 24;
}
DNS_RECORD_FLAGS;
//
// Wire Record Sections
//
// Useable both in record flags "Section" and as index into
// wire message header section counts.
//
typedef enum _DnsSection
{
DnsSectionQuestion,
DnsSectionAnswer,
DnsSectionAuthority,
DnsSectionAddtional,
}
DNS_SECTION;
// Update message section names
#define DnsSectionZone DnsSectionQuestion
#define DnsSectionPrereq DnsSectionAnswer
#define DnsSectionUpdate DnsSectionAuthority
//
// Record flags as bit flags
// These may be or'd together to set the fields
//
// RR Section in packet
#define DNSREC_SECTION (0x00000003)
#define DNSREC_QUESTION (0x00000000)
#define DNSREC_ANSWER (0x00000001)
#define DNSREC_AUTHORITY (0x00000002)
#define DNSREC_ADDITIONAL (0x00000003)
// RR Section in packet (update)
#define DNSREC_ZONE (0x00000000)
#define DNSREC_PREREQ (0x00000001)
#define DNSREC_UPDATE (0x00000002)
// Delete RR (update) or No-exist (prerequisite)
#define DNSREC_DELETE (0x00000004)
#define DNSREC_NOEXIST (0x00000004)
//
// Record \ RR set structure
//
// Note: The dwReserved flag serves to insure that the substructures
// start on 64-bit boundaries. Do NOT pack this structure, as the
// substructures may contain pointers or int64 values which are
// properly aligned unpacked.
//
#ifdef MIDL_PASS
#define PDNS_RECORD PVOID
#else
typedef struct _DnsRecord
{
struct _DnsRecord * pNext;
LPTSTR pName;
WORD wType;
WORD wDataLength; // Not referenced for DNS record types
// defined above.
union
{
DWORD DW; // flags as DWORD
DNS_RECORD_FLAGS S; // flags as structure
} Flags;
DWORD dwTtl;
DWORD dwReserved;
// Record Data
union
{
DNS_A_DATA A;
DNS_SOA_DATA SOA, Soa;
DNS_PTR_DATA PTR, Ptr,
NS, Ns,
CNAME, Cname,
MB, Mb,
MD, Md,
MF, Mf,
MG, Mg,
MR, Mr;
DNS_MINFO_DATA MINFO, Minfo,
RP, Rp;
DNS_MX_DATA MX, Mx,
AFSDB, Afsdb,
RT, Rt;
DNS_TXT_DATA HINFO, Hinfo,
ISDN, Isdn,
TXT, Txt,
X25;
DNS_NULL_DATA Null;
DNS_WKS_DATA WKS, Wks;
DNS_AAAA_DATA AAAA;
DNS_KEY_DATA KEY, Key;
DNS_SIG_DATA SIG, Sig;
DNS_ATMA_DATA ATMA, Atma;
DNS_NXT_DATA NXT, Nxt;
DNS_SRV_DATA SRV, Srv;
DNS_TKEY_DATA TKEY, Tkey;
DNS_TSIG_DATA TSIG, Tsig;
DNS_WINS_DATA WINS, Wins;
DNS_WINSR_DATA WINSR, WinsR, NBSTAT, Nbstat;
} Data;
}
DNS_RECORD, *PDNS_RECORD;
//
// Header or fixed size of DNS_RECORD
//
#define DNS_RECORD_FIXED_SIZE FIELD_OFFSET( DNS_RECORD, Data )
#define SIZEOF_DNS_RECORD_HEADER DNS_RECORD_FIXED_SIZE
#endif // PRIVATE_DNS_RECORD
//
// Resource record set building
//
// pFirst points to first record in list.
// pLast points to last record in list.
//
typedef struct _DnsRRSet
{
PDNS_RECORD pFirstRR;
PDNS_RECORD pLastRR;
}
DNS_RRSET, *PDNS_RRSET;
//
// To init pFirst is NULL.
// But pLast points at the location of the pFirst pointer -- essentially
// treating the pFirst ptr as a DNS_RECORD. (It is a DNS_RECORD with
// only a pNext field, but that's the only part we use.)
//
// Then when the first record is added to the list, the pNext field of
// this dummy record (which corresponds to pFirst's value) is set to
// point at the first record. So pFirst then properly points at the
// first record.
//
// (This works only because pNext is the first field in a
// DNS_RECORD structure and hence casting a PDNS_RECORD ptr to
// PDNS_RECORD* and dereferencing yields its pNext field)
//
// Use TERMINATE when have built RR set by grabbing records out of
// existing set. This makes sure that at the end, the last RR is
// properly NULL terminated.
//
#define DNS_RRSET_INIT( rrset ) \
{ \
PDNS_RRSET _prrset = &(rrset); \
_prrset->pFirstRR = NULL; \
_prrset->pLastRR = (PDNS_RECORD) &_prrset->pFirstRR; \
}
#define DNS_RRSET_ADD( rrset, pnewRR ) \
{ \
PDNS_RRSET _prrset = &(rrset); \
PDNS_RECORD _prrnew = (pnewRR); \
_prrset->pLastRR->pNext = _prrnew; \
_prrset->pLastRR = _prrnew; \
}
#define DNS_RRSET_TERMINATE( rrset ) \
{ \
PDNS_RRSET _prrset = &(rrset); \
_prrset->pLastRR->pNext = NULL; \
}
//
// Record set manipulation
//
//
// Record Copy
// Record copy functions also do conversion between character sets.
//
// Note, it might be advisable to directly expose non-Ex copy
// functions _W, _A for record and set, to avoid exposing the
// conversion enum.
//
typedef enum _DNS_CHARSET
{
DnsCharSetUnknown,
DnsCharSetUnicode,
DnsCharSetUtf8,
DnsCharSetAnsi,
}
DNS_CHARSET;
PDNS_RECORD
WINAPI
DnsRecordCopyEx(
IN PDNS_RECORD pRecord,
IN DNS_CHARSET CharSetIn,
IN DNS_CHARSET CharSetOut
);
PDNS_RECORD
WINAPI
DnsRecordSetCopyEx(
IN PDNS_RECORD pRecordSet,
IN DNS_CHARSET CharSetIn,
IN DNS_CHARSET CharSetOut
);
#ifdef UNICODE
#define DnsRecordCopy(pRR) \
DnsRecordCopyEx( (pRR), DnsCharSetUnicode, DnsCharSetUnicode )
#define DnsRecordSetCopy(pRR) \
DnsRecordSetCopyEx( (pRR), DnsCharSetUnicode, DnsCharSetUnicode )
#else
#define DnsRecordCopy(pRR) \
DnsRecordCopyEx( (pRR), DnsCharSetAnsi, DnsCharSetAnsi )
#define DnsRecordSetCopy(pRR) \
DnsRecordSetCopyEx( (pRR), DnsCharSetAnsi, DnsCharSetAnsi )
#endif
//
// Record Compare
//
// Note: these routines only compare records of the SAME character set.
// (ANSI, unicode or UTF8). Furthermore the routines assume the character
// set is indicated within the record. If compare of user created, rather
// than DNS API created record lists is desired, then caller should use
// DnsRecordCopy API and compare copies.
//
BOOL
WINAPI
DnsRecordCompare(
IN PDNS_RECORD pRecord1,
IN PDNS_RECORD pRecord2
);
BOOL
WINAPI
DnsRecordSetCompare(
IN OUT PDNS_RECORD pRR1,
IN OUT PDNS_RECORD pRR2,
OUT PDNS_RECORD * ppDiff1,
OUT PDNS_RECORD * ppDiff2
);
//
// Detach next record set from record list
//
PDNS_RECORD
DnsRecordSetDetach(
IN OUT PDNS_RECORD pRecordList
);
//
// Free record list
//
// Only supported free is deep free of entire record list with LocalFree().
// This correctly frees record list returned by DnsQuery() or DnsRecordSetCopy()
//
typedef enum
{
DnsFreeFlat = 0,
DnsFreeRecordList
}
DNS_FREE_TYPE;
#define DnsFreeRecordListDeep DnsFreeRecordList
VOID
WINAPI
DnsRecordListFree(
IN OUT PDNS_RECORD pRecordList,
IN DNS_FREE_TYPE FreeType
);
VOID
WINAPI
DnsFree(
IN OUT PVOID pData,
IN DNS_FREE_TYPE FreeType
);
//
// DNS Query API
//
//
// Options for DnsQuery
//
#define DNS_QUERY_STANDARD 0x00000000
#define DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE 0x00000001
#define DNS_QUERY_USE_TCP_ONLY 0x00000002
#define DNS_QUERY_NO_RECURSION 0x00000004
#define DNS_QUERY_BYPASS_CACHE 0x00000008
#define DNS_QUERY_NO_WIRE_QUERY 0x00000010
#define DNS_QUERY_NO_LOCAL_NAME 0x00000020
#define DNS_QUERY_NO_HOSTS_FILE 0x00000040
#define DNS_QUERY_NO_NETBT 0x00000080
#define DNS_QUERY_WIRE_ONLY 0x00000100
#define DNS_QUERY_RETURN_MESSAGE 0x00000200
#define DNS_QUERY_TREAT_AS_FQDN 0x00001000
#define DNS_QUERY_DONT_RESET_TTL_VALUES 0x00100000
#define DNS_QUERY_RESERVED 0xff000000
// Backward compatibility with Win2K
// Do not use
#define DNS_QUERY_CACHE_ONLY DNS_QUERY_NO_WIRE_QUERY
DNS_STATUS
WINAPI
DnsQuery_A(
IN PCSTR pszName,
IN WORD wType,
IN DWORD Options,
IN PIP4_ARRAY aipServers OPTIONAL,
IN OUT PDNS_RECORD * ppQueryResults OPTIONAL,
IN OUT PVOID * pReserved OPTIONAL
);
DNS_STATUS
WINAPI
DnsQuery_UTF8(
IN PCSTR pszName,
IN WORD wType,
IN DWORD Options,
IN PIP4_ARRAY aipServers OPTIONAL,
IN OUT PDNS_RECORD * ppQueryResults OPTIONAL,
IN OUT PVOID * pReserved OPTIONAL
);
DNS_STATUS
WINAPI
DnsQuery_W(
IN PCWSTR pszName,
IN WORD wType,
IN DWORD Options,
IN PIP4_ARRAY aipServers OPTIONAL,
IN OUT PDNS_RECORD * ppQueryResults OPTIONAL,
IN OUT PVOID * pReserved OPTIONAL
);
#ifdef UNICODE
#define DnsQuery DnsQuery_W
#else
#define DnsQuery DnsQuery_A
#endif
//
// DNS Update API
//
// DnsAcquireContextHandle
// DnsReleaseContextHandle
// DnsModifyRecordsInSet
// DnsReplaceRecordSet
//
//
// Update flags
//
#define DNS_UPDATE_SECURITY_USE_DEFAULT 0x00000000
#define DNS_UPDATE_SECURITY_OFF 0x00000010
#define DNS_UPDATE_SECURITY_ON 0x00000020
#define DNS_UPDATE_SECURITY_ONLY 0x00000100
#define DNS_UPDATE_CACHE_SECURITY_CONTEXT 0x00000200
#define DNS_UPDATE_TEST_USE_LOCAL_SYS_ACCT 0x00000400
#define DNS_UPDATE_FORCE_SECURITY_NEGO 0x00000800
#define DNS_UPDATE_TRY_ALL_MASTER_SERVERS 0x00001000
#define DNS_UPDATE_SKIP_NO_UPDATE_ADAPTERS 0x00002000
#define DNS_UPDATE_RESERVED 0xffff0000
//
// Note: pCredentials paramater is currently respectively
// PSEC_WINNT_AUTH_IDENTITY_W or PSEC_WINNT_AUTH_IDENTITY_A.
// Using PVOID to obviate the need for including rpcdce.h
// in order to include this file and to leave open the
// possibility of alternative credential specifications in
// the future.
//
DNS_STATUS
WINAPI
DnsAcquireContextHandle_W(
IN DWORD CredentialFlags,
IN PVOID pCredentials, OPTIONAL
//IN PSEC_WINNT_AUTH_IDENTITY_W pCredentials,
OUT PHANDLE pContextHandle
);
DNS_STATUS
WINAPI
DnsAcquireContextHandle_A(
IN DWORD CredentialFlags,
IN PVOID pCredentials, OPTIONAL
//IN PSEC_WINNT_AUTH_IDENTITY_A pCredentials,
OUT PHANDLE pContextHandle
);
#ifdef UNICODE
#define DnsAcquireContextHandle DnsAcquireContextHandle_W
#else
#define DnsAcquireContextHandle DnsAcquireContextHandle_A
#endif
VOID
WINAPI
DnsReleaseContextHandle(
IN HANDLE hContext
);
//
// Dynamic Update API
//
DNS_STATUS
WINAPI
DnsModifyRecordsInSet_W(
IN PDNS_RECORD pAddRecords,
IN PDNS_RECORD pDeleteRecords,
IN DWORD Options,
IN HANDLE hContext, OPTIONAL
IN PIP4_ARRAY pServerList, OPTIONAL
IN PVOID pReserved
);
DNS_STATUS
WINAPI
DnsModifyRecordsInSet_A(
IN PDNS_RECORD pAddRecords,
IN PDNS_RECORD pDeleteRecords,
IN DWORD Options,
IN HANDLE hContext, OPTIONAL
IN PIP4_ARRAY pServerList, OPTIONAL
IN PVOID pReserved
);
DNS_STATUS
WINAPI
DnsModifyRecordsInSet_UTF8(
IN PDNS_RECORD pAddRecords,
IN PDNS_RECORD pDeleteRecords,
IN DWORD Options,
IN HANDLE hContext, OPTIONAL
IN PIP4_ARRAY pServerList, OPTIONAL
IN PVOID pReserved
);
#ifdef UNICODE
#define DnsModifyRecordsInSet DnsModifyRecordsInSet_W
#else
#define DnsModifyRecordsInSet DnsModifyRecordsInSet_A
#endif
DNS_STATUS
WINAPI
DnsReplaceRecordSetW(
IN PDNS_RECORD pNewSet,
IN DWORD Options,
IN HANDLE hContext, OPTIONAL
IN PIP4_ARRAY pServerList, OPTIONAL
IN PVOID pReserved
);
DNS_STATUS
WINAPI
DnsReplaceRecordSetA(
IN PDNS_RECORD pNewSet,
IN DWORD Options,
IN HANDLE hContext, OPTIONAL
IN PIP4_ARRAY pServerList, OPTIONAL
IN PVOID pReserved
);
DNS_STATUS
WINAPI
DnsReplaceRecordSetUTF8(
IN PDNS_RECORD pNewSet,
IN DWORD Options,
IN HANDLE hContext, OPTIONAL
IN PIP4_ARRAY pServerList, OPTIONAL
IN PVOID pReserved
);
#ifdef UNICODE
#define DnsReplaceRecordSet DnsReplaceRecordSetW
#else
#define DnsReplaceRecordSet DnsReplaceRecordSetA
#endif
//
// DNS name validation
//
typedef enum _DNS_NAME_FORMAT
{
DnsNameDomain,
DnsNameDomainLabel,
DnsNameHostnameFull,
DnsNameHostnameLabel,
DnsNameWildcard,
DnsNameSrvRecord
}
DNS_NAME_FORMAT;
DNS_STATUS
DnsValidateName_UTF8(
IN LPCSTR pszName,
IN DNS_NAME_FORMAT Format
);
DNS_STATUS
DnsValidateName_W(
IN LPCWSTR pwszName,
IN DNS_NAME_FORMAT Format
);
DNS_STATUS
DnsValidateName_A(
IN LPCSTR pszName,
IN DNS_NAME_FORMAT Format
);
#ifdef UNICODE
#define DnsValidateName(p,f) DnsValidateName_W( (p), (f) )
#else
#define DnsValidateName(p,f) DnsValidateName_A( (p), (f) )
#endif
//
// DNS name comparison
//
BOOL
WINAPI
DnsNameCompare_A(
IN LPSTR pName1,
IN LPSTR pName2
);
BOOL
WINAPI
DnsNameCompare_W(
IN LPWSTR pName1,
IN LPWSTR pName2
);
#ifdef UNICODE
#define DnsNameCompare(n1,n2) DnsNameCompare_W( (n1),(n2) )
#else
#define DnsNameCompare(n1,n2) DnsNameCompare_A( (n1),(n2) )
#endif
//
// DNS message "roll-your-own" routines
//
typedef struct _DNS_MESSAGE_BUFFER
{
DNS_HEADER MessageHead;
CHAR MessageBody[1];
}
DNS_MESSAGE_BUFFER, *PDNS_MESSAGE_BUFFER;
BOOL
WINAPI
DnsWriteQuestionToBuffer_W(
IN OUT PDNS_MESSAGE_BUFFER pDnsBuffer,
IN OUT LPDWORD pdwBufferSize,
IN LPWSTR pszName,
IN WORD wType,
IN WORD Xid,
IN BOOL fRecursionDesired
);
BOOL WINAPI
DnsWriteQuestionToBuffer_UTF8(
IN OUT PDNS_MESSAGE_BUFFER pDnsBuffer,
IN OUT LPDWORD pdwBufferSize,
IN LPSTR pszName,
IN WORD wType,
IN WORD Xid,
IN BOOL fRecursionDesired
);
DNS_STATUS
WINAPI
DnsExtractRecordsFromMessage_W(
IN PDNS_MESSAGE_BUFFER pDnsBuffer,
IN WORD wMessageLength,
OUT PDNS_RECORD * ppRecord
);
DNS_STATUS
WINAPI
DnsExtractRecordsFromMessage_UTF8(
IN PDNS_MESSAGE_BUFFER pDnsBuffer,
IN WORD wMessageLength,
OUT PDNS_RECORD * ppRecord
);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // _WINDNS_INCLUDED_