/* Copyright (c) 2003 Juan Lang
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * I am heavily indebted to Chris Hertel's excellent Implementing CIFS,
 * http://ubiqx.org/cifs/ , for whatever understanding I have of NBT.
 * I also stole from Mike McCormack's smb.c and netapi32.c, although little of
 * that code remains.
 * Lack of understanding and bugs are my fault.
 *
 * FIXME:
 * - Of the NetBIOS session functions, only client functions are supported, and
 *   it's likely they'll be the only functions supported.  NBT requires session
 *   servers to listen on TCP/139.  This requires root privilege, and Samba is
 *   likely to be listening here already.  This further restricts NetBIOS
 *   applications, both explicit users and implicit ones:  CreateNamedPipe
 *   won't actually create a listening pipe, for example, so applications can't
 *   act as RPC servers using a named pipe protocol binding, DCOM won't be able
 *   to support callbacks or servers over the named pipe protocol, etc.
 *
 * - Datagram support is omitted for the same reason.  To send a NetBIOS
 *   datagram, you must include the NetBIOS name by which your application is
 *   known.  This requires you to have registered the name previously, and be
 *   able to act as a NetBIOS datagram server (listening on UDP/138).
 *
 * - Name registration functions are omitted for the same reason--registering a
 *   name requires you to be able to defend it, and this means listening on
 *   UDP/137.
 *   Win98 requires you either use your computer's NetBIOS name (with the NULL
 *   suffix byte) as the calling name when creating a session, or to register
 *   a new name before creating one:  it disallows '*' as the calling name.
 *   Win2K initially starts with an empty name table, and doesn't allow you to
 *   use the machine's NetBIOS name (with the NULL suffix byte) as the calling
 *   name.  Although it allows sessions to be created with '*' as the calling
 *   name, doing so results in timeouts for all receives, because the
 *   application never gets them.
 *   So, a well-behaved Netbios application will typically want to register a
 *   name.  I should probably support a do-nothing name list that allows
 *   NCBADDNAME to add to it, but doesn't actually register the name, or does
 *   attempt to register it without being able to defend it.
 *
 * - Name lookups may not behave quite as you'd expect/like if you have
 *   multiple LANAs.  If a name is resolvable through DNS, or if you're using
 *   WINS, it'll resolve on _any_ LANA.  So, a Call will succeed on any LANA as
 *   well.
 *   I'm not sure how Windows behaves in this case.  I could try to force
 *   lookups to the correct adapter by using one of the GetPreferred*
 *   functions, but with the possibility of multiple adapters in the same
 *   same subnet, there's no guarantee that what IpHlpApi thinks is the
 *   preferred adapter will actually be a LANA.  (It's highly probable because
 *   this is an unusual configuration, but not guaranteed.)
 *
 * See also other FIXMEs in the code.
 */

#include "config.h"
#include <stdarg.h>

#include "winsock2.h"
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include "winreg.h"
#include "iphlpapi.h"

#include "netbios.h"
#include "nbnamecache.h"

WINE_DEFAULT_DEBUG_CHANNEL(netbios);

#define PORT_NBNS 137
#define PORT_NBDG 138
#define PORT_NBSS 139

#ifndef INADDR_NONE
#define INADDR_NONE ~0UL
#endif

#define NBR_ADDWORD(p,word) (*(WORD *)(p)) = htons(word)
#define NBR_GETWORD(p) ntohs(*(WORD *)(p))

#define MIN_QUERIES         1
#define MAX_QUERIES         0xffff
#define MIN_QUERY_TIMEOUT   100
#define MAX_QUERY_TIMEOUT   0xffffffff
#define BCAST_QUERIES       3
#define BCAST_QUERY_TIMEOUT 750
#define WINS_QUERIES        3
#define WINS_QUERY_TIMEOUT  750
#define MAX_WINS_SERVERS    2
#define MIN_CACHE_TIMEOUT   60000
#define CACHE_TIMEOUT       360000

#define MAX_NBT_NAME_SZ (NCBNAMSZ * 2 + MAX_DOMAIN_NAME_LEN + 2)
#define SIMPLE_NAME_QUERY_PKT_SIZE 26 + MAX_NBT_NAME_SZ

#define DEFAULT_NBT_SESSIONS 16

#define NBNS_TYPE_NB             0x0020
#define NBNS_TYPE_NBSTAT         0x0021
#define NBNS_CLASS_INTERNET      0x00001
#define NBNS_HEADER_SIZE         (sizeof(WORD) * 6)
#define NBNS_RESPONSE_AND_OPCODE 0xf800
#define NBNS_RESPONSE_AND_QUERY  0x8000
#define NBNS_REPLYCODE           0x0f

#define NBSS_HDRSIZE 4

#define NBSS_MSG       0x00
#define NBSS_REQ       0x81
#define NBSS_ACK       0x82
#define NBSS_NACK      0x83
#define NBSS_RETARGET  0x84
#define NBSS_KEEPALIVE 0x85

#define NBSS_ERR_NOT_LISTENING_ON_NAME    0x80
#define NBSS_ERR_NOT_LISTENING_FOR_CALLER 0x81
#define NBSS_ERR_BAD_NAME                 0x82
#define NBSS_ERR_INSUFFICIENT_RESOURCES   0x83

#define NBSS_EXTENSION 0x01

typedef struct _NetBTSession
{
    CRITICAL_SECTION cs;
    SOCKET           fd;
    DWORD            bytesPending;
} NetBTSession;

typedef struct _NetBTAdapter
{
    MIB_IPADDRROW       ipr;
    WORD                nameQueryXID;
    struct NBNameCache *nameCache;
    DWORD               xmit_success;
    DWORD               recv_success;
} NetBTAdapter;

static ULONG gTransportID;
static BOOL  gEnableDNS;
static DWORD gBCastQueries;
static DWORD gBCastQueryTimeout;
static DWORD gWINSQueries;
static DWORD gWINSQueryTimeout;
static DWORD gWINSServers[MAX_WINS_SERVERS];
static int   gNumWINSServers;
static char  gScopeID[MAX_DOMAIN_NAME_LEN];
static DWORD gCacheTimeout;
static struct NBNameCache *gNameCache;

/* Converts from a NetBIOS name into a Second Level Encoding-formatted name.
 * Assumes p is not NULL and is either NULL terminated or has at most NCBNAMSZ
 * bytes, and buffer has at least MAX_NBT_NAME_SZ bytes.  Pads with space bytes
 * if p is NULL-terminated.  Returns the number of bytes stored in buffer.
 */
static int NetBTNameEncode(const UCHAR *p, UCHAR *buffer)
{
    int i,len=0;

    if (!p) return 0;
    if (!buffer) return 0;

    buffer[len++] = NCBNAMSZ * 2;
    for (i = 0; p[i] && i < NCBNAMSZ; i++)
    {
        buffer[len++] = ((p[i] & 0xf0) >> 4) + 'A';
        buffer[len++] =  (p[i] & 0x0f) + 'A';
    }
    while (len < NCBNAMSZ * 2)
    {
        buffer[len++] = 'C';
        buffer[len++] = 'A';
    }
    if (*gScopeID)
    {
        int scopeIDLen = strlen(gScopeID);

        memcpy(buffer + len, gScopeID, scopeIDLen);
        len += scopeIDLen;
    }
    buffer[len++] = 0;     /* add second terminator */
    return len;
}

