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); }
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; }
// 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; }