// 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