Go Back   FileForums > Game Backup > PC Games > PC Games - CD/DVD Conversions > Conversion Tutorials
Register FAQ Community Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 20-06-2026, 15:11
BLACKFIRE69's Avatar
BLACKFIRE69 BLACKFIRE69 is offline
Registered User
 
Join Date: Mar 2019
Location: In the Hell
Posts: 701
Thanks: 486
Thanked 2,610 Times in 574 Posts
BLACKFIRE69 is on a distinguished road
Arrow ISApexEx - Unified API for 7z / FreeArc / RAR Extraction and Xdelta3 Patching

ISApexEx v0.1 Beta 3
Unified Archive Extraction & Patching API for Inno Setup
7-Zip · FreeArc · RAR · Xdelta3 · HDiffPatch — one DLL · Win32 · by BLACKFIRE69

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

▌ OVERVIEW
ISApexEx is a high-performance unified library crafted for Inno Setup. It integrates five engines — 7-Zip, FreeArc, RAR, Xdelta3, and HDiffPatch — into a single DLL with seamless cross-format progress tracking. Mix and match .7z, .zip, .arc, .bf, .rar and xdelta3 / HDiff patch operations in one installer with continuous progress across all of them.

▌ TECHNICAL SPECIFICATIONS
  • Version — v0.1 Beta 2
  • Author — BLACKFIRE69
  • Build — 6A3DC100
  • File Size — 305 KB
  • Compatibility — Inno Setup v6.x or v5.x

Code:
╭──────────┬──────────┬──────────────────────┬─────────────────────────────╮
│ Engine   │ Version  │ Native DLL           │ Supported Extensions        │
├──────────┼──────────┼──────────────────────┼─────────────────────────────┤
│ 7-Zip    │ v26.10   │ 7z_32.dll            │ .7z, .zip, .7z.001/.002...  │
│ FreeArc  │ v0.67    │ UnArc_32.dll         │ .arc, .bf...                │
│ UnRAR    │ v7.22    │ UnRAR_32.dll         │ .rar, .part01.rar...        │
│ xdelta3  │ v0.1     │ xdelta3_wrapper.dll  │ .xd3, .xdelta, .vcdiff...   │
│ HDiff    │ v0.1     │ hpatchz_wrapper.dll  │ .hdiff...                   │
╰──────────┴──────────┴──────────────────────┴─────────────────────────────╯
Disk-spanning (FreeArc 'diskspan' volumes — setup-1.bin, setup-2.bin …): handled by cls-diskspan v2.0 (modified edition) natively — no ClsFunc* calls needed from your script.

▌ KEY FEATURES

✦ Unified Multi-Format Support
Handle .7z, .zip, .arc, .bf, .rar and xdelta3 / HDiff patches from one DLL. Format is auto-detected from the file extension — no manual engine selection.

✦ Top-Level AND Split / Multi-Volume Support
Every format extracts both as a single top-level archive and as a split set: 7z split volumes (.7z.001…), RAR multi-volume (.partNN.rar / .rNN), FreeArc disk-span volumes. Parts may even be scattered across different folders or discs.

✦ Universal File Browsing (Locate a Missing Archive or Part)
When ISApexEx can't find a file it needs — a top-level archive of ANY format, a 7z split part, a RAR volume, or a FreeArc spanned volume — it lets the user locate it, then resumes. Built-in native browse dialog, or your own themed dialog via ISApexExSetDiskRequestCallback (one callback covers every case).

✦ Lazy DLL Loading
Only the native engine DLLs actually needed are loaded at runtime. Using only .7z and .rar? UnArc_32.dll, xdelta3_wrapper.dll and hpatchz_wrapper.dll are never touched.

✦ Cross-Format Progress
Overall progress (0–1000) spans all registered disks regardless of format. A mixed .arc + .7z + .rar + xdelta3 + .hdiff setup shows one smooth, continuous bar.

✦ Custom Extension Mapping
Archives don't have to use standard extensions — map any extension to any engine via ISApexExRegisterExtension before adding disks.
Code:
ISApexExRegisterExtension('.bin', APEX_ARC_7Z);   // .bin -> 7z engine
ISApexExRegisterExtension('.cp',  APEX_ARC_ARC);  // .cp  -> FreeArc engine
ISApexExRegisterExtension('.dat', APEX_ARC_RAR);  // .dat -> RAR engine
✦ Advanced Progress Tracking
Real-time Overall Progress, Current Disk Progress, and Extracted/Total File Counts.

✦ Performance Metrics
Accurate Current and Average Speed (MB/s).

✦ Time Management
"Time Remaining" + "Elapsed Time" with three display formats (00:00:00 / x hr y min / x hours y minutes).

✦ Process Control
Suspend, Resume, or Stop the extraction safely at any point.

✦ UI Stability
"Calc Accuracy" reduction logic prevents erratic jumping in speed and ETA displays.

✦ Localization
Switch languages at runtime via external .ini files. Ships with English and Russian.

✦ Event Callback System
Optional callback fires on discrete lifecycle events — engine loaded, disk started/finished/failed, error, all done. Great for logging and diagnostics.

✦ File-Based Logging
Thread-safe logging with configurable verbosity (Off, Error, Info, Verbose).

✦ Thread Priority Control
Set extraction thread priority before each disk (Idle … Highest).

✦ Disk Space Pre-Check
Verify free space on the output drive before extraction — per-disk or all disks at once.

✦ Progress Persistence / Resume (Crash Recovery)
On a crash (power loss, kill, BSOD) the library has saved state after each disk; on relaunch ISApexExLoadResume validates and restores progress, already-done disks are skipped. CRC32-checked, auto-deleted on success, fully opt-in (zero overhead unless ISApexExSetResumeFile is called).

▌ ENGINE FEATURES

◆ 7-Zip
Normal + split archives (.7z.001…), ZIP via the same engine, password-protected archives. The 7-Zip API requires split parts to be merged first, so ISApexEx builds a local temp file. Single directory → auto-detected; parts spread across folders → set the total with ISApexExSetSplitPartCount; override the temp location with ISApexExSetSplitTmpPath.

◆ FreeArc
Normal .arc/.bf, selective folder extraction (ISApexExAddDisksEx), external processor integration (SREP, XTool, LOLZ, NZ, RZ…), config file + work path (ISApexExExtractEx), password-protected archives, and native disk-span support via cls-diskspan v2.0 — when a volume is missing, the user is prompted to locate it and extraction resumes. Ship cls-diskspan.dll next to ISApexEx.dll; no ClsFunc* calls needed.

◆ RAR
Normal + multi-volume archives (.part01.rar…) with automatic volume switching (no extra API calls), password-protected archives.

◆ Xdelta3 Patching
  • Single-file patching — ISApexExAddDeltaPatch(PatchFile, SourceFile, OutputFile)
  • Batch directory patching — ISApexExAddDeltaPatchDir(PatchDir, SourceDir, OutputDir, Pattern)
  • In-place patching — when source = output, done via a temp file (decode to .xd3tmp, delete original, rename)
  • User-defined patch extensions — Pattern controls the scanned extension: *.xd3 (default), *.patch, *.delta, *.myext …
  • Recursive directory scanning — batch mode searches subdirectories (now recursive by default)
  • Deferred listing — patch/source dirs are scanned at extraction time, so you can patch files produced by an earlier archive in the same installer
  • Interleaved workflow — extract archives and apply patches in any order; progress stays continuous

◆ HDiffPatch [NEW]
  • Single-file patching — ISApexExAddHDiffPatch(PatchFile, SourceFile, OutputFile) applies a .hdiff binary patch (old + diff → new)
  • Batch directory patching — ISApexExAddHDiffPatchDir(PatchDir, SourceDir, OutputDir, Pattern), default pattern *.hdiff, recursive (scans subfolders)
  • Apply-side only — via hpatchz_wrapper.dll, lazy-loaded; ArchiveType APEX_ARC_HDIFF = 4
  • Fully interleaved — mixes with .7z/.arc/.rar/.xd3 in one session under the same unified progress (0–1000)

▌ SUPPORTED FILE STRUCTURES
Code:
[ROOT]
 ├── data1.7z                  (normal 7z archive)
 ├── data2.zip                 (ZIP archive via 7z engine)
 ├── Disks/
 │    ├── Disk1/
 │    │    ├── Sonic 2.7z.001   (split 7z, parts across directories)
 │    │    └── Sonic 2.7z.002
 │    └── Disk2/
 │         ├── Sonic 2.7z.003
 │         └── Sonic 2.7z.004
 ├── data3.arc                 (FreeArc archive)
 ├── data4.bf                  (FreeArc archive)
 ├── data5.part01.rar          (multi-volume RAR)
 ├── data5.part02.rar
 ├── data5.part03.rar
 ├── data6.rar                 (normal RAR archive)
 ├── setup-1.bin               (cls-diskspan archive)
 ├── data7_xdelta.bin          (archive containing xdelta3 patches)
 ├── data8_hdiff.bin           (archive containing .hdiff patches)
 └── Setup.exe
▌ SUPPORTED FILE EXTENSIONS
Code:
╭────────────────────────────┬──────────────────┬──────────────────╮
│ Extensions                 │ Engine           │ Constant         │
├────────────────────────────┼──────────────────┼──────────────────┤
│ .7z .7z.001 .7z.002 ...    │ 7z engineAPEX_ARC_7Z      │
│ .zip                       │ 7z engineAPEX_ARC_7Z      │
│ .arc .bf                   │ FreeArc engineAPEX_ARC_ARC     │
│ .rar .r00 .r01 ...         │ RAR engineAPEX_ARC_RAR     │
│ .xd3 .xdelta .vcdiff ...   │ xdelta3 engineAPEX_ARC_XDELTA  │
│ .hdiff ...                 │ HDiff engineAPEX_ARC_HDIFF   │
╰────────────────────────────┴──────────────────┴──────────────────╯
▌ EXPORTED API FUNCTIONS
  • Initialization — ISApexExInit, ISApexExInitEx
  • Disk Registration — ISApexExAddDisks, ISApexExAddDisksEx, ISApexExAddDeltaPatch, ISApexExAddDeltaPatchDir, ISApexExAddHDiffPatch, ISApexExAddHDiffPatchDir, ISApexExRegisterExtension, ISApexExClearExtensions
  • Extraction — ISApexExExtract, ISApexExExtractEx
  • Process Control — ISApexExSuspendProc, ISApexExResumeProc, ISApexExIsSuspended, ISApexExStop
  • Progress & Metrics — ISApexExGetTotalSizeMBOfAllDisks, ISApexExGetExtractedSizeMBOfAllDisks, ISApexExCallbackInterval, ISApexExGetCallbackInterval, ISApexExReduceCalcAccuracy
  • Configuration — ISApexExChangeLanguage, ISApexExSetSplitPartCount, ISApexExSetSplitTmpPath, ISApexExSetThreadPriority, ISApexExCheckFreeSpace, ISApexExCheckAllFreeSpace
  • Logging & Events — ISApexExSetLogFile, ISApexExSetLogLevel, ISApexExSetEventCallback
  • File Browsing — ISApexExSetDiskRequestCallback (global — covers every format + missing-part case)
  • Resume / Crash Recovery — ISApexExSetResumeFile, ISApexExLoadResume, ISApexExHasResume, ISApexExClearResume

▌ QUICK START EXAMPLES

Example 1 — Mixed Archives (7z + FreeArc + RAR)
Code:
#include "ISApexEx.iss"

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then
  begin
    if not AddArchiveEntry('data1.7z')  then Exit;
    if not AddArchiveEntry('data2.bf')  then Exit;
    if not AddArchiveEntry('data3.rar') then Exit;

    if ISApexExInitEx(2, @ProgressCallbackEx) then
    begin
      for i := 1 to ISApexExDiskCount do
        if not ISApexExExtract(i) then Break;
      ISApexExStop;
    end;
  end;
