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

📄 connectionmanager.cpp

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


struct IDLE_LIST {
    ULONG ulConnectionID;
    DWORD dwLastUsed;
    ActiveConnection *pConn;
};

ULONG 
ConnectionManager::FindStaleConnection(DWORD dwIdleTime)
{   
    CCritSection csLock(&m_MyCS);
    csLock.Lock();
    
    ActiveConnection *pAC = NULL;
    ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator it;
    ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator itEnd = m_MyConnections.end(); 
    ce::list<IDLE_LIST> idleList;
    ce::list<IDLE_LIST>::iterator itIdleList;
    IDLE_LIST *pThis = NULL;
    PREFAST_ASSERT(pThis);
    
    DWORD dwNow = GetTickCount();
    
    for(it=m_MyConnections.begin(); it!=itEnd; it++) {  
        pAC = *it;
        pThis = NULL;
        //
        // Seek out this connection ID
        for(itIdleList=idleList.begin(); itIdleList!=idleList.end(); itIdleList++) {
            if((*itIdleList).ulConnectionID == pAC->ConnectionID()) {
                pThis = &(*itIdleList);
            }
        }

        //
        // If its a new node, add it
        if(NULL == pThis) {       
            ce::list<IDLE_LIST>::iterator itIdle;
            if(idleList.end() == (itIdle = idleList.insert(idleList.begin()))) {
                return 0xFFFFFFFF;
            }
            itIdle->ulConnectionID = pAC->ConnectionID();
            itIdle->dwLastUsed = pAC->m_dwLastUsed;
            itIdle->pConn = pAC;
            
            pThis = &(*itIdle);
            
            ASSERT(pThis->ulConnectionID == pAC->ConnectionID());
            ASSERT(pThis->dwLastUsed == pAC->m_dwLastUsed);
        }
        ASSERT(NULL != pThis);
        ASSERT(pAC->ConnectionID() == pThis->ulConnectionID);

        //
        // If this current connection has been active more recently than the one in the
        //   list, update the list
        if(dwNow-pAC->m_dwLastUsed <= dwNow-pThis->dwLastUsed) {
            pThis->dwLastUsed = pAC->m_dwLastUsed;
            pThis->pConn = pAC;
        }        
    }   

    //
    // Now we have a list of the most recently used connections (and each 
    //    connection is only represented once) find the one that was used
    //    the longest ago -- connections that are in use are off limits
    pThis = NULL;
    if(idleList.size()) {
        pThis = &(*idleList.begin());
        
        for(itIdleList=idleList.begin(); itIdleList!=idleList.end(); itIdleList++) {
           if(!itIdleList->pConn->HasOpenedResources() && (dwNow - pThis->dwLastUsed <= dwNow - (*itIdleList).dwLastUsed)) {
                pThis = &(*itIdleList);
           }
        }
    }

    if(pThis && (dwNow - pThis->dwLastUsed) >= dwIdleTime) {
       return pThis->ulConnectionID;
    } else {
        return 0xFFFFFFFF;
    }
}



HRESULT 
ConnectionManager::AddConnection(SMB_PACKET *pSMB)
{
  CCritSection csLock(&m_MyCS);  
  csLock.Lock();
  USHORT usUid;
  HRESULT hr;
  BOOL fNewConnection = TRUE;
  
  //
  // Check to see if we could be getting hacked
  if(NumGuests() > MAX_NUM_GUESTS) {
        RETAILMSG(1, (L"SMBSRV: we have too many guest users... someone probably is trying to DoS us"));
        ASSERT(FALSE); //<-- we could remove this ASSERT if its a prob for test (if DoS tests are made), its just here to make
                       //   sure we dont hide a problem if one exists 
        hr = E_UNEXPECTED;
        goto Done;
  }
  
  //
  // Get a unique UID for them
  if(FAILED(m_UIDGenerator.GetID(&usUid))) {
      ASSERT(FALSE);
      hr = E_UNEXPECTED;
      goto Done;
  }
  
  //
  // Zero is a special number of UID -- dont give it out
  if(0 == usUid) {
      m_fZeroUIDTaken = TRUE;
      if(FAILED(m_UIDGenerator.GetID(&usUid))) {
           ASSERT(FALSE);
           hr = E_UNEXPECTED;
           goto Done;
       }
  }
  pSMB->pInSMB->Uid = usUid;
  
  //
  // Be super sure that we dont have multiple instances of this connection
  //   if we do, blast the old one
  hr = RemoveConnection(pSMB->ulConnectionID, usUid);
  ASSERT(FAILED(hr));  

  m_MyConnections.push_front(new ActiveConnection);
  ((m_MyConnections.front()))->SetConnectionInfo(pSMB->ulConnectionID, usUid);

  hr = S_OK;
  
  Done:
    return hr;  
}


//
// Return the # of active connections (there could be multiple SESSIONS on ONE connection)
UINT 
ConnectionManager::NumConnections(UINT uiExemptConnection) 
{
    CCritSection csLock(&m_MyCS);
    csLock.Lock();
    
    ce::list<UINT> ConnList;
    ce::list<UINT>::iterator itConnList;
    ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator itAC;
    
    //
    // Count the # of unique connections
    for(itAC=m_MyConnections.begin(); itAC!=m_MyConnections.end(); ++itAC) {
        BOOL fInList = FALSE;
        for(itConnList=ConnList.begin(); itConnList!=ConnList.end(); ++itConnList) {
            if((*itAC)->ConnectionID() == (*itConnList)) { 
                fInList = TRUE;
                break;
            }      
        }
        if(!fInList && (*itAC)->ConnectionID() != uiExemptConnection) {
            if(!ConnList.push_back((*itAC)->ConnectionID())) {
                goto Done;
            }
        }
    }

    Done:
        return ConnList.size();
}

