/* 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
 */
#include "config.h"
#include "wine/debug.h"
#include "nbcmdqueue.h"
#include "netbios.h"

WINE_DEFAULT_DEBUG_CHANNEL(netbios);

/* This file provides a NetBIOS emulator that implements the NetBIOS interface,
 * including thread safety and asynchronous call support.  The protocol
 * implementation is separate, with blocking (synchronous) functions.
 */

#define ADAPTERS_INCR 8
#define DEFAULT_NUM_SESSIONS 16

typedef struct _NetBIOSTransportTableEntry
{
    ULONG            id;
    NetBIOSTransport transport;
} NetBIOSTransportTableEntry;

typedef struct _NetBIOSSession
{
    BOOL  inUse;
    UCHAR state;
    UCHAR local_name[NCBNAMSZ];
    UCHAR remote_name[NCBNAMSZ];
    void *data;
} NetBIOSSession;

/* This struct needs a little explanation, unfortunately.  enabled is only
 * used by nbInternalEnum (see).  If transport_id is not 0 and transport
 * is not NULL, the adapter is considered valid.  (transport is a pointer to
 * an entry in a NetBIOSTransportTableEntry.)  data has data for the callers of
 * NetBIOSEnumAdapters to be able to see.  The lana is repeated there, even
 * though I don't use it internally--it's for transports to use reenabling
 * adapters using NetBIOSEnableAdapter.
 */
typedef struct _NetBIOSAdapter
{
    BOOL               enabled;
    BOOL               shuttingDown;
    ULONG              resetting;
    ULONG              transport_id;
    NetBIOSTransport  *transport;
    NetBIOSAdapterImpl impl;
    struct NBCmdQueue *cmdQueue;
    CRITICAL_SECTION   cs;
    DWORD              sessionsLen;
    NetBIOSSession    *sessions;
} NetBIOSAdapter;

typedef struct _NetBIOSAdapterTable {
    CRITICAL_SECTION cs;
    BOOL             enumerated;
    BOOL             enumerating;
    UCHAR            tableSize;
    NetBIOSAdapter  *table;
} NetBIOSAdapterTable;

/* Just enough space for NBT right now */
static NetBIOSTransportTableEntry gTransports[1];
static UCHAR gNumTransports = 0;
static NetBIOSAdapterTable gNBTable;

static UCHAR nbResizeAdapterTable(UCHAR newSize)
{
    UCHAR ret;

    if (gNBTable.table)
        gNBTable.table = (NetBIOSAdapter *)HeapReAlloc(GetProcessHeap(),
         HEAP_ZERO_MEMORY, gNBTable.table,
         newSize * sizeof(NetBIOSAdapter));
    else
        gNBTable.table = (NetBIOSAdapter *)HeapAlloc(GetProcessHeap(),
         HEAP_ZERO_MEMORY, newSize * sizeof(NetBIOSAdapter));
    if (gNBTable.table)
    {
        gNBTable.tableSize = newSize;
        ret = NRC_GOODRET;
    }
    else
        ret = NRC_OSRESNOTAV;
    return ret;
}

void NetBIOSInit(void)
{
    memset(&gNBTable, 0, sizeof(gNBTable));
    InitializeCriticalSection(&gNBTable.cs);
}

void NetBIOSShutdown(void)
{
    UCHAR i;

    EnterCriticalSection(&gNBTable.cs);
    for (i = 0; i < gNBTable.tableSize; i++)
    {
        if (gNBTable.table[i].transport &&
         gNBTable.table[i].transport->cleanupAdapter)
            gNBTable.table[i].transport->cleanupAdapter(
             gNBTable.table[i].impl.data);
    }
    for (i = 0; i < gNumTransports; i++)
        if (gTransports[i].transport.cleanup)
            gTransports[i].transport.cleanup();
    LeaveCriticalSection(&gNBTable.cs);
    DeleteCriticalSection(&gNBTable.cs);
    HeapFree(GetProcessHeap(), 0, gNBTable.table);
}