/* Creates a NBT name request packet for name in buffer.  If broadcast is true,
 * creates a broadcast request, otherwise creates a unicast request.
 * Returns the number of bytes stored in buffer.
 */
static DWORD NetBTNameReq(const UCHAR name[NCBNAMSZ], WORD xid, WORD qtype,
 BOOL broadcast, UCHAR *buffer, int len)
{
    int i = 0;

    if (len < SIMPLE_NAME_QUERY_PKT_SIZE) return 0;

    NBR_ADDWORD(&buffer[i],xid);    i+=2; /* transaction */
    if (broadcast)
    {
        NBR_ADDWORD(&buffer[i],0x0110); /* flags: r=req,op=query,rd=1,b=1 */
        i+=2;
    }
    else
    {
        NBR_ADDWORD(&buffer[i],0x0100); /* flags: r=req,op=query,rd=1,b=0 */
        i+=2;
    }
    NBR_ADDWORD(&buffer[i],0x0001); i+=2; /* one name query */
    NBR_ADDWORD(&buffer[i],0x0000); i+=2; /* zero answers */
    NBR_ADDWORD(&buffer[i],0x0000); i+=2; /* zero authorities */
    NBR_ADDWORD(&buffer[i],0x0000); i+=2; /* zero additional */

    i += NetBTNameEncode(name, &buffer[i]);

    NBR_ADDWORD(&buffer[i],qtype); i+=2;
    NBR_ADDWORD(&buffer[i],NBNS_CLASS_INTERNET); i+=2;

    return i;
}

/* Sends a name query request for name on fd to destAddr.  Sets SO_BROADCAST on
 * fd if broadcast is TRUE.  Assumes fd is not INVALID_SOCKET, and name is not
 * NULL.
 * Returns 0 on success, -1 on failure.
 */
static int NetBTSendNameQuery(SOCKET fd, const UCHAR name[NCBNAMSZ], WORD xid,
 WORD qtype, DWORD destAddr, BOOL broadcast)
{
    int ret = 0, on = 1;
    struct in_addr addr;

    addr.s_addr = destAddr;
    TRACE("name %s, dest addr %s\n", name, inet_ntoa(addr));

    if (broadcast)
        ret = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (PUCHAR)&on, sizeof(on));
    if(ret == 0)
    {
        WSABUF wsaBuf;
        UCHAR buf[SIMPLE_NAME_QUERY_PKT_SIZE];
        struct sockaddr_in sin;

        memset(&sin, 0, sizeof(sin));
        sin.sin_addr.s_addr = destAddr;
        sin.sin_family      = AF_INET;
        sin.sin_port        = htons(PORT_NBNS);

        wsaBuf.buf = buf;
        wsaBuf.len = NetBTNameReq(name, xid, qtype, broadcast, buf,
         sizeof(buf));
        if (wsaBuf.len > 0)
        {
            DWORD bytesSent;

            ret = WSASendTo(fd, &wsaBuf, 1, &bytesSent, 0,
             (struct sockaddr*)&sin, sizeof(sin), NULL, NULL);
            if (ret < 0 || bytesSent < wsaBuf.len)
                ret = -1;
            else
                ret = 0;
        }
        else
            ret = -1;
    }
    return ret;
}

typedef BOOL (*NetBTAnswerCallback)(void *data, WORD answerCount,
 WORD answerIndex, PUCHAR rData, WORD rdLength);

/* Waits on fd until GetTickCount() returns a value greater than or equal to
 * waitUntil for a name service response.  If a name response matching xid
 * is received, calls answerCallback once for each answer resource record in
 * the response.  (The callback's answerCount will be the total number of
 * answers to expect, and answerIndex will be the 0-based index that's being
 * sent this time.)  Quits parsing if answerCallback returns FALSE.
 * Returns NRC_GOODRET on timeout or a valid response received, something else
 * on error.
 */
