bool WINAPI SFileFinishFile(HANDLE hFile)
{
    TMPQFile * hf = (TMPQFile *)hFile;
    int nError = ERROR_SUCCESS;

    // Check the proper parameters
    if(!IsValidFileHandle(hf))
        nError = ERROR_INVALID_HANDLE;
    if(hf->bIsWriteHandle == false)
        nError = ERROR_INVALID_HANDLE;

    // Finish the file
    if(nError == ERROR_SUCCESS)
        nError = SFileAddFile_Finish(hf);
    
    // Deal with errors
    if(nError != ERROR_SUCCESS)
        SetLastError(nError);
    return (nError == ERROR_SUCCESS);
}
Beispiel #2
0
int SSignFileCreate(TMPQArchive * ha)
{
    TMPQFile * hf = NULL;
    BYTE EmptySignature[MPQ_SIGNATURE_FILE_SIZE];
    int nError = ERROR_SUCCESS;

    // Only save the signature if we should do so
    if(ha->dwFileFlags3 != 0)
    {
        // The (signature) file must be non-encrypted and non-compressed
        assert(ha->dwFlags & MPQ_FLAG_SIGNATURE_NEW);
        assert(ha->dwFileFlags3 == MPQ_FILE_EXISTS);
        assert(ha->dwReservedFiles > 0);

        // Create the (signature) file file in the MPQ
        // Note that the file must not be compressed or encrypted
        nError = SFileAddFile_Init(ha, SIGNATURE_NAME,
                                       0,
                                       sizeof(EmptySignature),
                                       LANG_NEUTRAL,
                                       ha->dwFileFlags3 | MPQ_FILE_REPLACEEXISTING,
                                      &hf);

        // Write the empty signature file to the archive
        if(nError == ERROR_SUCCESS)
        {
            // Write the empty zeroed file to the MPQ
            memset(EmptySignature, 0, sizeof(EmptySignature));
            nError = SFileAddFile_Write(hf, EmptySignature, (DWORD)sizeof(EmptySignature), 0);
            SFileAddFile_Finish(hf);

            // Clear the invalid mark
            ha->dwFlags &= ~(MPQ_FLAG_SIGNATURE_NEW | MPQ_FLAG_SIGNATURE_NONE);
            ha->dwReservedFiles--;
        }
    }

    return nError;
}
Beispiel #3
0
// Saves the whole listfile into the MPQ.
int SListFileSaveToMpq(TMPQArchive * ha)
{
    TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
    TFileEntry * pFileEntry;
    TMPQFile * hf = NULL;
    char * szPrevItem;
    char ** SortTable = NULL;
    DWORD dwFileSize = 0;
    size_t nFileNodes = 0;
    size_t i;
    int nError = ERROR_SUCCESS;

    // Allocate the table for sorting listfile
    SortTable = STORM_ALLOC(char*, ha->dwFileTableSize);
    if(SortTable == NULL)
        return ERROR_NOT_ENOUGH_MEMORY;

    // Construct the sort table
    // Note: in MPQs with multiple locale versions of the same file,
    // this code causes adding multiple listfile entries.
    // Since those MPQs were last time used in Starcraft,
    // we leave it as it is.
    for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
    {
        // Only take existing items
        if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->szFileName != NULL)
        {
            // Ignore pseudo-names
            if(!IsPseudoFileName(pFileEntry->szFileName, NULL) && !IsInternalMpqFileName(pFileEntry->szFileName))
            {
                SortTable[nFileNodes++] = pFileEntry->szFileName;
            }
        }
    }

    // Sort the table
    qsort(SortTable, nFileNodes, sizeof(char *), CompareFileNodes);

    // Now parse the table of file names again - remove duplicates
    // and count file size.
    if(nFileNodes != 0)
    {
        // Count the 0-th item
        dwFileSize += (DWORD)strlen(SortTable[0]) + 2;
        szPrevItem = SortTable[0];
        
        // Count all next items
        for(i = 1; i < nFileNodes; i++)
        {
            // If the item is the same like the last one, skip it
            if(_stricmp(SortTable[i], szPrevItem))
            {
                dwFileSize += (DWORD)strlen(SortTable[i]) + 2;
                szPrevItem = SortTable[i];
            }
        }

        // Determine the flags for (listfile)
        if(ha->dwFileFlags1 == 0)
            ha->dwFileFlags1 = GetDefaultSpecialFileFlags(ha, dwFileSize);

        // Create the listfile in the MPQ
        nError = SFileAddFile_Init(ha, LISTFILE_NAME,
                                       0,
                                       dwFileSize,
                                       LANG_NEUTRAL,
                                       ha->dwFileFlags1 | MPQ_FILE_REPLACEEXISTING,
                                      &hf);
        // Add all file names
        if(nError == ERROR_SUCCESS)
        {
            // Each name is followed by newline ("\x0D\x0A")
            szPrevItem = SortTable[0];
            nError = WriteListFileLine(hf, SortTable[0]);

            // Count all next items
            for(i = 1; i < nFileNodes; i++)
            {
                // If the item is the same like the last one, skip it
                if(_stricmp(SortTable[i], szPrevItem))
                {
                    WriteListFileLine(hf, SortTable[i]);
                    szPrevItem = SortTable[i];
                }
            }
        }
    }
    else
    {
        // Create the listfile in the MPQ
        dwFileSize = (DWORD)strlen(LISTFILE_NAME) + 2;
        nError = SFileAddFile_Init(ha, LISTFILE_NAME,
                                       0,
                                       dwFileSize,
                                       LANG_NEUTRAL,
                                       MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS | MPQ_FILE_REPLACEEXISTING,
                                      &hf);

        // Just add "(listfile)" there
        if(nError == ERROR_SUCCESS)
        {
            WriteListFileLine(hf, LISTFILE_NAME);
        }
    }

    // Finalize the file in the MPQ
    if(hf != NULL)
    {
        SFileAddFile_Finish(hf);
    }
    
    // Free buffers
    if(nError == ERROR_SUCCESS)
        ha->dwFlags &= ~MPQ_FLAG_INV_LISTFILE;
    if(SortTable != NULL)
        STORM_FREE(SortTable);
    return nError;
}