View Single Post
  #104  
Old Yesterday, 16:02
BLACKFIRE69's Avatar
BLACKFIRE69 BLACKFIRE69 is offline
Registered User
 
Join Date: Mar 2019
Location: In the Hell
Posts: 692
Thanks: 481
Thanked 2,553 Times in 563 Posts
BLACKFIRE69 is on a distinguished road
Arrow CLS-DiskSpan v2.0

CLS·DiskSpan v2.0
Reliability + Performance Overhaul for FreeArc Disk-Spanning
Windows · 32-bit plugin · built on Razor12911's original · modified by BLACKFIRE69

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━

▌ OVERVIEW
A big reliability + speed overhaul of Razor12911's original FreeArc disk-spanning plugin. The plugin splits a FreeArc archive across multiple volumes (discs) and reassembles them on extraction.

⚠ Matched-pair release: the on-disk volume format changed (clean break). Archives written by v2.0 are unpacked by v2.0 only — v2.0 will not read old volumes, and the old version will not read v2.0 volumes.

▌ TECHNICAL SPECIFICATIONS
  • Version — v2.0
  • Built with — RAD Studio 13.1
  • Platform — Windows, 32-bit
  • Targets — FreeArc 0.67 (March 15 2014)
  • Disc format — self-describing v2 volumes: a "set GUID" shared by every disc of one archive, plus a CRC32 on every disc
  • I/O buffer — 1 MB default; override with env var CLS_BUFKB (KB, clamped 64 KB .. 64 MB)
  • Debug log — OFF by default; set env var CLS_DEBUG_LOG=1 to append diagnostics to cls-diskspan.log next to the DLL

▌ CREDITS / AUTHORS
  • Original — Razor12911
  • v2.0 overhaul — BLACKFIRE69

▌ WHAT'S NEW IN v2.0

✦ It just works for EVERY layout
Solid (-s;), non-solid (-s-), big/small solid blocks (-s<size>), and file-mask / grouped packs (arc.groups) all span and round-trip correctly. The old "must be fully solid" limitation — where anything else silently produced broken discs — is GONE.

