forked from Tr0n/client
Removed Panama & HybridCrypt, added experimental Folder and Zip archive providers
This commit is contained in:
@ -4,38 +4,16 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "EterPackManager.h"
|
||||
#include "EterPackPolicy_CSHybridCrypt.h"
|
||||
|
||||
#include "../eterBase/Debug.h"
|
||||
#include "../eterBase/CRC32.h"
|
||||
|
||||
#include "Folder.h"
|
||||
#include "ZIP.h"
|
||||
|
||||
#define PATH_ABSOLUTE_YMIRWORK1 "d:/ymir work/"
|
||||
#define PATH_ABSOLUTE_YMIRWORK2 "d:\\ymir work\\"
|
||||
|
||||
CEterPack* CEterPackManager::FindPack(const char* c_szPathName)
|
||||
{
|
||||
std::string strFileName;
|
||||
|
||||
if (0 == ConvertFileName(c_szPathName, strFileName))
|
||||
{
|
||||
return &m_RootPack;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (TEterPackMap::iterator itor = m_DirPackMap.begin(); itor != m_DirPackMap.end(); ++itor)
|
||||
{
|
||||
const std::string & c_rstrName = itor->first;
|
||||
CEterPack * pEterPack = itor->second;
|
||||
|
||||
if (CompareName(c_rstrName.c_str(), c_rstrName.length(), strFileName.c_str()))
|
||||
{
|
||||
return pEterPack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CEterPackManager::SetCacheMode()
|
||||
{
|
||||
@ -49,25 +27,18 @@ void CEterPackManager::SetRelativePathMode()
|
||||
|
||||
|
||||
// StringPath std::string <20><><EFBFBD><EFBFBD>
|
||||
int CEterPackManager::ConvertFileName(const char * c_szFileName, std::string & rstrFileName)
|
||||
std::string CEterPackManager::ConvertFileName(std::string fileName)
|
||||
{
|
||||
rstrFileName = c_szFileName;
|
||||
stl_lowers(rstrFileName);
|
||||
std::string convertedFileName = fileName;
|
||||
stl_lowers(convertedFileName);
|
||||
|
||||
int iCount = 0;
|
||||
|
||||
for (DWORD i = 0; i < rstrFileName.length(); ++i)
|
||||
for (DWORD i = 0; i < convertedFileName.length(); i++)
|
||||
{
|
||||
if (rstrFileName[i] == '/')
|
||||
++iCount;
|
||||
else if (rstrFileName[i] == '\\')
|
||||
{
|
||||
rstrFileName[i] = '/';
|
||||
++iCount;
|
||||
}
|
||||
if (convertedFileName[i] == '\\')
|
||||
convertedFileName[i] = '/';
|
||||
}
|
||||
|
||||
return iCount;
|
||||
return convertedFileName;
|
||||
}
|
||||
|
||||
bool CEterPackManager::CompareName(const char * c_szDirectoryName, DWORD /*dwLength*/, const char * c_szFileName)
|
||||
@ -92,11 +63,7 @@ void CEterPackManager::LoadStaticCache(const char* c_szFileName)
|
||||
if (!m_isCacheMode)
|
||||
return;
|
||||
|
||||
std::string strFileName;
|
||||
if (0 == ConvertFileName(c_szFileName, strFileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::string strFileName = ConvertFileName(c_szFileName);
|
||||
|
||||
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
|
||||
|
||||
@ -192,58 +159,39 @@ bool CEterPackManager::GetFromPack(CMappedFile & rMappedFile, const char * c_szF
|
||||
{
|
||||
FinderLock lock(m_csFinder);
|
||||
|
||||
static std::string strFileName;
|
||||
|
||||
if (0 == ConvertFileName(c_szFileName, strFileName))
|
||||
std::string strFileName = ConvertFileName(c_szFileName);
|
||||
|
||||
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
|
||||
SCache* pkCache = __FindCache(dwFileNameHash);
|
||||
|
||||
if (pkCache)
|
||||
{
|
||||
return m_RootPack.Get(rMappedFile, strFileName.c_str(), pData);
|
||||
rMappedFile.Link(pkCache->m_dwBufSize, pkCache->m_abBufData);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
|
||||
SCache* pkCache = __FindCache(dwFileNameHash);
|
||||
|
||||
if (pkCache)
|
||||
{
|
||||
rMappedFile.Link(pkCache->m_dwBufSize, pkCache->m_abBufData);
|
||||
return true;
|
||||
}
|
||||
auto pkFileItem = m_FileDict.find(dwFileNameHash);
|
||||
|
||||
CEterFileDict::Item* pkFileItem = m_FileDict.GetItem(dwFileNameHash, strFileName.c_str());
|
||||
|
||||
if (pkFileItem)
|
||||
if (pkFileItem->pkPack)
|
||||
{
|
||||
bool r = pkFileItem->pkPack->Get2(rMappedFile, strFileName.c_str(), pkFileItem->pkInfo, pData);
|
||||
//pkFileItem->pkPack->ClearDataMemoryMap();
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if (pkFileItem == m_FileDict.end()) {
|
||||
#ifdef _DEBUG
|
||||
TraceError("CANNOT_FIND_PACK_FILE [%s]", strFileName.c_str());
|
||||
TraceError("CANNOT_FIND_PACK_FILE [%s]", strFileName.c_str());
|
||||
#endif
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto data = std::make_shared<std::vector<char>>();
|
||||
bool r = pkFileItem->second->getFile(strFileName, data);
|
||||
|
||||
// Keep the file loaded by always forcing a reference in the smart pointer (temporary hack)
|
||||
keepDataReferencedArray.push_back(data);
|
||||
|
||||
rMappedFile.Link(data->size(), data->data());
|
||||
*pData = (LPCVOID *) data->data();
|
||||
return r;
|
||||
}
|
||||
|
||||
const time_t g_tCachingInterval = 10; // 10<31><30>
|
||||
void CEterPackManager::ArrangeMemoryMappedPack()
|
||||
{
|
||||
//time_t curTime = time(NULL);
|
||||
//CEterFileDict::TDict dict = m_FileDict.GetDict();
|
||||
//for (CEterFileDict::TDict::iterator it = dict.begin(); it != dict.end(); ++it)
|
||||
//{
|
||||
// CEterFileDict::Item &rFileItem = it->second;
|
||||
// CEterPack* pkPack = rFileItem.pkPack;
|
||||
// if (pkPack)
|
||||
// {
|
||||
// if (curTime - pkPack->GetLastAccessTime() > g_tCachingInterval)
|
||||
// {
|
||||
// pkPack->ClearDataMemoryMap();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
bool CEterPackManager::GetFromFile(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData)
|
||||
{
|
||||
@ -273,24 +221,16 @@ bool CEterPackManager::GetFromFile(CMappedFile & rMappedFile, const char * c_szF
|
||||
|
||||
bool CEterPackManager::isExistInPack(const char * c_szFileName)
|
||||
{
|
||||
std::string strFileName;
|
||||
std::string strFileName = ConvertFileName(c_szFileName);
|
||||
|
||||
if (0 == ConvertFileName(c_szFileName, strFileName))
|
||||
{
|
||||
return m_RootPack.IsExist(strFileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
|
||||
CEterFileDict::Item* pkFileItem = m_FileDict.GetItem(dwFileNameHash, strFileName.c_str());
|
||||
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
|
||||
auto pkFileItem = m_FileDict.find(dwFileNameHash);
|
||||
|
||||
if (pkFileItem)
|
||||
if (pkFileItem->pkPack)
|
||||
return pkFileItem->pkPack->IsExist(strFileName.c_str());
|
||||
}
|
||||
if (pkFileItem == m_FileDict.end())
|
||||
return false;
|
||||
|
||||
// NOTE : <20><>ġ <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD> false - [levites]
|
||||
return false;
|
||||
if (pkFileItem->second)
|
||||
return pkFileItem->second->fileExists(strFileName.c_str());
|
||||
}
|
||||
|
||||
bool CEterPackManager::isExist(const char * c_szFileName)
|
||||
@ -317,82 +257,38 @@ bool CEterPackManager::isExist(const char * c_szFileName)
|
||||
}
|
||||
|
||||
|
||||
void CEterPackManager::RegisterRootPack(const char * c_szName)
|
||||
{
|
||||
if (!m_RootPack.Create(m_FileDict, c_szName, ""))
|
||||
{
|
||||
TraceError("%s: Pack file does not exist", c_szName);
|
||||
}
|
||||
}
|
||||
|
||||
const char * CEterPackManager::GetRootPackFileName()
|
||||
{
|
||||
return m_RootPack.GetDBName();
|
||||
}
|
||||
|
||||
bool CEterPackManager::DecryptPackIV(DWORD dwPanamaKey)
|
||||
{
|
||||
TEterPackMap::iterator itor = m_PackMap.begin();
|
||||
while (itor != m_PackMap.end())
|
||||
{
|
||||
itor->second->DecryptIV(dwPanamaKey);
|
||||
itor++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CEterPackManager::RegisterPackWhenPackMaking(const char * c_szName, const char * c_szDirectory, CEterPack* pPack)
|
||||
{
|
||||
m_PackMap.insert(TEterPackMap::value_type(c_szName, pPack));
|
||||
m_PackList.push_front(pPack);
|
||||
|
||||
m_DirPackMap.insert(TEterPackMap::value_type(c_szDirectory, pPack));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CEterPackManager::RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV)
|
||||
{
|
||||
CEterPack * pEterPack = NULL;
|
||||
{
|
||||
TEterPackMap::iterator itor = m_PackMap.find(c_szName);
|
||||
auto it = m_PackMap.find(c_szName);
|
||||
|
||||
if (m_PackMap.end() == itor)
|
||||
{
|
||||
bool bReadOnly = true;
|
||||
if (it != m_PackMap.end())
|
||||
return true;
|
||||
|
||||
pEterPack = new CEterPack;
|
||||
if (pEterPack->Create(m_FileDict, c_szName, c_szDirectory, bReadOnly, c_pbIV))
|
||||
{
|
||||
m_PackMap.insert(TEterPackMap::value_type(c_szName, pEterPack));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
Tracef("The eterpack doesn't exist [%s]\n", c_szName);
|
||||
#endif
|
||||
delete pEterPack;
|
||||
pEterPack = NULL;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
bool bReadOnly = true;
|
||||
|
||||
std::shared_ptr<FileProvider> pack;
|
||||
|
||||
// TODO: allow configurable containers
|
||||
|
||||
//pack = std::make_shared<Folder>(c_szName);
|
||||
pack = std::make_shared<ZIP>(std::string(c_szName) + ".zip");
|
||||
|
||||
auto packFiles = pack->listFiles();
|
||||
|
||||
for (auto const& fileName : packFiles) {
|
||||
DWORD dwFileNameHash = GetCRC32(fileName.c_str(), fileName.length());
|
||||
m_FileDict.insert({ dwFileNameHash, pack });
|
||||
}
|
||||
else
|
||||
{
|
||||
pEterPack = itor->second;
|
||||
}
|
||||
|
||||
m_PackMap.insert(TEterPackMap::value_type(c_szName, pack));
|
||||
}
|
||||
|
||||
if (c_szDirectory && c_szDirectory[0] != '*')
|
||||
catch (...)
|
||||
{
|
||||
TEterPackMap::iterator itor = m_DirPackMap.find(c_szDirectory);
|
||||
if (m_DirPackMap.end() == itor)
|
||||
{
|
||||
m_PackList.push_front(pEterPack);
|
||||
m_DirPackMap.insert(TEterPackMap::value_type(c_szDirectory, pEterPack));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
#ifdef _DEBUG
|
||||
Tracef("The eterpack doesn't exist [%s]\n", c_szName);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void CEterPackManager::SetSearchMode(bool bPackFirst)
|
||||
@ -414,200 +310,5 @@ CEterPackManager::~CEterPackManager()
|
||||
{
|
||||
__ClearCacheMap();
|
||||
|
||||
TEterPackMap::iterator i = m_PackMap.begin();
|
||||
TEterPackMap::iterator e = m_PackMap.end();
|
||||
while (i != e)
|
||||
{
|
||||
delete i->second;
|
||||
i++;
|
||||
}
|
||||
DeleteCriticalSection(&m_csFinder);
|
||||
}
|
||||
|
||||
void CEterPackManager::RetrieveHybridCryptPackKeys(const BYTE *pStream)
|
||||
{
|
||||
////dump file format
|
||||
//total packagecnt (4byte)
|
||||
// for packagecntpackage
|
||||
// db name hash ( stl.h stringhash )
|
||||
// extension cnt( 4byte)
|
||||
// for extension cnt
|
||||
// ext hash ( stl.h stringhash )
|
||||
// key-16byte
|
||||
// iv-16byte
|
||||
int iMemOffset = 0;
|
||||
|
||||
int iPackageCnt;
|
||||
DWORD dwPackageNameHash;
|
||||
|
||||
memcpy( &iPackageCnt, pStream + iMemOffset, sizeof(int) );
|
||||
iMemOffset += sizeof(iPackageCnt);
|
||||
|
||||
for( int i = 0; i < iPackageCnt; ++i )
|
||||
{
|
||||
int iRecvedCryptKeySize = 0;
|
||||
memcpy( &iRecvedCryptKeySize, pStream + iMemOffset, sizeof(iRecvedCryptKeySize) );
|
||||
iRecvedCryptKeySize -= sizeof(dwPackageNameHash); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> key stream<61><6D><EFBFBD><EFBFBD> filename hash<73><68> <20><><EFBFBD>ԵǾ<D4B5> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>, hash <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ŭ <20><><EFBFBD><EFBFBD>.
|
||||
iMemOffset += sizeof(iRecvedCryptKeySize);
|
||||
|
||||
memcpy( &dwPackageNameHash, pStream + iMemOffset, sizeof(dwPackageNameHash) );
|
||||
iMemOffset += sizeof(dwPackageNameHash);
|
||||
|
||||
TEterPackMap::const_iterator cit;
|
||||
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
|
||||
{
|
||||
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
|
||||
if( dwPackageNameHash == stringhash().GetHash(noPathName) )
|
||||
{
|
||||
EterPackPolicy_CSHybridCrypt* pCryptPolicy = cit->second->GetPackPolicy_HybridCrypt();
|
||||
int iHavedCryptKeySize = pCryptPolicy->ReadCryptKeyInfoFromStream( pStream + iMemOffset );
|
||||
if (iRecvedCryptKeySize != iHavedCryptKeySize)
|
||||
{
|
||||
TraceError("CEterPackManager::RetrieveHybridCryptPackKeys cryptokey length of file(%s) is not matched. received(%d) != haved(%d)", noPathName.c_str(), iRecvedCryptKeySize, iHavedCryptKeySize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
iMemOffset += iRecvedCryptKeySize;
|
||||
}
|
||||
}
|
||||
|
||||
void CEterPackManager::RetrieveHybridCryptPackSDB( const BYTE* pStream )
|
||||
{
|
||||
//cnt
|
||||
//for cnt
|
||||
//DWORD dwPackageIdentifier;
|
||||
//DWORD dwFileIdentifier;
|
||||
//std::vector<BYTE> vecSDBStream;
|
||||
int iReadOffset = 0;
|
||||
int iSDBInfoCount = 0;
|
||||
|
||||
memcpy( &iSDBInfoCount, pStream+iReadOffset, sizeof(int) );
|
||||
iReadOffset += sizeof(int);
|
||||
|
||||
for( int i = 0; i < iSDBInfoCount; ++i )
|
||||
{
|
||||
DWORD dwPackgeIdentifier;
|
||||
memcpy( &dwPackgeIdentifier, pStream+iReadOffset, sizeof(DWORD) );
|
||||
iReadOffset += sizeof(DWORD);
|
||||
|
||||
TEterPackMap::const_iterator cit;
|
||||
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
|
||||
{
|
||||
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
|
||||
if( dwPackgeIdentifier == stringhash().GetHash(noPathName) )
|
||||
{
|
||||
EterPackPolicy_CSHybridCrypt* pCryptPolicy = cit->second->GetPackPolicy_HybridCrypt();
|
||||
iReadOffset += pCryptPolicy->ReadSupplementatyDataBlockFromStream( pStream+iReadOffset );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CEterPackManager::WriteHybridCryptPackInfo(const char* pFileName)
|
||||
{
|
||||
//NOTE : this file format contains a little bit of redundant data.
|
||||
//however it`s better for seperating cryptkey & supplementary data block.
|
||||
|
||||
//dump file format
|
||||
|
||||
//SDB data offset(4)
|
||||
|
||||
// about cryptkey
|
||||
//total packagecnt (4byte)
|
||||
// for packagecnt
|
||||
// db name hash 4byte( stl.h stringhash )
|
||||
// extension cnt( 4byte)
|
||||
// for extension cnt
|
||||
// ext hash ( stl.h stringhash )
|
||||
// key-16byte
|
||||
// iv-16byte
|
||||
|
||||
//about SDB data
|
||||
//total packagecnt (4byte)
|
||||
// for packagecnt
|
||||
// db name hash 4byte( stl.h stringhash ) +child node size(4byte)
|
||||
// sdb file cnt( 4byte )
|
||||
// for sdb file cnt
|
||||
// filename hash ( stl.h stringhash )
|
||||
// related map name size(4), relate map name
|
||||
// sdb block size( 1byte )
|
||||
// sdb blocks
|
||||
|
||||
CFileBase keyFile;
|
||||
|
||||
if( !keyFile.Create( pFileName, CFileBase::FILEMODE_WRITE) )
|
||||
{
|
||||
//TODO : write log
|
||||
return;
|
||||
}
|
||||
|
||||
int iKeyPackageCount = 0;
|
||||
|
||||
//write later ( SDB Offset & PackageCnt for Key )
|
||||
keyFile.SeekCur(2*sizeof(int));
|
||||
|
||||
TEterPackMap::const_iterator cit;
|
||||
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
|
||||
{
|
||||
EterPackPolicy_CSHybridCrypt* pPolicy = cit->second->GetPackPolicy_HybridCrypt();
|
||||
if( !pPolicy || !pPolicy->IsContainingCryptKey() )
|
||||
continue;
|
||||
|
||||
iKeyPackageCount++;
|
||||
|
||||
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
|
||||
|
||||
DWORD dwPackNamehash = stringhash().GetHash(noPathName);
|
||||
|
||||
CMakePackLog::GetSingleton().Writef("CEterPackManager::WriteHybridCryptPackInfo PackName : %s, Hash : %x", noPathName.c_str(), dwPackNamehash);
|
||||
keyFile.Write( &dwPackNamehash, sizeof(DWORD) );
|
||||
|
||||
pPolicy->WriteCryptKeyToFile( keyFile );
|
||||
}
|
||||
|
||||
//Write SDB Data
|
||||
int iSDBDataOffset = keyFile.GetPosition();
|
||||
int iSDBPackageCnt = 0;
|
||||
|
||||
//Write SDB PackageCnt Later
|
||||
keyFile.SeekCur(sizeof(int));
|
||||
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
|
||||
{
|
||||
EterPackPolicy_CSHybridCrypt* pPolicy = cit->second->GetPackPolicy_HybridCrypt();
|
||||
if( !pPolicy || !pPolicy->IsContainingSDBFile() )
|
||||
continue;
|
||||
|
||||
iSDBPackageCnt++;
|
||||
|
||||
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
|
||||
|
||||
DWORD dwPackNamehash = stringhash().GetHash(noPathName);
|
||||
keyFile.Write( &dwPackNamehash, sizeof(DWORD) );
|
||||
|
||||
int iSDBSizeWriteOffset = keyFile.GetPosition();
|
||||
keyFile.SeekCur(sizeof(int));
|
||||
|
||||
pPolicy->WriteSupplementaryDataBlockToFile( keyFile );
|
||||
int iSDBSizeAfterWrite = keyFile.GetPosition();
|
||||
|
||||
keyFile.Seek(iSDBSizeWriteOffset);
|
||||
|
||||
int iSDBSize = iSDBSizeAfterWrite-(iSDBSizeWriteOffset+4);
|
||||
keyFile.Write( &iSDBSize, sizeof(int) );
|
||||
|
||||
keyFile.Seek(iSDBSizeAfterWrite);
|
||||
}
|
||||
|
||||
//write sdb data start offset & package cnt
|
||||
keyFile.Seek(0);
|
||||
keyFile.Write( &iSDBDataOffset, sizeof(int));
|
||||
keyFile.Write( &iKeyPackageCount, sizeof(int));
|
||||
|
||||
keyFile.Seek(iSDBDataOffset);
|
||||
keyFile.Write( &iSDBPackageCnt, sizeof(int));
|
||||
|
||||
keyFile.Close();
|
||||
}
|
||||
|
Reference in New Issue
Block a user