Artifact Content

Not logged in

Artifact eeea8ebd808979ec2caa7dce299adb97aae75e4f



#include "stdafx.h"
#include "ArcAce.h"
#include "NoahApp.h"


int CArcAce::v_load()
{
	if( hDLL = kiSUtil::loadLibrary("UnAceV2") )
	{
		if( (aceInit = (FI)::GetProcAddress( hDLL,"ACEInitDll" ))
		 && (aceHead = (FR)::GetProcAddress( hDLL,"ACEReadArchiveData" ))
		 && (aceList = (FL)::GetProcAddress( hDLL,"ACEList" ))
		 && (aceTest = (FT)::GetProcAddress( hDLL,"ACETest" ))
		 && (aceExtr = (FE)::GetProcAddress( hDLL,"ACEExtract" )) )
		{
			tACEInitDllStruc ini;
			ki_memzero( &ini, sizeof(ini) );

			ini.GlobalData.Obj                 = this;
			ini.GlobalData.MaxArchiveTestBytes = 0x2ffFF;
			ini.GlobalData.MaxFileBufSize      = 0x2ffFF;
			ini.GlobalData.InfoCallbackProc    = callback_info;
			ini.GlobalData.ErrorCallbackProc   = callback_error;
			ini.GlobalData.RequestCallbackProc = callback_request;
			ini.GlobalData.StateCallbackProc   = callback_state;
			ini.GlobalData.DecryptPassword     = pwdBuf;

			if( 0 == aceInit( &ini ) )
				return aCheck|aMelt|aList|aMeltEach;
		}

		::FreeLibrary( hDLL );
		hDLL = NULL;
	}
	return 0;
}

bool CArcAce::v_ver( kiStr& str )
{
	str = "UnAceV2.dll  ";

	//-- 存在確認
	char buf[40];
	if( hDLL )
		if( GetVersionInfoStr( "UnAceV2", buf, sizeof(buf) ) )
			str += buf;
		else
			str += "OK!";
	else
		str += "----";

	return true;
}

bool CArcAce::v_check( const kiPath& aname )
{
	//-- 書庫情報を読み込んでみる
	tACEReadArchiveDataStruc dt;
	ki_memzero( &dt, sizeof(dt) );
	return (  0==aceHead( const_cast<char*>((const char*)aname), &dt )
		&& NULL!=dt.ArchiveData );
}

bool CArcAce::v_list( const arcname& aname, aflArray& files )
{
	list = &files;

	//-- リスティング開始!
	tACEListStruc lst;
	ki_memzero( &lst, sizeof(lst) );
	lst.Files.SourceDir   = "";
	lst.Files.FileList    = "*";
	lst.Files.ExcludeList = "";
	lst.Files.FullMatch   = FALSE;

	char anm[MAX_PATH];
	ki_strcpy( anm, aname.basedir );
	ki_strcat( anm, aname.lname );

	return ( 0==aceList( anm, &lst ) );
}

int CArcAce::v_contents( const kiPath& aname, kiPath& dname )
{
	list = NULL;
	aCnt = aUnknown;
	dName = &dname;

	//-- リスティング開始!
	tACEListStruc lst;
	ki_memzero( &lst, sizeof(lst) );
	lst.Files.SourceDir   = "";
	lst.Files.FileList    = "*";
	lst.Files.ExcludeList = "";
	lst.Files.FullMatch   = TRUE;
	if( 0!=aceList( const_cast<char*>((const char*)aname), &lst ) )
		return aMulti;
	return aCnt;
}

int CArcAce::v_melt( const arcname& aname, const kiPath& ddir, const aflArray* files )
{
	pathCheck = new CArcPathCheckDlg;

	//-- 渡すファイルリスト作成
	kiStr lst;
	if( files )
	{
		dlg = NULL;
		for( unsigned int i=0; i!=list->len(); i++ )
			if( (*files)[i].selected )
				lst += (*files)[i].inf.szFileName, lst += '\xd';
	}
	else
		lst = "*", dlg = new CArcProgressDlg( 32768 );

	//-- 展開開始!
	::SetCurrentDirectory( ddir );

	m_aname = aname.lname;
	pwdBuf[0] = -1;

	tACEExtractStruc ex;
	ki_memzero( &ex, sizeof(ex) );
	ex.Files.SourceDir   = "";
	ex.Files.FileList    = const_cast<char*>((const char*)lst);
	ex.Files.ExcludeList = "";
	ex.Files.FullMatch   = files==NULL;
	ex.DestinationDir    = const_cast<char*>((const char*)ddir);
	ex.ExcludePath       = FALSE;
	ex.DecryptPassword   = "";

	char anm[MAX_PATH];
	ki_strcpy( anm, aname.basedir );
	ki_strcat( anm, aname.lname );

	m_bCanceled = false;
	bool ans = ( 0==aceExtr( anm, &ex ) );
	if( dlg && ans )
	{
		dlg->change(NULL,32768);
		::Sleep(100);
	}
	delete dlg;
	delete pathCheck;
	return ans ? 0 : (m_bCanceled?0x8020:0xffff);
}

int __stdcall CArcAce::callback_error( pACEErrorCallbackProcStruc Error )
{
	return ACE_CALLBACK_RETURN_OK;
}

