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

📄 netbiostransport.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                }




            }
            pAddr = pAddr->Next;
        }

        pAdapTemp = pAdapTemp->Next;
    }

    Done:

#ifdef DEBUG
        if(FALSE == fAllowed) {
            TRACEMSG(ZONE_ERROR, (L"NETBIOS: not an allowed interface -- this is okay, but might mean the adapter should be configured -- see docs"));
        }
#endif

        if(NULL != pAdapInfo && &AdapInfo[0] != pAdapInfo) {
            delete [] pAdapInfo;
        }
        return fAllowed;
}


//
//  Init a NetBIOS lana -- this involves
//     registering for our name on the interface
//     and spinning transport threads to queue
//     our CIFS packets
HRESULT InitLana(UCHAR ulLANIdx, DWORD dwNTE)
{
    TRACEMSG(ZONE_INIT, (TEXT("SMBSRV:Initing NETBIOS LANA(%d)"),ulLANIdx));
    HRESULT hr = E_FAIL;
    BYTE *pCName;
    UCHAR retVal;
    UINT uiCNameLen;
    ncb tNcb;
    NetBIOSAdapter *pNewAdapter = NULL;
    LANA_INFO LanaInfo;

    //
    // Get the CName from globals
    if(FAILED(hr = SMB_Globals::GetCName(&pCName, &uiCNameLen)) ||
       NULL == pCName ||
       0 == uiCNameLen ||
       uiCNameLen > 15)
    {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV:Invalid CName returned from globals!")));
        if(SUCCEEDED(hr))  //preserve any failure HR we might have
            hr = E_FAIL;
        goto Done;
    }

    //
    // Query into netbios for the ipaddress of the new adapter
    tNcb.ncb_command = NCBQUERYLANA;
    tNcb.ncb_length = sizeof(LANA_INFO);
    tNcb.ncb_buffer = (BYTE *)&LanaInfo;
    tNcb.ncb_lana_num = ulLANIdx;

    retVal = Netbios(&tNcb);
    if (0 != (retVal = tNcb.ncb_retcode)) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV:InitLana: NCBQUERYLANA returned %s"), NETBIOS_TRANSPORT::NCBError(retVal)));
        if(SUCCEEDED(hr))  //preserve any failure HR we might have
            hr = E_FAIL;
        goto Done;
    }

    //
    // See if we want to listen on this adapter
    if(FALSE == AllowLana(&LanaInfo)) {
        TRACEMSG(ZONE_NETBIOS, (L"SMBSRV:InitLana: we dont allow this LANA (%d)", ulLANIdx));
        hr = S_OK;
        goto Done;
    }

    RETAILMSG(1, (TEXT("SMBSRV:InitLana: staring lana: %d"), ulLANIdx));

    //
    // Setup addname and claim our name
    tNcb.ncb_command = NCBADDNAME;
    tNcb.ncb_lana_num = ulLANIdx;
    tNcb.ncb_length = 0;
    tNcb.ncb_buffer = NULL;
    memset(tNcb.ncb_name, ' ', 16);
    memcpy(tNcb.ncb_name, pCName, uiCNameLen);

    retVal = Netbios(&tNcb);
    if (0 != (retVal = tNcb.ncb_retcode)) {
        RETAILMSG(1, (TEXT("SMBSRV:InitLana: NCBADDNAME returned %s"), NETBIOS_TRANSPORT::NCBError(retVal)));
        if(SUCCEEDED(hr))  //preserve any failure HR we might have
            hr = E_FAIL;
        goto Done;
    }

    //
    // Startup a TCP transport
    if(FAILED(hr = StartTCPListenThread(LanaInfo.IPAddr, ulLANIdx))) {
        goto Done;
    }

    //fire up the interface (by creating a new NetBIOSAdapter object) --
    //  inside that will spin any threads it needs (it will be self contained)
    if(NULL == (pNewAdapter = new NetBIOSAdapter(ulLANIdx))) {
        hr = E_OUTOFMEMORY;
        goto Done;
    }

    pNewAdapter->SetNTE(dwNTE);
    pNewAdapter->SetCName(tNcb.ncb_name);
    if(!NBAdapterStack.push_back(pNewAdapter)) {
        hr = E_OUTOFMEMORY;
    }
    pNewAdapter = NULL;
    hr = S_OK;

    Done:
        //
        // NOTE: this is nulled on init/success... only on failure would
        //    it be non-null
        if(pNewAdapter)
            delete pNewAdapter;

        return hr;
}


HRESULT
InitNetbiosTransport()
{
    if(g_fIsInited) {
        return S_OK;
    }

    g_fIsInited = TRUE;

    InitializeCriticalSection(&csSendLock);
    InitializeCriticalSection(&csActiveRecvListLock);
    InitializeCriticalSection(&csAdapterStackList);
    InitializeCriticalSection(&csNCBLock);

    //
    // Create an event to stop any threads that we may create
    if(NULL == g_hHaltNetbiosTransport) {
       g_hHaltNetbiosTransport = CreateEvent(NULL, TRUE, FALSE, NULL);
    }

    return (NULL == g_hHaltNetbiosTransport)?E_FAIL:S_OK;
}

HRESULT
DestroyNetbiosTransport()
{
    if(!g_fIsInited) {
        return S_OK;
    }

    g_fIsInited = FALSE;

    if(NULL != g_hHaltNetbiosTransport) {
        CloseHandle(g_hHaltNetbiosTransport);
        g_hHaltNetbiosTransport = NULL;
    }
    DeleteCriticalSection(&csSendLock);
    DeleteCriticalSection(&csActiveRecvListLock);
    DeleteCriticalSection(&csAdapterStackList);
    DeleteCriticalSection(&csNCBLock);
    return S_OK;
}

//
//  Start the netbios transport -- this includes
//     initing any global variables before threads get spun
//     etc
HRESULT StartNetbiosTransport()
{
    TRACEMSG(ZONE_INIT, (TEXT("SMBSRV:Starting NETBIOS transport")));
    HRESULT hr=E_FAIL;

    //
    // If we are already running dont start up
    if(TRUE == g_fIsRunning) {
        hr = S_OK;
        goto Done;
    }

    //
    // running must be true for the enumeration code to operate properly
    InterlockedExchange(&g_fIsRunning, TRUE);

    ASSERT(INVALID_HANDLE_VALUE == g_hNetbiosIOCTL);
    if(INVALID_HANDLE_VALUE == (g_hNetbiosIOCTL = CreateFile(NETBIOS_DEV_NAME,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL))) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV:Couldnt connect to NETBIOS!")));
        ASSERT(FALSE);
        goto Done;
    }

    //
    // Start up a thread to listen for name change events (this thread never goes away)
    if(FAILED(hr = StartListenOnNameChange())) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV:Failed to start the netbios name listen thread!")));
        goto Done;
    }

    //
    // Start enuming netbios calls -- this registers with netbios to receive lan up/down events
    if(FAILED(hr = StartEnumeratingNetbios())) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV:Failed getting number of interfaces!")));
        goto Done;
    }

    hr = S_OK;

    InterlockedExchange(&g_fIsAccepting, TRUE);
    Done:
        if(FAILED(hr)) {
            InterlockedExchange(&g_fIsRunning, FALSE);
        }
        return hr;
}



HRESULT StopNetbiosTransport(void)
{
    TRACEMSG(ZONE_INIT, (TEXT("SMBSRV:Stopping NETBIOS transport")));

    HRESULT hr = S_OK;
    BOOL fHaldAdapterFailed = FALSE;

    //
    // Stop listening on name change (NOTE; this maybe running even when the rest
    //   of netbios isnt, so dont check g_fIsRunning
    if(FAILED(hr = StopListeningOnNameChange())) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV:error stoping listening on name change")));
        ASSERT(FALSE);
        goto Done;
    }
    if(FALSE == g_fIsRunning) {
        hr = S_OK;
        goto Done;
    }

    InterlockedExchange(&g_fIsRunning, FALSE);
    ASSERT(INVALID_HANDLE_VALUE != g_hNetbiosIOCTL);

    //
    // Stop enumerating netbios devices
    if(FAILED(hr = StopEnumeratingNetbios())) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV:error stoping enum thread")));
        ASSERT(FALSE);
        goto Done;
    }

    //
    // Flush out any remaining adapters
    while(NBAdapterStack.size()) {
        NetBIOSAdapter *pAdapter = NBAdapterStack.front();

        if(NULL == pAdapter) {
            ASSERT(FALSE);
        } else {
            if(FAILED(hr = pAdapter->HaltAdapter())) {
                fHaldAdapterFailed = TRUE;
                TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV:error stoping netbios adapter")));
            }
            NBAdapterStack.pop_front();
            delete pAdapter;
        }
    }

    //
    // Just empty out the list -- the values inside it are worthless now
    //     as the NBAdapterStack has been flushed
    while(NBAdapterDeleteStack.size()) {
        NBAdapterDeleteStack.pop_front();
    }

    InterlockedExchange(&g_fIsAccepting, FALSE);

    Done:
        if(fHaldAdapterFailed || FAILED(hr)) {
            hr = E_FAIL;
            InterlockedExchange(&g_fIsAccepting, TRUE);
            InterlockedExchange(&g_fIsRunning, TRUE);
        }
        if(INVALID_HANDLE_VALUE != g_hNetbiosIOCTL) {
            CloseHandle(g_hNetbiosIOCTL);
            g_hNetbiosIOCTL = INVALID_HANDLE_VALUE;
        }
        return hr;
}




