static int WowHandler_Insert(
    TRootHandler_WoW6 * pRootHandler, 
    const char * szFileName,
    LPBYTE pbEncodingKey)
{
    PCASC_FILE_ENTRY pFileEntry;
    DWORD FileDataId = 0;

    // Don't let the number of items to overflow
    if(pRootHandler->FileTable.ItemCount >= pRootHandler->FileTable.ItemCountMax)
        return ERROR_NOT_ENOUGH_MEMORY;

    // Insert the item to the linear file list
    pFileEntry = (PCASC_FILE_ENTRY)Array_Insert(&pRootHandler->FileTable, NULL, 1);
    if(pFileEntry != NULL)
    {
        // Get the file data ID of the previous item (0 if this is the first one)
        if(pRootHandler->FileTable.ItemCount > 1)
            FileDataId = pFileEntry[-1].FileDataId;

        // Fill-in the new entry
        pFileEntry->EncodingKey  = *(PENCODING_KEY)pbEncodingKey;
        pFileEntry->FileNameHash = CalcFileNameHash(szFileName);
        pFileEntry->FileDataId   = FileDataId + 1;
        pFileEntry->Locales      = CASC_LOCALE_ALL;

        // Verify collisions (debug version only)
        assert(Map_FindObject(pRootHandler->pRootMap, &pFileEntry->FileNameHash, NULL) == NULL);

        // Insert the entry to the map
        Map_InsertObject(pRootHandler->pRootMap, pFileEntry, &pFileEntry->FileNameHash);
    }

    return ERROR_SUCCESS;
}
Exemple #2
0
static PLISTFILE_MAP ListMap_InsertName(PLISTFILE_MAP pListMap, const char * szFileName, size_t nLength)
{
    PLISTFILE_ENTRY pListEntry;
    size_t cbToAllocate;
    size_t cbEntrySize;

    // Make sure there is enough space in the list map
    cbEntrySize = sizeof(LISTFILE_ENTRY) + nLength;
    cbEntrySize = ALIGN_TO_SIZE(cbEntrySize, 8);
    if((pListMap->cbBuffer + cbEntrySize) > pListMap->cbBufferMax)
    {
        cbToAllocate = sizeof(LISTFILE_MAP) + (pListMap->cbBufferMax * 3) / 2;
        pListMap = (PLISTFILE_MAP)CASC_REALLOC(BYTE, pListMap, cbToAllocate);
        if(pListMap == NULL)
            return NULL;

        pListMap->cbBufferMax = (pListMap->cbBufferMax * 3) / 2;
    }

    // Get the pointer to the first entry
    pListEntry = (PLISTFILE_ENTRY)((LPBYTE)(pListMap + 1) + pListMap->cbBuffer);
    pListEntry->FileNameHash = CalcFileNameHash(szFileName);
    pListEntry->cbEntrySize = (DWORD)cbEntrySize;

    // Copy the file name to the entry
    memcpy(pListEntry->szFileName, szFileName, nLength);
    pListEntry->szFileName[nLength] = 0;

    // Move the next entry
    pListMap->cbBuffer += cbEntrySize;
    pListMap->nEntries++;
    return pListMap;
}
static void ResolveFullFileNames(
    TRootHandler_Diablo3 * pRootHandler,
    PDIABLO3_CORE_TOC_ENTRY pCoreTocEntries,
    PCASC_MAP pPackageMap,
    LPBYTE pbCoreTocFile,
    DWORD dwFileIndexes)
{
    PCASC_FILE_ENTRY pFileEntry;
    char * szPlainName;
    char * szNamePtr;
    size_t nLength;
    DWORD dwRootIndex;
    DWORD dwFileIndex;
    DWORD dwSubIndex;
    char szShortName[MAX_PATH+1];
    char szFullName[MAX_PATH+1];

    // Keep compiler happy
    CASCLIB_UNUSED(dwFileIndexes);

    // Parse the entire file table
    for(size_t i = 0; i < pRootHandler->FileTable.ItemCount; i++)
    {
        // Retrieve the file entry at n-th position
        pFileEntry = (PCASC_FILE_ENTRY)Array_ItemAt(&pRootHandler->FileTable, i);

        // Skip the items that already have full name
        if(pFileEntry->dwFlags & CASC_ENTRY_SHORT_NAME)
        {
            // Retrieve the file index of that file
            dwRootIndex = INDEX64_ROOT_INDEX(pFileEntry->FileNameHash);
            dwFileIndex = INDEX64_FILE_INDEX(pFileEntry->FileNameHash);
            dwSubIndex = (pFileEntry->dwFlags & CASC_ENTRY_HAS_SUBINDEX) ? INDEX64_SUB_INDEX(pFileEntry->FileNameHash) : DIABLO3_INVALID_INDEX;
            assert(dwFileIndex < dwFileIndexes);

            // Get the plain name of the file
            szPlainName = (char *)(pbCoreTocFile + pCoreTocEntries[dwFileIndex].NameOffset);

            // Create the short file name
            nLength = CreateShortName(pPackageMap,
                                      dwRootIndex,
                                      pCoreTocEntries[dwFileIndex].AssetIndex,
                                      szPlainName,
                                      dwSubIndex,
                                      szShortName);

            // Insert the short name to the list of the names
            szNamePtr = (char *)Array_Insert(&pRootHandler->FileNames, szShortName, nLength + 1);
            pFileEntry->dwFileName = (DWORD)Array_IndexOf(&pRootHandler->FileNames, szNamePtr);

            // Create the full file name
            nLength = CreateFileName(pRootHandler, szShortName, szFullName);
            pFileEntry->FileNameHash = CalcFileNameHash(szFullName);

            // Insert the entry to the name map. Use the mapping of FullName -> FileHash
            Map_InsertObject(pRootHandler->pRootMap, pFileEntry, &pFileEntry->FileNameHash);
        }
    }
}
// Search by file name hash
// Also used in CascSearchFile
PCASC_FILE_ENTRY FindRootEntry(PCASC_MAP pRootMap, const char * szFileName, DWORD * PtrTableIndex)
{
    // Calculate the HASH value of the normalized file name
    ULONGLONG FileNameHash = CalcFileNameHash(szFileName);

    // Perform the hash search
    return (PCASC_FILE_ENTRY)Map_FindObject(pRootMap, &FileNameHash, PtrTableIndex);
}
static LPBYTE D3Handler_GetKey(TRootHandler_Diablo3 * pRootHandler, const char * szFileName)
{
    PCASC_FILE_ENTRY pFileEntry;
    ULONGLONG FileNameHash = CalcFileNameHash(szFileName);

    // Find the file in the name table
    pFileEntry = (PCASC_FILE_ENTRY)Map_FindObject(pRootHandler->pRootMap, &FileNameHash, NULL);
    return (pFileEntry != NULL) ? pFileEntry->EncodingKey.Value : NULL;
}
// Insert an entry with file name as-is
static int InsertFileEntry(
    TRootHandler_Diablo3 * pRootHandler,
    ENCODING_KEY & EncodingKey,
    const char * szFileName,
    size_t cchFileName)
{
    PCASC_FILE_ENTRY pFileEntry;

    // We must not allow the file name array to be reallocated.
    // Reallocating the array would cause pointers in TRootHandler_Diablo3::pRootMap
    // become invalid
    if(pRootHandler->FileTable.ItemCount >= pRootHandler->FileTable.ItemCountMax)
    {
        assert(false);
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    // Insert the plain name to the root handler's global name list
    szFileName = (const char *)Array_Insert(&pRootHandler->FileNames, szFileName, cchFileName);
    if(szFileName == NULL)
        return ERROR_NOT_ENOUGH_MEMORY;

    // Make sure that we don't exceed the file limit at this phase
    pFileEntry = (PCASC_FILE_ENTRY)Array_Insert(&pRootHandler->FileTable, NULL, 1);
    assert(pFileEntry != NULL);

    // Store the info into the file entry
    pFileEntry->EncodingKey  = EncodingKey;
    pFileEntry->FileNameHash = CalcFileNameHash(szFileName);
    pFileEntry->dwFileName   = (DWORD)Array_IndexOf(&pRootHandler->FileNames, szFileName);
    pFileEntry->dwFlags      = 0;

    // Verify collisions (debug version only)
    assert(Map_FindObject(pRootHandler->pRootMap, &pFileEntry->FileNameHash, NULL) == NULL);

    // Calculate the file name hash
    Map_InsertObject(pRootHandler->pRootMap, pFileEntry, &pFileEntry->FileNameHash);

    // Success
    return ERROR_SUCCESS;
}