00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "StdAfx.h"
00027 #include "Shareaza.h"
00028 #include "Settings.h"
00029 #include "EDPartImporter.h"
00030 #include "EDPacket.h"
00031 #include "ED2K.h"
00032 #include "Transfers.h"
00033 #include "Downloads.h"
00034 #include "Download.h"
00035 #include "FragmentedFile.h"
00036 #include "CtrlText.h"
00037
00038 #ifdef _DEBUG
00039 #define new DEBUG_NEW
00040 #undef THIS_FILE
00041 static char THIS_FILE[] = __FILE__;
00042 #endif
00043
00044 IMPLEMENT_DYNAMIC(CEDPartImporter, CWinThread)
00045
00046 BEGIN_MESSAGE_MAP(CEDPartImporter, CWinThread)
00047
00048
00049 END_MESSAGE_MAP()
00050
00051
00053
00054
00055 CEDPartImporter::CEDPartImporter()
00056 {
00057 m_bAutoDelete = FALSE;
00058 m_pTextCtrl = NULL;
00059 }
00060
00061 CEDPartImporter::~CEDPartImporter()
00062 {
00063 }
00064
00065 BOOL CEDPartImporter::InitInstance()
00066 {
00067 return TRUE;
00068 }
00069
00071
00072
00073 void CEDPartImporter::AddFolder(LPCTSTR pszFolder)
00074 {
00075 if ( m_pTextCtrl != NULL ) return;
00076 m_pFolders.AddTail( pszFolder );
00077 }
00078
00079 void CEDPartImporter::Start(CEdit* pCtrl)
00080 {
00081 ASSERT( pCtrl != NULL );
00082 m_pTextCtrl = pCtrl;
00083 CreateThread();
00084 }
00085
00086 void CEDPartImporter::Stop()
00087 {
00088 if ( m_pTextCtrl == NULL ) return;
00089 m_pTextCtrl = NULL;
00090 WaitForSingleObject( m_hThread, INFINITE );
00091 }
00092
00093 BOOL CEDPartImporter::IsRunning()
00094 {
00095 if ( m_hThread == NULL ) return FALSE;
00096 DWORD nCode = 0;
00097 if ( ! GetExitCodeThread( m_hThread, &nCode ) ) return FALSE;
00098 return nCode == STILL_ACTIVE;
00099 }
00100
00102
00103
00104 int CEDPartImporter::Run()
00105 {
00106 Message( IDS_ED2K_EPI_START );
00107 m_nCount = 0;
00108
00109 CreateDirectory( Settings.Downloads.IncompletePath, NULL );
00110
00111 for ( POSITION pos = m_pFolders.GetHeadPosition() ; pos && m_pTextCtrl != NULL ; )
00112 {
00113 ImportFolder( m_pFolders.GetNext( pos ) );
00114 }
00115
00116 Message( IDS_ED2K_EPI_FINISHED, m_nCount );
00117
00118 if ( m_nCount ) Downloads.Save();
00119
00120 return 0;
00121 }
00122
00124
00125
00126 void CEDPartImporter::ImportFolder(LPCTSTR pszPath)
00127 {
00128 WIN32_FIND_DATA pFind;
00129 CString strPath;
00130 HANDLE hSearch;
00131
00132 Message( IDS_ED2K_EPI_FOLDER, pszPath );
00133
00134 strPath.Format( _T("%s\\*.part.met"), pszPath );
00135 hSearch = FindFirstFile( strPath, &pFind );
00136 if ( hSearch == INVALID_HANDLE_VALUE ) return;
00137
00138 do
00139 {
00140 if ( m_pTextCtrl == NULL ) break;
00141
00142 if ( pFind.cFileName[0] == '.' ) continue;
00143 if ( pFind.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM) ) continue;
00144
00145 strPath = pFind.cFileName;
00146 int nPos = strPath.Find( _T(".part.met") );
00147 if ( nPos < 1 ) continue;
00148 strPath = strPath.Left( nPos );
00149
00150 if ( ImportFile( pszPath, strPath ) )
00151 {
00152 m_nCount++;
00153 }
00154 else
00155 {
00156 Message( IDS_ED2K_EPI_FILE_FAILED );
00157 }
00158 }
00159 while ( FindNextFile( hSearch, &pFind ) );
00160
00161 FindClose( hSearch );
00162 }
00163
00165
00166
00167 BOOL CEDPartImporter::ImportFile(LPCTSTR pszPath, LPCTSTR pszFile)
00168 {
00169 CString strPath;
00170 CFile pFile;
00171
00172 Message( IDS_ED2K_EPI_FILE_START, pszFile );
00173
00174 strPath.Format( _T("%s\\%s.part.met"), pszPath, pszFile );
00175 if ( ! pFile.Open( strPath, CFile::modeRead ) )
00176 {
00177 Message( IDS_ED2K_EPI_CANT_OPEN_PART, (LPCTSTR)strPath );
00178 return FALSE;
00179 }
00180
00181 BYTE nMagic = 0;
00182 pFile.Read( &nMagic, 1 );
00183 if ( nMagic != 0xE0 ) return FALSE;
00184
00185 LONG nDate = 0;
00186 WORD nParts = 0;
00187 CED2K pED2K;
00188 MD4 pMD4;
00189
00190 pFile.Read( &nDate, 4 );
00191 pFile.Read( &pMD4, sizeof(MD4) );
00192 pFile.Read( &nParts, 2 );
00193
00194 if ( Transfers.m_pSection.Lock() )
00195 {
00196 CDownload* pDownload = Downloads.FindByED2K( &pMD4 );
00197 Transfers.m_pSection.Unlock();
00198
00199 if ( pDownload != NULL )
00200 {
00201 Message( IDS_ED2K_EPI_ALREADY );
00202 return FALSE;
00203 }
00204 }
00205
00206 if ( nParts == 0 )
00207 {
00208 pED2K.FromRoot( &pMD4 );
00209 }
00210 else if ( nParts > 0 )
00211 {
00212 MD4* pHashset = new MD4[ nParts ];
00213 pFile.Read( pHashset, sizeof(MD4) * nParts );
00214 BOOL bSuccess = pED2K.FromBytes( (BYTE*)pHashset, sizeof(MD4) * nParts );
00215 delete [] pHashset;
00216 if ( ! bSuccess ) return FALSE;
00217
00218 MD4 pCheck;
00219 pED2K.GetRoot( &pCheck );
00220 if ( pCheck != pMD4 ) return FALSE;
00221 }
00222 else
00223 {
00224 return FALSE;
00225 }
00226
00227 if ( ! pED2K.IsAvailable() ) return FALSE;
00228
00229 DWORD nCount = 0;
00230 pFile.Read( &nCount, 4 );
00231 if ( nCount > 2048 ) return FALSE;
00232
00233 CMapWordToPtr pGapStart, pGapStop;
00234 CWordArray pGapIndex;
00235 BOOL bPaused = FALSE;
00236 CString strName;
00237 DWORD nSize = 0;
00238
00239 while ( nCount-- )
00240 {
00241 CEDTag pTag;
00242 if ( ! pTag.Read( &pFile ) ) return FALSE;
00243
00244 if ( pTag.Check( ED2K_FT_FILENAME, ED2K_TAG_STRING ) )
00245 {
00246 strName = pTag.m_sValue;
00247 }
00248 else if ( pTag.Check( ED2K_FT_FILESIZE, ED2K_TAG_INT ) )
00249 {
00250 nSize = pTag.m_nValue;
00251 }
00252 else if ( pTag.Check( ED2K_FT_STATUS, ED2K_TAG_INT ) )
00253 {
00254 bPaused = pTag.m_nValue;
00255 }
00256 else if ( pTag.m_nType == ED2K_TAG_INT && pTag.m_sKey.GetLength() > 1 )
00257 {
00258 if ( pTag.m_sKey.GetAt( 0 ) == 0x09 )
00259 {
00260 int niPart = 0;
00261 _stscanf( (LPCTSTR)pTag.m_sKey + 1, _T("%i"), &niPart );
00262 WORD nPart = (int)niPart;
00263 pGapStart.SetAt( nPart, (LPVOID)pTag.m_nValue );
00264 pGapIndex.Add( nPart );
00265 }
00266 else if ( pTag.m_sKey.GetAt( 0 ) == 0x0A )
00267 {
00268 int niPart = 0;
00269 _stscanf( (LPCTSTR)pTag.m_sKey + 1, _T("%i"), &niPart );
00270 WORD nPart = (int)niPart;
00271 pGapStop.SetAt( nPart, (LPVOID)pTag.m_nValue );
00272 }
00273 }
00274
00275 if ( m_pTextCtrl == NULL ) return FALSE;
00276 }
00277
00278 if ( strName.IsEmpty() || nSize == 0 || pGapStart.IsEmpty() ) return FALSE;
00279
00280 for ( int nGap = 0 ; nGap < pGapIndex.GetSize() ; nGap++ )
00281 {
00282 WORD nPart = pGapIndex.GetAt( nGap );
00283 DWORD nStart = 0, nStop = 0;
00284
00285 if ( ! pGapStart.Lookup( nPart, (void*&)nStart ) ) return FALSE;
00286 if ( nStart >= nSize ) return FALSE;
00287
00288 if ( ! pGapStop.Lookup( nPart, (void*&)nStop ) ) return FALSE;
00289 if ( nStop > nSize || nStop <= nStart ) return FALSE;
00290 }
00291
00292 Message( IDS_ED2K_EPI_DETECTED,
00293 (LPCTSTR)strName,
00294 (LPCTSTR)Settings.SmartVolume( nSize, FALSE ) );
00295
00296 if ( ! Downloads.IsSpaceAvailable( nSize, Downloads.dlPathIncomplete ) )
00297 {
00298 Message( IDS_ED2K_EPI_DISK_SPACE );
00299 return FALSE;
00300 }
00301
00302 CFileStatus pStatus;
00303 CFile pData;
00304
00305 strPath.Format( _T("%s\\%s.part"), pszPath, pszFile );
00306 if ( ! pData.Open( strPath, CFile::modeRead ) ) return FALSE;
00307 pData.GetStatus( pStatus );
00308 pData.Close();
00309 if ( nDate > mktime( pStatus.m_mtime.GetLocalTm( NULL ) ) )
00310 {
00311 Message( IDS_ED2K_EPI_FILE_OLD );
00312 return FALSE;
00313 }
00314
00315 CString strTarget;
00316 strTarget.Format( _T("%s\\%s %s"),
00317 (LPCTSTR)Settings.Downloads.IncompletePath,
00318 (LPCTSTR)CED2K::HashToString( &pMD4 ),
00319 (LPCTSTR)strName );
00320
00321 Message( IDS_ED2K_EPI_COPY_START, (LPCTSTR)strPath, (LPCTSTR)strTarget );
00322
00323 if ( m_pTextCtrl == NULL ) return FALSE;
00324 if ( ! CopyFile( strPath, strTarget ) ) return FALSE;
00325 if ( m_pTextCtrl == NULL ) return FALSE;
00326
00327 Message( IDS_ED2K_EPI_COPY_FINISHED );
00328
00329 Transfers.m_pSection.Lock();
00330
00331 CDownload* pDownload = Downloads.Add();
00332
00333 pDownload->m_bED2K = TRUE;
00334 pDownload->m_pED2K = pMD4;
00335 pDownload->m_nSize = nSize;
00336 pDownload->m_sRemoteName = strName;
00337 pDownload->m_sLocalName = strTarget;
00338
00339 pDownload->m_pFile->m_oFList.swap( FF::SimpleFragmentList( nSize ) );
00340
00341 for ( int nGap = 0 ; nGap < pGapIndex.GetSize() ; nGap++ )
00342 {
00343 WORD nPart = pGapIndex.GetAt( nGap );
00344 DWORD nStart = 0, nStop = 0;
00345
00346 pGapStart.Lookup( nPart, (void*&)nStart );
00347 pGapStop.Lookup( nPart, (void*&)nStop );
00348
00349 pDownload->m_pFile->m_oFList.insert( FF::SimpleFragment( nStart, nStop ) );
00350 }
00351
00352 if ( pED2K.IsAvailable() )
00353 {
00354 BYTE* pHashset = NULL;
00355 DWORD nHashset = 0;
00356 pED2K.ToBytes( &pHashset, &nHashset );
00357 pDownload->SetHashset( pHashset, nHashset );
00358 delete [] pHashset;
00359 }
00360
00361 if ( bPaused ) pDownload->Pause();
00362
00363 pDownload->Save();
00364
00365 Transfers.m_pSection.Unlock();
00366
00367 Message( IDS_ED2K_EPI_FILE_CREATED,
00368 (LPCTSTR)Settings.SmartVolume( pDownload->m_pFile->m_oFList.sumLength(), FALSE ) );
00369
00370 return TRUE;
00371 }
00372
00374
00375
00376 BOOL CEDPartImporter::CopyFile(LPCTSTR pszSource, LPCTSTR pszTarget)
00377 {
00378 return ::CopyFile( pszSource, pszTarget, TRUE );
00379 }
00380
00382
00383
00384 void CEDPartImporter::Message(UINT nMessageID, ...)
00385 {
00386 CEdit* pCtrl = m_pTextCtrl;
00387 if ( pCtrl == NULL ) return;
00388
00389 TCHAR szBuffer[2048] = { 0 };
00390 CString strFormat;
00391 va_list pArgs;
00392
00393 LoadString( strFormat, nMessageID );
00394 va_start( pArgs, nMessageID );
00395 _vsntprintf( szBuffer, 2040, strFormat, pArgs );
00396 _tcscat( szBuffer, _T("\r\n") );
00397 va_end( pArgs );
00398
00399 int nLen = pCtrl->GetWindowTextLength();
00400 pCtrl->SetSel( nLen, nLen );
00401 pCtrl->ReplaceSel( szBuffer );
00402 nLen += _tcslen( szBuffer );
00403 pCtrl->SetSel( nLen, nLen );
00404 }