DWORD
NETBIOS_TRANSPORT::SMBSRVR_NetbiosListenThread(LPVOID _pMyAdapter)
{
    HRESULT hr = E_FAIL;
    PREFAST_ASSERT(_pMyAdapter);
    NetBIOSAdapter *pMyAdapter = (NetBIOSAdapter *)_pMyAdapter;
    ASSERT(pMyAdapter);
    UINT uiConsecFails = 0;

    // See if we have been shut down -- (note we were created suspended so
    //   errors can be checked for
    if(pMyAdapter->DuringShutDown()) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-LSTNTHREAD:Listen thread not starting -- error before launch")));
        hr = E_FAIL;
        goto Done;
    }

    //
    // Loop as long as we are not shutting down
    while (FALSE == pMyAdapter->DuringShutDown()) {
        ncb ncb;
        BYTE *pCName;
        UINT uiCNameLen;
        UCHAR ncb_err;

#ifdef DEBUG
        memset(&ncb, 0xAB, sizeof(ncb));
#endif

        ncb.ncb_lana_num = pMyAdapter->GetLANA();
        ncb.ncb_command = NCBLISTEN;
        ncb.ncb_callname[0] = '*';
        ncb.ncb_length = 0;
        ncb.ncb_buffer = NULL;

        //
        // Get the CName from globals
        if(FAILED(hr = SMB_Globals::GetCName(&pCName, &uiCNameLen)) ||
           NULL == pCName ||
           0 == uiCNameLen ||
           uiCNameLen > 15)
        {
            //
            // If getting the CName fails, there really isnt much we can do
            //    just abort out
            TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-LSTNTHREAD:Invalid CName returned from globals!")));
            if(SUCCEEDED(hr))  //preserve any failure HR we might have
                hr = E_FAIL;
            goto Done;
        }
        memset(ncb.ncb_name, ' ', 16);
        memcpy(ncb.ncb_name, pCName, uiCNameLen);

        ncb_err = Netbios(&ncb);

        //
        // Make sure we didnt return from the blocked state into a shutdown
        if(TRUE == pMyAdapter->DuringShutDown()) {
            TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-LSTNTHREAD:ListenThread -- recved shutdown")));
            break;
        }

        //
        // Check for errors on the return of NETBIOS
        if(NRC_ADPTMALFN == ncb_err || NRC_IFAIL == ncb_err) {
            RETAILMSG(1, (TEXT("SMBSRV-LSTNTHREAD:ListenThread stopping because of adapter malfunction -- prob was pulled?")));
            break;
        } else if(0 != ncb_err) {
            TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-LSTNTHREAD:ListenThread NCBLISTEN(%d) returned %s"), pMyAdapter->GetLANA(), NETBIOS_TRANSPORT::NCBError(ncb_err)));
            ASSERT(FALSE);
            uiConsecFails ++;
        } else {
            TRACEMSG(ZONE_ERROR, (L"NETBIOS Listen got -- LSN:%d on LANA:%d", ncb.ncb_lsn, ncb.ncb_lana_num));

            HANDLE hRecvThread;
            RecvNode NewNode;
            RecvNode *pNodePtr = NULL;

            CCritSection csLock(&csActiveRecvListLock);
            csLock.Lock();
            if(!ActiveRecvList.push_front(NewNode)) {
                hr = E_OUTOFMEMORY;
                goto Done;
            }
            pNodePtr = &(ActiveRecvList.front());

            hRecvThread   = CreateThread(NULL, 0, SMBSRVR_NetbiosRecvThread,  (LPVOID)pNodePtr, CREATE_SUSPENDED, NULL);
            pNodePtr->pAdapter = pMyAdapter;
            pNodePtr->LANA = ncb.ncb_lana_num;
            pNodePtr->usLSN = ncb.ncb_lsn;
            pNodePtr->MyHandle = hRecvThread;

            if(NULL == hRecvThread) {
                TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV:InitLana: CreateThread failed starting NB Recv:%d"), GetLastError()));
                ActiveRecvList.pop_front();
                goto Done;
            }
            if(0xFFFFFFFF == ResumeThread(hRecvThread)) {
                TRACEMSG(ZONE_ERROR, (L"SMBSRV:Resuming  recv thread %d FAILED!"));
                CloseHandle(hRecvThread);
            }
            uiConsecFails = 0;
        }

        //
        // If we have failed a bunch of times in a row, abort... something is wrong
        if(uiConsecFails >= 20) { //BUGBUG: use some real number here
            TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-LSTNTHREAD:ListenThread too many back to back fails... quitting thread\n")));
            break;
        }
    }

    Done:
        TRACEMSG(ZONE_DETAIL, (TEXT("SMBSRV-LSTNTHREAD:Exiting thread!")));
        if(FAILED(hr))
            return -1;
        else
            return 0;
}

HRESULT
NETBIOS_TRANSPORT::CopyNBTransportToken(VOID *pToken, VOID **pNewToken)
{
    ((ref_ncb *)pToken)->AddRef();
    *pNewToken = pToken;
    return S_OK;
}


HRESULT
NETBIOS_TRANSPORT::DeleteNBTransportToken(VOID *pToken)
{
    ((ref_ncb *)pToken)->Release();
    return S_OK;
}



DWORD
NETBIOS_TRANSPORT::SMBSRVR_NetbiosRecvThread(LPVOID _pAdapter)

⌨️ 快捷键说明

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