diff options
Diffstat (limited to 'dep/CascLib/src/CascMndxRoot.h')
-rw-r--r-- | dep/CascLib/src/CascMndxRoot.h | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/dep/CascLib/src/CascMndxRoot.h b/dep/CascLib/src/CascMndxRoot.h new file mode 100644 index 00000000000..23017642ff9 --- /dev/null +++ b/dep/CascLib/src/CascMndxRoot.h @@ -0,0 +1,365 @@ +/*****************************************************************************/ +/* CascMndxRoot.h Copyright (c) Ladislav Zezula 2014 */ +/*---------------------------------------------------------------------------*/ +/* Interface file for MNDX structures */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 15.05.14 1.00 Lad Created */ +/*****************************************************************************/ + +#ifndef __CASC_MNDX_ROOT__ +#define __CASC_MNDX_ROOT__ + +class TFileNameDatabase; + +#define CASC_MAX_ENTRIES(type) (0xFFFFFFFF / sizeof(type)) + +#define CASC_SEARCH_INITIALIZING 0 +#define CASC_SEARCH_SEARCHING 2 +#define CASC_SEARCH_FINISHED 4 + +typedef struct _TRIPLET +{ + DWORD BaseValue; + DWORD Value2; + DWORD Value3; +} TRIPLET, *PTRIPLET; + +typedef struct _NAME_FRAG +{ + DWORD ItemIndex; // Back index to various tables + DWORD NextIndex; // The following item index + DWORD FragOffs; // Higher 24 bits are 0xFFFFFF00 --> A single matching character + // Otherwise --> Offset to the name fragment table +} NAME_FRAG, *PNAME_FRAG; + +typedef struct _PATH_STOP +{ + DWORD ItemIndex; + DWORD field_4; + DWORD field_8; + DWORD field_C; + DWORD field_10; +} PATH_STOP, *PPATH_STOP; + +typedef union _ARRAY_POINTER +{ + LPBYTE Bytes; // Pointer to an octet + char * Chars; // Pointer to a character + PDWORD Uint32s; // Pointer to a DWORD + PTRIPLET Triplets; // Pointer to TRIPLET + PNAME_FRAG NameFrags; // Pointer to name fragment entry + PPATH_STOP PathStopPtr; // Pointer to path checkpoint + PULONGLONG Int64Ptr; // Pointer to 64-bit integer + +} ARRAY_POINTER, *PARRAY_POINTER; + +// Simple access to various tables within TGenericArray +#define ByteArray ArrayPointer.Bytes +#define CharArray ArrayPointer.Chars +#define Uint32Array ArrayPointer.Uint32s +#define TripletArray ArrayPointer.Triplets +#define NameFragArray ArrayPointer.NameFrags + +class TByteStream +{ + public: + + TByteStream(); + + void ExchangeWith(TByteStream & Target); + int GetBytes(DWORD cbByteCount, PARRAY_POINTER PtrArray); + int SkipBytes(DWORD cbByteCount); + int SetByteBuffer(LPBYTE pbNewMarData, DWORD cbNewMarData); + int GetValue_DWORD(DWORD & Value); + int GetValue_ItemCount(DWORD & NumberOfBytes, DWORD & ItemCount, DWORD ItemSize); + int GetArray_DWORDs(PARRAY_POINTER PtrArray, DWORD ItemCount); + int GetArray_Triplets(PARRAY_POINTER PtrArray, DWORD ItemCount); + int GetArray_NameTable(PARRAY_POINTER PtrArray, DWORD ItemCount); + int GetArray_BYTES(PARRAY_POINTER PtrArray, DWORD ItemCount); + + LPBYTE pbByteData; + void * pvMappedFile; + DWORD cbByteData; + DWORD field_C; + HANDLE hFile; + HANDLE hMap; +}; + +class TGenericArray +{ + public: + + TGenericArray(); + ~TGenericArray(); + + int SetArrayValid(); + + void ExchangeWith(TGenericArray & Target); + void CopyFrom(TGenericArray & Source); + + void SetMaxItems_CHARS(DWORD NewMaxItemCount); + void SetMaxItems_PATH_STOP(DWORD NewMaxItemCount); + + void InsertOneItem_CHAR(char OneChar); + void InsertOneItem_PATH_STOP(PATH_STOP & NewItem); + + void sub_19583A0(DWORD NewItemCount); + + int LoadDwordsArray(TByteStream & InStream); + int LoadTripletsArray(TByteStream & InStream); + int LoadByteArray(TByteStream & InStream); + int LoadFragmentInfos(TByteStream & InStream); + int LoadStrings(TByteStream & InStream); + + int LoadDwordsArray_Copy(TByteStream & InStream); + int LoadTripletsArray_Copy(TByteStream & InStream); + int LoadBytes_Copy(TByteStream & InStream); + int LoadFragmentInfos_Copy(TByteStream & InStream); + int LoadStringsWithCopy(TByteStream & InStream); + + ARRAY_POINTER DataBuffer; + ARRAY_POINTER FirstValid; + + ARRAY_POINTER ArrayPointer; + DWORD ItemCount; // Number of items in the array + DWORD MaxItemCount; // Capacity of the array + bool bIsValidArray; +}; + +class TBitEntryArray : public TGenericArray +{ + public: + + TBitEntryArray(); + ~TBitEntryArray(); + + DWORD GetBitEntry(DWORD EntryIndex) + { + DWORD dwItemIndex = (EntryIndex * BitsPerEntry) >> 0x05; + DWORD dwStartBit = (EntryIndex * BitsPerEntry) & 0x1F; + DWORD dwEndBit = dwStartBit + BitsPerEntry; + DWORD dwResult; + + // If the end bit index is greater than 32, + // we also need to load from the next 32-bit item + if(dwEndBit > 0x20) + { + dwResult = (Uint32Array[dwItemIndex + 1] << (0x20 - dwStartBit)) | (Uint32Array[dwItemIndex] >> dwStartBit); + } + else + { + dwResult = Uint32Array[dwItemIndex] >> dwStartBit; + } + + // Now we also need to mask the result by the bit mask + return dwResult & EntryBitMask; + } + + void ExchangeWith(TBitEntryArray & Target); + int LoadFromStream(TByteStream & InStream); + int LoadFromStream_Exchange(TByteStream & InStream); + + DWORD BitsPerEntry; + DWORD EntryBitMask; + DWORD TotalEntries; +}; + +class TStruct40 +{ + public: + + TStruct40(); + + void InitSearchBuffers(); + + TGenericArray array_00; + TGenericArray PathStops; // Array of path checkpoints + DWORD ItemIndex; // Current name fragment: Index to various tables + DWORD CharIndex; + DWORD ItemCount; + DWORD SearchPhase; // 0 = initializing, 2 = searching, 4 = finished +}; + +class TMndxFindResult +{ + public: + + TMndxFindResult(); + ~TMndxFindResult(); + + int CreateStruct40(); + void FreeStruct40(); + + int SetSearchPath(const char * szNewSearchPath, size_t cchNewSearchPath); + + const char * szSearchMask; // Search mask without wioldcards + size_t cchSearchMask; // Length of the search mask + DWORD field_8; + const char * szFoundPath; // Found path name + size_t cchFoundPath; // Length of the found path name + DWORD FileNameIndex; // Index of the file name + TStruct40 * pStruct40; +}; + +class TSparseArray +{ + public: + + TSparseArray(); + + void ExchangeWith(TSparseArray & TargetObject); + int LoadFromStream(TByteStream & InStream); + int LoadFromStream_Exchange(TByteStream & InStream); + + // Returns true if the item at n-th position is present + DWORD IsItemPresent(DWORD ItemIndex) + { + return (ItemBits.Uint32Array[ItemIndex >> 0x05] & (1 << (ItemIndex & 0x1F))); + } + + DWORD GetItemValue(DWORD ItemIndex); + + TGenericArray ItemBits; // Bit array for each item (1 = item is present) + DWORD TotalItemCount; // Total number of items in the array + DWORD ValidItemCount; // Number of present items in the array + TGenericArray BaseValues; // Array of base values for item indexes >= 0x200 + TGenericArray ArrayDwords_38; + TGenericArray ArrayDwords_50; +}; + +class TNameIndexStruct +{ + public: + + TNameIndexStruct(); + ~TNameIndexStruct(); + + bool CheckNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs); + bool CheckAndCopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs); + void CopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs); + + void ExchangeWith(TNameIndexStruct & Target); + int LoadFromStream(TByteStream & InStream); + int LoadFromStream_Exchange(TByteStream & InStream); + + TGenericArray NameFragments; + TSparseArray Struct68; +}; + +class TStruct10 +{ + public: + + TStruct10(); + + void CopyFrom(TStruct10 & Target); + int sub_1956FD0(DWORD dwBitMask); + int sub_1957050(DWORD dwBitMask); + int sub_19572E0(DWORD dwBitMask); + int sub_1957800(DWORD dwBitMask); + + DWORD field_0; + DWORD field_4; + DWORD field_8; + DWORD field_C; +}; + +class TFileNameDatabasePtr +{ + public: + + TFileNameDatabasePtr(); + ~TFileNameDatabasePtr(); + + int FindFileInDatabase(TMndxFindResult * pStruct1C); + int sub_1956CE0(TMndxFindResult * pStruct1C, bool * pbFindResult); + + int GetFileNameCount(PDWORD PtrFileNameCount); + int CreateDatabase(LPBYTE pbMarData, DWORD cbMarData); + int SetDatabase(TFileNameDatabase * pNewDB); + + TFileNameDatabase * pDB; +}; + +class TFileNameDatabase +{ + public: + + TFileNameDatabase(); + + void ExchangeWith(TFileNameDatabase & Target); + int LoadFromStream(TByteStream & InStream); + int LoadFromStream_Exchange(TByteStream & InStream); + + DWORD sub_1959CB0(DWORD dwHashValue); + DWORD sub_1959F50(DWORD arg_0); + + // Retrieves the name fragment distance + // HOTS: 19573D0/inlined + DWORD GetNameFragmentOffsetEx(DWORD LoBitsIndex, DWORD HiBitsIndex) + { + return (FrgmDist_HiBits.GetBitEntry(HiBitsIndex) << 0x08) | FrgmDist_LoBits.ByteArray[LoBitsIndex]; + } + + // HOTS: 1957350, inlined + DWORD GetNameFragmentOffset(DWORD LoBitsIndex) + { + return GetNameFragmentOffsetEx(LoBitsIndex, Struct68_D0.GetItemValue(LoBitsIndex)); + } + + bool sub_1957B80(TMndxFindResult * pStruct1C, DWORD dwKey); + bool CheckNextPathFragment(TMndxFindResult * pStruct1C); + bool FindFileInDatabase(TMndxFindResult * pStruct1C); + + void sub_1958D70(TMndxFindResult * pStruct1C, DWORD arg_4); + bool sub_1959010(TMndxFindResult * pStruct1C, DWORD arg_4); + bool sub_1958B00(TMndxFindResult * pStruct1C); + bool sub_1959460(TMndxFindResult * pStruct1C); + + TSparseArray Struct68_00; + TSparseArray FileNameIndexes; // Array of file name indexes + TSparseArray Struct68_D0; + + // This pair of arrays serves for fast conversion from name hash to fragment offset + TGenericArray FrgmDist_LoBits; // Array of lower 8 bits of name fragment offset + TBitEntryArray FrgmDist_HiBits; // Array of upper x bits of name fragment offset + + TNameIndexStruct IndexStruct_174; + TFileNameDatabasePtr NextDB; + + TGenericArray NameFragTable; + + DWORD NameFragIndexMask; + DWORD field_214; + TStruct10 Struct10; + TByteStream MarStream; +}; + +typedef struct _MAR_FILE +{ + TFileNameDatabasePtr * pDatabasePtr; + LPBYTE pbMarData; + DWORD cbMarData; +} MAR_FILE, *PMAR_FILE; + +//----------------------------------------------------------------------------- +// Macros + +// Returns nonzero if the name fragment match is a single-char match +inline bool IS_SINGLE_CHAR_MATCH(TGenericArray & Table, DWORD ItemIndex) +{ + return ((Table.NameFragArray[ItemIndex].FragOffs & 0xFFFFFF00) == 0xFFFFFF00); +} + +//----------------------------------------------------------------------------- +// CASC functions related to MNDX + +int LoadMndxRootFile(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile); +PCASC_PACKAGE FindMndxPackage(TCascStorage * hs, const char * szFileName); +int SearchMndxInfo(PCASC_MNDX_INFO pMndxInfo, const char * szFileName, DWORD dwPackage, PCASC_ROOT_KEY_INFO pFoundInfo); +bool DoStorageSearch_MNDX(TCascSearch * pSearch, PCASC_FIND_DATA pFindData); +void FreeMndxInfo(PCASC_MNDX_INFO pMndxInfo); + +#endif // __CASC_MNDX_ROOT__ |