bool CKnownFileList::Append(CKnownFile *Record, bool afterHashing) { if (Record->GetFileSize() > 0) { const CMD4Hash& tkey = Record->GetFileHash(); CKnownFileMap::iterator it = m_knownFileMap.find(tkey); if (it == m_knownFileMap.end()) { m_knownFileMap[tkey] = Record; return true; } else { CKnownFile *existing = it->second; if (KnownFileMatches(Record, existing->GetFileName(), existing->GetLastChangeDatetime(), existing->GetFileSize())) { // The file is already on the list, ignore it. AddDebugLogLineN(logKnownFiles, CFormat(wxT("%s is already on the list")) % Record->GetFileName().GetPrintable()); return false; } else if (IsOnDuplicates(Record->GetFileName(), Record->GetLastChangeDatetime(), Record->GetFileSize())) { // The file is on the duplicates list, ignore it. // Should not happen, at least not after hashing. Or why did it get hashed in the first place then? AddDebugLogLineN(logKnownFiles, CFormat(wxT("%s is on the duplicates list")) % Record->GetFileName().GetPrintable()); return false; } else { if (afterHashing && existing->GetFileSize() == Record->GetFileSize()) { // We just hashed a "new" shared file and find it's already known under a different name or date. // Guess what - it was probably renamed or touched. // So copy over all properties from the existing known file and just keep name/date. time_t newDate = Record->GetLastChangeDatetime(); CPath newName = Record->GetFileName(); CMemFile f; existing->WriteToFile(&f); f.Reset(); Record->LoadFromFile(&f); Record->SetLastChangeDatetime(newDate); Record->SetFileName(newName); } // The file is a duplicated hash. Add THE OLD ONE to the duplicates list. // (This is used when reading the known file list where the duplicates are stored in front.) m_duplicateFileList.push_back(existing); if (theApp->sharedfiles) { // Removing the old kad keywords created with the old filename theApp->sharedfiles->RemoveKeywords(existing); } m_knownFileMap[tkey] = Record; return true; } } } else { AddDebugLogLineN(logGeneral, CFormat(wxT("%s is 0-size, not added")) % Record->GetFileName()); return false; } }
void CKnownFileList::Save() { if (thePrefs.GetLogFileSaving()) AddDebugLogLine(false, _T("Saving known files list file \"%s\""), KNOWN_MET_FILENAME); m_nLastSaved = ::GetTickCount(); CString fullpath = thePrefs.GetMuleDirectory(EMULE_CONFIGDIR); fullpath += KNOWN_MET_FILENAME; CSafeBufferedFile file; CFileException fexp; if (!file.Open(fullpath, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary|CFile::shareDenyWrite, &fexp)){ CString strError(_T("Failed to save ") KNOWN_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); } else{ setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try{ file.WriteUInt8(0); // we will write the version tag later depending if any large files are on the list UINT nRecordsNumber = 0; bool bContainsAnyLargeFiles = false; file.WriteUInt32(nRecordsNumber); POSITION pos = m_Files_map.GetStartPosition(); while( pos != NULL ) { CKnownFile* pFile; CCKey key; m_Files_map.GetNextAssoc( pos, key, pFile ); if (!thePrefs.IsRememberingDownloadedFiles() && !theApp.sharedfiles->IsFilePtrInList(pFile)){ continue; } else{ pFile->WriteToFile(&file); nRecordsNumber++; if (pFile->IsLargeFile()) bContainsAnyLargeFiles = true; } } file.SeekToBegin(); file.WriteUInt8(bContainsAnyLargeFiles ? MET_HEADER_I64TAGS : MET_HEADER); file.WriteUInt32(nRecordsNumber); if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && !theApp.emuledlg->IsRunning())){ file.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(file.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, GetLastError(), file.GetFileName()); } file.Close(); } catch(CFileException* error){ CString strError(_T("Failed to save ") KNOWN_MET_FILENAME _T(" file")); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (error->GetErrorMessage(szError, ARRSIZE(szError))){ strError += _T(" - "); strError += szError; } LogError(LOG_STATUSBAR, _T("%s"), strError); error->Delete(); } } if (thePrefs.GetLogFileSaving()) AddDebugLogLine(false, _T("Saving known files list file \"%s\""), CANCELLED_MET_FILENAME); fullpath = thePrefs.GetMuleDirectory(EMULE_CONFIGDIR); fullpath += CANCELLED_MET_FILENAME; if (!file.Open(fullpath, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary|CFile::shareDenyWrite, &fexp)){ CString strError(_T("Failed to save ") CANCELLED_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); } else{ setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try{ file.WriteUInt8(CANCELLED_HEADER); file.WriteUInt8(CANCELLED_VERSION); file.WriteUInt32(m_dwCancelledFilesSeed); if (!thePrefs.IsRememberingCancelledFiles()){ file.WriteUInt32(0); } else{ UINT nRecordsNumber = m_mapCancelledFiles.GetCount(); file.WriteUInt32(nRecordsNumber); POSITION pos = m_mapCancelledFiles.GetStartPosition(); while( pos != NULL ) { int dwDummy; CSKey key; m_mapCancelledFiles.GetNextAssoc( pos, key, dwDummy ); file.WriteHash16(key.m_key); file.WriteUInt8(0); } } if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && !theApp.emuledlg->IsRunning())){ file.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(file.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, GetLastError(), file.GetFileName()); } file.Close(); } catch(CFileException* error){ CString strError(_T("Failed to save ") CANCELLED_MET_FILENAME _T(" file")); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (error->GetErrorMessage(szError, ARRSIZE(szError))){ strError += _T(" - "); strError += szError; } LogError(LOG_STATUSBAR, _T("%s"), strError); error->Delete(); } } }