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

📄 netbiostransport.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
{
    DWORD dwRet = -1;
    HRESULT hr = E_FAIL;
    BYTE *pCName;
    UINT uiCNameLen;
    ncb ncbRequest;
    BYTE ncb_err;
    PREFAST_ASSERT(_pAdapter);
    RecvNode *pNode = (RecvNode *)_pAdapter;
    NetBIOSAdapter *pAdapter = pNode->pAdapter;
    SMB_PACKET *pNewPacket = NULL;
    ref_ncb *pSendNCB = NULL;
    ref_ncb *pMainNCB = NULL;
    CCritSection csLock(&csActiveRecvListLock);

    ASSERT(pAdapter);

    TRACEMSG(ZONE_ERROR, (L"SMBSRV-NBRECV:RecvThread listening on LANA: %d  LSN:%d", pNode->LANA, pNode->usLSN));

    //check to be sure we are in the correct state -- get any persistent data before
    //  going into main processing loop
    if(pAdapter->DuringShutDown()) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-NBRECV:RecvThread thread not starting -- error before launch")));
        hr = E_ABORT;
        goto Done;
    }
    if(NULL == pAdapter) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-NBRECV:RecvThread thread could not get global adapter object")));
        hr = E_UNEXPECTED;
        goto Done;
    }
    if(FAILED(hr = SMB_Globals::GetCName(&pCName, &uiCNameLen)) ||
       NULL == pCName ||
       0 == uiCNameLen ||
       uiCNameLen > 15) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-NBRECV:Invalid CName returned from globals!")));
        if(SUCCEEDED(hr)) //preserve any failure hr
            hr = E_FAIL;
        goto Done;
    }

    if(NULL == (pMainNCB = new ref_ncb())) {
        hr = E_OUTOFMEMORY;
        goto Done;
    }

    while(!pAdapter->DuringShutDown())
    {
        ASSERT(NULL == pSendNCB);

        ncbRequest.ncb_command = NCBRECV;
        ncbRequest.ncb_lana_num = pNode->LANA;
        ncbRequest.ncb_lsn = pNode->usLSN;;
        memset(ncbRequest.ncb_name, ' ', 16);
        memcpy(ncbRequest.ncb_name, pCName, uiCNameLen);

        //
        // Get some memory out of our free pool
        if(NULL == (pNewPacket = SMB_Globals::g_SMB_Pool.Alloc())) {
            hr = E_OUTOFMEMORY;
            goto Done;
        }

        pNewPacket->pInSMB = (SMB_HEADER *)pNewPacket->InSMB;
        ncbRequest.ncb_buffer = pNewPacket->InSMB;
        ncbRequest.ncb_length = SMB_Globals::MAX_PACKET_SIZE;

        (pNewPacket->InSMB)[0] = 0;
        (pNewPacket->InSMB)[1] = 0;
        (pNewPacket->InSMB)[2] = 0;
        (pNewPacket->InSMB)[3] = 0;

        //read a packet
        if(0 == (ncb_err = Netbios(&ncbRequest)) && FALSE == pAdapter->DuringShutDown() &&
            (pNewPacket->InSMB)[0] == 0xFF &&
            (pNewPacket->InSMB)[1] == 'S' &&
            (pNewPacket->InSMB)[2] == 'M' &&
            (pNewPacket->InSMB)[3] == 'B') {
            TRACEMSG(ZONE_NETBIOS, (L"SMBSRV-NBRECV: got packet on LSN: %d   LANA: %d", ncbRequest.ncb_lsn, ncbRequest.ncb_lana_num));
            IFDBG(pNewPacket->PerfStartTimer());

            pSendNCB = pMainNCB;
            pSendNCB->AddRef();
            memcpy((void*)&pSendNCB->m_ncb, (void *)&ncbRequest, sizeof(ncb));
            pNewPacket->pToken = (void *)pSendNCB;
            pNewPacket->uiInSize = ncbRequest.ncb_length;
            pNewPacket->pOutSMB = NULL;
            pNewPacket->uiOutSize = 0;
            pNewPacket->pfnQueueFunction = QueueNBPacketForSend;
            pNewPacket->pfnCopyTranportToken = CopyNBTransportToken;
            pNewPacket->pfnDeleteTransportToken = DeleteNBTransportToken;
            //pNewPacket->pfnGetSocketName = NB_GetSocketName;
            pNewPacket->uiPacketType = SMB_NORMAL_PACKET;
            pNewPacket->ulConnectionID = (ULONG)(SMB_Globals::NB_TRANSPORT << 16) | ncbRequest.ncb_lsn;
            pNewPacket->dwDelayBeforeSending = 0;
#ifdef DEBUG
            pNewPacket->uiPacketNumber = InterlockedIncrement(&SMB_Globals::g_PacketID);
#endif

            //
            // If this connection isnt on our outstanding list put it there
            csLock.Lock();
            ce::list<ULONG>::iterator it = pNode->OutStandingConnectionIDs.begin();
            BOOL fOnList = FALSE;
            while(it != pNode->OutStandingConnectionIDs.end()) {
                if(pNewPacket->ulConnectionID == (*it)) {
                    fOnList = TRUE;
                    break;
                }
                it ++;
            }
            if(FALSE == fOnList) {
                if(!pNode->OutStandingConnectionIDs.push_front(pNewPacket->ulConnectionID)) {
                    hr = E_OUTOFMEMORY;
                    goto Done;
                }
            }
            csLock.UnLock();

            //
            // Hand off the packet to the SMB cracker
            IFDBG(pNewPacket->PerfPrintStatus(L"NB, got all of packet"));
            if(FAILED(CrackPacket(pNewPacket))) {
                //this should *NEVER* happen... Crack should handle its own errors
                TRACEMSG(ZONE_NETBIOS, (TEXT("SMBSRV-NBRECV: UNEXPECTED ERROR IN CRACK()!")));
                ASSERT(FALSE);
                hr = E_UNEXPECTED;
                goto Done;
            } else {
                // if it DID work, zero out all our pointers as the cracker owns
                //   our memory
                pNewPacket = NULL;
                pSendNCB = NULL;
            }
        } else {
            TRACEMSG(ZONE_NETBIOS, (L"SMBSRV-LSTNTHREAD: Hangup LSN(%d)\n", ncbRequest.ncb_lsn));
            BOOL fBadLana = (NRC_ADPTMALFN == ncb_err);

            //
            // Clean up any memory we might have allocated (that would normally
            //   be send through the cracker
            ASSERT(NULL == pSendNCB);

            if(pSendNCB)
                pSendNCB->Release();
            pSendNCB = NULL;

            // Hang up this session!
            ncbRequest.ncb_command = NCBHANGUP;
            ncbRequest.ncb_length = 0;
            ncbRequest.ncb_buffer = NULL;

            //
            // if we are here AND the previous error WASNT BAD_LANA issue a hangup
            //    request
            if(FALSE == fBadLana && (ncb_err = Netbios(&ncbRequest))) {
                TRACEMSG(ZONE_ERROR, (L"SMBSRV-NBRECV: Error hanging up LSN(%d)!!! (%s) -- maybe we are shutting down -- if so we will catch that on next iteration of loop?",ncbRequest.ncb_lsn, NETBIOS_TRANSPORT::NCBError(ncb_err)));
            } else if(TRUE == fBadLana) {
                TRACEMSG(ZONE_ERROR, (L"SMBSRV-NBRECV: bad LANA on LSN(%d)!!!",ncbRequest.ncb_lsn));
            }

            //
            // Purge out the cracker
            if(NULL != pNewPacket) {
                memset(pNewPacket, 0, sizeof(SMB_PACKET));
                pNewPacket->uiPacketType = SMB_CONNECTION_DROPPED;
                pNewPacket->ulConnectionID = (ULONG)(SMB_Globals::NB_TRANSPORT << 16) | ncbRequest.ncb_lsn;
                pNewPacket->pfnQueueFunction = QueueNBPacketForSend;
                pNewPacket->pfnCopyTranportToken = CopyNBTransportToken;
                pNewPacket->pfnDeleteTransportToken = DeleteNBTransportToken;
                //pNewPacket->pfnGetSocketName = NB_GetSocketName;
                pNewPacket->dwDelayBeforeSending = 0;
        #ifdef DEBUG
                pNewPacket->uiPacketNumber = InterlockedIncrement(&SMB_Globals::g_PacketID);
        #endif

                TRACEMSG(ZONE_TCPIP, (L"SMBSRV-NBRECV: sending out connection dropped for %d", pNewPacket->ulConnectionID));

                //
                // And remove this guy from out outstanding list
                csLock.Lock();
                ce::list<ULONG>::iterator it = pNode->OutStandingConnectionIDs.begin();
                while(it != pNode->OutStandingConnectionIDs.end()) {
                    if(pNewPacket->ulConnectionID == (*it)) {
                        pNode->OutStandingConnectionIDs.erase(it);
                        break;
                    }
                    it++;
                }
                csLock.UnLock();

                //hand off the packet to the SMB cracker
                if(FAILED(CrackPacket(pNewPacket))) {
                    //this should *NEVER* happen... Crack should handle its own errors
                    //  and when there is one it should return back an error code to the client
                    TRACEMSG(ZONE_ERROR, (L"SMBSRV-NBRECV: UNEXPECTED ERROR IN CRACK()!"));
                    ASSERT(FALSE);
                    hr = E_UNEXPECTED;
                    goto Done;
                } else {
                    pNewPacket = NULL;
                }
            }

            //
            // If the lana is bad, exit out to prevent spining
            if(TRUE == fBadLana) {
                CCritSection csLockStack(&csAdapterStackList);
                csLockStack.Lock();
                if(!NBAdapterDeleteStack.push_back(pAdapter)) {
                    hr = E_OUTOFMEMORY;
                }
                goto Done;
            }

            //
            // We need to go away now
            break;
        }
    }

    hr = S_OK;
    Done:
        TRACEMSG(ZONE_NETBIOS, (L"SMBSRV-NBRECV:Exiting thread!"));

        //
        // Drop any connections that might be outstanding
        csLock.Lock();
        while(pNode->OutStandingConnectionIDs.size()) {
            //
            // Purge out the cracker
            if(NULL == (pNewPacket = SMB_Globals::g_SMB_Pool.Alloc())) {
                hr = E_OUTOFMEMORY;
                goto Done;
            }

            if(NULL != pNewPacket) {
                memset(pNewPacket, 0, sizeof(SMB_PACKET));
                pNewPacket->uiPacketType = SMB_CONNECTION_DROPPED;
                pNewPacket->ulConnectionID = (pNode->OutStandingConnectionIDs.front());
                pNewPacket->pfnQueueFunction = QueueNBPacketForSend;
                pNewPacket->pfnCopyTranportToken = CopyNBTransportToken;
                pNewPacket->pfnDeleteTransportToken = DeleteNBTransportToken;
                //pNewPacket->pfnGetSocketName = NB_GetSocketName;
                pNewPacket->dwDelayBeforeSending = 0;
        #ifdef DEBUG
                pNewPacket->uiPacketNumber = InterlockedIncrement(&SMB_Globals::g_PacketID);
        #endif

                TRACEMSG(ZONE_TCPIP, (L"SMBSRV-NBRECV: sending out connection dropped for %d", pNewPacket->ulConnectionID));

                //hand off the packet to the SMB cracker
                if(FAILED(CrackPacket(pNewPacket))) {
                    //this should *NEVER* happen... Crack should handle its own errors
                    //  and when there is one it should return back an error code to the client
                    TRACEMSG(ZONE_ERROR, (L"SMBSRV-NBRECV: UNEXPECTED ERROR IN CRACK()!"));
                    ASSERT(FALSE);
                    hr = E_UNEXPECTED;
                    break;
                } else {
                    pNewPacket = NULL;
               }
            }
            pNode->OutStandingConnectionIDs.pop_front();
        }
        csLock.UnLock();

        if(pNewPacket) {
            SMB_Globals::g_SMB_Pool.Free(pNewPacket);
        }
        if(pSendNCB) {
            pSendNCB->Release();
        }
        if(pMainNCB) {
            pMainNCB->Release();
        }


        //
        // Remove ourself from the active list
        csLock.Lock();
        ce::list<RecvNode, NETBIOS_CONNECTION_ALLOC >::iterator it;
        ce::list<RecvNode, NETBIOS_CONNECTION_ALLOC >::iterator itEnd = ActiveRecvList.end();
        for(it = ActiveRecvList.begin(); it != itEnd; it++) {
            if((*it).MyHandle == pNode->MyHandle) {
               ActiveRecvList.erase(it);
               break;
            }
        }

        return FAILED(hr) ? -1 : 0;
}


HRESULT NB_GetSocketName(SMB_PACKET *pPacket, struct sockaddr *pSockAddr, int *pNameLen)

{
   /* ncb *pNCB = NULL;
    NCB newncb;
    HRESULT hr = E_FAIL;

    //
    // If the connection has dropped delete memory
    if(SMB_CONNECTION_DROPPED == pPacket->uiPacketType) {
        TRACEMSG(ZONE_SMB, (L"NETBIOS: connection dropped packet -- deleting memory"));
        hr = S_OK;
        goto Done;
    }

    //
    // They (the cracker)must send us a packet!
    if(NULL == pPacket) {
        ASSERT(FALSE);
        hr = E_UNEXPECTED;
        goto Done;
    }

    //
    //  get a pointer to the NCB... this is our 'token'
    if(NULL == (pNCB = (ncb *)(pPacket->pToken))) {
        //
        // If this happens, we were given a bad token... memory corruption?
        ASSERT(FALSE);
        hr = E_UNEXPECTED;
        goto Done;
    }


    newncb.LSN = pNCB->ncb_lsn;
    newncb.LanaNum = pNCB->ncb_lana_num;

    DWORD dwLen = *pNameLen;
    if(NETbiosThunk(0, NB_GET_SOCKADDR, &newncb, NULL, (BYTE*)pSockAddr, 0, &dwLen)) {
        hr = S_OK;
    }
    IFDBG(else {ASSERT(FALSE);});
    *pNameLen = dwLen;


    Done:
        return hr;*/
    return E_FAIL;
}



