File Annotation

Not logged in
13b7203622 2011-02-23        kinaba: // Archiver.cpp
13b7203622 2011-02-23        kinaba: //-- CArchiver -- common interface in 'Noah' for archiving routine --
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: #include "stdafx.h"
13b7203622 2011-02-23        kinaba: #include "Archiver.h"
13b7203622 2011-02-23        kinaba: #include "NoahApp.h"
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: CArcModule::CArcModule( const char* name, bool us )
13b7203622 2011-02-23        kinaba: 	: m_dll(NULL)
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	// SearchPathの前にカレントディレクトリをnoah.exeと同じ場所へ
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: 	kiSUtil::switchCurDirToExeDir();
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	if( 0!=::SearchPath( NULL,name,NULL,MAX_PATH,m_name,NULL ) )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		const char* xt=kiPath::ext(name);
13b7203622 2011-02-23        kinaba: 		if( 0!=ki_strcmpi("dll",xt) )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			// EXEの場合
13b7203622 2011-02-23        kinaba: 			m_type = us ? EXEUS : EXE;
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 		else
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			// DLLの場合
13b7203622 2011-02-23        kinaba: 			m_dll = new kiArcDLLRaw(name);
13b7203622 2011-02-23        kinaba: 			m_type = DLL;
13b7203622 2011-02-23        kinaba: 			if(name<=xt-8&&xt[-6]=='G'&&xt[-5]=='C'&&xt[-4]=='A' )
13b7203622 2011-02-23        kinaba: 				m_type = DLLGCA;
13b7203622 2011-02-23        kinaba: 			else if(name==xt-6&&xt[-6]=='B'&&xt[-5]=='g'&&xt[-4]=='a' )
13b7203622 2011-02-23        kinaba: 				m_type = DLLBGA;
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: 		// ファイルが無いか、シェルのコマンドの場合
13b7203622 2011-02-23        kinaba: 		// バッファオーバーフローの危険…(^^;
13b7203622 2011-02-23        kinaba: 		ki_strcpy( m_name, name );
13b7203622 2011-02-23        kinaba: 		m_type = SHLCMD;
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// カレントを戻す
13b7203622 2011-02-23        kinaba: 	::SetCurrentDirectory(prev_cur);
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: CArcModule::~CArcModule()
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	delete m_dll;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: int CArcModule::cmd( const char* cmd, bool mini )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	if( m_dll )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		// アーカイバDLLモードなら簡単に終了
13b7203622 2011-02-23        kinaba: 		char buf[1024];
13b7203622 2011-02-23        kinaba: 		return m_dll->command( NULL, cmd, buf, sizeof(buf) );
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// NTかどうかのチェック等
13b7203622 2011-02-23        kinaba: 	kiPath tmpdir;
13b7203622 2011-02-23        kinaba: 	static const bool isNT =
13b7203622 2011-02-23        kinaba: 		(app()->osver().dwPlatformId==VER_PLATFORM_WIN32_NT);
13b7203622 2011-02-23        kinaba: 	static const char* const closeShell =
13b7203622 2011-02-23        kinaba: 		(isNT ? "cmd.exe /c " : "command.com /c ");
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// コマンド文字列作成
13b7203622 2011-02-23        kinaba: 	kiVar theCmd( m_name );
13b7203622 2011-02-23        kinaba: 	theCmd.quote();
13b7203622 2011-02-23        kinaba: 	theCmd += ' ';
13b7203622 2011-02-23        kinaba: 	theCmd += cmd;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	if( m_type==SHLCMD )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		// シェルコマンドの場合
13b7203622 2011-02-23        kinaba: 		theCmd = closeShell + theCmd;
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 	else if( m_type==EXEUS )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		// USモードの場合
13b7203622 2011-02-23        kinaba: 		if( isNT )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			::SetEnvironmentVariable( "NOAHCMD", theCmd );
13b7203622 2011-02-23        kinaba: 			theCmd = "%NOAHCMD%";
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		// 切替バッチファイル生成
13b7203622 2011-02-23        kinaba: 		myapp().get_tempdir(tmpdir);
13b7203622 2011-02-23        kinaba: 		kiPath batname(tmpdir);
13b7203622 2011-02-23        kinaba: 		batname += "ncmd.bat";
13b7203622 2011-02-23        kinaba: 		kiFile bat;
13b7203622 2011-02-23        kinaba: 		bat.open( batname,false );
13b7203622 2011-02-23        kinaba: 		bat.write( "@CHCP 437\r\n@", 12 );
13b7203622 2011-02-23        kinaba: 		bat.write( theCmd, theCmd.len() );
13b7203622 2011-02-23        kinaba: 		bat.write( "\r\n@CHCP 932\r\n", 13 );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		theCmd  = closeShell;
13b7203622 2011-02-23        kinaba: 		theCmd += batname;
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// プロセス開始
13b7203622 2011-02-23        kinaba: 	PROCESS_INFORMATION pi;
13b7203622 2011-02-23        kinaba: 	STARTUPINFO si={sizeof(STARTUPINFO)};
13b7203622 2011-02-23        kinaba: 	si.dwFlags    =STARTF_USESHOWWINDOW;
13b7203622 2011-02-23        kinaba: 	si.wShowWindow=mini?SW_MINIMIZE:SW_SHOW;
13b7203622 2011-02-23        kinaba: 	if( !::CreateProcess( NULL,const_cast<char*>((const char*)theCmd),
13b7203622 2011-02-23        kinaba: 		NULL,NULL,FALSE,CREATE_NEW_PROCESS_GROUP|NORMAL_PRIORITY_CLASS,
13b7203622 2011-02-23        kinaba: 		NULL,NULL, &si,&pi ) )
13b7203622 2011-02-23        kinaba: 		return 0xffff;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 終了待機
13b7203622 2011-02-23        kinaba: 	::CloseHandle( pi.hThread );
13b7203622 2011-02-23        kinaba: 	while( WAIT_OBJECT_0 != ::WaitForSingleObject( pi.hProcess, 500 ) )
13b7203622 2011-02-23        kinaba: 		kiWindow::msg();
13b7203622 2011-02-23        kinaba: 	int ex;
13b7203622 2011-02-23        kinaba: 	::GetExitCodeProcess( pi.hProcess, (DWORD*)&ex );
13b7203622 2011-02-23        kinaba: 	::CloseHandle( pi.hProcess );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 後始末
13b7203622 2011-02-23        kinaba: 	if( m_type==EXEUS )
13b7203622 2011-02-23        kinaba: 		tmpdir.remove();
13b7203622 2011-02-23        kinaba: 	return ex;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: void CArcModule::ver( kiStr& str )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	// バージョン情報を整形して表示
13b7203622 2011-02-23        kinaba: 	char *verstr="----", buf[200];
13b7203622 2011-02-23        kinaba: 	if( m_dll )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		if( WORD ver=m_dll->getVer() )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			WORD sub=m_dll->getVerSub();
13b7203622 2011-02-23        kinaba: 			::wsprintf( verstr=buf, "%d.%02d%c", ver/100, ver%100, (sub<100)?0:sub/100+'a'-1 );
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 	else if( m_type != NOTEXIST )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		// 可能ならリソースからの取得を試みる
13b7203622 2011-02-23        kinaba: 		if( CArchiver::GetVersionInfoStr( m_name, buf, sizeof(buf) ) )
13b7203622 2011-02-23        kinaba: 			verstr = buf;
13b7203622 2011-02-23        kinaba: 		else
13b7203622 2011-02-23        kinaba: 			verstr = "OK!";
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	char ans[300];
13b7203622 2011-02-23        kinaba: 	::wsprintf( ans, "%-12s %s", kiPath::name(m_name), verstr );
13b7203622 2011-02-23        kinaba: 	str = ans;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: bool CArcModule::lst_dll( const arcname& aname, aflArray& files, const char* wild )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	if( !m_dll )
13b7203622 2011-02-23        kinaba: 		return false;
13b7203622 2011-02-23        kinaba: 	kiPath nm(aname.basedir); nm+=aname.lname;
13b7203622 2011-02-23        kinaba: 	HANDLE h = m_dll->openArc( app()->mainhwnd(), nm, M_CHECK_FILENAME_ONLY|M_ERROR_MESSAGE_OFF );
13b7203622 2011-02-23        kinaba: 	if( !h ) return false;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	int ct=0;
13b7203622 2011-02-23        kinaba: 	files.forcelen( 1 );
13b7203622 2011-02-23        kinaba: 	if( 0==m_dll->findfirst( h, wild, &files[0].inf ) )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		do
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			INDIVIDUALINFO& iii = files[ct].inf;
13b7203622 2011-02-23        kinaba: 			files[ct].isfile =
13b7203622 2011-02-23        kinaba: 				 ( *files[ct].inf.szAttribute!='d'
13b7203622 2011-02-23        kinaba: 				&& !kiPath::endwithyen(files[ct].inf.szFileName)
13b7203622 2011-02-23        kinaba: 				&& !(m_dll->getAttr( h )&FILE_ATTRIBUTE_DIRECTORY) );
13b7203622 2011-02-23        kinaba: 			files.forcelen( 1+(++ct) );
13b7203622 2011-02-23        kinaba: 		} while( 0==m_dll->findnext( h, &files[ct].inf ) );
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 	files.forcelen( ct );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	m_dll->closeArc( h );
13b7203622 2011-02-23        kinaba: 	return true;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: int CArcModule::cnt( const kiPath& aname, kiPath& dname, const char* wild )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	int ans = aUnknown;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	if( m_dll )
13b7203622 2011-02-23        kinaba: 		if( HANDLE h = m_dll->openArc( app()->mainhwnd(), aname, M_CHECK_FILENAME_ONLY|M_ERROR_MESSAGE_OFF ) )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			INDIVIDUALINFO inf1st, inf;
13b7203622 2011-02-23        kinaba: 			if( 0==m_dll->findfirst( h, wild, &inf1st ) )
13b7203622 2011-02-23        kinaba: 			{
13b7203622 2011-02-23        kinaba: 				for( const char* y=inf1st.szFileName; *y && *y!='\\' && *y!='/'; y=kiPath::next(y) );
13b7203622 2011-02-23        kinaba: 				if( y!=inf1st.szFileName )
13b7203622 2011-02-23        kinaba: 				{
13b7203622 2011-02-23        kinaba: 					if( 0!=m_dll->findnext( h, &inf ) )
13b7203622 2011-02-23        kinaba: 						ans = *y ? aSingleDir : aSingleFile;
13b7203622 2011-02-23        kinaba: 					else if( *y && (y-inf1st.szFileName!=1 || inf1st.szFileName[0]!='.') )
13b7203622 2011-02-23        kinaba: 					{
13b7203622 2011-02-23        kinaba: 						ans = aSingleDir;
13b7203622 2011-02-23        kinaba: 						do
13b7203622 2011-02-23        kinaba: 							if( !ki_memcmp( inf1st.szFileName, inf.szFileName, (y-inf1st.szFileName)+1 ) )
13b7203622 2011-02-23        kinaba: 							{
13b7203622 2011-02-23        kinaba: 								ans = aUnknown;
13b7203622 2011-02-23        kinaba: 								break;
13b7203622 2011-02-23        kinaba: 							}
13b7203622 2011-02-23        kinaba: 						while( 0==m_dll->findnext( h, &inf ) );
13b7203622 2011-02-23        kinaba: 					}
13b7203622 2011-02-23        kinaba: 					if( ans==aSingleDir )
13b7203622 2011-02-23        kinaba: 						inf1st.szFileName[y-inf1st.szFileName]='\0', dname+=inf1st.szFileName;
13b7203622 2011-02-23        kinaba: 				}
13b7203622 2011-02-23        kinaba: 			}
13b7203622 2011-02-23        kinaba: 			m_dll->closeArc( h );
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	return ans;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: bool CArcModule::lst_exe( const char* lstcmd, aflArray& files,
13b7203622 2011-02-23        kinaba: 	const char* BL, int BSL, const char* EL, int SL, int dx )
13b7203622 2011-02-23        kinaba: 	// BeginLine, BeginSkipLine, EndLine, SkipLine, delta-x
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	files.forcelen(0);
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 作業変数
13b7203622 2011-02-23        kinaba: 	const int BLLEN = ki_strlen(BL);
13b7203622 2011-02-23        kinaba: 	const int ELLEN = ki_strlen(EL);
13b7203622 2011-02-23        kinaba: 	int /*ct=0,*/ step=BSL;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// EXE以外のものではダメ
13b7203622 2011-02-23        kinaba: 	if( m_type!=EXE && m_type!=EXEUS )
13b7203622 2011-02-23        kinaba: 		return false;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// コマンド文字列作成
13b7203622 2011-02-23        kinaba: 	kiVar theCmd( m_name );
13b7203622 2011-02-23        kinaba: 	theCmd.quote();
13b7203622 2011-02-23        kinaba: 	theCmd += ' ';
13b7203622 2011-02-23        kinaba: 	theCmd += lstcmd;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// パイプ作成(両方とも継承ON。DupHanするの面倒いので…(^^;)
13b7203622 2011-02-23        kinaba: 	HANDLE rp, wp;
13b7203622 2011-02-23        kinaba: 	SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES),NULL,TRUE};
13b7203622 2011-02-23        kinaba: 	::CreatePipe( &rp, &wp, &sa, 4096 );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// プロセス開始
13b7203622 2011-02-23        kinaba: 	PROCESS_INFORMATION pi;
13b7203622 2011-02-23        kinaba: 	STARTUPINFO si = {sizeof(STARTUPINFO)};
13b7203622 2011-02-23        kinaba: 	si.dwFlags     = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
13b7203622 2011-02-23        kinaba: 	si.wShowWindow = SW_MINIMIZE;
13b7203622 2011-02-23        kinaba: 	si.hStdOutput  = si.hStdError = wp;
13b7203622 2011-02-23        kinaba: 	BOOL ok =
13b7203622 2011-02-23        kinaba: 		::CreateProcess( NULL,const_cast<char*>((const char*)theCmd),NULL,
13b7203622 2011-02-23        kinaba: 			NULL, TRUE, CREATE_NEW_PROCESS_GROUP|NORMAL_PRIORITY_CLASS,
13b7203622 2011-02-23        kinaba: 			NULL, NULL, &si,&pi );
13b7203622 2011-02-23        kinaba: 	::CloseHandle( wp );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 失敗したらパイプを閉じて即終了
13b7203622 2011-02-23        kinaba: 	if( !ok )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		::CloseHandle( rp );
13b7203622 2011-02-23        kinaba: 		return false;
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 	::CloseHandle( pi.hThread );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 解析作業etc(バッファのサイズはパイプのサイズの倍以上でなくてはならない)
13b7203622 2011-02-23        kinaba: 	char buf[8192], *end=buf;
13b7203622 2011-02-23        kinaba: 	for( bool endpr=false; !endpr; )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		// 終了待機
13b7203622 2011-02-23        kinaba: 		endpr = (WAIT_OBJECT_0==::WaitForSingleObject(pi.hProcess,500));
13b7203622 2011-02-23        kinaba: 		kiWindow::msg();
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		// パイプから読みとり
13b7203622 2011-02-23        kinaba: 		DWORD red;
13b7203622 2011-02-23        kinaba: 		::PeekNamedPipe( rp, NULL, 0, NULL, &red, NULL );
13b7203622 2011-02-23        kinaba: 		if( red==0 )
13b7203622 2011-02-23        kinaba: 			continue;
13b7203622 2011-02-23        kinaba: 		::ReadFile( rp, end, buf+sizeof(buf)-end, &red, NULL );
13b7203622 2011-02-23        kinaba: 		end += red;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		// 行に分解
13b7203622 2011-02-23        kinaba: 		char *lss=buf;
13b7203622 2011-02-23        kinaba: 		for( char *ls, *le=buf; le<end; ++le )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			// 行末を探す
13b7203622 2011-02-23        kinaba: 			for( lss=ls=le; le<end; ++le )
13b7203622 2011-02-23        kinaba: 				if( *le=='\n' )
13b7203622 2011-02-23        kinaba: 					break;
13b7203622 2011-02-23        kinaba: 			if( le==end )
13b7203622 2011-02-23        kinaba: 				break;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			// 先頭行スキップ処理
13b7203622 2011-02-23        kinaba: 			if( *BL )
13b7203622 2011-02-23        kinaba: 			{
13b7203622 2011-02-23        kinaba: 				if( BLLEN<=le-ls && ki_memcmp(BL,ls,BLLEN) )
13b7203622 2011-02-23        kinaba: 					BL = "";
13b7203622 2011-02-23        kinaba: 			}
13b7203622 2011-02-23        kinaba: 			// 行ステップ処理
13b7203622 2011-02-23        kinaba: 			else if( --step<=0 )
13b7203622 2011-02-23        kinaba: 			{
13b7203622 2011-02-23        kinaba: 				step = SL;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 				// 終端行処理
13b7203622 2011-02-23        kinaba: 				if( ELLEN==0 )
13b7203622 2011-02-23        kinaba: 					{ if( le-ls<=1 ) break; }
13b7203622 2011-02-23        kinaba: 				else if( ELLEN<=le-ls && ki_memcmp(EL,ls,ELLEN) )
13b7203622 2011-02-23        kinaba: 					break;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 				// 文字スキップ処理
13b7203622 2011-02-23        kinaba: 				if( dx>=0 )
13b7203622 2011-02-23        kinaba: 					ls += dx;
13b7203622 2011-02-23        kinaba: 				// 引数ブロックスキップ処理
13b7203622 2011-02-23        kinaba: 				else
13b7203622 2011-02-23        kinaba: 				{
13b7203622 2011-02-23        kinaba: 					for( ;ls<le;++ls )
13b7203622 2011-02-23        kinaba: 						if( *ls!=' ' && *ls!='\t' && *ls!='\r' )
13b7203622 2011-02-23        kinaba: 							break;
13b7203622 2011-02-23        kinaba: 					for( int t=dx; ++t; )
13b7203622 2011-02-23        kinaba: 					{
13b7203622 2011-02-23        kinaba: 						for( ;ls<le;++ls )
13b7203622 2011-02-23        kinaba: 							if( *ls==' ' || *ls=='\t' && *ls=='\r' )
13b7203622 2011-02-23        kinaba: 								break;
13b7203622 2011-02-23        kinaba: 						for( ;ls<le;++ls )
13b7203622 2011-02-23        kinaba: 							if( *ls!=' ' && *ls!='\t' && *ls!='\r' )
13b7203622 2011-02-23        kinaba: 								break;
13b7203622 2011-02-23        kinaba: 					}
13b7203622 2011-02-23        kinaba: 				}
13b7203622 2011-02-23        kinaba: 				// ファイル名コピー
13b7203622 2011-02-23        kinaba: 				if( ls<le )
13b7203622 2011-02-23        kinaba: 				{
13b7203622 2011-02-23        kinaba: 					arcfile af; ki_memzero(&af, sizeof(af));
13b7203622 2011-02-23        kinaba: 					af.inf.dwOriginalSize = 0xffffffff;
13b7203622 2011-02-23        kinaba: //					ki_memzero( &files[ct].inf, sizeof(files[ct].inf) );
13b7203622 2011-02-23        kinaba: //					files[ct].inf.dwOriginalSize = 0xffffffff;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 					int i=0;
13b7203622 2011-02-23        kinaba: 					bool prev_is_space=false;
13b7203622 2011-02-23        kinaba: 					while( i<FNAME_MAX32 && ls<le )
13b7203622 2011-02-23        kinaba: 					{
13b7203622 2011-02-23        kinaba: 						if( *ls==' ' )
13b7203622 2011-02-23        kinaba: 						{
13b7203622 2011-02-23        kinaba: 							if( prev_is_space )
13b7203622 2011-02-23        kinaba: 								break;
13b7203622 2011-02-23        kinaba: 							prev_is_space = true;
13b7203622 2011-02-23        kinaba: 						}
13b7203622 2011-02-23        kinaba: 						else if( *ls=='\t' || *ls=='\r' )
13b7203622 2011-02-23        kinaba: 							break;
13b7203622 2011-02-23        kinaba: 						else
13b7203622 2011-02-23        kinaba: 							prev_is_space = false;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 						af.inf.szFileName[i++] = *ls++;
13b7203622 2011-02-23        kinaba: //						files[ct].inf.szFileName[i++] = *ls++;
13b7203622 2011-02-23        kinaba: 					}
13b7203622 2011-02-23        kinaba: 					if( prev_is_space )
13b7203622 2011-02-23        kinaba: 						--i;
13b7203622 2011-02-23        kinaba: 					if( i )
13b7203622 2011-02-23        kinaba: 					{
13b7203622 2011-02-23        kinaba: /*
13b7203622 2011-02-23        kinaba: 						files[ct].inf.szFileName[i] = '\0';
13b7203622 2011-02-23        kinaba: 						files[ct].isfile = true;
13b7203622 2011-02-23        kinaba: 						files.forcelen( 1+(++ct) );
13b7203622 2011-02-23        kinaba: */
13b7203622 2011-02-23        kinaba: 						af.inf.szFileName[i] = '\0';
13b7203622 2011-02-23        kinaba: 						af.isfile = true;
13b7203622 2011-02-23        kinaba: 						files.add(af);
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( lss != buf )
13b7203622 2011-02-23        kinaba: 			ki_memmov( buf, lss, end-lss ), end=buf+(end-lss);
13b7203622 2011-02-23        kinaba: 		else if( end==buf+sizeof(buf) )
13b7203622 2011-02-23        kinaba: 			end = buf;
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// お終い
13b7203622 2011-02-23        kinaba: 	::CloseHandle( pi.hProcess );
13b7203622 2011-02-23        kinaba: 	::CloseHandle( rp );
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: 
13b7203622 2011-02-23        kinaba: bool CArchiver::GetVersionInfoStr( char* name, char* buf, size_t cbBuf )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	static bool old = mycnf().oldver();
13b7203622 2011-02-23        kinaba: 	if( old )
13b7203622 2011-02-23        kinaba: 		return false;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	DWORD dummy = 0;
13b7203622 2011-02-23        kinaba: 	DWORD siz = ::GetFileVersionInfoSize( name, &dummy );
13b7203622 2011-02-23        kinaba: 	if( siz == 0 )
13b7203622 2011-02-23        kinaba: 		return false;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	bool got = false;
13b7203622 2011-02-23        kinaba: 	BYTE* vbuf = new BYTE[siz];
13b7203622 2011-02-23        kinaba: 	if( 0 != ::GetFileVersionInfo( name, 0, siz, vbuf ) )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		WORD* tr = NULL;
13b7203622 2011-02-23        kinaba: 		UINT cbTr = 0;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		// 最初に見つけた言語とコードページで情報取得
13b7203622 2011-02-23        kinaba: 		if( ::VerQueryValue( vbuf,
13b7203622 2011-02-23        kinaba: 			"\\VarFileInfo\\Translation", (void**)&tr, &cbTr )
13b7203622 2011-02-23        kinaba: 		 && cbTr >= 4 )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			char blockname[500]="";
13b7203622 2011-02-23        kinaba: 			::wsprintf( blockname,
13b7203622 2011-02-23        kinaba: 				"\\StringFileInfo\\%04x%04x\\ProductVersion",
13b7203622 2011-02-23        kinaba: 				tr[0], tr[1] );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			char* inf = NULL;
13b7203622 2011-02-23        kinaba: 			UINT cbInf = 0;
13b7203622 2011-02-23        kinaba: 			if( ::VerQueryValue( vbuf, blockname, (void**)&inf, &cbInf )
13b7203622 2011-02-23        kinaba: 			 && cbInf < cbBuf-1 )
13b7203622 2011-02-23        kinaba: 			{
13b7203622 2011-02-23        kinaba: 				for( char* v=buf; *inf && cbInf; ++inf,--cbInf )
13b7203622 2011-02-23        kinaba: 					if( *inf != ' ' )
13b7203622 2011-02-23        kinaba: 						*v++ = (*inf==',' ? '.' : *inf);
13b7203622 2011-02-23        kinaba: 				*v = '\0';
13b7203622 2011-02-23        kinaba: 				got = true;
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: 			void* fi = NULL;
13b7203622 2011-02-23        kinaba: 			UINT cbFi = 0;
13b7203622 2011-02-23        kinaba: 			VS_FIXEDFILEINFO vffi;
13b7203622 2011-02-23        kinaba: 			if( ::VerQueryValue( vbuf, "\\", &fi, &cbFi )
13b7203622 2011-02-23        kinaba: 			 && sizeof(vffi)<=cbFi )
13b7203622 2011-02-23        kinaba: 			{
13b7203622 2011-02-23        kinaba: 				ki_memcpy( &vffi, fi, sizeof(vffi) );
13b7203622 2011-02-23        kinaba: 				if( vffi.dwFileVersionLS >= 0x10000 )
13b7203622 2011-02-23        kinaba: 					::wsprintf( buf, "%d.%d.%d", vffi.dwFileVersionMS>>16,
13b7203622 2011-02-23        kinaba: 						vffi.dwFileVersionMS&0xffff, vffi.dwFileVersionLS>>16 );
13b7203622 2011-02-23        kinaba: 				else
13b7203622 2011-02-23        kinaba: 					::wsprintf( buf, "%d.%d", vffi.dwFileVersionMS>>16,
13b7203622 2011-02-23        kinaba: 						vffi.dwFileVersionMS&0xffff );
13b7203622 2011-02-23        kinaba: 				got = 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: 	delete [] vbuf;
13b7203622 2011-02-23        kinaba: 	return got;
13b7203622 2011-02-23        kinaba: }