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; }
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; }
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 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; }
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; }
size_t FAfread(void * ptr, size_t size, size_t count, FAFile* stream) { switch(stream->mode) { case FAFile::PlainFile: return fread(ptr, size, count, stream->data.plainFile.file); case FAFile::MPQFile: { std::lock_guard<std::mutex> lock(m); DWORD dwBytes = 1; if(!SFileReadFile(*((HANDLE*)stream->data.mpqFile), ptr, size*count, &dwBytes, NULL)) { int errorCode = GetLastError(); // if the error code is ERROR_HANDLE_EOF, it's not really an error, // we just requested a read that goes over the end of the file. // The normal fread behaviour in this case is to truncate the read to fit within // the file, and return the actual number of bytes read, which we do, // so there is no need to print an error message. if(errorCode != ERROR_HANDLE_EOF) std::cout << "Error reading from file, error code: " << errorCode << std::endl; } return dwBytes; } } return 0; }
static int LoadMpqPatch_COPY(TMPQFile * hf, TPatchHeader * pPatchHeader) { int nError = ERROR_SUCCESS; // Allocate space for patch header and compressed data hf->pPatchHeader = (TPatchHeader *)ALLOCMEM(BYTE, pPatchHeader->dwSizeOfPatchData); if(hf->pPatchHeader == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; // Load the patch data and decide if they are compressed or not if(nError == ERROR_SUCCESS) { LPBYTE pbPatchFile = (LPBYTE)hf->pPatchHeader; // Copy the patch header itself memcpy(pbPatchFile, pPatchHeader, sizeof(TPatchHeader)); pbPatchFile += sizeof(TPatchHeader); // Load the rest of the patch if(!SFileReadFile((HANDLE)hf, pbPatchFile, pPatchHeader->dwSizeOfPatchData - sizeof(TPatchHeader))) nError = GetLastError(); } return nError; }
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; }
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); }
static int LoadMpqPatch_BSD0(TMPQFile * hf, TPatchHeader * pPatchHeader) { LPBYTE pbDecompressed = NULL; LPBYTE pbCompressed = NULL; DWORD cbDecompressed = 0; DWORD cbCompressed = 0; DWORD dwBytesRead = 0; int nError = ERROR_SUCCESS; // Allocate space for compressed data cbCompressed = pPatchHeader->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER; pbCompressed = ALLOCMEM(BYTE, cbCompressed); if(pbCompressed == NULL) nError = ERROR_SUCCESS; // Read the compressed patch data if(nError == ERROR_SUCCESS) { // Load the rest of the header SFileReadFile((HANDLE)hf, pbCompressed, cbCompressed, &dwBytesRead); if(dwBytesRead != cbCompressed) nError = ERROR_FILE_CORRUPT; } // Get the uncompressed size of the patch if(nError == ERROR_SUCCESS) { cbDecompressed = pPatchHeader->dwSizeOfPatchData - sizeof(TPatchHeader); hf->pPatchHeader = (TPatchHeader *)ALLOCMEM(BYTE, pPatchHeader->dwSizeOfPatchData); if(hf->pPatchHeader == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; } // Now decompress the patch data if(nError == ERROR_SUCCESS) { // Copy the patch header memcpy(hf->pPatchHeader, pPatchHeader, sizeof(TPatchHeader)); pbDecompressed = (LPBYTE)hf->pPatchHeader + sizeof(TPatchHeader); // Uncompress or copy the patch data if(cbCompressed < cbDecompressed) { Decompress_RLE(pbDecompressed, cbDecompressed, pbCompressed, cbCompressed); } else { assert(cbCompressed == cbDecompressed); memcpy(pbDecompressed, pbCompressed, cbCompressed); } } // Free buffers and exit if(pbCompressed != NULL) FREEMEM(pbCompressed); return nError; }
static int LoadFilePatch_COPY(TMPQFile * hf, PMPQ_PATCH_HEADER pFullPatch) { DWORD cbBytesToRead = pFullPatch->dwSizeOfPatchData - sizeof(MPQ_PATCH_HEADER); DWORD cbBytesRead = 0; // Simply load the rest of the patch SFileReadFile((HANDLE)hf, (pFullPatch + 1), cbBytesToRead, &cbBytesRead, NULL); return (cbBytesRead == cbBytesToRead) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT; }
BOOL WINAPI SFileReadFile_stub(MPQHANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped) { LoadSFMpqDll(); if (hSFMpq) { *(FARPROC *)&SFileReadFile = GetProcAddress(hSFMpq,"SFileReadFile"); if (SFileReadFile) return SFileReadFile(hFile,lpBuffer,nNumberOfBytesToRead,lpNumberOfBytesRead,lpOverlapped); } return FALSE; }
static int LoadFilePatch_COPY(TMPQFile * hf, PMPQ_PATCH_HEADER pFullPatch) { size_t cbBytesToRead = pFullPatch->dwSizeOfPatchData - sizeof(MPQ_PATCH_HEADER); size_t cbBytesRead = 0; /* Simply load the rest of the patch */ SFileReadFile((void *)hf, (pFullPatch + 1), cbBytesToRead, &cbBytesRead); return (cbBytesRead == cbBytesToRead) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT; }
static int LoadFilePatch_BSD0(TMPQFile * hf, PMPQ_PATCH_HEADER pFullPatch) { unsigned char * pbDecompressed = (unsigned char *)(pFullPatch + 1); unsigned char * pbCompressed = NULL; size_t cbDecompressed = 0; size_t cbCompressed = 0; size_t dwBytesRead = 0; int nError = ERROR_SUCCESS; /* Calculate the size of compressed data */ cbDecompressed = pFullPatch->dwSizeOfPatchData - sizeof(MPQ_PATCH_HEADER); cbCompressed = pFullPatch->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER; /* Is that file compressed? */ if(cbCompressed < cbDecompressed) { pbCompressed = STORM_ALLOC(uint8_t, cbCompressed); if(pbCompressed == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; /* Read the compressed patch data */ if(nError == ERROR_SUCCESS) { SFileReadFile((void *)hf, pbCompressed, cbCompressed, &dwBytesRead); if(dwBytesRead != cbCompressed) nError = ERROR_FILE_CORRUPT; } /* Decompress the data */ if(nError == ERROR_SUCCESS) Decompress_RLE(pbDecompressed, cbDecompressed, pbCompressed, cbCompressed); if(pbCompressed != NULL) STORM_FREE(pbCompressed); } else { SFileReadFile((void *)hf, pbDecompressed, cbDecompressed, &dwBytesRead); if(dwBytesRead != cbDecompressed) nError = ERROR_FILE_CORRUPT; } return nError; }
static int LoadFilePatch_BSD0(TMPQFile * hf, PMPQ_PATCH_HEADER pFullPatch) { LPBYTE pbDecompressed = (LPBYTE)(pFullPatch + 1); LPBYTE pbCompressed = NULL; DWORD cbDecompressed = 0; DWORD cbCompressed = 0; DWORD dwBytesRead = 0; int nError = ERROR_SUCCESS; // Calculate the size of compressed data cbDecompressed = pFullPatch->dwSizeOfPatchData - sizeof(MPQ_PATCH_HEADER); cbCompressed = pFullPatch->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER; // Is that file compressed? if(cbCompressed < cbDecompressed) { pbCompressed = STORM_ALLOC(BYTE, cbCompressed); if(pbCompressed == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; // Read the compressed patch data if(nError == ERROR_SUCCESS) { SFileReadFile((HANDLE)hf, pbCompressed, cbCompressed, &dwBytesRead, NULL); if(dwBytesRead != cbCompressed) nError = ERROR_FILE_CORRUPT; } // Decompress the data if(nError == ERROR_SUCCESS) Decompress_RLE(pbDecompressed, cbDecompressed, pbCompressed, cbCompressed); if(pbCompressed != NULL) STORM_FREE(pbCompressed); } else { SFileReadFile((HANDLE)hf, pbDecompressed, cbDecompressed, &dwBytesRead, NULL); if(dwBytesRead != cbDecompressed) nError = ERROR_FILE_CORRUPT; } return nError; }
int MPQStream::Read(void* buffer, int size) { if (handle == nullptr || size <= 0) return 0; DWORD readBytes = 0; SFileReadFile(handle, buffer, size, &readBytes, nullptr); return static_cast<int>(readBytes); }
// 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 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); }
uint32 ReadBuild(int locale) { // include build info file also std::string filename = std::string("component.wow-")+langs[locale]+".txt"; //printf("Read %s file... ", filename.c_str()); HANDLE fileHandle; if (!OpenNewestFile(filename.c_str(), &fileHandle)) { printf("Fatal error: Not found %s file!\n", filename.c_str()); exit(1); } unsigned int data_size = SFileGetFileSize(fileHandle); std::string text; text.resize(data_size); if (!SFileReadFile(fileHandle, &text[0], data_size)) { printf("Fatal error: Can't read %s file!\n", filename.c_str()); exit(1); } SFileCloseFile(fileHandle); size_t pos = text.find("version=\""); size_t pos1 = pos + strlen("version=\""); size_t pos2 = text.find("\"",pos1); if (pos == text.npos || pos2 == text.npos || pos1 >= pos2) { printf("Fatal error: Invalid %s file format!\n", filename.c_str()); exit(1); } std::string build_str = text.substr(pos1,pos2-pos1); int build = atoi(build_str.c_str()); if (build <= 0) { printf("Fatal error: Invalid %s file format!\n", filename.c_str()); exit(1); } if (build < MIN_SUPPORTED_BUILD) { printf("Fatal error: tool can correctly extract data only for build %u or later (detected: %u)!\n", MIN_SUPPORTED_BUILD, build); exit(1); } return build; }
static TListFileCache * CreateListFileCache(HANDLE hListFile, const char * szMask) { TListFileCache * pCache = NULL; size_t nMaskLength = 0; DWORD dwBytesRead = 0; DWORD dwFileSize; // Get the amount of bytes that need to be allocated dwFileSize = SFileGetFileSize(hListFile, NULL); if(dwFileSize == 0) return NULL; // Append buffer for name mask, if any if(szMask != NULL) nMaskLength = strlen(szMask) + 1; // Allocate cache for one file block pCache = (TListFileCache *)STORM_ALLOC(BYTE, sizeof(TListFileCache)); if(pCache != NULL) { // Clear the entire structure memset(pCache, 0, sizeof(TListFileCache) + nMaskLength); // Shall we copy the mask? if(szMask != NULL) { pCache->szMask = (char *)(pCache + 1); memcpy(pCache->szMask, szMask, nMaskLength); } // Load the file cache from the file SFileReadFile(hListFile, pCache->Buffer, CACHE_BUFFER_SIZE, &dwBytesRead, NULL); if(dwBytesRead != 0) { // Allocate pointers pCache->pBegin = pCache->pPos = &pCache->Buffer[0]; pCache->pEnd = pCache->pBegin + dwBytesRead; pCache->dwFileSize = dwFileSize; pCache->hFile = hListFile; } else { FreeListFileCache(pCache); pCache = NULL; } } // Return the cache return pCache; }
ULONG64 CMPQFileAccessor::Read(LPVOID pBuff,ULONG64 Size) { if(m_hFile) { DWORD ReadSize; if(SFileReadFile(m_hFile,pBuff,Size,&ReadSize)) return ReadSize; } else if(m_pRealFSFile) { return m_pRealFSFile->Read(pBuff,Size); } return 0; }
size_t FAfread(void * ptr, size_t size, size_t count, FAFile* stream) { switch(stream->mode) { case FAFile::PlainFile: return fread(ptr, size, count, stream->data.plainFile.file); case FAFile::MPQFile: DWORD dwBytes = 1; SFileReadFile(*((HANDLE*)stream->data.mpqFile), ptr, size*count, &dwBytes, NULL); return dwBytes; } return 0; }
int SC2Map::readArchiveFile( const HANDLE archive, const char* strFilename, int* bufferOutSize, u8** bufferOut ) { HANDLE hFile; if( !SFileOpenFileEx( archive, strFilename, 0, &hFile ) ) { //printWarning( "Could not open %s for reading.\n", strFilename ); return -1; } DWORD fileSizeBytes = SFileGetFileSize( hFile, NULL ); if( fileSizeBytes == SFILE_INVALID_SIZE || fileSizeBytes <= 0 ) { printWarning( "%s is empty or invalid.\n", strFilename ); return -1; } u8* buffer = new u8[fileSizeBytes]; DWORD numBytesRead; // initialize buffer to easily recognized values, // after a successful read all of them are overwritten memset( buffer, 'q', fileSizeBytes ); if( !SFileReadFile( hFile, (void*)buffer, fileSizeBytes, &numBytesRead, NULL ) ) { delete buffer; printWarning( "Could not read %s from archive.\n", strFilename ); return -1; } if( numBytesRead != fileSizeBytes ) { delete buffer; printWarning( "Could not read %s from archive. [NOT EXPECTING TO SEE THIS WARNING!]\n", strFilename ); return -1; } *bufferOutSize = fileSizeBytes; *bufferOut = buffer; SFileCloseFile( hFile ); return 0; }
int ExtractFileToHardDrive(HANDLE &MPQ_handle, const char * szArchivedFile, const char * szFileName) { HANDLE hFile = NULL; // Archived file handle TFileStream* handle = NULL; // Disk file handle int nError = ERROR_SUCCESS; // Result value if (nError == ERROR_SUCCESS) { if (!SFileOpenFileEx(MPQ_handle, szArchivedFile, SFILE_OPEN_PATCHED_FILE, &hFile)) nError = GetLastError(); } // Create the target file if (nError == ERROR_SUCCESS) { handle = FileStream_CreateFile(szFileName); if (handle == NULL) nError = GetLastError(); } // Read the file from the archive if (nError == ERROR_SUCCESS) { // Get the size of the full patched file DWORD dwFileSize = SFileGetFileSize(hFile, NULL); if (dwFileSize != 0) { // Allocate space for the full file BYTE * pbFullFile = new BYTE[dwFileSize]; if (!SFileReadFile(hFile, pbFullFile, dwFileSize)) { nError = GetLastError(); printf("Failed to read full patched file data \"%s\"\n", szFileName); assert(false); } FileStream_Write(handle, NULL, pbFullFile, dwFileSize); delete [] pbFullFile; } } // Cleanup and exit if (handle != NULL) FileStream_Close(handle); if (hFile != NULL) SFileCloseFile(hFile); return nError; }
size_t FAfread(void * ptr, size_t size, size_t count, FAFile* stream) { switch(stream->mode) { case FAFile::PlainFile: return fread(ptr, size, count, stream->data.plainFile.file); case FAFile::MPQFile: DWORD dwBytes = 1; if(!SFileReadFile(*((HANDLE*)stream->data.mpqFile), ptr, size*count, &dwBytes, NULL)) std::cout << "Error reading from file" << std::endl; return dwBytes; } return 0; }
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; }
MPQFile::MPQFile(HANDLE mpq, const char* filename, bool warnNoExist /*= true*/) : eof(false), buffer(0), pointer(0), size(0) { HANDLE file; if (!SFileOpenFileEx(mpq, filename, SFILE_OPEN_PATCHED_FILE, &file)) { if (warnNoExist || GetLastError() != ERROR_FILE_NOT_FOUND) fprintf(stderr, "Can't open %s, err=%u!\n", filename, GetLastError()); eof = true; return; } DWORD hi = 0; size = SFileGetFileSize(file, &hi); if (hi) { fprintf(stderr, "Can't open %s, size[hi] = %u!\n", filename, uint32(hi)); SFileCloseFile(file); eof = true; return; } if (size <= 1) { fprintf(stderr, "Can't open %s, size = %u!\n", filename, uint32(size)); SFileCloseFile(file); eof = true; return; } DWORD read = 0; buffer = new char[size]; if (!SFileReadFile(file, buffer, size, &read) || size != read) { fprintf(stderr, "Can't read %s, size=%u read=%u!\n", filename, uint32(size), uint32(read)); SFileCloseFile(file); eof = true; return; } SFileCloseFile(file); }
static PHYSFS_sint64 MPQ_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len) { MPQFileHandle *handle = (MPQFileHandle*)io->opaque; DWORD dwBytesRead; DWORD dwBytesToRead; if (len < (PHYSFS_uint64)handle->size) dwBytesToRead = (DWORD)len; else dwBytesToRead = (DWORD)handle->size; SFileReadFile(handle->fileHandle, buf, dwBytesToRead, &dwBytesRead, NULL); if (dwBytesRead != dwBytesToRead) return -1L; return (PHYSFS_sint64)dwBytesRead; }
uint32 ReadBuild(int locale) { // include build info file also std::string filename = std::string("component.wow-") + Locales[locale] + ".txt"; //printf("Read %s file... ", filename.c_str()); HANDLE dbcFile; if (!SFileOpenFileEx(LocaleMpq, filename.c_str(), SFILE_OPEN_PATCHED_FILE, &dbcFile)) { printf("Fatal error: Not found %s file!\n", filename.c_str()); exit(1); } char buff[512]; DWORD readBytes = 0; SFileReadFile(dbcFile, buff, 512, &readBytes, NULL); if (!readBytes) { printf("Fatal error: Not found %s file!\n", filename.c_str()); exit(1); } std::string text = buff; SFileCloseFile(dbcFile); size_t pos = text.find("version=\""); size_t pos1 = pos + strlen("version=\""); size_t pos2 = text.find("\"", pos1); if (pos == text.npos || pos2 == text.npos || pos1 >= pos2) { printf("Fatal error: Invalid %s file format!\n", filename.c_str()); exit(1); } std::string build_str = text.substr(pos1,pos2-pos1); int build = atoi(build_str.c_str()); if (build <= 0) { printf("Fatal error: Invalid %s file format!\n", filename.c_str()); exit(1); } return build; }