| 365 | } |
| 366 | |
| 367 | static DWORD ReadMpkFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) |
| 368 | { |
| 369 | ULONGLONG RawFilePos = hf->RawFilePos + 0x0C; // For some reason, MPK files start at position (hf->RawFilePos + 0x0C) |
| 370 | TMPQArchive * ha = hf->ha; |
| 371 | TFileEntry * pFileEntry = hf->pFileEntry; |
| 372 | LPBYTE pbCompressed = NULL; |
| 373 | LPBYTE pbRawData = hf->pbFileSector; |
| 374 | DWORD dwErrCode = ERROR_SUCCESS; |
| 375 | |
| 376 | // We do not support patch files in MPK archives |
| 377 | assert(hf->pPatchInfo == NULL); |
| 378 | |
| 379 | // If the file buffer is not allocated yet, do it. |
| 380 | if(hf->pbFileSector == NULL) |
| 381 | { |
| 382 | dwErrCode = AllocateSectorBuffer(hf); |
| 383 | if(dwErrCode != ERROR_SUCCESS || hf->pbFileSector == NULL) |
| 384 | return dwErrCode; |
| 385 | pbRawData = hf->pbFileSector; |
| 386 | } |
| 387 | |
| 388 | // If the file sector is not loaded yet, do it |
| 389 | if(hf->dwSectorOffs != 0) |
| 390 | { |
| 391 | // Is the file compressed? |
| 392 | if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) |
| 393 | { |
| 394 | // Allocate space for compressed data |
| 395 | pbCompressed = STORM_ALLOC(BYTE, pFileEntry->dwCmpSize); |
| 396 | if(pbCompressed == NULL) |
| 397 | return ERROR_NOT_ENOUGH_MEMORY; |
| 398 | pbRawData = pbCompressed; |
| 399 | } |
| 400 | |
| 401 | // Load the raw (compressed, encrypted) data |
| 402 | if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize)) |
| 403 | { |
| 404 | STORM_FREE(pbCompressed); |
| 405 | return GetLastError(); |
| 406 | } |
| 407 | |
| 408 | // If the file is encrypted, we have to decrypt the data first |
| 409 | if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) |
| 410 | { |
| 411 | DecryptMpkTable(pbRawData, pFileEntry->dwCmpSize); |
| 412 | } |
| 413 | |
| 414 | // If the file is compressed, we have to decompress it now |
| 415 | if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) |
| 416 | { |
| 417 | int cbOutBuffer = (int)hf->dwDataSize; |
| 418 | |
| 419 | hf->dwCompression0 = pbRawData[0]; |
| 420 | if(!SCompDecompressMpk(hf->pbFileSector, &cbOutBuffer, pbRawData, (int)pFileEntry->dwCmpSize)) |
| 421 | dwErrCode = ERROR_FILE_CORRUPT; |
| 422 | } |
| 423 | else |
| 424 | { |
no test coverage detected