UINT 
ConnectionManager::NumGuests()
{
    CCritSection csLock(&m_MyCS);
    csLock.Lock();
    
    ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator it;
    UINT uiGuests = 0;
    
    for(it=m_MyConnections.begin(); it!=m_MyConnections.end(); it++) {
        if((*it)->IsGuest()) { 
            uiGuests ++;
        }
    }
    return uiGuests;
}

HRESULT 
ConnectionManager::TerminateTIDsOnShare(Share *pShare)
{
    CCritSection csLock(&m_MyCS);
    csLock.Lock();
    
    ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator it;    
    HRESULT hr = S_OK;
    for(it=m_MyConnections.begin(); it!=m_MyConnections.end(); it++) {
        if(FAILED(hr = (*it)->TerminateConnectionsForShare(pShare))) {
            goto Done;
        }
    }
    Done:
        return hr;
}


HRESULT 
ConnectionManager::RemoveConnection(ULONG ulConnectionID, USHORT usUid)
{  
    HRESULT hr = E_FAIL;
    CCritSection csLock(&m_MyCS);
    csLock.Lock();
   
    for(ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator it=m_MyConnections.begin(); it!=m_MyConnections.end(); ) {
      ActiveConnection *pAC = *it;
      
      if(0xFFFF == usUid &&  pAC->ConnectionID() == ulConnectionID) {
            TRACEMSG(ZONE_DETAIL, (L"SMB_SRV: Killing ALL connections on transport connection: 0x%x", ulConnectionID));
                 
            //
            // Give back the unique UID 
            m_UIDGenerator.RemoveID(pAC->Uid());            
            m_MyConnections.erase(it++);
            hr = S_OK;
      } 
      else if(pAC->ConnectionID() == ulConnectionID && pAC->Uid() == usUid) {
            TRACEMSG(ZONE_DETAIL, (L"SMB_SRV: Killing specific connection on transport connection: 0x%x", ulConnectionID));
            
            //
            // Give back the unique UID 
            m_UIDGenerator.RemoveID(pAC->Uid());            
            m_MyConnections.erase(it++);    
            hr = S_OK;
      } else {
            ++it;
      }
    }
    
    //
    // If usUid is 0xFFFF we are pulling the entire connection down
    //    so remove any CHALLENGE nodes
    if(0xFFFF == usUid) {
        hr = RemoveChallenge(ulConnectionID);
    }    
    return hr;       
}


HRESULT 
ConnectionManager::AddChallenge(ULONG ulConnectionID, BYTE *pChallenge)
{
    HRESULT hr;
    CCritSection csLock(&m_MyCS);
    OldChallengeNode newNode;
    newNode.ulConnectionID = ulConnectionID;
    memcpy(newNode.Challenge, pChallenge, sizeof(newNode.Challenge));
    
    if(FAILED(hr = RemoveChallenge(ulConnectionID))) {
        goto Done;
    }

    csLock.Lock();
    if(!m_OldChallengeList.push_front(newNode)) {
        hr = E_OUTOFMEMORY;
    } else {
        hr = S_OK;
    }
    
    Done:    
        return hr;
}

HRESULT 
ConnectionManager::RemoveChallenge(ULONG ulConnectionID)
{
    CCritSection csLock(&m_MyCS);
    csLock.Lock();
    
    ce::list<OldChallengeNode, OLD_CHALLENGE_ALLOC >::iterator  itChal = m_OldChallengeList.begin();
    IFDBG(UINT uiHits = 0);
    for(itChal = m_OldChallengeList.begin();
        itChal != m_OldChallengeList.end();) {
        
        if(ulConnectionID == (*itChal).ulConnectionID) {
            m_OldChallengeList.erase(itChal++);
            IFDBG(uiHits ++);
        } else {
            ++itChal;
        }
    }
    return S_OK;
}

HRESULT 
ConnectionManager::FindChallenge(ULONG ulConnectionID, BYTE **pChallenge)
{
    HRESULT hr = E_FAIL;
    CCritSection csLock(&m_MyCS);
    csLock.Lock();
    
    ce::list<OldChallengeNode, OLD_CHALLENGE_ALLOC >::iterator  itChal = m_OldChallengeList.begin();
    for(itChal = m_OldChallengeList.begin();
        itChal != m_OldChallengeList.end();) {
        
        if(ulConnectionID == (*itChal).ulConnectionID) {
            *pChallenge = (*itChal).Challenge;            
            hr = S_OK;
            break;
        } else {
            ++itChal;
        }
    }    
    ASSERT(SUCCEEDED(hr));
    return hr;
}



VOID
ConnectionManager::ListConnectedUsers(ce::wstring &sRet)
{
  CCritSection csLock(&m_MyCS);
  csLock.Lock();
  //ce::wstring sRet;

  ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator it;
  ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator itEnd = m_MyConnections.end();


  for(it = m_MyConnections.begin(); it != itEnd; it++) {
       sRet += (*it)->UserName();
       sRet.resize(sRet.length() + 1);
  }
  
  //return sRet;
}

#ifdef DEBUG
VOID
ConnectionManager::DebugPrint()
{
  HRESULT hr = E_FAIL;
  CCritSection csLock(&m_MyCS);
  csLock.Lock();

  ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator it;
  ce::list<ce::smart_ptr<ActiveConnection> , CONNECTION_MANAGER_CONNECTION_ALLOC >::iterator itEnd = m_MyConnections.end();


  for(it = m_MyConnections.begin(); it != itEnd; it++) {
       (*it)->DebugPrint();
  }
  
}
#endif

⌨️ 快捷键说明

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