📄 ziplibs.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <lzexpand.h>
#include "ZipLibs.h"
#include "ZipBuilder.h"
#include "ZipMsg.h"
#include "ZipBuildDefs.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
char* RType = "BinFile";
const int zldTemp = 1;
const int zldAuto = 2;
const int zldFixed = 4;
const int DllRes[2] = {RDLL_Unz, RDLL_Zip};
// new resource numbers RDLL_ZVer= 11607, RDLL_UVer = 11608
const int VersRes[2] = {RDLL_UVer, RDLL_ZVer};
const char* DllNames[2] = {"UNZDLL.DLL","ZIPDLL.DLL"};
const char* ExecNames[2] = {"UnzDllExec","ZipDllExec"};
const char* VersNames[2] = {"GetUnzDllVersion","GetZipDllVersion"};
const char* PrivNames[2] = {"GetUnzDllPrivVersion", "GetZipDllPrivVersion"};
TZipLib::TZipLib(TObject *owner, bool type)
{
Clear();
fOwner = dynamic_cast<TZipBuilder*>(owner) ;
IsZip = type ? 1 : 0;
loadLevel = 0;
/* fVer = 0;
hndl = 0;
fExecFunc = NULL;
fVersFunc = NULL;
fPrivFunc = NULL; */
fPath = DllNames[IsZip];
TmpFileName = "";
}
TZipLib::~TZipLib(void)
{
if(hndl) ::FreeLibrary(hndl);
hndl = NULL;
if((TmpFileName != "") && FileExists(TmpFileName)) DeleteFile(TmpFileName);
loadLevel = 0;
}
void TZipLib::Clear(void)
{
hndl = 0;
fExecFunc = NULL;
fVersFunc = NULL;
fPrivFunc = NULL;
fVer = 0;
fPriv = 0;
}
// 1.73 27 July 2003 RA / RP unload wrong version
int TZipLib::LoadDll(int minver, bool level)
{
DoLoad(level ? zldFixed : zldAuto);
if(fVer < minver)
{
DoUnload(zldFixed | zldAuto | zldTemp);
throw EZipBuilder(LD_BadDll,fPath);
}
return hndl ? fVer : 0;
}
// TZipLib::LoadLib
// 1.73 15 September 2003 RA added parameter MustExist
//1.73.2.4 10 September 2003 RP new function
int TZipLib::LoadLib(AnsiString Fullpath, bool MustExist)
{
if(hndl) FreeLibrary(hndl);
Clear();
unsigned oldMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
try
{
hndl = ::LoadLibrary(Fullpath.c_str());
if(hndl)
{
fExecFunc = (ZDllExecAddress)::GetProcAddress(hndl, ExecNames[IsZip]);
fVersFunc = (ZDllVersionAddress)::GetProcAddress(hndl, VersNames[IsZip]);
fPrivFunc = (ZDllPrivFuncAddress)::GetProcAddress(hndl, PrivNames[IsZip]);
fPath = GetLoadedPath();
}
}
__finally
{
SetErrorMode(oldMode);
}
if(!hndl)
{
Clear();
loadLevel = 0;
if(MustExist) throw EZipBuilder(LD_NoDll, Fullpath);
return 0;
}
if(fExecFunc && fVersFunc)
{
fVer = fVersFunc();
if(fPrivFunc) fPriv = fPrivFunc();
}
if((fVer < 153) || (fVer > 300))
{
Fullpath = fPath;
FreeLibrary(hndl);
Clear();
loadLevel = 0;
if(MustExist) throw EZipBuilder(LD_BadDll, Fullpath);
}
return fPriv;
}
// TZipLib::LoadLib
void TZipLib::Unload(bool level)
{
DoUnload(level ? zldFixed : zldAuto);
}
int __fastcall TZipLib::GetLoaded(void)
{
return hndl ? fVer : 0;
}
// TZipLib::Expand
//1.73.2.4 10 September 2003 RP new function
int TZipLib::Expand(AnsiString src, AnsiString dest)
{
OFSTRUCT sTOF;
OFSTRUCT dTOF;
int sH = -1, dH = -1;
int Result = 0;
try
{
sH = LZOpenFile(src.c_str(), &sTOF, OF_READ);
dH = LZOpenFile(dest.c_str(), &dTOF, OF_CREATE);
if((sH > 0) && (dH >= 0)) Result = LZCopy(sH, dH);
}
__finally
{
if(sH >= 0) LZClose(sH);
if(dH >= 0) LZClose(dH);
}
return Result;
}
// 1.80 7 September 2003 RA trace message adapted
int TZipLib::DoUnload(int level)
{
loadLevel = (loadLevel & ~level) & 7; // reset bit
if (!loadLevel && hndl)
{
TZipBuilder *z = dynamic_cast<TZipBuilder *>(fOwner);
if (z->Verbose)
z->CallBack(zacMessage,0,z->LoadZipStr(LD_DllUnloaded,"unloaded ")+ Path,0);
::FreeLibrary(hndl);
hndl = NULL;
}
if (!hndl)
{
Clear();
loadLevel = 0;
}
return fVer;
}
// 1.73 (2 August 2003 RA) added minver parameter, loading by call to LoadDll
int TZipLib::DoExec(void *info, int minver)
{
LoadDll(minver, false);
int r = fExecFunc(info);
DoUnload(zldTemp);
return r;
}
AnsiString __fastcall TZipLib::GetLoadedPath(void)
{
String p = "";
String buf;
buf.SetLength(MAX_PATH);
if(hndl && GetModuleFileName(hndl, buf.c_str(), MAX_PATH))
p = buf.c_str();
return p;
}
/* TZipLIb::DoLoad
1.73 15 September RA extra parameter in LoadLib
1.73.2.6 10 September 2003 RP only load resource if later or no other found
1.73 24 July 2003 RA fix
*/
int TZipLib::DoLoad(int level)
{
loadLevel = (loadLevel | level) & 7;
if(!hndl)
{
fVer = 0;
loadLevel = level;
String FullPath = "";
TZipBuilder* zip= dynamic_cast<TZipBuilder*>(fOwner);
String dir = zip->DLLDirectory;
if(TmpFileName != "") FullPath = TmpFileName;
if(FullPath == "")
{
if(dir != "")
{
FullPath = TZipBuilder::PathConcat(dir, DllNames[IsZip]);
if(dir[1] == '.')
FullPath = TZipBuilder::PathConcat(ExtractFilePath(ParamStr(0)),FullPath);
if(!FileExists(FullPath)) FullPath = "";
}
}
if(FullPath == "")
FullPath = DllNames[IsZip]; // let Windows search the std dirs
AnsiString RVrs = LoadStr(VersRes[IsZip]);
int RVer = StrToIntDef(RVrs.SubString(1,5),0);
if(RVer > LoadLib(FullPath, RVer))
{
if(LoadLib(GetResDllPath(), true) < 17300) // res dll older than 1.73
LoadLib(FullPath, false); //could not load resource
}
if(zip->Verbose)
zip->CallBack(zacMessage,0,zip->LoadZipStr(LD_DllLoaded,"loaded ") + fPath,0);
}
return fVer;
}
// TZipLib::DoLoad
/*? TZipLib::GetResDllPath
1.73.2.6 7 September 2006 extract 'compressed' resource files
*/
AnsiString __fastcall TZipLib::GetResDllPath(void)
{
Word m;
AnsiString Result = "";
bool done = false;
AnsiString tmp = LoadStr(VersRes[IsZip]);
int ver = StrToIntDef(tmp.SubString(1,5),0);
if( ver > 17300) // works from version 1.73.0.0 onwards
{
TZipBuilder *z = dynamic_cast<TZipBuilder *>(fOwner);
if(IsZip)
TmpFileName = z->MakeTempFileName("ZMZ",".dll");
else
TmpFileName = z->MakeTempFileName("ZMU",".dll");
TResourceStream* rs = new TResourceStream((int)HInstance, DllRes[IsZip], RType);
try
{
if(rs)
{
TFileStream* fs;
try
{
rs->Read(&m, 2);
if(m == 0)
{
fs = new TFileStream(TmpFileName, fmCreate);
rs->Position = 6;
done = (fs->CopyFrom(rs,rs->Size - 6) == (rs->Size - 6));
}
else if(m == 2)
{
tmp = z->MakeTempFileName("ZMt",".tmp");
rs->Position = 6;
fs = new TFileStream(tmp, fmCreate);
done = (fs->CopyFrom(rs,rs->Size - 6) == (rs->Size - 6));
delete fs;
fs = NULL; // to avoid second delete in __finally
if(done)
{
done = Expand(tmp, TmpFileName) > 100000; // expand returns size of expanded dll
DeleteFile(tmp);
}
}
}
__finally
{
delete fs;
}
}
}
__finally
{
delete rs;
if(!done && FileExists(TmpFileName))
DeleteFile(TmpFileName);
if(!FileExists(TmpFileName)) TmpFileName = "";
else Result = TmpFileName;
}
}
return Result;
}
/*? TZipLib::GetVer
1.73.2.8 2 Oct 2003 new getter
*/
int __fastcall TZipLib::GetVer(void)
{
DoLoad(zldTemp);
int Result = fVer;
DoUnload(zldTemp);
return Result;
}
//? TZipLib::GetVer
/*? TZipLib::GetPath
1.73.2.8 2 Oct 2003 new getter
*/
AnsiString __fastcall TZipLib::GetPath(void)
{
DoLoad(zldTemp);
AnsiString Result = fPath;
DoUnload(zldTemp);
return Result;
}
//? TZipLib::GetPath
/*? TZipLib::GetPriv
1.73.2.8 2 Oct 2003 new getter
*/
int __fastcall TZipLib::GetPriv(void)
{
DoLoad(zldTemp);
int Result = fPriv;
DoUnload(zldTemp);
return Result;
}
//? TZipLib::GetPriv
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -