- Import Alex's dnslib
authorCameron Gutman <aicommander@gmail.com>
Thu, 15 Oct 2009 01:23:39 +0000 (01:23 +0000)
committerCameron Gutman <aicommander@gmail.com>
Thu, 15 Oct 2009 01:23:39 +0000 (01:23 +0000)
 - Add headers and definitions needed for dnslib to build
 - Part 2 of 2

svn path=/trunk/; revision=43469

24 files changed:
reactos/include/psdk/windns.h
reactos/include/psdk/ws2atm.h [new file with mode: 0644]
reactos/lib/dnslib/addr.c [new file with mode: 0644]
reactos/lib/dnslib/debug.c [new file with mode: 0644]
reactos/lib/dnslib/dnsaddr.c [new file with mode: 0644]
reactos/lib/dnslib/dnslib.rbuild [new file with mode: 0644]
reactos/lib/dnslib/dnsutil.c [new file with mode: 0644]
reactos/lib/dnslib/flatbuf.c [new file with mode: 0644]
reactos/lib/dnslib/hostent.c [new file with mode: 0644]
reactos/lib/dnslib/inc/dnslib.h [new file with mode: 0644]
reactos/lib/dnslib/inc/precomp.h [new file with mode: 0644]
reactos/lib/dnslib/inc/windnsp.h [new file with mode: 0644]
reactos/lib/dnslib/ip6.c [new file with mode: 0644]
reactos/lib/dnslib/memory.c [new file with mode: 0644]
reactos/lib/dnslib/name.c [new file with mode: 0644]
reactos/lib/dnslib/print.c [new file with mode: 0644]
reactos/lib/dnslib/record.c [new file with mode: 0644]
reactos/lib/dnslib/rrprint.c [new file with mode: 0644]
reactos/lib/dnslib/sablob.c [new file with mode: 0644]
reactos/lib/dnslib/straddr.c [new file with mode: 0644]
reactos/lib/dnslib/string.c [new file with mode: 0644]
reactos/lib/dnslib/table.c [new file with mode: 0644]
reactos/lib/dnslib/utf8.c [new file with mode: 0644]
reactos/lib/lib.rbuild

index c037b67..3e3714f 100644 (file)
@@ -171,6 +171,10 @@ typedef struct _DnsRecordFlags {
        DWORD Unused    :3;
        DWORD Reserved  :24;
 } DNS_RECORD_FLAGS;
        DWORD Unused    :3;
        DWORD Reserved  :24;
 } DNS_RECORD_FLAGS;
+#define DNSREC_QUESTION 0
+#define DNSREC_ANSWER 1
+#define DNSREC_AUTHORITY 2
+#define DNSREC_ADDITIONAL 3
 typedef struct {
        IP4_ADDRESS IpAddress;
 } DNS_A_DATA, *PDNS_A_DATA;
 typedef struct {
        IP4_ADDRESS IpAddress;
 } DNS_A_DATA, *PDNS_A_DATA;
