⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nbt.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
    else if (NCB_CANCELLED(ncb))
    {
        LeaveCriticalSection(&session->cs);
        ret = NRC_CMDCAN;
    }
    else
    {
        if (bufferCount == 2)
        {
            if (buffer[0] == NBSS_KEEPALIVE)
            {
                LeaveCriticalSection(&session->cs);
                FIXME("Oops, received a session keepalive and lost my place\n");
                /* need to read another session header until we get a session
                 * message header. */
                NetBIOSHangupSession(ncb);
                ret = NRC_SABORT;
            }
            else if (buffer[0] != NBSS_MSG)
            {
                LeaveCriticalSection(&session->cs);
                FIXME("Received unexpected session msg type %d\n", buffer[0]);
                NetBIOSHangupSession(ncb);
                ret = NRC_SABORT;
            }
            else
            {
                if (buffer[1] & NBSS_EXTENSION)
                {
                    LeaveCriticalSection(&session->cs);
                    FIXME("Received a message that's too long for my taste\n");
                    NetBIOSHangupSession(ncb);
                    ret = NRC_SABORT;
                }
                else
                {
                    session->bytesPending = NBSS_HDRSIZE
                     + NBR_GETWORD(&buffer[2]) - bytesReceived;
                    ncb->ncb_length = bytesReceived - NBSS_HDRSIZE;
                    LeaveCriticalSection(&session->cs);
                }
            }
        }
        else
        {
            if (bytesReceived < session->bytesPending)
                session->bytesPending -= bytesReceived;
            else
                session->bytesPending = 0;
            LeaveCriticalSection(&session->cs);
            ncb->ncb_length = bytesReceived;
        }
        if (session->bytesPending > 0)
            ret = NRC_INCOMP;
        else
        {
            ret = NRC_GOODRET;
            adapter->recv_success++;
        }
    }
    TRACE("returning 0x%02x\n", ret);
    return ret;
}

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

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

    if (!session) return NRC_SNUMOUT;

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

    return NRC_GOODRET;
}

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

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

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

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

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

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

    if (table && data)
    {
        DWORD ndx;

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

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

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

    TRACE("\n");

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

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

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

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

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

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

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

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

    TRACE("\n");

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

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

        size = sizeof(dword);
        if (RegQueryValueExW(hKey, EnableDNSW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS)
            gEnableDNS = dword;
        size = sizeof(dword);
        if (RegQueryValueExW(hKey, BcastNameQueryCountW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERIES
         && dword <= MAX_QUERIES)
            gBCastQueries = dword;
        size = sizeof(dword);
        if (RegQueryValueExW(hKey, BcastNameQueryTimeoutW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERY_TIMEOUT
         && dword <= MAX_QUERY_TIMEOUT)
            gBCastQueryTimeout = dword;
        size = sizeof(dword);
        if (RegQueryValueExW(hKey, NameSrvQueryCountW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERIES
         && dword <= MAX_QUERIES)
            gWINSQueries = dword;
        size = sizeof(dword);
        if (RegQueryValueExW(hKey, NameSrvQueryTimeoutW, NULL, NULL,
         (LPBYTE)&dword, &size) == ERROR_SUCCESS && dword >= MIN_QUERY_TIMEOUT
         && dword <= MAX_QUERY_TIMEOUT)
            gWINSQueryTimeout = dword;
        size = MAX_DOMAIN_NAME_LEN - 1;
        if (RegQueryValueExW(hKey, ScopeIDW, NULL, NULL, (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);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -