13b7203622 2011-02-23 kinaba: // Noah.cpp 13b7203622 2011-02-23 kinaba: // -- entrypoint etc for 'Noah' 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: #include "stdafx.h" 13b7203622 2011-02-23 kinaba: #include "NoahApp.h" 13b7203622 2011-02-23 kinaba: #include "resource.h" 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: #if _MSC_VER >= 1300 13b7203622 2011-02-23 kinaba: extern "C" { int _afxForceEXCLUDE; } 13b7203622 2011-02-23 kinaba: extern "C" BOOL WINAPI _imp__IsDebuggerPresent() { return FALSE; } 13b7203622 2011-02-23 kinaba: #endif 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // プロセス個数制限ゾーン 13b7203622 2011-02-23 kinaba: class ProcessNumLimitZone 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: HANDLE m_han; 13b7203622 2011-02-23 kinaba: public: 13b7203622 2011-02-23 kinaba: ProcessNumLimitZone(int Max, const char* name) 13b7203622 2011-02-23 kinaba: : m_han( ::CreateSemaphore( NULL, Max, Max, name ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( m_han ) 13b7203622 2011-02-23 kinaba: ::WaitForSingleObject( m_han, INFINITE ); 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: kiSUtil::msgLastError("CreateSemaphore Failed"); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: ~ProcessNumLimitZone() 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( m_han ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: ::ReleaseSemaphore( m_han, 1, NULL ); 13b7203622 2011-02-23 kinaba: ::CloseHandle( m_han ); 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: //--------- Noah のエントリポイント ------------// 13b7203622 2011-02-23 kinaba: //----------------------------------------------// 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void kilib_create_new_app() 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- kilib にアプリケーションを設定 13b7203622 2011-02-23 kinaba: new CNoahApp; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahApp::run( kiCmdParser& cmd ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 初期化 13b7203622 2011-02-23 kinaba: m_cnfMan.init(); 13b7203622 2011-02-23 kinaba: m_arcMan.init(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- コマンドラインパラメータ保持 13b7203622 2011-02-23 kinaba: m_pCmd = &cmd; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 「ファイル名が渡されてない or Shift押し起動」なら設定画面表示 13b7203622 2011-02-23 kinaba: if( cmd.param().len()==0 || keyPushed(VK_SHIFT) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- Load-INI ( 全部 ) 13b7203622 2011-02-23 kinaba: m_cnfMan.load( All ); 13b7203622 2011-02-23 kinaba: //-- 設定画面表示 13b7203622 2011-02-23 kinaba: m_cnfMan.dialog(); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 圧縮解凍などの作業 13b7203622 2011-02-23 kinaba: do_cmdline( true ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 終了処理 13b7203622 2011-02-23 kinaba: m_tmpDir.remove(); 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 CNoahApp::is_writable_dir( const kiPath& path ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // 要するに、CDROM/DVDROM を切りたい。 13b7203622 2011-02-23 kinaba: // FDD, PacketWriteなDisk を切るのはあきらめる。 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: // RAMDISK, REMOTE, FIXED, UNKNOWN なディスクは書き込み可能と見なす 13b7203622 2011-02-23 kinaba: UINT drv = path.getDriveType(); 13b7203622 2011-02-23 kinaba: if( drv==DRIVE_REMOVABLE || drv==DRIVE_CDROM ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // 素Win95では使えない関数なのでDynamicLoad 13b7203622 2011-02-23 kinaba: typedef BOOL (WINAPI*pGDFSE)( LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER ); 13b7203622 2011-02-23 kinaba: pGDFSE pGetDiskFreeSpaceEx 13b7203622 2011-02-23 kinaba: = (pGDFSE) ::GetProcAddress( ::GetModuleHandle("kernel32.dll"), "GetDiskFreeSpaceExA" ); 13b7203622 2011-02-23 kinaba: if( pGetDiskFreeSpaceEx ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: // 空き容量が0なら、書き込み不可とみなす 13b7203622 2011-02-23 kinaba: ULARGE_INTEGER fs, dummy; 13b7203622 2011-02-23 kinaba: pGetDiskFreeSpaceEx( path, &dummy, &dummy, &fs ); 13b7203622 2011-02-23 kinaba: if( fs.QuadPart == 0 ) 13b7203622 2011-02-23 kinaba: return false; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: return true; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahApp::do_cmdline( bool directcall ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: do_files( m_pCmd->param(), &m_pCmd->option(), !directcall ); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: void CNoahApp::do_files( const cCharArray& files, 13b7203622 2011-02-23 kinaba: const cCharArray* opts, 13b7203622 2011-02-23 kinaba: bool basicaly_ignore ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: struct local { 13b7203622 2011-02-23 kinaba: ~local() {kiSUtil::switchCurDirToExeDir(); } // ディレクトリロックしないように 13b7203622 2011-02-23 kinaba: } _; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- Archiver Manager にファイル名リストを記憶する 13b7203622 2011-02-23 kinaba: if( 0 == m_arcMan.set_files( files ) ) 13b7203622 2011-02-23 kinaba: return; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 作業用変数 13b7203622 2011-02-23 kinaba: enum { unknown, melt, compress } 13b7203622 2011-02-23 kinaba: whattodo = unknown; 13b7203622 2011-02-23 kinaba: bool ctrl_mlt = keyPushed( VK_CONTROL ); 13b7203622 2011-02-23 kinaba: bool ctrl_cmp = ctrl_mlt; 13b7203622 2011-02-23 kinaba: bool alt = keyPushed( VK_MENU ) || keyPushed( VK_RWIN ) || keyPushed( VK_LWIN ); 13b7203622 2011-02-23 kinaba: const char *cmptype=NULL, *method=NULL; 13b7203622 2011-02-23 kinaba: kiPath destdir; 13b7203622 2011-02-23 kinaba: kiStr tmp(300); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- ( もしあれば )コマンドラインオプションを解釈 13b7203622 2011-02-23 kinaba: if( opts ) 13b7203622 2011-02-23 kinaba: for( unsigned int i=0; i!=opts->len(); i++ ) 13b7203622 2011-02-23 kinaba: switch( (*opts)[i][1] ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: case 'a': if( !basicaly_ignore ) 13b7203622 2011-02-23 kinaba: case 'A': whattodo = compress; break; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: case 'x': if( !basicaly_ignore ) 13b7203622 2011-02-23 kinaba: case 'X': whattodo = melt; break; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: case 'd': if( !basicaly_ignore ) 13b7203622 2011-02-23 kinaba: case 'D': destdir = (*opts)[i]+2; break; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: case 'w': if( !basicaly_ignore ) 13b7203622 2011-02-23 kinaba: case 'W': alt = true; break; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: case 't': if( !basicaly_ignore ) 13b7203622 2011-02-23 kinaba: case 'T': cmptype = (*opts)[i]+2; break; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: case 'm': if( !basicaly_ignore ) 13b7203622 2011-02-23 kinaba: case 'M': method = (*opts)[i]+2; break; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: case 'c': if( !basicaly_ignore ) { 13b7203622 2011-02-23 kinaba: case 'C': if((*opts)[i][2]!='x') ctrl_cmp = true; 13b7203622 2011-02-23 kinaba: if((*opts)[i][2]!='a') ctrl_mlt = true; 13b7203622 2011-02-23 kinaba: break;} 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- Load-INI ( 動作モード設定 ) 13b7203622 2011-02-23 kinaba: m_cnfMan.load( Mode ); 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: // ・そうでなければ、まずNoahの動作モード取得 13b7203622 2011-02-23 kinaba: // m0:圧縮専用 m1:圧縮優先 m2:解凍優先 m3:解凍専用 13b7203622 2011-02-23 kinaba: // コマンドラインで解凍と指定されていれば m3。 13b7203622 2011-02-23 kinaba: // 指定が無ければ、m_cnfMan から読み込み。 13b7203622 2011-02-23 kinaba: // 13b7203622 2011-02-23 kinaba: // ・m0 か、'm1でしかもファイルが複数' の時は無条件で圧縮へ 13b7203622 2011-02-23 kinaba: // 13b7203622 2011-02-23 kinaba: // ・そうでなければ、解凍ルーチンを割り当ててみる。 13b7203622 2011-02-23 kinaba: // この際、m3 以外のときは一個でも割り当て失敗したらエラー>圧縮へ 13b7203622 2011-02-23 kinaba: // m3 でも、一個も割り当てられなければエラー。>処理終了 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: if( whattodo != compress ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: int mode = 3; 13b7203622 2011-02-23 kinaba: if( whattodo != melt ) 13b7203622 2011-02-23 kinaba: mode = m_cnfMan.mode(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: if( mode==0 || ( mode==1 && m_arcMan.file_num()>=2 ) ) 13b7203622 2011-02-23 kinaba: whattodo = compress; 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 解凍ルーチン割り当ててみる 13b7203622 2011-02-23 kinaba: bool suc = m_arcMan.map_melters( mode ); 13b7203622 2011-02-23 kinaba: if( suc ) 13b7203622 2011-02-23 kinaba: whattodo = melt; 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( mode != 3 ) 13b7203622 2011-02-23 kinaba: whattodo = compress; 13b7203622 2011-02-23 kinaba: else 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 解凍専用モードだけど解凍不可!! 13b7203622 2011-02-23 kinaba: msgBox( tmp.loadRsrc(IDS_M_ERROR) ); 13b7203622 2011-02-23 kinaba: return; 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: if( whattodo == melt ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 解凍設定は既にm_cnfMan.init()でロードされている… 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: if( destdir.len()==0 ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 解凍先ディレクトリ取得 13b7203622 2011-02-23 kinaba: if( m_cnfMan.mdirsm() ) 13b7203622 2011-02-23 kinaba: if( is_writable_dir(m_arcMan.get_basepath()) ) 13b7203622 2011-02-23 kinaba: destdir = m_arcMan.get_basepath(); 13b7203622 2011-02-23 kinaba: if( destdir.len()==0 ) 13b7203622 2011-02-23 kinaba: destdir = m_cnfMan.mdir(); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 解凍 13b7203622 2011-02-23 kinaba: if( ctrl_mlt ) m_arcMan.do_listing( destdir ); 13b7203622 2011-02-23 kinaba: else { 13b7203622 2011-02-23 kinaba: ProcessNumLimitZone zone( mycnf().multiboot_limit(), "LimitterForNoahAtKmonosNet" ); 13b7203622 2011-02-23 kinaba: m_arcMan.do_melting( destdir ); 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: //-- Load-INI( 圧縮設定 ) 13b7203622 2011-02-23 kinaba: m_cnfMan.load( Compress ); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: if( destdir.len()==0 ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 圧縮先ディレクトリ取得 13b7203622 2011-02-23 kinaba: if( m_cnfMan.cdirsm() ) 13b7203622 2011-02-23 kinaba: if( is_writable_dir(m_arcMan.get_basepath()) ) 13b7203622 2011-02-23 kinaba: destdir = m_arcMan.get_basepath(); 13b7203622 2011-02-23 kinaba: if( destdir.len()==0 ) 13b7203622 2011-02-23 kinaba: destdir = m_cnfMan.cdir(); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: if( !cmptype ) cmptype = m_cnfMan.cext(); 13b7203622 2011-02-23 kinaba: else if( !method ) method = ""; 13b7203622 2011-02-23 kinaba: if( !method ) method = m_cnfMan.cmhd(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 圧縮用ルーチンを割り当て 13b7203622 2011-02-23 kinaba: if( !m_arcMan.map_compressor( cmptype, method, ctrl_cmp ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- 圧縮不能な形式!! 13b7203622 2011-02-23 kinaba: msgBox( tmp.loadRsrc(IDS_C_ERROR) ); 13b7203622 2011-02-23 kinaba: return; 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- 圧縮 13b7203622 2011-02-23 kinaba: ProcessNumLimitZone zone( mycnf().multiboot_limit(), "LimitterForNoahAtKmonosNet" ); 13b7203622 2011-02-23 kinaba: m_arcMan.do_compressing( destdir, alt ); 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: // from= 0:normal 1:melt 2:compress 13b7203622 2011-02-23 kinaba: void CNoahApp::open_folder( const kiPath& path, int from ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: if( from==1 || from==2 ) //-- Shellに更新通知 13b7203622 2011-02-23 kinaba: ::SHChangeNotify( SHCNE_UPDATEDIR, SHCNF_PATH, (const void*)(const char*)path, NULL ); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: //-- デスクトップだったら開かない 13b7203622 2011-02-23 kinaba: kiPath dir(path), tmp(kiPath::Dsk,false); 13b7203622 2011-02-23 kinaba: dir.beBackSlash(false), dir.beShortPath(), tmp.beShortPath(); 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: if( !tmp.isSame( dir ) ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: //-- Load-INI( フォルダ開き設定 ) 13b7203622 2011-02-23 kinaba: m_cnfMan.load( OpenDir ); 13b7203622 2011-02-23 kinaba: if( (from==1 && !m_cnfMan.modir()) 13b7203622 2011-02-23 kinaba: || (from==2 && !m_cnfMan.codir()) ) 13b7203622 2011-02-23 kinaba: return; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: char cmdline[1000]; 13b7203622 2011-02-23 kinaba: wsprintf( cmdline, m_cnfMan.openby(), (const char*)dir ); 13b7203622 2011-02-23 kinaba: ::WinExec( cmdline, SW_SHOWDEFAULT ); 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 CNoahApp::get_tempdir( kiPath& tmp ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: char buf[MAX_PATH]; 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: if( m_tmpDir.len()==0 ) 13b7203622 2011-02-23 kinaba: { 13b7203622 2011-02-23 kinaba: ::GetTempFileName( kiPath( kiPath::Tmp ), "noa", 0, buf ); 13b7203622 2011-02-23 kinaba: ::DeleteFile( buf ); 13b7203622 2011-02-23 kinaba: m_tmpDir = buf; 13b7203622 2011-02-23 kinaba: m_tmpDir.beBackSlash( true ); 13b7203622 2011-02-23 kinaba: m_tmpDir.mkdir(); 13b7203622 2011-02-23 kinaba: m_tmpID = ::GetCurrentProcessId(); 13b7203622 2011-02-23 kinaba: } 13b7203622 2011-02-23 kinaba: 13b7203622 2011-02-23 kinaba: ::GetTempFileName( m_tmpDir, "noa", m_tmpID++, buf ); 13b7203622 2011-02-23 kinaba: ::DeleteFile( buf ); 13b7203622 2011-02-23 kinaba: tmp = buf; 13b7203622 2011-02-23 kinaba: tmp.beBackSlash( true ); 13b7203622 2011-02-23 kinaba: tmp.mkdir(); 13b7203622 2011-02-23 kinaba: }