| 1516 | } |
| 1517 | |
| 1518 | static bool PartStream_LoadBitmap(TBlockStream * pStream) |
| 1519 | { |
| 1520 | PPART_FILE_MAP_ENTRY FileBitmap; |
| 1521 | PART_FILE_HEADER PartHdr; |
| 1522 | ULONGLONG ByteOffset = 0; |
| 1523 | ULONGLONG StreamSize = 0; |
| 1524 | DWORD BlockCount; |
| 1525 | DWORD BitmapSize; |
| 1526 | |
| 1527 | // Only if the size is greater than size of the bitmap header |
| 1528 | if(pStream->Base.File.FileSize > sizeof(PART_FILE_HEADER)) |
| 1529 | { |
| 1530 | // Attempt to read PART file header |
| 1531 | if(pStream->BaseRead(pStream, &ByteOffset, &PartHdr, sizeof(PART_FILE_HEADER))) |
| 1532 | { |
| 1533 | // We need to swap PART file header on big-endian platforms |
| 1534 | BSWAP_ARRAY32_UNSIGNED(&PartHdr, sizeof(PART_FILE_HEADER)); |
| 1535 | |
| 1536 | // Verify the PART file header |
| 1537 | if(IsPartHeader(&PartHdr)) |
| 1538 | { |
| 1539 | // Get the number of blocks and size of one block |
| 1540 | StreamSize = MAKE_OFFSET64(PartHdr.FileSizeHi, PartHdr.FileSizeLo); |
| 1541 | ByteOffset = sizeof(PART_FILE_HEADER); |
| 1542 | BlockCount = (DWORD)((StreamSize + PartHdr.BlockSize - 1) / PartHdr.BlockSize); |
| 1543 | BitmapSize = BlockCount * sizeof(PART_FILE_MAP_ENTRY); |
| 1544 | |
| 1545 | // Check if sizes match |
| 1546 | if((ByteOffset + BitmapSize) < pStream->Base.File.FileSize) |
| 1547 | { |
| 1548 | // Allocate space for the array of PART_FILE_MAP_ENTRY |
| 1549 | FileBitmap = CASC_ALLOC<PART_FILE_MAP_ENTRY>(BlockCount); |
| 1550 | if(FileBitmap != NULL) |
| 1551 | { |
| 1552 | // Load the block map |
| 1553 | if(!pStream->BaseRead(pStream, &ByteOffset, FileBitmap, BitmapSize)) |
| 1554 | { |
| 1555 | CASC_FREE(FileBitmap); |
| 1556 | return false; |
| 1557 | } |
| 1558 | |
| 1559 | // Make sure that the byte order is correct |
| 1560 | BSWAP_ARRAY32_UNSIGNED(FileBitmap, BitmapSize); |
| 1561 | |
| 1562 | // Update the stream size |
| 1563 | pStream->BuildNumber = StringToInt(PartHdr.GameBuildNumber); |
| 1564 | pStream->StreamSize = StreamSize; |
| 1565 | |
| 1566 | // Fill the bitmap information |
| 1567 | pStream->FileBitmap = FileBitmap; |
| 1568 | pStream->BitmapSize = BitmapSize; |
| 1569 | pStream->BlockSize = PartHdr.BlockSize; |
| 1570 | pStream->BlockCount = BlockCount; |
| 1571 | pStream->IsComplete = PartStream_CheckFile(pStream); |
| 1572 | return true; |
| 1573 | } |
| 1574 | } |
| 1575 | } |
no test coverage detected