Hfsinspect
An open-source HFS+ filesystem explorer and debugger (in the spirit of hfsdebug)
Install / Use
/learn @ahknight/HfsinspectREADME
hfsinspect
An open-source HFS+ filesystem explorer and debugger (in the spirit of hfsdebug)
This program is a work-in-progress and is quite buggy in its current state. That said, it's read-only and can display some really interesting information already so have a run with it, help where you can, and file some suggestions on the site.
https://github.com/ahknight/hfsinspect
Quick Guide
$ git clone https://github.com/ahknight/hfsinspect.git
$ cd hfsinspect
$ make
$ [sudo] make install # PREFIX defaults to /usr/local; for somewhere else do: PREFIX=/home/you make -e install
Once built and the product located, go ahead and hit "hfsinspect --help" for a quick blurb about the options.
Building on Linux
You'll need the @uuid-dev@ package for the @libuuid@ headers (in Ubuntu at least). I've tested a lot of the app in Linux but there are occassional issues with some disks and files so if you run into them please file a detailed issue or, if you can, submit a fix.
Building on BSD
Haven't tried. Please do and report back. As it works on OS X and Linux I would hope it functions on at least FreeBSD.
Testing in VitualBox
One thing to note when testing in VirtualBox is that it doesn't pass-through SSE4 instructions by default, so only the software CRC32C path can be tested. As of VirtualBox 4.3.8, however, there is a semi-hidden option to enable this:
VBoxManage setextradata "VM name" VBoxInternal/CPUM/SSE4.1 1
VBoxManage setextradata "VM name" VBoxInternal/CPUM/SSE4.2 1
Examples
$ hfsinspect -d ./fstest -P /
# Record ID 1 (2/20) (offset 124; length: 32) (Node 1)
Catalog Key
+-----------------------------------------------------------------------------------+
| length | parentID | length | nodeName |
| 6 | 2 | 0 | |
+-----------------------------------------------------------------------------------+
recordType = kHFSPlusFolderThreadRecord
reserved = 0
parentID = 1
nodeName = "FS Test" (7)
$ hfsinspect -d ./fstest -l -P /
Listing for FS Test
CNID kind mode user group data rsrc name
18 folder d--------- 0 0 - - ␀␀␀␀HFS+ Private Data
19 folder dr-xr-xr-t 0 0 - - .HFS+ Private Directory Data
20 folder d-wx-wx-wt 501 20 - - .Trashes
21 folder drwx------ 501 20 - - .fseventsd
16 file ---------- 0 0 512.00 KiB 0.00 bytes .journal
17 file ---------- 0 0 4.00 KiB 0.00 bytes .journal_info_block
----------------------------------------------------------------------------------------------------
516.00 KiB 0.00 bytes
Folders: 4 Data forks: 2 Hard links: 0
Files: 2 RSRC forks: 0 Symlinks: 0
$ hfsinspect -d ./fstest -P /.journal
# Record ID 6 (7/20) (offset 676; length: 272) (Node 1)
Catalog Key
+-----------------------------------------------------------------------------------+
| length | parentID | length | nodeName |
| 22 | 2 | 8 | .journal |
+-----------------------------------------------------------------------------------+
recordType = kHFSPlusFileRecord
flags = 00000000000000000000000000000010
. kHFSThreadExistsMask
reserved1 = 0
fileID = 16
createDate = Sun May 12 00:42:42 2013 UTC
contentModDate = Sun May 12 00:42:42 2013 UTC
attributeModDate = Thu Jan 1 00:00:00 1970 UTC
accessDate = Thu Jan 1 00:00:00 1970 UTC
backupDate = Thu Jan 1 00:00:00 1970 UTC
ownerID = 0
groupID = 0
adminFlags = 000000
ownerFlags = 000000
fileMode = ----------
fileMode = 100000
. 100000 (S_IFREG)
special.linkCount = 1
fdType = 0x6A726E6C (jrnl)
fdCreator = 0x6866732B (hfs+)
fdFlags = 00000000000000000000000001010000
. kNameLocked (4096)
. kIsInvisible (16384)
fdLocation = (0, 0)
opaque = 0
textEncoding = 0
reserved2 = 0
fork = data
logicalSize = 512.00 KiB (524288 bytes)
clumpSize = 0.00 bytes (0 bytes)
totalBlocks = 512.00 KiB (128 blocks)
extents = startBlock blockCount % of file
3 128 100.00
--------------------------------------
1 extents 128 100.00
128.00 blocks per extent on average.
fork = resource
logicalSize = (empty)
$ hfsinspect -d ./fstest -v
# HFSX Volume Format (v5)
volume name = FS Test
case sensitivity = case sensitive
bootable = no
# HFS Plus Volume Header
signature = 0x4858 (HX)
version = 5
attributes = 00000000000000000000000000000000
= 00000000000000000010000000100001
. kHFSVolumeUnmountedMask (256)
. kHFSVolumeJournaledMask (8192)
. kHFSUnusedNodeFixMask (18446744071562067968)
. kHFSMDBAttributesMask (33664)
lastMountedVersion = 0x4846534A (HFSJ)
journalInfoBlock = 2
createDate = Sat May 11 19:42:41 2013 UTC
modifyDate = Sun May 12 06:24:19 2013 UTC
backupDate = Thu Jan 1 00:00:00 1970 UTC
checkedDate = Sun May 12 00:42:41 2013 UTC
fileCount = 5
folderCount = 4
blockSize = 4.00 KiB (4096 bytes)
totalBlocks = 100.00 MiB (25600 blocks)
freeBlocks = 97.13 MiB (24865 blocks)
nextAllocation = 4733
rsrcClumpSize = 64.00 KiB (65536 bytes)
dataClumpSize = 64.00 KiB (65536 bytes)
nextCatalogID = 25
writeCount = 6
encodingsBitmap = 00000000000000000000000000000000
= 00000000000000000000000000000000
= 00000000000000000000000000000000
= 00000000000000000000000000000001
. kTextEncodingMacRoman (0)
# Finder Info
bootDirID = 0 ()
bootParentID = 0 ()
openWindowDirID = 0 ()
os9DirID = 0 ()
reserved = 00000000000000000000000000000000
= 00000000000000000000000000000000
osXDirID = 0 ()
volID = 0x7EF9BE3682182A73
# Journal Info Block
flags = 00000000000000000000000000000000
= 00000000000000000000000000000001
. kJIJournalInFSMask (1)
device_signature = 0x00000000000000000000000000000000
= 0x00000000000000000000000000000000
offset = 12.00 KiB (12288 bytes)
size = 512.00 KiB (524288 bytes)
ext_jnl_uuid =
machine_serial_num =
# Allocation Bitmap File
fork = data
logicalSize = 4.00 KiB (4096 bytes)
clumpSize = 4.00 KiB (4096 bytes)
totalBlocks = 4.00 KiB (1 blocks)
extents = startBlock blockCount % of file
1 1 100.00
--------------------------------------
1 extents 1 100.00
1.00 blocks per extent on average.
# Extents Overflow File
fork = data
logicalSize = 800.00 KiB (819200 bytes)
clumpSize = 800.00 KiB (819200 bytes)
totalBlocks = 800.00 KiB (200 blocks)
extents = startBlock blockCount % of file
131 200 100.00
--------------------------------------
1 extents 200 100.00
200.00 blocks per extent on average.
# Catalog File
fork = data
logicalSize = 800.00 Ki


