File Annotation

Not logged in
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: }