static UCHAR NetBTWaitForNameResponse(NetBTAdapter *adapter, SOCKET fd,
 DWORD waitUntil, NetBTAnswerCallback answerCallback, void *data)
{
    BOOL found = FALSE;
    DWORD now;
    UCHAR ret = NRC_GOODRET;

    if (!adapter) return NRC_BADDR;
    if (fd == INVALID_SOCKET) return NRC_BADDR;
    if (!answerCallback) return NRC_BADDR;

    while (!found && ret == NRC_GOODRET && (now = GetTickCount()) < waitUntil)
    {
        DWORD msToWait = waitUntil - now;
        struct fd_set fds;
        struct timeval timeout = { msToWait / 1000, msToWait % 1000 };
        int r;

        FD_ZERO(&fds);
        FD_SET(fd, &fds);
        r = select(fd + 1, &fds, NULL, NULL, &timeout);
        if (r < 0)
            ret = NRC_SYSTEM;
        else if (r == 1)
        {
            /* FIXME: magic #, is this always enough? */
            UCHAR buffer[256];
            int fromsize;
            struct sockaddr_in fromaddr;
            WORD respXID, flags, queryCount, answerCount;
            WSABUF wsaBuf = { sizeof(buffer), buffer };
            DWORD bytesReceived, recvFlags = 0;

            fromsize = sizeof(fromaddr);
            r = WSARecvFrom(fd, &wsaBuf, 1, &bytesReceived, &recvFlags,
             (struct sockaddr*)&fromaddr, &fromsize, NULL, NULL);
            if(r < 0)
            {
                ret = NRC_SYSTEM;
                break;
            }

            if (bytesReceived < NBNS_HEADER_SIZE)
                continue;

            respXID = NBR_GETWORD(buffer);
            if (adapter->nameQueryXID != respXID)
                continue;

            flags = NBR_GETWORD(buffer + 2);
            queryCount = NBR_GETWORD(buffer + 4);
            answerCount = NBR_GETWORD(buffer + 6);

            /* a reply shouldn't contain a query, ignore bad packet */
            if (queryCount > 0)
                continue;

            if ((flags & NBNS_RESPONSE_AND_OPCODE) == NBNS_RESPONSE_AND_QUERY)
            {
                if ((flags & NBNS_REPLYCODE) != 0)
                    ret = NRC_NAMERR;
                else if ((flags & NBNS_REPLYCODE) == 0 && answerCount > 0)
                {
                    PUCHAR ptr = buffer + NBNS_HEADER_SIZE;
                    BOOL shouldContinue = TRUE;
                    WORD answerIndex = 0;

                    found = TRUE;
                    /* decode one answer at a time */
                    while (ret == NRC_GOODRET && answerIndex < answerCount &&
                     ptr - buffer < bytesReceived && shouldContinue)
                    {
                        WORD rLen;

                        /* scan past name */
                        for (; ptr[0] && ptr - buffer < bytesReceived; )
                            ptr += ptr[0] + 1;
                        ptr++;
                        ptr += 2; /* scan past type */
                        if (ptr - buffer < bytesReceived && ret == NRC_GOODRET
                         && NBR_GETWORD(ptr) == NBNS_CLASS_INTERNET)
                            ptr += sizeof(WORD);
                        else
                            ret = NRC_SYSTEM; /* parse error */
                        ptr += sizeof(DWORD); /* TTL */
                        rLen = NBR_GETWORD(ptr);
                        rLen = min(rLen, bytesReceived - (ptr - buffer));
                        ptr += sizeof(WORD);
                        shouldContinue = answerCallback(data, answerCount,
                         answerIndex, ptr, rLen);
                        ptr += rLen;
                        answerIndex++;
                    }
                }
            }
        }
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

typedef struct _NetBTNameQueryData {
    NBNameCacheEntry *cacheEntry;
    UCHAR ret;
} NetBTNameQueryData;

/* Name query callback function for NetBTWaitForNameResponse, creates a cache
 * entry on the first answer, adds each address as it's called again (as long
 * as there's space).  If there's an error that should be propagated as the
 * NetBIOS error, modifies queryData's ret member to the proper return code.
 */
static BOOL NetBTFindNameAnswerCallback(void *pVoid, WORD answerCount,
 WORD answerIndex, PUCHAR rData, WORD rLen)
{
    NetBTNameQueryData *queryData = (NetBTNameQueryData *)pVoid;
    BOOL ret;

    if (queryData)
    {
        if (queryData->cacheEntry == NULL)
        {
            queryData->cacheEntry = HeapAlloc(
             GetProcessHeap(), 0, sizeof(NBNameCacheEntry) +
             (answerCount - 1) * sizeof(DWORD));
            if (queryData->cacheEntry)
                queryData->cacheEntry->numAddresses = 0;
            else
            {
                ret = FALSE;
                queryData->ret = NRC_OSRESNOTAV;
            }
        }
        if (rLen == 6 && queryData->cacheEntry &&
         queryData->cacheEntry->numAddresses < answerCount)
        {
            queryData->cacheEntry->addresses[queryData->cacheEntry->
             numAddresses++] = *(PDWORD)(rData + 2);
            ret = queryData->cacheEntry->numAddresses < answerCount;
        }
        else
            ret = FALSE;
    }
    else
        ret = FALSE;
    return ret;
}

/* Workhorse NetBT name lookup function.  Sends a name lookup query for
 * ncb->ncb_callname to sendTo, as a broadcast if broadcast is TRUE, using
 * adapter->nameQueryXID as the transaction ID.  Waits up to timeout
 * milliseconds, and retries up to maxQueries times, waiting for a reply.
 * If a valid response is received, stores the looked up addresses as a
 * NBNameCacheEntry in *cacheEntry.
 * Returns NRC_GOODRET on success, though this may not mean the name was
 * resolved--check whether *cacheEntry is NULL.
 */
static UCHAR NetBTNameWaitLoop(NetBTAdapter *adapter, SOCKET fd, PNCB ncb,
 DWORD sendTo, BOOL broadcast, DWORD timeout, DWORD maxQueries,
 NBNameCacheEntry **cacheEntry)
{
    unsigned int queries;
    NetBTNameQueryData queryData;

    if (!adapter) return NRC_BADDR;
    if (fd == INVALID_SOCKET) return NRC_BADDR;
    if (!ncb) return NRC_BADDR;
    if (!cacheEntry) return NRC_BADDR;

    queryData.cacheEntry = NULL;
    queryData.ret = NRC_GOODRET;
    for (queries = 0; queryData.cacheEntry == NULL && queries < maxQueries;
     queries++)
    {
        if (!NCB_CANCELLED(ncb))
        {
            int r = NetBTSendNameQuery(fd, ncb->ncb_callname,
             adapter->nameQueryXID, NBNS_TYPE_NB, sendTo, broadcast);

            if (r == 0)
                queryData.ret = NetBTWaitForNameResponse(adapter, fd,
                 GetTickCount() + timeout, NetBTFindNameAnswerCallback,
                 &queryData);
            else
                queryData.ret = NRC_SYSTEM;
        }
        else
            queryData.ret = NRC_CMDCAN;
    }
    if (queryData.cacheEntry)
    {
        memcpy(queryData.cacheEntry->name, ncb->ncb_callname, NCBNAMSZ);
        memcpy(queryData.cacheEntry->nbname, ncb->ncb_callname, NCBNAMSZ);
    }
    *cacheEntry = queryData.cacheEntry;
    return queryData.ret;
}

/* Attempts to add cacheEntry to the name cache in *nameCache; if *nameCache
 * has not yet been created, creates it, using gCacheTimeout as the cache
 * entry timeout.  If memory allocation fails, or if NBNameCacheAddEntry fails,
 * frees cacheEntry.
 * Returns NRC_GOODRET on success, and something else on failure.
 */
static UCHAR NetBTStoreCacheEntry(struct NBNameCache **nameCache,
 NBNameCacheEntry *cacheEntry)
{
    UCHAR ret;

    if (!nameCache) return NRC_BADDR;
    if (!cacheEntry) return NRC_BADDR;

    if (!*nameCache)
        *nameCache = NBNameCacheCreate(GetProcessHeap(), gCacheTimeout);
    if (*nameCache)
        ret = NBNameCacheAddEntry(*nameCache, cacheEntry)
         ?  NRC_GOODRET : NRC_OSRESNOTAV;
    else
    {
        HeapFree(GetProcessHeap(), 0, cacheEntry);
        ret = NRC_OSRESNOTAV;
    }
    return ret;
}

/* Attempts to resolve name using inet_addr(), then gethostbyname() if
 * gEnableDNS is TRUE, if the suffix byte is either <00> or <20>.  If the name
 * can be looked up, returns 0 and stores the looked up addresses as a
 * NBNameCacheEntry in *cacheEntry.
 * Returns NRC_GOODRET on success, though this may not mean the name was
 * resolved--check whether *cacheEntry is NULL.  Returns something else on
 * error.
 */
static UCHAR NetBTinetResolve(const UCHAR name[NCBNAMSZ],
 NBNameCacheEntry **cacheEntry)
{
    UCHAR ret = NRC_GOODRET;

    TRACE("name %s, cacheEntry %p\n", name, cacheEntry);

    if (!name) return NRC_BADDR;
    if (!cacheEntry) return NRC_BADDR;

    if (isalnum(name[0]) && (name[NCBNAMSZ - 1] == 0 ||
     name[NCBNAMSZ - 1] == 0x20))
    {
        UCHAR toLookup[NCBNAMSZ];
        unsigned int i;

        for (i = 0; i < NCBNAMSZ - 1 && name[i] && name[i] != ' '; i++)
            toLookup[i] = name[i];
        toLookup[i] = '\0';

        if (isdigit(toLookup[0]))
        {
            unsigned long addr = inet_addr(toLookup);

            if (addr != INADDR_NONE)
            {
                *cacheEntry = HeapAlloc(GetProcessHeap(),
                 0, sizeof(NBNameCacheEntry));
                if (*cacheEntry)
                {
                    memcpy((*cacheEntry)->name, name, NCBNAMSZ);
                    memset((*cacheEntry)->nbname, 0, NCBNAMSZ);
                    (*cacheEntry)->nbname[0] = '*';
                    (*cacheEntry)->numAddresses = 1;
                    (*cacheEntry)->addresses[0] = addr;
                }
                else
                    ret = NRC_OSRESNOTAV;
            }
        }
        if (gEnableDNS && ret == NRC_GOODRET && !*cacheEntry)
        {
            struct hostent *host;

            if ((host = gethostbyname(toLookup)) != NULL)
            {
                for (i = 0; ret == NRC_GOODRET && host->h_addr_list &&
                 host->h_addr_list[i]; i++)
                    ;
                if (host->h_addr_list && host->h_addr_list[0])
                {
                    *cacheEntry = HeapAlloc(
                     GetProcessHeap(), 0, sizeof(NBNameCacheEntry) +
                     (i - 1) * sizeof(DWORD));
                    if (*cacheEntry)
                    {
                        memcpy((*cacheEntry)->name, name, NCBNAMSZ);
                        memset((*cacheEntry)->nbname, 0, NCBNAMSZ);
                        (*cacheEntry)->nbname[0] = '*';
                        (*cacheEntry)->numAddresses = i;
                        for (i = 0; i < (*cacheEntry)->numAddresses; i++)
                            (*cacheEntry)->addresses[i] =
                             (DWORD)host->h_addr_list[i];
                    }
                    else
                        ret = NRC_OSRESNOTAV;
                }
            }
        }
    }

    TRACE("returning 0x%02x\n", ret);
    return ret;
}

/* Looks up the name in ncb->ncb_callname, first in the name caches (global
 * and this adapter's), then using gethostbyname(), next by WINS if configured,
 * and finally using broadcast NetBT name resolution.  In NBT parlance, this
 * makes this an "H-node".  Stores an entry in the appropriate name cache for a
 * found node, and returns it as *cacheEntry.
 * Assumes data, ncb, and cacheEntry are not NULL.
 * Returns NRC_GOODRET on success--which doesn't mean the name was resolved,
 * just that all name lookup operations completed successfully--and something
 * else on failure.  *cacheEntry will be NULL if the name was not found.
 */
static UCHAR NetBTInternalFindName(NetBTAdapter *adapter, PNCB ncb,
 const NBNameCacheEntry **cacheEntry)
{
    UCHAR ret = NRC_GOODRET;

    TRACE("adapter %p, ncb %p, cacheEntry %p\n", adapter, ncb, cacheEntry);

    if (!cacheEntry) return NRC_BADDR;
    *cacheEntry = NULL;

    if (!adapter) return NRC_BADDR;
    if (!ncb) return NRC_BADDR;

    if (ncb->ncb_callname[0] == '*')
        ret = NRC_NOWILD;
    else
    {
        *cacheEntry = NBNameCacheFindEntry(gNameCache, ncb->ncb_callname);
        if (!*cacheEntry)
            *cacheEntry = NBNameCacheFindEntry(adapter->nameCache,
             ncb->ncb_callname);
        if (!*cacheEntry)
        {
            NBNameCacheEntry *newEntry = NULL;

            ret = NetBTinetResolve(ncb->ncb_callname, &newEntry);
            if (ret == NRC_GOODRET && newEntry)
            {
                ret = NetBTStoreCacheEntry(&gNameCache, newEntry);
                if (ret != NRC_GOODRET)
                    newEntry = NULL;
            }
            else
            {
                SOCKET fd = WSASocketA(PF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL,
                 0, WSA_FLAG_OVERLAPPED);

                if(fd == INVALID_SOCKET)
                    ret = NRC_OSRESNOTAV;
                else
                {
                    int winsNdx;

                    adapter->nameQueryXID++;
                    for (winsNdx = 0; ret == NRC_GOODRET && *cacheEntry == NULL
                     && winsNdx < gNumWINSServers; winsNdx++)
                        ret = NetBTNameWaitLoop(adapter, fd, ncb,
                         gWINSServers[winsNdx], FALSE, gWINSQueryTimeout,
                         gWINSQueries, &newEntry);
                    if (ret == NRC_GOODRET && newEntry)
                    {
                        ret = NetBTStoreCacheEntry(&gNameCache, newEntry);
                        if (ret != NRC_GOODRET)
                            newEntry = NULL;
                    }
                    if (ret == NRC_GOODRET && *cacheEntry == NULL)
                    {
                        DWORD bcastAddr =
                         adapter->ipr.dwAddr & adapter->ipr.dwMask;

                        if (adapter->ipr.dwBCastAddr)
                            bcastAddr |= ~adapter->ipr.dwMask;
                        ret = NetBTNameWaitLoop(adapter, fd, ncb, bcastAddr,
                         TRUE, gBCastQueryTimeout, gBCastQueries, &newEntry);
                        if (ret == NRC_GOODRET && newEntry)
                        {
                            ret = NetBTStoreCacheEntry(&adapter->nameCache,
                             newEntry);
                            if (ret != NRC_GOODRET)
                                newEntry = NULL;
                        }
                    }
                    closesocket(fd);
                }
            }
            *cacheEntry = newEntry;
        }
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

typedef struct _NetBTNodeQueryData
{
    BOOL gotResponse;
    PADAPTER_STATUS astat;
    WORD astatLen;
} NetBTNodeQueryData;

/* Callback function for NetBTAstatRemote, parses the rData for the node
 * status and name list of the remote node.  Always returns FALSE, since
 * there's never more than one answer we care about in a node status response.
 */
static BOOL NetBTNodeStatusAnswerCallback(void *pVoid, WORD answerCount,
 WORD answerIndex, PUCHAR rData, WORD rLen)
{
    NetBTNodeQueryData *data = (NetBTNodeQueryData *)pVoid;

    if (data && !data->gotResponse && rData && rLen >= 1)
    {
        /* num names is first byte; each name is NCBNAMSZ + 2 bytes */
        if (rLen >= rData[0] * (NCBNAMSZ + 2))
        {
            WORD i;
            PUCHAR src;
            PNAME_BUFFER dst;

            data->gotResponse = TRUE;
            data->astat->name_count = rData[0];
            for (i = 0, src = rData + 1,
             dst = (PNAME_BUFFER)((PUCHAR)data->astat +
              sizeof(ADAPTER_STATUS));
             i < data->astat->name_count && src - rData < rLen &&
             (PUCHAR)dst - (PUCHAR)data->astat < data->astatLen;
             i++, dst++, src += NCBNAMSZ + 2)
            {
                UCHAR flags = *(src + NCBNAMSZ);

                memcpy(dst->name, src, NCBNAMSZ);
                /* we won't actually see a registering name in the returned
                 * response.  It's useful to see if no other flags are set; if
                 * none are, then the name is registered. */
                dst->name_flags = REGISTERING;
                if (flags & 0x80)
                    dst->name_flags |= GROUP_NAME;
                if (flags & 0x10)
                    dst->name_flags |= DEREGISTERED;
                if (flags & 0x08)
                    dst->name_flags |= DUPLICATE;
                if (dst->name_flags == REGISTERING)
                    dst->name_flags = REGISTERED;
            }
            /* arbitrarily set HW type to Ethernet */
            data->astat->adapter_type = 0xfe;
            if (src - rData < rLen)
                memcpy(data->astat->adapter_address, src,
                 min(rLen - (src - rData), 6));
        }
    }
    return FALSE;
}

/* This uses the WINS timeout and query values, as they're the
 * UCAST_REQ_RETRY_TIMEOUT and UCAST_REQ_RETRY_COUNT according to the RFCs.
 */
static UCHAR NetBTAstatRemote(NetBTAdapter *adapter, PNCB ncb)
{
    UCHAR ret = NRC_GOODRET;
    const NBNameCacheEntry *cacheEntry = NULL;

    TRACE("adapter %p, NCB %p\n", adapter, ncb);

    if (!adapter) return NRC_BADDR;
    if (!ncb) return NRC_INVADDRESS;

    ret = NetBTInternalFindName(adapter, ncb, &cacheEntry);
    if (ret == NRC_GOODRET && cacheEntry)
    {
        if (cacheEntry->numAddresses > 0)
        {
            SOCKET fd = WSASocketA(PF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0,
             WSA_FLAG_OVERLAPPED);

            if(fd == INVALID_SOCKET)
                ret = NRC_OSRESNOTAV;
            else
            {
                NetBTNodeQueryData queryData;
                DWORD queries;
                PADAPTER_STATUS astat = (PADAPTER_STATUS)ncb->ncb_buffer;

                adapter->nameQueryXID++;
                astat->name_count = 0;
                queryData.gotResponse = FALSE;
                queryData.astat = astat;
                queryData.astatLen = ncb->ncb_length;
                for (queries = 0; !queryData.gotResponse &&
                 queries < gWINSQueries; queries++)
                {
                    if (!NCB_CANCELLED(ncb))
                    {
                        int r = NetBTSendNameQuery(fd, ncb->ncb_callname,
                         adapter->nameQueryXID, NBNS_TYPE_NBSTAT,
                         cacheEntry->addresses[0], FALSE);

                        if (r == 0)
                            ret = NetBTWaitForNameResponse(adapter, fd,
                             GetTickCount() + gWINSQueryTimeout,
                             NetBTNodeStatusAnswerCallback, &queryData);
                        else
                            ret = NRC_SYSTEM;
                    }
                    else
                        ret = NRC_CMDCAN;
                }
                closesocket(fd);
            }
        }
        else
            ret = NRC_CMDTMO;
    }
    else if (ret == NRC_CMDCAN)
        ; /* do nothing, we were cancelled */
    else
        ret = NRC_CMDTMO;
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static UCHAR NetBTAstat(void *adapt, PNCB ncb)
{
    NetBTAdapter *adapter = (NetBTAdapter *)adapt;
    UCHAR ret;

    TRACE("adapt %p, NCB %p\n", adapt, ncb);

    if (!adapter) return NRC_ENVNOTDEF;
    if (!ncb) return NRC_INVADDRESS;
    if (!ncb->ncb_buffer) return NRC_BADDR;
    if (ncb->ncb_length < sizeof(ADAPTER_STATUS)) return NRC_BUFLEN;

    if (ncb->ncb_callname[0] == '*')
    {
        DWORD physAddrLen;
        MIB_IFROW ifRow;
        PADAPTER_STATUS astat = (PADAPTER_STATUS)ncb->ncb_buffer;
  
        memset(astat, 0, sizeof(ADAPTER_STATUS));
        astat->rev_major = 3;
        ifRow.dwIndex = adapter->ipr.dwIndex;
        if (GetIfEntry(&ifRow) != NO_ERROR)
            ret = NRC_BRIDGE;
        else
        {
            physAddrLen = min(ifRow.dwPhysAddrLen, 6);
            if (physAddrLen > 0)
                memcpy(astat->adapter_address, ifRow.bPhysAddr, physAddrLen);
            /* doubt anyone cares, but why not.. */
            if (ifRow.dwType == MIB_IF_TYPE_TOKENRING)
                astat->adapter_type = 0xff;
            else
                astat->adapter_type = 0xfe; /* for Ethernet */
            astat->max_sess_pkt_size = 0xffff;
            astat->xmit_success = adapter->xmit_success;
            astat->recv_success = adapter->recv_success;
        }
        ret = NRC_GOODRET;
    }
    else
        ret = NetBTAstatRemote(adapter, ncb);
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static UCHAR NetBTFindName(void *adapt, PNCB ncb)
{
    NetBTAdapter *adapter = (NetBTAdapter *)adapt;
    UCHAR ret;
    const NBNameCacheEntry *cacheEntry = NULL;
    PFIND_NAME_HEADER foundName;

    TRACE("adapt %p, NCB %p\n", adapt, ncb);

    if (!adapter) return NRC_ENVNOTDEF;
    if (!ncb) return NRC_INVADDRESS;
    if (!ncb->ncb_buffer) return NRC_BADDR;
    if (ncb->ncb_length < sizeof(FIND_NAME_HEADER)) return NRC_BUFLEN;

    foundName = (PFIND_NAME_HEADER)ncb->ncb_buffer;
    memset(foundName, 0, sizeof(FIND_NAME_HEADER));

    ret = NetBTInternalFindName(adapter, ncb, &cacheEntry);
    if (ret == NRC_GOODRET)
    {
        if (cacheEntry)
        {
            DWORD spaceFor = min((ncb->ncb_length - sizeof(FIND_NAME_HEADER)) /
             sizeof(FIND_NAME_BUFFER), cacheEntry->numAddresses);
            DWORD ndx;

            for (ndx = 0; ndx < spaceFor; ndx++)
            {
                PFIND_NAME_BUFFER findNameBuffer;

                findNameBuffer =
                 (PFIND_NAME_BUFFER)((PUCHAR)foundName +
                 sizeof(FIND_NAME_HEADER) + foundName->node_count *
                 sizeof(FIND_NAME_BUFFER));
                memset(findNameBuffer->destination_addr, 0, 2);
                memcpy(findNameBuffer->destination_addr + 2,
                 &adapter->ipr.dwAddr, sizeof(DWORD));
                memset(findNameBuffer->source_addr, 0, 2);
                memcpy(findNameBuffer->source_addr + 2,
                 &cacheEntry->addresses[ndx], sizeof(DWORD));
                foundName->node_count++;
            }
            if (spaceFor < cacheEntry->numAddresses)
                ret = NRC_BUFLEN;
        }
        else
            ret = NRC_CMDTMO;
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static UCHAR NetBTSessionReq(SOCKET fd, const UCHAR *calledName,
 const UCHAR *callingName)
{
    UCHAR buffer[NBSS_HDRSIZE + MAX_DOMAIN_NAME_LEN * 2], ret;
    int r;
    unsigned int len = 0;
    DWORD bytesSent, bytesReceived, recvFlags = 0;
    WSABUF wsaBuf;

    buffer[0] = NBSS_REQ;
    buffer[1] = 0;

    len += NetBTNameEncode(calledName, &buffer[NBSS_HDRSIZE]);
    len += NetBTNameEncode(callingName, &buffer[NBSS_HDRSIZE + len]);

    NBR_ADDWORD(&buffer[2], len);

    wsaBuf.len = len + NBSS_HDRSIZE;
    wsaBuf.buf = buffer;

    r = WSASend(fd, &wsaBuf, 1, &bytesSent, 0, NULL, NULL);
    if(r < 0 || bytesSent < len + NBSS_HDRSIZE)
    {
        ERR("send failed\n");
        return NRC_SABORT;
    }

    /* I've already set the recv timeout on this socket (if it supports it), so
     * just block.  Hopefully we'll always receive the session acknowledgement
     * within one timeout.
     */
    wsaBuf.len = NBSS_HDRSIZE + 1;
    r = WSARecv(fd, &wsaBuf, 1, &bytesReceived, &recvFlags, NULL, NULL);
    if (r < 0 || bytesReceived < NBSS_HDRSIZE)
        ret = NRC_SABORT;
    else if (buffer[0] == NBSS_NACK)
    {
        if (r == NBSS_HDRSIZE + 1)
        {
            switch (buffer[NBSS_HDRSIZE])
            {
                case NBSS_ERR_INSUFFICIENT_RESOURCES:
                    ret = NRC_REMTFUL;
                    break;
                default:
                    ret = NRC_NOCALL;
            }
        }
        else
            ret = NRC_NOCALL;
    }
    else if (buffer[0] == NBSS_RETARGET)
    {
        FIXME("Got a session retarget, can't deal\n");
        ret = NRC_NOCALL;
    }
    else if (buffer[0] == NBSS_ACK)
        ret = NRC_GOODRET;
    else
        ret = NRC_SYSTEM;

    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static UCHAR NetBTCall(void *adapt, PNCB ncb, void **sess)
{
    NetBTAdapter *adapter = (NetBTAdapter *)adapt;
    UCHAR ret;
    const NBNameCacheEntry *cacheEntry = NULL;

    TRACE("adapt %p, ncb %p\n", adapt, ncb);

    if (!adapter) return NRC_ENVNOTDEF;
    if (!ncb) return NRC_INVADDRESS;
    if (!sess) return NRC_BADDR;

    ret = NetBTInternalFindName(adapter, ncb, &cacheEntry);
    if (ret == NRC_GOODRET)
    {
        if (cacheEntry && cacheEntry->numAddresses > 0)
        {
            SOCKET fd;

            fd = WSASocketA(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0,
             WSA_FLAG_OVERLAPPED);
            if (fd != INVALID_SOCKET)
            {
                DWORD timeout;
                struct sockaddr_in sin;

                if (ncb->ncb_rto > 0)
                {
                    timeout = ncb->ncb_rto * 500;
                    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (PUCHAR)&timeout,
                     sizeof(timeout));
                }
                if (ncb->ncb_rto > 0)
                {
                    timeout = ncb->ncb_sto * 500;
                    setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (PUCHAR)&timeout,
                     sizeof(timeout));
                }

                memset(&sin, 0, sizeof(sin));
                memcpy(&sin.sin_addr, &cacheEntry->addresses[0],
                 sizeof(sin.sin_addr));
                sin.sin_family = AF_INET;
                sin.sin_port   = htons(PORT_NBSS);
                /* FIXME: use nonblocking mode for the socket, check the
                 * cancel flag periodically
                 */
                if (connect(fd, (struct sockaddr *)&sin, sizeof(sin))
                 == SOCKET_ERROR)
                    ret = NRC_CMDTMO;
                else
                {
                    static UCHAR fakedCalledName[] = "*SMBSERVER";
                    const UCHAR *calledParty = cacheEntry->nbname[0] == '*'
                     ? fakedCalledName : cacheEntry->nbname;

                    ret = NetBTSessionReq(fd, calledParty, ncb->ncb_name);
                    if (ret != NRC_GOODRET && calledParty[0] == '*')
                    {
                        FIXME("NBT session to \"*SMBSERVER\" refused,\n");
                        FIXME("should try finding name using ASTAT\n");
                    }
                }
                if (ret != NRC_GOODRET)
                    closesocket(fd);
                else
                {
                    NetBTSession *session = HeapAlloc(
                     GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NetBTSession));

                    if (session)
                    {
                        session->fd = fd;
                        InitializeCriticalSection(&session->cs);
                        *sess = session;
                    }
                    else
                    {
                        ret = NRC_OSRESNOTAV;
                        closesocket(fd);
                    }
                }
            }
            else
                ret = NRC_OSRESNOTAV;
        }
        else
            ret = NRC_NAMERR;
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

/* Notice that I don't protect against multiple thread access to NetBTSend.
 * This is because I don't update any data in the adapter, and I only make a
 * single call to WSASend, which I assume to act atomically (not interleaving
 * data from other threads).
 * I don't lock, because I only depend on the fd being valid, and this won't be
 * true until a session setup is completed.
 */
static UCHAR NetBTSend(void *adapt, void *sess, PNCB ncb)
{
    NetBTAdapter *adapter = (NetBTAdapter *)adapt;
    NetBTSession *session = (NetBTSession *)sess;
    UCHAR buffer[NBSS_HDRSIZE], ret;
    int r;
    WSABUF wsaBufs[2];
    DWORD bytesSent;

    TRACE("adapt %p, session %p, NCB %p\n", adapt, session, ncb);

    if (!adapter) return NRC_ENVNOTDEF;
    if (!ncb) return NRC_INVADDRESS;
    if (!ncb->ncb_buffer) return NRC_BADDR;
    if (!session) return NRC_SNUMOUT;
    if (session->fd == INVALID_SOCKET) return NRC_SNUMOUT;

    buffer[0] = NBSS_MSG;
    buffer[1] = 0;
    NBR_ADDWORD(&buffer[2], ncb->ncb_length);

    wsaBufs[0].len = NBSS_HDRSIZE;
    wsaBufs[0].buf = buffer;
    wsaBufs[1].len = ncb->ncb_length;
    wsaBufs[1].buf = ncb->ncb_buffer;

    r = WSASend(session->fd, wsaBufs, sizeof(wsaBufs) / sizeof(wsaBufs[0]),
     &bytesSent, 0, NULL, NULL);
    if (r == SOCKET_ERROR)
    {
        NetBIOSHangupSession(ncb);
        ret = NRC_SABORT;
    }
    else if (bytesSent < NBSS_HDRSIZE + ncb->ncb_length)
    {
        FIXME("Only sent %ld bytes (of %d), hanging up session\n", bytesSent,
         NBSS_HDRSIZE + ncb->ncb_length);
        NetBIOSHangupSession(ncb);
        ret = NRC_SABORT;
    }
    else
    {
        ret = NRC_GOODRET;
        adapter->xmit_success++;
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static UCHAR NetBTRecv(void *adapt, void *sess, PNCB ncb)
{
    NetBTAdapter *adapter = (NetBTAdapter *)adapt;
    NetBTSession *session = (NetBTSession *)sess;
    UCHAR buffer[NBSS_HDRSIZE], ret;
    int r;
    WSABUF wsaBufs[2];
    DWORD bufferCount, bytesReceived, flags;

    TRACE("adapt %p, session %p, NCB %p\n", adapt, session, ncb);

    if (!adapter) return NRC_ENVNOTDEF;
    if (!ncb) return NRC_BADDR;
    if (!ncb->ncb_buffer) return NRC_BADDR;
    if (!session) return NRC_SNUMOUT;
    if (session->fd == INVALID_SOCKET) return NRC_SNUMOUT;

    EnterCriticalSection(&session->cs);
    bufferCount = 0;
    if (session->bytesPending == 0)
    {
        bufferCount++;
        wsaBufs[0].len = NBSS_HDRSIZE;
        wsaBufs[0].buf = buffer;
    }
    wsaBufs[bufferCount].len = ncb->ncb_length;
    wsaBufs[bufferCount].buf = ncb->ncb_buffer;
    bufferCount++;

    flags = 0;
    /* FIXME: should poll a bit so I can check the cancel flag */
    r = WSARecv(session->fd, wsaBufs, bufferCount, &bytesReceived, &flags,
     NULL, NULL);
    if (r == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
    {
        LeaveCriticalSection(&session->cs);
        ERR("Receive error, WSAGetLastError() returns %d\n", WSAGetLastError());
        NetBIOSHangupSession(ncb);
        ret = NRC_SABORT;
    }
    else if (NCB_CANCELLED(ncb))
    {
        LeaveCriticalSection(&session->cs);
        ret = NRC_CMDCAN;
    }
    else
    {
        if (bufferCount == 2)
        {
            if (buffer[0] == NBSS_KEEPALIVE)
            {
                LeaveCriticalSection(&session->cs);
                FIXME("Oops, received a session keepalive and lost my place\n");
                /* need to read another session header until we get a session
                 * message header. */
                NetBIOSHangupSession(ncb);
                ret = NRC_SABORT;
            }
            else if (buffer[0] != NBSS_MSG)
            {
                LeaveCriticalSection(&session->cs);
                FIXME("Received unexpected session msg type %d\n", buffer[0]);
                NetBIOSHangupSession(ncb);
                ret = NRC_SABORT;
            }
            else
            {
                if (buffer[1] & NBSS_EXTENSION)
                {
                    LeaveCriticalSection(&session->cs);
                    FIXME("Received a message that's too long for my taste\n");
                    NetBIOSHangupSession(ncb);
                    ret = NRC_SABORT;
                }
                else
                {
                    session->bytesPending = NBSS_HDRSIZE
                     + NBR_GETWORD(&buffer[2]) - bytesReceived;
                    ncb->ncb_length = bytesReceived - NBSS_HDRSIZE;
                    LeaveCriticalSection(&session->cs);
                }
            }
        }
        else
        {
            if (bytesReceived < session->bytesPending)
                session->bytesPending -= bytesReceived;
            else
                session->bytesPending = 0;
            LeaveCriticalSection(&session->cs);
            ncb->ncb_length = bytesReceived;
        }
        if (session->bytesPending > 0)
            ret = NRC_INCOMP;
        else
        {
            ret = NRC_GOODRET;
            adapter->recv_success++;
        }
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static UCHAR NetBTHangup(void *adapt, void *sess)
{
    NetBTSession *session = (NetBTSession *)sess;

    TRACE("adapt %p, session %p\n", adapt, session);

    if (!session) return NRC_SNUMOUT;

    /* I don't lock the session, because NetBTRecv knows not to decrement
     * past 0, so if a receive completes after this it should still deal.
     */
    closesocket(session->fd);
    session->fd = INVALID_SOCKET;
    session->bytesPending = 0;
    DeleteCriticalSection(&session->cs);
    HeapFree(GetProcessHeap(), 0, session);

    return NRC_GOODRET;
}

static void NetBTCleanupAdapter(void *adapt)
{
    TRACE("adapt %p\n", adapt);
    if (adapt)
    {
        NetBTAdapter *adapter = (NetBTAdapter *)adapt;

        if (adapter->nameCache)
            NBNameCacheDestroy(adapter->nameCache);
        HeapFree(GetProcessHeap(), 0, adapt);
    }
}

static void NetBTCleanup(void)
{
    TRACE("\n");
    if (gNameCache)
    {
        NBNameCacheDestroy(gNameCache);
        gNameCache = NULL;
    }
}

static UCHAR NetBTRegisterAdapter(PMIB_IPADDRROW ipRow)
{
    UCHAR ret;
    NetBTAdapter *adapter;
    
    if (!ipRow) return NRC_BADDR;

    adapter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NetBTAdapter));
    if (adapter)
    {
        memcpy(&adapter->ipr, ipRow, sizeof(MIB_IPADDRROW));
        if (!NetBIOSRegisterAdapter(gTransportID, ipRow->dwIndex, adapter))
        {
            NetBTCleanupAdapter(adapter);
            ret = NRC_SYSTEM;
        }
        else
            ret = NRC_GOODRET;
    }
    else
        ret = NRC_OSRESNOTAV;
    return ret;
}

/* Callback for NetBIOS adapter enumeration.  Assumes closure is a pointer to
 * a MIB_IPADDRTABLE containing all the IP adapters needed to be added to the
 * NetBIOS adapter table.  For each callback, checks if the passed-in adapt
 * has an entry in the table; if so, this adapter was enumerated previously,
 * and it's enabled.  As a flag, the table's dwAddr entry is changed to
 * INADDR_LOOPBACK, since this is an invalid address for a NetBT adapter.
 * The NetBTEnum function will add any remaining adapters from the
 * MIB_IPADDRTABLE to the NetBIOS adapter table.
 */
static BOOL NetBTEnumCallback(UCHAR totalLANAs, UCHAR lanaIndex,
 ULONG transport, const NetBIOSAdapterImpl *data, void *closure)
{
    BOOL ret;
    PMIB_IPADDRTABLE table = (PMIB_IPADDRTABLE)closure;

    if (table && data)
    {
        DWORD ndx;

        ret = FALSE;
        for (ndx = 0; !ret && ndx < table->dwNumEntries; ndx++)
        {
            const NetBTAdapter *adapter = (const NetBTAdapter *)data->data;

            if (table->table[ndx].dwIndex == adapter->ipr.dwIndex)
            {
                NetBIOSEnableAdapter(data->lana);
                table->table[ndx].dwAddr = INADDR_LOOPBACK;
                ret = TRUE;
            }
        }
    }
    else
        ret = FALSE;
    return ret;
}

/* Enumerates adapters by:
 * - retrieving the IP address table for the local machine
 * - eliminating loopback addresses from the table
 * - eliminating redundant addresses, that is, multiple addresses on the same
 *   subnet
 * Calls NetBIOSEnumAdapters, passing the resulting table as the callback
 * data.  The callback reenables each adapter that's already in the NetBIOS
 * table.  After NetBIOSEnumAdapters returns, this function adds any remaining
 * adapters to the NetBIOS table.
 */
static UCHAR NetBTEnum(void)
{
    UCHAR ret;
    DWORD size = 0;

    TRACE("\n");

    if (GetIpAddrTable(NULL, &size, FALSE) == ERROR_INSUFFICIENT_BUFFER)
    {
        PMIB_IPADDRTABLE ipAddrs, coalesceTable = NULL;
        DWORD numIPAddrs = (size - sizeof(MIB_IPADDRTABLE)) /
         sizeof(MIB_IPADDRROW) + 1;

        ipAddrs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
        if (ipAddrs)
            coalesceTable = HeapAlloc(GetProcessHeap(),
             HEAP_ZERO_MEMORY, sizeof(MIB_IPADDRTABLE) +
             (min(numIPAddrs, MAX_LANA + 1) - 1) * sizeof(MIB_IPADDRROW));
        if (ipAddrs && coalesceTable)
        {
            if (GetIpAddrTable(ipAddrs, &size, FALSE) == ERROR_SUCCESS)
            {
                DWORD ndx;

                for (ndx = 0; ndx < ipAddrs->dwNumEntries; ndx++)
                {
                    if ((ipAddrs->table[ndx].dwAddr &
                     ipAddrs->table[ndx].dwMask) !=
                     htonl((INADDR_LOOPBACK & IN_CLASSA_NET)))
                    {
                        BOOL newNetwork = TRUE;
                        DWORD innerIndex;

                        /* make sure we don't have more than one entry
                         * for a subnet */
                        for (innerIndex = 0; newNetwork &&
                         innerIndex < coalesceTable->dwNumEntries; innerIndex++)
                            if ((ipAddrs->table[ndx].dwAddr &
                             ipAddrs->table[ndx].dwMask) ==
                             (coalesceTable->table[innerIndex].dwAddr
                             & coalesceTable->table[innerIndex].dwMask))
                                newNetwork = FALSE;

                        if (newNetwork)
                            memcpy(&coalesceTable->table[
                             coalesceTable->dwNumEntries++],
                             &ipAddrs->table[ndx], sizeof(MIB_IPADDRROW));
                    }
                }

                NetBIOSEnumAdapters(gTransportID, NetBTEnumCallback,
                 coalesceTable);
                ret = NRC_GOODRET;
                for (ndx = 0; ret == NRC_GOODRET &&
                 ndx < coalesceTable->dwNumEntries; ndx++)
                    if (coalesceTable->table[ndx].dwAddr != INADDR_LOOPBACK)
                        ret = NetBTRegisterAdapter(&coalesceTable->table[ndx]);
            }
            else
                ret = NRC_SYSTEM;
            HeapFree(GetProcessHeap(), 0, ipAddrs);
            HeapFree(GetProcessHeap(), 0, coalesceTable);
        }
        else
            ret = NRC_OSRESNOTAV;
    }
    else
        ret = NRC_SYSTEM;
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static const WCHAR VxD_MSTCPW[] = { 'S','Y','S','T','E','M','\\','C','u','r',
 'r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','S','e','r','v',
 'i','c','e','s','\\','V','x','D','\\','M','S','T','C','P','\0' };
static const WCHAR NetBT_ParametersW[] = { 'S','Y','S','T','E','M','\\','C','u',
 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','S','e','r',
 'v','i','c','e','s','\\','N','e','t','B','T','\\','P','a','r','a','m','e','t',
 'e','r','s','\0' };
static const WCHAR EnableDNSW[] = { 'E','n','a','b','l','e','D','N','S','\0' };
static const WCHAR BcastNameQueryCountW[] = { 'B','c','a','s','t','N','a','m',
 'e','Q','u','e','r','y','C','o','u','n','t','\0' };
static const WCHAR BcastNameQueryTimeoutW[] = { 'B','c','a','s','t','N','a','m',
 'e','Q','u','e','r','y','T','i','m','e','o','u','t','\0' };
static const WCHAR NameSrvQueryCountW[] = { 'N','a','m','e','S','r','v',
 'Q','u','e','r','y','C','o','u','n','t','\0' };
static const WCHAR NameSrvQueryTimeoutW[] = { 'N','a','m','e','S','r','v',
 'Q','u','e','r','y','T','i','m','e','o','u','t','\0' };
static const WCHAR ScopeIDW[] = { 'S','c','o','p','e','I','D','\0' };
static const WCHAR CacheTimeoutW[] = { 'C','a','c','h','e','T','i','m','e','o',
 'u','t','\0' };
static const WCHAR Config_NetworkW[] = { 'S','o','f','t','w','a','r','e','\\',
                                         'W','i','n','e','\\','N','e','t','w','o','r','k','\0' };

/* Initializes global variables and registers the NetBT transport */
void NetBTInit(void)
{
    HKEY hKey;
    NetBIOSTransport transport;
    LONG ret;

    TRACE("\n");

    gEnableDNS = TRUE;
    gBCastQueries = BCAST_QUERIES;
    gBCastQueryTimeout = BCAST_QUERY_TIMEOUT;
    gWINSQueries = WINS_QUERIES;
    gWINSQueryTimeout = WINS_QUERY_TIMEOUT;
    gNumWINSServers = 0;
    memset(gWINSServers, 0, sizeof(gWINSServers));
    gScopeID[0] = '\0';
    gCacheTimeout = CACHE_TIMEOUT;

    /* Try to open the Win9x NetBT configuration key */
    ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, VxD_MSTCPW, 0, KEY_READ, &hKey);
    /* If that fails, try the WinNT NetBT configuration key */
    if (ret != ERROR_SUCCESS)
        ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NetBT_ParametersW, 0, KEY_READ,
         &hKey);
    if (ret == ERROR_SUCCESS)
    {
        DWORD dword, size;

        size = sizeof(dword);
        if (RegQueryValueExW(hKey, EnableDNSW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS)
            gEnableDNS = dword;
        size = sizeof(dword);
        if (RegQueryValueExW(hKey, BcastNameQueryCountW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERIES
         && dword <= MAX_QUERIES)
            gBCastQueries = dword;
        size = sizeof(dword);
        if (RegQueryValueExW(hKey, BcastNameQueryTimeoutW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERY_TIMEOUT
         && dword <= MAX_QUERY_TIMEOUT)
            gBCastQueryTimeout = dword;
        size = sizeof(dword);
        if (RegQueryValueExW(hKey, NameSrvQueryCountW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERIES
         && dword <= MAX_QUERIES)
            gWINSQueries = dword;
        size = sizeof(dword);
        if (RegQueryValueExW(hKey, NameSrvQueryTimeoutW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERY_TIMEOUT
         && dword <= MAX_QUERY_TIMEOUT)
            gWINSQueryTimeout = dword;
        size = MAX_DOMAIN_NAME_LEN - 1;
        if (RegQueryValueExW(hKey, ScopeIDW, NULL, NULL, gScopeID + 1, &size)
         == ERROR_SUCCESS)
        {
            /* convert into L2-encoded version, suitable for use by
               NetBTNameEncode */
            char *ptr, *lenPtr;

            for (ptr = gScopeID + 1; *ptr &&
             ptr - gScopeID < MAX_DOMAIN_NAME_LEN; )
            {
                for (lenPtr = ptr - 1, *lenPtr = 0; *ptr && *ptr != '.' &&
                 ptr - gScopeID < MAX_DOMAIN_NAME_LEN; ptr++)
                    *lenPtr += 1;
                ptr++;
            }
        }
        if (RegQueryValueExW(hKey, CacheTimeoutW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_CACHE_TIMEOUT)
            gCacheTimeout = dword;
        RegCloseKey(hKey);
    }
    /* WINE-specific NetBT registry settings.  Because our adapter naming is
     * different than MS', we can't do per-adapter WINS configuration in the
     * same place.  Just do a global WINS configuration instead.
     */
    /* @@ Wine registry key: HKCU\Software\Wine\Network */
    if (RegOpenKeyW(HKEY_CURRENT_USER, Config_NetworkW, &hKey) == ERROR_SUCCESS)
    {
        static const char *nsValueNames[] = { "WinsServer", "BackupWinsServer" };
        char nsString[16];
        DWORD size, ndx;

        for (ndx = 0; ndx < sizeof(nsValueNames) / sizeof(nsValueNames[0]);
         ndx++)
        {
            size = sizeof(nsString) / sizeof(char);
            if (RegQueryValueExA(hKey, nsValueNames[ndx], NULL, NULL,
             (LPBYTE)nsString, &size) == ERROR_SUCCESS)
            {
                unsigned long addr = inet_addr(nsString);

                if (addr != INADDR_NONE && gNumWINSServers < MAX_WINS_SERVERS)
                    gWINSServers[gNumWINSServers++] = addr;
            }
        }
        RegCloseKey(hKey);
    }

    transport.enumerate      = NetBTEnum;
    transport.astat          = NetBTAstat;
    transport.findName       = NetBTFindName;
    transport.call           = NetBTCall;
    transport.send           = NetBTSend;
    transport.recv           = NetBTRecv;
    transport.hangup         = NetBTHangup;
    transport.cleanupAdapter = NetBTCleanupAdapter;
    transport.cleanup        = NetBTCleanup;
    memcpy(&gTransportID, TRANSPORT_NBT, sizeof(ULONG));
    NetBIOSRegisterTransport(gTransportID, &transport);
}