end;
Example 2 — Extract + xdelta3 Batch Patching
Code:
if not AddArchiveEntry('data1.7z') then Exit;        // base archive
if not AddArchiveEntry('data_xdelta.rar') then Exit;  // sources + patches

// apply all *.xd3 in \patches to sources in \modified -> \rebuilt (recursive)
ISApexExAddDeltaPatchDir(
  ExpandConstant('{app}\patches'),
  ExpandConstant('{app}\modified'),
  ExpandConstant('{app}\rebuilt'),
  '*.xd3');
ISApexExDiskCount := ISApexExDiskCount + 1;
Example 3 — Single File xdelta3 Patch (In-Place)
Code:
if not AddArchiveEntry('data1.7z') then Exit;  // contains original game.exe

// patch game.exe in-place using game.exe.xd3
ISApexExAddDeltaPatch(
  ExpandConstant('{src}\game.exe.xd3'),
  ExpandConstant('{app}\game.exe'),
  ExpandConstant('{app}\game.exe'));
ISApexExDiskCount := ISApexExDiskCount + 1;
Example 4 — Split 7z Archive (Multi-Part .7z.001/.002/…)
Code:
if not AddArchiveEntry('Sonic 2.7z.001') then Exit;

// parts spread across folders: declare total count + a temp path
ISApexExSetSplitPartCount(ISApexExDiskCount, 7);
ISApexExSetSplitTmpPath(ISApexExDiskCount, ExpandConstant('{src}'));
Example 5 — Split RAR Archive (Multi-Volume .part01.rar/…)
Code:
if not AddArchiveEntry('data1.7z') then Exit;

// just pass the first part — UnRAR switches volumes automatically
if not AddArchiveEntry('data3.part01.rar') then Exit;
Example 6 — Progress Persistence / Resume (Crash Recovery)
Code:
ISApexExSetResumeFile(ExpandConstant('{src}\ISApexEx.resume'));

if ISApexExInitEx(2, @ProgressCallbackEx) then
begin
  if ISApexExLoadResume then   // prompts Yes/No to resume
    Log('Resuming from previous session');
  for i := 1 to ISApexExDiskCount do   // done disks are skipped
    if not ISApexExExtractEx(i, cfg, tmp) then Break;
  ISApexExStop;   // auto-deletes resume file on success
end;
Example 7 — Global "Locate Missing Archive / Volume / Part" Dialog
One callback handles EVERY case: a missing top-level archive of any format, a 7z split part, a RAR volume, or a FreeArc spanned volume. Runs on the main thread (MsgBox / GetOpenFileName / a custom TForm are all safe). Omit it to use the built-in native browse.
Code:
function MyDiskRequest(const Filename, CurrentDir: WideString): WideString;
begin
  if MsgBox('Please insert / locate: ' + Filename,
            mbConfirmation, MB_OKCANCEL) = mrCancel then
  begin
    Result := '';   // cancel -> clean user-abort
    Exit;
  end;
  // ... GetOpenFileName, or your own themed TForm ...
  Result := PickedFolder;   // the folder that now holds Filename
end;

// register once, after Init, before Extract:
ISApexExSetDiskRequestCallback(@MyDiskRequest);
Example 8 — HDiffPatch (Single-File + Batch) [NEW]
A full runnable version is in bin\ISApexEx_Example_HDiff.iss. Ship hpatchz_wrapper.dll next to the other engine DLLs.
Code:
if not AddArchiveEntry('data1.7z') then Exit;  // sources + .hdiff patches

// single file: apply game.exe.hdiff to game.exe in-place
ISApexExAddHDiffPatch(
  ExpandConstant('{src}\game.exe.hdiff'),
  ExpandConstant('{app}\game.exe'),
  ExpandConstant('{app}\game.exe'));
ISApexExDiskCount := ISApexExDiskCount + 1;

// batch: apply all *.hdiff in \patches to \modified -> \rebuilt (recursive)
ISApexExAddHDiffPatchDir(
  ExpandConstant('{app}\patches'),
  ExpandConstant('{app}\modified'),
  ExpandConstant('{app}\rebuilt'),
  '*.hdiff');
ISApexExDiskCount := ISApexExDiskCount + 1;
▌ DISTRIBUTION FILES
  • ISApexEx.dll — Unified API library (single DLL for all five engines)
  • ISApexEx.iss — Header for Inno Setup (types, constants, imports)
  • 7z_32.dll — 7-Zip engine (.7z/.zip)
  • UnArc_32.dll — FreeArc engine (.arc/.bf)
  • UnRAR_32.dll — UnRAR engine (.rar)
  • xdelta3_wrapper.dll — xdelta3 engine (.xd3 patching)
  • hpatchz_wrapper.dll — HDiffPatch engine (.hdiff apply)
  • cls-diskspan.dll — (Optional) FreeArc disk-spanning plugin, v2.0 modified edition. Only for setup-N.bin sets.
  • English.ini / Russian.ini — Language files
  • arc.ini / CLS.ini — FreeArc external-processor configuration
Engine DLLs are lazy-loaded — ship only the ones the archives you use actually need.

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

Feedback, bug reports, and edge cases are all welcome.


.
Attached Images
File Type: png 0.png (102.2 KB, 23 views)
File Type: png 1.png (110.6 KB, 23 views)
File Type: png 3.png (81.2 KB, 23 views)
File Type: png 4.png (78.9 KB, 23 views)
File Type: png 5.png (101.9 KB, 23 views)
File Type: png 6.png (95.4 KB, 23 views)
File Type: png 7.png (81.4 KB, 23 views)
File Type: png 8.png (82.9 KB, 23 views)
File Type: png e1.png (103.9 KB, 23 views)
File Type: png e2.png (83.0 KB, 23 views)
File Type: png d0.png (80.2 KB, 23 views)
File Type: png d1.png (107.9 KB, 23 views)
File Type: png d3.png (78.6 KB, 23 views)
File Type: png d4.png (67.3 KB, 23 views)
File Type: png d6.png (79.4 KB, 23 views)
Attached Files
File Type: rar ISApexEx v0.1 Beta 03 + Examples.rar (4.62 MB, 2 views)

