| 463 | |
| 464 | |
| 465 | static DWORD ReadMpqFileSectorFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwBytesToRead, LPDWORD pdwBytesRead) |
| 466 | { |
| 467 | TMPQArchive * ha = hf->ha; |
| 468 | LPBYTE pbBuffer = (BYTE *)pvBuffer; |
| 469 | DWORD dwTotalBytesRead = 0; // Total bytes read in all three parts |
| 470 | DWORD dwSectorSizeMask = ha->dwSectorSize - 1; // Mask for block size, usually 0x0FFF |
| 471 | DWORD dwFileSectorPos; // File offset of the loaded sector |
| 472 | DWORD dwBytesRead; // Number of bytes read (temporary variable) |
| 473 | DWORD dwErrCode; |
| 474 | |
| 475 | // If the file position is at or beyond end of file, do nothing |
| 476 | if(dwFilePos >= hf->dwDataSize) |
| 477 | { |
| 478 | *pdwBytesRead = 0; |
| 479 | return ERROR_SUCCESS; |
| 480 | } |
| 481 | |
| 482 | // If not enough bytes in the file remaining, cut them |
| 483 | if(dwBytesToRead > (hf->dwDataSize - dwFilePos)) |
| 484 | dwBytesToRead = (hf->dwDataSize - dwFilePos); |
| 485 | |
| 486 | // Compute sector position in the file |
| 487 | dwFileSectorPos = dwFilePos & ~dwSectorSizeMask; // Position in the block |
| 488 | |
| 489 | // If the file sector buffer is not allocated yet, do it now |
| 490 | if(hf->pbFileSector == NULL) |
| 491 | { |
| 492 | dwErrCode = AllocateSectorBuffer(hf); |
| 493 | if(dwErrCode != ERROR_SUCCESS || hf->pbFileSector == NULL) |
| 494 | return dwErrCode; |
| 495 | } |
| 496 | |
| 497 | // Load the first (incomplete) file sector |
| 498 | if(dwFilePos & dwSectorSizeMask) |
| 499 | { |
| 500 | DWORD dwBytesInSector = ha->dwSectorSize; |
| 501 | DWORD dwBufferOffs = dwFilePos & dwSectorSizeMask; |
| 502 | DWORD dwToCopy; |
| 503 | |
| 504 | // Is the file sector already loaded ? |
| 505 | if(hf->dwSectorOffs != dwFileSectorPos) |
| 506 | { |
| 507 | // Load one MPQ sector into archive buffer |
| 508 | dwErrCode = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesInSector); |
| 509 | if(dwErrCode != ERROR_SUCCESS) |
| 510 | return dwErrCode; |
| 511 | |
| 512 | // Remember that the data loaded to the sector have new file offset |
| 513 | hf->dwSectorOffs = dwFileSectorPos; |
| 514 | } |
| 515 | else |
| 516 | { |
| 517 | if((dwFileSectorPos + dwBytesInSector) > hf->dwDataSize) |
| 518 | dwBytesInSector = hf->dwDataSize - dwFileSectorPos; |
| 519 | } |
| 520 | |
| 521 | // Copy the data from the offset in the loaded sector to the end of the sector |
| 522 | dwToCopy = dwBytesInSector - dwBufferOffs; |
no test coverage detected