Initial dnsapi sources.

svn path=/trunk/; revision=7112
This commit is contained in:
Art Yerkes
2003-12-18 10:54:02 +00:00
parent c52179ff55
commit 9bd7d5ce0f
5 changed files with 726 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/dnsapi/dnsapi/context.c
* PURPOSE: ADNS translation.
* PROGRAMER: Art Yerkes
* UPDATE HISTORY:
* 12/15/03 -- Created
*/
#include <windows.h>
#include <WinError.h>
#include <WinDNS.h>
#include <internal/windns.h>
DNS_STATUS DnsIntTranslateAdnsToDNS_STATUS( int Status ) {
switch( Status ) {
case adns_s_ok:
return ERROR_SUCCESS;
case adns_s_nomemory:
case adns_s_systemfail:
default: /* There really aren't any general errors in the dns part. */
return DNS_ERROR_NO_MEMORY;
}
}
+117
View File
@@ -0,0 +1,117 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/dnsapi/dnsapi/context.c
* PURPOSE: DNSAPI functions built on the ADNS library.
* PROGRAMER: Art Yerkes
* UPDATE HISTORY:
* 12/15/03 -- Created
*/
#include <windows.h>
#include <WinError.h>
#include <WinDNS.h>
#include <internal/windns.h>
/* DnsAcquireContextHandle *************
* Create a context handle that will allow us to open and retrieve queries.
*
* DWORD CredentialsFlags -- TRUE -- Unicode
* FALSE -- Ansi or UTF-8?
*
* PVOID Credentials -- Pointer to a SEC_WINNT_AUTH_IDENTITY
* TODO: Use it.
*
* PHANDLE ContextHandle -- Pointer to a HANDLE that will receive
* our context pointer.
*
* RETURNS:
* ERROR_SUCCESS or a failure code.
* TODO: Which ones area allowed?
*/
extern DNS_STATUS WINAPI DnsAcquireContextHandle_UTF8
( DWORD CredentialsFlags,
PVOID Credentials,
HANDLE *ContextHandle );
DNS_STATUS WINAPI DnsAcquireContextHandle_W
( DWORD CredentialsFlags,
PVOID Credentials,
HANDLE *ContextHandle ) {
if( CredentialsFlags ) {
PWINDNS_CONTEXT Context;
int adns_status;
/* For now, don't worry about the user's identity. */
Context = (PWINDNS_CONTEXT)RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof( WINDNS_CONTEXT ) );
/* The real work here is to create an adns_state that will help us
* do what we want to later. */
adns_status = adns_init( &Context->State,
adns_if_noenv |
adns_if_noerrprint |
adns_if_noserverwarn,
0 );
if( adns_status != adns_s_ok ) {
*ContextHandle = 0;
return DnsIntTranslateAdnsToDNS_STATUS( adns_status );
} else {
*ContextHandle = (HANDLE)Context;
return ERROR_SUCCESS;
}
} else {
return DnsAcquireContextHandle_UTF8( CredentialsFlags,
Credentials,
ContextHandle );
}
}
DNS_STATUS WINAPI DnsAcquireContextHandle_UTF8
( DWORD CredentialsFlags,
PVOID Credentials,
HANDLE *ContextHandle ) {
if( CredentialsFlags ) {
return DnsAcquireContextHandle_W( CredentialsFlags,
Credentials,
ContextHandle );
} else {
/* Convert to unicode, then call the _W version
* For now, there is no conversion */
DNS_STATUS Status;
Status = DnsAcquireContextHandle_W( TRUE,
Credentials, /* XXX arty */
ContextHandle );
/* Free the unicode credentials when they exist. */
return Status;
}
}
DNS_STATUS WINAPI DnsAcquireContextHandle_A
( DWORD CredentialFlags,
PVOID Credentials,
HANDLE *ContextHandle ) {
if( CredentialFlags ) {
return DnsAcquireContextHandle_W( CredentialFlags,
Credentials,
ContextHandle );
} else {
return DnsAcquireContextHandle_UTF8( CredentialFlags,
Credentials,
ContextHandle );
}
}
/* DnsReleaseContextHandle *************
* Release a context handle, freeing all resources.
*/
void WINAPI DnsReleaseContextHandle
( HANDLE ContextHandle ) {
PWINDNS_CONTEXT Context = (PWINDNS_CONTEXT)ContextHandle;
adns_finish( Context->State );
RtlFreeHeap( RtlGetProcessHeap(), 0, Context );
}
+36
View File
@@ -0,0 +1,36 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/dnsapi/dnsapi/free.c
* PURPOSE: DNSAPI functions built on the ADNS library.
* PROGRAMER: Art Yerkes
* UPDATE HISTORY:
* 12/15/03 -- Created
*/
#include <windows.h>
#include <WinError.h>
#include <WinDNS.h>
#include <internal/windns.h>
VOID WINAPI DnsFree
( PVOID Data, DNS_FREE_TYPE FreeType ) {
switch( FreeType ) {
case DnsFreeFlat:
RtlFreeHeap( RtlGetProcessHeap(), 0, Data );
break;
case DnsFreeRecordList:
DnsIntFreeRecordList( (PDNS_RECORDA)Data );
break;
case DnsFreeParsedMessageFields:
/* assert( FALSE ); XXX arty not yet implemented. */
break;
}
}
VOID WINAPI DnsRecordListFree
( PVOID Data, DNS_FREE_TYPE FreeType ) {
DnsFree( Data, FreeType );
}
+199
View File
@@ -0,0 +1,199 @@
#include <windows.h>
#include <WinError.h>
#include <WinDNS.h>
#include <internal/windns.h>
#include <wchar.h>
#include <string.h>
#include <ctype.h>
static BOOL DnsIntNameContainsDots( LPCWSTR Name ) {
return wcschr( Name, '.' ) ? TRUE : FALSE;
}
static BOOL DnsIntTwoConsecutiveDots( LPCWSTR Name ) {
return wcsstr( Name, L".." ) ? TRUE : FALSE;
}
static BOOL DnsIntContainsUnderscore( LPCWSTR Name ) {
return wcschr( Name, '_' ) ? TRUE : FALSE;
}
/* DnsValidateName *********************
* Use some different algorithms to validate the given name as suitable for
* use with DNS.
*
* Name -- The name to evaluate.
* Format -- Format to use:
* DnsNameDomain
* DnsNameDomainLabel
* DnsNameHostnameFull
* DnsNameHostnameLabel
* DnsNameWildcard
* DnsNameSrvRecord
* RETURNS:
* ERROR_SUCCESS -- All good
* ERROR_INVALID_NAME --
* Name greater than 255 chars.
* Label greater than 63 chars.
* Two consecutive dots, or starts with dot.
* Contains a dot, but a Label check was specified.
* DNS_ERROR_INVALID_NAME_CHAR
* Contains any invalid char: " {|}~[\]^':;<=>?@!"#$%^`()+/,"
* Contains an *, except when it is the first label and Wildcard was
* specified.
* DNS_ERROR_NUMERIC_NAME
* Set if the name contains only numerics, unless Domain is specified.
* DNS_ERROR_NON_RFC_NAME
* If the name contains underscore.
* If there is an underscore in any position but the first in the SrvRecord
* case.
* If the name contains a non-ascii character.
*/
DNS_STATUS WINAPI DnsValidateName_W
( LPCWSTR Name,
DNS_NAME_FORMAT Format ) {
BOOL AllowDot = FALSE;
BOOL AllowLeadingAst = FALSE;
BOOL AllowLeadingUnderscore = FALSE;
BOOL AllowAllDigits = FALSE;
const WCHAR *NextLabel, *CurrentLabel, *CurrentChar;
switch( Format ) {
case DnsNameDomain:
AllowAllDigits = TRUE;
AllowDot = TRUE;
break;
case DnsNameDomainLabel:
AllowAllDigits = TRUE;
break;
case DnsNameHostnameFull:
AllowDot = TRUE;
break;
case DnsNameHostnameLabel:
break;
case DnsNameWildcard:
AllowLeadingAst = TRUE;
AllowDot = TRUE;
break;
case DnsNameSrvRecord:
AllowLeadingUnderscore = TRUE;
break;
default:
break;
}
/* Preliminary checks */
if( Name[0] == 0 ) return ERROR_INVALID_NAME; /* XXX arty: Check this */
/* Name too long */
if( wcslen( Name ) > 255 ) {
return ERROR_INVALID_NAME;
}
/* Violations about dots */
if( (!AllowDot && DnsIntNameContainsDots( Name )) ||
Name[0] == '.' || DnsIntTwoConsecutiveDots( Name ) )
return ERROR_INVALID_NAME;
/* Check component sizes */
CurrentLabel = Name;
do {
NextLabel = CurrentLabel;
while( *NextLabel && *NextLabel != '.' ) NextLabel++;
if( NextLabel - CurrentLabel > 63 )
return ERROR_INVALID_NAME;
CurrentLabel = NextLabel;
} while( *CurrentLabel );
CurrentChar = Name;
while( *CurrentChar ) {
if( wcschr(L" {|}~[\\]^':;<=>?@!\"#$%^`()+/,",*CurrentChar) )
return DNS_ERROR_INVALID_NAME_CHAR;
CurrentChar++;
}
if( (!AllowLeadingAst && Name[0] == '*') ||
(AllowLeadingAst && Name[0] == '*' && Name[1] && Name[1] != '.') )
return DNS_ERROR_INVALID_NAME_CHAR;
if( wcschr( Name + 1, '*' ) )
return DNS_ERROR_INVALID_NAME_CHAR;
CurrentChar = Name;
while( !AllowAllDigits && *CurrentChar ) {
if( *CurrentChar == '.' || (*CurrentChar >= '0' && *CurrentChar <= '9') )
return DNS_ERROR_NUMERIC_NAME;
}
if( ((AllowLeadingUnderscore && Name[0] == '_') || Name[0] != '_') &&
!DnsIntContainsUnderscore( Name + 1 ) )
return DNS_ERROR_NON_RFC_NAME;
return ERROR_SUCCESS;
}
DNS_STATUS WINAPI DnsValidateName_UTF8
( LPCSTR Name,
DNS_NAME_FORMAT Format ) {
PWCHAR Buffer;
int StrLenWc;
DNS_STATUS Status;
StrLenWc = mbstowcs( NULL, Name, 0 );
Buffer = RtlAllocateHeap( GetProcessHeap(), 0,
sizeof( WCHAR ) * (StrLenWc + 1) );
mbstowcs( Buffer, Name, StrLenWc + 1 );
Status = DnsValidateName_W( Buffer, Format );
RtlFreeHeap( GetProcessHeap(), 0, Buffer );
return Status;
}
DNS_STATUS WINAPI DnsValidateName_A
( LPCSTR Name,
DNS_NAME_FORMAT Format ) {
return DnsValidateName_UTF8( Name, Format );
}
/* DnsNameCompare **********************
* Return TRUE if the names are identical.
*
* Name1 & Name2 -- Names.
*/
BOOL WINAPI DnsNameCompare_W
( LPWSTR Name1,
LPWSTR Name2 ) {
int offset = 0;
while( Name1[offset] && Name2[offset] &&
towupper( Name1[offset] ) == towupper( Name2[offset] ) ) offset++;
return
(!Name1[offset] && !Name2[offset]) ||
(!Name1[offset] && !wcscmp( Name2 + offset, L"." )) ||
(!Name2[offset] && !wcscmp( Name1 + offset, L"." ));
}
BOOL WINAPI DnsNameCompare_UTF8
( LPCSTR Name1,
LPCSTR Name2 ) {
int offset = 0;
while( Name1[offset] && Name2[offset] &&
toupper( Name1[offset] ) == toupper( Name2[offset] ) ) offset++;
return
(!Name1[offset] && !Name2[offset]) ||
(!Name1[offset] && !strcmp( Name2 + offset, ".")) ||
(!Name2[offset] && !strcmp( Name1 + offset, "."));
}
BOOL WINAPI DnsNameCompare_A
( LPCSTR Name1,
LPCSTR Name2 ) {
return DnsNameCompare_UTF8( Name1, Name2 );
}
+348
View File
@@ -0,0 +1,348 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/dnsapi/dnsapi/query.c
* PURPOSE: DNSAPI functions built on the ADNS library.
* PROGRAMER: Art Yerkes
* UPDATE HISTORY:
* 12/15/03 -- Created
*/
#include <windows.h>
#include <WinError.h>
#include <WinDNS.h>
#include <internal/windns.h>
#include <string.h>
/* DnsQuery ****************************
* Begin a DNS query, and allow the result to be placed in the application
* supplied result pointer. The result can be manipulated with the record
* functions.
*
* Name -- The DNS object to be queried.
* Type -- The type of records to be returned. These are
* listed in windns.h
* Options -- Query options. DNS_QUERY_STANDARD is the base
* state, and every other option takes precedence.
* multiple options can be combined. Listed in
* windns.h
* Servers -- List of alternate servers (optional)
* QueryResultSet -- Pointer to the result pointer that will be filled
* when the response is available.
* Reserved -- Response as it appears on the wire. Optional.
*/
char *xstrsave(const char *str) {
char *p;
p= RtlAllocateHeap( RtlGetProcessHeap(), 0, strlen(str)+1 );
strcpy(p,str);
return p;
}
DNS_STATUS WINAPI DnsQuery_A
( LPCSTR Name,
WORD Type,
DWORD Options,
PIP4_ARRAY Servers,
PDNS_RECORDA *QueryResultSet,
PVOID *Reserved ) {
adns_state astate;
int quflags = 0;
int adns_error;
adns_answer *answer;
*QueryResultSet = 0;
switch( Type ) {
case DNS_TYPE_A:
adns_error = adns_init( &astate,
adns_if_noenv |
adns_if_noerrprint |
adns_if_noserverwarn,
0 );
if( adns_error != adns_s_ok ) {
adns_finish( astate );
return DnsIntTranslateAdnsToDNS_STATUS( adns_error );
}
adns_error = adns_synchronous( astate,
Name,
adns_r_addr,
quflags,
&answer );
if( adns_error != adns_s_ok ) {
adns_finish( astate );
return DnsIntTranslateAdnsToDNS_STATUS( adns_error );
}
*QueryResultSet = (PDNS_RECORDA)RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof( DNS_RECORDA ) );
(*QueryResultSet)->wType = Type;
(*QueryResultSet)->pName = xstrsave( Name );
(*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA);
(*QueryResultSet)->Data.A.IpAddress =
ntohl( answer->rrs.addr->addr.inet.sin_addr.s_addr );
adns_finish( astate );
return ERROR_SUCCESS;
default:
return DNS_ERROR_NO_MEMORY; /* XXX arty: find a better error code. */
}
}
static PCHAR DnsWToC( const WCHAR *WideString ) {
int chars = wcstombs( NULL, WideString, 0 );
PCHAR out = RtlAllocateHeap( RtlGetProcessHeap(), 0, chars + 1 );
wcstombs( out, WideString, chars + 1 );
return out;
}
static PWCHAR DnsCToW( const CHAR *NarrowString ) {
int chars = mbstowcs( NULL, NarrowString, 0 );
PWCHAR out = RtlAllocateHeap( RtlGetProcessHeap(), 0,
(chars + 1) * sizeof(WCHAR) );
mbstowcs( out, NarrowString, chars + 1 );
return out;
}
DNS_STATUS WINAPI DnsQuery_W
( LPCWSTR Name,
WORD Type,
DWORD Options,
PIP4_ARRAY Servers,
PDNS_RECORDW *QueryResultSet,
PVOID *Reserved ) {
int i;
PCHAR Buffer;
DNS_STATUS Status;
PDNS_RECORDA QueryResultWide;
PDNS_RECORDW ConvertedRecord = 0, LastRecord = 0;
Buffer = DnsWToC( Name );
Status = DnsQuery_A( Buffer, Type, Options, Servers, &QueryResultWide,
Reserved );
while( Status == ERROR_SUCCESS && QueryResultWide ) {
switch( QueryResultWide->wType ) {
case DNS_TYPE_A:
case DNS_TYPE_WKS:
case DNS_TYPE_AAAA:
case DNS_TYPE_KEY:
ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof(DNS_RECORDA) );
ConvertedRecord->pName = DnsCToW( QueryResultWide->pName );
ConvertedRecord->wType = QueryResultWide->wType;
ConvertedRecord->wDataLength = QueryResultWide->wDataLength;
memcpy( ConvertedRecord, QueryResultWide,
QueryResultWide->wDataLength );
break;
case DNS_TYPE_CNAME:
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
case DNS_TYPE_MB:
case DNS_TYPE_MD:
case DNS_TYPE_MF:
case DNS_TYPE_MG:
case DNS_TYPE_MR:
ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof(DNS_RECORDA) );
ConvertedRecord->pName = DnsCToW( QueryResultWide->pName );
ConvertedRecord->wType = QueryResultWide->wType;
ConvertedRecord->wDataLength = sizeof(DNS_PTR_DATAA);
ConvertedRecord->Data.PTR.pNameHost =
DnsCToW( QueryResultWide->Data.PTR.pNameHost );
break;
case DNS_TYPE_MINFO:
case DNS_TYPE_RP:
ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof(DNS_RECORDA) );
ConvertedRecord->pName = DnsCToW( QueryResultWide->pName );
ConvertedRecord->wType = QueryResultWide->wType;
ConvertedRecord->wDataLength = sizeof(DNS_MINFO_DATAA);
ConvertedRecord->Data.MINFO.pNameMailbox =
DnsCToW( QueryResultWide->Data.MINFO.pNameMailbox );
ConvertedRecord->Data.MINFO.pNameErrorsMailbox =
DnsCToW( QueryResultWide->Data.MINFO.pNameErrorsMailbox );
break;
case DNS_TYPE_MX:
case DNS_TYPE_AFSDB:
case DNS_TYPE_RT:
ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof(DNS_RECORDA) );
ConvertedRecord->pName = DnsCToW( QueryResultWide->pName );
ConvertedRecord->wType = QueryResultWide->wType;
ConvertedRecord->wDataLength = sizeof(DNS_MX_DATAW);
ConvertedRecord->Data.MX.pNameExchange =
DnsCToW( QueryResultWide->Data.MX.pNameExchange );
ConvertedRecord->Data.MX.wPreference =
QueryResultWide->Data.MX.wPreference;
break;
case DNS_TYPE_TXT:
case DNS_TYPE_HINFO:
case DNS_TYPE_ISDN:
ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof(DNS_TXT_DATAW) +
QueryResultWide->
Data.TXT.dwStringCount );
ConvertedRecord->pName = DnsCToW( QueryResultWide->pName );
ConvertedRecord->wType = QueryResultWide->wType;
ConvertedRecord->wDataLength =
sizeof(DNS_TXT_DATAW) +
(sizeof(PWCHAR) * QueryResultWide->Data.TXT.dwStringCount);
ConvertedRecord->Data.TXT.dwStringCount =
QueryResultWide->Data.TXT.dwStringCount;
for( i = 0; i < ConvertedRecord->Data.TXT.dwStringCount; i++ ) {
ConvertedRecord->Data.TXT.pStringArray[i] =
DnsCToW( QueryResultWide->Data.TXT.pStringArray[i] );
}
break;
case DNS_TYPE_NULL:
ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof(DNS_NULL_DATA) +
QueryResultWide->
Data.Null.dwByteCount );
ConvertedRecord->pName = DnsCToW( QueryResultWide->pName );
ConvertedRecord->wType = QueryResultWide->wType;
ConvertedRecord->wDataLength =
sizeof(DNS_NULL_DATA) + QueryResultWide->Data.Null.dwByteCount;
ConvertedRecord->Data.Null.dwByteCount =
QueryResultWide->Data.Null.dwByteCount;
memcpy( &ConvertedRecord->Data.Null.Data,
&QueryResultWide->Data.Null.Data,
QueryResultWide->Data.Null.dwByteCount );
break;
case DNS_TYPE_SIG:
ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof(DNS_RECORDA) );
ConvertedRecord->pName = DnsCToW( QueryResultWide->pName );
ConvertedRecord->wType = QueryResultWide->wType;
ConvertedRecord->wDataLength = sizeof(DNS_SIG_DATAA);
memcpy( &ConvertedRecord->Data.SIG,
&QueryResultWide->Data.SIG,
sizeof(QueryResultWide->Data.SIG) );
ConvertedRecord->Data.SIG.pNameSigner =
DnsCToW( QueryResultWide->Data.SIG.pNameSigner );
break;
case DNS_TYPE_NXT:
ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof(DNS_RECORDA) );
ConvertedRecord->pName = DnsCToW( QueryResultWide->pName );
ConvertedRecord->wType = QueryResultWide->wType;
ConvertedRecord->wDataLength = sizeof(DNS_NXT_DATAA);
memcpy( &ConvertedRecord->Data.NXT,
&QueryResultWide->Data.NXT,
sizeof(QueryResultWide->Data.NXT) );
ConvertedRecord->Data.NXT.pNameNext =
DnsCToW( QueryResultWide->Data.NXT.pNameNext );
break;
case DNS_TYPE_SRV:
ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0,
sizeof(DNS_RECORDA) );
ConvertedRecord->pName = DnsCToW( QueryResultWide->pName );
ConvertedRecord->wType = QueryResultWide->wType;
ConvertedRecord->wDataLength = sizeof(DNS_SRV_DATAA);
memcpy( &ConvertedRecord->Data.SRV,
&QueryResultWide->Data.SRV,
sizeof(QueryResultWide->Data.SRV) );
ConvertedRecord->Data.SRV.pNameTarget =
DnsCToW( QueryResultWide->Data.SRV.pNameTarget );
break;
}
if( LastRecord ) {
LastRecord->pNext = ConvertedRecord;
LastRecord = LastRecord->pNext;
} else {
LastRecord = *QueryResultSet = ConvertedRecord;
}
}
LastRecord->pNext = 0;
/* The name */
RtlFreeHeap( RtlGetProcessHeap(), 0, Buffer );
return Status;
}
DNS_STATUS WINAPI DnsQuery_UTF8
( LPCSTR Name,
WORD Type,
DWORD Options,
PIP4_ARRAY Servers,
PDNS_RECORDA *QueryResultSet,
PVOID *Reserved ) {
return DnsQuery_UTF8( Name, Type, Options, Servers, QueryResultSet,
Reserved );
}
void DnsIntFreeRecordList( PDNS_RECORDA ToDelete ) {
int i;
PDNS_RECORDA next = 0;
while( ToDelete ) {
if( ToDelete->pName )
RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->pName );
switch( ToDelete->wType ) {
case DNS_TYPE_CNAME:
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
case DNS_TYPE_MB:
case DNS_TYPE_MD:
case DNS_TYPE_MF:
case DNS_TYPE_MG:
case DNS_TYPE_MR:
RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.PTR.pNameHost );
break;
case DNS_TYPE_MINFO:
case DNS_TYPE_RP:
RtlFreeHeap( RtlGetProcessHeap(), 0,
ToDelete->Data.MINFO.pNameMailbox );
RtlFreeHeap( RtlGetProcessHeap(), 0,
ToDelete->Data.MINFO.pNameErrorsMailbox );
break;
case DNS_TYPE_MX:
case DNS_TYPE_AFSDB:
case DNS_TYPE_RT:
RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.MX.pNameExchange );
break;
case DNS_TYPE_TXT:
case DNS_TYPE_HINFO:
case DNS_TYPE_ISDN:
for( i = 0; i < ToDelete->Data.TXT.dwStringCount; i++ ) {
RtlFreeHeap( RtlGetProcessHeap(), 0,
ToDelete->Data.TXT.pStringArray[i] );
}
RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.TXT.pStringArray );
break;
case DNS_TYPE_SIG:
RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.SIG.pNameSigner );
break;
case DNS_TYPE_NXT:
RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.NXT.pNameNext );
break;
case DNS_TYPE_SRV:
RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.SRV.pNameTarget );
break;
}
next = ToDelete->pNext;
RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete );
ToDelete = next;
}
}