13b7203622 2011-02-23 kinaba: // NoahAM.cpp 13b7203622 2011-02-23 kinaba: //-- control many archiver routines -- 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: #include "stdafx.h" 13b7203622 2011-02-23 kinaba: #include "resource.h" 13b7203622 2011-02-23 kinaba: #include "NoahApp.h" 13b7203622 2011-02-23 kinaba: #include "NoahAM.h" 13b7203622 2011-02-23 kinaba: #include "ArcDLL.h" 13b7203622 2011-02-23 kinaba: #include "ArcAce.h" 13b7203622 2011-02-23 kinaba: #include "ArcMsc.h" 13b7203622 2011-02-23 kinaba: #include "ArcB2e.h" 13b7203622 2011-02-23 kinaba: #include "ArcCpt.h" 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: //------ 実働部隊のデータで初期化しておく ------// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahArchiverManager::init() 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: const char* kl = mycnf().kill(); 13b7203622 2011-02-23 kinaba: static int dead[128]; 13b7203622 2011-02-23 kinaba: while( *kl ) dead[ 0x7f & (*(kl++)) ] = 1; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // 初期対応形式 13b7203622 2011-02-23 kinaba: if( !dead['L'] ) m_AList.add( new CArcLzh ); 13b7203622 2011-02-23 kinaba: if( !dead['7'] ) m_AList.add( new CArc7z ), 13b7203622 2011-02-23 kinaba: m_AList.add( new CArc7zZip ); 13b7203622 2011-02-23 kinaba: if( !dead['Z'] ) m_AList.add( new CArcUnZip ); 13b7203622 2011-02-23 kinaba: if( !dead['z'] ) m_AList.add( new CArcZip ); 13b7203622 2011-02-23 kinaba: if( !dead['T'] ) m_AList.add( new CArcTar ); 13b7203622 2011-02-23 kinaba: if( !dead['C'] ) m_AList.add( new CArcCab ); 13b7203622 2011-02-23 kinaba: if( !dead['R'] ) m_AList.add( new CArcRar ); 13b7203622 2011-02-23 kinaba: if( !dead['A'] ) m_AList.add( new CArcArj ); 13b7203622 2011-02-23 kinaba: if( !dead['B'] ) m_AList.add( new CArcBga ); 13b7203622 2011-02-23 kinaba: if( !dead['Y'] ) m_AList.add( new CArcYz1 ); 13b7203622 2011-02-23 kinaba: if( !dead['G'] ) m_AList.add( new CArcGca ); 13b7203622 2011-02-23 kinaba: if( !dead['a'] ) m_AList.add( new CArcAce ); 13b7203622 2011-02-23 kinaba: if( !dead['M'] ) m_AList.add( new CArcMsc ); 13b7203622 2011-02-23 kinaba: if( !dead['c'] ) m_AList.add( new CArcCpt ); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // 拡張スクリプトロード 13b7203622 2011-02-23 kinaba: char prev_cur[MAX_PATH]; 13b7203622 2011-02-23 kinaba: ::GetCurrentDirectory(MAX_PATH, prev_cur); 13b7203622 2011-02-23 kinaba: ::SetCurrentDirectory( CArcB2e::init_b2e_path() ); 13b7203622 2011-02-23 kinaba: kiFindFile find; 13b7203622 2011-02-23 kinaba: find.begin( "*.b2e" ); 13b7203622 2011-02-23 kinaba: WIN32_FIND_DATA fd; 13b7203622 2011-02-23 kinaba: for( int t=0; find.next(&fd); t++ ) 13b7203622 2011-02-23 kinaba: m_AList.add( new CArcB2e(fd.cFileName) ); 13b7203622 2011-02-23 kinaba: m_b2e = (t>1); 13b7203622 2011-02-23 kinaba: ::SetCurrentDirectory(prev_cur); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: //------------ ファイルリストを記憶 ------------// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: unsigned long CNoahArchiverManager::set_files( const cCharArray& files ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- クリア 13b7203622 2011-02-23 kinaba: m_FName.empty(); 13b7203622 2011-02-23 kinaba: m_BasePathList.empty(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 基底パスを取得( 出来るだけ利用範囲を広げるため、8.3形式で ) 13b7203622 2011-02-23 kinaba: if( files.len() != 0 ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: char spath[MAX_PATH]; 13b7203622 2011-02-23 kinaba: m_BasePath = 13b7203622 2011-02-23 kinaba: ( 0!=::GetShortPathName( files[0], spath, MAX_PATH ) ) 13b7203622 2011-02-23 kinaba: ? spath : ""; 13b7203622 2011-02-23 kinaba: if( !m_BasePath.beDirOnly() ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: m_BasePath.beSpecialPath( kiPath::Cur ); 13b7203622 2011-02-23 kinaba: m_BasePath.beBackSlash( true ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 短いファイル名と長いのを両方取得しておく 13b7203622 2011-02-23 kinaba: m_FName.alloc( files.len() ); 13b7203622 2011-02-23 kinaba: m_BasePathList.alloc( files.len() ); 13b7203622 2011-02-23 kinaba: for( unsigned int i=0,c=0; i!=files.len(); i++ ) 13b7203622 2011-02-23 kinaba: if( kiFindFile::findfirst( files[i], &m_FName[c] ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( m_FName[c].cAlternateFileName[0] == '\0' ) 13b7203622 2011-02-23 kinaba: ::lstrcpy(m_FName[c].cAlternateFileName,m_FName[c].cFileName); 13b7203622 2011-02-23 kinaba: m_BasePathList[c] = files[i]; 13b7203622 2011-02-23 kinaba: if( !m_BasePathList[c].beDirOnly() ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: m_BasePathList[c].beSpecialPath( kiPath::Cur ); 13b7203622 2011-02-23 kinaba: m_BasePathList[c].beBackSlash( true ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: ++c; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: m_FName.forcelen( c ); 13b7203622 2011-02-23 kinaba: m_BasePathList.forcelen( c ); 13b7203622 2011-02-23 kinaba: return c; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: //--- ファイルリストに解凍ルーチンを割り当て ---// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // 指定された拡張子に対応しているルーチンを線形探索 13b7203622 2011-02-23 kinaba: CArchiver* CNoahArchiverManager::fromExt( const char* ext ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: kiStr tmp = ext; 13b7203622 2011-02-23 kinaba: tmp.lower(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=m_AList.len(); i++ ) 13b7203622 2011-02-23 kinaba: if( m_AList[i]->extCheck( tmp ) 13b7203622 2011-02-23 kinaba: && (m_AList[i]->ability() & aMelt) ) 13b7203622 2011-02-23 kinaba: return m_AList[i]; 13b7203622 2011-02-23 kinaba: return NULL; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: bool CNoahArchiverManager::map_melters( int mode ) // 1:cmp 2:mlt 3:must_mlt 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // クリア 13b7203622 2011-02-23 kinaba: m_Melters.empty(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: #define attrb (m_FName[ct].dwFileAttributes) 13b7203622 2011-02-23 kinaba: #define lname (m_FName[ct].cFileName) 13b7203622 2011-02-23 kinaba: #define sname (m_FName[ct].cAlternateFileName[0]==0 ? m_FName[ct].cFileName : m_FName[ct].cAlternateFileName) 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: kiPath fnm; 13b7203622 2011-02-23 kinaba: const char* ext; 13b7203622 2011-02-23 kinaba: for( unsigned int ct=0, bad=0; ct!=file_num(); ct++ ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // fnm = m_BasePath, fnm += sname; 13b7203622 2011-02-23 kinaba: fnm = m_BasePathList[ct], fnm += sname; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 0byteファイル / ディレクトリは弾く 13b7203622 2011-02-23 kinaba: if( !(attrb & FILE_ATTRIBUTE_DIRECTORY) && 0!=kiFile::getSize( fnm, 0 ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- まず対応拡張子かどうかで候補Aを一つ選出 13b7203622 2011-02-23 kinaba: CArchiver* x = fromExt( ext=kiPath::ext(lname) ); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 候補Aで、ファイル内容によるチェック 13b7203622 2011-02-23 kinaba: if( x && x->check( fnm ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: m_Melters.add( x ); 13b7203622 2011-02-23 kinaba: continue; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 候補Aが内容チェック不可なものだったらそれを使う 13b7203622 2011-02-23 kinaba: if( x && !(x->ability() & aCheck) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: m_Melters.add( x ); 13b7203622 2011-02-23 kinaba: continue; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 候補Aがダメなら、その他の内容チェック可能なルーチン全てで試す 13b7203622 2011-02-23 kinaba: if( mode!=1 || 0==ki_strcmpi( "exe", ext ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: for( unsigned long j=0; j!=m_AList.len(); j++ ) 13b7203622 2011-02-23 kinaba: if( m_AList[j]!=x && m_AList[j]->check( fnm ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: m_Melters.add( m_AList[j] ); 13b7203622 2011-02-23 kinaba: break; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: if( m_Melters.len() == ct+1 ) 13b7203622 2011-02-23 kinaba: continue; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- チェックの結果、解凍不能でしたとさ 13b7203622 2011-02-23 kinaba: if( mode!=3 ) 13b7203622 2011-02-23 kinaba: return false; //-- 解凍専用モードでなければ終了 13b7203622 2011-02-23 kinaba: m_Melters.add( NULL ), bad++; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: #undef sname 13b7203622 2011-02-23 kinaba: #undef lname 13b7203622 2011-02-23 kinaba: #undef attrb 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: return (ct!=bad); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: //--- ファイルリストに圧縮ルーチンを割り当て ---// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: bool CNoahArchiverManager::map_compressor( const char* ext, const char* method, bool sfx ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: int m; 13b7203622 2011-02-23 kinaba: m_Method = -1; 13b7203622 2011-02-23 kinaba: m_Sfx = sfx; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=m_AList.len(); i++ ) 13b7203622 2011-02-23 kinaba: if( -1 != (m=m_AList[i]->cancompressby(ext,method,sfx)) ) 13b7203622 2011-02-23 kinaba: if( m!=-2 ) // 完全一致 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: m_Compressor = m_AList[i]; 13b7203622 2011-02-23 kinaba: m_Method = m; 13b7203622 2011-02-23 kinaba: break; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: else if( m_Method == -1 ) // 形式名のみ一致した最初のモノ 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: m_Compressor = m_AList[i]; 13b7203622 2011-02-23 kinaba: m_Method = m_AList[i]->cmp_mhd_default(); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: return (m_Method != -1); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: //------------ バージョン情報文字列 ------------// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahArchiverManager::get_version( kiStr& str ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: kiStr tmp; 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=m_AList.len(); i++ ) 13b7203622 2011-02-23 kinaba: if( m_AList[i]->ver( tmp ) ) 13b7203622 2011-02-23 kinaba: str+=tmp, str+="\r\n"; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: //--------------- 圧縮形式リスト ---------------// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: static unsigned int find( const cCharArray& x, const char* o ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=x.len(); i++ ) 13b7203622 2011-02-23 kinaba: if( 0==ki_strcmp( x[i], o ) ) 13b7203622 2011-02-23 kinaba: return i; 13b7203622 2011-02-23 kinaba: return 0xffffffff; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: static unsigned int find( const StrArray& x, const char* o ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=x.len(); i++ ) 13b7203622 2011-02-23 kinaba: if( x[i]==o ) 13b7203622 2011-02-23 kinaba: return i; 13b7203622 2011-02-23 kinaba: return 0xffffffff; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahArchiverManager::get_cmpmethod( 13b7203622 2011-02-23 kinaba: const char* set, 13b7203622 2011-02-23 kinaba: int& def_mhd, 13b7203622 2011-02-23 kinaba: StrArray& mhd_list, 13b7203622 2011-02-23 kinaba: bool need_ext, 13b7203622 2011-02-23 kinaba: cCharArray* ext_list ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: def_mhd = -1; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: const char* x; 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=m_AList.len(); i++ ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( *(x = m_AList[i]->cmp_ext())=='\0' ) 13b7203622 2011-02-23 kinaba: continue; 13b7203622 2011-02-23 kinaba: if( need_ext ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( -1 == find( *ext_list, x ) ) 13b7203622 2011-02-23 kinaba: ext_list->add( x ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: if( 0 == ki_strcmp( set, x ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( mhd_list.len()==0 ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: def_mhd = m_AList[i]->cmp_mhd_default(); 13b7203622 2011-02-23 kinaba: for( unsigned int j=0; j!=m_AList[i]->cmp_mhd_list().len(); j++ ) 13b7203622 2011-02-23 kinaba: mhd_list.add( (m_AList[i]->cmp_mhd_list())[j] ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: for( unsigned int j=0; j!=m_AList[i]->cmp_mhd_list().len(); j++ ) 13b7203622 2011-02-23 kinaba: if( -1 == find( mhd_list, (m_AList[i]->cmp_mhd_list())[j] ) ) 13b7203622 2011-02-23 kinaba: mhd_list.add( (m_AList[i]->cmp_mhd_list())[j] ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: if( def_mhd == -1 ) 13b7203622 2011-02-23 kinaba: def_mhd = 0; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: //--------------- 書庫一覧モード ---------------// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: #include "SubDlg.h" 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahArchiverManager::do_listing( kiPath& destdir ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: kiWindow* mptr = app()->mainwnd(); 13b7203622 2011-02-23 kinaba: kiPath ddir; 13b7203622 2011-02-23 kinaba: int mdf = mycnf().mkdir(); 13b7203622 2011-02-23 kinaba: bool rmn = mycnf().mnonum(); 13b7203622 2011-02-23 kinaba: destdir.beBackSlash( true ); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- ダイアログの個数カウンタをクリア 13b7203622 2011-02-23 kinaba: kiArray<CArcViewDlg*> views; 13b7203622 2011-02-23 kinaba: CArcViewDlg::clear(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- ダイアログ起動 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=m_FName.len(); i++ ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( !m_Melters[i] ) 13b7203622 2011-02-23 kinaba: continue; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: arcname an( 13b7203622 2011-02-23 kinaba: m_BasePathList[i], 13b7203622 2011-02-23 kinaba: // m_BasePath, 13b7203622 2011-02-23 kinaba: m_FName[i].cAlternateFileName[0]==0 ? m_FName[i].cFileName : m_FName[i].cAlternateFileName, 13b7203622 2011-02-23 kinaba: m_FName[i].cFileName ); 13b7203622 2011-02-23 kinaba: ddir = destdir; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: if( mdf ) 13b7203622 2011-02-23 kinaba: generate_dirname( m_FName[i].cFileName, ddir, rmn ); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: CArcViewDlg* x = new CArcViewDlg( m_Melters[i],an,ddir ); 13b7203622 2011-02-23 kinaba: views.add( x ); 13b7203622 2011-02-23 kinaba: x->createModeless( NULL ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 全部終了するまで待機 13b7203622 2011-02-23 kinaba: kiWindow::msgLoop( kiWindow::GET ); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- お終い 13b7203622 2011-02-23 kinaba: app()->setMainWnd( mptr ); 13b7203622 2011-02-23 kinaba: for( i=0; i!=views.len(); i++ ) 13b7203622 2011-02-23 kinaba: delete views[i]; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: //----------------- 解凍作業 -------------------// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahArchiverManager::do_melting( kiPath& destdir ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 設定ロード 13b7203622 2011-02-23 kinaba: const int mdf = mycnf().mkdir(); // Make Directory Flag( 0:no 1:no1file 2: noddir 3:yes ) 13b7203622 2011-02-23 kinaba: const bool rmn = mycnf().mnonum(); // Remove NuMber ? 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 出力先 13b7203622 2011-02-23 kinaba: destdir.beBackSlash( true ); 13b7203622 2011-02-23 kinaba: destdir.mkdir(), destdir.beShortPath(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=m_FName.len(); i++ ) 13b7203622 2011-02-23 kinaba: if( m_Melters[i] ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 出力先 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: int mk=2; // 0:no 1:yes 2:??? 13b7203622 2011-02-23 kinaba: kiPath ddir( destdir ), dnm; 13b7203622 2011-02-23 kinaba: if( mdf==0 ) 13b7203622 2011-02-23 kinaba: mk=0; 13b7203622 2011-02-23 kinaba: else if( mdf==3 ) 13b7203622 2011-02-23 kinaba: mk=1; 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: kiPath anm(m_BasePathList[i]); 13b7203622 2011-02-23 kinaba: // kiPath anm(m_BasePath); 13b7203622 2011-02-23 kinaba: anm+=m_FName[i].cFileName; 13b7203622 2011-02-23 kinaba: int c = m_Melters[i]->contents( anm, dnm ); 13b7203622 2011-02-23 kinaba: if( c==aSingleDir || (c==aSingleFile && mdf==1) ) 13b7203622 2011-02-23 kinaba: mk=0; // 2重フォルダ防止処理(強) 13b7203622 2011-02-23 kinaba: else if( c==aMulti ) 13b7203622 2011-02-23 kinaba: mk=1; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: if( mk ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: generate_dirname( m_FName[i].cFileName, ddir, rmn ); 13b7203622 2011-02-23 kinaba: if( mk==2 && kiSUtil::exist(ddir) ) 13b7203622 2011-02-23 kinaba: mk=1; 13b7203622 2011-02-23 kinaba: ddir+='\\'; 13b7203622 2011-02-23 kinaba: ddir.mkdir(); 13b7203622 2011-02-23 kinaba: ddir.beShortPath(); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 解凍! 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: arcname an( m_BasePathList[i], 13b7203622 2011-02-23 kinaba: // arcname an( m_BasePath, 13b7203622 2011-02-23 kinaba: m_FName[i].cAlternateFileName[0]==0 ? m_FName[i].cFileName : m_FName[i].cAlternateFileName, 13b7203622 2011-02-23 kinaba: m_FName[i].cFileName ); 13b7203622 2011-02-23 kinaba: int result = m_Melters[i]->melt( an, ddir ); 13b7203622 2011-02-23 kinaba: if( result<0x8000 ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( mk==2 ) // 2重フォルダ防止処理(弱) 13b7203622 2011-02-23 kinaba: break_ddir( ddir, mdf==2 ); 13b7203622 2011-02-23 kinaba: else if( mk==0 && dnm.len() ) // 2重フォルダ防止処理(強) 13b7203622 2011-02-23 kinaba: if( dnm.len()<=1 || dnm[1]!=':' ) // 絶対パスは開かない 13b7203622 2011-02-23 kinaba: ddir+=dnm, ddir+='\\'; 13b7203622 2011-02-23 kinaba: // 出力先を開くかも 13b7203622 2011-02-23 kinaba: myapp().open_folder( ddir, 1 ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: else if( result!=0x8020 ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //エラー! 13b7203622 2011-02-23 kinaba: char str[255]; 13b7203622 2011-02-23 kinaba: wsprintf( str, "%s\nError No: [%x]", 13b7203622 2011-02-23 kinaba: (const char*)kiStr().loadRsrc( IDS_M_ERROR ), result ); 13b7203622 2011-02-23 kinaba: app()->msgBox( str ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahArchiverManager::generate_dirname( const char* src, kiPath& dst, bool rmn ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // srcで示された書庫名からディレクトリ名を生成し、 13b7203622 2011-02-23 kinaba: // dstへ足す。rmn==trueなら末尾の数字も削除 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // 一番左の . と左から二番目の . を探す 13b7203622 2011-02-23 kinaba: const char *fdot=NULL, *sdot=NULL, *tail; 13b7203622 2011-02-23 kinaba: for( tail=src; *tail; tail=kiStr::next(tail) ) 13b7203622 2011-02-23 kinaba: if( *tail=='.' ) 13b7203622 2011-02-23 kinaba: sdot=fdot, fdot=tail; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // .tar.xxx か、.xxx.gz/.xxx.z/.xxx.bz2 なら二つ削除 13b7203622 2011-02-23 kinaba: if( fdot ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: tail = fdot; 13b7203622 2011-02-23 kinaba: if( sdot ) 13b7203622 2011-02-23 kinaba: if( 0==::lstrcmpi(fdot,".gz") 13b7203622 2011-02-23 kinaba: || 0==::lstrcmpi(fdot,".z") 13b7203622 2011-02-23 kinaba: || 0==::lstrcmpi(fdot,".bz2") 13b7203622 2011-02-23 kinaba: || (sdot+4==fdot 13b7203622 2011-02-23 kinaba: && (sdot[1]=='t'||sdot[1]=='T') 13b7203622 2011-02-23 kinaba: && (sdot[2]=='a'||sdot[2]=='A') 13b7203622 2011-02-23 kinaba: && (sdot[3]=='r'||sdot[3]=='R') 13b7203622 2011-02-23 kinaba: )) 13b7203622 2011-02-23 kinaba: tail = sdot; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // 末尾の数字と'-'と'_'と'.'削除。半角スペースも。 13b7203622 2011-02-23 kinaba: bool del[256]; 13b7203622 2011-02-23 kinaba: ki_memzero( del, sizeof(del) ); 13b7203622 2011-02-23 kinaba: if( rmn ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: del['-'] = del['_'] = del['.'] = true; 13b7203622 2011-02-23 kinaba: for( char c='0'; c<='9'; ++c ) 13b7203622 2011-02-23 kinaba: del[c] = true; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: del[' '] = true; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: const char* mjs=NULL; 13b7203622 2011-02-23 kinaba: for( const char *x=src; x<tail; x=kiStr::next(x) ) 13b7203622 2011-02-23 kinaba: if( !del[(unsigned char)(*x)] ) 13b7203622 2011-02-23 kinaba: mjs = NULL; 13b7203622 2011-02-23 kinaba: else if( !mjs ) 13b7203622 2011-02-23 kinaba: mjs = x; 13b7203622 2011-02-23 kinaba: if( mjs && mjs!=src ) 13b7203622 2011-02-23 kinaba: tail = mjs; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // 空になってしまったら "noahmelt" という名前にしてしまう。 13b7203622 2011-02-23 kinaba: if( src==tail ) 13b7203622 2011-02-23 kinaba: dst += "noahmelt"; 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: while( src!=tail ) 13b7203622 2011-02-23 kinaba: dst += *src++; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: bool CNoahArchiverManager::break_ddir( kiPath& dir, bool onlydir ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // 2重フォルダ or 単一ファイル 状態を解消 13b7203622 2011-02-23 kinaba: // 13b7203622 2011-02-23 kinaba: // 素直に格納ファイル名を一度走査するのが本当なんですが、 13b7203622 2011-02-23 kinaba: // 特に巨大書庫の時速度低下が激しいのと、FindFirst系を 13b7203622 2011-02-23 kinaba: // サポートしたDLLや内蔵エンジン以外に対応できないという 13b7203622 2011-02-23 kinaba: // 欠点があるため、相変わらず Noah 2.xx と同じ手法です。 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 中に1個しか入ってないことを確認 ----------------- 13b7203622 2011-02-23 kinaba: char wild[MAX_PATH]; 13b7203622 2011-02-23 kinaba: ki_strcpy( wild, dir ); 13b7203622 2011-02-23 kinaba: ki_strcat( wild, "*.*" ); 13b7203622 2011-02-23 kinaba: kiFindFile find; 13b7203622 2011-02-23 kinaba: if( !find.begin( wild ) ) 13b7203622 2011-02-23 kinaba: return false; 13b7203622 2011-02-23 kinaba: WIN32_FIND_DATA fd,fd2,fd3; 13b7203622 2011-02-23 kinaba: find.next( &fd ); 13b7203622 2011-02-23 kinaba: if( find.next( &fd2 ) ) 13b7203622 2011-02-23 kinaba: return false; 13b7203622 2011-02-23 kinaba: find.close(); 13b7203622 2011-02-23 kinaba: //---------------------------------------------------- 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- to:最終移動先ファイル名。ついでに、カレントDirは消せない問題の回避策 ----- 13b7203622 2011-02-23 kinaba: kiPath to(dir); to.beBackSlash( false ), to.beDirOnly(); 13b7203622 2011-02-23 kinaba: ::SetCurrentDirectory( to ); 13b7203622 2011-02-23 kinaba: to += fd.cFileName; 13b7203622 2011-02-23 kinaba: //------------------------------------------------------------------------- 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- ファイルだった場合 -------------------------------------- 13b7203622 2011-02-23 kinaba: if( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( !onlydir ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // now 現在のファイル名 13b7203622 2011-02-23 kinaba: kiStr now=dir; now+=fd.cFileName; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // now -> to 移動 13b7203622 2011-02-23 kinaba: if( ::MoveFile( now, to ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: dir.remove(); 13b7203622 2011-02-23 kinaba: dir.beBackSlash( false ), dir.beDirOnly(); 13b7203622 2011-02-23 kinaba: return true; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: //-- フォルダだった場合 ---------------------------------------- 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // 'base/aaa/aaa/' だと中のaaaを外にmoveできない。 13b7203622 2011-02-23 kinaba: // よって、回避策。-> 'base/aaa_noah_tmp_178116/aaa/' 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: dir.beBackSlash( false ); 13b7203622 2011-02-23 kinaba: kiFindFile::findfirst( dir, &fd3 ); 13b7203622 2011-02-23 kinaba: kiPath dirx( dir ); dirx+="_noah_tmp_178116"; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: if( ::MoveFile( dir, dirx ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // now 現在のファイル名 13b7203622 2011-02-23 kinaba: kiStr now( dirx ); now+='\\', now+=fd.cFileName; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // ディレクトリを移動 13b7203622 2011-02-23 kinaba: if( ::MoveFile( now, to ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: dirx.remove(); 13b7203622 2011-02-23 kinaba: dir=to, dir.beBackSlash( true ); 13b7203622 2011-02-23 kinaba: return true; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // 'base/aaa_noah_tmp_178116/aaa/' -> 'base/aaa/aaa/' 13b7203622 2011-02-23 kinaba: dir.beDirOnly(), dir+=fd3.cFileName; 13b7203622 2011-02-23 kinaba: ::MoveFile( dirx, dir ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: dir.beBackSlash( true ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: //------------------------------------------------------------ 13b7203622 2011-02-23 kinaba: return false; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: //----------------- 圧縮作業 -------------------// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahArchiverManager::do_compressing( kiPath& destdir, bool each ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: int result = 0xffff, tr; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // 出力先を確実に作っておく 13b7203622 2011-02-23 kinaba: destdir.beBackSlash( true ); 13b7203622 2011-02-23 kinaba: destdir.mkdir(); 13b7203622 2011-02-23 kinaba: destdir.beShortPath(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // 個別圧縮モードか、Archiving不可の形式なら一個ずつ 13b7203622 2011-02-23 kinaba: if( each || !(m_Compressor->ability() & aArchive) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: wfdArray templist; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=m_FName.len(); i++ ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: templist.empty(); 13b7203622 2011-02-23 kinaba: templist.add( m_FName[i] ); 13b7203622 2011-02-23 kinaba: tr = m_Compressor->compress( m_BasePath,templist,destdir,m_Method,m_Sfx ); 13b7203622 2011-02-23 kinaba: if( tr<0x8000 || tr==0x8020 ) 13b7203622 2011-02-23 kinaba: result = tr; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: result = m_Compressor->compress( m_BasePath,m_FName,destdir,m_Method,m_Sfx ); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // 開くかも 13b7203622 2011-02-23 kinaba: if( result<0x8000 ) 13b7203622 2011-02-23 kinaba: myapp().open_folder( destdir, 2 ); 13b7203622 2011-02-23 kinaba: else if( result!=0x8020 ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //エラー! 13b7203622 2011-02-23 kinaba: char str[255]; 13b7203622 2011-02-23 kinaba: wsprintf( str, "%s\nError No: [%x]", "Compression Error", result ); 13b7203622 2011-02-23 kinaba: app()->msgBox( str ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: }