✦ Mixed group sizes are flagged
With file-mask groups, all groups share ONE volume set, so only a single disc size is used (the first block's). A group asking for a different size is kept-and-warned once — the set still packs/unpacks fine. Use the same size on every group.

✦ Damage is caught
Every disc carries a CRC32 and shares a "set GUID". A truncated, byte-flipped, swapped, or foreign disc is detected and reported instead of silently producing a bad install.

✦ No more hangs or crashes
A missing disc in a silent/hidden run fails cleanly with a non-zero exit (never freezes on a hidden dialog), and no Delphi error can crash back into FreeArc — failures map to proper CLS error codes.

✦ Safe inside installers
The --sort / --makeiso / --version helpers only run under FreeArc's Arc.exe; embedded in an Inno Setup installer (unarc) the DLL never touches the host process, so it can't accidentally close the installer.

✦ You see the REAL reason a span failed
On a bad decode FreeArc otherwise prints only its own misleading line. diskspan now prints the true cause first, on its own line — e.g. "diskspan: missing volume game-3.bin" or "diskspan: CRC mismatch ...".

✦ An archive kept in a subfolder extracts correctly
Sibling discs are found next to the main archive, not in the current directory — so arc t out\game-1.bin works (the real conversion flow packs into a subfolder).

✦ The disc-tools are reliable
--sort lays the discs into burnable DISC_1, DISC_2 … folders (with autorun.inf + setup files) and exits cleanly. --makeiso turns those folders into .ISO images without freezing; a folder is deleted ONLY after its ISO is safely written, so a failing oscdimg.exe can never destroy your discs.

✦ Flexible disc naming (auto-detected — no new option)
Code:
game-1.bin      ->  game-2.bin,  game-3.bin       (classic digit step)
data.bin.001    ->  data.bin.002, data.bin.003    (numbered extension)
setup-1a.bin    ->  setup-1b.bin ... 1z, 1aa      (letters per disc, number fixed)
Put a number in the name. If you forget, it still works, but extra discs get plain names (game_002.bin …) and you get a reminder at pack time.

✦ Locate-a-missing-disc
In an interactive run (installer window OR plain console arc x), a Browse dialog lets the user point to a disc that isn't where expected, then the extract continues. Silent/hidden/redirected runs just fail cleanly.

✦ It's faster
The per-disc checksum was rewritten (slicing-by-8) and I/O runs in 1 MB chunks (tunable), cutting spanning overhead from ~+96% over a raw store down to ~+20%. At real multi-GB disc sizes the compressor dominates anyway, so spanning is effectively free.

✦ Version probe
arc.exe --version prints build, disc-format version and copyright; the DiskSpanInfo() export returns the same string to tools.

▌ ORIGINAL vs MODIFIED (v1 → v2.0)
Code:
╭───────────────────────────┬────────────────────────┬────────────────────────────────╮
│ Area                      │ Original (v1)          │ Modified (v2.0)                │
├───────────────────────────┼────────────────────────┼────────────────────────────────┤
│ Solid archives            │ OKOK                             │
│ Non-solid (-s-)           │ SILENT CORRUPTIONOK                             │
│ Small blocks (-s<size>)   │ SILENT CORRUPTIONOK                             │
│ File masks / arc.groups   │ unsupported / corruptOK                             │
│ Mixed group sizes         │ SILENT CORRUPTIONOK (first size wins + warns)   │
│ Archive in a subfolder    │ extract could failOK                             │
│ Per-volume integrity      │ noneCRC32 (header + payload)       │
│ Wrong / foreign volume    │ used blindlyrejected (set GUID)            │
│ Missing volume (hidden)   │ could hang on dialogclean nonzero exit             │
│ Missing volume (UI)       │ host prompt only       │ browse (UI or console)         │
│ Failure reason shown      │ FreeArc generic only   │ + diskspan's real reason       │
│ Disc-1 size budget        │ per solid block        │ shared across all blocks       │
│ Error across DLL boundary │ could crash FreeArcmapped to CLS error codes      │
│ Volume naming             │ digit substitution     │ Type 1 / 2 / 3 (auto)          │
│ Non-numbered name         │ silent _NNN fallback   │ warns at pack time             │
│ --sort exit code          │ wrong ("unknown cmd")clean exit 0                   │
│ --makeiso                 │ hung after first ISObuilds all, safe delete        │
│ CRC speed                 │ n/a (no CRC)slicing-by-8 (~20% over)       │
│ Copy buffer               │ 64 KB                  │ 1 MB (tunable, CLS_BUFKB)      │
│ Version/copyright probe   │ none--version + DiskSpanInfo()     │
│ Build toolchain           │ older Delphi           │ RAD Studio 13.1, Win32         │
│ Compiler warnings         │ several                │ zero (clean build)             │
╰───────────────────────────┴────────────────────────┴────────────────────────────────╯
▌ EXPORTED API FUNCTIONS
  • ClsInit — host hands over the source path + a parent-window handle (used by Inno Setup installers)
  • ClsFunc1 (ClsSourcePath) — host sets/updates the folder to read sibling discs (2, 3 …) from
  • ClsFunc2 (ClsDiskRequest) — host installs a callback diskspan can call to ask the user to "insert the next disc"
  • DiskSpanInfo — extra (not called by FreeArc): returns build + format-version + copyright so any tool can identify the DLL

▌ QUICK START EXAMPLES
Run from the folder holding Arc.exe + cls-diskspan.dll. -w sets a temp folder; diskspan:<first>:<other> = first-disc size : every other disc's size. Put a NUMBER in the archive name.
Legend: program · command · method / diskspan · archive · input mask

Show the build + copyright
Code:
Arc.exe --version
Pack + split — one solid block, no compression (fast smoke test)
Code:
Arc.exe a -ep1 -r -ed -s; -w.\temp -m0+diskspan:2mb:2mb out\game-1.bin "_data\*"
Pack + split — REAL compression (put diskspan LAST in the chain)
Code:
Arc.exe a -ep1 -r -ed -s; -w.\temp -msrep+lzma+diskspan:4467mb:4474mb out\game-1.bin "MyFiles\*"
Pack + split — NON-solid (-s-, every file its own block — the old silent-corruption case, now correct)
Code:
Arc.exe a -ep1 -r -ed -s- -w.\temp -m0+diskspan:2mb:2mb out\game-1.bin "_data\*"
Pack + split — SMALL solid blocks (-s<size>, e.g. 8 MB blocks)
Code:
Arc.exe a -ep1 -r -ed -s8m -w.\temp -m0+diskspan:2mb:2mb out\game-1.bin "_data\*"
Pack + split — file-MASK groups (end each group's method with diskspan so every group spans)
Code:
Arc.exe a -ep1 -r -ed -s; -w.\temp -mtor+diskspan:2mb:2mb/$grpbin=lzma+diskspan:2mb:2mb out\game-1.bin "_data\*"
Test the disc set (reads every disc + checks each disc's CRC)
Code:
Arc.exe t out\game-1.bin
Extract
Code:
Arc.exe x -dpunpacked\ out\game-1.bin
Lay discs into burnable folders, then build one ISO per folder
Code:
Arc.exe --sort    OutFolder DISC_ setup.exe setup.ico out\game-1.bin
Arc.exe --makeiso OutFolder\DISC_
Pick a naming style just by how you name the first disc
Code:
Arc.exe a ... +diskspan:300mb:400mb data.bin.001 "MyFiles\*"   (-> .002, .003)
Arc.exe a ... +diskspan:300mb:400mb setup-1a.bin "MyFiles\*"   (-> 1b, 1c, ...)
Tuning / diagnostics (env vars, optional)
Code:
setlocal & set CLS_BUFKB=4096   & Arc.exe ...   (4 MB I/O buffer instead of 1 MB)
setlocal & set CLS_DEBUG_LOG=1  & Arc.exe ...   (write cls-diskspan.log next to the DLL)
Ready-to-run, double-clickable versions of all of the above are in bin\_examples\_demo\ — start with 00_version.bat.

▌ TESTS & BENCHMARKS
Both live in bin\_test\ and drive the same Arc.exe + cls-diskspan.dll in bin\.

run_tests.ps1 — round-trip regression suite. Packs 8 scenarios (solid, single-volume, store, groups, non-solid, small-block, groups+blocks, many-volume), extracts each, and SHA-256 compares against the originals. Plus 3 robustness checks: a missing middle disc must fail cleanly, a byte-flipped disc must be caught by the CRC, and a subfolder archive must still round-trip. Prints a PASS/FAIL matrix.
Code:
powershell -ExecutionPolicy Bypass -File run_tests.ps1 -DebugLog
bench.ps1 — throughput benchmark. Uses a STORE method (-m0) on purpose, so timing reflects the spanning engine + disk I/O, not a compressor. Packs/extracts at three I/O buffer sizes (CLS_BUFKB = 64 / 1024 / 4096 KB), verifies SHA-256 each time, and prints encode/decode MB/s per buffer size.
Code:
powershell -ExecutionPolicy Bypass -File bench.ps1 -SizeMB 120
▌ DISTRIBUTION FILES
  • cls-diskspan.dll — REQUIRED. The plugin. Drop it next to Arc.exe.
  • Arc.exe — REQUIRED. FreeArc's command-line driver (ships in bin\).
  • oscdimg.exe — Optional. Only for --makeiso; must sit next to Arc.exe.
  • arc.ini — Optional. FreeArc method config (example in bin\).
  • arc.groups — Optional. File-grouping masks (example in bin\).

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━

▌ A NOTE FROM THE MODDER
I'm not quite a repack guy, so do some rough tests on this with your own data and feel free to report any bug / issue.


.
Attached Images
File Type: png e1.png (108.7 KB, 10 views)
File Type: png e2.png (80.1 KB, 10 views)
File Type: png e3.png (207.9 KB, 10 views)
File Type: png e4.png (269.4 KB, 10 views)
File Type: png e5.png (107.2 KB, 10 views)
File Type: png xa.png (6.2 KB, 10 views)
File Type: png xb.png (19.5 KB, 10 views)
File Type: png xc.png (19.7 KB, 10 views)
File Type: png xd.png (254.3 KB, 10 views)
File Type: png xe.png (14.4 KB, 10 views)
Attached Files
File Type: rar cls-diskspan v2.0 + Examples.rar (2.73 MB, 4 views)

Last edited by BLACKFIRE69; Today at 03:24. Reason: Modified the description
Reply With Quote
The Following 3 Users Say Thank You to BLACKFIRE69 For This Useful Post:
audiofeel (Yesterday), Ele (Yesterday), Razor12911 (Today)