📄 connectionmanager.cpp
字号:
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 + -