/*
 * DNS support
 *
 * Copyright (C) 2006 Hans Leidekker
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"
#include "wine/debug.h"

#include <stdarg.h>
#include <string.h>
#include <sys/types.h>

#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_NAMESER_H
# include <arpa/nameser.h>
#endif
#ifdef HAVE_RESOLV_H
# include <resolv.h>
#endif
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winnls.h"
#include "windns.h"
#include "nb30.h"

#include "dnsapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);

#ifdef HAVE_RESOLV

/* call res_init() just once because of a bug in Mac OS X 10.4 */
/* call once per thread on systems that have per-thread _res */
static void initialise_resolver( void )
{
    if ((_res.options & RES_INIT) == 0)
        res_init();
}

static const char *dns_section_to_str( ns_sect section )
{
    switch (section)
    {
    case ns_s_qd:   return "Question";
    case ns_s_an:   return "Answer";
    case ns_s_ns:   return "Authority";
    case ns_s_ar:   return "Additional";
    default:
    {
        static char tmp[5];
        FIXME( "unknown section: 0x%02x\n", section );
        sprintf( tmp, "0x%02x", section );
        return tmp;
    }
    }
}

static unsigned long dns_map_options( DWORD options )
{
    unsigned long ret = 0;
            
    if (options == DNS_QUERY_STANDARD)
        return RES_DEFAULT;

    if (options & DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE)
        ret |= RES_IGNTC;
    if (options & DNS_QUERY_USE_TCP_ONLY)
        ret |= RES_USEVC;
    if (options & DNS_QUERY_NO_RECURSION)
        ret &= ~RES_RECURSE;
    if (options & DNS_QUERY_NO_LOCAL_NAME)
        ret &= ~RES_DNSRCH;
    if (options & DNS_QUERY_NO_HOSTS_FILE)
        ret |= RES_NOALIASES;
    if (options & DNS_QUERY_TREAT_AS_FQDN)
        ret &= ~RES_DEFNAMES;

    if (options & DNS_QUERY_DONT_RESET_TTL_VALUES)
        FIXME( "option DNS_QUERY_DONT_RESET_TTL_VALUES not implemented\n" );
    if (options & DNS_QUERY_RESERVED)
        FIXME( "option DNS_QUERY_RESERVED not implemented\n" );
    if (options & DNS_QUERY_WIRE_ONLY)
        FIXME( "option DNS_QUERY_WIRE_ONLY not implemented\n" );
    if (options & DNS_QUERY_NO_WIRE_QUERY)
        FIXME( "option DNS_QUERY_NO_WIRE_QUERY not implemented\n" );
    if (options & DNS_QUERY_BYPASS_CACHE)
        FIXME( "option DNS_QUERY_BYPASS_CACHE not implemented\n" );
    if (options & DNS_QUERY_RETURN_MESSAGE)
        FIXME( "option DNS_QUERY_RETURN_MESSAGE not implemented\n" );

    if (options & DNS_QUERY_NO_NETBT)
        TRACE( "netbios query disabled\n" );

    return ret;
}

static DNS_STATUS dns_map_error( int error )
{
    switch (error)
    {
    case ns_r_noerror:  return ERROR_SUCCESS;
    case ns_r_formerr:  return DNS_ERROR_RCODE_FORMAT_ERROR;
    case ns_r_servfail: return DNS_ERROR_RCODE_SERVER_FAILURE;
    case ns_r_nxdomain: return DNS_ERROR_RCODE_NAME_ERROR;
    case ns_r_notimpl:  return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
    case ns_r_refused:  return DNS_ERROR_RCODE_REFUSED;
    case ns_r_yxdomain: return DNS_ERROR_RCODE_YXDOMAIN;
    case ns_r_yxrrset:  return DNS_ERROR_RCODE_YXRRSET;
    case ns_r_nxrrset:  return DNS_ERROR_RCODE_NXRRSET;
    case ns_r_notauth:  return DNS_ERROR_RCODE_NOTAUTH;
    case ns_r_notzone:  return DNS_ERROR_RCODE_NOTZONE;
    default:
        FIXME( "unmapped error code: %d\n", error );
        return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
    }
}

