示例#1
0
int RootHandler_CreateWoW6(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile, DWORD dwLocaleMask)
{
    TRootHandler_WoW6 * pRootHandler;
    LPBYTE pbRootFileEnd = pbRootFile + cbRootFile;
    int nError;

    // Verify the size
    if(pbRootFile == NULL || cbRootFile <= sizeof(PFILE_LOCALE_BLOCK))
        nError = ERROR_FILE_CORRUPT;

    // Allocate the root handler object
    hs->pRootHandler = pRootHandler = CASC_ALLOC(TRootHandler_WoW6, 1);
    if(pRootHandler == NULL)
        return ERROR_NOT_ENOUGH_MEMORY;

    // Fill-in the handler functions
    memset(pRootHandler, 0, sizeof(TRootHandler_WoW6));
    pRootHandler->Insert      = (ROOT_INSERT)WowHandler_Insert;
    pRootHandler->Search      = (ROOT_SEARCH)WowHandler_Search;
    pRootHandler->EndSearch   = (ROOT_ENDSEARCH)WowHandler_EndSearch;
    pRootHandler->GetKey      = (ROOT_GETKEY)WowHandler_GetKey;
    pRootHandler->Close       = (ROOT_CLOSE)WowHandler_Close;

#ifdef _DEBUG
    pRootHandler->Dump = TRootHandlerWoW6_Dump;    // Support for ROOT file dump
#endif  // _DEBUG

    // Count the files that are going to be loaded
    ParseWowRootFile(pRootHandler, ParseRoot_CountFiles, pbRootFile, pbRootFileEnd, dwLocaleMask);
    pRootHandler->dwTotalFileCount += CASC_EXTRA_FILES;

    // Create linear table that will contain all root items
    nError = Array_Create(&pRootHandler->FileTable, CASC_FILE_ENTRY, pRootHandler->dwTotalFileCount);
    if(nError != ERROR_SUCCESS)
        return nError;

    // Create sorted table that will contain all root items to lookup by FileDataId
    nError = Array_Create(&pRootHandler->FileDataIdLookupTable, PCASC_FILE_ENTRY, pRootHandler->dwTotalFileCount);
    if (nError != ERROR_SUCCESS)
        return nError;

    // Create the map of FileHash ->FileEntry
    pRootHandler->pRootMap = Map_Create(pRootHandler->dwTotalFileCount, sizeof(ULONGLONG), FIELD_OFFSET(CASC_FILE_ENTRY, FileNameHash));
    if(pRootHandler->pRootMap == NULL)
        return ERROR_NOT_ENOUGH_MEMORY;

    // Parse the root file again and insert all files to the map
    ParseWowRootFile(pRootHandler, ParseRoot_AddRootEntries, pbRootFile, pbRootFileEnd, dwLocaleMask);

    // Sort entries by FileDataId for searches
    qsort_pointer_array((void**)pRootHandler->FileDataIdLookupTable.ItemArray, pRootHandler->FileDataIdLookupTable.ItemCount, &FileDataIdCompare, NULL);
    return ERROR_SUCCESS;
}
示例#2
0
// Create empty project
AProject *AProject_Create (const char *OutputName)
{
	AProject *pProject;
	geBoolean NoErrors;
	char OutputNameAndExt[MAX_PATH];

	assert (OutputName != NULL);

	pProject = GE_RAM_ALLOCATE_STRUCT (AProject);
	if (pProject == NULL)
	{
		geErrorLog_AddString (GE_ERR_MEMORY_RESOURCE, "Allocating project structure",NULL);
		return NULL;
	}

	// Initialize defaults
	// Output
	pProject->Output.Filename = NULL;
	pProject->Output.Fmt = ApjOutput_Binary;

	// Paths
	pProject->Paths.ForceRelative = GE_TRUE;
	pProject->Paths.Materials = NULL;

	// Body
	pProject->Body.Filename = NULL;
	pProject->Body.Fmt = ApjBody_Max;

	// Materials
	pProject->Materials.Count = 0;
	pProject->Materials.Items = NULL;

	// Motions
	pProject->Motions.Count = 0;
	pProject->Motions.Items = NULL;

	FilePath_SetExt (OutputName, ".act", OutputNameAndExt);

	// Allocate required memory
	NoErrors = 
		((pProject->Output.Filename = Util_Strdup (OutputNameAndExt)) != NULL) &&
		((pProject->Paths.Materials = Util_Strdup ("")) != NULL) &&
		((pProject->Paths.TempFiles = Util_Strdup (".\\BldTemp")) != NULL) &&
		((pProject->Body.Filename	= Util_Strdup ("")) != NULL);
		
	// Build motion and material arrays.  Initially empty.
	NoErrors = NoErrors &&
		((pProject->Materials.Items = Array_Create (1, sizeof (ApjMaterialEntry))) != NULL);

	NoErrors = NoErrors &&
		((pProject->Motions.Items = Array_Create (1, sizeof (ApjMotionEntry))) != NULL);

	// if unsuccessful, destroy any allocated data
	if (!NoErrors)
	{
		geErrorLog_AddString (GE_ERR_MEMORY_RESOURCE, "Initializing project structure",NULL);
		if (pProject != NULL)
		{
			AProject_Destroy (&pProject);
		}
	}

	return pProject;
}
int RootHandler_CreateDiablo3(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile)
{
    TRootHandler_Diablo3 * pRootHandler;
    PCASC_MAP pPackageMap = NULL;
    LPBYTE pbRootFileEnd = pbRootFile + cbRootFile;
    LPBYTE pbPackagesDat = NULL;
    DWORD dwTotalFileCount;
    DWORD cbPackagesDat = 0;
    int nError;

    // Allocate the root handler object
    hs->pRootHandler = pRootHandler = CASC_ALLOC(TRootHandler_Diablo3, 1);
    if(pRootHandler == NULL)
        return ERROR_NOT_ENOUGH_MEMORY;

    // Fill-in the handler functions
    memset(pRootHandler, 0, sizeof(TRootHandler_Diablo3));
    pRootHandler->Insert      = (ROOT_INSERT)D3Handler_Insert;
    pRootHandler->Search      = (ROOT_SEARCH)D3Handler_Search;
    pRootHandler->EndSearch   = (ROOT_ENDSEARCH)D3Handler_EndSearch;
    pRootHandler->GetKey      = (ROOT_GETKEY)D3Handler_GetKey;
    pRootHandler->Close       = (ROOT_CLOSE)D3Handler_Close;
    pRootHandler->GetFileId   = (ROOT_GETFILEID)D3Handler_GetFileId;

    // Fill-in the flags
    pRootHandler->dwRootFlags |= ROOT_FLAG_HAS_NAMES;

    // Scan the total number of files in the root directories
    // Reserve space for extra files
    dwTotalFileCount = ScanDirectoryFile(hs, pbRootFile, pbRootFileEnd);
    if(dwTotalFileCount == 0)
        return ERROR_FILE_CORRUPT;
    dwTotalFileCount += CASC_EXTRA_FILES;

    // Allocate the global linear file table
    // Note: This is about 18 MB of memory for Diablo III PTR build 30013
    nError = Array_Create(&pRootHandler->FileTable, CASC_FILE_ENTRY, dwTotalFileCount);
    if(nError != ERROR_SUCCESS)
        return nError;

    // Allocate global buffer for file names.
    // The size of the buffer was taken from Diablo III build 30013
    nError = Array_Create(&pRootHandler->FileNames, char, 0x01000000);
    if(nError != ERROR_SUCCESS)
        return nError;

    // Create map of ROOT_ENTRY -> FileEntry
    pRootHandler->pRootMap = Map_Create(dwTotalFileCount, sizeof(ULONGLONG), FIELD_OFFSET(CASC_FILE_ENTRY, FileNameHash));
    if(pRootHandler->pRootMap == NULL)
        return ERROR_NOT_ENOUGH_MEMORY;

    // Parse the ROOT file and insert all entries in the file table
    nError = ParseDirectoryFile(pRootHandler, pbRootFile, pbRootFileEnd, DIABLO3_INVALID_INDEX);
    if(nError == ERROR_SUCCESS)
    {
        size_t dwRootEntries = pRootHandler->FileTable.ItemCount;

        // We expect the number of level-0 to be less than maximum
        assert(dwRootEntries < DIABLO3_MAX_SUBDIRS);

        // Now parse the all root items and load them
        for(DWORD i = 0; i < dwRootEntries; i++)
        {
            PCASC_FILE_ENTRY pRootEntry = (PCASC_FILE_ENTRY)Array_ItemAt(&pRootHandler->FileTable, i);

            // Load the entire file to memory
            pbRootFile = LoadFileToMemory(hs, pRootEntry->EncodingKey.Value, &cbRootFile);
            if(pbRootFile != NULL)
            {
                nError = ParseDirectoryFile(pRootHandler, pbRootFile, pbRootFile + cbRootFile, i);
                CASC_FREE(pbRootFile);
            }
        }
    }

    // Note: The file "Base\Data_D3\PC\Misc\Packages.dat" contains the names
    // of the files (without level-0 and level-1 directory). We can use these
    // names for supplying the missing extensions
    if(nError == ERROR_SUCCESS)
    {
        // Load the entire file to memory
        pbPackagesDat = LoadFileToMemory(hs, "Base\\Data_D3\\PC\\Misc\\Packages.dat", &cbPackagesDat);
        if(pbPackagesDat != NULL)
        {
            pPackageMap = CreatePackageMap(pbPackagesDat, pbPackagesDat + cbPackagesDat);
        }
    }

    // Vast majorify of files at this moment don't have names.
    // We can load the Base\CoreTOC.dat file in order
    // to get directory asset indexes, file names and extensions
    if(nError == ERROR_SUCCESS)
    {
        LPBYTE pbCoreTOC;
        DWORD cbCoreTOC = 0;

        // Load the entire file to memory
        pbCoreTOC = LoadFileToMemory(hs, "Base\\CoreTOC.dat", &cbCoreTOC);
        if(pbCoreTOC != NULL)
        {
            ParseCoreTOC(pRootHandler, pPackageMap, pbCoreTOC, pbCoreTOC + cbCoreTOC);
            CASC_FREE(pbCoreTOC);
        }
    }

    // Free the packages map
    if(pPackageMap != NULL)
        Map_Free(pPackageMap);
    if(pbPackagesDat != NULL)
        CASC_FREE(pbPackagesDat);
    return nError;
}