Last edited by BLACKFIRE69; Yesterday at 04:04. Reason: Updated to Beta 03
Reply With Quote
The Following 7 Users Say Thank You to BLACKFIRE69 For This Useful Post:
audiofeel (20-06-2026), Cesar82 (24-06-2026), Ele (20-06-2026), Gehrman (22-06-2026), Razer-785 (21-06-2026), Razor12911 (21-06-2026), ScOOt3r (23-06-2026)
Sponsored Links
  #2  
Old 23-06-2026, 02:55
Razor12911's Avatar
Razor12911 Razor12911 is offline
Noob
 
Join Date: Jul 2012
Location: South Africa
Posts: 3,754
Thanks: 2,191
Thanked 11,222 Times in 2,312 Posts
Razor12911 is on a distinguished road
First of, I'd like to say. Amazing work I just have one small request or a query rather, is it possible to get 64-bit builds? Thanks.

Last edited by Razor12911; 23-06-2026 at 04:48.
Reply With Quote
The Following 2 Users Say Thank You to Razor12911 For This Useful Post:
BLACKFIRE69 (23-06-2026), Ele (23-06-2026)
  #3  
Old 23-06-2026, 14:25
BLACKFIRE69's Avatar
BLACKFIRE69 BLACKFIRE69 is offline
Registered User
 
Join Date: Mar 2019
Location: In the Hell
Posts: 701
Thanks: 486
Thanked 2,610 Times in 574 Posts
BLACKFIRE69 is on a distinguished road
Quote:
Originally Posted by Razor12911 View Post
First of, I'd like to say. Amazing work I just have one small request or a query rather, is it possible to get 64-bit builds? Thanks.
Thanks, mate!

It's possible to have x64 builds, but the problem is FreeArc.

Razor, do you have any tested x64 versions of unarc.dll?
Reply With Quote
The Following 2 Users Say Thank You to BLACKFIRE69 For This Useful Post:
Behnam2018 (23-06-2026), Razor12911 (24-06-2026)
  #4  
Old 24-06-2026, 04:39
Razor12911's Avatar
Razor12911 Razor12911 is offline
Noob
 
Join Date: Jul 2012
Location: South Africa
Posts: 3,754
Thanks: 2,191
Thanked 11,222 Times in 2,312 Posts
Razor12911 is on a distinguished road
Quote:
Originally Posted by BLACKFIRE69 View Post
Thanks, mate!

It's possible to have x64 builds, but the problem is FreeArc.

Razor, do you have any tested x64 versions of unarc.dll?
You can find one that I posted years ago here
Reply With Quote
The Following 4 Users Say Thank You to Razor12911 For This Useful Post:
BLACKFIRE69 (24-06-2026), Cesar82 (24-06-2026), Ele (25-06-2026), Razer-785 (24-06-2026)
  #5  
Old 25-06-2026, 08:17
BLACKFIRE69's Avatar
BLACKFIRE69 BLACKFIRE69 is offline
Registered User
 
Join Date: Mar 2019
Location: In the Hell
Posts: 701
Thanks: 486
Thanked 2,610 Times in 574 Posts
BLACKFIRE69 is on a distinguished road
Question

Quote:
Originally Posted by Razor12911 View Post
First of, I'd like to say. Amazing work I just have one small request or a query rather, is it possible to get 64-bit builds? Thanks.
Quote:
Originally Posted by BLACKFIRE69 View Post
Thanks, mate!

It's possible to have x64 builds, but the problem is FreeArc.

Razor, do you have any tested x64 versions of unarc.dll?
Quote:
Originally Posted by Razor12911 View Post
You can find one that I posted years ago here
Razor, but there are other practical technical issues we have to face, right? for example, facompress*.dll is still x86, existing CLS plugins are x86, and so on. There are some workarounds, but I guess bringing them in is out of the question. What do you think?
Reply With Quote
The Following 2 Users Say Thank You to BLACKFIRE69 For This Useful Post:
Cesar82 (25-06-2026), Razor12911 (25-06-2026)
  #6  
Old 25-06-2026, 12:51
Razor12911's Avatar
Razor12911 Razor12911 is offline
Noob
 
Join Date: Jul 2012
Location: South Africa
Posts: 3,754
Thanks: 2,191
Thanked 11,222 Times in 2,312 Posts
Razor12911 is on a distinguished road
I'm well aware but the reason I would like a 64-bit build is because I want there to be tools specifically designed to work natively with Inno Setup 7 and I believe projects like this one are perfect foundation that might kick things off, of course they'll be challenges ahead but those are for the people who might be interested with this route to deal with and all I want is just availability.
Reply With Quote
The Following User Says Thank You to Razor12911 For This Useful Post:
Cesar82 (25-06-2026)
  #7  
Old 26-06-2026, 04:24
BLACKFIRE69's Avatar
BLACKFIRE69 BLACKFIRE69 is offline
Registered User
 
Join Date: Mar 2019
Location: In the Hell
Posts: 701
Thanks: 486
Thanked 2,610 Times in 574 Posts
BLACKFIRE69 is on a distinguished road
Quote:
Originally Posted by Razor12911 View Post
I'm well aware but the reason I would like a 64-bit build is because I want there to be tools specifically designed to work natively with Inno Setup 7 and I believe projects like this one are perfect foundation that might kick things off, of course they'll be challenges ahead but those are for the people who might be interested with this route to deal with and all I want is just availability.
Ya, I agree. In the current scenario (repacking), FreeArc plays a huge role, so the entire backbone of ISApexEx effectively depends on it.
The lack of support for `cls-srep.dll` , `cls-lolz.dll`, etc. also leaves a huge gap. Without support for them, ISApexEx becomes more of a toy tool than a top-tier tool.

