Beispiel #1
0
bool CArchiver7ZIP::AddItemToArchive(LPCTSTR ArcFileName,const std::list<CString> &FileList,CConfigManager &ConfMan,LPCTSTR lpDestDir,CString &strLog)
{
	// レスポンスファイル用テンポラリファイル名取得
	TCHAR ResponceFileName[_MAX_PATH+1];
	FILL_ZERO(ResponceFileName);
	if(!UtilGetTemporaryFileName(ResponceFileName,_T("zip"))){
		strLog=CString(MAKEINTRESOURCE(IDS_ERROR_TEMPORARY_FILE_CREATE));
		return false;
	}
	ASSERT(0!=_tcslen(ResponceFileName));

	//===一時的にファイルをコピー
	//---\で終わる基点パスを取得
	CPath strBasePath;
	UtilGetBaseDirectory(strBasePath,FileList);
	TRACE(_T("%s\n"),strBasePath);

	//---テンポラリに対象ファイルをコピー
	//テンポラリ準備
	CTemporaryDirectoryManager tdm(_T("lhaf"));
	CPath strDestPath(tdm.GetDirPath());
	strDestPath+=lpDestDir;
	UtilMakeSureDirectoryPathExists(strDestPath);

	// 圧縮対象ファイル名を修正する
	const int BasePathLength=((CString)strBasePath).GetLength();
	CString strSrcFiles;	//コピー元ファイルの一覧
	CString strDestFiles;	//コピー先ファイルの一覧
	std::list<CString>::const_iterator ite;
	for(ite=FileList.begin();ite!=FileList.end();++ite){
		//ベースパスを元に相対パス取得 : 共通である基底パスの文字数分だけカットする
		LPCTSTR lpSrc((LPCTSTR)(*ite)+BasePathLength);

		//送り側ファイル名指定
		strSrcFiles+=(strBasePath+lpSrc);	//PathAppend相当
		strSrcFiles+=_T('|');
		//受け側ファイル名指定
		strDestFiles+=strDestPath+lpSrc;
		strDestFiles+=_T('|');
	}
	strSrcFiles+=_T('|');
	strDestFiles+=_T('|');

	//'|'を'\0'に変換する
	std::vector<TCHAR> srcBuf(strSrcFiles.GetLength()+1);
	UtilMakeFilterString(strSrcFiles,&srcBuf[0],srcBuf.size());
	std::vector<TCHAR> destBuf(strDestFiles.GetLength()+1);
	UtilMakeFilterString(strDestFiles,&destBuf[0],destBuf.size());

	//ファイル操作内容
	SHFILEOPSTRUCT fileOp={0};
	fileOp.wFunc=FO_COPY;
	fileOp.fFlags=FOF_MULTIDESTFILES|FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOCOPYSECURITYATTRIBS|FOF_NO_CONNECTED_ELEMENTS;
	fileOp.pFrom=&srcBuf[0];
	fileOp.pTo=&destBuf[0];

	//コピー実行
	if(::SHFileOperation(&fileOp)){
		//エラー
		strLog=CString(MAKEINTRESOURCE(IDS_ERROR_FILE_COPY));
		return false;
	}else if(fileOp.fAnyOperationsAborted){
		//キャンセル
		strLog=CString(MAKEINTRESOURCE(IDS_ERROR_USERCANCEL));
		return false;
	}

	//カレントディレクトリ設定
	::SetCurrentDirectory(tdm.GetDirPath());
	// 同時に、レスポンスファイル内にアーカイブ名および圧縮対象ファイル名を記入する
	{
		HANDLE hFile=CreateFile(ResponceFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
		if(INVALID_HANDLE_VALUE==hFile){
			strLog=CString(MAKEINTRESOURCE(IDS_ERROR_TEMPORARY_FILE_ACCESS));
			return false;
		}
		//レスポンスファイルへの書き込み
		//全て圧縮
		WriteResponceFile(hFile,_T("*"));
		CloseHandle(hFile);
	}


	//===========================
	// DLLに渡すオプションの設定
	//===========================
	TRACE(_T("DLLに渡すオプションの設定\n"));

	CString Param;//コマンドライン パラメータ バッファ

	CConfigZIP confZIP;
	CConfig7Z  conf7Z;
	ASSERT(ArchiverGetArchiveType);
	switch(ArchiverGetArchiveType(C2UTF8(ArcFileName))){
	case 1:	//ZIP形式で圧縮
		confZIP.load(ConfMan);
		if(!FormatCompressCommandZIP(confZIP,Param,false,0,NULL,NULL,strLog)){
			DeleteFile(ResponceFileName);
			return false;
		}
		break;
	case 2:	//7z形式で圧縮
		conf7Z.load(ConfMan);
		if(!FormatCompressCommand7Z(conf7Z,Param,0,NULL,strLog)){
			DeleteFile(ResponceFileName);
			return false;
		}
		break;
	default:
		ASSERT(!"This code cannot be run");
		//エラー処理が面倒なので放っておく。
		return false;
	}

	Param+=_T("-scsUTF-8 ");	//レスポンスファイルのコードページ指定

	//作業ディレクトリ
	Param+=_T("\"-w");
	Param+=UtilGetTempPath();
	Param+=_T("\" ");

	//圧縮先ファイル名指定
	Param+=_T("\"");
	Param+=ArcFileName;
	Param+=_T("\" ");

	//レスポンスファイル名指定
	Param+=_T("\"@");
	Param+=ResponceFileName;
	Param+=_T("\"");

	ASSERT(!Param.IsEmpty());
	TRACE(_T("ArchiveHandler Commandline Parameter:%s\n"),Param);

	TRACE(_T("ArchiveHandler呼び出し\n"));
	//char szLog[LOG_BUFFER_SIZE]={0};
	std::vector<BYTE> szLog(LOG_BUFFER_SIZE);
	szLog[0]='\0';
	int Ret=ArchiveHandler(NULL,C2UTF8(Param),(LPSTR)&szLog[0],LOG_BUFFER_SIZE-1);
	CString strTmp;
	UtilToUNICODE(strTmp,&szLog[0],szLog.size()-1,UTILCP_UTF8);
	//strLog=&szLog[0];
	strLog=strTmp;

	//使ったレスポンスファイルは消去
	DeleteFile(ResponceFileName);

	return 0==Ret;
}
DWORD __stdcall CInjection::Initialize(LPVOID lpParameter )
{
	USES_CONVERSION;

	HMODULE hInstance = (HMODULE)lpParameter;
	// get the current directory
	CString strCurrentDir = CUtility::GetCurrentDirectory();

	// dbghelp.dll
	{
		CString strDbgHelpDll;
		strDbgHelpDll.Format( _T("%s%s"), strCurrentDir, DBG_HELP_DLL);
		HMODULE hModule = ::LoadLibrary(strDbgHelpDll);
		if( hModule == NULL || !CPdbHelper::Initialize(hModule) )
		{
			s_nStatus = Status_Error_DbgHelpNotFound;
			SetEvent( s_hEvent );
			return FALSE;
		}
	}

	// find the JIT module
	g_hJitModule = GetModuleHandleA("clrjit.dll");
	if( !g_hJitModule )
		g_hJitModule = GetModuleHandleA("mscorjit.dll");
	if( g_hJitModule == NULL )
	{
		s_nStatus = Status_Error_JITNotFound;
		SetEvent( s_hEvent );
		return FALSE;
	}

	// find the CLR module
	g_hClrModule = GetModuleHandleA("clr.dll");
	if( !g_hClrModule )
		g_hClrModule = GetModuleHandleA("mscorwks.dll");
	if( g_hClrModule == NULL || !DetermineDotNetVersion() )
	{
		s_nStatus = Status_Error_CLRNotFound;
		SetEvent( s_hEvent );
		return FALSE;
	}	

	// try to quick load the symbol address base on the binary hash
	if( !CSymbolAddressCache::TryCache() )
	{
		// get the pdb directory
		CString strDestPath(strCurrentDir);
		{
			strDestPath.AppendFormat( _T("PDB_symbols\\") );
			::CreateDirectory(strDestPath, NULL);
		}

		// copy the JIT dll
		{
			TCHAR tszFilename[MAX_PATH] = {0};
			GetModuleFileName( g_hJitModule, tszFilename, MAX_PATH);

			::CopyFile( tszFilename, strDestPath + CUtility::GetFileName(tszFilename), FALSE);
		}

		// copy the CLR dll
		{
			TCHAR tszFilename[MAX_PATH] = {0};
			GetModuleFileName( g_hClrModule, tszFilename, MAX_PATH);

			::CopyFile( tszFilename, strDestPath + CUtility::GetFileName(tszFilename), FALSE);
		}

		// Set Environment Variable 
		{
			CString strVariable;
			strVariable.Format( _T("symsrv*symsrv.dll*%s*http://msdl.microsoft.com/download/symbols"), strDestPath);
			SetEnvironmentVariable( _T("_NT_SYMBOL_PATH"), strVariable.GetBuffer());
			strVariable.ReleaseBuffer();
		}


		if( !SearchMethodAddresses(T2W(strDestPath.GetBuffer())) )
		{
			// download the pdb
			// symchk.exe /if "C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorjit.dll" /s srv*G:\HookDotNet*http://msdl.microsoft.com/download/symbols
			CString strCmd;
			strCmd.Format( _T("\"%s%s\" /if \"%s*.dll\" /s symsrv*symsrv.dll*%s*http://msdl.microsoft.com/download/symbols")
				, strCurrentDir
				, SYMCHK_EXE
				, strDestPath
				, strDestPath
				);
			ATLTRACE( _T("\n%s"), strCmd);

			STARTUPINFO si = { sizeof(si) };
			si.dwFlags = STARTF_USESHOWWINDOW;
			si.wShowWindow = SW_HIDE;
			PROCESS_INFORMATION  pi = {0};
			BOOL bRet = CreateProcess( NULL
				, strCmd.GetBuffer()
				, NULL
				, NULL
				, FALSE
				, 0
				, NULL
				, strCurrentDir
				, &si
				, &pi
				);
			strCmd.ReleaseBuffer();
			if( !bRet )
			{
				s_nStatus = Status_Error_DownloadPDBFailed;
				SetEvent( s_hEvent );
				return FALSE;
			}

			WaitForSingleObject(pi.hProcess, INFINITE); 

			CloseHandle(pi.hProcess);
			CloseHandle(pi.hThread);


			// find all the pdb files
			if( !SearchMethodAddresses(NULL) )
				SearchMethodAddresses(NULL, FALSE);
		}	

		// cache the address offset according to the binary hash
		if( ICorJitCompiler::s_pfnComplieMethod )
		{
			CSymbolAddressCache::GenerateJitCache();
		};

		if( MethodDesc::IsInitialized() && LoadedMethodDescIterator::IsInitialized() )
		{
			CSymbolAddressCache::GenerateClrCache();
		}
	}

	
	HookApi();
	SetEvent( s_hEvent );
	return TRUE;
}