static DNS_STATUS dns_map_h_errno( int error )
{
    switch (error)
    {
    case NO_DATA:
    case HOST_NOT_FOUND: return DNS_ERROR_RCODE_NAME_ERROR;
    case TRY_AGAIN:      return DNS_ERROR_RCODE_SERVER_FAILURE;
    case NO_RECOVERY:    return DNS_ERROR_RCODE_REFUSED;
    case NETDB_INTERNAL: return DNS_ERROR_RCODE;
    default:
        FIXME( "unmapped error code: %d\n", error );
        return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
    }
}

static char *dns_dname_from_msg( ns_msg msg, const unsigned char *pos )
{
    int len;
    char *str, dname[NS_MAXDNAME] = ".";

    /* returns *compressed* length, ignore it */
    len = dns_ns_name_uncompress( ns_msg_base( msg ), ns_msg_end( msg ),
                                  pos, dname, sizeof(dname) );

    len = strlen( dname );
    str = heap_alloc( len + 1 );
    if (str) strcpy( str, dname );
    return str;
}

static char *dns_str_from_rdata( const unsigned char *rdata )
{
    char *str;
    unsigned int len = rdata[0];

    str = heap_alloc( len + 1 );
    if (str)
    {
        memcpy( str, ++rdata, len );
        str[len] = '\0';
    }
    return str;
}

static unsigned int dns_get_record_size( const ns_rr *rr )
{
    const unsigned char *pos = rr->rdata;
    unsigned int num = 0, size = sizeof(DNS_RECORDA);

    switch (rr->type)
    {
    case ns_t_key:
    {
        pos += sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE);
        size += rr->rdata + rr->rdlength - pos - 1;
        break;
    }
    case ns_t_sig:
    {
        pos += sizeof(PCHAR) + sizeof(WORD) + 2 * sizeof(BYTE);
        pos += 3 * sizeof(DWORD) + 2 * sizeof(WORD);
        size += rr->rdata + rr->rdlength - pos - 1;
        break;
    }
    case ns_t_hinfo:
    case ns_t_isdn:
    case ns_t_txt:
    case ns_t_x25:
    {
        while (pos[0] && pos < rr->rdata + rr->rdlength)
        {
            num++;
            pos += pos[0] + 1;
        }
        size += (num - 1) * sizeof(PCHAR);
        break;
    }
    case ns_t_null:
    {
        size += rr->rdlength - 1;
        break;
    }
    case ns_t_nxt:
    case ns_t_wks:
    case 0xff01:  /* WINS */
    {
        FIXME( "unhandled type: %s\n", dns_type_to_str( rr->type ) );
        break;
    }
    default:
        break;
    }
    return size;
}

