bool MpkManip::cleanupFragment(const char* mpkFilename) { bool bOk = false; HANDLE hMpk = 0; char tempFilename[MAX_PATH]; if(SFileCreateArchiveEx(mpkFilename,OPEN_EXISTING,8000,&hMpk)) { uint nTotal = SFileGetFileInfo(hMpk,SFILE_INFO_NUM_FILES); uint nFiles = 0; char tempPath[MAX_PATH]; getTempPath(MAX_PATH, tempPath); getTempFileName(tempPath,tempFilename); HANDLE hTargetMpk = 0; if(SFileCreateArchiveEx(tempFilename,CREATE_ALWAYS,8000,&hTargetMpk)) { SFILE_FIND_DATA fileFindData; HANDLE hFind = SFileFindFirstFile(hMpk,"*",&fileFindData,0); if(hFind) { do { const char* pFilename = fileFindData.cFileName; char tempFilename[MAX_PATH]; getTempFileName(tempPath,tempFilename); if(SFileExtractFile(hMpk,pFilename,tempFilename)) { if(SFileAddFile(hTargetMpk,tempFilename,pFilename,MPK_FILE_REPLACEEXISTING | MPK_FILE_COMPRESS_PKWARE)) { nFiles++; } } } while(SFileFindNextFile(hFind,&fileFindData)); if(nTotal == nFiles)bOk = true; } SFileCloseArchive(hTargetMpk); } SFileCloseArchive(hMpk); } if(bOk && copyFile(tempFilename,mpkFilename,FALSE)) { bOk = true; } return bOk; }
STDCALL void merc_inventory_mpq_unload(void) { if (!merc_mpq) return; SFileCloseArchive(merc_mpq); }
int getFileType(const char *szFileName) { if ( !szFileName ) return 0; int rVal = 0; HANDLE hMPQ; HANDLE hFile; // Open archive for map checking if ( SFileOpenArchive(szFileName, 0, 0, &hMPQ) && hMPQ ) { // Open scenario.chk file if ( SFileOpenFileEx(hMPQ, "staredit\\scenario.chk", SFILE_FROM_MPQ, &hFile) && hFile ) { rVal = 1; SFileCloseFile(hFile); } // Close archive SFileCloseArchive(hMPQ); } else if ( SFileOpenFileEx(NULL, szFileName, SFILE_FROM_ABSOLUTE, &hFile) && hFile ) { DWORD dwRead = 0; char tbuff[16]; DWORD dwSize = SFileGetFileSize(hFile, 0); // Read file data to check if it's a replay if ( dwSize > 16 && SFileReadFile(hFile, &tbuff, 16, &dwRead, 0) && dwRead == 16 && *(DWORD*)&tbuff[12] == 'SRer' ) rVal = 2; // Close file SFileCloseFile(hFile); } return rVal; }
void quit() { if (NULL != diabdat) { SFileCloseArchive(diabdat); } }
~stormlib_builder() { if (handle_) { SFileCloseArchive(handle_); handle_ = NULL; } }
BOOL WINAPI SFileCloseArchive_stub(MPQHANDLE hMPQ) { LoadSFMpqDll(); if (hSFMpq) { *(FARPROC *)&SFileCloseArchive = GetProcAddress(hSFMpq,"SFileCloseArchive"); if (SFileCloseArchive) return SFileCloseArchive(hMPQ); } return FALSE; }
static void MPQ_closeArchive(void *opaque) { MPQHandle *handle = (MPQHandle*)opaque; if (!handle) return; SFileCloseArchive(handle->mpqHandle); handle->io->destroy(handle->io); allocator.Free(handle); }
void MainWindow::closeMPQ() { FAIO::quit(); ui->listView->clear(); if (mDiabdat) { SFileCloseArchive(mDiabdat); mDiabdat = NULL; } }
bool MpkManip::close() { if(!m_hMpk)return true; bool bOk = SFileCloseArchive(m_hMpk) != FALSE; if(bOk) { m_hMpk = 0; } return bOk; }
uint MpkManip::getUseRate(const char* mpkFilename) { HANDLE hMpk = 0; uint nRate = 100; if(SFileCreateArchiveEx(mpkFilename,OPEN_EXISTING,8000,&hMpk)) { DWORD dwTotal,dwFree; SFileGetBlockNum(hMpk,dwTotal,dwFree); if(dwTotal > 0) nRate = 100 * (dwTotal - dwFree) / dwTotal; SFileCloseArchive(hMpk); } return nRate; }
int SC2Map::readMap() { HANDLE archive; string fullArchiveName( argPath ); fullArchiveName.append( archiveWithExt ); if( !SFileOpenArchive( fullArchiveName.data(), 0, 0, &archive ) ) { printWarning( "Could not open map MPQ archive file %s\n", archiveWithExt.data() ); return -1; } // the order of reading archive files is important--some // analysis data structures are depedenent on one another if( readGameStrings_txt( archive ) < 0 ) { printWarning( "Could not find a locale to extract map name, using archive filename instead.\n" ); mapName.assign( archiveName ); } // however we got a name for the map, make a version // that is valid for use in filenames makeMapNameValidForFilenames(); printMessage( " map name found for preferred locale: [%s]\n", mapName.data() ); printMessage( " map name as part of filenames: [%s]\n", mapNameInOutputFiles.data() ); if( readMapInfo( archive ) < 0 ) { printMessage( " No MapInfo file.\n" ); return -1; } if( debugMapInfo > 0 ) { printMessage( "End debugging MapInfo\n" ); exit( 0 ); } if( readt3HeightMap( archive ) < 0 ) { printMessage( " No t3HeightMap file.\n" ); return -1; } computePathingFromCliffChanges(); if( readt3Terrain_xml( archive ) < 0 ) { printMessage( " No Terrain.xml file, continuing...\n" ); } if( readPaintedPathingLayer( archive ) < 0 ) { printMessage( " No PaintedPathingLayer file, continuing...\n" ); } if( readObjects( archive ) < 0 ) { printMessage( " No Objects file, (StartLocs, resources, etc.), continuing...\n" ); } else { // only do this after all Objects are read applyFillsAndFootprints(); if( startLocs.empty() ) { printWarning( "No start locations have been placed, some outputs may have odd values.\n" ); } } if( debugObjects > 0 ) { printMessage( "End debugging Objects\n" ); exit( 0 ); } SFileCloseArchive( archive ); return 0; }
int main(int argc, char * arg[]) { printf("Map & DBC Extractor\n"); printf("===================\n\n"); HandleArgs(argc, arg); int FirstLocale = -1; uint32 build = 0; for (int i = 0; i < LOCALES_COUNT; ++i) { TCHAR tmp1[512]; _stprintf(tmp1, _T("%s/Data/%s/locale-%s.MPQ"), input_path, Locales[i], Locales[i]); //Open MPQs if (!LoadLocaleMPQFile(i)) { if (GetLastError() != ERROR_PATH_NOT_FOUND) printf("Unable to load %s locale archives!\n", Locales[i]); continue; } printf("Detected locale: %s\n", Locales[i]); if ((CONF_extract & EXTRACT_DBC) == 0) { FirstLocale = i; build = ReadBuild(i); if (build > CONF_TargetBuild) { printf("Base locale-%s.MPQ has build higher than target build (%u > %u), nothing extracted!\n", Locales[i], build, CONF_TargetBuild); return 0; } printf("Detected client build: %u\n", build); break; } //Extract DBC files uint32 tempBuild = ReadBuild(i); printf("Detected client build %u for locale %s\n", tempBuild, Locales[i]); if (tempBuild > CONF_TargetBuild) { printf("Base locale-%s.MPQ has build higher than target build (%u > %u), nothing extracted!\n", Locales[i], tempBuild, CONF_TargetBuild); continue; } ExtractDBCFiles(i, FirstLocale < 0); ExtractDB2Files(i, FirstLocale < 0); if (FirstLocale < 0) { FirstLocale = i; build = tempBuild; } //Close MPQs SFileCloseArchive(LocaleMpq); } if (FirstLocale < 0) { printf("No locales detected\n"); return 0; } if (CONF_extract & EXTRACT_MAP) { printf("Using locale: %s\n", Locales[FirstLocale]); // Open MPQs LoadLocaleMPQFile(FirstLocale); LoadCommonMPQFiles(build); // Extract maps ExtractMapsFromMpq(build); // Close MPQs SFileCloseArchive(WorldMpq); SFileCloseArchive(LocaleMpq); } return 0; }
bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq) { TFileStream * pStream = NULL; // File stream TMPQArchive * ha = NULL; // MPQ archive handle ULONGLONG MpqPos = 0; // Position of MPQ header in the file HANDLE hMpq = NULL; DWORD dwBlockTableSize = 0; // Initial block table size DWORD dwHashTableSize = 0; DWORD dwMaxFileCount; int nError = ERROR_SUCCESS; // Check the parameters, if they are valid if(szMpqName == NULL || *szMpqName == 0 || pCreateInfo == NULL || phMpq == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return false; } // Verify if all variables in SFILE_CREATE_MPQ are correct if((pCreateInfo->cbSize == 0 || pCreateInfo->cbSize > sizeof(SFILE_CREATE_MPQ)) || (pCreateInfo->dwMpqVersion > MPQ_FORMAT_VERSION_4) || (pCreateInfo->pvUserData != NULL || pCreateInfo->cbUserData != 0) || (pCreateInfo->dwAttrFlags & ~MPQ_ATTRIBUTE_ALL) || (pCreateInfo->dwSectorSize & (pCreateInfo->dwSectorSize - 1)) || (pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1)) || (pCreateInfo->dwMaxFileCount < 4)) { SetLastError(ERROR_INVALID_PARAMETER); return false; } // One time initialization of MPQ cryptography InitializeMpqCryptography(); // We verify if the file already exists and if it's a MPQ archive. // If yes, we won't allow to overwrite it. if(SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE | MPQ_OPEN_NO_ATTRIBUTES | MPQ_OPEN_NO_LISTFILE, &hMpq)) { SFileCloseArchive(hMpq); SetLastError(ERROR_ALREADY_EXISTS); return false; } // // At this point, we have to create the archive. // - If the file exists, convert it to MPQ archive. // - If the file doesn't exist, create new empty file // pStream = FileStream_OpenFile(szMpqName, pCreateInfo->dwStreamFlags); if(pStream == NULL) { pStream = FileStream_CreateFile(szMpqName, pCreateInfo->dwStreamFlags); if(pStream == NULL) return false; } // Increment the maximum amount of files to have space // for listfile and attributes file dwMaxFileCount = pCreateInfo->dwMaxFileCount; if(pCreateInfo->dwAttrFlags != 0) dwMaxFileCount++; dwMaxFileCount++; // If file count is not zero, initialize the hash table size dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount); // Retrieve the file size and round it up to 0x200 bytes FileStream_GetSize(pStream, MpqPos); MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL; if(!FileStream_SetSize(pStream, MpqPos)) nError = GetLastError(); #ifdef _DEBUG // Debug code, used for testing StormLib // dwBlockTableSize = dwHashTableSize * 2; #endif // Create the archive handle if(nError == ERROR_SUCCESS) { if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; } // Fill the MPQ archive handle structure if(nError == ERROR_SUCCESS) { memset(ha, 0, sizeof(TMPQArchive)); ha->pStream = pStream; ha->dwSectorSize = pCreateInfo->dwSectorSize; ha->UserDataPos = MpqPos; ha->MpqPos = MpqPos; ha->pHeader = (TMPQHeader *)ha->HeaderData; ha->dwMaxFileCount = dwMaxFileCount; ha->dwFileTableSize = 0; ha->dwFileFlags1 = pCreateInfo->dwFileFlags1; ha->dwFileFlags2 = pCreateInfo->dwFileFlags2; ha->dwFlags = 0; // Setup the attributes ha->dwAttrFlags = pCreateInfo->dwAttrFlags; pStream = NULL; } // Fill the MPQ header if(nError == ERROR_SUCCESS) { TMPQHeader * pHeader = ha->pHeader; // Fill the MPQ header memset(pHeader, 0, sizeof(ha->HeaderData)); pHeader->dwID = ID_MPQ; pHeader->dwHeaderSize = MpqHeaderSizes[pCreateInfo->dwMpqVersion]; pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash); pHeader->wFormatVersion = (USHORT)pCreateInfo->dwMpqVersion; pHeader->wSectorSize = GetSectorSizeShift(ha->dwSectorSize); pHeader->dwHashTablePos = pHeader->dwHeaderSize; pHeader->dwHashTableSize = dwHashTableSize; pHeader->dwBlockTablePos = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash); pHeader->dwBlockTableSize = dwBlockTableSize; // For MPQs version 4 and higher, we set the size of raw data block // for calculating MD5 if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4) pHeader->dwRawChunkSize = pCreateInfo->dwRawChunkSize; // Write the naked MPQ header nError = WriteNakedMPQHeader(ha); // Remember that the (listfile) and (attributes) need to be saved ha->dwFlags |= MPQ_FLAG_CHANGED | MPQ_FLAG_INV_LISTFILE | MPQ_FLAG_INV_ATTRIBUTES; } // Create initial HET table, if the caller required an MPQ format 3.0 or newer if(nError == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3) { ha->pHetTable = CreateHetTable(ha->dwMaxFileCount, 0x40, true); if(ha->pHetTable == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; } // Create initial hash table if(nError == ERROR_SUCCESS) { nError = CreateHashTable(ha, dwHashTableSize); } // Create initial file table if(nError == ERROR_SUCCESS) { ha->pFileTable = STORM_ALLOC(TFileEntry, ha->dwMaxFileCount); if(ha->pFileTable != NULL) memset(ha->pFileTable, 0x00, sizeof(TFileEntry) * ha->dwMaxFileCount); else nError = ERROR_NOT_ENOUGH_MEMORY; } // Cleanup : If an error, delete all buffers and return if(nError != ERROR_SUCCESS) { FileStream_Close(pStream); FreeMPQArchive(ha); SetLastError(nError); ha = NULL; } // Return the values *phMpq = (HANDLE)ha; return (nError == ERROR_SUCCESS); }
void CloseArchives() { for(ArchiveSet::const_iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i) SFileCloseArchive(*i); gOpenArchives.clear(); }
bool CloseArchive(MPQHANDLE mpq) { return SFileCloseArchive(mpq) == TRUE; }
int main(int argc, char* argv[]) { HANDLE hMPQ=0,hMPQ2=0,hMPQ3=0; DWORD *dwPalette = (DWORD *)_alloca(1024); memset(dwPalette,0,1024); LoadStorm("SFMpq.dll"); SetMpqDll("SFMpq.dll"); if (SFileOpenArchive!=0) { char *buffer = (char *)_alloca(13); memcpy(buffer,"StarDat.mpq",12); if (SFileOpenArchive(buffer,1000,0,&hMPQ)==0) return 0; memcpy(buffer,"BrooDat.mpq",12); SFileOpenArchive(buffer,2000,0,&hMPQ2); memcpy(buffer,"Patch_rt.mpq",13); SFileOpenArchive(buffer,3000,0,&hMPQ3); } BufferInfo BI; LoadPalette("tileset\\Platform.wpe",dwPalette); HANDLE hGrp, hGrp2; if (argc>1) hGrp = LoadGrp(argv[1]); else hGrp = LoadGrp("unit\\zerg\\zergling.grp"); HDC hDC = GetDC(0); GRPHEADER GrpInfo; if (GetGrpInfo(hGrp,&GrpInfo)==0) {GrpInfo.nFrames=0;GrpInfo.wMaxWidth=0;GrpInfo.wMaxHeight=0;} BI.nWidth = GrpInfo.wMaxWidth; BI.nHeight = GrpInfo.wMaxHeight; //BI.nWidth = 255; //BI.nHeight = 255; BI.pBuffer = (signed short *)malloc(GrpInfo.nFrames * BI.nWidth * BI.nHeight * sizeof(short)); WORD i,x,y; DWORD j, nGrpSize; unsigned int u,v; memset(BI.pBuffer, 0xFF, GrpInfo.nFrames * BI.nWidth * BI.nHeight * sizeof(short)); //for (DWORD j=0;j<16;j++){ /*for (WORD i=0;i<GrpInfo.nFrames;i++) { DrawGrp(hGrp,hDC,0,0,i,dwPalette,ALPHA_BLEND,0x401020); }*/ signed short clrPixel; RECT rect; /*for (i=0;i<GrpInfo.nFrames;i++) { for (j=0;j<16;j++) { rand_s(&u); rand_s(&v); u = u % 800; v = v % 600; DrawGrp(hGrp,hDC,u,v,i,dwPalette,ALPHA_BLEND,0x404040); } }*/ SetFunctionGetPixel((GETPIXELPROC)ReadPixelFromBuffer); SetFunctionSetPixel((SETPIXELPROC)WritePixelToBuffer); for (i=0;i<GrpInfo.nFrames;i++) { BI.nFrame = i; u = (BI.nWidth - GrpInfo.wMaxWidth) / 2; v = (BI.nHeight - GrpInfo.wMaxHeight) / 2; for (y = 0; y < BI.nHeight; y++) { for (x = 0; x < BI.nWidth; x++) { WritePixelToBuffer(&BI, x, y, -1); } } DrawGrp(hGrp,(HDC)&BI,u,v,i,0,USE_INDEX,0); } hGrp2 = hGrp; hGrp = CreateGrp(BI.pBuffer, GrpInfo.nFrames, BI.nWidth, BI.nHeight, FALSE, &nGrpSize); /*HANDLE hFile; hFile = CreateFile("generated zergling.grp", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); if (hFile != INVALID_HANDLE_VALUE) { WriteFile(hFile, hGrp, nGrpSize, &j, 0); CloseHandle(hFile); }*/ BI.nFrame = 0xFFFF; j=0; for (i=0;i<GrpInfo.nFrames;i+=1) { rect.left = rect.top = 0; rect.right = rect.left + BI.nWidth; rect.bottom = rect.top + BI.nHeight; for (x = 0; x < BI.nWidth * BI.nHeight; x++) BI.pBuffer[x] = -1; //for (j=0;j<(1 * 1);j++) { // DrawGrp(hGrp,(HDC)&BI,i,0,i % (17*8),dwPalette,ALPHA_BLEND,0x401020); //DrawGrp(hGrp2,(HDC)&BI,0,0,i,0,USE_INDEX,0x401020); //u = memcmp(BI.pBuffer, &BI.pBuffer[i * BI.nWidth * BI.nHeight], BI.nWidth * BI.nHeight * sizeof(short)); DrawGrp(hGrp,(HDC)&BI,0,0,i,0,USE_INDEX,0x401020); u = memcmp(BI.pBuffer, &BI.pBuffer[i * BI.nWidth * BI.nHeight], BI.nWidth * BI.nHeight * sizeof(short)); for (x = 0; x < BI.nWidth; x++) for (y = 0; y < BI.nHeight; y++) { clrPixel = BI.pBuffer[(y * BI.nWidth) + x]; if (clrPixel != -1) SetPixelV(hDC, x, y, dwPalette[clrPixel]); } //} if (u) { printf("Output of re-encoded graphic for frame %d does not match original! Total %d\n", i, ++j); //break; } FillRect(hDC, &rect, (HBRUSH) (COLOR_WINDOW+1)); } for (i=4;i<400;i+=17) { rect.left = rect.top = 400-i; rect.right = rect.left + BI.nWidth; rect.bottom = rect.top + BI.nHeight; for (x = 0; x < BI.nWidth * BI.nHeight; x++) BI.pBuffer[x] = -1; for (j=0;j<32;j++) { // DrawGrp(hGrp,(HDC)&BI,400-i,0,i % (17*8),dwPalette,HORIZONTAL_FLIP|ALPHA_BLEND,0x401020); DrawGrp(hGrp,(HDC)&BI,0,0,i % (17*8),0,HORIZONTAL_FLIP|USE_INDEX,0x401020); for (x = 0; x < BI.nWidth; x++) for (y = 0; y < BI.nHeight; y++) { clrPixel = BI.pBuffer[(y * BI.nWidth) + x]; if (clrPixel != -1) SetPixelV(hDC, 400-i + x, 400-i + y, dwPalette[clrPixel]); } } FillRect(hDC, &rect, (HBRUSH) (COLOR_WINDOW+1)); } for (i = 0; i < BI.nWidth; i++) for (j = 0; j < BI.nHeight; j++) { clrPixel = BI.pBuffer[(j * BI.nWidth) + i]; if (clrPixel != -1) SetPixelV(hDC, 400 + i, 300 + j, dwPalette[clrPixel]); } //} ReleaseDC(0,hDC); free(BI.pBuffer); DestroyGrp(hGrp); DestroyGrp(hGrp2); if (SFileCloseArchive!=0) { if (hMPQ3!=0) SFileCloseArchive(hMPQ3); if (hMPQ2!=0) SFileCloseArchive(hMPQ2); if (hMPQ!=0) SFileCloseArchive(hMPQ); } return 0; }
void CMpqArchive::UnLoad() { SFileCloseArchive(m_hMpq); }
bool WINAPI SFileCreateArchive(const char * szMpqName, DWORD dwFlags, DWORD dwMaxFileCount, HANDLE * phMpq) { TFileStream * pStream = NULL; // File stream TMPQArchive * ha = NULL; // MPQ archive handle ULONGLONG MpqPos = 0; // Position of MPQ header in the file HANDLE hMpq = NULL; USHORT wFormatVersion = MPQ_FORMAT_VERSION_1; DWORD dwBlockTableSize = 0; // Initial block table size DWORD dwHashTableSize = 0; int nError = ERROR_SUCCESS; // Check the parameters, if they are valid if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return false; } // One time initialization of MPQ cryptography InitializeMpqCryptography(); // We verify if the file already exists and if it's a MPQ archive. // If yes, we won't allow to overwrite it. if(SFileOpenArchive(szMpqName, 0, dwFlags, &hMpq)) { SFileCloseArchive(hMpq); SetLastError(ERROR_ALREADY_EXISTS); return false; } // // At this point, we have to create the archive. // - If the file exists, convert it to MPQ archive. // - If the file doesn't exist, create new empty file // pStream = FileStream_OpenFile(szMpqName, true); if(pStream == NULL) { pStream = FileStream_CreateFile(szMpqName); if(pStream == NULL) return false; } // Decide what format to use wFormatVersion = (USHORT)((dwFlags & MPQ_CREATE_ARCHIVE_VMASK) >> 16); if(wFormatVersion > MPQ_FORMAT_VERSION_4) { SetLastError(ERROR_INVALID_PARAMETER); return false; } // Increment the maximum amount of files to have space // for listfile and attributes file if(dwFlags & MPQ_CREATE_ATTRIBUTES) dwMaxFileCount++; dwMaxFileCount++; // If file count is not zero, initialize the hash table size dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount); // Retrieve the file size and round it up to 0x200 bytes FileStream_GetSize(pStream, MpqPos); MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL; if(!FileStream_SetSize(pStream, MpqPos)) nError = GetLastError(); #ifdef _DEBUG // Debug code, used for testing StormLib // dwBlockTableSize = dwHashTableSize * 2; #endif // Create the archive handle if(nError == ERROR_SUCCESS) { if((ha = ALLOCMEM(TMPQArchive, 1)) == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; } // Fill the MPQ archive handle structure if(nError == ERROR_SUCCESS) { memset(ha, 0, sizeof(TMPQArchive)); ha->pStream = pStream; ha->dwSectorSize = (wFormatVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000; ha->UserDataPos = MpqPos; ha->MpqPos = MpqPos; ha->pHeader = (TMPQHeader *)ha->HeaderData; ha->dwMaxFileCount = dwMaxFileCount; ha->dwFileTableSize = 0; ha->dwFileFlags1 = MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS | MPQ_FILE_REPLACEEXISTING; ha->dwFileFlags2 = MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS | MPQ_FILE_REPLACEEXISTING; ha->dwFlags = 0; // Setup the attributes if(dwFlags & MPQ_CREATE_ATTRIBUTES) ha->dwAttrFlags = MPQ_ATTRIBUTE_CRC32 | MPQ_ATTRIBUTE_FILETIME | MPQ_ATTRIBUTE_MD5; pStream = NULL; } // Fill the MPQ header if(nError == ERROR_SUCCESS) { TMPQHeader * pHeader = ha->pHeader; // Fill the MPQ header memset(pHeader, 0, sizeof(ha->HeaderData)); pHeader->dwID = ID_MPQ; pHeader->dwHeaderSize = MpqHeaderSizes[wFormatVersion]; pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash); pHeader->wFormatVersion = wFormatVersion; pHeader->wSectorSize = GetSectorSizeShift(ha->dwSectorSize); pHeader->dwHashTablePos = pHeader->dwHeaderSize; pHeader->dwHashTableSize = dwHashTableSize; pHeader->dwBlockTablePos = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash); pHeader->dwBlockTableSize = dwBlockTableSize; // For MPQs version 4 and higher, we set the size of raw data block // for calculating MD5 if(wFormatVersion >= MPQ_FORMAT_VERSION_4) pHeader->dwRawChunkSize = 0x4000; // Write the naked MPQ header nError = WriteNakedMPQHeader(ha); // // Note: Don't recalculate position of MPQ tables at this point. // We merely set a flag that indicates that the MPQ tables // have been changed, and SaveMpqTables will do the work when closing the archive. // ha->dwFlags |= MPQ_FLAG_CHANGED; } // Create initial hash table if(nError == ERROR_SUCCESS) { nError = CreateHashTable(ha, dwHashTableSize); } // Create initial HET table, if the caller required an MPQ format 3.0 or newer if(nError == ERROR_SUCCESS && wFormatVersion >= MPQ_FORMAT_VERSION_3) { ha->pHetTable = CreateHetTable(ha->dwMaxFileCount, 0x40, true); if(ha->pHetTable == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; } // Create initial file table if(nError == ERROR_SUCCESS) { ha->pFileTable = ALLOCMEM(TFileEntry, dwMaxFileCount); if(ha->pFileTable != NULL) memset(ha->pFileTable, 0x00, sizeof(TFileEntry) * dwMaxFileCount); else nError = ERROR_NOT_ENOUGH_MEMORY; } // Cleanup : If an error, delete all buffers and return if(nError != ERROR_SUCCESS) { FileStream_Close(pStream); FreeMPQArchive(ha); SetLastError(nError); ha = NULL; } // Return the values *phMpq = (HANDLE)ha; return (nError == ERROR_SUCCESS); }
int main(int argc, char** argv) try { po::options_description desc("Required options"); desc.add_options() ("help,h", "produce help message") ("force,f", "overwrite existing files") ("mpq", po::value<std::string>(), "the mpq to create") ("files", po::value<std::vector<std::string> >(), "input files"); po::positional_options_description p; p.add("mpq", 1); p.add("files", -1); po::variables_map vm; po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); po::notify(vm); if (!vm.count("files") || !vm.count("mpq") || vm.count("help")) { std::cout << "usage: <mpq> [<files> ...]" << std::endl << std::endl << desc << std::endl; return 1; } std::vector<std::string> files(vm["files"].as< std::vector<std::string> >()); std::vector<FileEntry> toAdd; fs::path mpqPath(vm["mpq"].as<std::string>()); if(fs::exists(mpqPath)) { if(vm.count("force")) fs::remove(mpqPath); else throw std::runtime_error("mpq does already exist"); } for(std::vector<std::string>::iterator path = files.begin(); path != files.end(); ++path) { if(fs::is_regular_file(*path)) toAdd.push_back(FileEntry(*path, *path)); if(!fs::is_directory(*path)) //no symlinks etc continue; for(fs::recursive_directory_iterator file(*path), end; file != end; ++file) if(fs::is_regular_file(file->path())) toAdd.push_back(FileEntry(file->path(), makeRelative(*path, file->path()))); } for(std::vector<FileEntry>::iterator it = toAdd.begin(); it != toAdd.end(); ++it) std::cout << it->realPath << " >> " << it->mpqPath << std::endl; HANDLE mpq; if(!SFileCreateArchive(mpqPath.string().c_str(), MPQ_CREATE_ARCHIVE_V2, toAdd.size(), &mpq)) throw std::runtime_error("couldn't create mpq"); SFileSetLocale(0); size_t counter(0); for(std::vector<FileEntry>::iterator it = toAdd.begin(); it != toAdd.end(); ++it) { loadbar(++counter, toAdd.size()); if(!SFileAddFileEx(mpq, it->realPath.string().c_str(), it->mpqPath.string().c_str(), MPQ_FILE_COMPRESS, MPQ_COMPRESSION_BZIP2, MPQ_COMPRESSION_BZIP2)) std::cout << "couldn't add file " << it->realPath << std::endl; } std::cout << std::endl; SFileCompactArchive(mpq, NULL, false); SFileFlushArchive(mpq); SFileCloseArchive(mpq); return 0; } catch (const std::exception& e) { std::cerr << "error: " << e.what() << "\n"; }
void PackageManager::createMpqPackage(const char* pathName, const char* pszMpqName) { #ifdef WIN32 if (!pathName || pathName[0] == 0) { return; } PackageUtil::logMsg("createPackage begin"); std::string realPath = PackageUtil::flattenPathName(pathName); s_rootDir = realPath; std::replace(s_rootDir.begin(), s_rootDir.end(), '\\', '/'); std::transform(s_rootDir.begin(), s_rootDir.end(), s_rootDir.begin(), tolower); if (s_rootDir.back() != '/') { s_rootDir += '/'; } std::string fileName; if (realPath.back() == '/') { int last = realPath.find_last_of('/', realPath.size() - 2); fileName = realPath.substr(last + 1, realPath.size() - last - 1 - 1); } else { int last = realPath.find_last_of('/'); fileName = realPath.substr(last, realPath.size() - last); } std::string listFileName = WORK_PATH + fileName + ".txt"; std::string mpqName = WORK_PATH; mpqName += fileName; mpqName += ".mpq"; if (PackageUtil::fileExists(mpqName.c_str())) { remove(mpqName.c_str()); } #ifdef WIN32 wchar_t szMpqName[256] = {0}; MultiByteToWideChar (CP_ACP, 0, mpqName.c_str(), mpqName.size(), szMpqName, 255); if (!SFileCreateArchive(szMpqName, MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_ATTRIBUTES, 4000, &s_currentMpqHandle)) { s_currentMpqHandle = NULL; return; } #else if (!SFileCreateArchive(mpqName.c_str(), MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_ATTRIBUTES, 4000, &s_currentMpqHandle)) { s_currentMpqHandle = NULL; return; } #endif if (s_fpListFile) { fclose(s_fpListFile); } s_fpListFile = fopen(listFileName.c_str(), "w"); archivePath(realPath.c_str()); fclose(s_fpListFile); SFileCloseArchive(s_currentMpqHandle); PackageUtil::logMsg("createPackage over"); // 测试文件是否正确 #ifdef WIN32 if(SFileOpenArchive(szMpqName, 0, 0, &s_currentMpqHandle)) { SFileCloseArchive(s_currentMpqHandle); return; } #else if(SFileOpenArchive(mpqName.c_str(), 0, 0, &s_currentMpqHandle)) { SFileCloseArchive(s_currentMpqHandle); return; } #endif assert(false); #endif }
int main(int argc, char ** argv) { bool success=true; const char *versionString = "V4.00 2012_02"; // Use command line arguments, when some if (!processArgv(argc, argv, versionString)) return 1; // some simple check if working dir is dirty else { std::string sdir = std::string(szWorkDirWmo) + "/dir"; std::string sdir_bin = std::string(szWorkDirWmo) + "/dir_bin"; struct stat status; if (!stat(sdir.c_str(), &status) || !stat(sdir_bin.c_str(), &status)) { printf("Your output directory seems to be polluted, please use an empty directory!\n"); printf("<press return to exit>"); char garbage[2]; return scanf("%c", garbage); } } printf("Extract %s. Beginning work ....\n\n",versionString); //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // Create the working directory if (mkdir(szWorkDirWmo #if defined(__linux__) || defined(__APPLE__) , 0711 #endif )) success = (errno == EEXIST); LoadCommonMPQFiles(CONF_TargetBuild); for (int i = 0; i < LOCALES_COUNT; ++i) { //Open MPQs if (!LoadLocaleMPQFile(i)) { if (GetLastError() != ERROR_PATH_NOT_FOUND) printf("Unable to load %s locale archives!\n", Locales[i]); continue; } printf("Detected and using locale: %s\n", Locales[i]); break; } ReadLiquidTypeTableDBC(); // extract data if (success) success = ExtractWmo(); //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //map.dbc if (success) { DBCFile * dbc = new DBCFile(LocaleMpq, "DBFilesClient\\Map.dbc"); if (!dbc->open()) { delete dbc; printf("FATAL ERROR: Map.dbc not found in data file.\n"); return 1; } map_count=dbc->getRecordCount (); map_ids=new map_id[map_count]; for (unsigned int x=0;x<map_count;++x) { map_ids[x].id=dbc->getRecord (x).getUInt(0); strcpy(map_ids[x].name,dbc->getRecord(x).getString(1)); printf("Map - %s\n",map_ids[x].name); } delete dbc; ParsMapFiles(); delete [] map_ids; //nError = ERROR_SUCCESS; // Extract models, listed in GameObjectDisplayInfo.dbc ExtractGameobjectModels(); } SFileCloseArchive(LocaleMpq); SFileCloseArchive(WorldMpq); printf("\n"); if (!success) { printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n",versionString, preciseVectorData); getchar(); } printf("Extract %s. Work complete. No errors.\n",versionString); delete [] LiqType; return 0; }
void MPQArchive::close() { SFileCloseArchive(hMPQ); }