Artifact Content

Not logged in

Artifact 6f288846948232f7920dd1a4ba3c3368554bef0e


// Archiver.h
//-- CArchiver -- common interface in 'Noah' for arhiving routine --

#ifndef AFX_ARCHIVER_H__359A2ED3_2F97_480E_BC94_24834EBA6498__INCLUDED_
#define AFX_ARCHIVER_H__359A2ED3_2F97_480E_BC94_24834EBA6498__INCLUDED_

enum {
	aCheck = 1, aMelt = 2, aList = 4, aMeltEach = 8, aCompress = 16, aArchive = 32, aSfx = 64,
};
enum {
	aUnknown=0, aSingleFile, aSingleDir, aMulti
};

struct arcname {
	arcname( const kiPath& b,const char *s,const char *l )
		: basedir(b),sname(s),lname(l) {}
	const kiPath& basedir;
	const char*   lname;
	const char*   sname;
};

struct arcfile {
	INDIVIDUALINFO inf;
	union {
		bool selected;
		bool isfile;
	};
};

#define aflArray kiArray<arcfile>
#define wfdArray kiArray<WIN32_FIND_DATA>

class CArchiver
{
public: //--< attribute >--

	int ability();
	int cancompressby( const char* ext, const char* mhd, bool sfx );

	const char*     mlt_ext();
	const kiStr&    cmp_ext();
	const StrArray& cmp_mhd_list();
	const int       cmp_mhd_default();
	bool            ver( kiStr& str );
	static bool GetVersionInfoStr( char* name, char* buf, size_t cbBuf );

public: //--< action >--

	bool check( const kiPath& aname );
	int  contents( const kiPath& aname, kiPath& dname );
	int  melt( const arcname& aname, const kiPath& ddir, const aflArray* files=NULL );
	bool list( const arcname& aname, aflArray& files );
	int  compress( const kiPath& base, const wfdArray& files, const kiPath& ddir, int method, bool sfx );
	kiStr arctype_name(const char* an) const { return v_name(an); }

protected: //--< for child >--

	CArchiver( const char* mext );
	void set_cmp_ext( const char* ext );
	void add_cmp_mhd( const char* mhd, bool def=false );

	virtual int  v_load(){return 0;}
	virtual bool v_ver( kiStr& str ){return false;}
	virtual bool v_check( const kiPath& aname ){return false;}
	virtual int  v_contents( const kiPath& aname, kiPath& dname ){return aUnknown;}
	virtual int  v_melt( const arcname& aname, const kiPath& ddir, const aflArray* files ){return false;}
	virtual bool v_list( const arcname& aname, aflArray& files ){return false;}
	virtual int  v_compress( const kiPath& base, const wfdArray& files, const kiPath& ddir, int method, bool sfx ){return false;}
	virtual kiStr v_name(const char*) const { return ""; }

private: //--< private >--

	friend class CNoahArchiverManager;
	bool extCheck( const char* ext );
	kiStr m_MyExtList, m_MyCmpExt;
	StrArray m_Mhd;
	int m_MhdDef,m_Able;
	bool not_loaded;

public: //--< dummy >--

	virtual ~CArchiver(){}
};

inline int CArchiver::ability()
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return m_Able;
}

inline int CArchiver::cancompressby( const char* ext, const char* mhd, bool sfx )
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	if( (sfx && !(m_Able&aSfx)) || !(m_Able&aCompress) || !m_MyCmpExt.isSame(ext) )
		return -1; // no
	for( unsigned int i=0; i!=m_Mhd.len(); i++ )
		if( m_Mhd[i] == mhd )
			return (int)i;
	return -2; // only - 'type name' matched
}

inline bool CArchiver::check( const kiPath& aname )
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return (m_Able&aCheck)?v_check(aname):false;
}

inline int CArchiver::contents( const kiPath& aname, kiPath& dname )
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return (m_Able&aList)?v_contents(aname,dname):false;
}

inline int CArchiver::melt( const arcname& aname, const kiPath& ddir, const aflArray* files )
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return (m_Able&aMelt)?v_melt(aname,ddir,files):0xffff;
}

inline bool CArchiver::list( const arcname& aname, aflArray& files )
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return (m_Able&aList)?v_list(aname,files):false;
}

inline int CArchiver::compress( const kiPath& base, const wfdArray& files, const kiPath& ddir, int method, bool sfx )
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return (m_Able&aCompress)?v_compress(base,files,ddir,method,sfx):0xffff;
}

inline bool CArchiver::ver( kiStr& str )
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return v_ver(str);
}

