/* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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, (const char*)&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 = (CHAR*)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(const 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), (CHAR*)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++] = *(const DWORD *)(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(const NetBTAdapter *adapter, SOCKET fd, const NCB *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))
    {
        CHAR 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 = (char*)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, (char*)&timeout,
                     sizeof(timeout));
                }
                if (ncb->ncb_rto > 0)
                {
                    timeout = ncb->ncb_sto * 500;
                    setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&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 const 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);
                        session->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": NetBTSession.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 = (char*)buffer;
    wsaBufs[1].len = ncb->ncb_length;
    wsaBufs[1].buf = (char*)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 %d 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 = (char*)buffer;
    }
    wsaBufs[bufferCount].len = ncb->ncb_length;
    wsaBufs[bufferCount].buf = (char*)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;
    session->cs.DebugInfo->Spare[0] = 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(const MIB_IPADDRROW *ipRow)
{
    UCHAR ret;
    NetBTAdapter *adapter;

    if (!ipRow) return NRC_BADDR;

    adapter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NetBTAdapter));
    if (adapter)
    {
        adapter->ipr = *ipRow;
        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, (LPBYTE)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);
}