Because of that, the transition to Inno Setup 7 x64 won't be particularly easy or smooth from this side, especially since many of the plugins we commonly use, such as `botva2.dll`, are still x86, and some of them haven't received updates in *years*.

So, I do plan to release an x64 build of ISApexEx, but for now, I'd like to buy some time before releasing it. In the meantime, we can try compiling the entire FreeArc project as an x64 build. Hopefully, we'll also find a solid and practical way to handle the existing x86 CLS plugins whose development has already stopped, so they can still be supported in an x64 host.
Reply With Quote
The Following User Says Thank You to BLACKFIRE69 For This Useful Post:
audiofeel (26-06-2026)
  #8  
Old 26-06-2026, 04:44
audiofeel's Avatar
audiofeel audiofeel is online now
Registered User
 
Join Date: Jan 2013
Location: Russia
Posts: 56
Thanks: 492
Thanked 1,097 Times in 381 Posts
audiofeel is on a distinguished road
Quote:
Originally Posted by BLACKFIRE69 View Post
Because of that, the transition to Inno Setup 7 x64 won't be particularly easy or smooth from this side, especially since many of the plugins we commonly use, such as `botva2.dll`, are still x86, and some of them haven't received updates in *years*.
It's not a big deal, you can convert Botva2.dll to x64 very quickly. I'm sure of it

https://github.com/Krinkelss/botva2/tree/master
__________________
https://t.me/FMXInno
Reply With Quote
The Following User Says Thank You to audiofeel For This Useful Post:
BLACKFIRE69 (26-06-2026)
  #9  
Old 26-06-2026, 04:56
BLACKFIRE69's Avatar
BLACKFIRE69 BLACKFIRE69 is offline
Registered User
 
Join Date: Mar 2019
Location: In the Hell
Posts: 701
Thanks: 486
Thanked 2,610 Times in 574 Posts
BLACKFIRE69 is on a distinguished road
Lightbulb ISApexEx Update

ISApexEx Update

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

▌ v0.1 Beta 2 (Build 6A3DC100)

✦ Added
  • New engine: HDiffPatch v5.0.0 — applies .hdiff binary patches (old + diff → new), single-file and batch directory modes. Native DLL: hpatchz_wrapper.dll (apply side only). ArchiveType APEX_ARC_HDIFF = 4. Lazy-loaded; not a load-time dependency of ISApexEx.dll.
  • New exports — ISApexExAddHDiffPatch, ISApexExAddHDiffPatchDir (default batch pattern '*.hdiff').
  • .hdiff extension auto-detected and routed to the HDiffPatch engine; mixes with .7z / .arc / .rar / .xd3 in one session with unified progress (0–1000).
  • New example installer — bin\ISApexEx_Example_HDiff.iss.
  • ERROR_HDIFF_* language strings in English.ini and Russian.ini.
  • Thanks, @Cesar82, for the HDiffPatch suggestion.

✦ Changed — BREAKING
xdelta patch exports renamed (signatures unchanged):
Code:
╭──────────────────────────┬──────────────────────────────╮
│ Old name (removed)       │ New name                     │
├──────────────────────────┼──────────────────────────────┤
│ ISApexExAddPatchISApexExAddDeltaPatch        │
│ ISApexExAddPatchDirISApexExAddDeltaPatchDir     │
╰──────────────────────────┴──────────────────────────────╯
Update any [Code] script that calls the old names. The generic "Patch" names are removed entirely.

✦ Changed
  • Batch (...Dir) patching is now recursive by default for BOTH engines — scans subfolders too (switched to the leaner wfs_FindFilesForHashEx scanner; faster, lower memory, same relative-path results).
  • Version v0.1 Beta → v0.1 Beta 2; build 6A20C000 → 6A3DC100 (shown in init log, DLL version info, and dialog titles).
  • ISApexEx.iss header, example scripts (.iss), and the forum description updated for the new engine and renamed exports.
  • Inno Setup example scripts updated to work with both Inno Setup v6.x and v5.x.

✦ Fixed
  • Single-file patching now force-overwrites the output even when it is read-only/locked — the read-only attribute is cleared and the stale file removed before patching, in BOTH the Delta and HDiff engines.

✦ Upgrade Notes
  • Rename xdelta calls to the ...Delta... names (see the BREAKING table above).
  • To apply .hdiff patches, ship hpatchz_wrapper.dll next to the other engine DLLs and call ISApexExAddHDiffPatch / ...Dir.
  • ...Dir patching is now recursive — confirm no stray patches sit in subfolders you did not intend to process.

✦ Download
  • - Check the first post.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━
Reply With Quote
The Following 3 Users Say Thank You to BLACKFIRE69 For This Useful Post:
audiofeel (26-06-2026), Cesar82 (26-06-2026), Razor12911 (26-06-2026)
  #10  
Old Yesterday, 04:10
BLACKFIRE69's Avatar
BLACKFIRE69 BLACKFIRE69 is offline
Registered User
 
Join Date: Mar 2019
Location: In the Hell
Posts: 701
Thanks: 486
Thanked 2,610 Times in 574 Posts
BLACKFIRE69 is on a distinguished road
Lightbulb ISApexEx Update

ISApexEx Update
Unified Archive Extraction & Patching API for Inno Setup
by BLACKFIRE69

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

▌ v0.1 Beta 3 (Build 6A406400)
Compared to: v0.1 Beta 2 (Build 6A3DC100)

✦ Added
  • Archive testing (no extraction) — ISApexExTestDisk(n) and ISApexExTestAll test and CRC-check every member while writing nothing to disk. Real archives (7z / FreeArc / RAR) only; patch and zip-create jobs are skipped. Returns False on the first corrupt archive (fires APEX_EVENT_ERROR).
  • Existing-file overwrite policy — ISApexExSetOverwritePolicy(n, policy): APEX_OVERWRITE (default) / APEX_SKIP / APEX_RENAME. Skip and overwrite work on all engines; rename ('name (N).ext') is honoured by 7z and RAR. FreeArc has no per-file rename, so rename falls back to overwrite there.
  • Selective extraction — ISApexExSetExtractFilter(n, include, exclude): per-disk include/exclude masks using the scanner syntax — pipe-separated globs ('*.dll|data\*'), '@listfile', or regex wrapped as $"pattern" (e.g. '$"^setup.*\.exe$"' — the $ and quotes are required and protect any '|' inside). Honoured per-member by 7z and RAR; FreeArc maps globs to native filespecs / -x (the $"..." regex and @list forms are ignored for FreeArc).
  • Interactive password prompt — ISApexExSetPasswordCallback(cb) for a custom prompt, plus a built-in fallback password box. An encrypted archive with no / empty / wrong stored password now prompts the user instead of failing. Covers all three real engines — 7z, RAR, and FreeArc. (Triggers only for genuinely encrypted archives.)
  • ZIP creation from a folder — ISApexExAddZip(srcDir, outZip, include, exclude, method, level, password, deleteSource) builds a .zip with a selectable compression method (APEX_ZIP_STORE / DEFLATE / DEFLATE64 / BZIP2 / LZMA / PPMD) and level (0=store .. 9=ultra, default 5), plus optional AES-256 (non-empty password). deleteSource=True removes the source folder (incl. subdirs) after a successful zip — never if the job fails or is cancelled. Registered like the patch helpers and runs in the unified extraction loop with continuous progress; the folder is walked at extraction time (deferred). New constants APEX_ARC_ZIPCREATE = 5 and APEX_ZIP_* methods.
  • New example scripts — one per feature, for individual testing: ISApexEx_Example_Test.iss, ISApexEx_Example_Overwrite.iss, ISApexEx_Example_Filter.iss, ISApexEx_Example_Password.iss, ISApexEx_Example_Zip.iss, ISApexEx_Example_Verify.iss.
  • Batch signature verification — ISApexExVerifyFolder(folder, recursive, callback) walks a folder, finds every <file>.sig and verifies the file beside it in one call (instead of many ISApexExVerifyFile calls). Returns the number of files that failed (0 = all authentic); a missing signed file is caught as VFY_NO_FILE. The optional callback reports per-file status (path, index/total, VFY_* code, running fail count) and can cancel (VFY_CANCELLED). New VFY_CANCELLED = -10.
  • Job counter — ISApexExGetDiskCount returns how many jobs are registered (archives, patches and zip-create jobs). The DLL is now the single source of truth, so scripts no longer need to track their own disk counter — just loop 1..ISApexExGetDiskCount.
  • Encrypted password keystore — ISApexExOpenKeyStore(file) / ISApexExCloseKeyStore. Keep archive (and .ekey) passwords out of the installer script entirely — store them in an encrypted (.keydb) keystore file and reference each by name. Once a keystore is open, a password argument of the form '@key:<name>' passed to ISApexExAddDisks / AddDisksEx / AddZip / SetVerifyKey is replaced with the matching stored password; the clear-text never appears in the .iss or the compiled Setup.exe. <name> is a FIXED reserved name, validated per use-site: 'disk' (archive password shared by all archives), 'disk2'/'disk3'/... (per-archive overrides, only when one differs), and 'ekey' (the ISApexExSetVerifyKey password). So 10 archives sharing one password need a single 'disk' entry. A name invalid for the site, or absent, resolves to an empty password (and is logged), so a typo or misuse cannot fall back to literal text. Companion console tool ApexKeyTool builds keystores (guided 'gen', plus add / remove / list); it is deliberately write-only for passwords — 'list' shows entry NAMES only and there is no command to print stored passwords (the keystore's key is embedded in the shipped tool, so a dump command would expose every keystore).
  • Full FreeArc error-message coverage — a failed FreeArc job now reports a specific, localizable reason (unknown method, output block too small, read/write error, not enough memory, unsupported feature, corrupted data, checksum mismatch, damaged headers, invalid password, ...) instead of a single generic "decompression error". New ERROR_ARC_* keys in English.ini / Russian.ini.
  • ZIP-create progress label — creating a zip now shows a clear status ("<name>.zip - Creating ZIP archive...", key STATUS_ZIPPING) and the archive-test (ISApexExTestDisk / TestAll) now reports per-file progress + count like a real extraction.

✦ Changed
  • The selective-extraction mask engine is now shared by both selective extraction and zip creation — one consistent include/exclude syntax.
  • The 7z engine gained archive-creation support, used by ISApexExAddZip (requires the full 7z library that ISApexEx ships).
  • FreeArc extraction now honours the per-disk overwrite policy when it would otherwise prompt to overwrite (overwrite-all / skip-all).
  • The 7z engine now opens real .zip archives (the format is detected from the file itself). Previously a .zip could fail to open and be reported as "not a valid 7z archive"; this also affected the Zip-Slip security test.
  • The log now records WHY a run ended early instead of a bare "finished with errors". On stop, ISApexEx writes the specific reason to ISApexEx.log: user cancellation from the progress callback, a declined password or disk-span volume prompt, the engine's own error text (e.g. a FreeArc "checksum mismatch"), or a host-initiated stop while a job was still running. (Needs a log file set with ISApexExSetLogFile.)
  • Version v0.1 Beta 2 → v0.1 Beta 3; build 6A3DC100 → 6A406400.

✦ Fixed
  • Interactive password on encrypted .7z archives whose file list is itself encrypted — a wrong or missing password now shows the prompt and retries (just like RAR and FreeArc) instead of failing with "not a valid 7z archive".
  • RAR wrong-password retry now also covers archives whose encrypted header is reported as generic data damage — but only when a password is actually involved, so genuinely corrupt archives are still reported as damaged.
  • A password-prompt callback that raises an error is now treated as a clean cancel instead of being misreported as a corrupt archive.
  • The crash-recovery (resume) checkpoint now saves reliably on all supported Windows versions (an internal integrity step could fail on some systems).
  • Optional component signature verification now loads the key and verifies files reliably on all supported Windows versions (same underlying fix). Files signed with the SignTool Suite verify unchanged.

✦ Security
  • In-memory password hygiene — archive passwords (per-disk, the session "last good password" cache, the interactive-prompt hand-off, and the FreeArc engine's working copies) are now overwritten with zeros as soon as they are no longer needed — not merely released — so a memory/crash dump cannot recover them from freed heap. Passwords are also wiped on ISApexExStop and on library unload.
  • Encrypted password keystore (AES-256, OFF by default) — see Added above. Lets the installer reference passwords by name instead of embedding clear text, and the stored passwords are wiped from memory on close / unload.
  • Optional component signature verification (RSA-2048 / SHA-256), OFF by default — ISApexExSetVerifyKey(ekey, password) turns on a check of every native engine component ISApexEx loads: each must carry a valid <name>.sig (made with the SignTool Suite) or the load is refused and the run fails (fail-closed). Plus ISApexExVerifyFile(path) to verify arbitrary shipped files (external compressors, helper tools, ISApexEx.dll's own image) and ISApexExGetVerifyStatus for diagnostics. Uses the OS crypto provider; no extra DLL shipped. One-time cost only; zero when unused. New result codes VFY_OK / VFY_TAMPERED / ...
  • Crash-recovery (resume) hardening — the resume file is now written atomically (temp file + flush-to-disk + atomic replace), so an instant crash mid-save can no longer truncate or lose the checkpoint.
  • Path-traversal protection on extraction (anti "Zip-Slip") — a malicious archive member that tries to write OUTSIDE the chosen destination — via '..' segments, an absolute path, a drive letter or a UNC path — is now blocked. ISApexEx fails closed: it stops the extraction, reports the blocked path, fires APEX_EVENT_ERROR and returns failure (no partial or dangerous install). Enforced for the 7z and RAR engines.
  • Hardened native-DLL loading — the engine DLLs and their dependencies now resolve only from System32 and ISApexEx's own folder, never the installer's working directory — closing a DLL-planting vector on end-user machines.
  • Password-handling robustness — the RAR password path now respects the engine's buffer size, removing a potential overflow with very long passwords.
  • New language string ERROR_UNSAFE_PATH (English.ini / Russian.ini).

✦ Notes / Known Limitations
  • Interactive password covers the three real archive engines (7z, RAR, FreeArc), including .7z archives whose file list is itself encrypted. On a wrong password all three now re-prompt: FreeArc retries until the password is correct or the user cancels; 7z and RAR retry up to 3 times, then fail that archive (re-run to try again). Cancelling the prompt aborts the archive cleanly (no corrupt output). Xdelta/HDiff patch jobs are unencrypted and never prompt.
  • Rename overwrite policy works on 7z and RAR. Only FreeArc lacks a rename-on-collision option and falls back to overwrite.
  • Selective extraction on FreeArc uses native globs only — quoted-regex and @listfile entries in the mask are ignored for the FreeArc engine (7z and RAR honour the full scanner syntax). Listing-time size totals are computed before filtering, so a heavily filtered job may show a slightly high byte total.
  • ZIP creation requires the full 7-Zip library that ISApexEx ships (it includes the zip writer). A stripped extract-only build cannot create archives and ISApexExAddZip fails. RAR creation is not possible; use ZIP for in-installer repacks.
  • ZIP methods STORE/DEFLATE/DEFLATE64 open in any unzip tool (incl. Windows Explorer); BZIP2/LZMA/PPMD compress better but need a modern tool (7-Zip, WinRAR). DEFLATE (the default) is the safe choice for end-user output.
  • Path-traversal protection is enforced for 7z and RAR. FreeArc (.arc/.bf) relies on its own engine to keep output inside the destination folder.

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

▌ v0.1 Beta 3 — Inno Setup Snippets
Runnable single-feature snippets — each also ships as its own example .iss (see the Added list above).

Example 1 — Archive Testing (No Extraction)
Code:
{ one shot - test every registered archive (writes nothing): }
if ISApexExTestAll then
  MsgBox('All archives are valid.', mbInformation, MB_OK)
else
  MsgBox('An archive is corrupt or the password is wrong.', mbError, MB_OK);

{ or per-disk, to pinpoint WHICH archive is bad: }
for i := 1 to ISApexExGetDiskCount do
  if not ISApexExTestDisk(i) then
    MsgBox(Format('Archive #%d failed the test.', [i]), mbError, MB_OK);
Example 2 — Existing-File Overwrite Policy
Code:
{ call AFTER AddDisks, once per disk. Policy is one of:
    APEX_OVERWRITE (0, default) | APEX_SKIP (1) | APEX_RENAME (2) }
ISApexExSetOverwritePolicy(ISApexExGetDiskCount, APEX_RENAME);
{ Overwrite + Skip work on all engines; Rename works on 7z and RAR
  (FreeArc has no per-file rename and falls back to overwrite). }
Example 3 — Selective Extraction (Include / Exclude Masks)
Code:
{ AFTER AddDisks, once per disk. '|' separates masks; exclude wins.
  Empty include = everything. }
ISApexExSetExtractFilter(ISApexExGetDiskCount, '*.dll|*.exe|data\*', '*.log|*.tmp');

{ regex form - wrap each pattern as $"..." (single-quoted Pascal string, so the
  inner double quotes are literal); a '|' inside is then protected: }
ISApexExSetExtractFilter(ISApexExGetDiskCount, '$".*\.(exe|dll)$"', '');
{ @listfile and the $"..." regex are honoured by 7z and RAR;
  FreeArc uses native globs only. }
Example 4 — Interactive Password Prompt (Custom Callback)
  • Way 1 — Native: do nothing extra; ISApexEx shows its own built-in password box automatically.
  • Way 2 — Custom callback (shown below): register your own prompt to replace the built-in box.
Code:
{ Custom callback prompt: register your own custom prompt to REPLACE
  the built-in box. Return the password, or '' to cancel (clean abort).
  Attempt is 1-based for retry messages. }
function OnPasswordRequest(const Filename: WideString; Attempt: Integer): WideString;
begin
  if Attempt > 1 then
    Result := InputBox('Wrong password - try again for ' + Filename, '', '')
  else
    Result := InputBox('Password for ' + Filename, '', '');
end;

{ register it BEFORE extraction (omit this call to use the native box): }
ISApexExSetPasswordCallback(@OnPasswordRequest);

{ Either way: triggers only for genuinely encrypted archives with no/empty/wrong
  password. The first entered password is cached and reused for the rest of the
  batch. Cancelling at the prompt writes the reason to ISApexEx.log (when a log
  file is set with ISApexExSetLogFile). }
Example 5 — Build a ZIP From a Folder
Code:
{ ISApexExAddZip(SrcDir, OutZip, Include, Exclude, Method, Level, Password, DeleteSource).
  Method : APEX_ZIP_STORE | DEFLATE | DEFLATE64 | BZIP2 | LZMA | PPMD
           (Store/Deflate/Deflate64 open anywhere; BZip2/LZMA/PPMd need a modern tool)
  Level  : 0=store .. 9=ultra (default 5; ignored for STORE)
  Password: '' = plain zip; non-empty = AES-256
  DeleteSource: True removes the source folder after a SUCCESSFUL zip. }
if not ISApexExAddZip(ExpandConstant('{app}\unpacked'),
                      ExpandConstant('{app}\bundle.zip'),
                      '*', '', APEX_ZIP_DEFLATE, 5, '', True) then
  MsgBox('Could not register the zip job.', mbError, MB_OK);
{ Runs in the same extraction loop as the archives, with unified progress. }
Example 6 — Job Counter (No Manual Disk Tracking)
Code:
{ No manual disk counter needed - loop 1..ISApexExGetDiskCount: }
for i := 1 to ISApexExGetDiskCount do
begin
  if not ISApexExExtract(i) then Break;
end;
Example 7 — Component Signature Verification
SetVerifyKey turns on fail-closed loading; VerifyFile checks one file, VerifyFolder batch-checks a whole tree.
Code:
{ Turn on verification: every engine DLL loaded after this must carry a valid
  '<name>.sig' beside it or its load is refused (fail-closed). }
if not ISApexExSetVerifyKey(ExpandConstant('{tmp}\public.ekey'), VerifyPassword) then
begin
  MsgBox('Verification could not be enabled: ' + ISApexExGetVerifyStatus,
         mbCriticalError, MB_OK);
  Exit;
end;

{ verify one file yourself (returns a VFY_* code; VFY_OK = authentic): }
if ISApexExVerifyFile(ExpandConstant('{tmp}\7z_32.dll')) <> VFY_OK then
  MsgBox('7z_32.dll is not trusted: ' + ISApexExGetVerifyStatus,
         mbCriticalError, MB_OK);

{ batch-verify every signed file under a folder. The callback (main thread)
  reports each file; return non-zero to cancel. The result is the number that
  FAILED (0 = all authentic; a negative value is an operational error). }
function VerifyProgress(Info: TISApexExVerifyProgress): LongWord;
begin
  Log(Format('Verify %d/%d: %s  code=%d',
      [Info.Index, Info.Total, Info.FilePath, Info.ResultCode]));
  Result := 0;
end;

Failed := ISApexExVerifyFolder(ExpandConstant('{tmp}'), True, @VerifyProgress);
if Failed <> 0 then
  MsgBox('Folder verification reported ' + IntToStr(Failed) + ' problem(s).',
         mbCriticalError, MB_OK);
Example 8 — Encrypted Password Keystore
Reserved names — 'disk' (shared password), 'disk2'/'disk3'... (per-archive overrides), 'ekey' (the SetVerifyKey password).
Code:
{ Keep the archive password out of the script: store it in an encrypted .keydb
  (built with the ApexKeyTool console utility) and reference it by NAME.
  Reserved names: 'disk' (shared archive password), 'disk2'/'disk3'.. (per-archive
  overrides), 'ekey' (the ISApexExSetVerifyKey password). }
if not ISApexExOpenKeyStore(ExpandConstant('{tmp}\ApexKeys.keydb')) then
begin
  MsgBox('Could not open the password keystore.', mbCriticalError, MB_OK);
  Exit;
end;

{ pass '@key:<name>' instead of a clear-text password - it is substituted from
  the keystore. A wrong/missing name resolves to an empty password (and is logged). }
if not ISApexExAddDisks(ExpandConstant('{src}\data1.7z'),
                        '@key:disk', ExpandConstant('{app}')) then
  MsgBox('Could not open the archive.', mbCriticalError, MB_OK);

{ close when done registering - the stored passwords are wiped from memory. }
ISApexExCloseKeyStore;
✦ Download
  • - Check the first post.

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

Feedback, bug reports, and edge cases are all welcome.
Attached Images
File Type: png 0.png (80.2 KB, 23 views)
File Type: png 1.png (107.9 KB, 23 views)
File Type: png 2.png (109.5 KB, 23 views)
File Type: png 3.png (78.6 KB, 23 views)
File Type: png 4.png (67.3 KB, 23 views)
File Type: png 5.png (70.9 KB, 23 views)
File Type: png 6.png (79.4 KB, 23 views)
File Type: png 7.png (74.6 KB, 23 views)
File Type: png 8.png (69.0 KB, 23 views)
File Type: png 9.png (129.1 KB, 23 views)
File Type: png 10.png (80.1 KB, 23 views)
File Type: png 11.png (114.3 KB, 23 views)
File Type: png 12.png (20.0 KB, 23 views)
Reply With Quote
The Following 3 Users Say Thank You to BLACKFIRE69 For This Useful Post:
audiofeel (Yesterday), Cesar82 (Yesterday), Ele (Yesterday)
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



All times are GMT -7. The time now is 13:27.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.
FileForums @ https://fileforums.com