📄 partfile.cpp
字号:
m_dwFileAttributes = GetFileAttributes(partfull);
if (m_dwFileAttributes == INVALID_FILE_ATTRIBUTES)
m_dwFileAttributes = 0;
if (GetED2KPartHashCount() == 0)
hashsetneeded = false;
m_SrcpartFrequency.SetSize(GetPartCount());
for (uint32 i = 0; i < GetPartCount();i++)
m_SrcpartFrequency[i] = 0;
paused = false;
if (thePrefs.AutoFilenameCleanup())
SetFileName(CleanupFilename(GetFileName()));
SavePartFile();
SetActive(theApp.IsConnected());
}
/*
* Due to the synchronized outflushing of the data in Shareaza, I am trying here a good-luck-file-reading approach.
* update: only worked with 2.0 and not on updates (as to be expected...) , removed for release
*/
//uint8 CPartFile::ImportShareazaTempfile(LPCTSTR in_directory,LPCTSTR in_filename , bool getsizeonly) {...
uint8 CPartFile::LoadPartFile(LPCTSTR in_directory,LPCTSTR in_filename, bool getsizeonly)
{
bool isnewstyle;
uint8 version,partmettype=PMT_UNKNOWN;
CMap<uint16, uint16, Gap_Struct*, Gap_Struct*> gap_map; // Slugfiller
transfered = 0;
m_partmetfilename = in_filename;
SetPath(in_directory);
m_fullname.Format(_T("%s\\%s"), GetPath(), m_partmetfilename);
// readfile data form part.met file
CSafeBufferedFile metFile;
CFileException fexpMet;
if (!metFile.Open(m_fullname, CFile::modeRead|CFile::osSequentialScan|CFile::typeBinary|CFile::shareDenyWrite, &fexpMet)){
CString strError;
strError.Format(GetResString(IDS_ERR_OPENMET), m_partmetfilename, _T(""));
TCHAR szError[MAX_CFEXP_ERRORMSG];
if (fexpMet.GetErrorMessage(szError, ARRSIZE(szError))){
strError += _T(" - ");
strError += szError;
}
AddLogLine(false, _T("%s"), strError);
return false;
}
setvbuf(metFile.m_pStream, NULL, _IOFBF, 16384);
try{
version = metFile.ReadUInt8();
if (version != PARTFILE_VERSION && version!= PARTFILE_SPLITTEDVERSION ){
metFile.Close();
//if (version==83) { return ImportShareazaTempfile(in_directory, in_filename,getsizeonly);}
AddLogLine(false, GetResString(IDS_ERR_BADMETVERSION), m_partmetfilename, GetFileName());
return false;
}
isnewstyle=(version== PARTFILE_SPLITTEDVERSION);
partmettype= isnewstyle?PMT_SPLITTED:PMT_DEFAULTOLD;
if (!isnewstyle) {
uint8 test[4];
metFile.Seek(24, CFile::begin);
metFile.Read(&test[0],1);
metFile.Read(&test[1],1);
metFile.Read(&test[2],1);
metFile.Read(&test[3],1);
metFile.Seek(1, CFile::begin);
if (test[0]==0 && test[1]==0 && test[2]==2 && test[3]==1) {
isnewstyle=true; // edonkeys so called "old part style"
partmettype=PMT_NEWOLD;
}
}
if (isnewstyle) {
uint32 temp;
metFile.Read(&temp,4);
if (temp==0) { // 0.48 partmets - different again
LoadHashsetFromFile(&metFile, false);
} else {
uchar gethash[16];
metFile.Seek(2, CFile::begin);
LoadDateFromFile(&metFile);
metFile.Read(&gethash, 16);
md4cpy(m_abyFileHash, gethash);
}
} else {
LoadDateFromFile(&metFile);
LoadHashsetFromFile(&metFile, false);
}
UINT tagcount = metFile.ReadUInt32();
for (UINT j = 0; j < tagcount; j++){
CTag* newtag = new CTag(&metFile, false);
if (!getsizeonly || (getsizeonly && (newtag->GetNameID()==FT_FILESIZE || newtag->GetNameID()==FT_FILENAME))){
switch (newtag->GetNameID()){
case FT_FILENAME:{
if (!newtag->IsStr()) {
AddLogLine(true, GetResString(IDS_ERR_METCORRUPT), m_partmetfilename, GetFileName());
delete newtag;
return false;
}
#ifdef _UNICODE
if (GetFileName().IsEmpty())
#endif
SetFileName(newtag->GetStr());
delete newtag;
break;
}
case FT_LASTSEENCOMPLETE:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
lastseencomplete = newtag->GetInt();
delete newtag;
break;
}
case FT_FILESIZE:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
SetFileSize(newtag->GetInt());
delete newtag;
break;
}
case FT_TRANSFERED:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
transfered = newtag->GetInt();
delete newtag;
break;
}
case FT_FILETYPE:{
ASSERT( newtag->IsStr() );
if (newtag->IsStr())
SetFileType(newtag->GetStr());
delete newtag;
break;
}
case FT_CATEGORY:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
m_category = newtag->GetInt();
delete newtag;
break;
}
case FT_DLPRIORITY:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt()){
if (!isnewstyle){
m_iDownPriority = newtag->GetInt();
if( m_iDownPriority == PR_AUTO ){
m_iDownPriority = PR_HIGH;
SetAutoDownPriority(true);
}
else{
if (m_iDownPriority != PR_LOW && m_iDownPriority != PR_NORMAL && m_iDownPriority != PR_HIGH)
m_iDownPriority = PR_NORMAL;
SetAutoDownPriority(false);
}
}
}
delete newtag;
break;
}
case FT_STATUS:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt()){
paused = newtag->GetInt();
stopped = paused;
}
delete newtag;
break;
}
case FT_ULPRIORITY:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt()){
if (!isnewstyle){
int iUpPriority = newtag->GetInt();
if( iUpPriority == PR_AUTO ){
SetUpPriority(PR_HIGH, false);
SetAutoUpPriority(true);
}
else{
if (iUpPriority != PR_VERYLOW && iUpPriority != PR_LOW && iUpPriority != PR_NORMAL && iUpPriority != PR_HIGH && iUpPriority != PR_VERYHIGH)
iUpPriority = PR_NORMAL;
SetUpPriority(iUpPriority, false);
SetAutoUpPriority(false);
}
}
}
delete newtag;
break;
}
case FT_KADLASTPUBLISHSRC:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
SetLastPublishTimeKadSrc(newtag->GetInt());
delete newtag;
break;
}
case FT_DL_PREVIEW:{
ASSERT( newtag->IsInt() );
if(newtag->GetInt() == 1) {
SetPreviewPrio(true);
} else {
SetPreviewPrio(false);
}
delete newtag;
break;
}
// statistics
case FT_ATTRANSFERED:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
statistic.alltimetransferred = newtag->GetInt();
delete newtag;
break;
}
case FT_ATTRANSFEREDHI:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
{
uint32 hi,low;
low=statistic.alltimetransferred;
hi = newtag->GetInt();
uint64 hi2;
hi2=hi;
hi2=hi2<<32;
statistic.alltimetransferred=low+hi2;
}
delete newtag;
break;
}
case FT_ATREQUESTED:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
statistic.alltimerequested = newtag->GetInt();
delete newtag;
break;
}
case FT_ATACCEPTED:{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
statistic.alltimeaccepted = newtag->GetInt();
delete newtag;
break;
}
// old tags: as long as they are not needed, take the chance to purge them
case FT_PERMISSIONS:
ASSERT( newtag->IsInt() );
delete newtag;
break;
case FT_KADLASTPUBLISHKEY:
ASSERT( newtag->IsInt() );
delete newtag;
break;
case FT_DL_ACTIVE_TIME:
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
m_nDlActiveTime = newtag->GetInt();
delete newtag;
break;
case FT_CORRUPTEDPARTS:
ASSERT( newtag->IsStr() );
if (newtag->IsStr())
{
ASSERT( corrupted_list.GetHeadPosition() == NULL );
CString strCorruptedParts(newtag->GetStr());
int iPos = 0;
CString strPart = strCorruptedParts.Tokenize(_T(","), iPos);
while (!strPart.IsEmpty())
{
UINT uPart;
if (_stscanf(strPart, _T("%u"), &uPart) == 1)
{
if (uPart < GetPartCount() && !IsCorruptedPart(uPart))
corrupted_list.AddTail(uPart);
}
strPart = strCorruptedParts.Tokenize(_T(","), iPos);
}
}
delete newtag;
break;
case FT_AICH_HASH:{
ASSERT( newtag->IsStr() );
CAICHHash hash;
if (DecodeBase32(newtag->GetStr(),hash) == CAICHHash::GetHashSize())
m_pAICHHashSet->SetMasterHash(hash, AICH_VERIFIED);
else
ASSERT( false );
delete newtag;
break;
}
default:{
if (newtag->GetNameID()==0 && (newtag->GetName()[0]==FT_GAPSTART || newtag->GetName()[0]==FT_GAPEND))
{
ASSERT( newtag->IsInt() );
if (newtag->IsInt())
{
Gap_Struct* gap;
uint16 gapkey = atoi(&newtag->GetName()[1]);
if (!gap_map.Lookup(gapkey, gap))
{
gap = new Gap_Struct;
gap_map.SetAt(gapkey, gap);
gap->start = (uint32)-1;
gap->end = (uint32)-1;
}
if (newtag->GetName()[0] == FT_GAPSTART)
gap->start = newtag->GetInt();
if (newtag->GetName()[0] == FT_GAPEND)
gap->end = newtag->GetInt() - 1;
}
delete newtag;
}
else
taglist.Add(newtag);
}
}
}
else
delete newtag;
}
// load the hashsets from the hybridstylepartmet
if (isnewstyle && !getsizeonly && (metFile.GetPosition()<metFile.GetLength()) ) {
uint8 temp;
metFile.Read(&temp,1);
uint16 parts=GetPartCount(); // assuming we will get all hashsets
for (uint16 i = 0; i < parts && (metFile.GetPosition()+16<metFile.GetLength()); i++){
uchar* cur_hash = new uchar[16];
metFile.Read(cur_hash, 16);
hashlist.Add(cur_hash);
}
uchar* checkhash= new uchar[16];
if (!hashlist.IsEmpty()){
uchar* buffer = new uchar[hashlist.GetCount()*16];
for (int i = 0; i < hashlist.GetCount(); i++)
md4cpy(buffer+(i*16), hashlist[i]);
CreateHashFromString(buffer, hashlist.GetCount()*16, checkhash);
delete[] buffer;
}
bool flag=false;
if (!md4cmp(m_abyFileHash, checkhash))
flag=true;
else{
for (int i = 0; i < hashlist.GetSize(); i++)
delete[] hashlist[i];
hashlist.RemoveAll();
flag=false;
}
delete[] checkhash;
}
metFile.Close();
}
catch(CFileException* error){
if (error->m_cause == CFileException::endOfFile)
AddLogLine(true, GetResString(IDS_ERR_METCORRUPT), m_partmetfilename, GetFileName());
else{
TCHAR buffer[MAX_CFEXP_ERRORMSG];
error->GetErrorMessage(buffer,ARRSIZE(buffer));
AddLogLine(true, GetResString(IDS_ERR_FILEERROR), m_partmetfilename, GetFileName(), buffer);
}
error->Delete();
return false;
}
catch(...){
AddLogLine(true, GetResString(IDS_ERR_METCORRUPT), m_partmetfilename, GetFileName());
ASSERT(0);
return false;
}
if (getsizeonly) {
return partmettype;
}
// Now to flush the map into the list (Slugfiller)
for (POSITION pos = gap_map.GetStartPosition(); pos != NULL; ){
Gap_Struct* gap;
uint16 gapkey;
gap_map.GetNextAssoc(pos, gapkey, gap);
// SLUGFILLER: SafeHash - revised code, and extra safety
if (gap->start != -1 && gap->end != -1 && gap->start <= gap->end && gap->start < m_nFileSize){
if (gap->end >= m_nFileSize)
gap->end = m_nFileSize-1; // Clipping
AddGap(gap->start, gap->end); // All tags accounted for, use safe adding
}
delete gap;
// SLUGFILLER: SafeHash
}
// verify corrupted parts list
POSITION posCorruptedPart = corrupted_list.GetHeadPosition();
while (posCorruptedPart)
{
POSITION posLast = posCorruptedPart;
UINT uCorruptedPart = corrupted_list.GetNext(posCorruptedPart);
if (IsComplete(uCorruptedPart*PARTSIZE, (uCorruptedPart+1)*PARTSIZE-1))
corrupted_list.RemoveAt(posLast);
}
//check if this is a backup
if(_tcsicmp(_tcsrchr(m_fullname, _T('.')), PARTMET_TMP_EXT) == 0)
m_fullname = RemoveFileExtension(m_fullname);
// open permanent handle
CString searchpath(RemoveFileExtension(m_fullname));
CFileException fexpPart;
if (!m_hpartfile.Open(searchpath, CFile::modeReadWrite|CFile::shareDenyWrite|CFile::osSequentialScan, &fexpPart)){
CString strError;
strError.Format(GetResString(IDS_ERR_FILEOPEN), searchpath, GetFileName());
TCHAR szError[MAX_CFEXP_ERRORMSG];
if (fexpPart.GetErrorMessage(szError, ARRSIZE(szError))){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -