1 Star 0 Fork 5

freestars/ZHLT_UPack

forked from ccc1/ZHLT_UPack 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
PackageFile.cpp 52.05 KB
一键复制 编辑 原始数据 按行查看 历史
ccc1 提交于 2016-08-22 09:19 . .
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164
#include "StdAfx.h"
#include "PackageFile.h"
#include "Compress.h"
#include <io.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <Shlwapi.h>
#include <zlib/zlib.h>
#include "md5.h"
using namespace SECRIET;
#define SEC_KEY_PARAM1 "*+!rjwe&oe2m0!4_yn2v"
#define SEC_KEY_PARAM2 "@#!web$jeofgr.,?i_32"
#define SEC_KEY_PARAM3 "/?>we68etofgr_)37kl,"
#define SEC_KEY_PARAM4 "<me[laierp0924-rkop"
#define SEC_KEY_PARAM5 "abcdefgjijklmnopqrs"
#define SEC_KEY_PARAM6 "tquvw1234567890!@#$"
#define SEC_KEY_PARAM7 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define SEC_KEY_SIZE strlen(SEC_KEY_PARAM1)
#ifndef ENCRYPT
#define ENCRYPT0(x,xlen,KEY,BeginPlace,KeyLen) if( (x)!=NULL ) \
{ \
\
BYTE* t_pBuffer = (x); \
for (UINT i = 0; i < (xlen); i++) \
{ \
*t_pBuffer ^= KEY[(i+BeginPlace)%KeyLen]; \
t_pBuffer++; \
} \
}
#define ENCRYPT(x,xlen,KEY,BeginPlace,KeyLen) if( (x)!=NULL ) \
{ \
BYTE* t_pBuffer = (x); \
BYTE chKey = 0; \
for (UINT i = 0; i < (xlen); i++) \
{ \
chKey = KEY[(i+BeginPlace)%KeyLen]; \
if ( *t_pBuffer && *t_pBuffer != chKey ) \
*t_pBuffer ^= chKey; \
t_pBuffer++; \
} \
}
#endif
void _tagPackageHeader_1_0::InitPassword()
{
const char *p[7] = {SEC_KEY_PARAM1,SEC_KEY_PARAM2,SEC_KEY_PARAM3,SEC_KEY_PARAM4,SEC_KEY_PARAM5,SEC_KEY_PARAM6,SEC_KEY_PARAM7};
for( int i=0 ;i<8; ++i )
{
for( int j=0; j<16; ++j )
{
secPassword[j][i] = p[ (i+j)%7 ][ (i*j)%18];
}
}
}
BOOL _FileIsExist(LPCTSTR DirName)
{
if(DirName==NULL)
return FALSE;
DWORD dwAttr = ::GetFileAttributes(DirName);
if (dwAttr == 0xFFFFFFFF)
return FALSE;
if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY )
return FALSE;
return TRUE;
}
std::string ConvertLower(const std::string& name)
{
std::string ret;
for(int i = 0; i < name.size() ; ++i)
ret+= (char)tolower(name.at(i));
return ret;
}
int gpCompress(char *pDst,UINT &lenDst,const char *pSrc,UINT lenSrc,int nCompressMethod)
{
uLongf len = lenDst;
int n = compress2((Bytef *)pDst,&len,(const Bytef *)pSrc,lenSrc,nCompressMethod);
lenDst = len;
return n;
}
int gpUncompress(char *pDst,UINT &lenDst,const char *pSrc,UINT lenSrc)
{
uLongf len = lenDst;
int n = uncompress((Bytef *)pDst,&len,(const Bytef *)pSrc,lenSrc);
lenDst = len;
return n;
}
CPackageFile::CPackageFile(void)
{
m_pFuncCompress = NULL;
m_pFuncUnCompress = NULL;
m_hFile = -1;
//m_hIndexFile = -1;
Close();
SetCompressFunc(gpCompress , gpUncompress);
}
CPackageFile::~CPackageFile(void)
{
Close();
}
//-----------------------------------------------------------------------------------
// 确定文件是否打开
// 参数:
//
// 返回值:
// 打开TRUE,否则返回FALSE
BOOL CPackageFile::IsOpen()
{
if(m_hFile == -1)
{
return FALSE;
}
else
{
return TRUE;
}
}
//-----------------------------------------------------------------------------------
// 返回包中文件个数
// 参数:
//
// 返回值:
// 失败返回-1, 成功返回文件个数
INT CPackageFile::GetFileCount()
{
if(!IsOpen())
{
return -1;
}
int nCount = 0;
for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
{
if( it->second->byModifyFlag != GL_FILE_STATE_MARK_DEL )
nCount++;
}
return nCount;
}
//-----------------------------------------------------------------------------------
// 判断文件在包中是否存在
// 参数:
// lpszFileName 文件名,不包含路径
// 返回值:
// 文件存在返回TRUE,否则返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::FileExist(LPCTSTR lpszFileName)
{
FileIndexList::iterator it = m_PackFileIndex.find(strlwr( _strdup(lpszFileName)));
if ( it != m_PackFileIndex.end() )
{
if( it->second->byModifyFlag == GL_FILE_STATE_NORMAL)
return TRUE;
}
return FALSE;
}
ConFileIndex CPackageFile::GetFileIndex( LPCTSTR pFilename )
{
FileIndexList::iterator it = m_PackFileIndex.find(strlwr( _strdup(pFilename)));
return it;
}
BOOL CPackageFile::IsSameFile( const PACKAGE_FILE_INFO &fInfo )
{
if( !FileExist( fInfo.szFileName) )
return FALSE;
PACKAGE_FILE_INFO fLocalInfo;
GetFileInfo( GetFileIndex(fInfo.szFileName), fLocalInfo );
if( fLocalInfo.uAppendInfoLength != 0 )
{
int br = 0;
++br;
}
BOOL b = (fInfo.uFileLength==fLocalInfo.uFileLength) && (fInfo.uAppendInfoLength==fLocalInfo.uAppendInfoLength);
if( b )
return memcmp( fLocalInfo.szBufferID, fInfo.szBufferID, 16 ) == 0;
else
return FALSE;
}
VOID CPackageFile::EnableSecret( BOOL b)
{
m_PackageHeader.dwSec = b;
}
//-----------------------------------------------------------------------------------
// 设置包的描述字符串
// 参数:
// lpszTitle 包说明
// 返回值:
//
//-----------------------------------------------------------------------------------
void CPackageFile::SetPackageTitle(LPCTSTR lpszTitle)
{
if(m_bReadOpen)
{
return;
}
if(lpszTitle == NULL)
{
return;
}
ZeroMemory(m_PackageHeader.szPackageName, sizeof(m_PackageHeader.szPackageName));
if(_strlen(lpszTitle) >= 127)
{
StrCpyN(m_PackageHeader.szPackageName,lpszTitle,127);
}
else
{
StrCpy(m_PackageHeader.szPackageName,lpszTitle);
}
if( _lseeki64(m_hFile, sizeof(CHAR) * 4, SEEK_SET) == -1)
{
return ;
}
Write(m_hFile, &m_PackageHeader.szPackageName, sizeof(m_PackageHeader.szPackageName));
}
//-----------------------------------------------------------------------------------
// 返回包的描述字符串
// 参数:
//
// 返回值:
// 包说明
//-----------------------------------------------------------------------------------
LPCTSTR CPackageFile::GetPackageTitle()
{
return m_PackageHeader.szPackageName;
}
void CPackageFile::SetPackageFileVersion( INT nVersion )
{
m_PackageHeader.dwPackageFileVersion = nVersion;
}
INT CPackageFile::GetPackageFileVersion()
{
return m_PackageHeader.dwPackageFileVersion;
}
void CPackageFile::SetPackageFilePreVersion(INT nVersion )
{
m_PackageHeader.dwPackageFilePreVersion = nVersion;
}
INT CPackageFile::GetPackageFilePreVersion()
{
return m_PackageHeader.dwPackageFilePreVersion;
}
void CPackageFile::SetPackageType( BYTE nType )
{
m_PackageHeader.dwPackageFileType = nType;
}
BYTE CPackageFile::GetPackageType()
{
return m_PackageHeader.dwPackageFileType;
}
void CPackageFile::SavePackageHeaderToDisk()
{
_lseeki64(m_hFile, 0, SEEK_SET);
SavePackageHeader(m_hFile);
}
//-----------------------------------------------------------------------------------
// 功 能:检测当前版本是不是类支持的最新版本
// 返回值:
// 不是最新版返回TRUE,否则返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::IsNeedUpdate()
{
if(m_PackageHeader.dwPackageVersion > PACKAGE_VERSOIN)
{
return FALSE;
}
if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSOIN)
{
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------------------
// 功 能:如果当前版本不是类支持的最新版本则升级文件
// 返回值:
// 不用升级或升级成功返回TRUE,否则返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::UpdatePackageFile()
{
if(!IsNeedUpdate())
{
return TRUE;
}
//保存文件内容
TCHAR szBackFile[MAX_PATH];
TCHAR szPathName[MAX_PATH];
TCHAR szIndexFile[MAX_PATH];
StrCpy(szPathName, m_szPathName);
ZeroMemory(szIndexFile, sizeof(szIndexFile));
ZeroMemory(szBackFile, sizeof(szBackFile));
StrCpy(szIndexFile, m_szPathName);
StrCpy(szBackFile, m_szPathName);
StrCat(szBackFile, _T(".bak"));
StrCat(szIndexFile, _T(".idx"));
if(!Save(szBackFile))
{
return FALSE;
}
Close();
if(_FileIsExist(szIndexFile))
{
if(!DeleteFile(szIndexFile))
{
return Open(szPathName, GL_FILE_OPEN_WRITE);
}
}
if(DeleteFile(szPathName))
{
__rename(szBackFile, szPathName);
}
return Open(szPathName, GL_FILE_OPEN_WRITE);
}
//-----------------------------------------------------------------------------------
// 打开包文件
// 参数:
// hFile 已经打开的文件句柄
// 返回值:
// 成功回TRUE,失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::Open(INT hFile)
{
if(hFile == -1)
{
return FALSE;
}
m_hFile = hFile;
//m_hIndexFile = -1;
if( _filelength(hFile) == 0)
{
m_PackageHeader.dbModifyTime = GetSystemTime();
m_PackageHeader.InitPassword();
m_PackageHeader.dwFileState = 0;
m_PackageHeader.dwSec = 1;
m_PackageHeader.dwPackageVersion = PACKAGE_VERSOIN;
int offset = (BYTE*)&m_PackageHeader.dwFileState-(BYTE*)&m_PackageHeader;
return SavePackageHeader();
}
//验证文件有效性
m_hFile = hFile;
int sizePKH = 936;
int sizePKH_C = sizeof(m_PackageHeader);
UINT uPackHeaderSize = sizeof(m_PackageHeader) - sizeof(double);
///1.0版本的空文件长度
if( _read(m_hFile, &m_PackageHeader, uPackHeaderSize) < SAVE_FLAG_POSITION_1_0 )
{
Close();
return FALSE;
}
ULONG *pL = (ULONG *)&m_PackageHeader;
ULONG l1 = pL[0];
if(StrCmp(m_PackageHeader.szPackIdentifier,_T(FILE_PACKET_IDENTIFY)) != 0)
{
Close();
return FALSE;
}
//检查版号1.0
if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_0)
{
//1.0版本没有这个字椴
m_PackageHeader.dbModifyTime = GetSystemTime();
//对于以前版本的文件将以只读方式打开
memset( &m_PackageHeader.dwReserved, 0 ,sizeof(m_PackageHeader.dwReserved) );
_lseeki64( hFile, SAVE_FLAG_POSITION_1_0, SEEK_SET ); ///对于以前版本,设置到正确的初始位置
// m_bReadOpen = TRUE;
}
//当前最新版本
else if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_2)
{
//if( sizeof(DWORD)*128 != _read(hFile, &m_PackageHeader.dwReserved, sizeof(DWORD)*128) )
//{
// return false;
//}
int x = 0;
}
else
{
Close();
return FALSE;
}
if( sizeof(BYTE) != _read(hFile, &m_bySaveFlags, sizeof(BYTE) ))
{
return TRUE;
}
if(m_bySaveFlags == 1)
{
//TRACE("\n发现包数据写入错,尝试恢复\n");
}
if(!CreateFileIndex())
{
return FALSE;
}
return TRUE;
}
BOOL CPackageFile::DelAllFile()
{
for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
{
delete it->second;
}
m_PackFileIndex.clear();
_chsize_s(m_hFile, 0 );
_lseeki64(m_hFile, 0, SEEK_SET);
m_PackageHeader.dwDelNumberInBytes = 0;
SavePackageHeader(m_hFile);
BeginSave( m_hFile );
// Save(m_szPathName);
EndSave( m_hFile );
return TRUE;
}
//-----------------------------------------------------------------------------------
// 从索引文件读入文件索引表
// 参数:
//
// 返回值:
//
//-----------------------------------------------------------------------------------
/*
BOOL CPackageFile::LoadFileIndex(INT hFile)
{
//不再使用索引文件
return FALSE;
if(hFile == -1)
{
return FALSE;
}
UINT uFileLen = _filelength(hFile);
if(uFileLen == 0)
{
return FALSE;
}
BYTE* pBuf = Read(hFile, uFileLen);
if(pBuf == NULL)
{
return FALSE;
}
BYTE* pRead = pBuf;
DWORD* pVersion = (DWORD*)pBuf;
if(uFileLen < (UINT)sizeof(DWORD) || *pVersion != PACKAGE_VERSOIN)
{
delete[] pBuf;
return FALSE;
}
pRead += (int)sizeof(DWORD);
uFileLen -= (UINT)sizeof(DWORD);
double* pModifyTime = (double*)pRead;
if(uFileLen < (UINT)sizeof(double) || *pModifyTime != m_PackageHeader.dbModifyTime)
{
delete[] pBuf;
return FALSE;
}
pRead += (int)sizeof(double);
uFileLen -= (UINT)sizeof(double);
if( (uFileLen % sizeof(PACKAGE_INDEX)) != 0)
{
return FALSE;
}
int uCount = uFileLen / sizeof(PACKAGE_INDEX);
for(int i = 0; i < uCount; i++)
{
PACKAGE_INDEX* pAddIndex = new PACKAGE_INDEX;
if(pAddIndex == NULL)
{
continue;
}
memcpy(pAddIndex, pRead, sizeof(PACKAGE_INDEX));
m_PackFileIndex.AddTail(pAddIndex);
pRead += sizeof(PACKAGE_INDEX);
}
delete[] pBuf;
return TRUE;
}
*/
//-----------------------------------------------------------------------------------
// 更新文件索引表
// 参数:
// pIndex 标识要更新的文件,如果为NULL 则更新整个文件索引表
// 返回值:
// 成功返回TRUE 失败返回FALSE
//-----------------------------------------------------------------------------------
/*
BOOL CPackageFile::SaveFileIndex(INT hFile, const PACKAGE_INDEX* pIndex)
{
//不再需要索引文件
return TRUE;
//file is readonly
if(hFile == -1)
{
if(m_bReadOpen)
{
return FALSE;
}
}
if(hFile == -1)
{
return FALSE;
}
if(pIndex == NULL)
{
if(_chsize( hFile, 0) == -1)
{
ASSERT(NULL);
return FALSE;
}
DWORD ver = PACKAGE_VERSOIN;
if(!Write(hFile, &ver, sizeof(DWORD)))
{
return FALSE;
}
if(!Write(hFile, &m_PackageHeader.dbModifyTime, sizeof(m_PackageHeader.dbModifyTime)))
{
return FALSE;
}
POSITION pos = m_PackFileIndex.GetHeadPosition();
while(pos != NULL)
{
PACKAGE_INDEX* pSave = (PACKAGE_INDEX*)m_PackFileIndex.GetNext(pos);
if(pSave != NULL)
{
if(!Write(hFile, pSave, sizeof(PACKAGE_INDEX)))
{
return FALSE;
}
}
}
}
else
{
if( _lseek(hFile, sizeof(DWORD), SEEK_SET) == -1)
{
return FALSE;
}
if(!Write(hFile, &m_PackageHeader.dbModifyTime, sizeof(m_PackageHeader.dbModifyTime)))
{
return FALSE;
}
if( _lseek(hFile, 0, SEEK_END) == -1)
{
return FALSE;
}
///
ASSERT(NULL);
//注意,查找到指定的Index 进行更新
//..
//..
//..
if(!Write(hFile, (PVOID)pIndex, sizeof(PACKAGE_INDEX)))
{
return FALSE;
}
}
return TRUE;
} */
/*
void CPackageFile::GetIndexFileName(const char* lpszFileName, char* lpIndexFile)
{
strcpy(lpIndexFile, lpszFileName);
char *ptr = lpIndexFile + strlen(lpIndexFile) - 1;
while(ptr >= lpIndexFile)
{
if(*ptr == '.')break;
ptr --;
}
ptr++;
ptr[0] = 'i';
ptr[1] = 'd';
ptr[2] = 'x';
ptr[3] = '\0';
}*/
void CPackageFile::GetBackupFileName(const char* lpszFileName, char* lpIndexFile)
{
strcpy(lpIndexFile, lpszFileName);
char *ptr = lpIndexFile + strlen(lpIndexFile) - 1;
while(ptr >= lpIndexFile)
{
if(*ptr == '.')break;
ptr --;
}
ptr++;
ptr[0] = 'b';
ptr[1] = 'a';
ptr[2] = 'k';
ptr[3] = '\0';
}
//-----------------------------------------------------------------------------------
// 打开包文件
// 参数:
// lpszFileName 文件名
// dwOpenMode 打开文件 GL_FILE_OPEN_WRITE GL_FILE_OPEN_READ
// 返回值:
// 成功回TRUE,失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::Open(LPCTSTR lpszFileName, DWORD dwOpenMode)
{
Close();
if(lpszFileName == NULL)
{
return FALSE;
}
StrCpy(m_szPathName,lpszFileName);
INT hFile;
if(dwOpenMode == GL_FILE_OPEN_READ)
{
hFile = __open(lpszFileName, _O_BINARY | _O_RDONLY, _S_IREAD);
m_bReadOpen = TRUE;
}
else
{
m_bReadOpen = FALSE;
hFile = __open(lpszFileName, _O_BINARY | _O_RDWR, 0);
}
//尝试重复份文件恢复
if(hFile == -1)
{
TCHAR szBackFile[MAX_PATH];
ZeroMemory(szBackFile, sizeof(szBackFile));
StrCpy(szBackFile, lpszFileName);
StrCat(szBackFile, _T(".bak"));
hFile = __open(szBackFile, _O_RDONLY, 0);
if(hFile != -1)
{
_close(hFile);
hFile = -1;
if(__rename(szBackFile,lpszFileName) == 0)
{
return Open(lpszFileName);
}
}
}
//创建文件
if(hFile == -1)
{
hFile = __open(lpszFileName, _O_BINARY | _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE);
}
return Open(hFile);
}
//-----------------------------------------------------------------------------------
// 向包增加一个文件
// 参数
// lpszFileName 文件名
// lpszPathName 文件路径
// lpszAppendInfo 文件附加信息文件
// bCompress 文件是否压缩
// 返回值:
// 成功返回TRUE,失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::AddFile(LPCTSTR lpszFileName, LPCTSTR lpszPathFile, UINT uMothedForExist, BOOL bSec, LPCTSTR lpszAppendInfoFile, BOOL bCompress)
{
if(m_bReadOpen)
{
return FALSE;
}
//检查文件是否存在
if(lpszFileName == NULL || lpszPathFile == NULL)
{
return FALSE;
}
BYTE *pbyFileData = NULL;
UINT uFileDataLen = 0;
BYTE *pbyAppendInfoData = NULL;
UINT uAppendInfoDataLen = 0;
UINT uLen = -1;
//读取文件
INT hFile = __open(lpszPathFile, _O_BINARY | _O_RDONLY, _S_IREAD);
uLen = _filelengthi64(hFile);
pbyFileData = Read(hFile, uLen, 0);
uFileDataLen = uLen;
_close(hFile);
//读取文件附加信息
uLen = 0;
if(lpszAppendInfoFile != NULL)
{
hFile = __open(lpszAppendInfoFile, _O_BINARY | _O_RDONLY, _S_IREAD);
if(hFile != -1)
{
uLen = _filelengthi64(hFile);
if(uLen == 0)
{
return FALSE;
}
pbyAppendInfoData = Read(hFile, uLen, 0);
uAppendInfoDataLen = uLen;
_close(hFile);
}
}
BOOL bRet = AddFile(lpszFileName, pbyFileData, uFileDataLen, uMothedForExist, pbyAppendInfoData, bSec, uAppendInfoDataLen, bCompress);
if(pbyFileData != NULL)
{
// delete pbyFileData;
free(pbyFileData);
}
if(pbyAppendInfoData != NULL)
{
// delete pbyAppendInfoData;
free(pbyAppendInfoData);
}
return bRet;
}
//-----------------------------------------------------------------------------------
// 从指定的位置读取指定长度的数据
// 参数:
// hFile 已经打开的文件句柄
// uRead 要读取的字节数,-1从文件开始处读取整个文件内容
// lReadPosition 读取的开始位置,-1从当前位置开始读
// 返回值:
// 文件内容,些指针要由用户释放,如果读取失败返回NULL
//-----------------------------------------------------------------------------------
BYTE* CPackageFile::Read(INT hFile, UINT uRead, UINT lReadPosition) const
{
if(hFile == -1)
{
return NULL;
}
UINT uReadLen = uRead;
if( (uRead == 0) || (uRead > FILE_PACKAGE_MAX_LENGTH) )
{
uReadLen = (UINT)_filelengthi64(hFile);
if(uReadLen <= 0)
{
return NULL;
}
if( _lseeki64(hFile,0,SEEK_SET) == -1)
{
return NULL;
}
}
else if(lReadPosition < FILE_PACKAGE_MAX_LENGTH)
{
if( _lseeki64(hFile, lReadPosition, SEEK_SET) == -1)
{
return NULL;
}
}
BYTE* pBuf = (BYTE *)malloc(uReadLen);/// new BYTE[uReadLen];
if(pBuf == NULL)
{
return NULL;
}
if(uReadLen != (UINT)_read(hFile, pBuf, uReadLen))
{
// delete[] pBuf;
free(pBuf);
return NULL;
}
return pBuf;
}
INT CPackageFile::ReadTo(INT hFile, BYTE *pBufferTo, UINT nBufferLength, UINT uRead, UINT lReadPosition )
{
if(hFile == -1)
{
return -1;
}
UINT uReadLen = uRead;
if( (uRead == 0) || (uRead > FILE_PACKAGE_MAX_LENGTH) )
{
uReadLen = (UINT)_filelengthi64(hFile);
if(uReadLen <= 0)
{
return -1;
}
if( _lseeki64(hFile,0,SEEK_SET) == -1)
{
return -1;
}
}
else if(lReadPosition < FILE_PACKAGE_MAX_LENGTH )
{
if( _lseeki64(hFile, lReadPosition, SEEK_SET) == -1)
{
return NULL;
}
}
if(uReadLen > nBufferLength)
{
return -1;
}
BYTE* pBuf = (BYTE *)pBufferTo;/// new BYTE[uReadLen];
if(uReadLen != (UINT)_read(hFile, pBuf, uReadLen))
{
// delete[] pBuf;
return -1;
}
return uReadLen;
}
//-----------------------------------------------------------------------------------
// 在指定的位置写入指定长度的数据
// 参数:
// hFile 已经打开的文件句柄
// pBuf 要写入的数据
// uBufLen 数据长度
// lWritePosition 写入位置,-1在当前位置写入
// 返回值:
// 成功返回TRUE,失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::Write(INT hFile, const void * pBuf, UINT uBufLen, UINT lWritePosition)
{
if(hFile == -1 || pBuf == NULL || uBufLen < 0)
{
return FALSE;
}
if(lWritePosition < FILE_PACKAGE_MAX_LENGTH )
{
if( _lseeki64(hFile, lWritePosition, SEEK_SET) == -1)
{
return FALSE;
}
}
if((int)uBufLen != _write(hFile, pBuf, uBufLen) )
{
return FALSE;
}
return TRUE;
}
VOID CPackageFile::WritePackageFileHeader( const PACKAGE_FILE_HEADER &ph )
{
if( ph.bSecIndex < 64 )
{
Write(m_hFile, &ph, sizeof(PACKAGE_FILE_HEADER));
}
else
{
PACKAGE_FILE_HEADER enH = ph;
enH.bSecLen = strlen(enH.szFileName);
ENCRYPT( (BYTE *)enH.szFileName, 260, m_PackageHeader.secPassword[ ph.bSecIndex - 64 ], 888888, 16);
Write( m_hFile, &enH, sizeof(PACKAGE_FILE_HEADER) );
}
}
BOOL CPackageFile::ReadPackageFileHeader( PACKAGE_FILE_HEADER &ph ,BOOL bEncrypt) const
{
if( m_PackageHeader.dwFileInfoOffset > sizeof(PACKAGE_FILE_HEADER) )
{
UINT nPos = _telli64(m_hFile);
if( nPos >= (m_PackageHeader.dwFileInfoOffset - sizeof(PACKAGE_FILE_HEADER)) )
{
return FALSE;
}
}
if (_read(m_hFile, &ph, sizeof(PACKAGE_FILE_HEADER) ) != sizeof(PACKAGE_FILE_HEADER) )
return FALSE;
if( ph.bSecIndex >= 64 && bEncrypt)
{
ENCRYPT((BYTE *) ph.szFileName, 260, m_PackageHeader.secPassword[ ph.bSecIndex - 64 ], 888888, 16);
}
return TRUE;
}
//-----------------------------------------------------------------------------------
// 向包增加一个文件
// 参数:
// lpszFileName 文件名,不包含路径
// pbyFileData 文件内容
// uFileDataLen 文件长度
// pbyAppendInfoData 文件附加信息,没有附加信息应为NULL
// uAppendInfoDataLen 文件附加信息长度
// bCompress` 是否进行压缩
// 返回值:
// 成功返回TRUE,失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::AddFile(LPCTSTR lpszFileName, BYTE *pbyFileData, UINT uFileDataLen, UINT uMothedForExist, BYTE *pbyAppendInfoData, BOOL bSec, UINT uAppendInfoDataLen, BOOL bCompress)
{
if(m_bReadOpen)
{
return FALSE;
}
if(pbyFileData == NULL || uFileDataLen <= 0 || lpszFileName == NULL)
{
return FALSE;
}
//检查文件是否已经存在
if(uMothedForExist == GL_MOTHED_NONE)
{
if(CPackageFile::FileExist(lpszFileName))
{
return FALSE;
}
}
else
{
DelFile(lpszFileName, uMothedForExist);
}
PACKAGE_FILE_HEADER FileHeader;
StrCpy(FileHeader.szFileName, ConvertLower(lpszFileName).c_str() );
FileHeader.byModify = GL_FILE_STATE_NORMAL;
FileHeader.uAppendInfoLength = uAppendInfoDataLen;
FileHeader.bCompress = bCompress;
{
MD5_CTX mctx;
MD5Init(&mctx);
MD5Update( &mctx, pbyFileData, uFileDataLen );
MD5Final( FileHeader.szBufferID, &mctx );
}
if( bSec && m_PackageHeader.dwSec)
{
INT n = 0;
//for( INT i=0; i<n; ++i )
//{
// n += FileHeader.szFileName[i];
//}
FileHeader.bSecIndex = 64 + n%8;
}
else
FileHeader.bSecIndex = 0;
BYTE* pFileData = pbyFileData;
INT nFileLen = (INT)uFileDataLen;
//处理文件压缩,如果文件压缩失败或压缩后文件更大,则不进行压缩
if(bCompress)
{
pFileData = (BYTE*)gpZipBuf(m_pFuncCompress, pFileData, nFileLen);
if(pFileData == NULL)
{
pFileData = pbyFileData;
nFileLen = (INT)uFileDataLen;
FileHeader.bCompress = FALSE;
}
else if(nFileLen >= (INT)uFileDataLen)
{
// delete[] pFileData;
free(pFileData);
pFileData = pbyFileData;
nFileLen = (INT)uFileDataLen;
FileHeader.bCompress = FALSE;
}
}
FileHeader.uFileLength = nFileLen;
if( FileHeader.bSecIndex >= 64 )
{
///Sec
//CBlowfish bf;
//bf.InitializeBlowfish( m_PackageHeader.secPassword[ FileHeader.bSecIndex - 64 ], 16 );
//char s[32];
//strcpy( s, SEC_KEY_PARAM, 32 );
//bf.Encrypt( SEC_KEY_PARAM
ENCRYPT( pFileData, nFileLen, m_PackageHeader.secPassword[ FileHeader.bSecIndex - 64 ], 888888, 16);
}
UINT nFileInfoOffset = m_PackageHeader.dwFileInfoOffset;
//开始写入数据
BeginSave();
if( _lseeki64(m_hFile, 0, SEEK_END) == -1)
{
return FALSE;
}
//更新文件索引表
UINT nPos = _telli64(m_hFile);
if( nFileInfoOffset > SAVE_FLAG_POSITION )
{
if( nPos > nFileInfoOffset )
{
_lseeki64(m_hFile, nFileInfoOffset, SEEK_SET );
}
}
PPACKAGE_INDEX pIndex = new PACKAGE_INDEX;
if(pIndex != NULL)
{
pIndex->byModifyFlag = GL_FILE_STATE_NORMAL;
strcpy(pIndex->szFileName, ConvertLower(lpszFileName ).c_str());
pIndex->lFilePosInPackage = _telli64(m_hFile);
m_PackFileIndex[pIndex->szFileName] = pIndex;
//m_PackFileIndex.AddTail(pIndex);
//SaveFileIndex(-1, pIndex);
}
// Write(m_hFile, &FileHeader, sizeof(FileHeader));
WritePackageFileHeader( FileHeader );
BOOL bSuccess = Write(m_hFile, pFileData, nFileLen);
//加入附加信息
if(pbyAppendInfoData != NULL && uAppendInfoDataLen > 0)
{
bSuccess = Write(m_hFile, pbyAppendInfoData, uAppendInfoDataLen);
}
nPos += FileHeader.uAppendInfoLength + FileHeader.uFileLength + sizeof(FileHeader);
_chsize_s(m_hFile, _telli64(m_hFile));
EndSave();
if(FileHeader.bCompress)
{
// delete[] pFileData;
free(pFileData);
}
return bSuccess;
}
//-----------------------------------------------------------------------------------
// 从包中删除一个文件
// 参数:
// lpszFileName 文件名,不包含路径
// 返回值:
// 删除成功返回TRUE,文件不存在或删除失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::DelFile(LPCTSTR lpszFileName, INT nDelMothed)
{
if(m_bReadOpen)
{
return FALSE;
}
if(nDelMothed <= GL_MOTHED_NONE || nDelMothed > GL_MOTHED_MARK_DEL)
{
return FALSE;
}
//检查文件是否已经存在
FileIndexList::iterator it = m_PackFileIndex.find(lpszFileName);
if ( it != m_PackFileIndex.end() )
{
if( it->second->byModifyFlag != GL_FILE_STATE_MARK_DEL )
{
PACKAGE_FILE_INFO info;
GetFileInfo(it, info);
m_PackageHeader.dwDelNumberInBytes += info.uFileLength;
m_PackageHeader.dwDelNumberInBytes += info.uAppendInfoLength;
BeginSave();
it->second->byModifyFlag = GL_MOTHED_MARK_DEL;
Write(m_hFile, &it->second->byModifyFlag, sizeof(BYTE), it->second->lFilePosInPackage);
EndSave();
///删除文件保存文件头
SavePackageHeader(m_hFile);
return TRUE;
}
}
return FALSE;
//BOOL bRet = FALSE;
//PPACKAGE_INDEX pIndex = NULL;
//POSITION pos = m_PackFileIndex.GetHeadPosition();
//POSITION DelPos = pos;
//LONG lIndexPos = 0;
//while( pos != NULL)
//{
// pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
// if(pIndex == NULL)
// {
// return FALSE;
// }
// if(pIndex->byModifyFlag != GL_FILE_STATE_MARK_DEL)
// {
// //文件已经存在
// if(StrCmpI(pIndex->szFileName,lpszFileName) == 0)
// {
// BeginSave();
// pIndex->byModifyFlag = GL_MOTHED_MARK_DEL;
// Write(m_hFile, &pIndex->byModifyFlag, sizeof(BYTE), pIndex->lFilePosInPackage);
//
// //不支持文件索引功能
// //SaveFileIndex(m_hIndexFile, pIndex);
// EndSave();
// bRet = TRUE;return TRUE;
// }
// }
// lIndexPos += sizeof(PACKAGE_INDEX);
//}
//return bRet;
}
//-----------------------------------------------------------------------------------
// 复制内存对像
// 参数:
// pBuf 待复制的数据
// uBufLen 数据长度
// 返回值:
// 成功返回数据的复本,失败返回NULL
//-----------------------------------------------------------------------------------
PVOID CPackageFile::CopyData(PVOID pBuf, UINT uBufLen)
{
BYTE* pCopy = (BYTE *)malloc(uBufLen);///new BYTE[uBufLen];
if(pCopy != NULL)
{
memcpy(pCopy, pBuf, uBufLen);
}
return pCopy;
}
//-----------------------------------------------------------------------------------
// 从包中读一个文件到缓冲区
// 参数:
// lpszFileName 文件名,不包含路径
// pbyFileData[out] 返回文件内存
// puFileLen[out] 返回文件长度
// pbyAppendInfoData 返回文件附加信息,如果NULL则不读取文件附回信息
// puAppendInfoDataLen 返回文件附加信息长度,如果为NULL则不读取文件附回信息
// 返回值:
// 成功返回TRUE,失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::GetFile(LPCTSTR lpszFileName, BYTE** pbyFileData, UINT* puFileLen, BYTE** pbyAppendInfoData, UINT* puAppendInfoDataLen)
{
if(pbyFileData == NULL || lpszFileName == NULL || puFileLen == NULL)
{
return FALSE;
}
char strFileName[MAX_PATH];
strcpy(strFileName,lpszFileName);
FileIndexList::const_iterator it =m_PackFileIndex.find(strlwr(strFileName));
if ( it == m_PackFileIndex.end() )
{
return FALSE;
}
PPACKAGE_INDEX pIndex = it->second;
//PPACKAGE_INDEX pIndex = NULL;
//POSITION pos = m_PackFileIndex.GetHeadPosition();
//BOOL bFind = FALSE;
//while(pos != NULL)
//{
// pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
// if(pIndex->byModifyFlag == GL_FILE_STATE_NORMAL)
// {
// if(StrCmpI(pIndex->szFileName,lpszFileName) == 0)
// {
// bFind = TRUE;
// break;
// }
// }
//}
//if(!bFind)
//{
// return FALSE;
//}
//读文件
UINT uOffset = pIndex->lFilePosInPackage;
PACKAGE_FILE_HEADER FileHeader;
int sizeofFH = sizeof(PACKAGE_FILE_HEADER);
if( _lseeki64(m_hFile, uOffset, SEEK_SET) == -1)
{
return FALSE;
}
if( sizeof(FileHeader) != _read(m_hFile, &FileHeader, sizeof(FileHeader)))
{
return FALSE;
}
UINT uFileLen = FileHeader.uFileLength;
UINT uDataLen = FileHeader.uAppendInfoLength;
BYTE* pSrcData = NULL;
pSrcData = Read(m_hFile, uFileLen);
if(pSrcData == NULL)
{
return FALSE;
}
if(FileHeader.bCompress)
{
int nDataLen = uFileLen;
*pbyFileData = (BYTE*)gpUnzipBuf(m_pFuncUnCompress,pSrcData,nDataLen);
if(*pbyFileData == NULL)
{
// delete[] pSrcData;
free(pSrcData);
return FALSE;
}
uFileLen = nDataLen;
// delete[] pSrcData;
free(pSrcData);
}
else
{
*pbyFileData = pSrcData;
}
int offPw = offsetof(PACKAGE_HEADER, secPassword);
if( FileHeader.bSecIndex >= 64 && FileHeader.bSecLen)
{
ENCRYPT( *pbyFileData, FileHeader.uFileLength, m_PackageHeader.secPassword[FileHeader.bSecIndex-64], 888888, 16);
}
*puFileLen = uFileLen;
//读附加信息
if(pbyAppendInfoData != NULL && puAppendInfoDataLen != NULL)
{
if(uDataLen > 0)
{
*pbyAppendInfoData = Read(m_hFile, uDataLen);
*puAppendInfoDataLen = uDataLen;
}
else
{
*pbyAppendInfoData = NULL;
*puAppendInfoDataLen = 0;
}
}
return TRUE;
}
//-----------------------------------------------------------------------------------
// 删除包中标记删除的文件,由DelFile 指定 GL_MOTHED_MARK_DEL 产生
// 参数:
//
//返回值:
//
//-----------------------------------------------------------------------------------
void CPackageFile::ClearMarkFile()
{
if(m_bReadOpen)return;
PPACKAGE_INDEX pIndex = NULL;
for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
{
if( it->second->byModifyFlag == GL_FILE_STATE_MARK_DEL)
{
pIndex = it->second;
break;
}
}
if ( NULL == pIndex )
return;
//BOOL bFind = FALSE;
//PPACKAGE_INDEX pIndex = NULL;
//POSITION pos = m_PackFileIndex.GetHeadPosition();
//while(pos != NULL)
//{
// pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
// if( pIndex->byModifyFlag == GL_FILE_STATE_MARK_DEL)
// {
// bFind = TRUE;
// break;
// }
//}
//if(!bFind)
//{
// return;
//}
//保存文件内容
TCHAR szBackFile[MAX_PATH];
TCHAR szPathName[MAX_PATH];
//TCHAR szIndexFile[MAX_PATH];
StrCpy(szPathName, m_szPathName);
//ZeroMemory(szIndexFile, sizeof(szIndexFile));
ZeroMemory(szBackFile, sizeof(szBackFile));
//GetIndexFileName(m_szPathName, szIndexFile);
GetBackupFileName(m_szPathName, szBackFile);
if(!Save(szBackFile))
{
return;
}
Close();
//DeleteFile(szIndexFile);
if(DeleteFile(szPathName))
{
__rename(szBackFile, szPathName);
}
Open(szPathName, GL_FILE_OPEN_WRITE);
}
void CPackageFile::RepareContent()
{
if(m_bReadOpen)return;
PPACKAGE_INDEX pIndex = NULL;
PACKAGE_FILE_INFO info;
DWORD dEndPosition = 0;
for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
{
if( it->second->byModifyFlag == GL_FILE_STATE_MARK_DEL)
{
pIndex = it->second;
break;
}
if( GetFileInfo( it, info ) )
{
DWORD dFileEnd = info.uFileLength + it->second->lFilePosInPackage + info.uAppendInfoLength + sizeof(PACKAGE_FILE_HEADER);
if( dFileEnd > dEndPosition )
dEndPosition = dFileEnd;
}
}
if ( (NULL == pIndex) && (dEndPosition == m_PackageHeader.dwFileInfoOffset) )
return;
//BOOL bFind = FALSE;
//PPACKAGE_INDEX pIndex = NULL;
//POSITION pos = m_PackFileIndex.GetHeadPosition();
//while(pos != NULL)
//{
// pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
// if( pIndex->byModifyFlag == GL_FILE_STATE_MARK_DEL)
// {
// bFind = TRUE;
// break;
// }
//}
//if(!bFind)
//{
// return;
//}
//保存文件内容
TCHAR szBackFile[MAX_PATH];
TCHAR szPathName[MAX_PATH];
//TCHAR szIndexFile[MAX_PATH];
StrCpy(szPathName, m_szPathName);
//ZeroMemory(szIndexFile, sizeof(szIndexFile));
ZeroMemory(szBackFile, sizeof(szBackFile));
//GetIndexFileName(m_szPathName, szIndexFile);
GetBackupFileName(m_szPathName, szBackFile);
if(!SaveUseIndex(szBackFile))
{
return;
}
Close();
//DeleteFile(szIndexFile);
if(DeleteFile(szPathName))
{
__rename(szBackFile, szPathName);
}
Open(szPathName, GL_FILE_OPEN_WRITE);
}
//-----------------------------------------------------------------------------------
// 保存内存到磁盘
// 参数:
// lpszFileName 文件名,如果为NULL使用打开时的文件名
// 返回值:
// 成功返回TRUE,失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::Save(LPCTSTR lpszFileName)
{
if(m_hFile == -1 || lpszFileName == NULL)
{
return FALSE;
}
if(StrCmpI(lpszFileName,m_szPathName) == 0)
{
return TRUE;
}
//TCHAR szIndexFile[MAX_PATH];
//ZeroMemory(szIndexFile, sizeof(szIndexFile));
//GetIndexFileName(lpszFileName, szIndexFile);
INT hFile = __open(lpszFileName, _O_BINARY | _O_RDWR, 0);
if(hFile == -1)
{
hFile = __open(lpszFileName, _O_BINARY | _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE);
}
if(hFile == -1)
{
if(hFile != -1)
{
_close(hFile);
}
return FALSE;
}
_chsize_s(hFile, 0);
DWORD dwTemp = m_PackageHeader.dwPackageVersion;
m_PackageHeader.dwPackageVersion = PACKAGE_VERSOIN;
m_PackageHeader.dbModifyTime = GetSystemTime();
UINT fInfoOffset = m_PackageHeader.dwFileInfoOffset;
UINT fInfoLength = m_PackageHeader.dwFileInfoLength;
m_PackageHeader.dwFileInfoOffset = 0;
m_PackageHeader.dwFileInfoLength = 0;
SavePackageHeader(hFile);
m_PackageHeader.dwPackageVersion = dwTemp;
m_PackageHeader.dwFileInfoOffset = fInfoOffset;
m_PackageHeader.dwFileInfoLength = fInfoLength;
BeginSave(hFile);
//保存文件内容
BYTE* pBuf = NULL;
PACKAGE_FILE_HEADER FileHeader;
UINT offset = 0;
if( m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_0)
{
offset = FILE_START_POSITION_1_0;
}
else
{
offset = FILE_START_POSITION;
}
if(_lseeki64(m_hFile, offset, SEEK_SET) == -1)
{
return FALSE;
}
/// OldFile Need Recovery, the info of file is not exist
// while(sizeof(FileHeader) == _read(m_hFile, &FileHeader, sizeof(FileHeader)))
while( ReadPackageFileHeader(FileHeader,FALSE) )
{
UINT nDataLen = FileHeader.uAppendInfoLength + FileHeader.uFileLength;
if(FileHeader.byModify == GL_FILE_STATE_MARK_DEL)
{
if( _lseeki64(m_hFile, nDataLen, SEEK_CUR) == -1)
{
return FALSE;
}
continue;
}
if(!Write(hFile, &FileHeader, sizeof(FileHeader)))
{
return FALSE;
}
//WritePackageFileHeader(FileHeader);
pBuf = Read(m_hFile, nDataLen);
if(pBuf == NULL)
{
return FALSE;
}
if(!Write(hFile, pBuf, nDataLen))
{
// delete[] pBuf;
free(pBuf);
return FALSE;
}
// delete[] pBuf;
free(pBuf);
}
EndSave(hFile);
/// can't do here, the index is changed
/// need recreate
/// SavePacketV12IndexInfo(hFile);
_close(m_hFile);
//_close(m_hIndexFile);
m_hFile = hFile;
StrCpy(m_szPathName, lpszFileName);
m_bReadOpen = FALSE;
return TRUE;
}
//-----------------------------------------------------------------------------------
// 保存内存到磁盘
// 参数:
// lpszFileName 文件名,如果为NULL使用打开时的文件名
// 返回值:
// 成功返回TRUE,失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::SaveUseIndex(LPCTSTR lpszFileName)
{
if(m_hFile == -1 || lpszFileName == NULL)
{
return FALSE;
}
if(StrCmpI(lpszFileName,m_szPathName) == 0)
{
return TRUE;
}
//TCHAR szIndexFile[MAX_PATH];
//ZeroMemory(szIndexFile, sizeof(szIndexFile));
//GetIndexFileName(lpszFileName, szIndexFile);
INT hFile = __open(lpszFileName, _O_BINARY | _O_RDWR, 0);
if(hFile == -1)
{
hFile = __open(lpszFileName, _O_BINARY | _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE);
}
if(hFile == -1)
{
if(hFile != -1)
{
_close(hFile);
}
return FALSE;
}
_chsize_s(hFile, 0);
DWORD dwTemp = m_PackageHeader.dwPackageVersion;
m_PackageHeader.dwPackageVersion = PACKAGE_VERSOIN;
m_PackageHeader.dbModifyTime = GetSystemTime();
UINT fInfoOffset = m_PackageHeader.dwFileInfoOffset;
UINT fInfoLength = m_PackageHeader.dwFileInfoLength;
m_PackageHeader.dwFileInfoOffset = 0;
m_PackageHeader.dwFileInfoLength = 0;
SavePackageHeader(hFile);
m_PackageHeader.dwPackageVersion = dwTemp;
m_PackageHeader.dwFileInfoOffset = fInfoOffset;
m_PackageHeader.dwFileInfoLength = fInfoLength;
BeginSave(hFile);
//保存文件内容
BYTE* pBuf = NULL;
PACKAGE_FILE_HEADER FileHeader;
UINT offset = 0;
if( m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_0)
{
offset = FILE_START_POSITION_1_0;
}
else
{
offset = FILE_START_POSITION;
}
if(_lseeki64(m_hFile, offset, SEEK_SET) == -1)
{
return FALSE;
}
/// OldFile Need Recovery, the info of file is not exist
// while(sizeof(FileHeader) == _read(m_hFile, &FileHeader, sizeof(FileHeader)))
// while( ReadPackageFileHeader(FileHeader,FALSE) )
for ( FileIndexList::iterator it =m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
{
// std::string sFileName = it->first;
if( it->second->byModifyFlag == GL_FILE_STATE_MARK_DEL )
{
continue;
}
if( _lseeki64(m_hFile, it->second->lFilePosInPackage, SEEK_SET) == -1)
{
return FALSE;
}
//if( sizeof(FileHeader) != _read(m_hFile, &FileHeader, sizeof(FileHeader)))
//{
// return FALSE;
//}
if( !ReadPackageFileHeader(FileHeader, FALSE) )
return FALSE;
UINT nDataLen = FileHeader.uAppendInfoLength + FileHeader.uFileLength;
if(FileHeader.byModify == GL_FILE_STATE_MARK_DEL)
{
continue;
}
if(!Write(hFile, &FileHeader, sizeof(FileHeader)))
{
return FALSE;
}
//WritePackageFileHeader(FileHeader);
pBuf = Read(m_hFile, nDataLen);
if(pBuf == NULL)
{
return FALSE;
}
if(!Write(hFile, pBuf, nDataLen))
{
// delete[] pBuf;
free(pBuf);
return FALSE;
}
// delete[] pBuf;
free(pBuf);
}
EndSave(hFile);
/// can't do here, the index is changed
/// need recreate
/// SavePacketV12IndexInfo(hFile);
_close(m_hFile);
//_close(m_hIndexFile);
m_hFile = hFile;
StrCpy(m_szPathName, lpszFileName);
m_bReadOpen = FALSE;
return TRUE;
}
ConFileIndex CPackageFile::GetFirstFilePosition()
{
return m_PackFileIndex.begin();
}
BOOL CPackageFile::IsEndFilePosition(ConFileIndex cit)
{
return (cit == m_PackFileIndex.end());
}
BOOL CPackageFile::GetFileInfo(ConFileIndex cit, PACKAGE_FILE_INFO &fInfo)
{
PPACKAGE_INDEX pIndex = cit->second;//(PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
if(pIndex->byModifyFlag == GL_FILE_STATE_MARK_DEL)
{
return FALSE;//GetNextFile(pos);
}
PACKAGE_FILE_HEADER FileHeader;
if( _lseeki64(m_hFile, pIndex->lFilePosInPackage, SEEK_SET) == -1)
{
return FALSE;
}
//if( sizeof(FileHeader) != _read(m_hFile, &FileHeader, sizeof(FileHeader)))
//{
// return FALSE;
//}
if( !ReadPackageFileHeader(FileHeader) )
return FALSE;
StrCpy(fInfo.szFileName, pIndex->szFileName);
memcpy( fInfo.szBufferID, FileHeader.szBufferID, 16 );
fInfo.bCompress = FileHeader.bCompress;
fInfo.uAppendInfoLength = FileHeader.uAppendInfoLength;
fInfo.uFileLength = FileHeader.uFileLength;
fInfo.bSecIndex = FileHeader.bSecIndex;
return TRUE;
}
//-----------------------------------------------------------------------------------
// 返回包文件起始位置,用于GetNextFile
// 参数:
//
// 返回值:
// 如果不存在文件,返回NULL
//-----------------------------------------------------------------------------------
//POSITION CPackageFile::GetFirstFilePosition()
//{
// return m_PackFileIndex.GetHeadPosition();
//}
//-----------------------------------------------------------------------------------
// 读取下一个位置文件
// 参数:
// pos 文件位置 ,用GetFirstFile GetNextFile 返回
// 返回值:
// 文件内容,些指针要由用户释放
//-----------------------------------------------------------------------------------
//PACKAGE_FILE_INFO* CPackageFile::GetNextFile(POSITION& pos)
//{
// if(pos == NULL)
// {
// return NULL;
// }
// PPACKAGE_INDEX pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
//
// if(pIndex->byModifyFlag == GL_FILE_STATE_MARK_DEL)
// {
// return GetNextFile(pos);
// }
//
//
// PACKAGE_FILE_HEADER FileHeader;
// if( _lseek(m_hFile, pIndex->lFilePosInPackage, SEEK_SET) == -1)
// {
// return NULL;
// }
// if( sizeof(FileHeader) != _read(m_hFile, &FileHeader, sizeof(FileHeader)))
// {
// return NULL;
// }
//
// PACKAGE_FILE_INFO *pFileInfo = new PACKAGE_FILE_INFO;
// if(pFileInfo == NULL)
// {
// return NULL;
// }
// StrCpy(pFileInfo->szFileName, pIndex->szFileName);
// pFileInfo->bCompress = FileHeader.bCompress;
// pFileInfo->uAppendInfoLength = FileHeader.uAppendInfoLength;
// pFileInfo->uFileLength = FileHeader.uFileLength;
// return pFileInfo;
//}
//-----------------------------------------------------------------------------------
// 并闭文件,释放内存
// 参数:
//
// 返回值:
//
//-----------------------------------------------------------------------------------
void CPackageFile::Close()
{
m_bReadOpen = TRUE;
ZeroMemory(m_szPathName, sizeof(m_szPathName));
ZeroMemory(&m_PackageHeader,sizeof(m_PackageHeader));
StrCpy(m_PackageHeader.szPackIdentifier, _T(FILE_PACKET_IDENTIFY));
StrCpy(m_PackageHeader.szPackageName,_T("User Package"));
m_PackageHeader.dwPackageVersion = PACKAGE_VERSOIN;
if(m_hFile != -1)
{
_close(m_hFile);
m_hFile = -1;
}
for ( FileIndexList::iterator it =m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
{
delete it->second;
}
m_PackFileIndex.clear();
//PPACKAGE_INDEX pDel = NULL;
//POSITION pos = m_PackFileIndex.GetHeadPosition();
//while(pos != NULL)
//{
// pDel = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
// delete pDel;
//}
//m_PackFileIndex.RemoveAll();
}
//-----------------------------------------------------------------------------------
// 写入开始更新标记
// 参数:
//
// 返回值:
//
//-----------------------------------------------------------------------------------
void CPackageFile::BeginSave(INT hFile)
{
if(hFile == -1)
{
if(m_bReadOpen)
{
return;
}
hFile = m_hFile;
}
m_bySaveFlags = 1;
///进行保存,必须重建索引
if( (hFile == m_hFile) &&
((m_PackageHeader.dwFileInfoOffset != 0)
|| (m_PackageHeader.dwFileInfoLength!=0)) )
{
DWORD dCurPos = _telli64(hFile);
_chsize_s(hFile, m_PackageHeader.dwFileInfoOffset);
UINT dNewFileSize = m_PackageHeader.dwFileInfoOffset;
m_PackageHeader.dwFileInfoOffset = 0;
m_PackageHeader.dwFileInfoLength = 0;
_lseeki64(hFile, 0, SEEK_SET );
SavePackageHeader(hFile);
if( dCurPos < dNewFileSize )
_lseeki64(hFile, dCurPos,SEEK_SET);
else
_lseeki64(hFile, dNewFileSize,SEEK_SET); ///Seek To End
}
if(_lseeki64(hFile, SAVE_FLAG_POSITION, SEEK_SET) == -1)
{
SavePackageHeader(hFile);
}
_write(hFile, &m_bySaveFlags, sizeof(BYTE));
}
//-----------------------------------------------------------------------------------
// 写放完成更新标记
// 参数:
//
// 返回值:
//
//-----------------------------------------------------------------------------------
void CPackageFile::EndSave(INT hFile)
{
if(hFile == -1)
{
if(m_bReadOpen)
{
return;
}
hFile = m_hFile;
}
m_bySaveFlags = 0;
// SavePacketV12IndexInfo();
if(_lseeki64(hFile, SAVE_FLAG_POSITION, SEEK_SET) == -1)
{
SavePackageHeader(hFile);
}
_write(hFile, &m_bySaveFlags, sizeof(BYTE));
}
//-----------------------------------------------------------------------------------
// 保存包头信息到磁盘
// 参数:
//
// 返回值:
//
//-----------------------------------------------------------------------------------
BOOL CPackageFile::SavePackageHeader(INT hFile)
{
if(hFile == -1)
{
if(m_bReadOpen)
{
return FALSE;
}
hFile = m_hFile;
}
if(!Write(hFile, &m_PackageHeader, sizeof(m_PackageHeader), 0))
{
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------------------
// 从包内容创建文件索引表
// 参数:
//
// 返回值:
//
//-----------------------------------------------------------------------------------
BOOL CPackageFile::CreateFileIndex()
{
if( _lseeki64(m_hFile, 0, SEEK_END) == -1)
{
return FALSE;
}
UINT nfilelen = _telli64(m_hFile);
ULONG offset = FILE_START_POSITION;//_1_0;
if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_0)
{
offset = FILE_START_POSITION_1_0;
}
//else if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSOIN)
//{
// offset = FILE_START_POSITION;
//}
if( _lseeki64(m_hFile, offset, SEEK_SET) == -1)
{
return FALSE;
}
if( !LoadPackageV12FileIndex() )
{
PACKAGE_FILE_HEADER FileHeader;
ULONG lFileLen = _telli64(m_hFile);
//while(sizeof(FileHeader) == _read(m_hFile, &FileHeader, sizeof(FileHeader)))
while( ReadPackageFileHeader(FileHeader) )
{
if( (int)FileHeader.uAppendInfoLength <= 0)FileHeader.uAppendInfoLength = 0;
if( (int)FileHeader.uFileLength <= 0) break;
//记录完整性检查
UINT nNextBegin = _telli64(m_hFile) + FileHeader.uFileLength + FileHeader.uAppendInfoLength;
if(nNextBegin > nfilelen)
{
//TRACE("\n文件 %s 不完整 丢弃", FileHeader.szFileName);
break;
}
PPACKAGE_INDEX pIndex = new PACKAGE_INDEX;
if(pIndex == NULL)
{
return FALSE;
}
///如果是删除的文件,不应该加载,跳过去
if( FileHeader.byModify != GL_FILE_STATE_MARK_DEL )
{
pIndex->byModifyFlag = FileHeader.byModify;
pIndex->lFilePosInPackage = lFileLen;
StrCpy(pIndex->szFileName, FileHeader.szFileName);
m_PackFileIndex[strlwr( pIndex->szFileName)] = pIndex;
}
//m_PackFileIndex.AddTail(pIndex);
//文件数据错误
if( _lseeki64(m_hFile, FileHeader.uAppendInfoLength + FileHeader.uFileLength, SEEK_CUR) == -1)
{
break;
}
lFileLen = _telli64(m_hFile);
if(lFileLen > nfilelen)
{
break;
}
}
if(!m_bReadOpen)
{
if(lFileLen < nfilelen )
{
_chsize_s(m_hFile, lFileLen);
}
}
}
return TRUE;
}
BOOL CPackageFile::LoadPackageV12FileIndex()
{
int offInit = offsetof(CPackageFile, m_PackageHeader);
if(m_PackageHeader.dwPackageVersion != PACKAGE_VERSION_1_2 )
return FALSE;
int startPos = FILE_START_POSITION;
int infoOffset = offsetof(PACKAGE_HEADER_1_2,dwFileInfoOffset);
int pvOffset = offsetof(PACKAGE_HEADER_1_2,dwPackageVersion);
if( m_PackageHeader.dwFileInfoOffset < FILE_START_POSITION
|| m_PackageHeader.dwFileInfoLength < 1)
{
return FALSE;
}
//FIXFIX: 不应该这样的 by 不说害怕
m_PackageHeader.dwFileInfoOffset += 320;
BOOL bS = TRUE;
INT hFile = m_hFile;
DWORD nFileLie = _telli64(hFile);
__int64 newpos = _lseeki64(hFile, m_PackageHeader.dwFileInfoOffset, SEEK_SET);
if( newpos == -1)
{
_lseeki64( hFile, nFileLie, SEEK_SET );
return FALSE;
}
/// 每个PackageHeader都存在一块
int sizeIdx = sizeof(PACKAGE_INDEX); // 288
int nNumHeader = m_PackageHeader.dwFileInfoLength / sizeof(PACKAGE_INDEX);
if( nNumHeader < 1 )
{
_lseeki64(hFile, nFileLie, SEEK_SET);
return FALSE;
}
for( int i=0; i<nNumHeader; ++i )
{
PACKAGE_INDEX *pIndex = new PACKAGE_INDEX;
if (_read(m_hFile, pIndex, sizeof(PACKAGE_INDEX) ) != sizeof(PACKAGE_INDEX) )
{
///需要释放也经加载的?
delete pIndex;
bS = FALSE;
break;
}
if( m_PackageHeader.btInfoSecIndex >= 64 )
{
if (pIndex->byFileNameLen)
{
ENCRYPT((BYTE *) pIndex->szFileName, pIndex->byFileNameLen, m_PackageHeader.secPassword[m_PackageHeader.btInfoSecIndex - 64 ], 888888, 16);
}
}
m_PackFileIndex[strlwr( pIndex->szFileName)] = pIndex;
}
_lseeki64(hFile, nFileLie, SEEK_SET);
if( !bS )
{
for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
{
delete it->second;
}
m_PackFileIndex.clear();
return FALSE;
}
return TRUE;
}
BOOL CPackageFile::SavePacketV12IndexInfo(INT nReInitIndexLie)
{
INT hFile = m_hFile;
if(m_PackageHeader.dwPackageVersion != PACKAGE_VERSION_1_2 )
return FALSE;
if( nReInitIndexLie > 0 )
{
m_PackageHeader.dwFileInfoOffset = 0;
m_PackageHeader.dwFileInfoLength = 0;
}
if( m_PackageHeader.dwFileInfoOffset < 1 )
{
///重新计算偏移和大小
ConFileIndex itLie = m_PackFileIndex.begin();
ConFileIndex itEnd = m_PackFileIndex.end();
PACKAGE_FILE_INFO info;
DWORD dEndPosition = 0;
INT nNumOfFileIndex=0;
for( ;itLie!=itEnd; ++itLie )
{
++nNumOfFileIndex;
if( GetFileInfo( itLie, info ) )
{
DWORD dFileEnd = info.uFileLength + itLie->second->lFilePosInPackage + info.uAppendInfoLength + sizeof(PACKAGE_FILE_HEADER);
if( dFileEnd > dEndPosition )
dEndPosition = dFileEnd;
}
}
m_PackageHeader.dwFileInfoOffset = dEndPosition;
m_PackageHeader.dwFileInfoLength = nNumOfFileIndex * sizeof(PACKAGE_INDEX);
m_PackageHeader.btInfoSecIndex = 6+64;
}
if( m_PackageHeader.dwFileInfoLength > 0 )
{
_lseeki64(hFile, m_PackageHeader.dwFileInfoOffset, SEEK_SET);
{
ConFileIndex itLie = m_PackFileIndex.begin();
ConFileIndex itEnd = m_PackFileIndex.end();
for( ;itLie!=itEnd; ++itLie )
{
PACKAGE_INDEX pIndex = *(itLie->second);
if( m_PackageHeader.btInfoSecIndex > 64 )
ENCRYPT((BYTE *) pIndex.szFileName, 260, m_PackageHeader.secPassword[m_PackageHeader.btInfoSecIndex - 64 ], 888888, 16);
if( _write( hFile, &pIndex, sizeof(pIndex) ) == -1 )
{
_chsize_s(hFile, m_PackageHeader.dwFileInfoOffset );
m_PackageHeader.dwFileInfoOffset = 0;
m_PackageHeader.dwFileInfoLength = 0;
break;
}
}
}
}
_lseeki64(hFile, 0, SEEK_SET);
SavePackageHeader(hFile);
return m_PackageHeader.dwFileInfoOffset!=0;//
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/f88/ZHLT_UPack.git
git@gitee.com:f88/ZHLT_UPack.git
f88
ZHLT_UPack
ZHLT_UPack
master

搜索帮助