static DNS_STATUS dns_copy_rdata( ns_msg msg, const ns_rr *rr, DNS_RECORDA *r, WORD *dlen )
{
    DNS_STATUS ret = ERROR_SUCCESS;
    const unsigned char *pos = rr->rdata;
    unsigned int i, size;

    switch (rr->type)
    {
    case ns_t_a:
    {
        r->Data.A.IpAddress = *(const DWORD *)pos;
        *dlen = sizeof(DNS_A_DATA);
        break; 
    }
    case ns_t_aaaa:
    {
        for (i = 0; i < sizeof(IP6_ADDRESS)/sizeof(DWORD); i++)
        {
            r->Data.AAAA.Ip6Address.IP6Dword[i] = *(const DWORD *)pos;
            pos += sizeof(DWORD);
        }

        *dlen = sizeof(DNS_AAAA_DATA);
        break;
    }
    case ns_t_key:
    {
        /* FIXME: byte order? */
        r->Data.KEY.wFlags      = *(const WORD *)pos;   pos += sizeof(WORD);
        r->Data.KEY.chProtocol  = *pos++;
        r->Data.KEY.chAlgorithm = *pos++;

        size = rr->rdata + rr->rdlength - pos;

        for (i = 0; i < size; i++)
            r->Data.KEY.Key[i] = *pos++;

        *dlen = sizeof(DNS_KEY_DATA) + (size - 1) * sizeof(BYTE);
        break;
    }
    case ns_t_rp:
    case ns_t_minfo:
    {
        r->Data.MINFO.pNameMailbox = dns_dname_from_msg( msg, pos );
        if (!r->Data.MINFO.pNameMailbox) return ERROR_NOT_ENOUGH_MEMORY;

        if (dns_ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
            return DNS_ERROR_BAD_PACKET;

        r->Data.MINFO.pNameErrorsMailbox = dns_dname_from_msg( msg, pos );
        if (!r->Data.MINFO.pNameErrorsMailbox)
        {
            heap_free( r->Data.MINFO.pNameMailbox );
            return ERROR_NOT_ENOUGH_MEMORY;
        }

        *dlen = sizeof(DNS_MINFO_DATAA);
        break; 
    }
    case ns_t_afsdb:
    case ns_t_rt:
    case ns_t_mx:
    {
        r->Data.MX.wPreference = ntohs( *(const WORD *)pos );
        r->Data.MX.pNameExchange = dns_dname_from_msg( msg, pos + sizeof(WORD) );
        if (!r->Data.MX.pNameExchange) return ERROR_NOT_ENOUGH_MEMORY;

        *dlen = sizeof(DNS_MX_DATAA);
        break; 
    }
    case ns_t_null:
    {
        r->Data.Null.dwByteCount = rr->rdlength;
        memcpy( r->Data.Null.Data, rr->rdata, rr->rdlength );

        *dlen = sizeof(DNS_NULL_DATA) + rr->rdlength - 1;
        break;
    }
    case ns_t_cname:
    case ns_t_ns:
    case ns_t_mb:
    case ns_t_md:
    case ns_t_mf:
    case ns_t_mg:
    case ns_t_mr:
    case ns_t_ptr:
    {
        r->Data.PTR.pNameHost = dns_dname_from_msg( msg, pos );
        if (!r->Data.PTR.pNameHost) return ERROR_NOT_ENOUGH_MEMORY;

        *dlen = sizeof(DNS_PTR_DATAA);
        break;
    }
    case ns_t_sig:
    {
        r->Data.SIG.pNameSigner = dns_dname_from_msg( msg, pos );
        if (!r->Data.SIG.pNameSigner) return ERROR_NOT_ENOUGH_MEMORY;

        if (dns_ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
            return DNS_ERROR_BAD_PACKET;

        /* FIXME: byte order? */
        r->Data.SIG.wTypeCovered  = *(const WORD *)pos;   pos += sizeof(WORD);
        r->Data.SIG.chAlgorithm   = *pos++;
        r->Data.SIG.chLabelCount  = *pos++;
        r->Data.SIG.dwOriginalTtl = *(const DWORD *)pos;  pos += sizeof(DWORD);
        r->Data.SIG.dwExpiration  = *(const DWORD *)pos;  pos += sizeof(DWORD);
        r->Data.SIG.dwTimeSigned  = *(const DWORD *)pos;  pos += sizeof(DWORD);
        r->Data.SIG.wKeyTag       = *(const WORD *)pos;

        size = rr->rdata + rr->rdlength - pos;

        for (i = 0; i < size; i++)
            r->Data.SIG.Signature[i] = *pos++;

        *dlen = sizeof(DNS_SIG_DATAA) + (size - 1) * sizeof(BYTE);
        break; 
    }
    case ns_t_soa:
    {
        r->Data.SOA.pNamePrimaryServer = dns_dname_from_msg( msg, pos );
        if (!r->Data.SOA.pNamePrimaryServer) return ERROR_NOT_ENOUGH_MEMORY;

        if (dns_ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
            return DNS_ERROR_BAD_PACKET;

        r->Data.SOA.pNameAdministrator = dns_dname_from_msg( msg, pos );
        if (!r->Data.SOA.pNameAdministrator)
        {
            heap_free( r->Data.SOA.pNamePrimaryServer );
            return ERROR_NOT_ENOUGH_MEMORY;
        }

        if (dns_ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
            return DNS_ERROR_BAD_PACKET;

        r->Data.SOA.dwSerialNo   = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
        r->Data.SOA.dwRefresh    = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
        r->Data.SOA.dwRetry      = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
        r->Data.SOA.dwExpire     = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
        r->Data.SOA.dwDefaultTtl = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);

        *dlen = sizeof(DNS_SOA_DATAA);
        break; 
    }
    case ns_t_srv:
    {
        r->Data.SRV.wPriority = ntohs( *(const WORD *)pos ); pos += sizeof(WORD);
        r->Data.SRV.wWeight   = ntohs( *(const WORD *)pos ); pos += sizeof(WORD);
        r->Data.SRV.wPort     = ntohs( *(const WORD *)pos ); pos += sizeof(WORD);

        r->Data.SRV.pNameTarget = dns_dname_from_msg( msg, pos );
        if (!r->Data.SRV.pNameTarget) return ERROR_NOT_ENOUGH_MEMORY;

        *dlen = sizeof(DNS_SRV_DATAA);
        break; 
    }
    case ns_t_hinfo:
    case ns_t_isdn:
    case ns_t_x25:
    case ns_t_txt:
    {
        i = 0;
        while (pos[0] && pos < rr->rdata + rr->rdlength)
        {
            r->Data.TXT.pStringArray[i] = dns_str_from_rdata( pos );
            if (!r->Data.TXT.pStringArray[i])
            {
                while (i > 0) heap_free( r->Data.TXT.pStringArray[--i] );
                return ERROR_NOT_ENOUGH_MEMORY;
            }
            i++;
            pos += pos[0] + 1;
        }
        r->Data.TXT.dwStringCount = i;
        *dlen = sizeof(DNS_TXT_DATAA) + (i - 1) * sizeof(PCHAR);
        break;
    }
    case ns_t_atma:
    case ns_t_loc:
    case ns_t_nxt:
    case ns_t_tsig:
    case ns_t_wks:
    case 0x00f9:  /* TKEY */
    case 0xff01:  /* WINS */
    case 0xff02:  /* WINSR */
    default:
        FIXME( "unhandled type: %s\n", dns_type_to_str( rr->type ) );
        return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
    }

    return ret;
} 

static DNS_STATUS dns_copy_record( ns_msg msg, ns_sect section,
                                   unsigned short num, DNS_RECORDA **recp )
{
    DNS_STATUS ret;
    DNS_RECORDA *record;
    WORD dlen;
    ns_rr rr;

    if (dns_ns_parserr( &msg, section, num, &rr ) < 0)
        return DNS_ERROR_BAD_PACKET;

    if (!(record = heap_alloc_zero( dns_get_record_size( &rr ) )))
        return ERROR_NOT_ENOUGH_MEMORY;

    record->pName = dns_strdup_u( rr.name );
    if (!record->pName)
    {
        heap_free( record );
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    record->wType = rr.type;
    record->Flags.S.Section = section;
    record->Flags.S.CharSet = DnsCharSetUtf8;
    record->dwTtl = rr.ttl;

    if ((ret = dns_copy_rdata( msg, &rr, record, &dlen )))
    {
        heap_free( record->pName );
        heap_free( record );
        return ret;
    }
    record->wDataLength = dlen;
    *recp = record;

    TRACE( "found %s record in %s section\n",
           dns_type_to_str( rr.type ), dns_section_to_str( section ) );
    return ERROR_SUCCESS;
}

#define DEFAULT_TTL  1200

static DNS_STATUS dns_do_query_netbios( PCSTR name, DNS_RECORDA **recp )
{
    NCB ncb;
    UCHAR ret;
    DNS_RRSET rrset;
    FIND_NAME_BUFFER *buffer;
    FIND_NAME_HEADER *header;
    DNS_RECORDA *record = NULL;
    unsigned int i, len;
    DNS_STATUS status = ERROR_INVALID_NAME;

    len = strlen( name );
    if (len >= NCBNAMSZ) return DNS_ERROR_RCODE_NAME_ERROR;

    DNS_RRSET_INIT( rrset );

    memset( &ncb, 0, sizeof(ncb) );
    ncb.ncb_command = NCBFINDNAME;

    memset( ncb.ncb_callname, ' ', sizeof(ncb.ncb_callname) );
    memcpy( ncb.ncb_callname, name, len );
    ncb.ncb_callname[NCBNAMSZ - 1] = '\0';

    ret = Netbios( &ncb );
    if (ret != NRC_GOODRET) return ERROR_INVALID_NAME;

    header = (FIND_NAME_HEADER *)ncb.ncb_buffer;
    buffer = (FIND_NAME_BUFFER *)((char *)header + sizeof(FIND_NAME_HEADER));

    for (i = 0; i < header->node_count; i++) 
    {
        record = heap_alloc_zero( sizeof(DNS_RECORDA) );
        if (!record)
        {
            status = ERROR_NOT_ENOUGH_MEMORY;
            goto exit;
        }
        else
        {
            record->pName = dns_strdup_u( name );
            if (!record->pName)
            {
                status = ERROR_NOT_ENOUGH_MEMORY;
                goto exit;
            }

            record->wType = DNS_TYPE_A;
            record->Flags.S.Section = DnsSectionAnswer;
            record->Flags.S.CharSet = DnsCharSetUtf8;
            record->dwTtl = DEFAULT_TTL;

            /* FIXME: network byte order? */
            record->Data.A.IpAddress = *(DWORD *)((char *)buffer[i].destination_addr + 2);

            DNS_RRSET_ADD( rrset, (DNS_RECORD *)record );
        }
    }
    status = ERROR_SUCCESS;

exit:
    DNS_RRSET_TERMINATE( rrset );

    if (status != ERROR_SUCCESS)
        DnsRecordListFree( rrset.pFirstRR, DnsFreeRecordList );
    else
        *recp = (DNS_RECORDA *)rrset.pFirstRR;

    return status;
}

/* res_init() must have been called before calling these three functions.
 */
static DNS_STATUS dns_set_serverlist( const IP4_ARRAY *addrs )
{
    int i;

    if (addrs->AddrCount > MAXNS) 
    {
        WARN( "too many servers: %d only using the first: %d\n",
              addrs->AddrCount, MAXNS );
        _res.nscount = MAXNS;
    }
    else _res.nscount = addrs->AddrCount;

    for (i = 0; i < _res.nscount; i++)
        _res.nsaddr_list[i].sin_addr.s_addr = addrs->AddrArray[i];

    return ERROR_SUCCESS;
}

static DNS_STATUS dns_get_serverlist( PIP4_ARRAY addrs, PDWORD len )
{
    unsigned int size;
    int i;

    size = sizeof(IP4_ARRAY) + sizeof(IP4_ADDRESS) * (_res.nscount - 1);
    if (!addrs || *len < size)
    {
        *len = size;
        return ERROR_INSUFFICIENT_BUFFER;
    }

    addrs->AddrCount = _res.nscount;

    for (i = 0; i < _res.nscount; i++)
        addrs->AddrArray[i] = _res.nsaddr_list[i].sin_addr.s_addr;

    return ERROR_SUCCESS;
}

static DNS_STATUS dns_do_query( PCSTR name, WORD type, DWORD options,
                                PDNS_RECORDA *result )
{
    DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;

    unsigned int i, num;
    unsigned char answer[NS_PACKETSZ];
    ns_sect sections[] = { ns_s_an, ns_s_ar };
    ns_msg msg;

    DNS_RECORDA *record = NULL;
    DNS_RRSET rrset;
    int len;

    DNS_RRSET_INIT( rrset );

    len = res_query( name, ns_c_in, type, answer, sizeof(answer) );
    if (len < 0)
    {
        ret = dns_map_h_errno( h_errno );
        goto exit;
    }

    if (dns_ns_initparse( answer, len, &msg ) < 0)
    {
        ret = DNS_ERROR_BAD_PACKET;
        goto exit;
    }

#define RCODE_MASK 0x0f
    if ((msg._flags & RCODE_MASK) != ns_r_noerror)
    {
        ret = dns_map_error( msg._flags & RCODE_MASK );
        goto exit;
    }

    for (i = 0; i < sizeof(sections)/sizeof(sections[0]); i++)
    {
        for (num = 0; num < ns_msg_count( msg, sections[i] ); num++)
        {
            ret = dns_copy_record( msg, sections[i], num, &record );
            if (ret != ERROR_SUCCESS) goto exit;

            DNS_RRSET_ADD( rrset, (DNS_RECORD *)record );
        }
    }

exit:
    DNS_RRSET_TERMINATE( rrset );

    if (ret != ERROR_SUCCESS)
        DnsRecordListFree( rrset.pFirstRR, DnsFreeRecordList );
    else
        *result = (DNS_RECORDA *)rrset.pFirstRR;

    return ret;
}

#endif /* HAVE_RESOLV */

/******************************************************************************
 * DnsQuery_A           [DNSAPI.@]
 *
 */
DNS_STATUS WINAPI DnsQuery_A( PCSTR name, WORD type, DWORD options, PVOID servers,
                              PDNS_RECORDA *result, PVOID *reserved )
{
    WCHAR *nameW;
    DNS_RECORDW *resultW;
    DNS_STATUS status;

    TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_a(name), dns_type_to_str( type ),
           options, servers, result, reserved );

    if (!name || !result)
        return ERROR_INVALID_PARAMETER;

    nameW = dns_strdup_aw( name );
    if (!nameW) return ERROR_NOT_ENOUGH_MEMORY;

    status = DnsQuery_W( nameW, type, options, servers, &resultW, reserved ); 

    if (status == ERROR_SUCCESS)
    {
        *result = (DNS_RECORDA *)DnsRecordSetCopyEx(
             (DNS_RECORD *)resultW, DnsCharSetUnicode, DnsCharSetAnsi );

        if (!*result) status = ERROR_NOT_ENOUGH_MEMORY;
        DnsRecordListFree( (DNS_RECORD *)resultW, DnsFreeRecordList );
    }

    heap_free( nameW );
    return status;
}

/******************************************************************************
 * DnsQuery_UTF8              [DNSAPI.@]
 *
 */
DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID servers,
                                 PDNS_RECORDA *result, PVOID *reserved )
{
    DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;
#ifdef HAVE_RESOLV

    TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_a(name), dns_type_to_str( type ),
           options, servers, result, reserved );

    if (!name || !result)
        return ERROR_INVALID_PARAMETER;

    initialise_resolver();
    _res.options |= dns_map_options( options );

    if (servers && (ret = dns_set_serverlist( servers )))
        return ret;

    ret = dns_do_query( name, type, options, result );

    if (ret == DNS_ERROR_RCODE_NAME_ERROR && type == DNS_TYPE_A &&
        !(options & DNS_QUERY_NO_NETBT))
    {
        TRACE( "dns lookup failed, trying netbios query\n" );
        ret = dns_do_query_netbios( name, result );
    }

#endif
    return ret;
}

/******************************************************************************
 * DnsQuery_W              [DNSAPI.@]
 *
 */
DNS_STATUS WINAPI DnsQuery_W( PCWSTR name, WORD type, DWORD options, PVOID servers,
                              PDNS_RECORDW *result, PVOID *reserved )
{
    char *nameU;
    DNS_RECORDA *resultA;
    DNS_STATUS status;

    TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_w(name), dns_type_to_str( type ),
           options, servers, result, reserved );

    if (!name || !result)
        return ERROR_INVALID_PARAMETER;

    nameU = dns_strdup_wu( name );
    if (!nameU) return ERROR_NOT_ENOUGH_MEMORY;

    status = DnsQuery_UTF8( nameU, type, options, servers, &resultA, reserved ); 

    if (status == ERROR_SUCCESS)
    {
        *result = (DNS_RECORDW *)DnsRecordSetCopyEx(
            (DNS_RECORD *)resultA, DnsCharSetUtf8, DnsCharSetUnicode );

        if (!*result) status = ERROR_NOT_ENOUGH_MEMORY;
        DnsRecordListFree( (DNS_RECORD *)resultA, DnsFreeRecordList );
    }

    heap_free( nameU );
    return status;
}

