* NAME: block->size() * DESCRIPTION: return the number of physical blocks on a volume's medium */
| 761 | * DESCRIPTION: return the number of physical blocks on a volume's medium |
| 762 | */ |
| 763 | unsigned long b_size(hfsvol *vol) |
| 764 | { |
| 765 | unsigned long low, high, mid; |
| 766 | block b; |
| 767 | |
| 768 | high = os_seek(&vol->priv, -1); |
| 769 | |
| 770 | if (high != (unsigned long) -1 && high > 0) |
| 771 | return high; |
| 772 | |
| 773 | /* manual size detection: first check there is at least 1 block in medium */ |
| 774 | |
| 775 | if (b_readpb(vol, 0, &b, 1) == -1) |
| 776 | ERROR(EIO, "size of medium indeterminable or empty"); |
| 777 | |
| 778 | for (low = 0, high = 2880; |
| 779 | high > 0 && b_readpb(vol, high - 1, &b, 1) != -1; |
| 780 | high <<= 1) |
| 781 | low = high - 1; |
| 782 | |
| 783 | if (high == 0) |
| 784 | ERROR(EIO, "size of medium indeterminable or too large"); |
| 785 | |
| 786 | /* common case: 1440K floppy */ |
| 787 | |
| 788 | if (low == 2879 && b_readpb(vol, 2880, &b, 1) == -1) |
| 789 | return 2880; |
| 790 | |
| 791 | /* binary search for other sizes */ |
| 792 | |
| 793 | while (low < high - 1) |
| 794 | { |
| 795 | mid = (low + high) >> 1; |
| 796 | |
| 797 | if (b_readpb(vol, mid, &b, 1) == -1) |
| 798 | high = mid; |
| 799 | else |
| 800 | low = mid; |
| 801 | } |
| 802 | |
| 803 | return low + 1; |
| 804 | |
| 805 | fail: |
| 806 | return 0; |
| 807 | } |
no test coverage detected