예제 #1
0
static int CopyMpqFiles(TMPQArchive * ha, LPDWORD pFileKeys, TFileStream * pNewStream)
{
    TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
    TFileEntry * pFileEntry;
    TMPQFile * hf = NULL;
    ULONGLONG MpqFilePos;
    int nError = ERROR_SUCCESS;

    // Walk through all files and write them to the destination MPQ archive
    for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
    {
        // Copy all the file sectors
        // Only do that when the file has nonzero size
        if((pFileEntry->dwFlags & MPQ_FILE_EXISTS))
        {
            // Query the position where the destination file will be
            FileStream_GetPos(pNewStream, &MpqFilePos);
            MpqFilePos = MpqFilePos - ha->MpqPos;

            // Perform file copy ONLY if the file has nonzero size
            if(pFileEntry->dwFileSize != 0)
            {
                // Allocate structure for the MPQ file
                hf = CreateFileHandle(ha, pFileEntry);
                if(hf == NULL)
                    return ERROR_NOT_ENOUGH_MEMORY;

                // Set the file decryption key
                hf->dwFileKey = pFileKeys[pFileEntry - ha->pFileTable];

                // If the file is a patch file, load the patch header
                if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
                {
                    nError = AllocatePatchInfo(hf, true);
                    if(nError != ERROR_SUCCESS)
                        break;
                }

                // Allocate buffers for file sector and sector offset table
                nError = AllocateSectorBuffer(hf);
                if(nError != ERROR_SUCCESS)
                    break;

                // Also allocate sector offset table and sector checksum table
                nError = AllocateSectorOffsets(hf, true);
                if(nError != ERROR_SUCCESS)
                    break;

                // Also load sector checksums, if any
                if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC)
                {
                    nError = AllocateSectorChecksums(hf, false);
                    if(nError != ERROR_SUCCESS)
                        break;
                }

                // Copy all file sectors
                nError = CopyMpqFileSectors(ha, hf, pNewStream, MpqFilePos);
                if(nError != ERROR_SUCCESS)
                    break;

                // Free buffers. This also sets "hf" to NULL.
                FreeFileHandle(hf);
            }

            // Note: DO NOT update the compressed size in the file entry, no matter how bad it is.
            pFileEntry->ByteOffset = MpqFilePos;
        }
    }

    // Cleanup and exit
    if(hf != NULL)
        FreeFileHandle(hf);
    return nError;
}
예제 #2
0
static int CopyMpqFiles(TMPQArchive * ha, LPDWORD pFileKeys, TFileStream * pNewStream)
{
    TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
    TFileEntry * pFileEntry;
    TMPQFile * hf = NULL;
    int nError = ERROR_SUCCESS;

    // Walk through all files and write them to the destination MPQ archive
    for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
    {
        // Copy all the file sectors
        // Only do that when the file has nonzero size
        if ((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->dwFileSize != 0)
        {
            // Allocate structure for the MPQ file
            hf = CreateMpqFile(ha);
            if (hf == NULL)
                return ERROR_NOT_ENOUGH_MEMORY;

            // Store file entry
            hf->pFileEntry = pFileEntry;

            // Set the raw file position
            hf->MpqFilePos = pFileEntry->ByteOffset;
            hf->RawFilePos = ha->MpqPos + hf->MpqFilePos;

            // Set the file decryption key
            hf->dwFileKey = pFileKeys[pFileEntry - ha->pFileTable];
            hf->dwDataSize = pFileEntry->dwFileSize;

            // If the file is a patch file, load the patch header
            if (pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
            {
                nError = AllocatePatchInfo(hf, true);
                if (nError != ERROR_SUCCESS)
                    break;
            }

            // Allocate buffers for file sector and sector offset table
            nError = AllocateSectorBuffer(hf);
            if (nError != ERROR_SUCCESS)
                break;

            // Also allocate sector offset table and sector checksum table
            nError = AllocateSectorOffsets(hf, true);
            if (nError != ERROR_SUCCESS)
                break;

            // Also load sector checksums, if any
            if (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC)
            {
                nError = AllocateSectorChecksums(hf, false);
                if (nError != ERROR_SUCCESS)
                    break;
            }

            // Copy all file sectors
            nError = CopyMpqFileSectors(ha, hf, pNewStream);
            if (nError != ERROR_SUCCESS)
                break;

            // Free buffers. This also sets "hf" to NULL.
            FreeMPQFile(hf);
        }
    }

    // Cleanup and exit
    if (hf != NULL)
        FreeMPQFile(hf);
    return nError;
}
예제 #3
0
static int CopyMpqFiles(TMPQArchive * ha, DWORD * pFileKeys, TFileStream * pNewStream)
{
    TMPQBlockEx * pBlockEx = ha->pExtBlockTable;
    TMPQBlock * pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize;
    TMPQBlock * pBlock;
    TMPQFile * hf = NULL;
    int nError = ERROR_SUCCESS;

    // Walk through all files and write them to the destination MPQ archive
    for(pBlock = ha->pBlockTable; pBlock < pBlockEnd; pBlock++, pBlockEx++)
    {
        // Copy all the file sectors
        // Only do that when the file has nonzero size
        if((pBlock->dwFlags & MPQ_FILE_EXISTS) && pBlock->dwFSize != 0)
        {
            // Allocate structure for the MPQ file
            hf = CreateMpqFile(ha, "<compacting>");
            if(hf == NULL)
                return ERROR_NOT_ENOUGH_MEMORY;

            // Store block positions
            hf->pBlockEx = pBlockEx;
            hf->pBlock = pBlock;

            // Set the raw file position
            hf->MpqFilePos.HighPart = hf->pBlockEx->wFilePosHigh;
            hf->MpqFilePos.LowPart  = hf->pBlock->dwFilePos;
            hf->RawFilePos.QuadPart = ha->MpqPos.QuadPart + hf->MpqFilePos.LowPart;

            // Set the file decryption key
            hf->dwFileKey = pFileKeys[pBlock - ha->pBlockTable];

            // Allocate buffers for file sector and sector offset table
            nError = AllocateSectorBuffer(hf);
            if(nError != ERROR_SUCCESS)
                break;

            // Also allocate sector offset table and sector checksum table
            nError = AllocateSectorOffsets(hf, true);
            if(nError != ERROR_SUCCESS)
                break;

            if(pBlock->dwFlags & MPQ_FILE_SECTOR_CRC)
            {
                nError = AllocateSectorChecksums(hf, false);
                if(nError != ERROR_SUCCESS)
                    break;
            }

            // Copy all file sectors
            nError = CopyMpqFileSectors(ha, hf, pNewStream);
            if(nError != ERROR_SUCCESS)
                break;

            // Free buffers. This also sets "hf" to NULL.
            FreeMPQFile(hf);
        }
    }

    // Cleanup and exit
    if(hf != NULL)
        FreeMPQFile(hf);
    return nError;
}