diff --git a/reactos/include/psdk/ws2atm.h b/reactos/include/psdk/ws2atm.h
new file mode 100644 (file)
index 0000000..1049683
--- /dev/null
@@ -0,0 +1,333 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WS2ATM_H_
+#define _WS2ATM_H_
+
+#include <pshpack4.h>
+
+#define ATMPROTO_AALUSER 0x00
+#define ATMPROTO_AAL1 0x01
+#define ATMPROTO_AAL2 0x02
+#define ATMPROTO_AAL34 0x03
+#define ATMPROTO_AAL5 0x05
+
+#define SAP_FIELD_ABSENT 0xFFFFFFFE
+#define SAP_FIELD_ANY 0xFFFFFFFF
+#define SAP_FIELD_ANY_AESA_SEL 0xFFFFFFFA
+#define SAP_FIELD_ANY_AESA_REST 0xFFFFFFFB
+
+#define ATM_E164 0x01
+#define ATM_NSAP 0x02
+#define ATM_AESA 0x02
+
+#define ATM_ADDR_SIZE 20
+typedef struct {
+  DWORD AddressType;
+  DWORD NumofDigits;
+  UCHAR Addr[ATM_ADDR_SIZE];
+} ATM_ADDRESS;
+
+#define BLLI_L2_ISO_1745 0x01
+#define BLLI_L2_Q921 0x02
+#define BLLI_L2_X25L 0x06
+#define BLLI_L2_X25M 0x07
+#define BLLI_L2_ELAPB 0x08
+#define BLLI_L2_HDLC_ARM 0x09
+#define BLLI_L2_HDLC_NRM 0x0A
+#define BLLI_L2_HDLC_ABM 0x0B
+#define BLLI_L2_LLC 0x0C
+#define BLLI_L2_X75 0x0D
+#define BLLI_L2_Q922 0x0E
+#define BLLI_L2_USER_SPECIFIED 0x10
+#define BLLI_L2_ISO_7776 0x11
+
+#define BLLI_L3_X25 0x06
+#define BLLI_L3_ISO_8208 0x07
+#define BLLI_L3_X223 0x08
+#define BLLI_L3_SIO_8473 0x09
+#define BLLI_L3_T70 0x0A
+#define BLLI_L3_ISO_TR9577 0x0B
+#define BLLI_L3_USER_SPECIFIED 0x10
+
+#define BLLI_L3_IPI_SNAP 0x80
+#define BLLI_L3_IPI_IP 0xCC
+
+typedef struct {
+  DWORD Layer2Protocol;
+  DWORD Layer2UserSpecifiedProtocol;
+  DWORD Layer3Protocol;
+  DWORD Layer3UserSpecifiedProtocol;
+  DWORD Layer3IPI;
+  UCHAR SnapID[5];
+} ATM_BLLI;
+
+#define BHLI_ISO 0x00
+#define BHLI_UserSpecific 0x01
+#define BHLI_HighLayerProfile 0x02
+#define BHLI_VendorSpecificAppId 0x03
+
+typedef struct {
+  DWORD HighLayerInfoType;
+  DWORD HighLayerInfoLength;
+  UCHAR HighLayerInfo[8];
+} ATM_BHLI;
+
+typedef struct sockaddr_atm {
+  u_short satm_family;
+  ATM_ADDRESS satm_number;
+  ATM_BLLI satm_blli;
+  ATM_BHLI satm_bhli;
+} sockaddr_atm,SOCKADDR_ATM,*PSOCKADDR_ATM,*LPSOCKADDR_ATM;
+
+typedef enum {
+  IE_AALParameters,IE_TrafficDescriptor,IE_BroadbandBearerCapability,IE_BHLI,IE_BLLI,IE_CalledPartyNumber,IE_CalledPartySubaddress,
+  IE_CallingPartyNumber,IE_CallingPartySubaddress,IE_Cause,IE_QOSClass,IE_TransitNetworkSelection
+} Q2931_IE_TYPE;
+
+typedef struct {
+  Q2931_IE_TYPE IEType;
+  ULONG IELength;
+  UCHAR IE[1];
+} Q2931_IE;
+
+typedef enum {
+  AALTYPE_5 = 5,AALTYPE_USER = 16
+} AAL_TYPE;
+
+#define AAL5_MODE_MESSAGE 0x01
+#define AAL5_MODE_STREAMING 0x02
+
+#define AAL5_SSCS_NULL 0x00
+#define AAL5_SSCS_SSCOP_ASSURED 0x01
+#define AAL5_SSCS_SSCOP_NON_ASSURED 0x02
+#define AAL5_SSCS_FRAME_RELAY 0x04
+
+typedef struct {
+  ULONG ForwardMaxCPCSSDUSize;
+  ULONG BackwardMaxCPCSSDUSize;
+  UCHAR Mode;
+  UCHAR SSCSType;
+} AAL5_PARAMETERS;
+
+typedef struct {
+  ULONG UserDefined;
+} AALUSER_PARAMETERS;
+
+typedef struct {
+  AAL_TYPE AALType;
+  union {
+    AAL5_PARAMETERS AAL5Parameters;
+    AALUSER_PARAMETERS AALUserParameters;
+  } AALSpecificParameters;
+} AAL_PARAMETERS_IE;
+
+typedef struct {
+  ULONG PeakCellRate_CLP0;
+  ULONG PeakCellRate_CLP01;
+  ULONG SustainableCellRate_CLP0;
+  ULONG SustainableCellRate_CLP01;
+  ULONG MaxBurstSize_CLP0;
+  ULONG MaxBurstSize_CLP01;
+  WINBOOL Tagging;
+} ATM_TD;
+
+typedef struct {
+  ATM_TD Forward;
+  ATM_TD Backward;
+  WINBOOL BestEffort;
+} ATM_TRAFFIC_DESCRIPTOR_IE;
+
+#define BCOB_A 0x01
+#define BCOB_C 0x03
+#define BCOB_X 0x10
+
+#define TT_NOIND 0x00
+#define TT_CBR 0x04
+#define TT_VBR 0x08
+
+#define TR_NOIND 0x00
+#define TR_END_TO_END 0x01
+#define TR_NO_END_TO_END 0x02
+
+#define CLIP_NOT 0x00
+#define CLIP_SUS 0x20
+
+#define UP_P2P 0x00
+#define UP_P2MP 0x01
+
+typedef struct {
+  UCHAR BearerClass;
+  UCHAR TrafficType;
+  UCHAR TimingRequirements;
+  UCHAR ClippingSusceptability;
+  UCHAR UserPlaneConnectionConfig;
+} ATM_BROADBAND_BEARER_CAPABILITY_IE;
+
+typedef ATM_BHLI ATM_BHLI_IE;
+
+#define BLLI_L2_MODE_NORMAL 0x40
+#define BLLI_L2_MODE_EXT 0x80
+
+#define BLLI_L3_MODE_NORMAL 0x40
+#define BLLI_L3_MODE_EXT 0x80
+
+#define BLLI_L3_PACKET_16 0x04
+#define BLLI_L3_PACKET_32 0x05
+#define BLLI_L3_PACKET_64 0x06
+#define BLLI_L3_PACKET_128 0x07
+#define BLLI_L3_PACKET_256 0x08
+#define BLLI_L3_PACKET_512 0x09
+#define BLLI_L3_PACKET_1024 0x0A
+#define BLLI_L3_PACKET_2048 0x0B
+#define BLLI_L3_PACKET_4096 0x0C
+
+typedef struct {
+  DWORD Layer2Protocol;
+  UCHAR Layer2Mode;
+  UCHAR Layer2WindowSize;
+  DWORD Layer2UserSpecifiedProtocol;
+  DWORD Layer3Protocol;
+  UCHAR Layer3Mode;
+  UCHAR Layer3DefaultPacketSize;
+  UCHAR Layer3PacketWindowSize;
+  DWORD Layer3UserSpecifiedProtocol;
+  DWORD Layer3IPI;
+  UCHAR SnapID[5];
+} ATM_BLLI_IE;
+
+typedef ATM_ADDRESS ATM_CALLED_PARTY_NUMBER_IE;
+typedef ATM_ADDRESS ATM_CALLED_PARTY_SUBADDRESS_IE;
+
+#define PI_ALLOWED 0x00
+#define PI_RESTRICTED 0x40
+#define PI_NUMBER_NOT_AVAILABLE 0x80
+
+#define SI_USER_NOT_SCREENED 0x00
+#define SI_USER_PASSED 0x01
+#define SI_USER_FAILED 0x02
+#define SI_NETWORK 0x03
+
+typedef struct {
+  ATM_ADDRESS ATM_Number;
+  UCHAR Presentation_Indication;
+  UCHAR Screening_Indicator;
+} ATM_CALLING_PARTY_NUMBER_IE;
+
+typedef ATM_ADDRESS ATM_CALLING_PARTY_SUBADDRESS_IE;
+
+#define CAUSE_LOC_USER 0x00
+#define CAUSE_LOC_PRIVATE_LOCAL 0x01
+#define CAUSE_LOC_PUBLIC_LOCAL 0x02
+#define CAUSE_LOC_TRANSIT_NETWORK 0x03
+#define CAUSE_LOC_PUBLIC_REMOTE 0x04
+#define CAUSE_LOC_PRIVATE_REMOTE 0x05
+#define CAUSE_LOC_INTERNATIONAL_NETWORK 0x07
+#define CAUSE_LOC_BEYOND_INTERWORKING 0x0A
+
+#define CAUSE_UNALLOCATED_NUMBER 0x01
+#define CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK 0x02
+#define CAUSE_NO_ROUTE_TO_DESTINATION 0x03
+#define CAUSE_VPI_VCI_UNACCEPTABLE 0x0A
+#define CAUSE_NORMAL_CALL_CLEARING 0x10
+#define CAUSE_USER_BUSY 0x11
+#define CAUSE_NO_USER_RESPONDING 0x12
+#define CAUSE_CALL_REJECTED 0x15
+#define CAUSE_NUMBER_CHANGED 0x16
+#define CAUSE_USER_REJECTS_CLIR 0x17
+#define CAUSE_DESTINATION_OUT_OF_ORDER 0x1B
+#define CAUSE_INVALID_NUMBER_FORMAT 0x1C
+#define CAUSE_STATUS_ENQUIRY_RESPONSE 0x1E
+#define CAUSE_NORMAL_UNSPECIFIED 0x1F
+#define CAUSE_VPI_VCI_UNAVAILABLE 0x23
+#define CAUSE_NETWORK_OUT_OF_ORDER 0x26
+#define CAUSE_TEMPORARY_FAILURE 0x29
+#define CAUSE_ACCESS_INFORMAION_DISCARDED 0x2B
+#define CAUSE_NO_VPI_VCI_AVAILABLE 0x2D
+#define CAUSE_RESOURCE_UNAVAILABLE 0x2F
+#define CAUSE_QOS_UNAVAILABLE 0x31
+#define CAUSE_USER_CELL_RATE_UNAVAILABLE 0x33
+#define CAUSE_BEARER_CAPABILITY_UNAUTHORIZED 0x39
+#define CAUSE_BEARER_CAPABILITY_UNAVAILABLE 0x3A
+#define CAUSE_OPTION_UNAVAILABLE 0x3F
+#define CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED 0x41
+#define CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS 0x49
+#define CAUSE_INVALID_CALL_REFERENCE 0x51
+#define CAUSE_CHANNEL_NONEXISTENT 0x52
+#define CAUSE_INCOMPATIBLE_DESTINATION 0x58
+#define CAUSE_INVALID_ENDPOINT_REFERENCE 0x59
+#define CAUSE_INVALID_TRANSIT_NETWORK_SELECTION 0x5B
+#define CAUSE_TOO_MANY_PENDING_ADD_PARTY 0x5C
+#define CAUSE_AAL_PARAMETERS_UNSUPPORTED 0x5D
+#define CAUSE_MANDATORY_IE_MISSING 0x60
+#define CAUSE_UNIMPLEMENTED_MESSAGE_TYPE 0x61
+#define CAUSE_UNIMPLEMENTED_IE 0x63
+#define CAUSE_INVALID_IE_CONTENTS 0x64
+#define CAUSE_INVALID_STATE_FOR_MESSAGE 0x65
+#define CAUSE_RECOVERY_ON_TIMEOUT 0x66
+#define CAUSE_INCORRECT_MESSAGE_LENGTH 0x68
+#define CAUSE_PROTOCOL_ERROR 0x6F
+
+#define CAUSE_COND_UNKNOWN 0x00
+#define CAUSE_COND_PERMANENT 0x01
+#define CAUSE_COND_TRANSIENT 0x02
+
+#define CAUSE_REASON_USER 0x00
+#define CAUSE_REASON_IE_MISSING 0x04
+#define CAUSE_REASON_IE_INSUFFICIENT 0x08
+
+#define CAUSE_PU_PROVIDER 0x00
+#define CAUSE_PU_USER 0x08
+
+#define CAUSE_NA_NORMAL 0x00
+#define CAUSE_NA_ABNORMAL 0x04
+
+typedef struct {
+  UCHAR Location;
+  UCHAR Cause;
+  UCHAR DiagnosticsLength;
+  UCHAR Diagnostics[4];
+} ATM_CAUSE_IE;
+
+#define QOS_CLASS0 0x00
+#define QOS_CLASS1 0x01
+#define QOS_CLASS2 0x02
+#define QOS_CLASS3 0x03
+#define QOS_CLASS4 0x04
+
+typedef struct {
+  UCHAR QOSClassForward;
+  UCHAR QOSClassBackward;
+} ATM_QOS_CLASS_IE;
+
+#define TNS_TYPE_NATIONAL 0x40
+
+#define TNS_PLAN_CARRIER_ID_CODE 0x01
+
+typedef struct {
+  UCHAR TypeOfNetworkId;
+  UCHAR NetworkIdPlan;
+  UCHAR NetworkIdLength;
+  UCHAR NetworkId[1];
+} ATM_TRANSIT_NETWORK_SELECTION_IE;
+
+#define SIO_GET_NUMBER_OF_ATM_DEVICES 0x50160001
+#define SIO_GET_ATM_ADDRESS 0xd0160002
+#define SIO_ASSOCIATE_PVC 0x90160003
+#define SIO_GET_ATM_CONNECTION_ID 0x50160004
+
+typedef struct {
+  DWORD DeviceNumber;
+  DWORD VPI;
+  DWORD VCI;
+} ATM_CONNECTION_ID;
+
+typedef struct {
+  ATM_CONNECTION_ID PvcConnectionId;
+  QOS PvcQos;
+} ATM_PVC_PARAMS;
+
+#include <poppack.h>
+#endif
diff --git a/reactos/lib/dnslib/addr.c b/reactos/lib/dnslib/addr.c
new file mode 100644 (file)
index 0000000..b91c532
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/addr.c
+ * PURPOSE:     Contains the Address Family Information Tables
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+DNS_FAMILY_INFO AddrFamilyTable[3] =
+{
+    {
+        AF_INET,
+        DNS_TYPE_A,
+        sizeof(IP4_ADDRESS),
+        sizeof(SOCKADDR_IN),
+        FIELD_OFFSET(SOCKADDR_IN, sin_addr)
+    },
+    {
+        AF_INET6,
+        DNS_TYPE_AAAA,
+        sizeof(IP6_ADDRESS),
+        sizeof(SOCKADDR_IN6),
+        FIELD_OFFSET(SOCKADDR_IN6, sin6_addr)
+    },
+    {
+        AF_ATM,
+        DNS_TYPE_ATMA,
+        sizeof(ATM_ADDRESS),
+        sizeof(SOCKADDR_ATM),
+        FIELD_OFFSET(SOCKADDR_ATM, satm_number)
+    }
+};
+
+/* FUNCTIONS *****************************************************************/
+
+PDNS_FAMILY_INFO
+WINAPI
+FamilyInfo_GetForFamily(IN WORD AddressFamily)
+{
+    /* Check which family this is */
+    switch (AddressFamily)
+    {
+        case AF_INET:
+            /* Return IPv4 Family Info */
+            return &AddrFamilyTable[0];
+        
+        case AF_INET6:
+            /* Return IPv6 Family Info */
+            return &AddrFamilyTable[1];
+        
+        case AF_ATM:
+            /* Return ATM Family Info */
+            return &AddrFamilyTable[2];
+        
+        default:
+            /* Invalid family */
+            return NULL;
+    }
+
+}
+
diff --git a/reactos/lib/dnslib/debug.c b/reactos/lib/dnslib/debug.c
new file mode 100644 (file)
index 0000000..7ec3597
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/debug.c
+ * PURPOSE:     Contains helpful debugging functions for DNSLIB structures.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
diff --git a/reactos/lib/dnslib/dnsaddr.c b/reactos/lib/dnslib/dnsaddr.c
new file mode 100644 (file)
index 0000000..310a096
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/dnsaddr.c
+ * PURPOSE:     Functions dealing with DNS_ADDRESS and DNS_ARRAY addresses.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+PDNS_ARRAY
+WINAPI
+DnsAddrArray_Create(ULONG Count)
+{
+    PDNS_ARRAY DnsAddrArray;
+
+    /* Allocate space for the array and the addresses within it */
+    DnsAddrArray = Dns_AllocZero(sizeof(DNS_ARRAY) +
+                                 (Count * sizeof(DNS_ADDRESS)));
+
+    /* Write the allocated address count */
+    if (DnsAddrArray) DnsAddrArray->AllocatedAddresses = Count;
+
+    /* Return it */
+    return DnsAddrArray;
+}
+
+VOID
+WINAPI
+DnsAddrArray_Free(IN PDNS_ARRAY DnsAddrArray)
+{
+    /* Just free the entire array */
+    Dns_Free(DnsAddrArray);
+}
+
+BOOL
+WINAPI
+DnsAddrArray_AddIp4(IN PDNS_ARRAY DnsAddrArray,
+                    IN IN_ADDR Address,
+                    IN DWORD AddressType)
+{
+    DNS_ADDRESS DnsAddress;
+
+    /* Build the DNS Address */
+    DnsAddr_BuildFromIp4(&DnsAddress, Address, 0);
+
+    /* Add it to the array */
+    return DnsAddrArray_AddAddr(DnsAddrArray, &DnsAddress, 0, AddressType);
+}
+
+BOOL
+WINAPI
+DnsAddrArray_AddAddr(IN PDNS_ARRAY DnsAddrArray,
+                     IN PDNS_ADDRESS DnsAddress,
+                     IN WORD AddressFamily OPTIONAL,
+                     IN DWORD AddressType OPTIONAL)
+{
+    /* Make sure we have an array */
+    if (!DnsAddrArray) return FALSE;
+    
+    /* Check if we should validate the Address Family */
+    if (AddressFamily)
+    {
+        /* Validate it */
+        if (AddressFamily != DnsAddress->AddressFamily) return TRUE;
+    }
+
+    /* Check if we should validate the Address Type */
+    if (AddressType)
+    {
+        /* Make sure that this array contains this type of addresses */
+        if (!DnsAddrArray_ContainsAddr(DnsAddrArray, DnsAddress, AddressType))
+        {
+            /* Won't be adding it */
+            return TRUE;
+        }
+    }
+
+    /* Make sure we have space in the array */
+    if (DnsAddrArray->AllocatedAddresses < DnsAddrArray->UsedAddresses)
+    {
+        return FALSE; 
+    }
+
+    /* Now add the address */
+    RtlCopyMemory(&DnsAddrArray->Addresses[DnsAddrArray->UsedAddresses],
+                  DnsAddress,
+                  sizeof(DNS_ADDRESS));
+
+    /* Return success */
+    return TRUE;
+}
+
+VOID
+WINAPI
+DnsAddr_BuildFromIp4(IN PDNS_ADDRESS DnsAddress,
+                     IN IN_ADDR Address,
+                     IN WORD Port)
+{
+    /* Clear the address */
+    RtlZeroMemory(DnsAddress, sizeof(DNS_ADDRESS));
+
+    /* Write data */
+    DnsAddress->Ip4Address.sin_family = AF_INET;
+    DnsAddress->Ip4Address.sin_port  = Port;
+    DnsAddress->Ip4Address.sin_addr = Address;
+    DnsAddress->AddressLength = sizeof(SOCKADDR_IN);
+}
+
+VOID
+WINAPI
+DnsAddr_BuildFromIp6(IN PDNS_ADDRESS DnsAddress,
+                     IN PIN6_ADDR Address,
+                     IN ULONG ScopeId,
+                     IN WORD Port)
+{
+    /* Clear the address */
+    RtlZeroMemory(DnsAddress, sizeof(DNS_ADDRESS));
+
+    /* Write data */
+    DnsAddress->Ip6Address.sin6_family = AF_INET6;
+    DnsAddress->Ip6Address.sin6_port  = Port;
+    DnsAddress->Ip6Address.sin6_addr = *Address;
+    DnsAddress->Ip6Address.sin6_scope_id = ScopeId;
+    DnsAddress->AddressLength = sizeof(SOCKADDR_IN6);
+}
+
+VOID
+WINAPI
+DnsAddr_BuildFromAtm(IN PDNS_ADDRESS DnsAddress,
+                     IN DWORD AddressType,
+                     IN PVOID AddressData)
+{
+    ATM_ADDRESS Address;
+
+    /* Clear the address */
+    RtlZeroMemory(DnsAddress, sizeof(DNS_ADDRESS));
+
+    /* Build an ATM Address */
+    Address.AddressType = AddressType;
+    Address.NumofDigits = DNS_ATMA_MAX_ADDR_LENGTH;
+    RtlCopyMemory(&Address.Addr, AddressData, DNS_ATMA_MAX_ADDR_LENGTH);
+
+    /* Write data */
+    DnsAddress->AtmAddress = Address;
+    DnsAddress->AddressLength = sizeof(ATM_ADDRESS);
+}
+
+BOOLEAN
+WINAPI
+DnsAddr_BuildFromDnsRecord(IN PDNS_RECORD DnsRecord,
+                           OUT PDNS_ADDRESS DnsAddr)
+{
+    /* Check what kind of record this is */
+    switch(DnsRecord->wType)
+    {
+        /* IPv4 */
+        case DNS_TYPE_A:
+            /* Create the DNS Address */
+            DnsAddr_BuildFromIp4(DnsAddr,
+                                 *(PIN_ADDR)&DnsRecord->Data.A.IpAddress,
+                                 0);
+            break;
+
+        /* IPv6 */
+        case DNS_TYPE_AAAA:
+            /* Create the DNS Address */
+            DnsAddr_BuildFromIp6(DnsAddr,
+                                 (PIN6_ADDR)&DnsRecord->Data.AAAA.Ip6Address,
+                                 DnsRecord->dwReserved,
+                                 0);
+            break;
+
+        /* ATM */
+        case DNS_TYPE_ATMA:
+            /* Create the DNS Address */
+            DnsAddr_BuildFromAtm(DnsAddr,
+                                 DnsRecord->Data.Atma.AddressType,
+                                 &DnsRecord->Data.Atma.Address);
+            break;
+    }
+
+    /* Done! */
+    return TRUE;
+}
+
+BOOL
+WINAPI
+DnsAddrArray_ContainsAddr(IN PDNS_ARRAY DnsAddrArray,
+                          IN PDNS_ADDRESS DnsAddress,
+                          IN DWORD AddressType)
+{
+    /* FIXME */
+    return TRUE;
+}
+
diff --git a/reactos/lib/dnslib/dnslib.rbuild b/reactos/lib/dnslib/dnslib.rbuild
new file mode 100644 (file)
index 0000000..7780623
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="dnslib" type="staticlibrary" unicode="yes">
+       <include base="dnslib">inc</include>
+       <file>addr.c</file>
+       <file>debug.c</file>
+       <file>dnsaddr.c</file>
+       <file>dnsutil.c</file>
+       <file>flatbuf.c</file>
+       <file>hostent.c</file>
+       <file>ip6.c</file>
+       <file>memory.c</file>
+       <file>name.c</file>
+       <file>print.c</file>
+       <file>record.c</file>
+       <file>rrprint.c</file>
+       <file>sablob.c</file>
+       <file>straddr.c</file>
+       <file>string.c</file>
+       <file>table.c</file>
+       <file>utf8.c</file>
+</module>
diff --git a/reactos/lib/dnslib/dnsutil.c b/reactos/lib/dnslib/dnsutil.c
new file mode 100644 (file)
index 0000000..1d0e814
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/dnsutil.c
+ * PURPOSE:     Contains misc. DNS utility functions, like DNS_STATUS->String.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
diff --git a/reactos/lib/dnslib/flatbuf.c b/reactos/lib/dnslib/flatbuf.c
new file mode 100644 (file)
index 0000000..dfceb3e
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/flatbuf.c
+ * PURPOSE:     Functions for managing the Flat Buffer Implementation (FLATBUF)
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+WINAPI
+FlatBuf_Init(IN PFLATBUFF FlatBuffer,
+             IN PVOID Buffer,
+             IN SIZE_T Size)
+{
+    /* Set up the Flat Buffer start, current and ending position */
+    FlatBuffer->Buffer = Buffer;
+    FlatBuffer->BufferPos = (ULONG_PTR)Buffer;
+    FlatBuffer->BufferEnd = (PVOID)(FlatBuffer->BufferPos + Size);
+
+    /* Setup the current size and the available size */
+    FlatBuffer->BufferSize = FlatBuffer->BufferFreeSize = Size;
+}
+
+PVOID
+WINAPI
+FlatBuf_Arg_Reserve(IN OUT PULONG_PTR Position,
+                    IN OUT PSIZE_T FreeSize,
+                    IN SIZE_T Size,
+                    IN ULONG Align)
+{
+    ULONG_PTR NewPosition, OldPosition = *Position;
+    SIZE_T NewFreeSize = *FreeSize;
+
+    /* Start by aligning our position */
+    if (Align) OldPosition += (Align - 1) & ~Align;
+
+    /* Update it */
+    NewPosition = OldPosition + Size;
+
+    /* Update Free Size */
+    NewFreeSize += (OldPosition - NewPosition);
+
+    /* Save new values */
+    *Position = NewPosition;
+    *FreeSize = NewFreeSize;
+
+    /* Check if we're out of space or not */
+    if (NewFreeSize > 0) return (PVOID)OldPosition;
+    return NULL;
+}
+
+PVOID
+WINAPI
+FlatBuf_Arg_CopyMemory(IN OUT PULONG_PTR Position,
+                       IN OUT PSIZE_T FreeSize,
+                       IN PVOID Buffer,
+                       IN SIZE_T Size,
+                       IN ULONG Align)
+{
+    PVOID Destination;
+
+    /* First reserve the memory */
+    Destination = FlatBuf_Arg_Reserve(Position, FreeSize, Size, Align);
+    if (Destination)
+    {
+        /* We have space, do the copy */
+        RtlCopyMemory(Destination, Buffer, Size);
+    }
+
+    /* Return the pointer to the data */
+    return Destination;
+}
+
+PVOID
+WINAPI
+FlatBuf_Arg_WriteString(IN OUT PULONG_PTR Position,
+                        IN OUT PSIZE_T FreeSize,
+                        IN PVOID String,
+                        IN BOOLEAN IsUnicode)
+{
+    PVOID Destination;
+    SIZE_T StringLength;
+    ULONG Align;
+
+    /* Calculate the string length */
+    if (IsUnicode)
+    {
+        /* Get the length in bytes and use WCHAR alignment */
+        StringLength = (wcslen((LPWSTR)String) + 1) * sizeof(WCHAR);
+        Align = sizeof(WCHAR);
+    }
+    else
+    {
+        /* Get the length in bytes and use CHAR alignment */
+        StringLength = strlen((LPSTR)String) + 1;
+        Align = sizeof(CHAR);
+    }
+
+    /* Now reserve the memory */
+    Destination = FlatBuf_Arg_Reserve(Position, FreeSize, StringLength, Align);
+    if (Destination)
+    {
+        /* We have space, do the copy */
+        RtlCopyMemory(Destination, String, StringLength);
+    }
+
+    /* Return the pointer to the data */
+    return Destination;
+}
+
diff --git a/reactos/lib/dnslib/hostent.c b/reactos/lib/dnslib/hostent.c
new file mode 100644 (file)
index 0000000..f7c9e64
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/hostent.c
+ * PURPOSE:     Functions for dealing with Host Entry structures
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+PHOSTENT
+WINAPI
+Hostent_Init(IN PVOID *Buffer,
+             IN WORD AddressFamily,
+             IN ULONG AddressSize,
+             IN ULONG AddressCount,
+             IN ULONG AliasCount)
+{
+    PHOSTENT Hostent;
+    ULONG_PTR BufferPosition = (ULONG_PTR)*Buffer;
+
+    /* Align the hostent on the buffer's 4 byte boundary */
+    BufferPosition += 3 & ~3;
+
+    /* Set up the basic data */
+    Hostent = (PHOSTENT)BufferPosition;
+    Hostent->h_length = (WORD)AddressSize;
+    Hostent->h_addrtype = AddressFamily;
+
+    /* Put aliases after Hostent */
+    Hostent->h_aliases = (PCHAR*)((ULONG_PTR)(Hostent + 1) & ~3);
+
+    /* Zero it out */
+    RtlZeroMemory(Hostent->h_aliases, AliasCount * sizeof(PCHAR));
+
+    /* Put addresses after aliases */
+    Hostent->h_addr_list = (PCHAR*)
+                           ((ULONG_PTR)Hostent->h_aliases +
+                            (AliasCount * sizeof(PCHAR)) + sizeof(PCHAR));
+
+    /* Update the location */
+    BufferPosition = (ULONG_PTR)Hostent->h_addr_list +
+                     ((AddressCount * sizeof(PCHAR)) + sizeof(PCHAR));
+
+    /* Send it back */
+    *Buffer = (PVOID)BufferPosition;
+
+    /* Return the hostent */
+    return Hostent;
+}
+
+VOID
+WINAPI
+Dns_PtrArrayToOffsetArray(PCHAR *List,
+                          ULONG_PTR Base)
+{
+    /* Loop every pointer in the list */
+    do 
+    {
+        /* Update the pointer */
+        *List = (PCHAR)((ULONG_PTR)*List - Base);
+    } while(*List++);
+}
+
+VOID
+WINAPI
+Hostent_ConvertToOffsets(IN PHOSTENT Hostent)
+{
+    /* Do we have a name? */
+    if (Hostent->h_name)
+    {
+        /* Update it */
+        Hostent->h_name -= (ULONG_PTR)Hostent;
+    }
+
+    /* Do we have aliases? */
+    if (Hostent->h_aliases)
+    {
+        /* Update the pointer */
+        Hostent->h_aliases -= (ULONG_PTR)Hostent;
+
+        /* Fix them up */
+        Dns_PtrArrayToOffsetArray(Hostent->h_aliases, (ULONG_PTR)Hostent);
+    }
+
+    /* Do we have addresses? */
+    if (Hostent->h_addr_list)
+    {
+        /* Fix them up */
+        Dns_PtrArrayToOffsetArray(Hostent->h_addr_list, (ULONG_PTR)Hostent);
+    }
+}
+
diff --git a/reactos/lib/dnslib/inc/dnslib.h b/reactos/lib/dnslib/inc/dnslib.h
new file mode 100644 (file)
index 0000000..4c187f1
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS Ancillary Function Driver DLL
+ * FILE:        include/mswsock.h
+ * PURPOSE:     Ancillary Function Driver DLL header
+ */
+#ifndef __DNSLIB_H
+#define __DNSLIB_H
+
+/* INCLUDES ******************************************************************/
+#include <ws2atm.h>
+
+/* ENUMERATIONS **************************************************************/
+
+typedef enum _DNS_STRING_TYPE
+{
+    UnicodeString = 1,
+    Utf8String,
+    AnsiString,
+} DNS_STRING_TYPE;
+
+#define IpV4Address 3
+
+/* TYPES *********************************************************************/
+
+typedef struct _DNS_IPV6_ADDRESS
+{
+    ULONG Unknown;
+    ULONG Unknown2;
+    IP6_ADDRESS Address;
+    ULONG Unknown3;
+    ULONG Unknown4;
+    DWORD Reserved;
+    ULONG Unknown5;
+} DNS_IPV6_ADDRESS, *PDNS_IPV6_ADDRESS;
+
+typedef struct _DNS_ADDRESS
+{
+    union
+    {
+        struct
+        {
+            WORD AddressFamily;
+            WORD Port;
+            ATM_ADDRESS AtmAddress;
+        };
+        SOCKADDR_IN Ip4Address;
+        SOCKADDR_IN6 Ip6Address;
+    };
+    ULONG AddressLength;
+    DWORD Sub;
+    ULONG Flag;
+} DNS_ADDRESS, *PDNS_ADDRESS;
+
+typedef struct _DNS_ARRAY
+{
+    ULONG AllocatedAddresses;
+    ULONG UsedAddresses;
+    ULONG Unknown[0x6];
+    DNS_ADDRESS Addresses[1];
+} DNS_ARRAY, *PDNS_ARRAY;
+
+typedef struct _DNS_BLOB
+{
+    LPWSTR Name;
+    PDNS_ARRAY DnsAddrArray;
+    PHOSTENT Hostent;
+    ULONG AliasCount;
+    ULONG Unknown;
+    LPWSTR Aliases[8];
+} DNS_BLOB, *PDNS_BLOB;
+
+typedef struct _DNS_FAMILY_INFO
+{
+    WORD AddrType;
+    WORD DnsType;
+    DWORD AddressSize;
+    DWORD SockaddrSize;
+    DWORD AddressOffset;
+} DNS_FAMILY_INFO, *PDNS_FAMILY_INFO;
+
+typedef struct _FLATBUFF
+{
+    PVOID Buffer;
+    PVOID BufferEnd;
+    ULONG_PTR BufferPos;
+    SIZE_T BufferSize;
+    SIZE_T BufferFreeSize;
+} FLATBUFF, *PFLATBUFF;
+
+/*
+ * memory.c
+ */
+VOID
+WINAPI
+Dns_Free(IN PVOID Address);
+
+PVOID
+WINAPI
+Dns_AllocZero(IN SIZE_T Size);
+
+/*
+ * addr.c
+ */
+PDNS_FAMILY_INFO
+WINAPI
+FamilyInfo_GetForFamily(IN WORD AddressFamily);
+
+/*
+ * dnsaddr.c
+ */
+VOID
+WINAPI
+DnsAddr_BuildFromIp4(
+    IN PDNS_ADDRESS DnsAddress,
+    IN IN_ADDR Address,
+    IN WORD Unknown
+);
+
+VOID
+WINAPI
+DnsAddr_BuildFromIp6(
+    IN PDNS_ADDRESS DnsAddress,
+    IN PIN6_ADDR Address,
+    IN ULONG ScopeId,
+    IN WORD Port
+);
+
+PDNS_ARRAY
+WINAPI
+DnsAddrArray_Create(ULONG Count);
+
+BOOL
+WINAPI
+DnsAddrArray_AddAddr(
+    IN PDNS_ARRAY DnsAddrArray,
+    IN PDNS_ADDRESS DnsAddress,
+    IN WORD AddressFamily OPTIONAL,
+    IN DWORD AddressType OPTIONAL
+);
+
+VOID
+WINAPI
+DnsAddrArray_Free(IN PDNS_ARRAY DnsAddrArray);
+
+BOOL
+WINAPI
+DnsAddrArray_AddIp4(
+    IN PDNS_ARRAY DnsAddrArray,
+    IN IN_ADDR Address,
+    IN DWORD AddressType
+);
+
+BOOL
+WINAPI
+DnsAddrArray_ContainsAddr(
+    IN PDNS_ARRAY DnsAddrArray,
+    IN PDNS_ADDRESS DnsAddress,
+    IN DWORD AddressType
+);
+
+BOOLEAN
+WINAPI
+DnsAddr_BuildFromDnsRecord(
+    IN PDNS_RECORD DnsRecord,
+    OUT PDNS_ADDRESS DnsAddr
+);
+
+/*
+ * hostent.c
+ */
+PHOSTENT
+WINAPI
+Hostent_Init(
+    IN PVOID *Buffer,
+    IN WORD AddressFamily,
+    IN ULONG AddressSize,
+    IN ULONG AddressCount,
+    IN ULONG AliasCount
+);
+
+VOID
+WINAPI
+Hostent_ConvertToOffsets(IN PHOSTENT Hostent);
+
+/*
+ * flatbuf.c
+ */
+VOID
+WINAPI
+FlatBuf_Init(
+    IN PFLATBUFF FlatBuffer,
+    IN PVOID Buffer,
+    IN SIZE_T Size
+);
+
+PVOID
+WINAPI
+FlatBuf_Arg_CopyMemory(
+    IN OUT PULONG_PTR Position,
+    IN OUT PSIZE_T FreeSize,
+    IN PVOID Buffer,
+    IN SIZE_T Size,
+    IN ULONG Align
+);
+
+PVOID
+WINAPI
+FlatBuf_Arg_Reserve(
+    IN OUT PULONG_PTR Position,
+    IN OUT PSIZE_T FreeSize,
+    IN SIZE_T Size,
+    IN ULONG Align
+);
+
+PVOID
+WINAPI
+FlatBuf_Arg_WriteString(
+    IN OUT PULONG_PTR Position,
+    IN OUT PSIZE_T FreeSize,
+    IN PVOID String,
+    IN BOOLEAN IsUnicode
+);
+
+/*
+ * sablob.c
+ */
+PDNS_BLOB
+WINAPI
+SaBlob_Create(
+    IN ULONG Count
+);
+
+PDNS_BLOB
+WINAPI
+SaBlob_CreateFromIp4(
+    IN LPWSTR Name,
+    IN ULONG Count,
+    IN PIN_ADDR AddressArray
+);
+
+VOID
+WINAPI
+SaBlob_Free(IN PDNS_BLOB Blob);
+
+PHOSTENT
+WINAPI
+SaBlob_CreateHostent(
+    IN OUT PULONG_PTR BufferPosition,
+    IN OUT PSIZE_T RemainingBufferSpace,
+    IN OUT PSIZE_T HostEntrySize,
+    IN PDNS_BLOB Blob,
+    IN DWORD StringType,
+    IN BOOLEAN Relative,
+    IN BOOLEAN BufferAllocated
+);
+
+INT
+WINAPI
+SaBlob_WriteNameOrAlias(
+    IN PDNS_BLOB Blob,
+    IN LPWSTR String,
+    IN BOOLEAN IsAlias
+);
+
+PDNS_BLOB
+WINAPI
+SaBlob_Query(
+    IN LPWSTR Name,
+    IN WORD DnsType,
+    IN ULONG Flags,
+    IN PVOID *Reserved,
+    IN DWORD AddressFamily
+);
+
+/*
+ * string.c
+ */
+ULONG
+WINAPI
+Dns_StringCopy(
+    OUT PVOID Destination,
+    IN OUT PULONG DestinationSize,
+    IN PVOID String,
+    IN ULONG StringSize OPTIONAL,
+    IN DWORD InputType,
+    IN DWORD OutputType
+);
+
+LPWSTR
+WINAPI
+Dns_CreateStringCopy_W(IN LPWSTR Name);
+
+ULONG
+WINAPI
+Dns_GetBufferLengthForStringCopy(
+    IN PVOID String,
+    IN ULONG Size OPTIONAL,
+    IN DWORD InputType,
+    IN DWORD OutputType
+);
+
+/*
+ * straddr.c
+ */
+BOOLEAN
+WINAPI
+Dns_StringToAddressW(
+    OUT PVOID Address,
+    IN OUT PULONG AddressSize,
+    IN LPWSTR AddressName,
+    IN OUT PDWORD AddressFamily
+);
+
+LPWSTR
+WINAPI
+Dns_Ip4AddressToReverseName_W(
+    OUT LPWSTR Name,
+    IN IN_ADDR Address
+);
+
+LPWSTR
+WINAPI
+Dns_Ip6AddressToReverseName_W(
+    OUT LPWSTR Name,
+    IN IN6_ADDR Address
+);
+
+BOOLEAN
+WINAPI
+Dns_ReverseNameToDnsAddr_W(
+    OUT PDNS_ADDRESS DnsAddr,
+    IN LPWSTR Name
+);
+
+BOOLEAN
+WINAPI
+Dns_Ip4ReverseNameToAddress_W(
+    OUT PIN_ADDR Address,
+    IN LPWSTR Name
+);
+
+#endif
diff --git a/reactos/lib/dnslib/inc/precomp.h b/reactos/lib/dnslib/inc/precomp.h
new file mode 100644 (file)
index 0000000..b30cb07
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/precomp.h
+ * PURPOSE:     DNSLIB Precompiled Header
+ */
+
+#define _CRT_SECURE_NO_DEPRECATE
+#define _WIN32_WINNT 0x502
+#define WIN32_NO_STATUS
+
+/* PSDK Headers */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windns.h>
+
+/* DNSLIB and DNSAPI Headers */
+#include <dnslib.h>
+#include <windnsp.h>
+
+/* NDK */
+#include <rtlfuncs.h>
+
+/* EOF */
diff --git a/reactos/lib/dnslib/inc/windnsp.h b/reactos/lib/dnslib/inc/windnsp.h
new file mode 100644 (file)
index 0000000..48087eb
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNSAPI Header
+ * FILE:        include/libs/dns/windnsp.h
+ * PURPOSE:     DNSLIB Precompiled Header
+ */
+
+PVOID
+WINAPI
+DnsApiAlloc(
+    IN DWORD Size
+);
+
+PVOID
+WINAPI
+DnsQueryConfigAllocEx(
+    IN DNS_CONFIG_TYPE Config,
+    OUT PVOID pBuffer,
+    IN OUT PDWORD pBufferLength
+);
+
+PVOID
+WINAPI
+DnsApiFree(
+    IN PVOID pBuffer
+);
+
+/* EOF */
diff --git a/reactos/lib/dnslib/ip6.c b/reactos/lib/dnslib/ip6.c
new file mode 100644 (file)
index 0000000..921fef4
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/ip6.c
+ * PURPOSE:     Functions for dealing with IPv6 Specific issues.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
diff --git a/reactos/lib/dnslib/memory.c b/reactos/lib/dnslib/memory.c
new file mode 100644 (file)
index 0000000..183088c
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/memory.c
+ * PURPOSE:     DNS Memory Manager Implementation and Heap.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+typedef PVOID
+(WINAPI *PDNS_ALLOC_FUNCTION)(IN SIZE_T Size);
+typedef VOID
+(WINAPI *PDNS_FREE_FUNCTION)(IN PVOID Buffer);
+
+PDNS_ALLOC_FUNCTION pDnsAllocFunction;
+PDNS_FREE_FUNCTION pDnsFreeFunction;
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+WINAPI
+Dns_Free(IN PVOID Address)
+{
+    /* Check if whoever imported us specified a special free function */
+    if (pDnsFreeFunction)
+    {
+        /* Use it */
+        pDnsFreeFunction(Address);
+    }
+    else
+    {
+        /* Use our own */
+        LocalFree(Address);
+    }
+}
+
+PVOID
+WINAPI
+Dns_AllocZero(IN SIZE_T Size)
+{
+    PVOID Buffer;
+
+    /* Check if whoever imported us specified a special allocation function */
+    if (pDnsAllocFunction)
+    {
+        /* Use it to allocate the memory */
+        Buffer = pDnsAllocFunction(Size);
+        if (Buffer)
+        {
+            /* Zero it out */
+            RtlZeroMemory(Buffer, Size);
+        }
+    }
+    else
+    {
+        /* Use our default */
+        Buffer = LocalAlloc(LMEM_ZEROINIT, Size);
+    }
+
+    /* Return the allocate pointer */
+    return Buffer;
+}
+
diff --git a/reactos/lib/dnslib/name.c b/reactos/lib/dnslib/name.c
new file mode 100644 (file)
index 0000000..4004912
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/name.c
+ * PURPOSE:     Functions dealing with DNS (Canonical, FQDN, Host) Names
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
diff --git a/reactos/lib/dnslib/print.c b/reactos/lib/dnslib/print.c
new file mode 100644 (file)
index 0000000..bead765
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/print.c
+ * PURPOSE:     Callback Functions for printing a variety of DNSLIB Structures
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
diff --git a/reactos/lib/dnslib/record.c b/reactos/lib/dnslib/record.c
new file mode 100644 (file)
index 0000000..c0325a9
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/record.c
+ * PURPOSE:     Functions for managing DNS Record structures.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
diff --git a/reactos/lib/dnslib/rrprint.c b/reactos/lib/dnslib/rrprint.c
new file mode 100644 (file)
index 0000000..29a58ff
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/rrprint.c
+ * PURPOSE:     Callback functions for printing RR Structures for each Record.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
diff --git a/reactos/lib/dnslib/sablob.c b/reactos/lib/dnslib/sablob.c
new file mode 100644 (file)
index 0000000..1d720d2
--- /dev/null
@@ -0,0 +1,640 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/sablob.c
+ * PURPOSE:     Functions for the Saved Answer Blob Implementation
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+PVOID
+WINAPI
+FlatBuf_Arg_ReserveAlignPointer(IN PVOID Position,
+                                IN PSIZE_T FreeSize,
+                                IN SIZE_T Size)
+{
+    /* Just a little helper that we use */
+    return FlatBuf_Arg_Reserve(Position, FreeSize, Size, sizeof(PVOID));
+}
+
+PDNS_BLOB
+WINAPI
+SaBlob_Create(IN ULONG Count)
+{
+    PDNS_BLOB Blob;
+    PDNS_ARRAY DnsAddrArray;
+
+    /* Allocate the blob */
+    Blob = Dns_AllocZero(sizeof(DNS_BLOB));
+    if (Blob)
+    {
+        /* Check if it'll hold any addresses */
+        if (Count)
+        {
+            /* Create the DNS Address Array */
+            DnsAddrArray = DnsAddrArray_Create(Count);
+            if (!DnsAddrArray)
+            {
+                /* Failure, free the blob */
+                SaBlob_Free(Blob);
+                SetLastError(ERROR_OUTOFMEMORY);
+            }
+            else
+            {
+                /* Link it with the blob */
+                Blob->DnsAddrArray = DnsAddrArray;
+            }
+        }
+    }
+
+    /* Return the blob */
+    return Blob;
+}
+
+PDNS_BLOB
+WINAPI
+SaBlob_CreateFromIp4(IN LPWSTR Name,
+                     IN ULONG Count,
+                     IN PIN_ADDR AddressArray)
+{
+    PDNS_BLOB Blob;
+    LPWSTR NameCopy;
+    ULONG i;
+
+    /* Create the blob */
+    Blob = SaBlob_Create(Count);
+    if (!Blob) goto Quickie;
+
+    /* If we have a name */
+    if (Name)
+    {
+        /* Create a copy of it */
+        NameCopy = Dns_CreateStringCopy_W(Name);
+        if (!NameCopy) goto Quickie;
+
+        /* Save the pointer to the name */
+        Blob->Name = NameCopy;
+    }
+
+    /* Loop all the addresses */
+    for (i = 0; i < Count; i++)
+    {
+        /* Add an entry for this address */
+        DnsAddrArray_AddIp4(Blob->DnsAddrArray, AddressArray[i], IpV4Address);
+    }
+
+    /* Return the blob */
+    return Blob;
+
+Quickie:
+    /* Free the blob, set error and fail */
+    SaBlob_Free(Blob);
+    SetLastError(ERROR_OUTOFMEMORY);
+    return NULL;
+}
+
+VOID
+WINAPI
+SaBlob_Free(IN PDNS_BLOB Blob)
+{
+    /* Make sure we got a blob */
+    if (Blob)
+    {
+        /* Free the name */
+        Dns_Free(Blob->Name);
+
+        /* Loop the aliases */
+        while (Blob->AliasCount)
+        {
+            /* Free the alias */
+            Dns_Free(Blob->Aliases[Blob->AliasCount]);
+
+            /* Decrease number of aliases */
+            Blob->AliasCount--;
+        }
+
+        /* Free the DNS Address Array */
+        DnsAddrArray_Free(Blob->DnsAddrArray);
+
+        /* Free the blob itself */
+        Dns_Free(Blob);
+    }
+}
+
+PHOSTENT
+WINAPI
+SaBlob_CreateHostent(IN OUT PULONG_PTR BufferPosition,
+                     IN OUT PSIZE_T FreeBufferSpace,
+                     IN OUT PSIZE_T HostEntrySize,
+                     IN PDNS_BLOB Blob,
+                     IN DWORD StringType,
+                     IN BOOLEAN Relative,
+                     IN BOOLEAN BufferAllocated)
+{
+    PDNS_ARRAY DnsAddrArray = Blob->DnsAddrArray;
+    ULONG AliasCount = Blob->AliasCount;
+    WORD AddressFamily = AF_UNSPEC;
+    ULONG AddressCount = 0, AddressSize = 0, TotalSize, NamePointerSize;
+    ULONG AliasPointerSize;
+    PDNS_FAMILY_INFO FamilyInfo = NULL;
+    ULONG StringLength = 0;
+    ULONG i;
+    ULONG HostentSize = 0;
+    PHOSTENT Hostent = NULL;
+    ULONG_PTR HostentPtr;
+    PVOID CurrentAddress;
+
+    /* Check if we actually have any addresses */
+    if (DnsAddrArray)
+    {
+        /* Get the address family */
+        AddressFamily = DnsAddrArray->Addresses[0].AddressFamily;
+
+        /* Get family information */
+        FamilyInfo = FamilyInfo_GetForFamily(AddressFamily);
+
+        /* Save the current address count and their size */
+        AddressCount = DnsAddrArray->UsedAddresses;
+        AddressSize = FamilyInfo->AddressSize;
+    }
+
+    /* Calculate total size for all the addresses, and their pointers */
+    TotalSize = AddressSize * AddressCount;
+    NamePointerSize = AddressCount * sizeof(PVOID) + sizeof(PVOID);
+
+    /* Check if we have a name */
+    if (Blob->Name)
+    {
+        /* Find out the size we'll need for a copy */
+        StringLength = (Dns_GetBufferLengthForStringCopy(Blob->Name,
+                                                         0,
+                                                         UnicodeString,
+                                                         StringType) + 1) & ~1;
+    }
+
+    /*  Now do the same for the aliases */
+    for (i = AliasCount; i; i--)
+    {
+        /* Find out the size we'll need for a copy */
+        HostentSize += (Dns_GetBufferLengthForStringCopy(Blob->Aliases[i],
+                                                         0,
+                                                         UnicodeString,
+                                                         StringType) + 1) & ~1;
+    }
+
+    /* Find out how much the pointers will take */
+    AliasPointerSize = AliasCount * sizeof(PVOID) + sizeof(PVOID);
+
+    /* Calculate Hostent Size */
+    HostentSize += TotalSize +
+                   NamePointerSize +
+                   AliasPointerSize +
+                   StringLength +
+                   sizeof(HOSTENT);
+
+    /* Check if we already have a buffer */
+    if (!BufferAllocated)
+    {
+        /* We don't, allocate space ourselves */
+        HostentPtr = (ULONG_PTR)Dns_AllocZero(HostentSize);
+    }
+    else
+    {
+        /* We do, so allocate space in the buffer */
+        HostentPtr = (ULONG_PTR)FlatBuf_Arg_ReserveAlignPointer(BufferPosition,
+                                                                FreeBufferSpace,
+                                                                HostentSize);
+    }
+
+    /* Make sure we got space */
+    if (HostentPtr)
+    {
+        /* Initialize it */
+        Hostent = Hostent_Init((PVOID)&HostentPtr,
+                               AddressFamily,
+                               AddressSize,
+                               AddressCount,
+                               AliasCount);
+    }
+
+    /* Loop the addresses */
+    for (i = 0; i < AddressCount; i++)
+    {
+        /* Get the pointer of the current address */
+        CurrentAddress = (PVOID)((ULONG_PTR)&DnsAddrArray->Addresses[i] +
+                                             FamilyInfo->AddressOffset);
+
+        /* Write the pointer */
+        Hostent->h_addr_list[i] = (PCHAR)HostentPtr;
+
+        /* Copy the address */
+        RtlCopyMemory((PVOID)HostentPtr, CurrentAddress, AddressSize);
+
+        /* Advance the buffer */
+        HostentPtr += AddressSize;
+    }
+
+    /* Check if we have a name */
+    if (Blob->Name)
+    {
+        /* Align our current position */
+        HostentPtr += 1 & ~1;
+
+        /* Save our name here */
+        Hostent->h_name = (LPSTR)HostentPtr;
+
+        /* Now copy it in the blob */
+        HostentPtr += Dns_StringCopy((PVOID)HostentPtr,
+                                     NULL,
+                                     Blob->Name,
+                                     0,
+                                     UnicodeString,
+                                     StringType);
+    }
+
+    /* Loop the Aliases */
+    for (i = AliasCount; i; i--)
+    {
+        /* Align our current position */
+        HostentPtr += 1 & ~1;
+
+        /* Save our alias here */
+        Hostent->h_aliases[i] = (LPSTR)HostentPtr;
+
+        /* Now copy it in the blob */
+        HostentPtr += Dns_StringCopy((PVOID)HostentPtr,
+                                     NULL,
+                                     Blob->Aliases[i],
+                                     0,
+                                     UnicodeString,
+                                     StringType);
+    }
+
+    /* Check if the caller didn't have a buffer */
+    if (!BufferAllocated)
+    {
+        /* Return the size; not needed if we had a blob, since it's internal */
+        *HostEntrySize = *BufferPosition - (ULONG_PTR)HostentPtr;
+    }
+
+    /* Convert to Offsets if requested */
+    if(Relative) Hostent_ConvertToOffsets(Hostent);
+
+    /* Return the full, complete, hostent */
+    return Hostent;
+}
+
+INT
+WINAPI
+SaBlob_WriteNameOrAlias(IN PDNS_BLOB Blob,
+                        IN LPWSTR String,
+                        IN BOOLEAN IsAlias)
+{
+    /* Check if this is an alias */
+    if (!IsAlias)
+    {
+        /* It's not. Simply create a copy of the string */
+        Blob->Name = Dns_CreateStringCopy_W(String);
+        if (!Blob->Name) return GetLastError();
+    }
+    else
+    {
+        /* Does it have a name, and less then 8 aliases? */
+        if ((Blob->Name) && (Blob->AliasCount <= 8))
+        {
+            /* Yup, create a copy of the string and increase the alias count */
+            Blob->Aliases[Blob->AliasCount] = Dns_CreateStringCopy_W(String);
+            Blob->AliasCount++;
+        }
+        else
+        {
+            /* Invalid request! */
+            return ERROR_MORE_DATA;
+        }
+    }
+
+    /* Return Success */
+    return ERROR_SUCCESS;
+}
+
+INT
+WINAPI
+SaBlob_WriteAddress(IN PDNS_BLOB Blob,
+                    OUT PDNS_ADDRESS DnsAddr)
+{
+    /* Check if we have an array yet */
+    if (!Blob->DnsAddrArray)
+    {
+        /* Allocate one! */
+        Blob->DnsAddrArray = DnsAddrArray_Create(1);
+        if (!Blob->DnsAddrArray) return ERROR_OUTOFMEMORY;
+    }
+
+    /* Add this address */
+    return DnsAddrArray_AddAddr(Blob->DnsAddrArray, DnsAddr, AF_UNSPEC, 0) ?
+           ERROR_SUCCESS:
+           ERROR_MORE_DATA;
+}
+
+BOOLEAN
+WINAPI
+SaBlob_IsSupportedAddrType(WORD DnsType)
+{
+    /* Check for valid Types that we support */
+    return (DnsType == DNS_TYPE_A ||
+            DnsType == DNS_TYPE_ATMA ||
+            DnsType == DNS_TYPE_AAAA);
+}
+
+INT
+WINAPI
+SaBlob_WriteRecords(OUT PDNS_BLOB Blob,
+                    IN PDNS_RECORD DnsRecord,
+                    IN BOOLEAN DoAlias)
+{
+    DNS_ADDRESS DnsAddress;
+    INT ErrorCode = STATUS_INVALID_PARAMETER;
+    BOOLEAN WroteOnce = FALSE;
+
+    /* Zero out the Address */
+    RtlZeroMemory(&DnsAddress, sizeof(DnsAddress));
+
+    /* Loop through all the Records */
+    while (DnsRecord)
+    {
+        /* Is this not an answer? */
+        if (DnsRecord->Flags.S.Section != DNSREC_ANSWER)
+        {
+            /* Then simply move on to the next DNS Record */
+            DnsRecord = DnsRecord->pNext;
+            continue;
+        }
+
+        /* Check the type of thsi record */
+        switch(DnsRecord->wType)
+        {
+            /* Regular IPv4, v6 or ATM Record */
+            case DNS_TYPE_A:
+            case DNS_TYPE_AAAA:
+            case DNS_TYPE_ATMA:
+
+                /* Create a DNS Address from the record */
+                DnsAddr_BuildFromDnsRecord(DnsRecord, &DnsAddress);
+
+                /* Add it to the DNS Blob */
+                ErrorCode = SaBlob_WriteAddress(Blob, &DnsAddress);
+
+                /* Add the name, if needed */
+                if ((DoAlias) &&
+                    (!WroteOnce) &&
+                    (!Blob->Name) &&
+                    (DnsRecord->pName))
+                {
+                    /* Write the name from the DNS Record */
+                    ErrorCode = SaBlob_WriteNameOrAlias(Blob,
+                                                        DnsRecord->pName,
+                                                        FALSE);
+                    WroteOnce = TRUE;
+                }
+                break;
+
+            case DNS_TYPE_CNAME:
+
+                /* Just write the alias name */
+                ErrorCode = SaBlob_WriteNameOrAlias(Blob,
+                                                    DnsRecord->pName,
+                                                    TRUE);
+                break;
+
+            case DNS_TYPE_PTR:
+
+                /* Check if we already have a name */
+                if (Blob->Name)
+                {
+                    /* We don't, so add this as a name */
+                    ErrorCode = SaBlob_WriteNameOrAlias(Blob,
+                                                        DnsRecord->pName,
+                                                        FALSE);
+                }
+                else
+                {
+                    /* We do, so add it as an alias */
+                    ErrorCode = SaBlob_WriteNameOrAlias(Blob,
+                                                        DnsRecord->pName,
+                                                        TRUE);
+                }
+                break;
+            default:
+                break;
+        }
+
+        /* Next record */
+        DnsRecord = DnsRecord->pNext;
+    }
+
+    /* Return error code */
+    return ErrorCode;
+}
+
+PDNS_BLOB
+WINAPI
+SaBlob_CreateFromRecords(IN PDNS_RECORD DnsRecord,
+                         IN BOOLEAN DoAliases,
+                         IN DWORD DnsType)
+{
+    PDNS_RECORD LocalDnsRecord;
+    ULONG ProcessedCount = 0;
+    PDNS_BLOB DnsBlob;
+    INT ErrorCode;
+    DNS_ADDRESS DnsAddress;
+
+    /* Find out how many DNS Addresses to allocate */
+    LocalDnsRecord = DnsRecord;
+    while (LocalDnsRecord)
+    {
+        /* Make sure this record is an answer */
+        if ((LocalDnsRecord->Flags.S.Section == DNSREC_ANSWER) &&
+            (SaBlob_IsSupportedAddrType(LocalDnsRecord->wType)))
+        {
+            /* Increase number of records to process */
+            ProcessedCount++;
+        }
+
+        /* Move to the next record */
+        LocalDnsRecord = LocalDnsRecord->pNext;
+    }
+
+    /* Create the DNS Blob */
+    DnsBlob = SaBlob_Create(ProcessedCount);
+    if (!DnsBlob)
+    {
+        /* Fail */
+        ErrorCode = GetLastError();
+        goto Quickie;
+    }
+
+    /* Write the record to the DNS Blob */
+    ErrorCode = SaBlob_WriteRecords(DnsBlob, DnsRecord, TRUE);
+    if (ErrorCode != NO_ERROR)
+    {
+        /* We failed... but do we still have valid data? */
+        if ((DnsBlob->Name) || (DnsBlob->AliasCount))
+        {
+            /* We'll just assume success then */
+            ErrorCode = NO_ERROR;
+        }
+        else
+        {
+            /* Ok, last chance..do you have a DNS Address Array? */
+            if ((DnsBlob->DnsAddrArray) &&
+                (DnsBlob->DnsAddrArray->UsedAddresses))
+            {
+                /* Boy are you lucky! */
+                ErrorCode = NO_ERROR;
+            }
+        }
+
+        /* Buh-bye! */
+        goto Quickie;
+    }
+
+    /* Check if this is a PTR record */
+    if ((DnsRecord->wType == DNS_TYPE_PTR) ||
+        ((DnsType == DNS_TYPE_PTR) &&
+         (DnsRecord->wType == DNS_TYPE_CNAME) &&
+         (DnsRecord->Flags.S.Section == DNSREC_ANSWER)))
+    {
+        /* Get a DNS Address Structure */
+        if (Dns_ReverseNameToDnsAddr_W(&DnsAddress, DnsRecord->pName))
+        {
+            /* Add it to the Blob */
+            if (SaBlob_WriteAddress(DnsBlob, &DnsAddress)) ErrorCode = NO_ERROR;
+        }
+    }
+
+    /* Ok...do we still not have a name? */
+    if (!(DnsBlob->Name) && (DoAliases) && (LocalDnsRecord))
+    {
+        /* We have an local DNS Record, so just use it to write the name */
+        ErrorCode = SaBlob_WriteNameOrAlias(DnsBlob,
+                                            LocalDnsRecord->pName,
+                                            FALSE);
+    }
+
+Quickie:
+    /* Check error code */
+    if (ErrorCode != NO_ERROR)
+    {
+        /* Free the blob and set the error */
+        SaBlob_Free(DnsBlob);
+        DnsBlob = NULL;
+        SetLastError(ErrorCode);
+    }
+
+    /* Return */
+    return DnsBlob;
+}
+
+PDNS_BLOB
+WINAPI
+SaBlob_Query(IN LPWSTR Name,
+             IN WORD DnsType,
+             IN ULONG Flags,
+             IN PVOID *Reserved,
+             IN DWORD AddressFamily)
+{
+    PDNS_RECORD DnsRecord = NULL;
+    INT ErrorCode;
+    PDNS_BLOB DnsBlob = NULL;
+    LPWSTR LocalName, LocalNameCopy;
+
+    /* If they want reserved data back, clear it out in case we fail */
+    if (Reserved) *Reserved = NULL;
+
+    /* Query DNS */
+    ErrorCode = DnsQuery_W(Name,
+                           DnsType,
+                           Flags,
+                           NULL,
+                           &DnsRecord,
+                           Reserved);
+    if (ErrorCode != ERROR_SUCCESS)
+    {
+        /* We failed... did the caller use reserved data? */
+        if (Reserved && *Reserved)
+        {
+            /* He did, and it was valid. Free it */
+            DnsApiFree(*Reserved);
+            *Reserved = NULL;
+        }
+
+        /* Normalize error code */
+        if (ErrorCode == RPC_S_SERVER_UNAVAILABLE) ErrorCode = WSATRY_AGAIN;
+        goto Quickie;
+    }
+
+    /* Now create the Blob from the DNS Records */
+    DnsBlob = SaBlob_CreateFromRecords(DnsRecord, TRUE, DnsType);
+    if (!DnsBlob)
+    {
+        /* Failed, get error code */
+        ErrorCode = GetLastError();
+        goto Quickie;
+    }
+
+    /* Make sure it has a name */
+    if (!DnsBlob->Name)
+    {
+        /* It doesn't, fail */
+        ErrorCode = DNS_INFO_NO_RECORDS;
+        goto Quickie;
+    }
+
+    /* Check if the name is local or loopback */
+    if (!(DnsNameCompare_W(DnsBlob->Name, L"localhost")) &&
+        !(DnsNameCompare_W(DnsBlob->Name, L"loopback")))
+    {
+        /* Nothing left to do, exit! */
+        goto Quickie;
+    }
+
+    /* This is a local name...query it */
+    LocalName = DnsQueryConfigAllocEx(DnsConfigFullHostName_W, NULL, NULL);
+    if (LocalName)
+    {
+        /* Create a copy for the caller */
+        LocalNameCopy = Dns_CreateStringCopy_W(LocalName);
+        if (LocalNameCopy)
+        {
+            /* Overwrite the one in the blob */
+            DnsBlob->Name = LocalNameCopy;
+        }
+        else
+        {
+            /* We failed to make a copy, free memory */
+            DnsApiFree(LocalName);
+        }
+    }
+
+Quickie:
+    /* Free the DNS Record if we have one */
+    if (DnsRecord) DnsRecordListFree(DnsRecord, DnsFreeRecordList);
+
+    /* Check if this is a failure path with an active blob */
+    if ((ErrorCode != ERROR_SUCCESS) && (DnsBlob))
+    {
+        /* Free the blob */
+        SaBlob_Free(DnsBlob);
+        DnsBlob = NULL;
+    }
+
+    /* Set the last error and return */
+    SetLastError(ErrorCode);
+    return DnsBlob;
+}
+
diff --git a/reactos/lib/dnslib/straddr.c b/reactos/lib/dnslib/straddr.c
new file mode 100644 (file)
index 0000000..4215a80
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/straddr.c
+ * PURPOSE:     Functions for address<->string conversion.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+LPWSTR
+WINAPI
+Dns_Ip6AddressToReverseName_W(OUT LPWSTR Name,
+                              IN IN6_ADDR Address)
+{
+    /* FIXME */
+    return NULL;
+}
+
+LPWSTR
+WINAPI
+Dns_Ip4AddressToReverseName_W(OUT LPWSTR Name,
+                              IN IN_ADDR Address)
+{
+    /* Simply append the ARPA string */
+    return Name + (wsprintfW(Name,
+                             L"%u.%u.%u.%u.in-addr.arpa.",
+                             Address.S_un.S_addr >> 24,
+                             Address.S_un.S_addr >> 10,
+                             Address.S_un.S_addr >> 8,
+                             Address.S_un.S_addr) * sizeof(WCHAR));
+}
+
+BOOLEAN
+WINAPI
+Dns_Ip4ReverseNameToAddress_A(OUT PIN_ADDR Address,
+                              IN LPSTR Name)
+{
+    /* FIXME */
+    return FALSE;
+}
+
+BOOLEAN
+WINAPI
+Dns_Ip6ReverseNameToAddress_A(OUT PIN6_ADDR Address,
+                              IN LPSTR Name)
+{
+    /* FIXME */
+    return FALSE;
+}
+
+BOOLEAN
+WINAPI
+Dns_Ip6StringToAddress_A(OUT PIN6_ADDR Address,
+                         IN LPSTR Name)
+{
+    PCHAR Terminator;
+    NTSTATUS Status;
+
+    /* Let RTL Do it for us */
+    Status = RtlIpv6StringToAddressA(Name, &Terminator, Address);
+    if (NT_SUCCESS(Status)) return TRUE;
+
+    /* We failed */
+    return FALSE;
+}
+
+BOOLEAN
+WINAPI
+Dns_Ip6StringToAddress_W(OUT PIN6_ADDR Address,
+                         IN LPWSTR Name)
+{
+    PCHAR Terminator;
+    NTSTATUS Status;
+
+    /* Let RTL Do it for us */
+    Status = RtlIpv6StringToAddressW(Name, &Terminator, Address);
+    if (NT_SUCCESS(Status)) return TRUE;
+
+    /* We failed */
+    return FALSE;
+}
+
+BOOLEAN
+WINAPI
+Dns_Ip4StringToAddress_A(OUT PIN_ADDR Address,
+                         IN LPSTR Name)
+{
+    ULONG Addr;
+
+    /* Use inet_addr to convert it... */
+    Addr = inet_addr(Name);
+    if (Addr == -1)
+    {
+        /* Check if it's the wildcard (which is ok...) */
+        if (strcmp("255.255.255.255", Name)) return FALSE;
+    }
+
+    /* If we got here, then we suceeded... return the address */
+    Address->S_un.S_addr = Addr;
+    return TRUE;
+}
+
+BOOLEAN
+WINAPI
+Dns_Ip4StringToAddress_W(OUT PIN_ADDR Address,
+                         IN LPWSTR Name)
+{
+    CHAR AnsiName[16];
+    ULONG Size = sizeof(AnsiName);
+    INT ErrorCode;
+
+    /* Make a copy of the name in ANSI */
+    ErrorCode = Dns_StringCopy(&AnsiName,
+                               &Size,
+                               Name,
+                               0,
+                               UnicodeString,
+                               AnsiString);
+    if (ErrorCode)
+    {
+        /* Copy made sucesfully, now convert it */
+        ErrorCode = Dns_Ip4StringToAddress_A(Address, AnsiName);
+    }
+
+    /* Return either 0 bytes copied (failure == false) or conversion status */
+    return ErrorCode;
+}
+
+BOOLEAN
+WINAPI
+Dns_Ip4ReverseNameToAddress_W(OUT PIN_ADDR Address,
+                              IN LPWSTR Name)
+{
+    CHAR AnsiName[32];
+    ULONG Size = sizeof(AnsiName);
+    INT ErrorCode;
+
+    /* Make a copy of the name in ANSI */
+    ErrorCode = Dns_StringCopy(&AnsiName,
+                               &Size,
+                               Name,
+                               0,
+                               UnicodeString,
+                               AnsiString);
+    if (ErrorCode)
+    {
+        /* Copy made sucesfully, now convert it */
+        ErrorCode = Dns_Ip4ReverseNameToAddress_A(Address, AnsiName);
+    }
+
+    /* Return either 0 bytes copied (failure == false) or conversion status */
+    return ErrorCode;
+}
+
+BOOLEAN
+WINAPI
+Dns_StringToAddressEx(OUT PVOID Address,
+                      IN OUT PULONG AddressSize,
+                      IN PVOID AddressName,
+                      IN OUT PDWORD AddressFamily,
+                      IN BOOLEAN Unicode,
+                      IN BOOLEAN Reverse)
+{
+    DWORD Af = *AddressFamily;
+    ULONG AddrSize = *AddressSize;
+    IN6_ADDR Addr;
+    BOOLEAN Return;
+    INT ErrorCode;
+    CHAR AnsiName[INET6_ADDRSTRLEN + sizeof("ip6.arpa.")];
+    ULONG Size = sizeof(AnsiName);
+
+    /* First check if this is a reverse address string */
+    if (Reverse)
+    {
+        /* Convert it right now to ANSI as an optimization */
+        Dns_StringCopy(AnsiName,
+                       &Size,
+                       AddressName,
+                       0,
+                       UnicodeString,
+                       AnsiString);
+
+        /* Use the ANSI Name instead */
+        AddressName = AnsiName;
+    }
+
+    /* 
+     * If the caller doesn't know what the family is, we'll assume IPv4 and
+     * check if we failed or not. If the caller told us it's IPv4, then just
+     * do IPv4...
+     */
+    if ((Af == AF_UNSPEC) || (Af == AF_INET))
+    {
+        /* Now check if the caller gave us the reverse name or not */
+        if (Reverse)
+        {
+            /* Get the Address */
+            Return = Dns_Ip4ReverseNameToAddress_A((PIN_ADDR)&Addr, AddressName);
+        }
+        else
+        {
+            /* Check if the caller gave us unicode or not */
+            if (Unicode)
+            {
+                /* Get the Address */
+                Return = Dns_Ip4StringToAddress_W((PIN_ADDR)&Addr, AddressName);
+            }
+            else
+            {
+                /* Get the Address */
+                Return = Dns_Ip4StringToAddress_A((PIN_ADDR)&Addr, AddressName);
+            }
+        }
+
+        /* Check if we suceeded */
+        if (Return)
+        {
+            /* Save address family */
+            Af = AF_INET;
+
+            /* Check if the address size matches */
+            if (AddrSize < sizeof(IN_ADDR))
+            {
+                /* Invalid match, set error code */
+                ErrorCode = ERROR_MORE_DATA;
+            }
+            else
+            {
+                /* It matches, save the address! */
+                *(PIN_ADDR)Address = *(PIN_ADDR)&Addr;
+            }
+        }
+    }
+
+    /* If we are here, either AF_INET6 was specified or IPv4 failed */
+    if ((Af == AF_UNSPEC) || (Af == AF_INET6))
+    {
+        /* Now check if the caller gave us the reverse name or not */
+        if (Reverse)
+        {
+            /* Get the Address */
+            Return = Dns_Ip6ReverseNameToAddress_A(&Addr, AddressName);
+        }
+        else
+        {
+            /* Check if the caller gave us unicode or not */
+            if (Unicode)
+            {
+                /* Get the Address */
+                Return = Dns_Ip6StringToAddress_W(&Addr, AddressName);
+            }
+            else
+            {
+                /* Get the Address */
+                Return = Dns_Ip6StringToAddress_A(&Addr, AddressName);
+            }
+        }
+
+        /* Check if we suceeded */
+        if (Return)
+        {
+            /* Save address family */
+            Af = AF_INET6;
+
+            /* Check if the address size matches */
+            if (AddrSize < sizeof(IN6_ADDR))
+            {
+                /* Invalid match, set error code */
+                ErrorCode = ERROR_MORE_DATA;
+            }
+            else
+            {
+                /* It matches, save the address! */
+                *(PIN6_ADDR)Address = Addr;
+            }
+        }
+    }
+    else if (Af != AF_INET)
+    {
+        /* You're like.. ATM or something? Get outta here! */
+        Af = AF_UNSPEC;
+        ErrorCode = WSA_INVALID_PARAMETER;
+    }
+
+    /* Set error if we had one */
+    if (ErrorCode) SetLastError(ErrorCode);
+
+    /* Return the address family and size */
+    *AddressFamily = Af;
+    *AddressSize = AddrSize;
+
+    /* Return success or failure */
+    return (ErrorCode == ERROR_SUCCESS);
+}
+
+BOOLEAN
+WINAPI
+Dns_StringToAddressW(OUT PVOID Address,
+                     IN OUT PULONG AddressSize,
+                     IN LPWSTR AddressName,
+                     IN OUT PDWORD AddressFamily)
+{
+    /* Call the common API */
+    return Dns_StringToAddressEx(Address,
+                                 AddressSize,
+                                 AddressName,
+                                 AddressFamily,
+                                 TRUE,
+                                 FALSE);
+}
+
+BOOLEAN
+WINAPI
+Dns_StringToDnsAddrEx(OUT PDNS_ADDRESS DnsAddr,
+                      IN PVOID AddressName,
+                      IN DWORD AddressFamily,
+                      IN BOOLEAN Unicode,
+                      IN BOOLEAN Reverse)
+{
+    IN6_ADDR Addr;
+    BOOLEAN Return;
+    INT ErrorCode = ERROR_SUCCESS;
+    CHAR AnsiName[INET6_ADDRSTRLEN + sizeof("ip6.arpa.")];
+    ULONG Size = sizeof(AnsiName);
+
+    /* First check if this is a reverse address string */
+    if ((Reverse) && (Unicode))
+    {
+        /* Convert it right now to ANSI as an optimization */
+        Dns_StringCopy(AnsiName,
+                       &Size,
+                       AddressName,
+                       0,
+                       UnicodeString,
+                       AnsiString);
+
+        /* Use the ANSI Name instead */
+        AddressName = AnsiName;
+    }
+
+    /* 
+     * If the caller doesn't know what the family is, we'll assume IPv4 and
+     * check if we failed or not. If the caller told us it's IPv4, then just
+     * do IPv4...
+     */
+    if ((AddressFamily == AF_UNSPEC) || (AddressFamily == AF_INET))
+    {
+        /* Now check if the caller gave us the reverse name or not */
+        if (Reverse)
+        {
+            /* Get the Address */
+            Return = Dns_Ip4ReverseNameToAddress_A((PIN_ADDR)&Addr, AddressName);
+        }
+        else
+        {
+            /* Check if the caller gave us unicode or not */
+            if (Unicode)
+            {
+                /* Get the Address */
+                Return = Dns_Ip4StringToAddress_W((PIN_ADDR)&Addr, AddressName);
+            }
+            else
+            {
+                /* Get the Address */
+                Return = Dns_Ip4StringToAddress_A((PIN_ADDR)&Addr, AddressName);
+            }
+        }
+
+        /* Check if we suceeded */
+        if (Return)
+        {
+            /* Build the IPv4 Address */
+            DnsAddr_BuildFromIp4(DnsAddr, *(PIN_ADDR)&Addr, 0);
+
+            /* So we don't go in the code below... */
+            AddressFamily = AF_INET;
+        }
+    }
+
+    /* If we are here, either AF_INET6 was specified or IPv4 failed */
+    if ((AddressFamily == AF_UNSPEC) || (AddressFamily == AF_INET6))
+    {
+        /* Now check if the caller gave us the reverse name or not */
+        if (Reverse)
+        {
+            /* Get the Address */
+            Return = Dns_Ip6ReverseNameToAddress_A(&Addr, AddressName);
+            if (Return)
+            {
+                /* Build the IPv6 Address */
+                DnsAddr_BuildFromIp6(DnsAddr, &Addr, 0, 0);
+            }
+            else
+            {
+                goto Quickie;
+            }
+        }
+        else
+        {
+            /* Check if the caller gave us unicode or not */
+            if (Unicode)
+            {
+                /* Get the Address */
+                if (NT_SUCCESS(RtlIpv6StringToAddressExW(AddressName,
+                                                         &DnsAddr->Ip6Address.sin6_addr,
+                                                         &DnsAddr->Ip6Address.sin6_scope_id,
+                                                         &DnsAddr->Ip6Address.sin6_port)))
+                    Return = TRUE;
+                else
+                    Return = FALSE;
+            }
+            else
+            {
+                /* Get the Address */
+                if (NT_SUCCESS(RtlIpv6StringToAddressExA(AddressName,
+                                                         &DnsAddr->Ip6Address.sin6_addr,
+                                                         &DnsAddr->Ip6Address.sin6_scope_id,
+                                                         &DnsAddr->Ip6Address.sin6_port)))
+                   Return = TRUE;
+                else
+                   Return = FALSE;
+            }
+        }
+
+        /* Check if we suceeded */
+        if (Return)
+        {
+            /* Finish setting up the structure */
+            DnsAddr->Ip6Address.sin6_family = AF_INET6;
+            DnsAddr->AddressLength = sizeof(SOCKADDR_IN6);
+        }
+    }
+    else if (AddressFamily != AF_INET)
+    {
+        /* You're like.. ATM or something? Get outta here! */
+        RtlZeroMemory(DnsAddr, sizeof(DNS_ADDRESS));
+        SetLastError(WSA_INVALID_PARAMETER);
+    }
+
+Quickie:
+    /* Return success or failure */
+    return (ErrorCode == ERROR_SUCCESS);
+}
+
+BOOLEAN
+WINAPI
+Dns_ReverseNameToDnsAddr_W(OUT PDNS_ADDRESS DnsAddr,
+                           IN LPWSTR Name)
+{
+    /* Call the common API */
+    return Dns_StringToDnsAddrEx(DnsAddr,
+                                 Name,
+                                 AF_UNSPEC,
+                                 TRUE,
+                                 TRUE);
+}
+
diff --git a/reactos/lib/dnslib/string.c b/reactos/lib/dnslib/string.c
new file mode 100644 (file)
index 0000000..e5ec0cf
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/string.c
+ * PURPOSE:     functions for string manipulation and conversion.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+ULONG
+WINAPI
+Dns_StringCopy(OUT PVOID Destination,
+               IN OUT PULONG DestinationSize,
+               IN PVOID String,
+               IN ULONG StringSize OPTIONAL,
+               IN DWORD InputType,
+               IN DWORD OutputType)
+{
+    ULONG DestSize;
+    ULONG OutputSize = 0;
+
+    /* Check if the caller already gave us the string size */
+    if (!StringSize)
+    {
+        /* He didn't, get the input type */
+        if (InputType == UnicodeString)
+        {
+            /* Unicode string, calculate the size */
+            StringSize = (ULONG)wcslen((LPWSTR)String);
+        }
+        else
+        {
+            /* ANSI or UTF-8 sting, get the size */
+            StringSize = (ULONG)strlen((LPSTR)String);
+        }
+    }
+
+    /* Check if we have a limit on the desination size */
+    if (DestinationSize)
+    {
+        /* Make sure that we can respect it */
+        DestSize = Dns_GetBufferLengthForStringCopy(String,
+                                                    StringSize,
+                                                    InputType,
+                                                    OutputType);
+        if (*DestinationSize < DestSize)
+        {
+            /* Fail due to missing buffer space */
+            SetLastError(ERROR_MORE_DATA);
+
+            /* Return how much data we actually need */
+            *DestinationSize = DestSize;
+            return 0;
+        }
+        else if (!DestSize)
+        {
+            /* Fail due to invalid data */
+            SetLastError(ERROR_INVALID_DATA);
+            return 0;
+        }
+
+        /* Return how much data we actually need */
+        *DestinationSize = DestSize;
+    }
+
+    /* Now check if this is a Unicode String as input */
+    if (InputType == UnicodeString)
+    {
+        /* Check if the output is ANSI */
+        if (OutputType == AnsiString)
+        {
+            /* Convert and return the final desination size */
+            OutputSize = WideCharToMultiByte(CP_ACP,
+                                             0,
+                                             String,
+                                             StringSize,
+                                             Destination,
+                                             -1,
+                                             NULL,
+                                             NULL) + 1;
+        }
+        else if (OutputType == UnicodeString)
+        {
+            /* Copy the string */
+            StringSize = StringSize * sizeof(WCHAR);
+            RtlMoveMemory(Destination, String, StringSize);
+
+            /* Return output length */
+            OutputSize = StringSize + 2;
+        }
+        else if (OutputType == Utf8String)
+        {
+            /* FIXME */
+            OutputSize = 0;
+        }
+    }
+    else if (InputType == AnsiString)
+    {
+        /* It's ANSI, is the output ansi too? */
+        if (OutputType == AnsiString)
+        {
+            /* Copy the string */
+            RtlMoveMemory(Destination, String, StringSize);
+
+            /* Return output length */
+            OutputSize = StringSize + 1;
+        }
+        else if (OutputType == UnicodeString)
+        {
+            /* Convert to Unicode and return size */
+            OutputSize = MultiByteToWideChar(CP_ACP,
+                                             0,
+                                             String,
+                                             StringSize,
+                                             Destination,
+                                             -1) * sizeof(WCHAR) + 2;
+        }
+        else if (OutputType == Utf8String)
+        {
+            /* FIXME */
+            OutputSize = 0;
+        }
+    }
+    else if (InputType == Utf8String)
+    {
+        /* FIXME */
+        OutputSize = 0;
+    }
+
+    /* Return the output size */
+    return OutputSize;
+}
+
+LPWSTR
+WINAPI
+Dns_CreateStringCopy_W(IN LPWSTR Name)
+{
+    SIZE_T StringLength;
+    LPWSTR NameCopy;
+
+    /* Make sure that we have a name */
+    if (!Name)
+    {
+        /* Fail */
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return NULL;
+    }
+
+    /* Find out the size of the string */
+    StringLength = (wcslen(Name) + 1) * sizeof(WCHAR);
+
+    /* Allocate space for the copy */
+    NameCopy = Dns_AllocZero(StringLength);
+    if (NameCopy)
+    {
+        /* Copy it */
+        RtlCopyMemory(NameCopy, Name, StringLength);
+    }
+    else
+    {
+        /* Fail */
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    }
+
+    /* Return the copy */
+    return NameCopy;
+}
+
+ULONG
+WINAPI
+Dns_GetBufferLengthForStringCopy(IN PVOID String,
+                                 IN ULONG Size OPTIONAL,
+                                 IN DWORD InputType,
+                                 IN DWORD OutputType)
+{
+    ULONG OutputSize = 0;
+
+    /* Check what kind of string this is */
+    if (InputType == UnicodeString)
+    {
+        /* Check if we have a size */
+        if (!Size)
+        {
+            /* Get it ourselves */
+            Size = (ULONG)wcslen(String);
+        }
+
+        /* Check the output type */
+        if (OutputType == UnicodeString)
+        {
+            /* Convert the size to bytes */
+            OutputSize = (Size + 1) * sizeof(WCHAR);
+        }
+        else if (OutputType == Utf8String)
+        {
+            /* FIXME */
+            OutputSize = 0;
+        }
+        else
+        {
+            /* Find out how much it will be in ANSI bytes */
+            OutputSize = WideCharToMultiByte(CP_ACP,
+                                             0,
+                                             String,
+                                             Size,
+                                             NULL,
+                                             0,
+                                             NULL,
+                                             NULL) + 1;
+        }
+    }
+    else if (InputType == AnsiString)
+    {
+        /* Check if we have a size */
+        if (!Size)
+        {
+            /* Get it ourselves */
+            Size = (ULONG)strlen(String);
+        }
+
+        /* Check the output type */
+        if (OutputType == AnsiString)
+        {
+            /* Just add a byte for the null char */
+            OutputSize = Size + 1;
+        }
+        else if (OutputType == UnicodeString)
+        {
+            /* Calculate the bytes for a Unicode string */
+            OutputSize = (MultiByteToWideChar(CP_ACP,
+                                              0,
+                                              String,
+                                              Size,
+                                              NULL,
+                                              0) + 1) * sizeof(WCHAR);
+        }
+        else if (OutputType == Utf8String)
+        {
+            /* FIXME */
+            OutputSize = 0;
+        }
+    }
+    else if (InputType == Utf8String)
+    {
+        /* FIXME */
+        OutputSize = 0;
+    }
+
+    /* Return the size required */
+    return OutputSize;
+}
+
diff --git a/reactos/lib/dnslib/table.c b/reactos/lib/dnslib/table.c
new file mode 100644 (file)
index 0000000..266c81b
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/table.c
+ * PURPOSE:     Functions for doing Table lookups, such as LUP Flags.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
diff --git a/reactos/lib/dnslib/utf8.c b/reactos/lib/dnslib/utf8.c
new file mode 100644 (file)
index 0000000..1cb6aa8
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS DNS Shared Library
+ * FILE:        lib/dnslib/utf8.c
+ * PURPOSE:     Functions for doing UTF8 string conversion and manipulation.
+ */
+
+/* INCLUDES ******************************************************************/
+#include "precomp.h"
+
+/* DATA **********************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
index 57c62f8..0b149cd 100644 (file)
@@ -13,6 +13,9 @@
        <directory name="debugsup">
                <xi:include href="debugsup/debugsup.rbuild" />
        </directory>
        <directory name="debugsup">
                <xi:include href="debugsup/debugsup.rbuild" />
        </directory>
+       <directory name="dnslib">
+               <xi:include href="dnslib/dnslib.rbuild" />
+       </directory>
        <directory name="drivers">
                <xi:include href="drivers/directory.rbuild" />
        </directory>
        <directory name="drivers">
                <xi:include href="drivers/directory.rbuild" />
        </directory>