f029de3450
Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione Partners 2.0 patch 314 git-svn-id: svn://10.65.10.50/trunk@10444 c028cbd2-c16b-5b4b-a496-9718f37d4682
464 lines
11 KiB
C++
Executable File
464 lines
11 KiB
C++
Executable File
#include "wxinc.h"
|
|
|
|
#include <fstream.h>
|
|
|
|
#include "agasys.h"
|
|
|
|
bool aga_get_host_name(char* name, int maxlen)
|
|
{
|
|
wxString str = wxGetHostName();
|
|
const int len = str.Length();
|
|
strncpy(name, str, maxlen);
|
|
name[maxlen-1] = '\0';
|
|
return len > 0;
|
|
}
|
|
|
|
bool aga_get_user_name(char* name, int maxlen)
|
|
{
|
|
wxString str = wxGetUserId();
|
|
str.MakeUpper();
|
|
const int len = str.Length();
|
|
strncpy(name, str, maxlen);
|
|
name[maxlen-1] = '\0';
|
|
return len > 0;
|
|
}
|
|
|
|
void aga_log(const char* fmt, ...)
|
|
{
|
|
static bool bStarted = false;
|
|
FILE* log = fopen("aga.log", bStarted ? "a" : "w");
|
|
|
|
va_list argptr;
|
|
va_start(argptr,fmt);
|
|
vfprintf(log, fmt, argptr);
|
|
va_end(argptr);
|
|
fprintf(log, "\n");
|
|
|
|
fclose(log);
|
|
bStarted = true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Unzip support
|
|
///////////////////////////////////////////////////////////
|
|
|
|
#include <wx/fs_zip.h>
|
|
#include <wx/wfstream.h>
|
|
#include <wx/zipstrm.h>
|
|
|
|
#include <../src/zlib/zlib.h>
|
|
#include <../src/common/unzip.h>
|
|
|
|
class WXDLLEXPORT wxAgaZipFSHandler : public wxFileSystemHandler
|
|
{
|
|
public:
|
|
wxAgaZipFSHandler();
|
|
virtual bool CanOpen(const wxString& location);
|
|
virtual wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
|
|
virtual wxString FindFirst(const wxString& spec, int flags = 0);
|
|
virtual wxString FindNext();
|
|
~wxAgaZipFSHandler();
|
|
|
|
private:
|
|
// these vars are used by FindFirst/Next:
|
|
unzFile m_Archive;
|
|
wxString m_Pattern, m_BaseDir, m_ZipFile;
|
|
bool m_AllowDirs, m_AllowFiles;
|
|
|
|
wxString DoFind();
|
|
};
|
|
|
|
wxAgaZipFSHandler::wxAgaZipFSHandler() : wxFileSystemHandler()
|
|
{
|
|
m_Archive = NULL;
|
|
m_ZipFile = m_Pattern = m_BaseDir = wxEmptyString;
|
|
m_AllowDirs = m_AllowFiles = TRUE;
|
|
}
|
|
|
|
wxAgaZipFSHandler::~wxAgaZipFSHandler()
|
|
{
|
|
if (m_Archive)
|
|
unzClose(m_Archive);
|
|
}
|
|
|
|
bool wxAgaZipFSHandler::CanOpen(const wxString& location)
|
|
{
|
|
wxString p = GetProtocol(location);
|
|
return (p == wxT("zip"));
|
|
}
|
|
|
|
wxFSFile* wxAgaZipFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
wxString wxAgaZipFSHandler::FindFirst(const wxString& spec, int flags)
|
|
{
|
|
wxString right = GetRightLocation(spec);
|
|
wxString left = GetLeftLocation(spec);
|
|
|
|
if (right.Last() == wxT('/')) right.RemoveLast();
|
|
|
|
if (m_Archive)
|
|
{
|
|
unzClose(m_Archive);
|
|
m_Archive = NULL;
|
|
}
|
|
|
|
if (GetProtocol(left) != wxT("file"))
|
|
return wxEmptyString;
|
|
|
|
switch (flags)
|
|
{
|
|
case wxFILE:
|
|
m_AllowDirs = FALSE, m_AllowFiles = TRUE; break;
|
|
case wxDIR:
|
|
m_AllowDirs = TRUE, m_AllowFiles = FALSE; break;
|
|
default:
|
|
m_AllowDirs = m_AllowFiles = TRUE; break;
|
|
}
|
|
|
|
m_ZipFile = left;
|
|
m_Archive = (void*) unzOpen(m_ZipFile.mb_str());
|
|
m_Pattern = right.AfterLast(wxT('/'));
|
|
m_BaseDir = right.BeforeLast(wxT('/'));
|
|
|
|
if (m_Archive)
|
|
{
|
|
if (unzGoToFirstFile((unzFile)m_Archive) != UNZ_OK)
|
|
{
|
|
unzClose((unzFile)m_Archive);
|
|
m_Archive = NULL;
|
|
}
|
|
else
|
|
return DoFind();
|
|
}
|
|
return wxEmptyString;
|
|
}
|
|
|
|
wxString wxAgaZipFSHandler::FindNext()
|
|
{
|
|
if (!m_Archive) return wxEmptyString;
|
|
return DoFind();
|
|
}
|
|
|
|
wxString wxAgaZipFSHandler::DoFind()
|
|
{
|
|
const size_t nBufSize = 1024;
|
|
char* namebuf = new char[nBufSize]; // char, not wxChar!
|
|
char *c;
|
|
wxString fn, dir, name;
|
|
wxString match = wxEmptyString;
|
|
bool wasdir;
|
|
|
|
while (match == wxEmptyString)
|
|
{
|
|
unzGetCurrentFileInfo(m_Archive, NULL, namebuf, nBufSize, NULL, 0, NULL, 0);
|
|
for (c = namebuf; *c; c++) if (*c == wxT('\\')) *c = wxT('/');
|
|
fn = namebuf;
|
|
if (fn.Length() > 0 && fn.Last() == wxT('/'))
|
|
{
|
|
fn.RemoveLast();
|
|
wasdir = TRUE;
|
|
}
|
|
else wasdir = FALSE;
|
|
|
|
name = fn.AfterLast(wxT('/'));
|
|
dir = fn.BeforeLast(wxT('/'));
|
|
|
|
if (m_AllowDirs || dir == m_BaseDir)
|
|
{
|
|
if (m_AllowFiles && !wasdir && wxMatchWild(m_Pattern, name, FALSE))
|
|
match = m_ZipFile + wxT("#zip:") + fn;
|
|
if (m_AllowDirs && wasdir && wxMatchWild(m_Pattern, name, FALSE))
|
|
match = m_ZipFile + wxT("#zip:") + fn;
|
|
}
|
|
|
|
if (unzGoToNextFile(m_Archive) != UNZ_OK)
|
|
{
|
|
unzClose(m_Archive);
|
|
m_Archive = NULL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
delete [] namebuf;
|
|
|
|
return match;
|
|
}
|
|
|
|
bool aga_unzip(const char* zipfile, const char* destdir)
|
|
{
|
|
wxString str = zipfile;
|
|
str += "#zip:*";
|
|
|
|
wxAgaZipFSHandler fs;
|
|
wxString strInFile = fs.FindFirst(str, 0);
|
|
while (!strInFile.IsEmpty())
|
|
{
|
|
const int nDiesis = strInFile.Find('#');
|
|
const wxString strFileName = strInFile.Mid(nDiesis+5);
|
|
wxZipInputStream fin(zipfile, strFileName);
|
|
|
|
wxString strOutFile = destdir;
|
|
strOutFile += '/';
|
|
strOutFile += strFileName;
|
|
|
|
wxString strPath;
|
|
::wxSplitPath(strOutFile, &strPath, NULL, NULL);
|
|
if (!::wxDirExists(strPath))
|
|
::wxMkdir(strPath);
|
|
|
|
wxFFileOutputStream fout(strOutFile);
|
|
fout.Write(fin);
|
|
|
|
strInFile = fs.FindNext();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Zip support
|
|
///////////////////////////////////////////////////////////
|
|
|
|
#include <wx/zstream.h>
|
|
|
|
#pragma pack(2)
|
|
|
|
struct ZipLocalFileHeader
|
|
{
|
|
unsigned short nVersionNeeded;
|
|
unsigned short nFlags;
|
|
unsigned short nMethod;
|
|
unsigned short nLastModTime;
|
|
unsigned short nLastModDate;
|
|
unsigned long dwCRC;
|
|
unsigned long dwCompressedSize;
|
|
unsigned long dwUncompressedSize;
|
|
unsigned short nNameLength;
|
|
unsigned short nExtraLength;
|
|
};
|
|
|
|
struct ZipDirectoryFileHeader
|
|
{
|
|
unsigned short nVersionUsed;
|
|
ZipLocalFileHeader zlfh;
|
|
unsigned short nCommentLength;
|
|
unsigned short nStartDisk;
|
|
unsigned short nInternalAttr;
|
|
unsigned long nExternalAttr;
|
|
unsigned long nLocalHeaderOffset;
|
|
};
|
|
|
|
struct ZipDirectoryEnd
|
|
{
|
|
unsigned short nThisDisk;
|
|
unsigned short nStartDisk;
|
|
unsigned short nDiskEntries;
|
|
unsigned short nTotalEntries;
|
|
unsigned long nSize;
|
|
unsigned long nStartOffset;
|
|
unsigned short nCommentLength;
|
|
};
|
|
|
|
#pragma pack()
|
|
|
|
class AgaZlibOutputStream : public wxZlibOutputStream
|
|
{
|
|
public:
|
|
AgaZlibOutputStream(wxOutputStream& stream, int level);
|
|
};
|
|
|
|
AgaZlibOutputStream::AgaZlibOutputStream(wxOutputStream& stream, int level)
|
|
: wxZlibOutputStream(stream, level)
|
|
{
|
|
const int DEF_MEM_LEVEL = 8;
|
|
deflateInit2_(m_deflate, level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL,
|
|
Z_DEFAULT_STRATEGY, "1.1.2", sizeof(*m_deflate));
|
|
}
|
|
|
|
static int AddFilesToList(const wxString& strBase, const wxString& strMask, wxStringList& aFiles)
|
|
{
|
|
int n = 0;
|
|
wxString f = strBase + "/" + strMask;
|
|
f = ::wxFindFirstFile(f, 0);
|
|
while (!f.IsEmpty())
|
|
{
|
|
if (wxDirExists(f))
|
|
{
|
|
n += AddFilesToList(f, strMask, aFiles);
|
|
}
|
|
else
|
|
{
|
|
aFiles.Add(f);
|
|
n++;
|
|
}
|
|
f = ::wxFindNextFile();
|
|
}
|
|
return n;
|
|
}
|
|
|
|
static unsigned long ComputeCRC(const char* strFile)
|
|
{
|
|
const int nSize = 1024*64;
|
|
wxByte* buffer = new wxByte[nSize];
|
|
unsigned long dwCrc = 0;
|
|
|
|
wxFFileInputStream fin(strFile);
|
|
unsigned long nLastRead = nSize;
|
|
while (nLastRead == nSize)
|
|
{
|
|
fin.Read(buffer, nSize);
|
|
nLastRead= fin.LastRead();
|
|
dwCrc = crc32(dwCrc, buffer, nLastRead);
|
|
}
|
|
return dwCrc;
|
|
}
|
|
|
|
static void AddFileToZip(const wxString& strPrefix, const wxString& strFile,
|
|
wxFFileOutputStream& fout, wxFFileOutputStream& fdir)
|
|
{
|
|
if (!wxFileExists(strFile))
|
|
return;
|
|
|
|
wxString strPath, strName, strExt;
|
|
wxSplitPath(strFile, &strPath, &strName, &strExt);
|
|
|
|
wxString strRelName;
|
|
strRelName = strPath.Mid(strPrefix.Length());
|
|
if (!strRelName.IsEmpty())
|
|
strRelName += '/';
|
|
strRelName += strName;
|
|
strRelName += '.';
|
|
strRelName += strExt;
|
|
|
|
const off_t nStartPos = fout.TellO(); // Memorizzo posizione
|
|
|
|
const unsigned long dwLocalSignature = 0x04034B50;
|
|
fout.Write(&dwLocalSignature, sizeof(dwLocalSignature)); // Scrivo PK34
|
|
ZipLocalFileHeader zlfh; memset(&zlfh, 0, sizeof(zlfh));
|
|
zlfh.nVersionNeeded = 20; // You need at least pkunzip 2.0
|
|
zlfh.nFlags = 0x0002; // Deep Hacking ???
|
|
zlfh.nMethod = 8; // Implode
|
|
zlfh.nNameLength = strRelName.Length();
|
|
fout.Write(&zlfh, sizeof(zlfh)); // Scrivo header azzerato
|
|
fout.Write((const char*)strRelName, zlfh.nNameLength); // Scrivo nome file
|
|
|
|
const off_t nDataStart = fout.TellO(); // Memorizzo posizione dati compressi
|
|
const int nMagicOffset = -4; // Deep hacking :-)
|
|
|
|
{
|
|
wxFFileInputStream fin(strFile);
|
|
AgaZlibOutputStream zout(fout, 9);
|
|
zout.Write(fin); // Scrivo file compresso
|
|
zlfh.dwUncompressedSize = fin.TellI();
|
|
}
|
|
|
|
fout.SeekO(nMagicOffset, wxFromEnd);
|
|
|
|
zlfh.dwCompressedSize = fout.TellO();
|
|
zlfh.dwCompressedSize -= nDataStart;
|
|
zlfh.dwCRC = ComputeCRC(strFile);
|
|
|
|
const time_t tMod = ::wxFileModificationTime(strFile);
|
|
const struct tm* t = localtime(&tMod);
|
|
if (t != NULL)
|
|
{
|
|
zlfh.nLastModDate = t->tm_mday + ((t->tm_mon+1) << 5) + ((t->tm_year-80) << 9);
|
|
zlfh.nLastModTime = t->tm_sec/2 + (t->tm_min << 5) + (t->tm_hour << 11);
|
|
}
|
|
|
|
fout.SeekO(nStartPos+sizeof(dwLocalSignature), wxFromStart);
|
|
fout.Write(&zlfh, sizeof(zlfh));
|
|
// fout.Write((const char*)strRelName, strRelName.Length());
|
|
|
|
// Deep Hacking Here!
|
|
// const wxByte pkHeader = 0x85;
|
|
// fout.Write(&pkHeader, 1);
|
|
|
|
fout.SeekO(nMagicOffset, wxFromEnd);
|
|
|
|
ZipDirectoryFileHeader zdfh; memset(&zdfh, 0, sizeof(zdfh));
|
|
zdfh.nVersionUsed = zlfh.nVersionNeeded;
|
|
memcpy(&zdfh.zlfh, &zlfh, sizeof(zlfh));
|
|
zdfh.nLocalHeaderOffset = nStartPos;
|
|
|
|
const unsigned long dwDirectorySignature = 0x02014B50; // Scrivo PK12
|
|
fdir.Write(&dwDirectorySignature, sizeof(dwDirectorySignature));
|
|
fdir.Write(&zdfh, sizeof(zdfh)); // Scrivo entry directory
|
|
fdir.Write((const char*)strRelName, strRelName.Length());
|
|
}
|
|
|
|
static bool AddFilesToZip(const wxString& strBase, wxStringList& aFiles, const char* zipfile)
|
|
{
|
|
const char* zipdir = "zipdir.tmp";
|
|
|
|
wxFFileOutputStream fout(zipfile);
|
|
|
|
off_t nDirSize = 0, nDirStart = 0;
|
|
|
|
if (aFiles.GetCount() > 0) // Dummy test
|
|
{
|
|
wxFFileOutputStream fdir(zipdir);
|
|
wxStringListNode* node = aFiles.GetFirst();
|
|
while (node)
|
|
{
|
|
const wxString strFile = node->GetData();
|
|
AddFileToZip(strBase, strFile, fout, fdir);
|
|
node = node->GetNext();
|
|
}
|
|
nDirSize = fdir.TellO();
|
|
nDirStart = fout.TellO();
|
|
}
|
|
|
|
if (nDirSize > 0)
|
|
{
|
|
wxFFileInputStream fdir(zipdir);
|
|
fout.Write(fdir); // Append central directory
|
|
|
|
ZipDirectoryEnd zde; memset(&zde, 0, sizeof(zde));
|
|
zde.nDiskEntries = zde.nTotalEntries = aFiles.GetCount();
|
|
zde.nSize = nDirSize;
|
|
zde.nStartOffset = nDirStart;
|
|
|
|
const unsigned long dwEndDirectorySignature = 0x06054B50;
|
|
fout.Write(&dwEndDirectorySignature, sizeof(dwEndDirectorySignature));
|
|
fout.Write(&zde, sizeof(zde));
|
|
}
|
|
|
|
if (nDirSize > 0)
|
|
wxRemoveFile(zipdir);
|
|
|
|
return nDirSize > 0;
|
|
}
|
|
|
|
bool aga_zip(const char* srcfiles, const char* zipfile)
|
|
{
|
|
wxString strBase, strMask, strExt;
|
|
wxSplitPath(srcfiles, &strBase, &strMask, &strExt);
|
|
strMask += '.';
|
|
strMask += strExt;
|
|
|
|
wxStringList aFiles;
|
|
AddFilesToList(strBase, strMask, aFiles);
|
|
|
|
return AddFilesToZip(strBase, aFiles, zipfile);
|
|
}
|
|
|
|
bool aga_zip_filelist(const char* filelist, const char* zipfile)
|
|
{
|
|
wxStringList aFiles;
|
|
ifstream fin(filelist);
|
|
while (!fin.eof())
|
|
{
|
|
char name[MAX_PATH];
|
|
fin.getline(name, sizeof(name));
|
|
if (*name)
|
|
aFiles.Add(name);
|
|
else
|
|
break;
|
|
}
|
|
return AddFilesToZip("", aFiles, zipfile);
|
|
}
|
|
|