inline const char* CArchiver::mlt_ext()
{
	return m_MyExtList;
}

inline const kiStr& CArchiver::cmp_ext()
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return m_MyCmpExt;
}

inline const StrArray& CArchiver::cmp_mhd_list()
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return m_Mhd;
}

inline const int CArchiver::cmp_mhd_default()
{
	if( not_loaded )
		m_Able=v_load(), not_loaded=false;
	return m_MhdDef;
}

inline CArchiver::CArchiver( const char* extlist )
		: m_MyExtList( extlist ), m_Mhd(3), m_MhdDef(0), not_loaded(true)
{
	m_MyExtList.lower();
}

inline void CArchiver::set_cmp_ext( const char* ext )
{
	m_MyCmpExt = ext;
}

inline void CArchiver::add_cmp_mhd( const char* method, bool Default )
{
	m_Mhd.add(method);
	if( Default )
		m_MhdDef = m_Mhd.len() - 1;
}

inline bool CArchiver::extCheck( const char* ext )
{
	const char *x=m_MyExtList,*y;
	int ln = ki_strlen(ext);
	while( *x )
	{
		for( y=x+1; *y && *y!='.'; y++ );
		if( *y=='\0' ) break;

		if( y-x == ln )
		{
			while( x!=y )
			{
				if( *x!=ext[ln+(x-y)] )
					break;
				x++;
			}
			if( x==y )
				return true;
		}
		x=y+1;
	}
	return false;
}

// 渡されたパス文字列が、絶対パスや".."を含んでいればtrue
static bool containsDangerPath( const char* path )
{
	// 絶対パス
	if( path[0]=='\\' || path[0]=='/' || path[0]!='\0' && path[1]==':' )
		return true;

	// ".."
	for( const char* p=path; *p; )
	{
		const char* q = p;
		while( *q!='\0' && *q!='\\' && *q!='/' )
			q = ::CharNext(q);

		if( p+2 <= q )
		{
			const char* r;
			for( r=p; r!=q; ++r )
				if( *r != '.' )
					break;
			if( r == q ) // all dot
				return true;
		}
		p = (*q ? ::CharNext(q) : q);
	}
	return false;
}

/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
// 統合アーカイバDLLレイヤ第二層 ver2。ついでにexeも適当に動く

class CArcModule
{
public:

	// 実行コマンド名を指定して作成
	//  ・ファイル名として探して見つからなかった場合
	//    シェルの内部コマンドと仮定して一応保持しておく
	//  ・拡張子が exe か com なら実行ファイルとして扱う。
	//  ・それ以外ならアーカイバDLLとして扱う。
	CArcModule( const char* name, bool us=false );
	virtual ~CArcModule();
	bool exist();
	bool isdll();

	kiStr name() const { return kiPath::name(m_name); }

	// 実行
	int cmd( const char* cmd, bool mini=false );

	// 書庫チェック
	bool chk( const char* aname );
	int  arctype( const char* aname ) const;

	// バージョン情報文字列を返す
	void ver( kiStr& str );

	// 書庫の中身をリストアップ
	bool lst_dll( const arcname& aname, aflArray& files, const char* wild="*" );
	int  cnt( const kiPath& aname, kiPath& dname, const char* wild="*" );
	bool lst_exe( const char* lstcmd, aflArray& files,
		const char* BL, int BSL, const char* EL, int SL, int dx );

	// DLL強制アンロード( BugTrap for UnZip32.dll )
	void unload() { m_dll->unload(); }
	// DLLオーナー窓設定( BugTrap for Unrar.dll )
	void own( HWND wnd ) { m_dll->setOwner( wnd ); }
	void fre() { m_dll->clearOwner(); }

private:
	enum { NOTEXIST, DLL, DLLGCA, DLLBGA, EXE, EXEUS, SHLCMD=0 } m_type;
	kiArcDLLRaw* m_dll;
	char         m_name[MAX_PATH];
	const char*  m_wild;
};

inline bool CArcModule::chk( const char* aname )
	{ return m_dll ? FALSE!=m_dll->check( aname, m_type==DLLGCA?24:0 ) : false; }

inline int CArcModule::arctype( const char* aname ) const
	{ return m_dll ?
		m_type==DLLBGA ? m_dll->check(aname,0) : m_dll->getArcType(aname)
	  : 0; }

inline bool CArcModule::exist()
	{ return m_type!=NOTEXIST; }

inline bool CArcModule::isdll()
	{ return m_type==DLL || m_type==DLLGCA; }



#endif