#define __CASCLIB_SELF__
#include "CascLib.h"
#include "CascCommon.h"
struct TRootHandler_SC1 : public TFileTreeRoot
{
public:
TRootHandler_SC1() : TFileTreeRoot(0)
{
dwFeatures |= (CASC_FEATURE_FILE_NAMES | CASC_FEATURE_ROOT_CKEY);
}
static bool IsRootFile(LPBYTE pbRootFile, size_t cbRootFile)
{
CASC_CSV Csv(1, false);
size_t nColumns;
bool bResult = false;
if(Csv.Load(pbRootFile, cbRootFile) == ERROR_SUCCESS)
{
nColumns = Csv[CSV_ZERO].GetColumnCount();
if(nColumns == 2 || nColumns == 3)
{
const CASC_CSV_COLUMN & FileName = Csv[CSV_ZERO][CSV_ZERO];
const CASC_CSV_COLUMN & CKeyStr = Csv[CSV_ZERO][1];
bResult = (FileName.szValue && CKeyStr.szValue && CKeyStr.nLength == MD5_STRING_SIZE);
}
}
return bResult;
}
DWORD Load(TCascStorage * hs, LPBYTE pbRootFile, size_t cbRootFile)
{
PCASC_CKEY_ENTRY pCKeyEntry;
CASC_CSV Csv(0, false);
BYTE CKey[MD5_HASH_SIZE];
DWORD dwErrCode;
dwErrCode = Csv.Load(pbRootFile, cbRootFile);
if(dwErrCode == ERROR_SUCCESS)
{
while(Csv.LoadNextLine())
{
const CASC_CSV_COLUMN & FileName = Csv[CSV_ZERO][CSV_ZERO];
const CASC_CSV_COLUMN & CKeyStr = Csv[CSV_ZERO][1];
if(BinaryFromString(CKeyStr.szValue, MD5_STRING_SIZE, CKey) == ERROR_SUCCESS)
{
if((pCKeyEntry = FindCKeyEntry_CKey(hs, CKey)) != NULL)
{
FileTree.InsertByName(pCKeyEntry, FileName.szValue);
}
}
}
}
return dwErrCode;
}
};
DWORD RootHandler_CreateStarcraft1(TCascStorage * hs, CASC_BLOB & RootFile)
{
TRootHandler_SC1 * pRootHandler = NULL;
DWORD dwErrCode = ERROR_BAD_FORMAT;
if(TRootHandler_SC1::IsRootFile(RootFile.pbData, RootFile.cbData))
{
pRootHandler = new TRootHandler_SC1();
if(pRootHandler != NULL)
{
dwErrCode = pRootHandler->Load(hs, RootFile.pbData, RootFile.cbData);
if(dwErrCode != ERROR_SUCCESS)
{
delete pRootHandler;
pRootHandler = NULL;
}
}
}
hs->pRootHandler = pRootHandler;
return dwErrCode;
}