📄 partfileconvert.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include <io.h>
#include "emule.h"
#include "PartFileConvert.h"
#include "OtherFunctions.h"
#include "DownloadQueue.h"
#include "PartFile.h"
#include "Preferences.h"
#include "SafeFile.h"
#include "emuledlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
enum convstatus{
CONV_OK =0,
CONV_QUEUE,
CONV_INPROGRESS,
CONV_OUTOFDISKSPACE,
CONV_PARTMETNOTFOUND,
CONV_IOERROR,
CONV_FAILED,
CONV_BADFORMAT,
CONV_ALREADYEXISTS
};
struct ConvertJob {
CString folder;
CString filename;
CString filehash;
int format;
int state;
uint32 size;
uint32 spaceneeded;
uint8 partmettype;
bool removeSource;
ConvertJob() {size=0;spaceneeded=0;partmettype=PMT_UNKNOWN;removeSource=true;}
//~ConvertJob() {}
};
int CPartFileConvert::ScanFolderToAdd(CString folder,bool deletesource) {
int count=0;
CFileFind finder;
BOOL bWorking;
bWorking = finder.FindFile(folder+_T("\\*.part.met"));
while (bWorking) {
bWorking=finder.FindNextFile();
ConvertToeMule(finder.GetFilePath(),deletesource);
count++;
}
/* Shareaza
bWorking = finder.FindFile(folder+_T("\\*.sd"));
while (bWorking) {
bWorking=finder.FindNextFile();
ConvertToeMule(finder.GetFilePath(),deletesource);
count++;
}
*/
bWorking = finder.FindFile(folder+_T("\\*.*"));
while (bWorking) {
bWorking = finder.FindNextFile();
CString test=finder.GetFilePath();
if (finder.IsDirectory() && finder.GetFileName().Left(1)!=".")
ScanFolderToAdd(finder.GetFilePath(),deletesource);
}
return count;
}
void CPartFileConvert::ConvertToeMule(CString folder,bool deletesource)
{
if (!PathFileExists(folder))
return;
//if ( folder.Left(strlen(thePrefs.GetTempDir())).CompareNoCase(thePrefs.GetTempDir()) ==0 ) return;
ConvertJob* newjob=new ConvertJob ();
newjob->folder=folder;
newjob->removeSource=deletesource;
newjob->state=CONV_QUEUE;
m_jobs.AddTail(newjob);
if (m_convertgui)
m_convertgui->AddJob(newjob);
StartThread();
}
void CPartFileConvert::StartThread() {
if (convertPfThread==NULL)
convertPfThread=AfxBeginThread(run, NULL);
}
UINT AFX_CDECL CPartFileConvert::run(LPVOID lpParam)
{
DbgSetThreadName("Partfile-Converter");
InitThreadLocale();
for (;;)
{
// search next queued job and start it
pfconverting=NULL;
for(POSITION pos = m_jobs.GetHeadPosition(); pos != NULL; m_jobs.GetNext(pos)){
pfconverting=m_jobs.GetAt(pos);
if (pfconverting->state==CONV_QUEUE) break; else pfconverting=NULL;
}
if (pfconverting!=NULL) {
pfconverting->state=CONV_INPROGRESS;
UpdateGUI(pfconverting);
pfconverting->state=performConvertToeMule(pfconverting->folder);
UpdateGUI(pfconverting);
AddLogLine(true,GetResString(IDS_IMP_STATUS),pfconverting->folder,GetReturncodeText(pfconverting->state));
} else
break;// nothing more to do now
}
// clean up
UpdateGUI(NULL);
convertPfThread=NULL;
return 0;
}
int CPartFileConvert::performConvertToeMule(CString folder)
{
BOOL bWorking;
CString filepartindex,newfilename;
CString buffer;
UINT fileindex;
CFileFind finder;
CString partfile=folder;
folder.Delete(folder.ReverseFind('\\'),folder.GetLength());
partfile=partfile.Mid(partfile.ReverseFind('\\')+1,partfile.GetLength());
UpdateGUI(0,GetResString(IDS_IMP_STEPREADPF),true);
filepartindex=partfile.Left(partfile.Find('.'));
//int pos=filepartindex.ReverseFind('\\');
//if (pos>-1) filepartindex=filepartindex.Mid(pos+1,filepartindex.GetLength()-pos);
UpdateGUI(4,GetResString(IDS_IMP_STEPBASICINF));
CPartFile* file=new CPartFile();
pfconverting->partmettype=file->LoadPartFile(folder,partfile,true);
switch (pfconverting->partmettype) {
case PMT_UNKNOWN:
case PMT_BADFORMAT:
delete file;
return CONV_BADFORMAT;
break;
}
CString oldfile=folder+_T("\\")+partfile.Left(partfile.GetLength()- ((pfconverting->partmettype==PMT_SHAREAZA)?3:4) );
pfconverting->size=file->GetFileSize();
pfconverting->filename=file->GetFileName();
pfconverting->filehash= EncodeBase16( file->GetFileHash() ,16);
UpdateGUI(pfconverting);
if (theApp.downloadqueue->GetFileByID(file->GetFileHash())!=0) {
delete file;
return CONV_ALREADYEXISTS;
}
if (pfconverting->partmettype==PMT_SPLITTED ) {
try {
CByteArray ba;
ba.SetSize(PARTSIZE);
CFile inputfile;
int pos1,pos2;
CString filename;
// just count
UINT maxindex=0;
UINT partfilecount=0;
bWorking = finder.FindFile(folder+_T("\\")+filepartindex+_T(".*.part"));
while (bWorking)
{
bWorking = finder.FindNextFile();
++partfilecount;
buffer=finder.GetFileName();
pos1=buffer.Find('.');
pos2=buffer.Find('.',pos1+1);
fileindex=_tstoi(buffer.Mid(pos1+1,pos2-pos1) );
if (fileindex==0) continue;
if (fileindex>maxindex) maxindex=fileindex;
}
float stepperpart;
if (partfilecount>0) {
stepperpart=(80.0f / partfilecount );
if (maxindex*PARTSIZE<=pfconverting->size) pfconverting->spaceneeded=maxindex*PARTSIZE;
else pfconverting->spaceneeded=((pfconverting->size / PARTSIZE) * PARTSIZE)+(pfconverting->size % PARTSIZE);
} else {
stepperpart=80.0f;
pfconverting->spaceneeded=0;
}
UpdateGUI(pfconverting);
if (GetFreeDiskSpaceX(thePrefs.GetTempDir()) < (maxindex*PARTSIZE) ) {
delete file;
return CONV_OUTOFDISKSPACE;
}
// create new partmetfile, and remember the new name
file->CreatePartFile();
newfilename=file->GetFullName();
UpdateGUI(8,GetResString(IDS_IMP_STEPCRDESTFILE));
file->m_hpartfile.SetLength( pfconverting->spaceneeded );
uint16 curindex=0;
bWorking = finder.FindFile(folder+_T("\\")+filepartindex+_T(".*.part"));
while (bWorking)
{
bWorking = finder.FindNextFile();
//stats
++curindex;
buffer.Format(GetResString(IDS_IMP_LOADDATA),curindex,partfilecount);
UpdateGUI( 10+(curindex*stepperpart) ,buffer);
filename=finder.GetFileName();
pos1=filename.Find('.');
pos2=filename.Find('.',pos1+1);
fileindex=_tstoi(filename.Mid(pos1+1,pos2-pos1) );
if (fileindex==0) continue;
uint32 chunkstart=(fileindex-1) * PARTSIZE ;
// open, read data of the part-part-file into buffer, close file
inputfile.Open(finder.GetFilePath(),CFile::modeRead|CFile::shareDenyWrite);
uint32 readed=inputfile.Read( ba.GetData() ,PARTSIZE);
inputfile.Close();
buffer.Format(GetResString(IDS_IMP_SAVEDATA),curindex,partfilecount);
UpdateGUI( 10+(curindex*stepperpart) ,buffer);
// write the buffered data
file->m_hpartfile.Seek(chunkstart, CFile::begin );
file->m_hpartfile.Write(ba.GetData(),readed);
}
}
catch(CFileException* error) {
CString strError(GetResString(IDS_IMP_IOERROR));
TCHAR szError[MAX_CFEXP_ERRORMSG];
if (error->GetErrorMessage(szError, ARRSIZE(szError))){
strError += _T(" - ");
strError += szError;
}
AddLogLine(false, _T("%s"), strError);
error->Delete();
delete file;
return CONV_IOERROR;
}
file->m_hpartfile.Close();
}
// import an external common format partdownload
else //if (pfconverting->partmettype==PMT_DEFAULTOLD || pfconverting->partmettype==PMT_NEWOLD || Shareaza )
{
if (!pfconverting->removeSource)
pfconverting->spaceneeded=GetDiskFileSize(oldfile);
UpdateGUI(pfconverting);
if (!pfconverting->removeSource && (GetFreeDiskSpaceX(thePrefs.GetTempDir()) < pfconverting->spaceneeded) ) {
delete file;
return CONV_OUTOFDISKSPACE;
}
file->CreatePartFile();
newfilename=file->GetFullName();
file->m_hpartfile.Close();
bool ret=false;
UpdateGUI( 92 ,GetResString(IDS_COPY));
DeleteFile(newfilename.Left(newfilename.GetLength()-4));
if (!PathFileExists(oldfile)) {
// data file does not exist. well, then create a 0 byte big one
HANDLE hFile = CreateFile( newfilename.Left(newfilename.GetLength()-4) , // file to open
GENERIC_WRITE, // open for reading
FILE_SHARE_READ, // share for reading
NULL, // default security
CREATE_NEW, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
ret= !(hFile == INVALID_HANDLE_VALUE) ;
CloseHandle(hFile);
}
else
if (pfconverting->removeSource)
ret=MoveFile( oldfile, newfilename.Left(newfilename.GetLength()-4) );
else
ret=CopyFile( oldfile, newfilename.Left(newfilename.GetLength()-4) ,false);
if (!ret) {
file->DeleteFile();
//delete file;
return CONV_FAILED;
}
}
UpdateGUI( 94 ,GetResString(IDS_IMP_GETPFINFO));
DeleteFile(newfilename);
if (pfconverting->removeSource)
MoveFile(folder+_T("\\")+partfile,newfilename);
else CopyFile(folder+_T("\\")+partfile,newfilename,false);
for (int i = 0; i < file->hashlist.GetSize(); i++)
delete[] file->hashlist[i];
file->hashlist.RemoveAll();
while (file->gaplist.GetCount()>0 ) {
delete file->gaplist.GetAt(file->gaplist.GetHeadPosition());
file->gaplist.RemoveAt(file->gaplist.GetHeadPosition());
}
if (!file->LoadPartFile(thePrefs.GetTempDir(),file->GetPartMetFileName(),false)) {
//delete file;
file->DeleteFile();
return CONV_BADFORMAT;
}
if (pfconverting->partmettype==PMT_NEWOLD || pfconverting->partmettype==PMT_SPLITTED ) {
file->completedsize=file->transfered;
file->m_iGainDueToCompression = 0;
file->m_iLostDueToCorruption = 0;
}
UpdateGUI( 100 ,GetResString(IDS_IMP_ADDDWL));
theApp.downloadqueue->AddDownload(file,thePrefs.AddNewFilesPaused());
file->SavePartFile();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -