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; }
static int SFileAddInternalListFile( TMPQArchive * ha, HANDLE hMpq) { TMPQArchive * haMpq = (TMPQArchive *)hMpq; TMPQHash * pFirstHash; TMPQHash * pHash; HANDLE hListFile; LCID lcSaveLocale = lcFileLocale; int nError = ERROR_SUCCESS; // If there is hash table, we need to support multiple listfiles // with different locales (BrooDat.mpq) if(haMpq->pHashTable != NULL) { pFirstHash = pHash = GetFirstHashEntry(haMpq, LISTFILE_NAME); while(nError == ERROR_SUCCESS && pHash != NULL) { // Set the prefered locale to that from list file SFileSetLocale(pHash->lcLocale); if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &hListFile)) { // Add the data from the listfile to MPQ nError = SFileAddArbitraryListFile(ha, hListFile); SFileCloseFile(hListFile); } // Restore the original locale SFileSetLocale(lcSaveLocale); // Move to the next hash pHash = GetNextHashEntry(haMpq, pFirstHash, pHash); } } else { // Open the external list file if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &hListFile)) { // Add the data from the listfile to MPQ // The function also closes the listfile handle nError = SFileAddArbitraryListFile(ha, hListFile); SFileCloseFile(hListFile); } } // Return the result of the operation return nError; }
bool ExtractFile( char const* mpq_name, std::string const& filename ) { for(ArchiveSet::const_reverse_iterator i=gOpenArchives.rbegin(); i!=gOpenArchives.rend();++i) { HANDLE fileHandle; if (!SFileOpenFileEx(*i, mpq_name, SFILE_OPEN_PATCHED_FILE, &fileHandle)) continue; if (SFileGetFileSize(fileHandle, NULL) == 0) // some files removed in next updates and its reported size 0 { SFileCloseFile(fileHandle); return true; } SFileCloseFile(fileHandle); if (!SFileExtractFile(*i, mpq_name, filename.c_str(), SFILE_OPEN_PATCHED_FILE)) { printf("Can't extract file: %s\n", mpq_name); return false; } return true; } printf("Extracting file not found: %s\n", filename.c_str()); return false; }
static int MPQ_stat(void *opaque, const char *filename, PHYSFS_Stat *stat) { char *filename2 = NULL; HANDLE hFile; char success; DWORD fileSize = 0; if (!opaque) return 0; filename2 = MPQ_getValidFilename(filename); if (!filename2) return 0; success = SFileOpenFileEx(((MPQHandle *)opaque)->mpqHandle, filename2, 0, &hFile); allocator.Free(filename2); if (!success) return 0; SFileGetFileInfo(hFile, SFileInfoFileSize, &fileSize, sizeof(fileSize), NULL); stat->filesize = fileSize; stat->modtime = 0; SFileGetFileInfo(hFile, SFileInfoFileTime, &stat->modtime, sizeof(stat->modtime), NULL); stat->createtime = stat->modtime; stat->accesstime = 0; stat->filetype = PHYSFS_FILETYPE_REGULAR; stat->readonly = 1; /* .MPQ files are always read only */ SFileCloseFile(hFile); return 1; }
MPQFile::MPQFile(const char* filename): eof(false), buffer(0), pointer(0), size(0) { for(ArchiveSet::const_iterator i=gOpenArchives.archives.begin(); i!=gOpenArchives.archives.end();++i) { HANDLE hFile = ""; hMPQ = i->hMPQ; BOOL succ = SFileOpenFileEx(hMPQ,filename,0, &hFile); if (succ) { DWORD s = SFileGetFileSize(hFile, 0); if (!s) { eof = true; buffer = 0; return; } size = (size_t)s; buffer = new char[s]; SFileReadFile(hFile, buffer, s, 0, 0); SFileCloseFile(hFile); eof = false; return; } } eof = true; buffer = 0; }
uint32 ReadMapDBC(int const locale) { HANDLE localeFile; char localMPQ[512]; sprintf(localMPQ, "%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]); if (!SFileOpenArchive(localMPQ, 0, MPQ_OPEN_READ_ONLY, &localeFile)) exit(1); printf("Read Map.dbc file... "); HANDLE dbcFile; if (!SFileOpenFileEx(localeFile, "DBFilesClient\\Map.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) { printf("Fatal error: Cannot find Map.dbc in archive!\n"); exit(1); } DBCFile dbc(dbcFile); if(!dbc.open()) { printf("Fatal error: Invalid Map.dbc file format!\n"); exit(1); } size_t map_count = dbc.getRecordCount(); map_ids = new map_id[map_count]; for(uint32 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("Done! (%u maps loaded)\n", map_count); return map_count; }
uint32 ReadMapDBC() { printf("Read Map.dbc file... "); HANDLE dbcFile; if (!SFileOpenFileEx(LocaleMpq, "DBFilesClient\\Map.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) { printf("Fatal error: Cannot find Map.dbc in archive!\n"); exit(1); } DBCFile dbc(dbcFile); if (!dbc.open()) { printf("Fatal error: Invalid Map.dbc file format!\n"); exit(1); } size_t map_count = dbc.getRecordCount(); map_ids = new map_id[map_count]; for(uint32 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)); } SFileCloseFile(dbcFile); printf("Done! (%u maps loaded)\n", map_count); return map_count; }
bool FileLoader::loadFile(HANDLE mpq, char* filename, bool log) { free(); HANDLE file; if (!SFileOpenFileEx(mpq, filename, SFILE_OPEN_PATCHED_FILE, &file)) { if (log) printf("No such file %s\n", filename); return false; } data_size = SFileGetFileSize(file, NULL); data = new uint8[data_size]; if (data) { SFileReadFile(file, data, data_size, NULL/*bytesRead*/, NULL); if (prepareLoadedData()) { SFileCloseFile(file); return true; } } printf("Error loading %s\n", filename); SFileCloseFile(file); free(); return false; }
void ReadLiquidTypeTableDBC(int const locale) { HANDLE localeFile; char localMPQ[512]; sprintf(localMPQ, "%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]); if (!SFileOpenArchive(localMPQ, 0, MPQ_OPEN_READ_ONLY, &localeFile)) exit(1); printf("Read LiquidType.dbc file..."); HANDLE dbcFile; if (!SFileOpenFileEx(localeFile, "DBFilesClient\\LiquidType.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) { printf("Fatal error: Cannot find LiquidType.dbc in archive!\n"); exit(1); } DBCFile dbc(dbcFile); if(!dbc.open()) { printf("Fatal error: Invalid LiquidType.dbc file format!\n"); exit(1); } size_t LiqType_count = dbc.getRecordCount(); size_t LiqType_maxid = dbc.getMaxId(); LiqType = new uint16[LiqType_maxid + 1]; memset(LiqType, 0xff, (LiqType_maxid + 1) * sizeof(uint16)); for(uint32 x = 0; x < LiqType_count; ++x) LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); printf("Done! (%u LiqTypes loaded)\n", LiqType_count); }
static int IsMatchingPatchFile( TMPQArchive * ha, const char * szFileName, unsigned char * pbFileMd5) { MPQ_PATCH_HEADER PatchHeader = {0}; void * hFile = NULL; size_t dwTransferred = 0; int bResult = 0; /* Open the file and load the patch header */ if(SFileOpenFileEx((void *)ha, szFileName, SFILE_OPEN_BASE_FILE, &hFile)) { /* Load the patch header */ SFileReadFile(hFile, &PatchHeader, sizeof(MPQ_PATCH_HEADER), &dwTransferred); BSWAP_ARRAY32_UNSIGNED(pPatchHeader, sizeof(uint32_t) * 6); /* If the file contains an incremental patch, */ /* compare the "MD5 before patching" with the base file MD5 */ if(dwTransferred == sizeof(MPQ_PATCH_HEADER) && PatchHeader.dwSignature == PATCH_SIGNATURE_HEADER) bResult = (!memcmp(PatchHeader.md5_before_patch, pbFileMd5, MD5_DIGEST_SIZE)); /* Close the file */ SFileCloseFile(hFile); } return bResult; }
static bool IsMatchingPatchFile( TMPQArchive * ha, const char * szFileName, LPBYTE pbFileMd5) { MPQ_PATCH_HEADER PatchHeader = {0}; HANDLE hFile = NULL; DWORD dwTransferred = 0; bool bResult = false; // Open the file and load the patch header if(SFileOpenFileEx((HANDLE)ha, szFileName, SFILE_OPEN_BASE_FILE, &hFile)) { // Load the patch header SFileReadFile(hFile, &PatchHeader, sizeof(MPQ_PATCH_HEADER), &dwTransferred, NULL); BSWAP_ARRAY32_UNSIGNED(pPatchHeader, sizeof(DWORD) * 6); // If the file contains an incremental patch, // compare the "MD5 before patching" with the base file MD5 if(dwTransferred == sizeof(MPQ_PATCH_HEADER) && PatchHeader.dwSignature == PATCH_SIGNATURE_HEADER) bResult = (!memcmp(PatchHeader.md5_before_patch, pbFileMd5, MD5_DIGEST_SIZE)); // Close the file SFileCloseFile(hFile); } return bResult; }
bool FileToBuffer(MPQHANDLE &hMpq, const std::string &fileName, buffer &buf) { if ( hMpq == nullptr ) CHKD_ERR("NULL MPQ file specified for opening %s", fileName.c_str()); else { u32 bytesRead = 0; HANDLE openFile = NULL; if ( SFileGetFileInfo(hMpq, SFILE_INFO_NUM_FILES) != 0xFFFFFFFF ) { if ( SFileOpenFileEx(hMpq, fileName.c_str(), SFILE_SEARCH_CURRENT_ONLY, &openFile) ) { u32 fileSize = (u32)SFileGetFileSize(openFile, NULL); if ( buf.setSize(fileSize) ) { buf.sizeUsed = fileSize; SFileReadFile(openFile, (LPVOID)buf.data, buf.sizeUsed, (LPDWORD)(&bytesRead), NULL); SFileCloseFile(openFile); if ( buf.sizeUsed == bytesRead ) return true; } else SFileCloseFile(openFile); } else CHKD_ERR("Failed to get %s from MPQ file", fileName.c_str()); } else CHKD_ERR("File is already open", fileName.c_str()); } return false; }
void ReadLiquidTypeTableDBC() { printf("Read LiquidType.dbc file..."); HANDLE dbcFile; if (!SFileOpenFileEx(LocaleMpq, "DBFilesClient\\LiquidType.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) { printf("Fatal error: Cannot find LiquidType.dbc in archive!\n"); exit(1); } DBCFile dbc(dbcFile); if(!dbc.open()) { printf("Fatal error: Invalid LiquidType.dbc file format!\n"); exit(1); } size_t liqTypeCount = dbc.getRecordCount(); size_t liqTypeMaxId = dbc.getMaxId(); LiqType = new uint16[liqTypeMaxId + 1]; memset(LiqType, 0xff, (liqTypeMaxId + 1) * sizeof(uint16)); for(uint32 x = 0; x < liqTypeCount; ++x) LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); SFileCloseFile(dbcFile); printf("Done! (%u LiqTypes loaded)\n", liqTypeCount); }
BOOL __stdcall _SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile) { /* Store the name of the last-opened file to retrieve the pointer once it's allocated */ lastFile = szFileName; if ( !phFile ) return FALSE; if ( !SFileOpenFileEx(NULL, szFileName, SFILE_FROM_ABSOLUTE | SFILE_FROM_RELATIVE, phFile) || !(*phFile) ) { if ( _SFileOpenFileExOld ) return _SFileOpenFileExOld(hMpq, szFileName, dwSearchScope, phFile); return SFileOpenFileEx(hMpq, szFileName, dwSearchScope, phFile); } return TRUE; }
void ReadAreaTableDBC() { printf("Read AreaTable.dbc file..."); HANDLE dbcFile; if (!SFileOpenFileEx(LocaleMpq, "DBFilesClient\\AreaTable.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) { printf("Fatal error: Cannot find AreaTable.dbc in archive!\n"); exit(1); } DBCFile dbc(dbcFile); if(!dbc.open()) { printf("Fatal error: Invalid AreaTable.dbc file format!\n"); exit(1); } size_t area_count = dbc.getRecordCount(); maxAreaId = dbc.getMaxId(); areas = new uint16[maxAreaId + 1]; for (uint32 x = 0; x < area_count; ++x) areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); SFileCloseFile(dbcFile); printf("Done! (%u areas loaded)\n", area_count); }
BOOL WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const char * szExtracted) { HANDLE hLocalFile = INVALID_HANDLE_VALUE; HANDLE hMpqFile = NULL; DWORD dwSearchScope = 0; int nError = ERROR_SUCCESS; // Open the MPQ file if(nError == ERROR_SUCCESS) { if((DWORD_PTR)szToExtract <= 0x10000) dwSearchScope = SFILE_OPEN_BY_INDEX; if(!SFileOpenFileEx(hMpq, szToExtract, dwSearchScope, &hMpqFile)) nError = GetLastError(); } // Create the local file if(nError == ERROR_SUCCESS) { hLocalFile = CreateFile(szExtracted, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); if(hLocalFile == INVALID_HANDLE_VALUE) nError = GetLastError(); } // Copy the file's content if(nError == ERROR_SUCCESS) { char szBuffer[0x1000]; DWORD dwTransferred; for(;;) { // dwTransferred is only set to nonzero if something has been read. // nError can be ERROR_SUCCESS or ERROR_HANDLE_EOF if(!SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL)) nError = GetLastError(); if(nError == ERROR_HANDLE_EOF) nError = ERROR_SUCCESS; if(dwTransferred == 0) break; // If something has been actually read, write it WriteFile(hLocalFile, szBuffer, dwTransferred, &dwTransferred, NULL); if(dwTransferred == 0) nError = ERROR_DISK_FULL; } } // Close the files if(hMpqFile != NULL) SFileCloseFile(hMpqFile); if(hLocalFile != INVALID_HANDLE_VALUE) CloseHandle(hLocalFile); if(nError != ERROR_SUCCESS) SetLastError(nError); return (BOOL)(nError == ERROR_SUCCESS); }
BOOL WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags) { crc32_context crc32_ctx; md5_context md5_ctx; TMPQFile * hf; TMPQCRC32 Crc32; TMPQMD5 Md5; BYTE Buffer[0x1000]; HANDLE hFile = NULL; DWORD dwBytesRead; BOOL bResult = TRUE; // Attempt to open the file if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile)) { // Initialize the CRC32 and MD5 counters CRC32_Init(&crc32_ctx); MD5_Init(&md5_ctx); hf = (TMPQFile *)hFile; // Go through entire file and update both CRC32 and MD5 for(;;) { // Read data from file SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL); if(dwBytesRead == 0) break; // Update CRC32 value if(dwFlags & MPQ_ATTRIBUTE_CRC32) CRC32_Update(&crc32_ctx, Buffer, (int)dwBytesRead); // Update MD5 value if(dwFlags & MPQ_ATTRIBUTE_MD5) MD5_Update(&md5_ctx, Buffer, (int)dwBytesRead); } // Check if the CRC32 matches if((dwFlags & MPQ_ATTRIBUTE_CRC32) && hf->pCrc32 != NULL) { CRC32_Finish(&crc32_ctx, (unsigned long *)&Crc32.dwValue); if(Crc32.dwValue != hf->pCrc32->dwValue) bResult = FALSE; } // Check if MD5 matches if((dwFlags & MPQ_ATTRIBUTE_MD5) && hf->pMd5 != NULL) { MD5_Finish(&md5_ctx, Md5.Value); if(memcmp(Md5.Value, hf->pMd5->Value, sizeof(TMPQMD5))) bResult = FALSE; } SFileCloseFile(hFile); } return bResult; }
// copied from contrib/extractor/System.cpp void ReadLiquidTypeTableDBC() { HANDLE localeFile; char localMPQ[1024]; snprintf(localMPQ, sizeof(localMPQ), "%smisc.MPQ", input_path); if (FileExists(localMPQ)==false) { // Use misc.mpq printf(localMPQ, "%s/Data/%s/locale-%s.MPQ", input_path); } if (!SFileOpenArchive(localMPQ, 0, MPQ_OPEN_READ_ONLY, &localeFile)) { exit(1); } printf("Read LiquidType.dbc file..."); HANDLE dbcFile; if (!SFileOpenFileEx(localeFile, "DBFilesClient\\LiquidType.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) { if (!SFileOpenFileEx(localeFile, "DBFilesClient\\LiquidType.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) { printf("Fatal error: Cannot find LiquidType.dbc in archive!\n"); exit(1); } } DBCFile dbc(localeFile, "DBFilesClient\\LiquidType.dbc"); if (!dbc.open()) { printf("Fatal error: Invalid LiquidType.dbc file format!\n"); exit(1); } size_t LiqType_count = dbc.getRecordCount(); size_t LiqType_maxid = dbc.getMaxId(); LiqType = new uint16[LiqType_maxid + 1]; memset(LiqType, 0xff, (LiqType_maxid + 1) * sizeof(uint16)); for (size_t x = 0; x < LiqType_count; ++x) LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); printf("Done! (%zu LiqTypes loaded)\n", LiqType_count); }
bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope) { TMPQArchive * ha = IsValidMpqHandle(hMpq); TMPQFile * hf = NULL; int nError = ERROR_SUCCESS; // Keep compiler happy dwSearchScope = dwSearchScope; // Check the parameters if(ha == NULL) nError = ERROR_INVALID_HANDLE; if(szFileName == NULL || *szFileName == 0) nError = ERROR_INVALID_PARAMETER; if(IsInternalMpqFileName(szFileName)) nError = ERROR_INTERNAL_FILE; // Do not allow to remove files from read-only or patched MPQs if(nError == ERROR_SUCCESS) { if((ha->dwFlags & MPQ_FLAG_READ_ONLY) || (ha->haPatch != NULL)) nError = ERROR_ACCESS_DENIED; } // If all checks have passed, we can delete the file from the MPQ if(nError == ERROR_SUCCESS) { // Open the file from the MPQ if(SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_BASE_FILE, (HANDLE *)&hf)) { // Delete the file entry nError = DeleteFileEntry(ha, hf); FreeFileHandle(hf); } else nError = GetLastError(); } // If the file has been deleted, we need to invalidate // the internal files and recreate HET table if(nError == ERROR_SUCCESS) { // Invalidate the entries for internal files // After we are done with MPQ changes, we need to re-create them anyway InvalidateInternalFiles(ha); // // Don't rebuild HET table now; the file's flags indicate // that it's been deleted, which is enough // } // Resolve error and exit if(nError != ERROR_SUCCESS) SetLastError(nError); return (nError == ERROR_SUCCESS); }
BOOL WINAPI SFileOpenFileEx_stub(MPQHANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, MPQHANDLE *hFile) { LoadSFMpqDll(); if (hSFMpq) { *(FARPROC *)&SFileOpenFileEx = GetProcAddress(hSFMpq,"SFileOpenFileEx"); if (SFileOpenFileEx) return SFileOpenFileEx(hMPQ,lpFileName,dwSearchScope,hFile); } return FALSE; }
IMpkFileManip* MpkManip::openFile(const char* filename) { if(!hasFile(filename))return 0; HANDLE hFile = 0; if(!SFileOpenFileEx(m_hMpk,filename,0,&hFile))return 0; return new MpkFileManip(hFile); }
MPQStream::MPQStream(MPQ* mpq, const String& path) : handle(nullptr) { if (mpq == nullptr || mpq->GetHandle() == nullptr) return; HANDLE internalHandle = NULL; if (SFileOpenFileEx(mpq->GetHandle(), path.CStr(), SFILE_OPEN_FROM_MPQ, &internalHandle)) handle = internalHandle; }
static PHYSFS_Io *MPQ_openRead(void *opaque, const char *filename) { char *filename2 = NULL; HANDLE hFile; PHYSFS_Io *retval = NULL; MPQFileHandle *handle = NULL; DWORD dwFileSizeHi = 0xCCCCCCCC; DWORD dwFileSizeLo = 0; char success; if (!opaque) return NULL; filename2 = MPQ_getValidFilename(filename); if (!filename2) return NULL; success = SFileOpenFileEx(((MPQHandle *)opaque)->mpqHandle, filename2, 0, &hFile); allocator.Free(filename2); if (!success) return NULL; retval = (PHYSFS_Io *)allocator.Malloc(sizeof(PHYSFS_Io)); if (!retval) { SFileCloseFile(hFile); return NULL; } handle = (MPQFileHandle *)allocator.Malloc(sizeof(MPQFileHandle)); if (!handle) { allocator.Free(retval); SFileCloseFile(hFile); return NULL; } dwFileSizeLo = SFileGetFileSize(hFile, &dwFileSizeHi); if (dwFileSizeLo == SFILE_INVALID_SIZE || dwFileSizeHi != 0) { allocator.Free(retval); allocator.Free(hFile); SFileCloseFile(hFile); return NULL; } handle->fileHandle = hFile; handle->size = (PHYSFS_sint64)dwFileSizeLo; memcpy(retval, &MPQ_Io, sizeof(PHYSFS_Io)); retval->opaque = handle; return retval; }
// Used in SFileGetFileInfo bool QueryMpqSignatureInfo( TMPQArchive * ha, PMPQ_SIGNATURE_INFO pSI) { ULONGLONG ExtraBytes; TMPQFile * hf; HANDLE hFile; DWORD dwFileSize; // Make sure it's all zeroed memset(pSI, 0, sizeof(MPQ_SIGNATURE_INFO)); // Calculate the range of the MPQ CalculateArchiveRange(ha, pSI); // If there is "(signature)" file in the MPQ, it has a weak signature if(SFileOpenFileEx((HANDLE)ha, SIGNATURE_NAME, SFILE_OPEN_BASE_FILE, &hFile)) { // Get the content of the signature SFileReadFile(hFile, pSI->Signature, sizeof(pSI->Signature), &pSI->cbSignatureSize, NULL); // Verify the size of the signature hf = (TMPQFile *)hFile; // We have to exclude the signature file from the digest pSI->BeginExclude = ha->MpqPos + hf->pFileEntry->ByteOffset; pSI->EndExclude = pSI->BeginExclude + hf->pFileEntry->dwCmpSize; dwFileSize = hf->dwDataSize; // Close the file SFileCloseFile(hFile); pSI->SignatureTypes |= SIGNATURE_TYPE_WEAK; return (dwFileSize == (MPQ_WEAK_SIGNATURE_SIZE + 8)) ? true : false; } // If there is extra bytes beyond the end of the archive, // it's the strong signature ExtraBytes = pSI->EndOfFile - pSI->EndMpqData; if(ExtraBytes >= (MPQ_STRONG_SIGNATURE_SIZE + 4)) { // Read the strong signature if(!FileStream_Read(ha->pStream, &pSI->EndMpqData, pSI->Signature, (MPQ_STRONG_SIGNATURE_SIZE + 4))) return false; // Check the signature header "NGIS" if(pSI->Signature[0] != 'N' || pSI->Signature[1] != 'G' || pSI->Signature[2] != 'I' || pSI->Signature[3] != 'S') return false; pSI->SignatureTypes |= SIGNATURE_TYPE_STRONG; return true; } // Succeeded, but no known signature found return true; }
bool OpenNewestFile(char const* filename, HANDLE* fileHandlerPtr) { for(ArchiveSet::const_reverse_iterator i=gOpenArchives.rbegin(); i!=gOpenArchives.rend();++i) { // always prefer get updated file version if (SFileOpenFileEx(*i, filename, SFILE_OPEN_PATCHED_FILE, fileHandlerPtr)) return true; } return false; }
FAFile* FAfopen(const std::string& filename) { bfs::path path(filename); path.make_preferred(); if(!bfs::exists(filename)) { int nError = ERROR_SUCCESS; if(diabdat == NULL && !SFileOpenArchive(getMPQFileName().c_str(), 0, STREAM_FLAG_READ_ONLY, &diabdat)) nError = GetLastError(); if(nError != ERROR_SUCCESS) { std::cerr << "Failed to open " << DIABDAT_MPQ << std::endl; return NULL; } std::string stormPath = getStormLibPath(path); if(!SFileHasFile(diabdat, stormPath.c_str())) { std::cerr << "File " << path << " not found" << std::endl; return NULL; } FAFile* file = new FAFile(); file->data.mpqFile = malloc(sizeof(HANDLE)); if(!SFileOpenFileEx(diabdat, stormPath.c_str(), 0, (HANDLE*)file->data.mpqFile)) { std::cerr << "Failed to open " << filename << " in " << DIABDAT_MPQ; delete file; return NULL; } file->mode = FAFile::MPQFile; return file; } else { FILE* plainFile = fopen(filename.c_str(), "rb"); if(plainFile == NULL) return NULL; FAFile* file = new FAFile(); file->mode = FAFile::PlainFile; file->data.plainFile.file = plainFile; file->data.plainFile.filename = new std::string(filename); return file; } }
bool DBCFile::open() { if (!SFileOpenFileEx(_mpq, _filename, SFILE_OPEN_PATCHED_FILE, &_file)) return false; char header[4]; unsigned int na, nb, es, ss; DWORD readBytes = 0; SFileReadFile(_file, header, 4, &readBytes, NULL); if (readBytes != 4) // Number of records return false; if (header[0] != 'W' || header[1] != 'D' || header[2] != 'B' || header[3] != 'C') return false; readBytes = 0; SFileReadFile(_file, &na, 4, &readBytes, NULL); if (readBytes != 4) // Number of records return false; readBytes = 0; SFileReadFile(_file, &nb, 4, &readBytes, NULL); if (readBytes != 4) // Number of fields return false; readBytes = 0; SFileReadFile(_file, &es, 4, &readBytes, NULL); if (readBytes != 4) // Size of a record return false; readBytes = 0; SFileReadFile(_file, &ss, 4, &readBytes, NULL); if (readBytes != 4) // String size return false; _recordSize = es; _recordCount = na; _fieldCount = nb; _stringSize = ss; if (_fieldCount * 4 != _recordSize) return false; _data = new unsigned char[_recordSize * _recordCount + _stringSize]; _stringTable = _data + _recordSize*_recordCount; size_t data_size = _recordSize * _recordCount + _stringSize; readBytes = 0; SFileReadFile(_file, _data, data_size, &readBytes, NULL); if (readBytes != data_size) return false; return true; }
//------------------------------------------ GET MAP HASH -------------------------------------------------- std::string Map::getMapHash() { unsigned char hash[20]; char hexstring[42]; std::string filename = Map::getPathName(); // Open File HANDLE hFile = NULL; if ( !SFileOpenFileEx(NULL, filename.c_str(), SFILE_FROM_ABSOLUTE, &hFile) || !hFile) { char szPath[MAX_PATH]; SStrCopy(szPath, filename.c_str(), MAX_PATH); SStrNCat(szPath, "\\staredit\\scenario.chk", MAX_PATH); if ( !SFileOpenFileEx(NULL, szPath, SFILE_FROM_MPQ, &hFile) || !hFile) return std::string("Error_map_cannot_be_opened"); } // Obtain file size DWORD dwFileSize = SFileGetFileSize(hFile, 0); // Allocate memory void *pBuffer = SMAlloc(dwFileSize); if ( !pBuffer ) { SFileCloseFile(hFile); return std::string("Error_could_not_allocate_memory"); } // Read file DWORD dwBytesRead = 0; SFileReadFile(hFile, pBuffer, dwFileSize, &dwBytesRead, 0); // Calculate hash sha1::calc(pBuffer, dwBytesRead, hash); sha1::toHexString(hash, hexstring); // Free memory and return SMFree(pBuffer); SFileCloseFile(hFile); return string(hexstring); }
void CMpqDataStream::Open(CString filename) { SFileOpenFileEx(m_hMpq, filename.c_str(), SFILE_OPEN_FROM_MPQ, &m_hFile); if (m_hFile == NULL) { // do something ... } m_nSize = SFileGetFileSize(m_hFile, 0); m_pByte = new byte[m_nSize]; Read(m_pByte, m_nSize); }
bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const char * szExtracted, DWORD dwSearchScope) { TFileStream * pLocalFile = NULL; HANDLE hMpqFile = NULL; int nError = ERROR_SUCCESS; // Open the MPQ file if (nError == ERROR_SUCCESS) { if(!SFileOpenFileEx(hMpq, szToExtract, dwSearchScope, &hMpqFile)) nError = GetLastError(); } // Create the local file if (nError == ERROR_SUCCESS) { pLocalFile = FileStream_CreateFile(szExtracted); if(pLocalFile == NULL) nError = GetLastError(); } // Copy the file's content if (nError == ERROR_SUCCESS) { char szBuffer[0x1000]; DWORD dwTransferred; for (;;) { // dwTransferred is only set to nonzero if something has been read. // nError can be ERROR_SUCCESS or ERROR_HANDLE_EOF if (!SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL)) nError = GetLastError(); if (nError == ERROR_HANDLE_EOF) nError = ERROR_SUCCESS; if (dwTransferred == 0) break; // If something has been actually read, write it if (!FileStream_Write(pLocalFile, NULL, szBuffer, dwTransferred)) nError = GetLastError(); } } // Close the files if (hMpqFile != NULL) SFileCloseFile(hMpqFile); if (pLocalFile != NULL) FileStream_Close(pLocalFile); if (nError != ERROR_SUCCESS) SetLastError(nError); return (nError == ERROR_SUCCESS); }