BOOL NetBIOSRegisterTransport(ULONG id, NetBIOSTransport *transport)
{
    BOOL ret;

    TRACE(": transport 0x%08lx, p %p\n", id, transport);
    if (!transport)
        ret = FALSE;
    else if (gNumTransports >= sizeof(gTransports) / sizeof(gTransports[0]))
    {
        FIXME("You tried to add %d transports, but I only have space for %d\n",
         gNumTransports + 1, sizeof(gTransports) / sizeof(gTransports[0]));
        ret = FALSE;
    }
    else
    {
        UCHAR i;

        ret = FALSE;
        for (i = 0; !ret && i < gNumTransports; i++)
        {
            if (gTransports[i].id == id)
            {
                WARN("Replacing NetBIOS transport ID %ld\n", id);
                memcpy(&gTransports[i].transport, transport,
                 sizeof(NetBIOSTransport));
                ret = TRUE;
            }
        }
        if (!ret)
        {
            gTransports[gNumTransports].id = id;
            memcpy(&gTransports[gNumTransports].transport, transport,
             sizeof(NetBIOSTransport));
            gNumTransports++;
            ret = TRUE;
        }
    }
    TRACE("returning %d\n", ret);
    return ret;
}

/* In this, I acquire the table lock to make sure no one else is modifying it.
 * This is _probably_ overkill since it should only be called during the
 * context of a NetBIOSEnum call, but just to be safe..
 */
BOOL NetBIOSRegisterAdapter(ULONG transport, DWORD ifIndex, void *data)
{
    BOOL ret;
    UCHAR i;

    TRACE(": transport 0x%08lx, ifIndex 0x%08lx, data %p\n", transport, ifIndex,
     data);
    for (i = 0; i < gNumTransports && gTransports[i].id != transport; i++)
        ;
    if (gTransports[i].id == transport)
    {
        NetBIOSTransport *transportPtr = &gTransports[i].transport;

        TRACE(": found transport %p for id 0x%08lx\n", transportPtr, transport);

        EnterCriticalSection(&gNBTable.cs);
        ret = FALSE;
        for (i = 0; i < gNBTable.tableSize &&
         gNBTable.table[i].transport != 0; i++)
            ;
        if (i == gNBTable.tableSize && gNBTable.tableSize < MAX_LANA + 1)
        {
            UCHAR newSize;

            if (gNBTable.tableSize < (MAX_LANA + 1) - ADAPTERS_INCR)
                newSize = gNBTable.tableSize + ADAPTERS_INCR;
            else
                newSize = MAX_LANA + 1;
            nbResizeAdapterTable(newSize);
        }
        if (i < gNBTable.tableSize && gNBTable.table[i].transport == 0)
        {
            TRACE(": registering as LANA %d\n", i);
            gNBTable.table[i].transport_id = transport;
            gNBTable.table[i].transport = transportPtr;
            gNBTable.table[i].impl.lana = i;
            gNBTable.table[i].impl.ifIndex = ifIndex;
            gNBTable.table[i].impl.data = data;
            gNBTable.table[i].cmdQueue = NBCmdQueueCreate(GetProcessHeap());
            InitializeCriticalSection(&gNBTable.table[i].cs);
            gNBTable.table[i].enabled = TRUE;
            ret = TRUE;
        }
        LeaveCriticalSection(&gNBTable.cs);
    }
    else
        ret = FALSE;
    TRACE("returning %d\n", ret);
    return ret;
}

/* In this, I acquire the table lock to make sure no one else is modifying it.
 * This is _probably_ overkill since it should only be called during the
 * context of a NetBIOSEnum call, but just to be safe..
 */
void NetBIOSEnableAdapter(UCHAR lana)
{
    TRACE(": %d\n", lana);
    if (lana < gNBTable.tableSize)
    {
        EnterCriticalSection(&gNBTable.cs);
        if (gNBTable.table[lana].transport != 0)
            gNBTable.table[lana].enabled = TRUE;
        LeaveCriticalSection(&gNBTable.cs);
    }
}

