Skip to main content

Module hfsplus_wrapper_clone

Module hfsplus_wrapper_clone 

Source
Expand description

Wrapper-aware HFS+ defrag clone.

Classic Mac OS 8.x/9.x volumes store an HFS+ volume embedded inside an HFS wrapper: the outer Apple_HFS partition is itself a classic HFS volume whose MDB has drEmbedSigWord == 0x482B/0x4858, with drEmbedExtent pointing at a contiguous range of outer allocation blocks that hold a real HFS+ volume. Mac OS 8.1+ reads the MDB, jumps straight to the inner HFS+, and mounts it; pre-8.1 systems mount the outer HFS and see a “Where_have_all_my_files_gone?” read-me file.

stream_defragmented_hfsplus only handles flat HFS+ (no wrapper). stream_wrapped_defragmented_hfsplus in this module wraps that with the surrounding HFS shell:

+---- new wrapper partition ----+
| boot blocks (verbatim)        |
| primary MDB (patched)         |
| volume bitmap (patched)       |
| wrapper alloc blocks 0..S-1   |  (verbatim from source — holds the
|   ("read-me" file + B-trees)  |   wrapper's catalog/extents, untouched)
| embedded extent (S..S+N-1)    |  ← stream_defragmented_hfsplus output
|   = new flat HFS+ volume      |
| alt MDB (patched mirror)      |
| reserved last sector          |
+-------------------------------+

where S = drEmbedExtent.startBlock (unchanged from source) and N = ceil(target_inner_size / drAlBlkSiz) (smaller than the source’s embedded extent). drNmAlBlks shrinks to S + N and the wrapper’s internal catalog/extents B-trees are preserved byte-for-byte because their allocation blocks all lie in [0..S) and stay at the same source byte offsets.

Structs§

WrappedClonePlan
Plan for emitting a shrunken wrapped HFS+ volume. All sizes are bytes unless noted.
WrappedHfsPlusInfo
Fields parsed from the outer HFS wrapper MDB that the clone pipeline needs to rebuild the wrapper around a shrunken inner volume.

Enums§

WrappedCloneError

Functions§

detect_wrapped_hfsplus
Probe the wrapper MDB at partition_offset + 1024 and return the parsed wrapper info iff it’s a classic HFS volume with an embedded HFS+/HFSX. Returns None for any other layout (flat HFS+, native HFS, non-HFS, parse errors).
detect_wrapped_hfsplus_at
Same as detect_wrapped_hfsplus but reads the MDB sector via positioned I/O (std::os::unix::fs::FileExt::read_at on Unix, [std::os::windows::fs::FileExt::seek_read] on Windows). Use this from any context that shares the underlying file descriptor across threads — try_clone() on Unix uses dup(), which shares the kernel-level seek offset, so concurrent seek + read callers can clobber each other and return the wrong partition’s MDB. Positioned reads carry the offset in the syscall itself and don’t touch the shared cursor, so they’re safe under any amount of fd sharing.
plan_wrapped_clone
Build a WrappedClonePlan sized for a shrunken inner HFS+ volume.
stream_wrapped_defragmented_hfsplus
Stream a shrunken wrapped HFS+ volume to dst. Single-pass; no seeks required on the writer.