From 338d13ff68666ece8e78b3bb8b12f8c0a68ef97b Mon Sep 17 00:00:00 2001 From: Robert M1 <50460704+githubrobbi@users.noreply.github.com> Date: Tue, 7 Jul 2026 15:53:20 -0700 Subject: [PATCH] docs(user-manual): document sysinfo + extract-mft, clarify status drive labels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fill the pre-rollout gaps in the capture handbook: * new "Step 0 — Discover volumes & probe the host": documents `uffs-mft sysinfo` (the capture-host probe — OS class / VSS / elevation / per-drive media, → capture_host.txt / --json) plus `drives` and `info` (previously thin coverage); * new "Extract a raw $MFT for third-party tools" subsection: `uffs-mft extract-mft --input C_mft.bin --output C.mft` for analyzeMFT / MFT2CSV interop (previously undocumented); * expanded the CLI cheat-sheet with drives / info / sysinfo / extract-mft; * intro note now lists extract-mft among the offline (any-platform) steps. Also clarify `uffs --daemon status -v`: drives are labelled by letter (live volumes by their real letter, offline .bin/.mft captures by the derived letter tagged `(file)`), explain the `[rec/names/tri/ch/ext]` tier breakdown, and note short view = aggregate, -v = per-drive, --json = {letter,records,tier}. All command/flag syntax verified against the clap CLI. Co-Authored-By: Claude Opus 4.8 --- docs/user-manual/daemon.md | 10 +++++ .../user-manual/mft-capture-verify-runbook.md | 39 ++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/docs/user-manual/daemon.md b/docs/user-manual/daemon.md index c83c529a9..e706e4d88 100644 --- a/docs/user-manual/daemon.md +++ b/docs/user-manual/daemon.md @@ -193,6 +193,16 @@ $ uffs --daemon status -v ... ``` +Each drive is labelled by its **letter** — live Windows volumes by their real +letter, and offline `.bin`/`.mft` captures by the letter derived from the file, +tagged **`(file)`** so a capture is distinguishable from a live volume. (The +source filename itself is not shown.) The trailing +`[rec=… names=… tri=… ch=… ext=…]` is the per-drive memory-tier breakdown — the +record, name-arena, trigram, child-map, and extension shard sizes. Note the +**short** view collapses this to a single count/records line; use `-v` for the +per-drive list or `--json` for the structured `{"letter","records","tier"}` +array. + > **`uffs --daemon stats` has been folded into `uffs --daemon status -v`.** > The old command now prints a one-line redirect. diff --git a/docs/user-manual/mft-capture-verify-runbook.md b/docs/user-manual/mft-capture-verify-runbook.md index 532d9ac93..193027160 100644 --- a/docs/user-manual/mft-capture-verify-runbook.md +++ b/docs/user-manual/mft-capture-verify-runbook.md @@ -10,7 +10,7 @@ on the Mac. > Design/internals: `docs/architecture/mft-full-capture.md`. > All `uffs-mft` MFT reads require **Windows, elevated (Administrator)**. The -> offline steps (`metafile-info`, `load`, `verify`) run anywhere. +> offline steps (`metafile-info`, `extract-mft`, `load`, `verify`) run anywhere. --- @@ -33,6 +33,26 @@ divergence. --- +## Step 0 — Discover volumes & probe the host + +List the NTFS volumes on the box, then record the machine and let UFFS pick the +best-effort capture strategy: + +```powershell +uffs-mft drives # list every NTFS volume (letter, format, size) +uffs-mft info --drive C # optional: live $MFT stats for one drive +uffs-mft sysinfo # host report to stdout +uffs-mft sysinfo --out capture_host.txt # also write it beside the capture +uffs-mft sysinfo --json # machine-readable (Windows only) +``` + +`sysinfo` records the **OS class** (client vs server — the VSS/shadow +discriminator), elevation, VSS availability, host resources, and every mounted +volume's media / format / size / used%. Drop `capture_host.txt` into the bundle +so the offline analyst knows exactly what host the capture came from. It is +read-only, and distinct from `uffs --daemon status` (which reports the running +daemon's health, not the capture host). + ## Step 1 — Capture (Windows, elevated) One drive (full `$MFT` + all 10 metafiles + `manifest.json` + `SHA256SUMS`): @@ -88,6 +108,19 @@ uffs-mft metafile-info --input c_secure.bin # $Secure:$SDS payload present uffs-mft metafile-info --input c_usnjrnl.bin # USN record count + sample entries ``` +### Extract a raw `$MFT` for third-party tools + +The captured `C_mft.bin` is a compressed UFFS artifact. To hand a **raw, +uncompressed `$MFT`** to tools like **analyzeMFT** or **MFT2CSV**, extract it: + +```bash +uffs-mft extract-mft --input C_mft.bin --output C.mft +``` + +`C.mft` is a byte-for-byte raw `$MFT` those tools ingest directly — no UFFS +header, no compression. (UFFS's own `load`/`verify` read the `.bin` directly, +so this step is only needed for external tooling.) + ## Step 4 — Three-way parity Export each source to CSV, then `verify`. The Rust CSV schema is identical on @@ -125,10 +158,14 @@ script on it. | Command | Purpose | Platform | |---------|---------|----------| +| `drives` | list NTFS volumes (letter, format, size) | Windows | +| `info --drive C` | live `$MFT` stats for a drive | Windows (elevated) | +| `sysinfo [--out FILE] [--json]` | probe the capture host (OS class / VSS / volumes) | any (JSON: Windows) | | `capture --drive C --out DIR` | bundle one drive | Windows (elevated) | | `capture --all-drives --out DIR` | bundle every NTFS volume | Windows (elevated) | | `capture … --zip [--split-gib N]` | pack `.tar.zst` (+split) | Windows (elevated) | | `metafile-info --input FILE` | decode one metafile | any | +| `extract-mft --input C_mft.bin --output C.mft` | raw `$MFT` for analyzeMFT / MFT2CSV | any | | `load FILE -o out.csv` | parse `$MFT` → CSV | any | | `verify --left A --right B [--columns …]` | CSV parity, exits non-zero on mismatch | any |