static DNS_STATUS dns_get_hostname_a( COMPUTER_NAME_FORMAT format,
                                      PSTR buffer, PDWORD len )
{
    char name[256];
    DWORD size = sizeof(name)/sizeof(name[0]);

    if (!GetComputerNameExA( format, name, &size ))
        return DNS_ERROR_NAME_DOES_NOT_EXIST;

    if (!buffer || (size = lstrlenA( name ) + 1) > *len)
    {
        *len = size;
        return ERROR_INSUFFICIENT_BUFFER;
    }

    lstrcpyA( buffer, name );
    return ERROR_SUCCESS;
}

static DNS_STATUS dns_get_hostname_w( COMPUTER_NAME_FORMAT format,
                                      PWSTR buffer, PDWORD len )
{
    WCHAR name[256];
    DWORD size = sizeof(name)/sizeof(name[0]);

    if (!GetComputerNameExW( format, name, &size ))
        return DNS_ERROR_NAME_DOES_NOT_EXIST;

    if (!buffer || (size = lstrlenW( name ) + 1) > *len)
    {
        *len = size;
        return ERROR_INSUFFICIENT_BUFFER;
    }

    lstrcpyW( buffer, name );
    return ERROR_SUCCESS;
}

/******************************************************************************
 * DnsQueryConfig          [DNSAPI.@]
 *
 */
