hf - MPQ File handle. pbBuffer - Pointer to target buffer to store sectors. dwByteOffset - Position of sector in the file (relative to file begin) dwBytesToRead - Number of bytes to read. Must be multiplier of sector size. pdwBytesRead - Stored number of bytes loaded
| 22 | // dwBytesToRead - Number of bytes to read. Must be multiplier of sector size. |
| 23 | // pdwBytesRead - Stored number of bytes loaded |
| 24 | static int ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DWORD dwBytesToRead, LPDWORD pdwBytesRead) |
| 25 | { |
| 26 | ULONGLONG RawFilePos; |
| 27 | TMPQArchive * ha = hf->ha; |
| 28 | TFileEntry * pFileEntry = hf->pFileEntry; |
| 29 | LPBYTE pbRawSector = NULL; |
| 30 | LPBYTE pbOutSector = pbBuffer; |
| 31 | LPBYTE pbInSector = pbBuffer; |
| 32 | DWORD dwRawBytesToRead; |
| 33 | DWORD dwRawSectorOffset = dwByteOffset; |
| 34 | DWORD dwSectorsToRead = dwBytesToRead / ha->dwSectorSize; |
| 35 | DWORD dwSectorIndex = dwByteOffset / ha->dwSectorSize; |
| 36 | DWORD dwSectorsDone = 0; |
| 37 | DWORD dwBytesRead = 0; |
| 38 | int nError = ERROR_SUCCESS; |
| 39 | |
| 40 | // Note that dwByteOffset must be aligned to size of one sector |
| 41 | // Note that dwBytesToRead must be a multiplier of one sector size |
| 42 | // This is local function, so we won't check if that's true. |
| 43 | // Note that files stored in single units are processed by a separate function |
| 44 | |
| 45 | // If there is not enough bytes remaining, cut dwBytesToRead |
| 46 | if((dwByteOffset + dwBytesToRead) > hf->dwDataSize) |
| 47 | dwBytesToRead = hf->dwDataSize - dwByteOffset; |
| 48 | dwRawBytesToRead = dwBytesToRead; |
| 49 | |
| 50 | // Perform all necessary work to do with compressed files |
| 51 | if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) |
| 52 | { |
| 53 | // If the sector positions are not loaded yet, do it |
| 54 | if(hf->SectorOffsets == NULL) |
| 55 | { |
| 56 | nError = AllocateSectorOffsets(hf, true); |
| 57 | if(nError != ERROR_SUCCESS || hf->SectorOffsets == NULL) |
| 58 | return nError; |
| 59 | } |
| 60 | |
| 61 | // If the sector checksums are not loaded yet, load them now. |
| 62 | if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->bLoadedSectorCRCs == false) |
| 63 | { |
| 64 | // |
| 65 | // Sector CRCs is plain crap feature. It is almost never present, |
| 66 | // often it's empty, or the end offset of sector CRCs is zero. |
| 67 | // We only try to load sector CRCs once, and regardless if it fails |
| 68 | // or not, we won't try that again for the given file. |
| 69 | // |
| 70 | |
| 71 | AllocateSectorChecksums(hf, true); |
| 72 | hf->bLoadedSectorCRCs = true; |
| 73 | } |
| 74 | |
| 75 | // TODO: If the raw data MD5s are not loaded yet, load them now |
| 76 | // Only do it if the MPQ is of format 4.0 |
| 77 | // if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4 && ha->pHeader->dwRawChunkSize != 0) |
| 78 | // { |
| 79 | // nError = AllocateRawMD5s(hf, true); |
| 80 | // if(nError != ERROR_SUCCESS) |
| 81 | // return nError; |
no test coverage detected