/* 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 "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include "winreg.h"
#include "iphlpapi.h"
#include "winsock2.h"
#include "netbios.h"
#include "nbnamecache.h"

WINE_DEFAULT_DEBUG_CHANNEL(netbios);

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

#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 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;
        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 = (NBNameCacheEntry *)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)
{
    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 look up name using gethostbyname(), 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 NetBTgethostbyname(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];
        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 = (NBNameCacheEntry *)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 (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 = (NBNameCacheEntry *)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 = NetBTgethostbyname(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)
                    {
                        ret = NetBTNameWaitLoop(adapter, fd, ncb,
                         adapter->ipr.dwBCastAddr, 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_pktsize = 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 len = 0, r;
    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", 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 = (NetBTSession *)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 = (NetBTAdapter *)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 = (PMIB_IPADDRTABLE)HeapAlloc(GetProcessHeap(),
         HEAP_ZERO_MEMORY, size);
        if (ipAddrs)
            coalesceTable = (PMIB_IPADDRTABLE)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;
}

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

    TRACE("\n");

    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;

    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
     "\\SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP", 0, KEY_READ, &hKey)
     == ERROR_SUCCESS)
    {
        DWORD dword, size = sizeof(dword), ndx;
        static const char *nsValueNames[] =
         { "NameServer", "BackupNameServer" };
        char nsString[16];

        size = sizeof(dword);
        if (RegQueryValueExA(hKey, "BcastNameQueryCount", NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERIES
         && dword <= MAX_QUERIES)
            gBCastQueries = dword;
        size = sizeof(dword);
        if (RegQueryValueExA(hKey, "BcastNameQueryTimeout", NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERY_TIMEOUT
         && dword <= MAX_QUERY_TIMEOUT)
            gBCastQueryTimeout = dword;
        size = sizeof(dword);
        if (RegQueryValueExA(hKey, "NameSrvQueryCount", NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERIES
         && dword <= MAX_QUERIES)
            gWINSQueries = dword;
        size = sizeof(dword);
        if (RegQueryValueExA(hKey, "NameSrvQueryTimeout", NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERY_TIMEOUT
         && dword <= MAX_QUERY_TIMEOUT)
            gWINSQueryTimeout = dword;
        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;
            }
        }
        size = MAX_DOMAIN_NAME_LEN - 1;
        if (RegQueryValueExA(hKey, "ScopeID", 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 (RegQueryValueExA(hKey, "CacheTimeout", NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_CACHE_TIMEOUT)
            gCacheTimeout = dword;
        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);
}