static void nbShutdownAdapter(NetBIOSAdapter *adapter)
{
    if (adapter)
    {
        adapter->shuttingDown = TRUE;
        NBCmdQueueCancelAll(adapter->cmdQueue);
        if (adapter->transport->cleanupAdapter)
            adapter->transport->cleanupAdapter(adapter->impl.data);
        NBCmdQueueDestroy(adapter->cmdQueue);
        DeleteCriticalSection(&adapter->cs);
        memset(adapter, 0, sizeof(NetBIOSAdapter));
    }
}

static void nbInternalEnum(void)
{
    UCHAR i;

    EnterCriticalSection(&gNBTable.cs);
    TRACE("before mark\n");
    /* mark: */
    for (i = 0; i < gNBTable.tableSize; i++)
        if (gNBTable.table[i].enabled && gNBTable.table[i].transport != 0)
            gNBTable.table[i].enabled = FALSE;

    TRACE("marked, before store, %d transports\n", gNumTransports);
    /* store adapters: */
    for (i = 0; i < gNumTransports; i++)
        if (gTransports[i].transport.enumerate)
            gTransports[i].transport.enumerate();

    TRACE("before sweep\n");
    /* sweep: */
    for (i = 0; i < gNBTable.tableSize; i++)
        if (!gNBTable.table[i].enabled && gNBTable.table[i].transport != 0)
            nbShutdownAdapter(&gNBTable.table[i]);
    gNBTable.enumerated = TRUE;
    LeaveCriticalSection(&gNBTable.cs);
}

UCHAR NetBIOSNumAdapters(void)
{
    UCHAR ret, i;

    if (!gNBTable.enumerated)
        nbInternalEnum();
    for (i = 0, ret = 0; i < gNBTable.tableSize; i++)
        if (gNBTable.table[i].transport != 0)
            ret++;
    return ret;
}

void NetBIOSEnumAdapters(ULONG transport, NetBIOSEnumAdaptersCallback cb,
 void *closure)
{
    TRACE("transport 0x%08lx, callback %p, closure %p\n", transport, cb,
     closure);
    if (cb)
    {
        BOOL enumAll = memcmp(&transport, ALL_TRANSPORTS, sizeof(ULONG)) == 0;
        UCHAR i, numLANAs = 0;

        EnterCriticalSection(&gNBTable.cs);
        if (!gNBTable.enumerating)
        {
            gNBTable.enumerating = TRUE;
            nbInternalEnum();
            gNBTable.enumerating = FALSE;
        }
        for (i = 0; i < gNBTable.tableSize; i++)
            if (enumAll || gNBTable.table[i].transport_id == transport)
                numLANAs++;
        if (numLANAs > 0)
        {
            UCHAR lanaIndex = 0;

            for (i = 0; i < gNBTable.tableSize; i++)
                if (gNBTable.table[i].transport_id != 0 &&
                 (enumAll || gNBTable.table[i].transport_id == transport))
                    cb(numLANAs, lanaIndex++, gNBTable.table[i].transport_id,
                     &gNBTable.table[i].impl, closure);
        }
        LeaveCriticalSection(&gNBTable.cs);
    }
}

static NetBIOSAdapter *nbGetAdapter(UCHAR lana)
{
    NetBIOSAdapter *ret = NULL;

    TRACE(": lana %d, num allocated adapters %d\n", lana, gNBTable.tableSize);
    if (lana < gNBTable.tableSize && gNBTable.table[lana].transport_id != 0
     && gNBTable.table[lana].transport)
        ret = &gNBTable.table[lana];
    TRACE("returning %p\n", ret);
    return ret;
}

static UCHAR nbEnum(PNCB ncb)
{
    PLANA_ENUM lanas = (PLANA_ENUM)ncb->ncb_buffer;
    UCHAR i, ret;

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

    if (!lanas)
        ret = NRC_BUFLEN;
    else if (ncb->ncb_length < sizeof(LANA_ENUM))
        ret = NRC_BUFLEN;
    else
    {
        nbInternalEnum();
        lanas->length = 0;
        for (i = 0; i < gNBTable.tableSize; i++)
            if (gNBTable.table[i].transport)
            {
                lanas->length++;
                lanas->lana[i] = i;
            }
        ret = NRC_GOODRET;
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static UCHAR nbInternalHangup(NetBIOSAdapter *adapter, NetBIOSSession *session);

static UCHAR nbCancel(NetBIOSAdapter *adapter, PNCB ncb)
{
    UCHAR ret;

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

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

    switch (ncb->ncb_command & 0x7f)
    {
        case NCBCANCEL:
        case NCBADDNAME:
        case NCBADDGRNAME:
        case NCBDELNAME:
        case NCBRESET:
        case NCBSSTAT:
            ret = NRC_CANCEL;
            break;

        /* NCBCALL, NCBCHAINSEND/NCBSEND, NCBHANGUP all close the associated
         * session if cancelled */
        case NCBCALL:
        case NCBSEND:
        case NCBCHAINSEND:
        case NCBSENDNA:
        case NCBCHAINSENDNA:
        case NCBHANGUP:
        {
            if (ncb->ncb_lsn >= adapter->sessionsLen)
                ret = NRC_SNUMOUT;
            else if (!adapter->sessions[ncb->ncb_lsn].inUse)
                ret = NRC_SNUMOUT;
            else
            {
                ret = NBCmdQueueCancel(adapter->cmdQueue, ncb);
                if (ret == NRC_CMDCAN || ret == NRC_CANOCCR)
                    nbInternalHangup(adapter, &adapter->sessions[ncb->ncb_lsn]);
            }
            break;
        }

        default:
            ret = NBCmdQueueCancel(adapter->cmdQueue, ncb);
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

/* Resizes adapter to contain space for at least sessionsLen sessions.
 * If allocating more space for sessions, sets the adapter's sessionsLen to
 * sessionsLen.  If the adapter's sessionsLen was already at least sessionsLen,
 * does nothing.  Does not modify existing sessions.  Assumes the adapter is
 * locked.
 * Returns NRC_GOODRET on success, and something else on failure.
 */
static UCHAR nbResizeAdapter(NetBIOSAdapter *adapter, UCHAR sessionsLen)
{
    UCHAR ret = NRC_GOODRET;

    if (adapter && adapter->sessionsLen < sessionsLen)
    {
        NetBIOSSession *newSessions;

        if (adapter->sessions)
            newSessions = (NetBIOSSession *)HeapReAlloc(GetProcessHeap(),
             HEAP_ZERO_MEMORY, adapter->sessions, sessionsLen *
             sizeof(NetBIOSSession));
        else
            newSessions = (NetBIOSSession *)HeapAlloc(GetProcessHeap(),
             HEAP_ZERO_MEMORY, sessionsLen * sizeof(NetBIOSSession));
        if (newSessions)
        {
            adapter->sessions = newSessions;
            adapter->sessionsLen = sessionsLen;
        }
        else
            ret = NRC_OSRESNOTAV;
    }
    return ret;
}

static UCHAR nbReset(NetBIOSAdapter *adapter, PNCB ncb)
{
    UCHAR ret;

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

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

    if (InterlockedIncrement(&adapter->resetting) == 1)
    {
        UCHAR i, resizeTo;

        NBCmdQueueCancelAll(adapter->cmdQueue);

        EnterCriticalSection(&adapter->cs);
        for (i = 0; i < adapter->sessionsLen; i++)
            if (adapter->sessions[i].inUse)
                nbInternalHangup(adapter, &adapter->sessions[i]);
        if (!ncb->ncb_lsn)
            resizeTo = ncb->ncb_callname[0] == 0 ? DEFAULT_NUM_SESSIONS :
             ncb->ncb_callname[0];
        else if (adapter->sessionsLen == 0)
            resizeTo = DEFAULT_NUM_SESSIONS;
        else
            resizeTo = 0;
        if (resizeTo > 0)
            ret = nbResizeAdapter(adapter, resizeTo);
        else
            ret = NRC_GOODRET;
        LeaveCriticalSection(&adapter->cs);
    }
    else
        ret = NRC_TOOMANY;
    InterlockedDecrement(&adapter->resetting);
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static UCHAR nbSStat(NetBIOSAdapter *adapter, PNCB ncb)
{
    UCHAR ret, i, spaceFor;
    PSESSION_HEADER sstat;

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

    if (!adapter) return NRC_BADDR;
    if (adapter->sessionsLen == 0) return NRC_ENVNOTDEF;
    if (!ncb) return NRC_INVADDRESS;
    if (!ncb->ncb_buffer) return NRC_BADDR;
    if (ncb->ncb_length < sizeof(SESSION_HEADER)) return NRC_BUFLEN;

    sstat = (PSESSION_HEADER)ncb->ncb_buffer;
    ret = NRC_GOODRET;
    memset(sstat, 0, sizeof(SESSION_HEADER));
    spaceFor = (ncb->ncb_length - sizeof(SESSION_HEADER)) /
     sizeof(SESSION_BUFFER);
    EnterCriticalSection(&adapter->cs);
    for (i = 0; ret == NRC_GOODRET && i < adapter->sessionsLen; i++)
    {
        if (adapter->sessions[i].inUse && (ncb->ncb_name[0] == '*' ||
         !memcmp(ncb->ncb_name, adapter->sessions[i].local_name, NCBNAMSZ)))
        {
            if (sstat->num_sess < spaceFor)
            {
                PSESSION_BUFFER buf;
               
                buf = (PSESSION_BUFFER)((PUCHAR)sstat + sizeof(SESSION_HEADER)
                 + sstat->num_sess * sizeof(SESSION_BUFFER));
                buf->lsn = i;
                buf->state = adapter->sessions[i].state;
                memcpy(buf->local_name, adapter->sessions[i].local_name,
                 NCBNAMSZ);
                memcpy(buf->remote_name, adapter->sessions[i].remote_name,
                 NCBNAMSZ);
                buf->rcvs_outstanding = buf->sends_outstanding = 0;
                sstat->num_sess++;
            }
            else
                ret = NRC_BUFLEN;
        }
    }
    LeaveCriticalSection(&adapter->cs);

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

static UCHAR nbCall(NetBIOSAdapter *adapter, PNCB ncb)
{
    UCHAR ret, i;

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

    if (!adapter) return NRC_BRIDGE;
    if (adapter->sessionsLen == 0) return NRC_ENVNOTDEF;
    if (!adapter->transport->call) return NRC_ILLCMD;
    if (!ncb) return NRC_INVADDRESS;

    EnterCriticalSection(&adapter->cs);
    for (i = 0; i < adapter->sessionsLen && adapter->sessions[i].inUse; i++)
        ;
    if (i < adapter->sessionsLen)
    {
        adapter->sessions[i].inUse = TRUE;
        adapter->sessions[i].state = CALL_PENDING;
        memcpy(adapter->sessions[i].local_name, ncb->ncb_name, NCBNAMSZ);
        memcpy(adapter->sessions[i].remote_name, ncb->ncb_callname, NCBNAMSZ);
        ret = NRC_GOODRET;
    }
    else
        ret = NRC_LOCTFUL;
    LeaveCriticalSection(&adapter->cs);

    if (ret == NRC_GOODRET)
    {
        ret = adapter->transport->call(adapter->impl.data, ncb,
         &adapter->sessions[i].data);
        if (ret == NRC_GOODRET)
        {
            ncb->ncb_lsn = i;
            adapter->sessions[i].state = SESSION_ESTABLISHED;
        }
        else
        {
            adapter->sessions[i].inUse = FALSE;
            adapter->sessions[i].state = 0;
        }
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static UCHAR nbSend(NetBIOSAdapter *adapter, PNCB ncb)
{
    UCHAR ret;
    NetBIOSSession *session;

    if (!adapter) return NRC_BRIDGE;
    if (!adapter->transport->send) return NRC_ILLCMD;
    if (!ncb) return NRC_INVADDRESS;
    if (ncb->ncb_lsn >= adapter->sessionsLen) return NRC_SNUMOUT;
    if (!adapter->sessions[ncb->ncb_lsn].inUse) return NRC_SNUMOUT;
    if (!ncb->ncb_buffer) return NRC_BADDR;

    session = &adapter->sessions[ncb->ncb_lsn];
    if (session->state != SESSION_ESTABLISHED)
        ret = NRC_SNUMOUT;
    else
        ret = adapter->transport->send(adapter->impl.data, session->data, ncb);
    return ret;
}

static UCHAR nbRecv(NetBIOSAdapter *adapter, PNCB ncb)
{
    UCHAR ret;
    NetBIOSSession *session;

    if (!adapter) return NRC_BRIDGE;
    if (!adapter->transport->recv) return NRC_ILLCMD;
    if (!ncb) return NRC_INVADDRESS;
    if (ncb->ncb_lsn >= adapter->sessionsLen) return NRC_SNUMOUT;
    if (!adapter->sessions[ncb->ncb_lsn].inUse) return NRC_SNUMOUT;
    if (!ncb->ncb_buffer) return NRC_BADDR;

    session = &adapter->sessions[ncb->ncb_lsn];
    if (session->state != SESSION_ESTABLISHED)
        ret = NRC_SNUMOUT;
    else
        ret = adapter->transport->recv(adapter->impl.data, session->data, ncb);
    return ret;
}

static UCHAR nbInternalHangup(NetBIOSAdapter *adapter, NetBIOSSession *session)
{
    UCHAR ret;

    if (!adapter) return NRC_BRIDGE;
    if (!session) return NRC_SNUMOUT;

    if (adapter->transport->hangup)
        ret = adapter->transport->hangup(adapter->impl.data, session->data);
    else
        ret = NRC_ILLCMD;
    EnterCriticalSection(&adapter->cs);
    memset(session, 0, sizeof(NetBIOSSession));
    LeaveCriticalSection(&adapter->cs);
    return NRC_GOODRET;
}

static UCHAR nbHangup(NetBIOSAdapter *adapter, PNCB ncb)
{
    UCHAR ret;
    NetBIOSSession *session;

    if (!adapter) return NRC_BRIDGE;
    if (!ncb) return NRC_INVADDRESS;
    if (ncb->ncb_lsn >= adapter->sessionsLen) return NRC_SNUMOUT;
    if (!adapter->sessions[ncb->ncb_lsn].inUse) return NRC_SNUMOUT;

    session = &adapter->sessions[ncb->ncb_lsn];
    if (session->state != SESSION_ESTABLISHED)
        ret = NRC_SNUMOUT;
    else
    {
        session->state = HANGUP_PENDING;
        ret = nbInternalHangup(adapter, session);
    }
    return ret;
}

void NetBIOSHangupSession(PNCB ncb)
{
    NetBIOSAdapter *adapter;

    if (!ncb) return;

    adapter = nbGetAdapter(ncb->ncb_lana_num);
    if (adapter)
    {
        if (ncb->ncb_lsn < adapter->sessionsLen &&
         adapter->sessions[ncb->ncb_lsn].inUse)
            nbHangup(adapter, ncb);
    }
}

static UCHAR nbAStat(NetBIOSAdapter *adapter, PNCB ncb)
{
    UCHAR ret;

    if (!adapter) return NRC_BRIDGE;
    if (!adapter->transport->astat) return NRC_ILLCMD;
    if (!ncb) return NRC_INVADDRESS;
    if (!ncb->ncb_buffer) return NRC_BADDR;
    if (ncb->ncb_length < sizeof(ADAPTER_STATUS)) return NRC_BUFLEN;

    ret = adapter->transport->astat(adapter->impl.data, ncb);
    if (ncb->ncb_callname[0] == '*')
    {
        PADAPTER_STATUS astat = (PADAPTER_STATUS)ncb->ncb_buffer;

        astat->max_sess = astat->max_cfg_sess = adapter->sessionsLen;
    }
    return ret;
}

static UCHAR nbDispatch(NetBIOSAdapter *adapter, PNCB ncb)
{
    UCHAR ret, cmd;

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

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

    cmd = ncb->ncb_command & 0x7f;
    if (cmd == NCBRESET)
        ret = nbReset(adapter, ncb);
    else
    {
        ret = NBCmdQueueAdd(adapter->cmdQueue, ncb);
        if (ret == NRC_GOODRET)
        {
            switch (cmd)
            {
                case NCBCALL:
                    ret = nbCall(adapter, ncb);
                    break;

                /* WinNT doesn't chain sends, it always sends immediately.
                 * Doubt there's any real significance to the NA variants.
                 */
                case NCBSEND:
                case NCBSENDNA:
                case NCBCHAINSEND:
                case NCBCHAINSENDNA:
                    ret = nbSend(adapter, ncb);
                    break;

                case NCBRECV:
                    ret = nbRecv(adapter, ncb);
                    break;

                case NCBHANGUP:
                    ret = nbHangup(adapter, ncb);
                    break;

                case NCBASTAT:
                    ret = nbAStat(adapter, ncb);
                    break;

                case NCBFINDNAME:
                    if (adapter->transport->findName)
                        ret = adapter->transport->findName(adapter->impl.data,
                         ncb);
                    else
                        ret = NRC_ILLCMD;
                    break;

                default:
                    FIXME("(%p): command code 0x%02x\n", ncb, ncb->ncb_command);
                    ret = NRC_ILLCMD;
            }
            NBCmdQueueComplete(adapter->cmdQueue, ncb, ret);
        }
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

static DWORD WINAPI nbCmdThread(LPVOID lpVoid)
{
    PNCB ncb = (PNCB)lpVoid;

    if (ncb)
    {
        UCHAR ret;
        NetBIOSAdapter *adapter = nbGetAdapter(ncb->ncb_lana_num);

        if (adapter)
            ret = nbDispatch(adapter, ncb);
        else
            ret = NRC_BRIDGE;
        ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret;
        if (ncb->ncb_post)
            ncb->ncb_post(ncb);
        else if (ncb->ncb_event)
            SetEvent(ncb->ncb_event);
    }
    return 0;
}

UCHAR WINAPI Netbios(PNCB ncb)
{
    UCHAR ret, cmd;

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

    if (!ncb) return NRC_INVADDRESS;

    TRACE("ncb_command 0x%02x, ncb_lana_num %d, ncb_buffer %p, ncb_length %d\n",
     ncb->ncb_command, ncb->ncb_lana_num, ncb->ncb_buffer, ncb->ncb_length);
    cmd = ncb->ncb_command & 0x7f;

    if (cmd == NCBENUM)
        ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret = nbEnum(ncb);
    else
    {
        NetBIOSAdapter *adapter = nbGetAdapter(ncb->ncb_lana_num);

        if (!adapter)
            ret = NRC_BRIDGE;
        else
        {
            if (adapter->shuttingDown)
                ret = NRC_IFBUSY;
            else if (adapter->resetting)
                ret = NRC_TOOMANY;
            else
            {
                /* non-asynch commands first */
                if (cmd == NCBCANCEL)
                    ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret =
                     nbCancel(adapter, ncb);
                else if (cmd == NCBSSTAT)
                    ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret =
                     nbSStat(adapter, ncb);
                else
                {
                    if (ncb->ncb_command & ASYNCH)
                    {
                        HANDLE thread = CreateThread(NULL, 0, nbCmdThread, ncb,
                         CREATE_SUSPENDED, NULL);

                        if (thread != NULL)
                        {
                            ncb->ncb_retcode = ncb->ncb_cmd_cplt = NRC_PENDING;
                            if (ncb->ncb_event)
                                ResetEvent(ncb->ncb_event);
                            ResumeThread(thread);
                            CloseHandle(thread);
                            ret = NRC_GOODRET;
                        }
                        else
                        ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret =
                         NRC_OSRESNOTAV;
                    }
                    else
                        ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret =
                         nbDispatch(adapter, ncb);
                }
            }
        }
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}
