From 45c5b396f7a939611f2641e2af4b52f0ac507c36 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 15 Oct 2009 01:23:39 +0000 Subject: [PATCH] - Import Alex's dnslib - Add headers and definitions needed for dnslib to build - Part 2 of 2 svn path=/trunk/; revision=43469 --- reactos/include/psdk/windns.h | 4 + reactos/include/psdk/ws2atm.h | 333 ++++++++++++++++ reactos/lib/dnslib/addr.c | 65 ++++ reactos/lib/dnslib/debug.c | 14 + reactos/lib/dnslib/dnsaddr.c | 200 ++++++++++ reactos/lib/dnslib/dnslib.rbuild | 22 ++ reactos/lib/dnslib/dnsutil.c | 14 + reactos/lib/dnslib/flatbuf.c | 116 ++++++ reactos/lib/dnslib/hostent.c | 97 +++++ reactos/lib/dnslib/inc/dnslib.h | 343 +++++++++++++++++ reactos/lib/dnslib/inc/precomp.h | 24 ++ reactos/lib/dnslib/inc/windnsp.h | 28 ++ reactos/lib/dnslib/ip6.c | 14 + reactos/lib/dnslib/memory.c | 66 ++++ reactos/lib/dnslib/name.c | 14 + reactos/lib/dnslib/print.c | 14 + reactos/lib/dnslib/record.c | 14 + reactos/lib/dnslib/rrprint.c | 14 + reactos/lib/dnslib/sablob.c | 640 +++++++++++++++++++++++++++++++ reactos/lib/dnslib/straddr.c | 462 ++++++++++++++++++++++ reactos/lib/dnslib/string.c | 257 +++++++++++++ reactos/lib/dnslib/table.c | 14 + reactos/lib/dnslib/utf8.c | 14 + reactos/lib/lib.rbuild | 3 + 24 files changed, 2786 insertions(+) create mode 100644 reactos/include/psdk/ws2atm.h create mode 100644 reactos/lib/dnslib/addr.c create mode 100644 reactos/lib/dnslib/debug.c create mode 100644 reactos/lib/dnslib/dnsaddr.c create mode 100644 reactos/lib/dnslib/dnslib.rbuild create mode 100644 reactos/lib/dnslib/dnsutil.c create mode 100644 reactos/lib/dnslib/flatbuf.c create mode 100644 reactos/lib/dnslib/hostent.c create mode 100644 reactos/lib/dnslib/inc/dnslib.h create mode 100644 reactos/lib/dnslib/inc/precomp.h create mode 100644 reactos/lib/dnslib/inc/windnsp.h create mode 100644 reactos/lib/dnslib/ip6.c create mode 100644 reactos/lib/dnslib/memory.c create mode 100644 reactos/lib/dnslib/name.c create mode 100644 reactos/lib/dnslib/print.c create mode 100644 reactos/lib/dnslib/record.c create mode 100644 reactos/lib/dnslib/rrprint.c create mode 100644 reactos/lib/dnslib/sablob.c create mode 100644 reactos/lib/dnslib/straddr.c create mode 100644 reactos/lib/dnslib/string.c create mode 100644 reactos/lib/dnslib/table.c create mode 100644 reactos/lib/dnslib/utf8.c diff --git a/reactos/include/psdk/windns.h b/reactos/include/psdk/windns.h index c037b679f6a..3e3714f1bd3 100644 --- a/reactos/include/psdk/windns.h +++ b/reactos/include/psdk/windns.h @@ -171,6 +171,10 @@ typedef struct _DnsRecordFlags { 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; diff --git a/reactos/include/psdk/ws2atm.h b/reactos/include/psdk/ws2atm.h new file mode 100644 index 00000000000..1049683ba9d --- /dev/null +++ b/reactos/include/psdk/ws2atm.h @@ -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 + +#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 +#endif diff --git a/reactos/lib/dnslib/addr.c b/reactos/lib/dnslib/addr.c new file mode 100644 index 00000000000..b91c532e49a --- /dev/null +++ b/reactos/lib/dnslib/addr.c @@ -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 index 00000000000..7ec359759b5 --- /dev/null +++ b/reactos/lib/dnslib/debug.c @@ -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 index 00000000000..310a0966f8b --- /dev/null +++ b/reactos/lib/dnslib/dnsaddr.c @@ -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 index 00000000000..77806231ca6 --- /dev/null +++ b/reactos/lib/dnslib/dnslib.rbuild @@ -0,0 +1,22 @@ + + + + inc + addr.c + debug.c + dnsaddr.c + dnsutil.c + flatbuf.c + hostent.c + ip6.c + memory.c + name.c + print.c + record.c + rrprint.c + sablob.c + straddr.c + string.c + table.c + utf8.c + diff --git a/reactos/lib/dnslib/dnsutil.c b/reactos/lib/dnslib/dnsutil.c new file mode 100644 index 00000000000..1d0e814d911 --- /dev/null +++ b/reactos/lib/dnslib/dnsutil.c @@ -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 index 00000000000..dfceb3e82a3 --- /dev/null +++ b/reactos/lib/dnslib/flatbuf.c @@ -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 index 00000000000..f7c9e64bb39 --- /dev/null +++ b/reactos/lib/dnslib/hostent.c @@ -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 index 00000000000..4c187f15b37 --- /dev/null +++ b/reactos/lib/dnslib/inc/dnslib.h @@ -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 + +/* 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 index 00000000000..b30cb072d00 --- /dev/null +++ b/reactos/lib/dnslib/inc/precomp.h @@ -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 +#include +#include + +/* DNSLIB and DNSAPI Headers */ +#include +#include + +/* NDK */ +#include + +/* EOF */ diff --git a/reactos/lib/dnslib/inc/windnsp.h b/reactos/lib/dnslib/inc/windnsp.h new file mode 100644 index 00000000000..48087eb134b --- /dev/null +++ b/reactos/lib/dnslib/inc/windnsp.h @@ -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 index 00000000000..921fef41175 --- /dev/null +++ b/reactos/lib/dnslib/ip6.c @@ -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 index 00000000000..183088c86b7 --- /dev/null +++ b/reactos/lib/dnslib/memory.c @@ -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 index 00000000000..4004912315e --- /dev/null +++ b/reactos/lib/dnslib/name.c @@ -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 index 00000000000..bead765eb3c --- /dev/null +++ b/reactos/lib/dnslib/print.c @@ -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 index 00000000000..c0325a9b850 --- /dev/null +++ b/reactos/lib/dnslib/record.c @@ -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 index 00000000000..29a58ff86ed --- /dev/null +++ b/reactos/lib/dnslib/rrprint.c @@ -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 index 00000000000..1d720d2bb16 --- /dev/null +++ b/reactos/lib/dnslib/sablob.c @@ -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 index 00000000000..4215a80dbf0 --- /dev/null +++ b/reactos/lib/dnslib/straddr.c @@ -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 index 00000000000..e5ec0cfa935 --- /dev/null +++ b/reactos/lib/dnslib/string.c @@ -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 index 00000000000..266c81b7296 --- /dev/null +++ b/reactos/lib/dnslib/table.c @@ -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 index 00000000000..1cb6aa8bd59 --- /dev/null +++ b/reactos/lib/dnslib/utf8.c @@ -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 *****************************************************************/ + diff --git a/reactos/lib/lib.rbuild b/reactos/lib/lib.rbuild index 57c62f8c288..0b149cd1f84 100644 --- a/reactos/lib/lib.rbuild +++ b/reactos/lib/lib.rbuild @@ -13,6 +13,9 @@ + + +