DNS_STATUS WINAPI DnsQueryConfig( DNS_CONFIG_TYPE config, DWORD flag, PCWSTR adapter,
                                  PVOID reserved, PVOID buffer, PDWORD len )
{
    DNS_STATUS ret = ERROR_INVALID_PARAMETER;

    TRACE( "(%d,0x%08x,%s,%p,%p,%p)\n", config, flag, debugstr_w(adapter),
           reserved, buffer, len );

    if (!len) return ERROR_INVALID_PARAMETER;

    switch (config)
    {
    case DnsConfigDnsServerList:
    {
#ifdef HAVE_RESOLV
        initialise_resolver();
        ret = dns_get_serverlist( buffer, len );
        break;
#else
        WARN( "compiled without resolver support\n" );
        break;
#endif
    }
    case DnsConfigHostName_A:
    case DnsConfigHostName_UTF8:
        return dns_get_hostname_a( ComputerNameDnsHostname, buffer, len );

    case DnsConfigFullHostName_A:
    case DnsConfigFullHostName_UTF8:
        return dns_get_hostname_a( ComputerNameDnsFullyQualified, buffer, len );

    case DnsConfigPrimaryDomainName_A:
    case DnsConfigPrimaryDomainName_UTF8:
        return dns_get_hostname_a( ComputerNameDnsDomain, buffer, len );

    case DnsConfigHostName_W:
        return dns_get_hostname_w( ComputerNameDnsHostname, buffer, len );

    case DnsConfigFullHostName_W:
        return dns_get_hostname_w( ComputerNameDnsFullyQualified, buffer, len );

    case DnsConfigPrimaryDomainName_W:
        return dns_get_hostname_w( ComputerNameDnsDomain, buffer, len );

    case DnsConfigAdapterDomainName_A:
    case DnsConfigAdapterDomainName_W:
    case DnsConfigAdapterDomainName_UTF8:
    case DnsConfigSearchList:
    case DnsConfigAdapterInfo:
    case DnsConfigPrimaryHostNameRegistrationEnabled:
    case DnsConfigAdapterHostNameRegistrationEnabled:
    case DnsConfigAddressRegistrationMaxCount:
        FIXME( "unimplemented config type %d\n", config );
        break;

    default:
        WARN( "unknown config type: %d\n", config );
        break;
    }
    return ret;
}