HRESULT
NETBIOS_TRANSPORT::QueueNBPacketForSend(SMB_PACKET *pPacket, BOOL fDestruct)
{
    ref_ncb *pNCB = NULL;
    HRESULT hr = E_FAIL;
    UCHAR ncb_err;
    CCritSection csLock(&csSendLock);
    csLock.Lock();
    PREFAST_ASSERT(pPacket);

    if(pPacket) {
        pNCB = (ref_ncb *)(pPacket->pToken);
    }

    //
    // If the connection has dropped delete memory
    if(SMB_NORMAL_PACKET != pPacket->uiPacketType) {
        TRACEMSG(ZONE_SMB, (L"NETBIOS: connection dropped packet -- deleting memory"));
        hr = S_OK;
        goto Done;
    }

    //
    // They (the cracker)must send us a packet!
    if(!pPacket) {
        ASSERT(FALSE);
        hr = E_UNEXPECTED;
        goto Done;
    }
    //
    //  get a pointer to the NCB... this is our 'token'
    if(!pNCB) {
        //
        // If this happens, we were given a bad token... memory corruption?
        ASSERT(FALSE);
        hr = E_UNEXPECTED;
        goto Done;
    }

    //
    pNCB->m_ncb.ncb_command = NCBSEND;
    pNCB->m_ncb.ncb_buffer = (BYTE *)pPacket->pOutSMB;
    pNCB->m_ncb.ncb_length = pPacket->uiOutSize;
    //

    // If we have been shut down dont send out the packet (see table at top for
    //    meanings for g_fIsAccepting
    if(FALSE == g_fIsAccepting) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV-NBSEND: we have shut down -- not sending packet"));
        hr = E_FAIL;
        goto Done;
    }

    ncb_err = Netbios(&(pNCB->m_ncb));
    if(!ncb_err) {
        TRACEMSG(ZONE_NETBIOS, (TEXT("SMBSRV-NBSEND: sent packet!")));
    } else {
       TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-NBRECV: Error sending packet! (%s)"),NETBIOS_TRANSPORT::NCBError(ncb_err)));
       hr = E_UNEXPECTED;
       goto Done;
    }

    hr = S_OK;
    Done:
        ASSERT(pPacket);
#ifdef DEBUG
         ASSERT(TRUE == Cracker::g_fIsRunning);
         if(TRUE == Cracker::g_fIsRunning && SMB_NORMAL_PACKET == pPacket->uiPacketType && pPacket->pInSMB) {
             UCHAR SMB = pPacket->pInSMB->Command;
             pPacket->PerfStopTimer(SMB);
             DWORD dwProcessing = pPacket->TimeProcessing();
             CCritSection csLockPerf(&Cracker::g_csPerfLock);
             csLockPerf.Lock();
                double dwNew = (Cracker::g_dblPerfAvePacketTime[SMB] * Cracker::g_dwPerfPacketsProcessed[SMB]);
                Cracker::g_dwPerfPacketsProcessed[SMB] ++;
                dwNew += dwProcessing;
                dwNew /= Cracker::g_dwPerfPacketsProcessed[SMB];
                Cracker::g_dblPerfAvePacketTime[SMB] = dwNew;
             csLockPerf.UnLock();
         }
#endif
        if(TRUE == fDestruct) {
            if(pNCB) {
                pNCB->Release();
            }
            if(NULL != pPacket) {
                SMB_Globals::g_SMB_Pool.Free(pPacket);
            }
        }
        return hr;
}

⌨️ 快捷键说明

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