Casc Storages

CascLib Library

CascLib Library

The CascLib library is a pack of modules, written in C++, which are able to read data from CASC storages. The library is free, released under the MIT license. You can download it from GitHub. Should you find any problems or or malfunctions, please, let me know.

CascLib functions

All CascLib functions are defined in CascLib.h header file.

Accessing CASC storages

Function Description
CascOpenStorageEx Opens a CASC storage
CascOpenStorage Opens a local CASC storage
CascOpenOnlineStorage Opens an online CASC storage
CascGetStorageInfo Allows to retrieve an information about an open storage
CascAddEncryptionKey Allows to add an external encryption key
CascFindEncryptionKey Allows to find an encryption key
CascCloseStorage Closes a CASC storage

Reading files from a storage

Function Description
CascOpenFile Opens a file from a storage
CascGetFileSize, CascGetFileSize64 Retrieves a size of the file within storage
CascSetFilePointer, CascSetFilePointer64 Sets a new position within a file
CascReadFile Reads data from the file
CascGetFileInfo Retrieves an information about an open file within storage
CascCloseFile Closes an open file

File searching

Function Description
CascFindFirstFile Finds a first file matching the specification
CascFindNextFile Finds a next file matching the specification
CascFindClose Stops searching in MPQ

Example

Here is an example of a function, which extracts one file from the storage.

//-----------------------------------------------------------------------------
// Extracts a file from the storage and saves it to the disk.
//
// Parameters :
//
//   char * szStorageName - Name of the storage local path (optionally with product code name)
//   char * szStorageFile - Name/number of storaged file.
//   char * szFileName    - Name of the target disk file.

static int ExtractFile(char * szStorageName, char * szStorageFile, char * szFileName)
{
    HANDLE hStorage = NULL;        // Open storage handle
    HANDLE hFile  = NULL;          // Storage file handle
    HANDLE handle = NULL;          // Disk file handle
    DWORD dwErrCode = ERROR_SUCCESS; // Result value

    // Open a CASC storage, e.g. "c:\Games\StarCraft II".
    // For a multi-product storage, a product code can be appended
    // after the storage local path, e.g. "C:\Games\World of Warcraft:wowt".
    if(dwErrCode == ERROR_SUCCESS)
    {
        if(!CascOpenStorage(szStorageName, 0, &hStorage))
            dwErrCode = GetLastError();
    }

    // Open a file in the storage, e.g. "mods\core.sc2mod\base.sc2assets\assets\sounds\ui_ac_allyfound.wav"
    if(dwErrCode == ERROR_SUCCESS)
    {
        if(!CascOpenFile(hStorage, szStorageFile, 0, 0, &hFile))
            dwErrCode = GetLastError();
    }

    // Create the target file
    if(dwErrCode == ERROR_SUCCESS)
    {
        handle = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
        if(handle == INVALID_HANDLE_VALUE)
            dwErrCode = GetLastError();
    }

    // Read the data from the file
    if(dwErrCode == ERROR_SUCCESS)
    {
        char  szBuffer[0x10000];
        DWORD dwBytes = 1;

        while(dwBytes != 0)
        {
            CascReadFile(hFile, szBuffer, sizeof(szBuffer), &dwBytes);
            if(dwBytes == 0)
                break;

            WriteFile(handle, szBuffer, dwBytes, &dwBytes, NULL);
            if(dwBytes == 0)
                break;
        }
    }

    // Cleanup and exit
    if(handle != NULL)
        CloseHandle(handle);
    if(hFile != NULL)
        CascCloseFile(hFile);
    if(hStorage != NULL)
        CascCloseStorage(hStorage);

    return dwErrCode;
}