Removed Panama & HybridCrypt, added experimental Folder and Zip archive providers

This commit is contained in:
2024-12-16 20:00:39 +02:00
parent e7b6680895
commit 6564e417f9
24 changed files with 378 additions and 718 deletions

View File

@ -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();
}