client/EterPack/EterPack.h

250 lines
6.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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