BOOL CUpdateInfo::DeleteUpdate(CString hash) { uchar UpdateHash[16]; CPartFile* pPartFile; if(!strmd4(hash,UpdateHash)) { return FALSE; } CKnownFile* file = CGlobalVariable::sharedfiles->GetFileByID(UpdateHash); try { //共享列表中是否有 if(file) { if(file->IsPartFile()) { //共享列表有,但未下载完,移除 pPartFile = DYNAMIC_DOWNCAST(CPartFile,file); if( pPartFile ) { pPartFile->DeleteFile(); } } else { //共享列表有,已经下载完成未安装,移除 DeleteFile(file->GetFilePath()); theApp.emuledlg->sharedfileswnd->sharedfilesctrl.RemoveFile(file); CGlobalVariable::sharedfiles->RemoveFile(file); } } if ((pPartFile = CGlobalVariable::downloadqueue->GetFileByID(UpdateHash)) != NULL) { //共享列表没有,但未下载完,移除 pPartFile->DeleteFile(); } } catch (CException* e) { e->Delete(); return FALSE; } return FALSE; }
int CAICHSyncThread::Run() { if ( !theApp.emuledlg->IsRunning() ) return 0; // we collect all masterhashs which we find in the known2.met and store them in a list CList<CAICHHash> liKnown2Hashs; CString fullpath=thePrefs.GetConfigDir(); fullpath.Append(KNOWN2_MET_FILENAME); CSafeFile file; CFileException fexp; uint32 nLastVerifiedPos = 0; if (!file.Open(fullpath,CFile::modeCreate|CFile::modeReadWrite|CFile::modeNoTruncate|CFile::osSequentialScan|CFile::typeBinary|CFile::shareDenyNone, &fexp)){ if (fexp.m_cause != CFileException::fileNotFound){ CString strError(_T("Failed to load ") KNOWN2_MET_FILENAME _T(" file")); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){ strError += _T(" - "); strError += szError; } LogError(LOG_STATUSBAR, _T("%s"), strError); } return false; } try { //setvbuf(file.m_pStream, NULL, _IOFBF, 16384); uint32 nExistingSize = file.GetLength(); uint16 nHashCount; while (file.GetPosition() < nExistingSize){ liKnown2Hashs.AddTail(CAICHHash(&file)); nHashCount = file.ReadUInt16(); if (file.GetPosition() + nHashCount*HASHSIZE > nExistingSize){ AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); } // skip the rest of this hashset file.Seek(nHashCount*HASHSIZE, CFile::current); nLastVerifiedPos = file.GetPosition(); } } catch(CFileException* error){ if (error->m_cause == CFileException::endOfFile){ LogError(LOG_STATUSBAR,GetResString(IDS_ERR_SERVERMET_BAD)); // truncate the file to the size to the last verified valid pos try{ file.SetLength(nLastVerifiedPos); } catch(CFileException* error2){ error2->Delete(); } } else{ TCHAR buffer[MAX_CFEXP_ERRORMSG]; error->GetErrorMessage(buffer, ARRSIZE(buffer)); LogError(LOG_STATUSBAR,GetResString(IDS_ERR_SERVERMET_UNKNOWN),buffer); } error->Delete(); return false; } file.Close(); // now we check that all files which are in the sharedfilelist have a corresponding hash in out list // those how don'T are added to the hashinglist for (uint32 i = 0; i < theApp.sharedfiles->GetCount(); i++){ CKnownFile* pCurFile = theApp.sharedfiles->GetFileByIndex(i); if (pCurFile != NULL && !pCurFile->IsPartFile() ){ if (theApp.emuledlg==NULL || !theApp.emuledlg->IsRunning()) // in case of shutdown while still hashing return 0; if (pCurFile->GetAICHHashset()->GetStatus() == AICH_HASHSETCOMPLETE){ bool bFound = false; for (POSITION pos = liKnown2Hashs.GetHeadPosition();pos != 0;) { if (liKnown2Hashs.GetNext(pos) == pCurFile->GetAICHHashset()->GetMasterHash()){ bFound = true; #ifdef _DEBUG // in debugmode we load and verify all hashsets ASSERT( pCurFile->GetAICHHashset()->LoadHashSet() ); // pCurFile->GetAICHHashset()->DbgTest(); pCurFile->GetAICHHashset()->FreeHashSet(); #endif break; } } if (bFound) // hashset is available, everything fine with this file continue; } pCurFile->GetAICHHashset()->SetStatus(AICH_ERROR); m_liToHash.AddTail(pCurFile); } } // warn the user if he just upgraded if (thePrefs.IsFirstStart() && !m_liToHash.IsEmpty()){ LogWarning(GetResString(IDS_AICH_WARNUSER)); } if (!m_liToHash.IsEmpty()){ AddLogLine(true, GetResString(IDS_AICH_SYNCTOTAL), m_liToHash.GetCount() ); // I18n: ThreadSafeLog theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(m_liToHash.GetCount()); // let first all normal hashing be done before starting out synchashing CSingleLock sLock1(&theApp.hashing_mut); // only one filehash at a time while (theApp.sharedfiles->GetHashingCount() != 0){ Sleep(100); } sLock1.Lock(); uint32 cDone = 0; for (POSITION pos = m_liToHash.GetHeadPosition();pos != 0; cDone++) { if (theApp.emuledlg==NULL || !theApp.emuledlg->IsRunning()){ // in case of shutdown while still hashing return 0; } theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(m_liToHash.GetCount()-cDone); if (theApp.emuledlg->sharedfileswnd->sharedfilesctrl.m_hWnd != NULL) theApp.emuledlg->sharedfileswnd->sharedfilesctrl.ShowFilesCount(); CKnownFile* pCurFile = m_liToHash.GetNext(pos); // just to be sure that the file hasnt been deleted lately if (!(theApp.knownfiles->IsKnownFile(pCurFile) && theApp.sharedfiles->GetFileByID(pCurFile->GetFileHash())) ) continue; AddLogLine(false, GetResString(IDS_AICH_CALCFILE), pCurFile->GetFileName()); // I18n: ThreadSafeLog if(!pCurFile->CreateAICHHashSetOnly()) // [TPT] - WebCache if(thePrefs.GetLogICHEvents()) //JP log ICH events AddDebugLogLine(false, _T("Failed to create AICH Hashset while sync. for file %s"), pCurFile->GetFileName()); // I18n: ThreadSafeLog } theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(0); if (theApp.emuledlg->sharedfileswnd->sharedfilesctrl.m_hWnd != NULL) theApp.emuledlg->sharedfileswnd->sharedfilesctrl.ShowFilesCount(); sLock1.Unlock(); } // [TPT] - WebCache if(thePrefs.GetLogICHEvents()) //JP log ICH events AddDebugLogLine(false, _T("AICHSyncThread finished")); // I18n: ThreadSafeLog return 0; }
void CSharedFilesCtrl::OnDrawItem( int item, wxDC* dc, const wxRect& rect, const wxRect& rectHL, bool highlighted ) { CKnownFile *file = (CKnownFile*)GetItemData(item); wxASSERT( file ); if ( highlighted ) { CMuleColour newcol(GetFocus() ? wxSYS_COLOUR_HIGHLIGHT : wxSYS_COLOUR_BTNSHADOW); dc->SetBackground(newcol.Blend(125).GetBrush()); dc->SetTextForeground( CMuleColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); // The second blending goes over the first one. dc->SetPen(newcol.Blend(65).GetPen()); } else { dc->SetBackground( CMuleColour(wxSYS_COLOUR_LISTBOX).GetBrush() ); dc->SetTextForeground(CMuleColour(wxSYS_COLOUR_WINDOWTEXT)); dc->SetPen(*wxTRANSPARENT_PEN); } dc->SetBrush(dc->GetBackground()); dc->DrawRectangle(rectHL); dc->SetPen(*wxTRANSPARENT_PEN); // Offset based on the height of the fonts const int textVOffset = ( rect.GetHeight() - dc->GetCharHeight() ) / 2; // Empty space to each side of a column const int SPARE_PIXELS_HORZ = 4; // The leftmost position of the current column int columnLeft = 0; for ( int i = 0; i < GetColumnCount(); ++i ) { const int columnWidth = GetColumnWidth(i); if (columnWidth > 2*SPARE_PIXELS_HORZ) { wxRect columnRect( columnLeft + SPARE_PIXELS_HORZ, rect.y, columnWidth - 2 * SPARE_PIXELS_HORZ, rect.height); wxDCClipper clipper(*dc, columnRect); wxString textBuffer; switch ( i ) { case ID_SHARED_COL_NAME: textBuffer = file->GetFileName().GetPrintable(); if (file->GetFileRating() || file->GetFileComment().Length()) { int image = Client_CommentOnly_Smiley; if (file->GetFileRating()) { image = Client_InvalidRating_Smiley + file->GetFileRating() - 1; } wxASSERT(image >= Client_InvalidRating_Smiley); wxASSERT(image <= Client_CommentOnly_Smiley); int imgWidth = 16; theApp->amuledlg->m_imagelist.Draw(image, *dc, columnRect.x, columnRect.y + 1, wxIMAGELIST_DRAW_TRANSPARENT); // Move the text to the right columnRect.x += (imgWidth + 4); } break; case ID_SHARED_COL_SIZE: textBuffer = CastItoXBytes(file->GetFileSize()); break; case ID_SHARED_COL_TYPE: textBuffer = GetFiletypeByName(file->GetFileName()); break; case ID_SHARED_COL_PRIO: textBuffer = PriorityToStr(file->GetUpPriority(), file->IsAutoUpPriority()); break; case ID_SHARED_COL_ID: textBuffer = file->GetFileHash().Encode(); break; case ID_SHARED_COL_REQ: textBuffer = CFormat(wxT("%u (%u)")) % file->statistic.GetRequests() % file->statistic.GetAllTimeRequests(); break; case ID_SHARED_COL_AREQ: textBuffer = CFormat(wxT("%u (%u)")) % file->statistic.GetAccepts() % file->statistic.GetAllTimeAccepts(); break; case ID_SHARED_COL_TRA: textBuffer = CastItoXBytes(file->statistic.GetTransferred()) + wxT(" (") + CastItoXBytes(file->statistic.GetAllTimeTransferred()) + wxT(")"); break; case ID_SHARED_COL_RTIO: textBuffer = CFormat(wxT("%.2f")) % ((double)file->statistic.GetAllTimeTransferred() / file->GetFileSize()); break; case ID_SHARED_COL_PART: if ( file->GetPartCount() ) { wxRect barRect(columnRect.x, columnRect. y + 1, columnRect.width, columnRect.height - 2); DrawAvailabilityBar(file, dc, barRect); } break; case ID_SHARED_COL_CMPL: if ( file->m_nCompleteSourcesCountLo == 0 ) { if ( file->m_nCompleteSourcesCountHi ) { textBuffer = CFormat(wxT("< %u")) % file->m_nCompleteSourcesCountHi; } else { textBuffer = wxT("0"); } } else if (file->m_nCompleteSourcesCountLo == file->m_nCompleteSourcesCountHi) { textBuffer = CFormat(wxT("%u")) % file->m_nCompleteSourcesCountLo; } else { textBuffer = CFormat(wxT("%u - %u")) % file->m_nCompleteSourcesCountLo % file->m_nCompleteSourcesCountHi; } break; case ID_SHARED_COL_PATH: if ( file->IsPartFile() ) { textBuffer = _("[PartFile]"); } else { textBuffer = file->GetFilePath().GetPrintable(); } } if (!textBuffer.IsEmpty()) { dc->DrawText(textBuffer, columnRect.x, columnRect.y + textVOffset); } } // Move to the next column columnLeft += columnWidth; } }
BOOL CUpdateInfo::ClearUpdateHistory(const uchar * hashkey)//清除历史升级任务 { for (int i = 0; i < CGlobalVariable::sharedfiles->GetCount(); i++) { CKnownFile* file = CGlobalVariable::sharedfiles->GetFileByIndex(i); CPartFile* pPartFile; try { //共享列表中是否有 if(file) { if ( IsUpdateTask( file->GetFilePath() ) && file->GetFileHash() != hashkey ) { if(file->IsPartFile()) { //共享列表有,但未下载完,移除 pPartFile = DYNAMIC_DOWNCAST(CPartFile,file); if( pPartFile ) { pPartFile->DeleteFile(); } } else { //共享列表有,已经下载完成未安装,移除 DeleteFile(file->GetFilePath()); theApp.emuledlg->sharedfileswnd->sharedfilesctrl.RemoveFile(file); CGlobalVariable::sharedfiles->RemoveFile(file); CGlobalVariable::filemgr.RemoveFileItem(file); } } else continue; } } catch (CException* e) { e->Delete(); //return FALSE; } } for (int i = 0; i < CGlobalVariable::downloadqueue->GetFileCount(); i++) { CPartFile* pFile = CGlobalVariable::downloadqueue->GetFileByIndex(i); try { if (pFile) { if ( IsUpdateTask( pFile->GetFilePath() ) && pFile->GetFileHash() != hashkey ) { //共享列表没有,但未下载完,移除 pFile->DeleteFile(); } } } catch (CException* e) { e->Delete(); //return FALSE; } } return TRUE; }
int CAICHSyncThread::Run() { if ( !theApp.emuledlg->IsRunning() ) return 0; // we need to keep a lock on this file while the thread is running CSingleLock lockKnown2Met(&CAICHHashSet::m_mutKnown2File); lockKnown2Met.Lock(); // we collect all masterhashs which we find in the known2.met and store them in a list CList<CAICHHash> liKnown2Hashs; CString fullpath=thePrefs.GetConfigDir(); fullpath.Append(KNOWN2_MET_FILENAME); CSafeFile file; CFileException fexp; uint32 nLastVerifiedPos = 0; if (!file.Open(fullpath,CFile::modeCreate|CFile::modeReadWrite|CFile::modeNoTruncate|CFile::osSequentialScan|CFile::typeBinary|CFile::shareDenyNone, &fexp)){ if (fexp.m_cause != CFileException::fileNotFound){ CString strError(_T("Failed to load ") KNOWN2_MET_FILENAME _T(" file")); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){ strError += _T(" - "); strError += szError; } LogError(LOG_STATUSBAR, _T("%s"), strError); } return false; } try { //setvbuf(file.m_pStream, NULL, _IOFBF, 16384); uint32 nExistingSize = (UINT)file.GetLength(); uint16 nHashCount; while (file.GetPosition() < nExistingSize){ liKnown2Hashs.AddTail(CAICHHash(&file)); nHashCount = file.ReadUInt16(); if (file.GetPosition() + nHashCount*CAICHHash::GetHashSize() > nExistingSize){ AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); } // skip the rest of this hashset file.Seek(nHashCount*CAICHHash::GetHashSize(), CFile::current); nLastVerifiedPos = (UINT)file.GetPosition(); } } catch(CFileException* error){ if (error->m_cause == CFileException::endOfFile){ LogError(LOG_STATUSBAR,GetResString(IDS_ERR_SERVERMET_BAD)); // truncate the file to the size to the last verified valid pos try{ file.SetLength(nLastVerifiedPos); } catch(CFileException* error2){ error2->Delete(); } } else{ TCHAR buffer[MAX_CFEXP_ERRORMSG]; error->GetErrorMessage(buffer, ARRSIZE(buffer)); LogError(LOG_STATUSBAR,GetResString(IDS_ERR_SERVERMET_UNKNOWN),buffer); } error->Delete(); return false; } // now we check that all files which are in the sharedfilelist have a corresponding hash in out list // those how don'T are added to the hashinglist CList<CAICHHash> liUsedHashs; CSingleLock sharelock(&theApp.sharedfiles->m_mutWriteList); sharelock.Lock(); for (uint32 i = 0; i < theApp.sharedfiles->GetCount(); i++){ CKnownFile* pCurFile = theApp.sharedfiles->GetFileByIndex(i); if (pCurFile != NULL && !pCurFile->IsPartFile() ){ if (theApp.emuledlg==NULL || !theApp.emuledlg->IsRunning()) // in case of shutdown while still hashing return 0; if (pCurFile->GetAICHHashset()->GetStatus() == AICH_HASHSETCOMPLETE){ bool bFound = false; for (POSITION pos = liKnown2Hashs.GetHeadPosition();pos != 0;) { CAICHHash current_hash = liKnown2Hashs.GetNext(pos); if (current_hash == pCurFile->GetAICHHashset()->GetMasterHash()){ bFound = true; liUsedHashs.AddTail(current_hash); //theApp.QueueDebugLogLine(false, _T("%s - %s"), current_hash.GetString(), pCurFile->GetFileName()); #ifdef _DEBUG // in debugmode we load and verify all hashsets ASSERT( pCurFile->GetAICHHashset()->LoadHashSet() ); // pCurFile->GetAICHHashset()->DbgTest(); pCurFile->GetAICHHashset()->FreeHashSet(); #endif break; } } if (bFound) // hashset is available, everything fine with this file continue; } pCurFile->GetAICHHashset()->SetStatus(AICH_ERROR); m_liToHash.AddTail(pCurFile); } } sharelock.Unlock(); // removed all unused AICH hashsets from known2.met if (!thePrefs.IsRememberingDownloadedFiles() && liUsedHashs.GetCount() != liKnown2Hashs.GetCount()){ file.SeekToBegin(); try { uint32 nExistingSize = (UINT)file.GetLength(); uint16 nHashCount; ULONGLONG posWritePos = 0; ULONGLONG posReadPos = 0; uint32 nPurgeCount = 0; while (file.GetPosition() < nExistingSize){ CAICHHash aichHash(&file); nHashCount = file.ReadUInt16(); if (file.GetPosition() + nHashCount*CAICHHash::GetHashSize() > nExistingSize){ AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); } if (liUsedHashs.Find(aichHash) == NULL){ // unused hashset skip the rest of this hashset file.Seek(nHashCount*CAICHHash::GetHashSize(), CFile::current); nPurgeCount++; } else if(nPurgeCount == 0){ // used Hashset, but it does not need to be moved as nothing changed yet file.Seek(nHashCount*CAICHHash::GetHashSize(), CFile::current); posWritePos = file.GetPosition(); } else{ // used Hashset, move position in file BYTE* buffer = new BYTE[nHashCount*CAICHHash::GetHashSize()]; file.Read(buffer, nHashCount*CAICHHash::GetHashSize()); posReadPos = file.GetPosition(); file.Seek(posWritePos, CFile::begin); file.Write(aichHash.GetRawHash(), CAICHHash::GetHashSize()); file.WriteUInt16(nHashCount); file.Write(buffer, nHashCount*CAICHHash::GetHashSize()); delete[] buffer; posWritePos = file.GetPosition(); file.Seek(posReadPos, CFile::begin); } } posReadPos = file.GetPosition(); file.SetLength(posWritePos); theApp.QueueDebugLogLine(false, _T("Cleaned up known2.met, removed %u hashsets (%s)"), nPurgeCount, CastItoXBytes(posReadPos-posWritePos)); file.Flush(); file.Close(); } catch(CFileException* error){ if (error->m_cause == CFileException::endOfFile){ // we just parsed this files some ms ago, should never happen here ASSERT( false ); } else{ TCHAR buffer[MAX_CFEXP_ERRORMSG]; error->GetErrorMessage(buffer, ARRSIZE(buffer)); LogError(LOG_STATUSBAR,GetResString(IDS_ERR_SERVERMET_UNKNOWN),buffer); } error->Delete(); return false; } } lockKnown2Met.Unlock(); // warn the user if he just upgraded if (thePrefs.IsFirstStart() && !m_liToHash.IsEmpty()){ LogWarning(GetResString(IDS_AICH_WARNUSER)); } if (!m_liToHash.IsEmpty()){ theApp.QueueLogLine(true, GetResString(IDS_AICH_SYNCTOTAL), m_liToHash.GetCount() ); theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(m_liToHash.GetCount()); // let first all normal hashing be done before starting out synchashing CSingleLock sLock1(&theApp.hashing_mut); // only one filehash at a time while (theApp.sharedfiles->GetHashingCount() != 0){ Sleep(100); } sLock1.Lock(); uint32 cDone = 0; for (POSITION pos = m_liToHash.GetHeadPosition();pos != 0; cDone++) { if (theApp.emuledlg==NULL || !theApp.emuledlg->IsRunning()){ // in case of shutdown while still hashing return 0; } theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(m_liToHash.GetCount()-cDone); if (theApp.emuledlg->sharedfileswnd->sharedfilesctrl.m_hWnd != NULL) theApp.emuledlg->sharedfileswnd->sharedfilesctrl.ShowFilesCount(); CKnownFile* pCurFile = m_liToHash.GetNext(pos); // just to be sure that the file hasnt been deleted lately if (!(theApp.knownfiles->IsKnownFile(pCurFile) && theApp.sharedfiles->GetFileByID(pCurFile->GetFileHash())) ) continue; theApp.QueueLogLine(false, GetResString(IDS_AICH_CALCFILE), pCurFile->GetFileName()); if(!pCurFile->CreateAICHHashSetOnly()) theApp.QueueDebugLogLine(false, _T("Failed to create AICH Hashset while sync. for file %s"), pCurFile->GetFileName()); } theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(0); if (theApp.emuledlg->sharedfileswnd->sharedfilesctrl.m_hWnd != NULL) theApp.emuledlg->sharedfileswnd->sharedfilesctrl.ShowFilesCount(); sLock1.Unlock(); } theApp.QueueDebugLogLine(false, _T("AICHSyncThread finished")); return 0; }
bool CClientUDPSocket::ProcessPacket(const BYTE* packet, uint16 size, uint8 opcode, uint32 ip, uint16 port) { switch(opcode) { case OP_REASKCALLBACKUDP: { if (thePrefs.GetDebugClientUDPLevel() > 0) DebugRecv("OP_ReaskCallbackUDP", NULL, NULL, ip); theStats.AddDownDataOverheadOther(size); CUpDownClient* buddy = theApp.clientlist->GetBuddy(); if( buddy ) { if( size < 17 || buddy->socket == NULL ) break; if (!md4cmp(packet, buddy->GetBuddyID())) { PokeUInt32(const_cast<BYTE*>(packet)+10, ip); PokeUInt16(const_cast<BYTE*>(packet)+14, port); Packet* response = new Packet(OP_EMULEPROT); response->opcode = OP_REASKCALLBACKTCP; response->pBuffer = new char[size]; memcpy(response->pBuffer, packet+10, size-10); response->size = size-10; if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP__ReaskCallbackTCP", buddy); theStats.AddUpDataOverheadFileRequest(response->size); buddy->socket->SendPacket(response); } } break; } case OP_REASKFILEPING: { theStats.AddDownDataOverheadFileRequest(size); CSafeMemFile data_in(packet, size); uchar reqfilehash[16]; data_in.ReadHash16(reqfilehash); CKnownFile* reqfile = theApp.sharedfiles->GetFileByID(reqfilehash); if (!reqfile) { if (thePrefs.GetDebugClientUDPLevel() > 0) { DebugRecv("OP_ReaskFilePing", NULL, reqfilehash, ip); DebugSend("OP__FileNotFound", NULL); } Packet* response = new Packet(OP_FILENOTFOUND,0,OP_EMULEPROT); theStats.AddUpDataOverheadFileRequest(response->size); SendPacket(response, ip, port); break; } CUpDownClient* sender = theApp.uploadqueue->GetWaitingClientByIP_UDP(ip, port); if (sender) { if (thePrefs.GetDebugClientUDPLevel() > 0) DebugRecv("OP_ReaskFilePing", sender, reqfilehash); //Make sure we are still thinking about the same file if (md4cmp(reqfilehash, sender->GetUploadFileID()) == 0) { sender->AddAskedCount(); sender->SetLastUpRequest(); //I messed up when I first added extended info to UDP //I should have originally used the entire ProcessExtenedInfo the first time. //So now I am forced to check UDPVersion to see if we are sending all the extended info. //For now on, we should not have to change anything here if we change //anything to the extended info data as this will be taken care of in ProcessExtendedInfo() //Update extended info. if (sender->GetUDPVersion() > 3) { sender->ProcessExtendedInfo(&data_in, reqfile); } //Update our complete source counts. else if (sender->GetUDPVersion() > 2) { uint16 nCompleteCountLast= sender->GetUpCompleteSourcesCount(); uint16 nCompleteCountNew = data_in.ReadUInt16(); sender->SetUpCompleteSourcesCount(nCompleteCountNew); if (nCompleteCountLast != nCompleteCountNew) { reqfile->UpdatePartsInfo(); } } CSafeMemFile data_out(128); if(sender->GetUDPVersion() > 3) { if (reqfile->IsPartFile()) ((CPartFile*)reqfile)->WritePartStatus(&data_out); else data_out.WriteUInt16(0); } data_out.WriteUInt16(theApp.uploadqueue->GetWaitingPosition(sender)); if (thePrefs.GetDebugClientUDPLevel() > 0) DebugSend("OP__ReaskAck", sender); Packet* response = new Packet(&data_out, OP_EMULEPROT); response->opcode = OP_REASKACK; theStats.AddUpDataOverheadFileRequest(response->size); theApp.clientudp->SendPacket(response, ip, port); } else { DebugLogError(_T("Client UDP socket; ReaskFilePing; reqfile does not match")); TRACE(_T("reqfile: %s\n"), DbgGetFileInfo(reqfile->GetFileHash())); TRACE(_T("sender->GetRequestFile(): %s\n"), sender->GetRequestFile() ? DbgGetFileInfo(sender->GetRequestFile()->GetFileHash()) : _T("(null)")); } } else { if (thePrefs.GetDebugClientUDPLevel() > 0) DebugRecv("OP_ReaskFilePing", NULL, reqfilehash, ip); if (((uint32)theApp.uploadqueue->GetWaitingUserCount() + 50) > thePrefs.GetQueueSize()) { if (thePrefs.GetDebugClientUDPLevel() > 0) DebugSend("OP__QueueFull", NULL); Packet* response = new Packet(OP_QUEUEFULL,0,OP_EMULEPROT); theStats.AddUpDataOverheadFileRequest(response->size); SendPacket(response, ip, port); } } break; } case OP_QUEUEFULL: { theStats.AddDownDataOverheadFileRequest(size); CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port); if (thePrefs.GetDebugClientUDPLevel() > 0) DebugRecv("OP_QueueFull", sender, NULL, ip); if (sender){ sender->SetRemoteQueueFull(true); sender->UDPReaskACK(0); } break; } case OP_REASKACK: { theStats.AddDownDataOverheadFileRequest(size); CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port); if (thePrefs.GetDebugClientUDPLevel() > 0) DebugRecv("OP_ReaskAck", sender, NULL, ip); if (sender){ CSafeMemFile data_in(packet, size); if ( sender->GetUDPVersion() > 3 ) { sender->ProcessFileStatus(true, &data_in, sender->GetRequestFile()); } uint16 nRank = data_in.ReadUInt16(); sender->SetRemoteQueueFull(false); sender->UDPReaskACK(nRank); sender->AddAskedCountDown(); } break; } case OP_FILENOTFOUND: { theStats.AddDownDataOverheadFileRequest(size); CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port); if (thePrefs.GetDebugClientUDPLevel() > 0) DebugRecv("OP_FileNotFound", sender, NULL, ip); if (sender){ sender->UDPReaskFNF(); // may delete 'sender'! sender = NULL; } break; } case OP_PORTTEST: { if (thePrefs.GetDebugClientUDPLevel() > 0) DebugRecv("OP_PortTest", NULL, NULL, ip); theStats.AddDownDataOverheadOther(size); if (size == 1){ if (packet[0] == 0x12){ bool ret = theApp.listensocket->SendPortTestReply('1', true); AddDebugLogLine(true, _T("UDP Portcheck packet arrived - ACK sent back (status=%i)"), ret); } } break; } default: theStats.AddDownDataOverheadOther(size); if (thePrefs.GetDebugClientUDPLevel() > 0) { CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port); Debug(_T("Unknown client UDP packet: host=%s:%u (%s) opcode=0x%02x size=%u\n"), ipstr(ip), port, sender ? sender->DbgGetClientInfo() : _T(""), opcode, size); } return false; } return true; }
BOOL CSharedDirsTreeCtrl::OnCommand(WPARAM wParam, LPARAM lParam) { CTypedPtrList<CPtrList, CKnownFile*> selectedList; int iSelectedItems = m_pSharedFilesCtrl->GetItemCount(); for (int i = 0; i < iSelectedItems; i++) { selectedList.AddTail((CKnownFile*)m_pSharedFilesCtrl->GetItemData(i)); } CDirectoryItem* pSelectedDir = GetSelectedFilter(); // folder based if (pSelectedDir != NULL){ switch (wParam){ case MP_OPENFOLDER: if (pSelectedDir && pSelectedDir->m_eItemType == SDI_NO){ ShellExecute(NULL, _T("open"), pSelectedDir->m_strFullPath, NULL, NULL, SW_SHOW); } break; case MP_SHAREDIR: EditSharedDirectories(pSelectedDir, true, false); break; case MP_SHAREDIRSUB: EditSharedDirectories(pSelectedDir, true, true); break; case MP_UNSHAREDIR: EditSharedDirectories(pSelectedDir, false, false); break; case MP_UNSHAREDIRSUB: EditSharedDirectories(pSelectedDir, false, true); break; } } // file based if (selectedList.GetCount() > 0 && pSelectedDir != NULL) { CKnownFile* file = NULL; if (selectedList.GetCount() == 1) file = selectedList.GetHead(); switch (wParam){ case MP_GETED2KLINK:{ CString str; POSITION pos = selectedList.GetHeadPosition(); while (pos != NULL) { file = selectedList.GetNext(pos); if (!str.IsEmpty()) str += _T("\r\n"); str += CreateED2kLink(file); } theApp.CopyTextToClipboard(str); break; } // file operations case MP_REMOVE: case MPG_DELETE:{ if (IDNO == AfxMessageBox(GetResString(IDS_CONFIRM_FILEDELETE),MB_ICONWARNING | MB_ICONQUESTION | MB_DEFBUTTON2 | MB_YESNO)) return TRUE; m_pSharedFilesCtrl->SetRedraw(FALSE); bool bRemovedItems = false; while (!selectedList.IsEmpty()) { CKnownFile* myfile = selectedList.RemoveHead(); if (!myfile || myfile->IsPartFile()) continue; BOOL delsucc = FALSE; if (!PathFileExists(myfile->GetFilePath())) delsucc = TRUE; else{ // Delete if (!thePrefs.GetRemoveToBin()){ delsucc = DeleteFile(myfile->GetFilePath()); } else{ // delete to recycle bin :( TCHAR todel[MAX_PATH+1]; memset(todel, 0, sizeof todel); _tcsncpy(todel, myfile->GetFilePath(), ARRSIZE(todel)-2); SHFILEOPSTRUCT fp = {0}; fp.wFunc = FO_DELETE; fp.hwnd = theApp.emuledlg->m_hWnd; fp.pFrom = todel; fp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT;// | FOF_NOERRORUI delsucc = (SHFileOperation(&fp) == 0); } } if (delsucc){ theApp.sharedfiles->RemoveFile(myfile); bRemovedItems = true; if (myfile->IsKindOf(RUNTIME_CLASS(CPartFile))) theApp.emuledlg->transferwnd->downloadlistctrl.ClearCompleted(static_cast<CPartFile*>(myfile)); } else{ CString strError; strError.Format( GetResString(IDS_ERR_DELFILE) + _T("\r\n\r\n%s"), myfile->GetFilePath(), GetErrorMessage(GetLastError())); AfxMessageBox(strError); } } m_pSharedFilesCtrl->SetRedraw(TRUE); if (bRemovedItems) m_pSharedFilesCtrl->AutoSelectItem(); break; } case MP_CMT: ShowFileDialog(selectedList, IDD_COMMENT); break; case MPG_ALTENTER: case MP_DETAIL: ShowFileDialog(selectedList); break; case MP_SHOWED2KLINK: ShowFileDialog(selectedList, IDD_ED2KLINK); break; case MP_PRIOVERYLOW: case MP_PRIOLOW: case MP_PRIONORMAL: case MP_PRIOHIGH: case MP_PRIOVERYHIGH: case MP_PRIOAUTO: { POSITION pos = selectedList.GetHeadPosition(); while (pos != NULL) { CKnownFile* file = selectedList.GetNext(pos); switch (wParam) { case MP_PRIOVERYLOW: file->SetAutoUpPriority(false); file->SetUpPriority(PR_VERYLOW); m_pSharedFilesCtrl->UpdateFile(file); break; case MP_PRIOLOW: file->SetAutoUpPriority(false); file->SetUpPriority(PR_LOW); m_pSharedFilesCtrl->UpdateFile(file); break; case MP_PRIONORMAL: file->SetAutoUpPriority(false); file->SetUpPriority(PR_NORMAL); m_pSharedFilesCtrl->UpdateFile(file); break; case MP_PRIOHIGH: file->SetAutoUpPriority(false); file->SetUpPriority(PR_HIGH); m_pSharedFilesCtrl->UpdateFile(file); break; case MP_PRIOVERYHIGH: file->SetAutoUpPriority(false); file->SetUpPriority(PR_VERYHIGH); m_pSharedFilesCtrl->UpdateFile(file); break; case MP_PRIOAUTO: file->SetAutoUpPriority(true); file->UpdateAutoUpPriority(); m_pSharedFilesCtrl->UpdateFile(file); break; } } break; } default: if (wParam>=MP_WEBURL && wParam<=MP_WEBURL+256){ theWebServices.RunURL(file, wParam); } break; } } return TRUE; }
int CAICHSyncThread::Run() { //MORPH START SLUGFILLER: SafeHash CReadWriteLock lock(&theApp.m_threadlock); if (!lock.ReadLock(0)) return 0; // MORPH END SLUGFILLER: SafeHash if ( !theApp.emuledlg->IsRunning() ) return 0; // we need to keep a lock on this file while the thread is running CSingleLock lockKnown2Met(&CAICHRecoveryHashSet::m_mutKnown2File); lockKnown2Met.Lock(); CSafeFile file; bool bJustCreated = ConvertToKnown2ToKnown264(&file); // we collect all masterhashs which we find in the known2.met and store them in a list CList<CAICHHash> liKnown2Hashs; CString fullpath = thePrefs.GetMuleDirectory(EMULE_CONFIGDIR); fullpath.Append(KNOWN2_MET_FILENAME); CFileException fexp; uint32 nLastVerifiedPos = 0; if (!bJustCreated && !file.Open(fullpath,CFile::modeCreate|CFile::modeReadWrite|CFile::modeNoTruncate|CFile::osSequentialScan|CFile::typeBinary|CFile::shareDenyNone, &fexp)){ if (fexp.m_cause != CFileException::fileNotFound){ CString strError(_T("Failed to load ") KNOWN2_MET_FILENAME _T(" file")); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){ strError += _T(" - "); strError += szError; } LogError(LOG_STATUSBAR, _T("%s"), strError); } return false; } try { if (file.GetLength() >= 1){ uint8 header = file.ReadUInt8(); if (header != KNOWN2_MET_VERSION){ AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); } //setvbuf(file.m_pStream, NULL, _IOFBF, 16384); uint32 nExistingSize = (UINT)file.GetLength(); uint32 nHashCount; while (file.GetPosition() < nExistingSize){ liKnown2Hashs.AddTail(CAICHHash(&file)); nHashCount = file.ReadUInt32(); if (file.GetPosition() + nHashCount*CAICHHash::GetHashSize() > nExistingSize){ AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); } // skip the rest of this hashset file.Seek(nHashCount*CAICHHash::GetHashSize(), CFile::current); nLastVerifiedPos = (UINT)file.GetPosition(); } } else file.WriteUInt8(KNOWN2_MET_VERSION); } catch(CFileException* error){ if (error->m_cause == CFileException::endOfFile){ LogError(LOG_STATUSBAR,GetResString(IDS_ERR_MET_BAD), KNOWN2_MET_FILENAME); // truncate the file to the size to the last verified valid pos try{ file.SetLength(nLastVerifiedPos); if (file.GetLength() == 0){ file.SeekToBegin(); file.WriteUInt8(KNOWN2_MET_VERSION); } } catch(CFileException* error2){ error2->Delete(); } } else{ TCHAR buffer[MAX_CFEXP_ERRORMSG]; error->GetErrorMessage(buffer, ARRSIZE(buffer)); LogError(LOG_STATUSBAR,GetResString(IDS_ERR_SERVERMET_UNKNOWN),buffer); } error->Delete(); return false; } // now we check that all files which are in the sharedfilelist have a corresponding hash in out list // those who don'T are added to the hashinglist CList<CAICHHash> liUsedHashs; CSingleLock sharelock(&theApp.sharedfiles->m_mutWriteList); sharelock.Lock(); bool bDbgMsgCreatingPartHashs = true; for (int i = 0; i < theApp.sharedfiles->GetCount(); i++){ CKnownFile* pCurFile = theApp.sharedfiles->GetFileByIndex(i); if (pCurFile != NULL && !pCurFile->IsPartFile() ) { if (theApp.emuledlg==NULL || !theApp.emuledlg->IsRunning()) // in case of shutdown while still hashing return 0; if (pCurFile->GetFileIdentifier().HasAICHHash()){ bool bFound = false; for (POSITION pos = liKnown2Hashs.GetHeadPosition();pos != 0;) { CAICHHash current_hash = liKnown2Hashs.GetNext(pos); if (current_hash == pCurFile->GetFileIdentifier().GetAICHHash()){ bFound = true; liUsedHashs.AddTail(current_hash); pCurFile->SetAICHRecoverHashSetAvailable(true); // Has the file the proper AICH Parthashset? If not probably upgrading, create it if (!pCurFile->GetFileIdentifier().HasExpectedAICHHashCount()) { if (bDbgMsgCreatingPartHashs) { bDbgMsgCreatingPartHashs = false; DebugLogWarning(_T("Missing AICH Part Hashsets for known files - maybe upgrading from earlier version. Creating them out of full AICH Recovery Hashsets, shouldn't take too long")); } CAICHRecoveryHashSet tempHashSet(pCurFile, pCurFile->GetFileSize()); tempHashSet.SetMasterHash(pCurFile->GetFileIdentifier().GetAICHHash(), AICH_HASHSETCOMPLETE); if (!tempHashSet.LoadHashSet()) { ASSERT( false ); DebugLogError(_T("Failed to load full AICH Recovery Hashset - known2.met might be corrupt. Unable to create AICH Part Hashset - %s"), pCurFile->GetFileName()); } else { if (!pCurFile->GetFileIdentifier().SetAICHHashSet(tempHashSet)) { DebugLogError(_T("Failed to create AICH Part Hashset out of full AICH Recovery Hashset - %s"), pCurFile->GetFileName()); ASSERT( false ); } ASSERT(pCurFile->GetFileIdentifier().HasExpectedAICHHashCount()); } } //theApp.QueueDebugLogLine(false, _T("%s - %s"), current_hash.GetString(), pCurFile->GetFileName()); /*#ifdef _DEBUG // in debugmode we load and verify all hashsets CAICHRecoveryHashSet* pTempHashSet = new CAICHRecoveryHashSet(pCurFile); pTempHashSet->SetFileSize(pCurFile->GetFileSize()); pTempHashSet->SetMasterHash(pCurFile->GetFileIdentifier().GetAICHHash(), AICH_HASHSETCOMPLETE) ASSERT( pTempHashSet->LoadHashSet() ); delete pTempHashSet; #endif*/ break; } } if (bFound) // hashset is available, everything fine with this file continue; } pCurFile->SetAICHRecoverHashSetAvailable(false); m_liToHash.AddTail(pCurFile); } } sharelock.Unlock(); // removed all unused AICH hashsets from known2.met if (liUsedHashs.GetCount() != liKnown2Hashs.GetCount() && // EastShare START - Added by TAHO, .met file control /* (!thePrefs.IsRememberingDownloadedFiles() || thePrefs.DoPartiallyPurgeOldKnownFiles())) */ (!thePrefs.IsRememberingDownloadedFiles() || thePrefs.DoPartiallyPurgeOldKnownFiles() || thePrefs.DoCompletlyPurgeOldKnownFiles() || thePrefs.DoRemoveAichImmediatly() ) ) // EastShare END - Added by TAHO, .met file control { file.SeekToBegin(); try { uint8 header = file.ReadUInt8(); if (header != KNOWN2_MET_VERSION){ AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); } uint32 nExistingSize = (UINT)file.GetLength(); uint32 nHashCount; ULONGLONG posWritePos = file.GetPosition(); ULONGLONG posReadPos = file.GetPosition(); uint32 nPurgeCount = 0; uint32 nPurgeBecauseOld = 0; while (file.GetPosition() < nExistingSize){ CAICHHash aichHash(&file); nHashCount = file.ReadUInt32(); if (file.GetPosition() + nHashCount*CAICHHash::GetHashSize() > nExistingSize){ AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); } if (!thePrefs.IsRememberingDownloadedFiles() && liUsedHashs.Find(aichHash) == NULL) { // unused hashset skip the rest of this hashset file.Seek(nHashCount*CAICHHash::GetHashSize(), CFile::current); nPurgeCount++; } else if (thePrefs.IsRememberingDownloadedFiles() && theApp.knownfiles->ShouldPurgeAICHHashset(aichHash)) { // EastShare START - Added by TAHO, .met file control /* ASSERT( thePrefs.DoPartiallyPurgeOldKnownFiles() ); */ ASSERT( thePrefs.DoPartiallyPurgeOldKnownFiles() || thePrefs.DoRemoveAichImmediatly()); // EastShare END - Added by TAHO, .met file control // also unused (purged) hashset skip the rest of this hashset file.Seek(nHashCount*CAICHHash::GetHashSize(), CFile::current); nPurgeCount++; nPurgeBecauseOld++; } else if(nPurgeCount == 0){ // used Hashset, but it does not need to be moved as nothing changed yet file.Seek(nHashCount*CAICHHash::GetHashSize(), CFile::current); posWritePos = file.GetPosition(); CAICHRecoveryHashSet::AddStoredAICHHash(aichHash); } else{ // used Hashset, move position in file BYTE* buffer = new BYTE[nHashCount*CAICHHash::GetHashSize()]; file.Read(buffer, nHashCount*CAICHHash::GetHashSize()); posReadPos = file.GetPosition(); file.Seek(posWritePos, CFile::begin); file.Write(aichHash.GetRawHash(), CAICHHash::GetHashSize()); file.WriteUInt32(nHashCount); file.Write(buffer, nHashCount*CAICHHash::GetHashSize()); delete[] buffer; posWritePos = file.GetPosition(); file.Seek(posReadPos, CFile::begin); CAICHRecoveryHashSet::AddStoredAICHHash(aichHash); } } posReadPos = file.GetPosition(); file.SetLength(posWritePos); theApp.QueueDebugLogLine(false, _T("Cleaned up known2.met, removed %u hashsets and purged %u hashsets of old known files (%s)") , nPurgeCount - nPurgeBecauseOld, nPurgeBecauseOld, CastItoXBytes(posReadPos-posWritePos)); file.Flush(); file.Close(); } catch(CFileException* error){ if (error->m_cause == CFileException::endOfFile){ // we just parsed this files some ms ago, should never happen here ASSERT( false ); } else{ TCHAR buffer[MAX_CFEXP_ERRORMSG]; error->GetErrorMessage(buffer, ARRSIZE(buffer)); LogError(LOG_STATUSBAR,GetResString(IDS_ERR_SERVERMET_UNKNOWN),buffer); } error->Delete(); return false; } } else { // remember (/index) all hashs which are stored in the file for faster checking lateron for (POSITION pos = liKnown2Hashs.GetHeadPosition();pos != 0;) { CAICHRecoveryHashSet::AddStoredAICHHash(liKnown2Hashs.GetNext(pos)); } } lockKnown2Met.Unlock(); // warn the user if he just upgraded if (thePrefs.IsFirstStart() && !m_liToHash.IsEmpty() && !bJustCreated){ LogWarning(GetResString(IDS_AICH_WARNUSER)); } if (!m_liToHash.IsEmpty()){ theApp.QueueLogLine(true, GetResString(IDS_AICH_SYNCTOTAL), m_liToHash.GetCount() ); theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(m_liToHash.GetCount()); // let first all normal hashing be done before starting out synchashing CSingleLock sLock1(&theApp.hashing_mut); // only one filehash at a time while (theApp.sharedfiles->GetHashingCount() != 0){ Sleep(100); if (!CemuleDlg::IsRunning()) return 0; } sLock1.Lock(); uint32 cDone = 0; for (POSITION pos = m_liToHash.GetHeadPosition();pos != 0; cDone++) { if (!CemuleDlg::IsRunning()){ // in case of shutdown while still hashing return 0; } theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(m_liToHash.GetCount()-cDone); if (theApp.emuledlg->sharedfileswnd->sharedfilesctrl.m_hWnd != NULL) theApp.emuledlg->sharedfileswnd->sharedfilesctrl.ShowFilesCount(); CKnownFile* pCurFile = m_liToHash.GetNext(pos); // just to be sure that the file hasnt been deleted lately if (!(theApp.knownfiles->IsKnownFile(pCurFile) && theApp.sharedfiles->GetFileByID(pCurFile->GetFileHash())) ) continue; theApp.QueueLogLine(false, GetResString(IDS_AICH_CALCFILE), pCurFile->GetFileName()); if(!pCurFile->CreateAICHHashSetOnly()) theApp.QueueDebugLogLine(false, _T("Failed to create AICH Hashset while sync. for file %s"), pCurFile->GetFileName()); } theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(0); if (theApp.emuledlg->sharedfileswnd->sharedfilesctrl.m_hWnd != NULL) theApp.emuledlg->sharedfileswnd->sharedfilesctrl.ShowFilesCount(); sLock1.Unlock(); } theApp.QueueDebugLogLine(false, _T("AICHSyncThread finished")); return 0; }