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