int __stdcall CArcAce::callback_info( pACEInfoCallbackProcStruc Info )
{
	return ACE_CALLBACK_RETURN_OK;
}

int __stdcall CArcAce::callback_request( pACERequestCallbackProcStruc Request )
{
	// パスワード要求@解凍 ... ArchivedFile
	if( Request->Global.Code == ACE_CALLBACK_REQUEST_PASSWORD
	 && Request->Global.Operation == ACE_CALLBACK_OPERATION_EXTRACT )
	{
		CArcAce* ace = (CArcAce*)(Request->Global.GlobalData->Obj);
		if( ace->pwdBuf[0] == -1 )
		{
			ace->pwdBuf[0]=0;

			CArcPwdDlg pwd( ace->dlg ? ace->dlg->hwnd() : NULL, ace->pwdBuf, 60, ace->m_aname );
			if( IDCANCEL == pwd.getEndCode() )
			{
				ace->m_bCanceled = true;
				return ACE_CALLBACK_RETURN_CANCEL;
			}

			Request->Global.GlobalData->DecryptPassword = ace->pwdBuf;
		}
	}

	if( Request->Global.Code == ACE_CALLBACK_REQUEST_CHANGEVOLUME )
		if( !kiSUtil::exist(Request->Archive.ArchiveData->ArchiveName) )
			return ACE_CALLBACK_RETURN_CANCEL;

	return ACE_CALLBACK_RETURN_OK;
}

int __stdcall CArcAce::callback_state( pACEStateCallbackProcStruc State )
{
	// ファイル処理開始@解凍orリスト
	if( State->Progress.Code == ACE_CALLBACK_STATE_STARTFILE )
	{
		CArcAce* ptr = (CArcAce*)(State->ArchivedFile.GlobalData->Obj);

		if( State->Progress.Operation == ACE_CALLBACK_OPERATION_LIST )
		{
			if( !ptr->listup( *(State->ArchivedFile.FileData) ) )
				return ACE_CALLBACK_RETURN_CANCEL;
		}
		else if( State->Progress.Operation == ACE_CALLBACK_OPERATION_EXTRACT )
		{
			if( ptr->dlg )
				ptr->dlg->change( State->ArchivedFile.FileData->SourceFileName );
			if( ptr->pathCheck )
				if( containsDangerPath( State->ArchivedFile.FileData->SourceFileName ) )
					if( ! ptr->pathCheck->is_ok_to_extract( State->ArchivedFile.FileData->SourceFileName, ptr->dlg ) )
						return ACE_CALLBACK_RETURN_CANCEL;
		}
	}
	// 進展状況グラフ@解凍
	else if( State->Progress.Code == ACE_CALLBACK_STATE_PROGRESS )
	{
		CArcAce* ptr = (CArcAce*)(State->ArchivedFile.GlobalData->Obj);

		if( State->Progress.Operation == ACE_CALLBACK_OPERATION_EXTRACT && ptr->dlg )
		{
			unsigned long prs = (unsigned long)State->Progress.ProgressData->TotalProcessedSize;
			unsigned long ttl = (unsigned long)State->Progress.ProgressData->TotalSize;
			ptr->dlg->change( NULL, ttl ? (int)((((__int64)prs)<<15)/ttl) : 10000 );
			if( !ptr->dlg->msgloop() )
			{
				ptr->m_bCanceled = true;
				return ACE_CALLBACK_RETURN_CANCEL;
			}
		}
	}
	// CRCチェック@解凍
	else if( State->Progress.Code == ACE_CALLBACK_STATE_ENDCRCCHECK )
	{
		if( !State->CRCCheck.CRCOk )
			::DeleteFile( State->CRCCheck.FileData->SourceFileName );
	}

	return ACE_CALLBACK_RETURN_OK;
}

bool CArcAce::listup( tACEFileDataStruc& f )
{
	if( list ) // 全ファイルリスティングモード
	{
		arcfile x;

		ki_strcpy( x.inf.szFileName, f.SourceFileName );
		x.isfile = ( 0== (f.Attributes & 0x10) ); //_A_SUBDIR
		x.inf.dwCompressedSize = (unsigned long)f.CompressedSize;
		x.inf.dwOriginalSize   = (unsigned long)f.Size;
		x.inf.wDate = (unsigned short)(f.Time>>16);
		x.inf.wTime = (unsigned short)(f.Time);

		if( f.Method==0 )		ki_strcpy( x.inf.szMode, "store" );
		else if( f.Method&2 )	ki_strcpy( x.inf.szMode, "ace2" );
		else if( f.Method&1 )	ki_strcpy( x.inf.szMode, "ace1" );
		else					ki_strcpy( x.inf.szMode, "-ace-" );

		list->add( x );
		return true;
	}

	// 書庫内ファイル構成検索モード
	for( const char* p=f.SourceFileName; *p; p=kiStr::next(p) )
		if( *p=='\\' || *p=='/' )
			return true; // ルートのファイルのみ処理対象…

	if( aCnt != aUnknown )
		return false;

	aCnt = (f.Attributes & 0x10) ? aSingleDir : aSingleFile;
	if( aCnt == aSingleDir )
		*dName = f.SourceFileName;

	return true;
}