--- /dev/null
+/*
+ * 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 );
+}
+
--- /dev/null
+#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 );
+}
+
--- /dev/null
+/*
+ * 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;
+ }
+}