250 lines
6.3 KiB
C++
250 lines
6.3 KiB
C++
#ifndef __INC_ETERPACKLIB_ETERPACK_H__
|
||
#define __INC_ETERPACKLIB_ETERPACK_H__
|
||
|
||
#include <list>
|
||
#include <boost/unordered_map.hpp>
|
||
#include <boost/shared_array.hpp>
|
||
|
||
#include "../EterBase/MappedFile.h"
|
||
|
||
#ifndef MAKEFOURCC
|
||
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||
((DWORD)(BYTE) (ch0 ) | ((DWORD)(BYTE) (ch1) << 8) | \
|
||
((DWORD)(BYTE) (ch2) << 16) | ((DWORD)(BYTE) (ch3) << 24))
|
||
#endif
|
||
|
||
|
||
//#define CHECKSUM_CHECK_MD5
|
||
|
||
#include "md5.h"
|
||
|
||
namespace eterpack
|
||
{
|
||
const DWORD c_PackCC = MAKEFOURCC('E', 'P', 'K', 'D');
|
||
const DWORD c_IndexCC = MAKEFOURCC('E', 'P', 'K', 'D');
|
||
const DWORD c_Version = 2;
|
||
// FourCC + Version + m_indexCount
|
||
const DWORD c_HeaderSize = sizeof(DWORD) + sizeof(DWORD) + sizeof(long);
|
||
};
|
||
|
||
enum EEterPackTypes
|
||
{
|
||
DBNAME_MAX_LEN = 255,
|
||
FILENAME_MAX_LEN = 160,
|
||
FREE_INDEX_BLOCK_SIZE = 32768,
|
||
FREE_INDEX_MAX_SIZE = 512,
|
||
DATA_BLOCK_SIZE = 256,
|
||
|
||
COMPRESSED_TYPE_NONE = 0,
|
||
COMPRESSED_TYPE_COMPRESS = 1,
|
||
COMPRESSED_TYPE_SECURITY = 2,
|
||
COMPRESSED_TYPE_PANAMA = 3,
|
||
COMPRESSED_TYPE_HYBRIDCRYPT = 4,
|
||
COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB = 5,
|
||
COMPRESSED_TYPE_COUNT = 6,
|
||
};
|
||
|
||
#pragma pack(push, 4)
|
||
typedef struct SEterPackIndex
|
||
{
|
||
long id;
|
||
char filename[FILENAME_MAX_LEN + 1];
|
||
DWORD filename_crc;
|
||
long real_data_size;
|
||
long data_size;
|
||
#ifdef CHECKSUM_CHECK_MD5
|
||
BYTE MD5Digest[16];
|
||
#else
|
||
DWORD data_crc;
|
||
#endif
|
||
long data_position;
|
||
char compressed_type;
|
||
} TEterPackIndex;
|
||
#pragma pack(pop)
|
||
|
||
typedef boost::unordered_map<DWORD, TEterPackIndex *> TDataPositionMap;
|
||
typedef std::list<TEterPackIndex *> TFreeIndexList;
|
||
|
||
|
||
class CEterPack;
|
||
|
||
class CEterFileDict
|
||
{
|
||
public:
|
||
struct Item
|
||
{
|
||
Item() : pkPack(NULL), pkInfo(NULL) {}
|
||
|
||
CEterPack* pkPack;
|
||
TEterPackIndex* pkInfo;
|
||
};
|
||
|
||
enum
|
||
{
|
||
BUCKET_SIZE = 16,
|
||
};
|
||
|
||
typedef boost::unordered_multimap<DWORD, Item> TDict;
|
||
|
||
public:
|
||
void InsertItem(CEterPack* pkPack, TEterPackIndex* pkInfo);
|
||
void UpdateItem(CEterPack* pkPack, TEterPackIndex* pkInfo);
|
||
|
||
Item* GetItem(DWORD dwFileNameHash, const char* c_pszFileName);
|
||
|
||
const TDict& GetDict() const
|
||
{
|
||
return m_dict;
|
||
}
|
||
|
||
private:
|
||
TDict m_dict;
|
||
};
|
||
|
||
class EterPackPolicy_CSHybridCrypt;
|
||
|
||
class CEterPack
|
||
{
|
||
public:
|
||
CEterPack();
|
||
virtual ~CEterPack();
|
||
|
||
void Destroy();
|
||
bool Create(CEterFileDict& rkFileDict, const char * dbname, const char * pathName, bool bReadOnly = true, const BYTE* iv = NULL);
|
||
bool DecryptIV(DWORD dwPanamaKey);
|
||
|
||
const std::string& GetPathName();
|
||
const char * GetDBName();
|
||
|
||
//THEMIDA
|
||
bool Get(CMappedFile & mappedFile, const char * filename, LPCVOID * data);
|
||
//THEMIDA
|
||
bool Get2(CMappedFile & mappedFile, const char * filename, TEterPackIndex* index, LPCVOID * data);
|
||
|
||
|
||
//THEMIDA
|
||
bool Put(const char * filename, const char * sourceFilename, BYTE packType, const std::string& strRelateMapName);
|
||
//THEMIDA
|
||
bool Put(const char * filename, LPCVOID data, long len, BYTE packType);
|
||
|
||
bool Delete(const char * filename);
|
||
|
||
bool Extract();
|
||
|
||
long GetFragmentSize();
|
||
|
||
bool IsExist(const char * filename);
|
||
|
||
TDataPositionMap & GetIndexMap();
|
||
|
||
bool EncryptIndexFile();
|
||
bool DecryptIndexFile();
|
||
|
||
DWORD DeleteUnreferencedData(); // <20><EFBFBD><EEB0B3> <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
|
||
bool GetNames(std::vector<std::string>* retNames);
|
||
|
||
EterPackPolicy_CSHybridCrypt* GetPackPolicy_HybridCrypt() const;
|
||
|
||
private:
|
||
bool __BuildIndex(CEterFileDict& rkFileDict, bool bOverwirte=false);
|
||
|
||
bool CreateIndexFile();
|
||
TEterPackIndex * FindIndex(const char * filename);
|
||
long GetNewIndexPosition(CFileBase& file);
|
||
TEterPackIndex * NewIndex(CFileBase& file, const char * filename, long size);
|
||
void WriteIndex(CFileBase& file, TEterPackIndex * index);
|
||
int GetFreeBlockIndex(long size);
|
||
void PushFreeIndex(TEterPackIndex * index);
|
||
|
||
bool CreateDataFile();
|
||
long GetNewDataPosition(CFileBase& file);
|
||
bool ReadData(CFileBase& file, TEterPackIndex * index, LPVOID data, long maxsize);
|
||
bool WriteData(CFileBase& file, TEterPackIndex * index, LPCVOID data);
|
||
bool WriteNewData(CFileBase& file, TEterPackIndex * index, LPCVOID data);
|
||
|
||
bool Delete(TEterPackIndex * pIndex);
|
||
|
||
protected:
|
||
CMappedFile m_file;
|
||
|
||
char* m_file_data;
|
||
unsigned m_file_size;
|
||
|
||
long m_indexCount;
|
||
bool m_bEncrypted;
|
||
|
||
char m_dbName[DBNAME_MAX_LEN+1];
|
||
char m_indexFileName[MAX_PATH+1];
|
||
TEterPackIndex * m_indexData;
|
||
long m_FragmentSize;
|
||
bool m_bReadOnly;
|
||
bool m_bDecrypedIV;
|
||
|
||
boost::unordered_map<DWORD, DWORD> m_map_indexRefCount;
|
||
TDataPositionMap m_DataPositionMap;
|
||
TFreeIndexList m_FreeIndexList[FREE_INDEX_MAX_SIZE + 1]; // MAX <20><> <20>\<EFBFBD><EFBCBC> <20>ϹǷ<CFB9> + 1 ũ<>⸸ŭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
|
||
std::string m_stDataFileName;
|
||
std::string m_stPathName;
|
||
|
||
|
||
EterPackPolicy_CSHybridCrypt* m_pCSHybridCryptPolicy;
|
||
|
||
private:
|
||
void __CreateFileNameKey_Panama(const char * filename, BYTE * key, unsigned int keySize);
|
||
bool __Decrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj);
|
||
bool __Encrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj);
|
||
std::string m_stIV_Panama;
|
||
|
||
//private:
|
||
// bool m_bIsDataLoaded;
|
||
// // <20>׳<EFBFBD> time_t<5F><74> <20><><EFBFBD><EFBFBD>, 32bit time_t<5F><74> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>ҽ<EFBFBD><D2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
|
||
// // CEterPack<63><6B> size<7A><65> <20><><EFBFBD><EFBFBD> size - 4<><34> <20>ν<EFBFBD><CEBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DFBB><EFBFBD> <20><> <20>ִ<EFBFBD>.
|
||
// __time64_t m_tLastAccessTime;
|
||
//public:
|
||
// __time64_t GetLastAccessTime() { return m_tLastAccessTime; }
|
||
// void UpdateLastAccessTime();
|
||
// void ClearDataMemoryMap();
|
||
|
||
#ifdef CHECKSUM_CHECK_MD5
|
||
void GenerateMD5Hash( BYTE* pData, int nLength, IN OUT MD5_CTX& context );
|
||
#endif
|
||
};
|
||
|
||
class CMakePackLog
|
||
{
|
||
public:
|
||
static CMakePackLog& GetSingleton();
|
||
|
||
public:
|
||
CMakePackLog();
|
||
~CMakePackLog();
|
||
|
||
void SetFileName(const char* c_szFileName);
|
||
|
||
void Writef(const char* c_szFormat, ...);
|
||
void Writenf(const char* c_szFormat, ...);
|
||
void Write(const char* c_szBuf);
|
||
|
||
void WriteErrorf(const char* c_szFormat, ...);
|
||
void WriteErrornf(const char* c_szFormat, ...);
|
||
void WriteError(const char* c_szBuf);
|
||
|
||
void FlushError();
|
||
|
||
private:
|
||
void __Write(const char* c_szBuf, int nBufLen);
|
||
void __WriteError(const char* c_szBuf, int nBufLen);
|
||
bool __IsLogMode();
|
||
|
||
private:
|
||
FILE* m_fp;
|
||
FILE* m_fp_err;
|
||
|
||
std::string m_stFileName;
|
||
std::string m_stErrorFileName;
|
||
};
|
||
|
||
#endif
|