Jump to content

Recommended Posts

Posted (edited)

 

AutoIt Resource Embedder

Version AutoIt License

A professional tool to convert binary files into self-contained AutoIt functions with advanced encoding and compression support.

Author: Dao Van Trong - TRONG.PRO


🌟 Features

Core Functionality

  • Binary File Embedding - Convert any binary file (DLL, EXE, images, etc.) into AutoIt code
  • Multiple Encoding Formats
    • Hex String Encoding
    • Base64 String Encoding (with Unicode support)
  • LZNT Compression
    • Level 1: Standard 4096-byte chunks
    • Level 2: No chunking (maximum compression)
  • Architecture Detection - Automatically detects PE file architecture (x86, x64, ARM, ARM64, IA64)
  • Dual Operation Modes
    • GUI Mode - User-friendly graphical interface
    • CLI Mode - Command-line for automation/scripting

Advanced Features

  • Smart Helper Functions
    • _DeployFile() for single file - Returns binary, hex string, or writes to file
    • _GetBin($filename) for multiple files - Switch/Case based retrieval
  • Automatic Decompression/Decoding - Generated code includes all necessary helper functions
  • Error Handling - Comprehensive error checking and reporting
  • Chunk Size Control - Configurable line length (100-4000 characters)
  • Batch Processing - Process multiple files at once

🚀 Quick Start

GUI Mode

  1. Run the script:

    Double-click "AutoIt Resource Embedder.au3"

     

  2. Add files:

    • Click "Add Files..." button
    • Select one or more binary files
    • Files appear in the list with size and architecture info
  3. Configure encoding:

    • Hex - Standard hex string encoding
    • Base64 - Base64 string encoding
    • Hex + LZNT - Hex encoding with compression
    • Base64 + LZNT - Base64 encoding with compression
    • Select LZNT Level (1 or 2) if using compression
  4. Generate code:

    • Click "Generate All Functions" or "Preview Single"
    • Code appears in the output window
  5. Save output:

    • "Save All to File" - Single .au3 file with all functions
    • "Save Separate Files" - Individual .au3 file per input file
    • "Copy to Clipboard" - Copy generated code

CLI Mode

Process files from command line:

AutoIt3.exe "AutoIt Resource Embedder.au3" file1.dll file2.exe

Output: All_Embedded.au3 (or individual file if only one input)


📖 Usage Examples

Example 1: Single File with Helper Function

Input: myLib.dll

Generated Code:

; Function containing encoded data
Func _GetBinData_myLib_dll_x86()
    Local $sHexData = '0x4D5A90000300000004000000FFFF...'
    Return $sHexData
EndFunc

; Helper function to deploy the file
Func _DeployFile($sDestPath = "", $bReturnHex = False)
    Local $sHexData = _GetBinData_myLib_dll_x86()
    If $sHexData = "" Then Return SetError(1, 0, "")
    Local $bBinary = Binary($sHexData)
    
    ; If no destination path, return binary or hex string
    If $sDestPath = "" Then
        If $bReturnHex Then
            Return StringTrimLeft($bBinary, 2)
        Else
            Return $bBinary
        EndIf
    EndIf
    
    ; Write binary data to file
    Local $hFile = FileOpen($sDestPath, 18)
    If $hFile = -1 Then Return SetError(4, 0, "")
    FileWrite($hFile, $bBinary)
    FileClose($hFile)
    
    If Not FileExists($sDestPath) Then Return SetError(5, 0, "")
    Return $sDestPath
EndFunc

Usage:

; Get binary data
$bData = _DeployFile()

; Get hex string
$sHex = _DeployFile("", True)

; Write to file
$sPath = _DeployFile(@TempDir & "\myLib.dll")

Example 2: Multiple Files with _GetBin()

Input: Multiple DLL files

Generated Code:

Func _GetBin($sName)
    Local $sData = ""
    Switch $sName
    Case "kernel32.dll"
        $sData = _GetBinData_kernel32_dll_x86()
    Case "user32.dll"
        $sData = _GetBinData_user32_dll_x86()
    Case "advapi32.dll"
        $sData = _GetBinData_advapi32_dll_x86()
    EndSwitch
    
    If $sData = "" Then Return SetError(1, 0, Binary(""))
    Local $bData = Binary($sData)
    
    Return $bData
EndFunc

Usage:

; Get any embedded file by name
$bKernel32 = _GetBin("kernel32.dll")
$bUser32 = _GetBin("user32.dll")
$bAdvapi32 = _GetBin("advapi32.dll")

Example 3: With Compression

Enable LZNT Compression:

  • Select "Hex + LZNT" or "Base64 + LZNT"
  • Choose compression level (1 or 2)
  • Generated code includes decompression function:
Func _WinAPI_LZNTDecompress($bCompressed)
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bCompressed) & "]")
    DllStructSetData($tInput, 1, $bCompressed)
    Local $tOutput = DllStructCreate("byte[" & (BinaryLen($bCompressed) * 10) & "]")
    Local $aRet = DllCall("ntdll.dll", "uint", "RtlDecompressBuffer", "ushort", 0x0002, "struct*", $tOutput, "ulong", DllStructGetSize($tOutput), "struct*", $tInput, "ulong", BinaryLen($bCompressed), "ulong*", 0)
    If @error Or $aRet[0] <> 0 Then Return SetError(1, 0, "")
    Return BinaryMid(DllStructGetData($tOutput, 1), 1, $aRet[6])
EndFunc

⚙️ Configuration Options

Encoding Formats

Option Description Use Case
Hex Standard hexadecimal encoding General purpose, human-readable
Base64 Base64 string encoding Smaller output, better for text
Hex + LZNT Hex with compression Large files, need compression
Base64 + LZNT Base64 with compression Maximum size reduction

Compression Levels

Level ChunkSize Description
Level 1 4096 bytes Standard LZNT compression
Level 2 0 (no chunking) Maximum compression ratio

Line Length

  • Range: 100 - 4000 characters
  • Default: 4000 characters
  • Purpose: Controls how long each line of encoded data is in the generated code

🎯 Use Cases

  1. DLL Embedding - Embed runtime libraries directly in your AutoIt scripts
  2. Resource Packaging - Package images, icons, or data files
  3. Portable Applications - Create single-file executables with all dependencies
  4. Obfuscation - Hide sensitive binary data within scripts
  5. Version Control - Include small binaries in source control as text
  6. Driver Deployment - Embed device drivers for automated installation
  7. Plugin Systems - Dynamically load plugins from embedded data

🏗️ Architecture Detection

Automatically identifies PE file architecture:

Architecture Machine Code Description
x86 0x014C 32-bit Intel
x64 0x8664 64-bit AMD/Intel
ARM 0x01C0, 0x01C4 ARM processors
ARM64 0xAA64 64-bit ARM
IA64 0x0200 Intel Itanium
Not PE - Non-executable files

🛠️ Technical Details

Encoding Methods

Hex Encoding:

Binary($sHexData) ; Direct conversion from hex string

Base64 Encoding:

  • Uses Windows Crypto API (Crypt32.dll)
  • Unicode support (CryptStringToBinaryW)
  • Automatic whitespace removal

Compression

LZNT Algorithm:

  • Windows native compression (ntdll.dll)
  • RtlCompressBuffer / RtlDecompressBuffer
  • Workspace allocation: 1MB (0x100000 bytes)
  • Error handling with proper status codes

Generated Code Structure

1. Header comments (file info, settings)
2. Data functions (_GetBinData_xxx)
3. Helper functions (decode/decompress)
4. Deployment functions (_DeployFile or _GetBin)
5. Usage examples (commented)

📝 Error Handling

The tool provides comprehensive error handling:

Error Code Description
SetError 1 Cannot read file or invalid data
SetError 2 Encoding/compression failed
SetError 3 Decompression failed
SetError 4 Cannot create output file
SetError 5 File write verification failed

Error Messages:

  • Console output for debugging
  • MessageBox alerts for critical errors
  • Descriptive error messages in generated code

🔧 Advanced Features

Custom Function Names

Function names are automatically sanitized:

  • Removes invalid characters
  • Includes filename and architecture
  • Format: _GetBinData_filename_architecture

Helper Function Options

For Single File:

_DeployFile($sDestPath = "", $bReturnHex = False)
  • Returns binary data (default)
  • Returns hex string ($bReturnHex = True)
  • Writes to file ($sDestPath provided)

For Multiple Files:

_GetBin($sName)
  • Switch/Case based selection
  • Returns binary data
  • Includes all decode/decompress logic

📊 Performance Tips

  1. Compression Trade-offs:

    • Level 1: Faster, moderate compression
    • Level 2: Slower, better compression
    • Skip compression for files < 10KB
  2. Encoding Selection:

    • Use Hex for debugging (readable)
    • Use Base64 for smaller output size
    • ~33% size increase with Base64 vs binary
  3. Chunk Size:

    • Larger chunks = fewer lines but harder to edit
    • Smaller chunks = more readable but more lines
    • Default 4000 is optimal for most cases

 

🔄 Version History

Version 3.0 (Current)

  • Added Base64 encoding support
  • Integrated LZNT compression (Level 1 & 2)
  • Redesigned GUI with radio buttons
  • Added _GetBin() for multiple files
  • Enhanced _DeployFile() with flexible return options
  • Fixed function naming (sanitization)
  • Improved error handling and reporting
  • Unicode support for Base64 (CryptStringToBinaryW)
  • Workspace allocation for LZNT compression
  • Integrated Base64.au3 library

Version 2.x

  • Legacy hex-only encoding
  • Basic helper functions
  • GUI mode only

📄 License

MIT License - Free to use, modify, and distribute.

 

🙏 Acknowledgments

  • AutoIt Community for feedback and testing
  • LZNT_Base64.au3 library implementation
  • Windows API documentation for LZNT compression

Quick Reference Card

╔══════════════════════════════════════════════════════════════╗
║  QUICK REFERENCE - AutoIt Resource Embedder v3.0            ║
╠══════════════════════════════════════════════════════════════╣
║  GUI Mode:         Double-click script                       ║
║  CLI Mode:         AutoIt3.exe script.au3 file1 file2 ...   ║
║                                                              ║
║  Encoding Options:                                           ║
║    • Hex          - Standard hex encoding                    ║
║    • Base64       - Base64 encoding                          ║
║    • Hex + LZNT   - Hex with compression                     ║
║    • Base64+LZNT  - Base64 with compression                  ║
║                                                              ║
║  Single File:     _DeployFile($path, $bReturnHex)           ║
║  Multiple Files:  _GetBin($filename)                         ║
║                                                              ║
║  Line Length:     100 - 4000 characters (default: 4000)     ║
║  Compression:     Level 1 (4096) or Level 2 (0)             ║
╚══════════════════════════════════════════════════════════════╝

Made with ❤️ by Dao Van Trong - TRONG.PRO

Embed anything, anywhere!

 

SSS.png

App Source:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; =================================================================================================
; Title .........: AutoIt Resource Embedder
; Author(s) .....: Dao Van Trong - TRONG.PRO
; Version .......: 3.0 (Enhanced with multiple encoding formats and compression support)
; Description ...: A professional tool to convert binary files into self-contained AutoIt functions.
;                  Features: Hex/Base64 encoding, LZNT compression, architecture detection,
;                  GUI and CLI modes, helper functions with automatic decompression/decoding.
; =================================================================================================

#Region ; *** INCLUDES ***
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <ListBoxConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>

#include <WinAPIError.au3>
#include <Security.au3>
#include <Memory.au3>
#include <Clipboard.au3>
#include <SendMessage.au3>
#include <WinAPISys.au3>
#include <WinAPISysWin.au3>
#include <GuiStatusBar.au3>
#include <Array.au3>
#include <File.au3>

#EndRegion ; *** INCLUDES ***

#Region ; *** GLOBAL VARIABLES ***
; Global variables for GUI controls
Global $g_hGUI, $g_hListView, $g_hEditOutput, $g_hInputChunkSize, $iStatusBar
Global $g_hBtnAddFiles, $g_hBtnRemoveSelected, $g_hBtnClearAll, $g_hCheckAddHelpers, $g_hBtnGenerate, $g_hBtnPreview, $g_hBtnCopy, $g_hBtnSaveAll, $g_hBtnSaveSeparate, $g_hBtnExit
Global $g_hRadioHex, $g_hRadioBase64, $g_hRadioHexLZNT, $g_hRadioBase64LZNT, $g_hComboCompression

; Global 2D array to store file information.
; Index [x][0]: Full Path
; Index [x][1]: File Name
; Index [x][2]: Formatted File Size
; Index [x][3]: Architecture
; Index [x][4]: Generated Function Name
Global $g_aSelectedFiles[0][5]
#EndRegion ; *** GLOBAL VARIABLES ***

#Region ; *** SCRIPT ENTRY POINT ***
; Check if command-line arguments were provided to determine execution mode.
If $CmdLine[0] > 0 Then
    _RunCommandLineMode()
Else
    _RunGuiMode()
EndIf
#EndRegion ; *** SCRIPT ENTRY POINT ***

#Region ; *** GUI MODE FUNCTIONS ***

; -------------------------------------------------------------------------------------------------
; Function:      _RunGuiMode()
; Purpose:       Creates and manages the main Graphical User Interface (GUI).
; -------------------------------------------------------------------------------------------------
Func _RunGuiMode()
    $g_hGUI = GUICreate("AutoIt Resource Embedder by Dao Van Trong - TRONG.PRO", 795, 555)
    GUISetFont(9, 400, 0, "Segoe UI", $g_hGUI, 5)
    GUISetBkColor(0xF0F0F0)
    _CreateGUI_Controls()
    $iStatusBar = _GUICtrlStatusBar_Create($g_hGUI)
    _GUICtrlStatusBar_SetText($iStatusBar, "Ready | AutoIt Resource Embedder v3.0")
    GUISetState(@SW_SHOW, $g_hGUI)

    Local $nMsg
    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE, $g_hBtnExit
                ExitLoop
            Case $g_hBtnAddFiles
                _GUI_HandleAddFiles()
            Case $g_hBtnRemoveSelected
                _GUI_HandleRemoveSelected()
            Case $g_hBtnClearAll
                _GUI_HandleClearAll()
            Case $g_hBtnGenerate
                _GUI_HandleGenerateAll()
            Case $g_hBtnPreview
                _GUI_HandlePreviewSingle()
            Case $g_hBtnCopy
                _GUI_HandleCopyToClipboard()
            Case $g_hBtnSaveAll
                _GUI_HandleSaveAll()
            Case $g_hBtnSaveSeparate
                _GUI_HandleSaveSeparate()
        EndSwitch
    WEnd
    GUIDelete($g_hGUI)
EndFunc   ;==>_RunGuiMode

; -------------------------------------------------------------------------------------------------
; Function:      _CreateGUI_Controls()
; Purpose:       Creates all controls for the main GUI window.
; -------------------------------------------------------------------------------------------------
Func _CreateGUI_Controls()
    GUICtrlCreateLabel("1. File Selection:", 10, 15, 150, 20, $SS_CENTERIMAGE, $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetFont(-1, 9, 800)
    $g_hBtnAddFiles = GUICtrlCreateButton("Add Files...", 162, 11, 100, 25, BitOR($BS_CENTER, $BS_VCENTER))
    $g_hBtnRemoveSelected = GUICtrlCreateButton("Remove Selected", 272, 11, 120, 25, BitOR($BS_CENTER, $BS_VCENTER))
    $g_hBtnClearAll = GUICtrlCreateButton("Clear All", 402, 11, 80, 25, BitOR($BS_CENTER, $BS_VCENTER))
    $g_hListView = GUICtrlCreateListView("File Name|Size|Architecture|Function Name", 10, 38, 780, 150)
    GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 0, 250)
    GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 1, 100)
    GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 2, 100)
    GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 3, 320)
    GUICtrlCreateLabel("2. Generation Options:", 10, 195, 150, 20, $SS_CENTERIMAGE, $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetFont(-1, 9, 800)
    GUICtrlCreateLabel("Output Format:", 4, 220, 132, 20, BitOR($SS_RIGHT, $SS_CENTERIMAGE), $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetFont(-1, 8, 700, 2)
    $g_hRadioHex = GUICtrlCreateRadio("Hex", 172, 220, 76, 22)
    GUICtrlSetState(-1, $GUI_CHECKED)
    $g_hRadioBase64 = GUICtrlCreateRadio("Base64", 252, 220, 100, 22)
    $g_hRadioHexLZNT = GUICtrlCreateRadio("Hex + LZNT", 358, 220, 100, 22)
    $g_hRadioBase64LZNT = GUICtrlCreateRadio("Base64 + LZNT", 470, 220, 100, 22)
    GUICtrlCreateLabel("LZNT Level:", 584, 220, 100, 20, BitOR($SS_RIGHT, $SS_CENTERIMAGE), $GUI_WS_EX_PARENTDRAG)
    $g_hComboCompression = GUICtrlCreateCombo("", 688, 220, 96, 25, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_SIMPLE))
    GUICtrlSetData($g_hComboCompression, "Level 1|Level 2", "Level 2")

    GUICtrlCreateLabel("Line Length (chars):", 584, 195, 100, 20, BitOR($SS_RIGHT, $SS_CENTERIMAGE), $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetFont(-1, 8, 700, 2)
    $g_hInputChunkSize = GUICtrlCreateInput("4000", 688, 195, 96, 23)
    $g_hCheckAddHelpers = GUICtrlCreateCheckbox("Include helper functions", 172, 195, 200, 22)
    GUICtrlSetState(-1, $GUI_CHECKED)
    $g_hBtnGenerate = GUICtrlCreateButton("3. Generate All Functions", 210, 243, 304, 35, BitOR($BS_CENTER, $BS_VCENTER))
    GUICtrlSetFont(-1, 10, 800)
    GUICtrlSetBkColor($g_hBtnGenerate, 0x90EE90)
    $g_hBtnPreview = GUICtrlCreateButton("Preview Single", 516, 243, 116, 35, BitOR($BS_CENTER, $BS_VCENTER))
    GUICtrlCreateLabel("Generated Code:", 10, 252, 150, 20, $SS_CENTERIMAGE, $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetFont(-1, 9, 800)
    $g_hEditOutput = GUICtrlCreateEdit("", 10, 280, 780, 220)
    GUICtrlSetData(-1, "")
    GUICtrlSetFont(-1, 9, 400)
    $g_hBtnCopy = GUICtrlCreateButton("Copy to Clipboard", 634, 243, 154, 35, BitOR($BS_CENTER, $BS_VCENTER))
    GUICtrlSetFont(-1, 9, 800)
    $g_hBtnSaveAll = GUICtrlCreateButton("Save All to File", 14, 502, 130, 30, BitOR($BS_CENTER, $BS_VCENTER))
    $g_hBtnSaveSeparate = GUICtrlCreateButton("Save Separate Files", 154, 502, 130, 30, BitOR($BS_CENTER, $BS_VCENTER))
    $g_hBtnExit = GUICtrlCreateButton("Exit", 660, 502, 130, 30, BitOR($BS_CENTER, $BS_VCENTER))
    GUICtrlSetBkColor($g_hBtnExit, 0xFFB6C1)

EndFunc   ;==>_CreateGUI_Controls

; -------------------------------------------------------------------------------------------------
; Function:      _GUI_HandleAddFiles()
; Purpose:       Opens a file dialog and adds selected files to the list.
; -------------------------------------------------------------------------------------------------
Func _GUI_HandleAddFiles()
    Local $sFiles = FileOpenDialog("Select Files", @ScriptDir, "All Files (*.*)", 4)
    If @error Then
        _GUICtrlStatusBar_SetText($iStatusBar, "File selection cancelled")
        Return
    EndIf
    
    Local $aNewFiles = StringSplit($sFiles, "|")
    Local $iAdded = 0, $iSkipped = 0
    
    If $aNewFiles[0] = 1 Then
        ; Single file
        If _AddFileToList($aNewFiles[1]) Then
            $iAdded = 1
        Else
            $iSkipped = 1
        EndIf
    Else
        ; Multiple files
        Local $sBasePath = $aNewFiles[1]
        For $i = 2 To $aNewFiles[0]
            If _AddFileToList($sBasePath & "\" & $aNewFiles[$i]) Then
                $iAdded += 1
            Else
                $iSkipped += 1
            EndIf
        Next
    EndIf
    
    ; Update status bar with detailed information
    Local $sStatus = ""
    If $iAdded > 0 Then $sStatus = "Added " & $iAdded & " file" & ($iAdded > 1 ? "s" : "")
    If $iSkipped > 0 Then $sStatus &= ($sStatus <> "" ? " | " : "") & "Skipped " & $iSkipped & " duplicate" & ($iSkipped > 1 ? "s" : "")
    $sStatus &= " | Total: " & UBound($g_aSelectedFiles) & " file(s)"
    _GUICtrlStatusBar_SetText($iStatusBar, $sStatus)
EndFunc   ;==>_GUI_HandleAddFiles

; -------------------------------------------------------------------------------------------------
; Function:      _GUI_HandleRemoveSelected()
; Purpose:       Removes the selected file from the list.
; -------------------------------------------------------------------------------------------------
Func _GUI_HandleRemoveSelected()
    Local $iIndex = GUICtrlSendMsg($g_hListView, $LVM_GETNEXTITEM, -1, $LVNI_SELECTED)
    If $iIndex = -1 Then
        _GUICtrlStatusBar_SetText($iStatusBar, "No file selected")
        Return
    EndIf
    _ArrayDelete($g_aSelectedFiles, $iIndex)
    GUICtrlSendMsg($g_hListView, $LVM_DELETEITEM, $iIndex, 0)
    _GUICtrlStatusBar_SetText($iStatusBar, "File removed | Total: " & UBound($g_aSelectedFiles) & " file(s)")
EndFunc   ;==>_GUI_HandleRemoveSelected

; -------------------------------------------------------------------------------------------------
; Function:      _GUI_HandleClearAll()
; Purpose:       Clears all files from the list and resets the UI.
; -------------------------------------------------------------------------------------------------
Func _GUI_HandleClearAll()
    ReDim $g_aSelectedFiles[0][5]
    GUICtrlSendMsg($g_hListView, $LVM_DELETEALLITEMS, 0, 0)
    GUICtrlSetData($g_hEditOutput, "")
    _GUICtrlStatusBar_SetText($iStatusBar, "All files cleared | Ready")
EndFunc   ;==>_GUI_HandleClearAll

; -------------------------------------------------------------------------------------------------
; Function:      _GUI_HandleGenerateAll()
; Purpose:       Generates the complete code for all files in the list.
; -------------------------------------------------------------------------------------------------
Func _GUI_HandleGenerateAll()
    If UBound($g_aSelectedFiles) = 0 Then Return MsgBox(48, "Warning", "Please add at least one file first.")
    GUICtrlSetData($g_hEditOutput, "Generating code, please wait...")
    Sleep(10)
    Local $bAddHelpers = (GUICtrlRead($g_hCheckAddHelpers) = $GUI_CHECKED)
    Local $iChunkSize = _ValidateChunkSize(GUICtrlRead($g_hInputChunkSize))

    ; Determine encoding/compression from radio buttons
    Local $bUseHex = False, $bUseBase64 = False, $bUseCompression = False, $iCompLevel = 0
    If GUICtrlRead($g_hRadioHex) = $GUI_CHECKED Then
        $bUseHex = True
    ElseIf GUICtrlRead($g_hRadioBase64) = $GUI_CHECKED Then
        $bUseBase64 = True
    ElseIf GUICtrlRead($g_hRadioHexLZNT) = $GUI_CHECKED Then
        $bUseHex = True
        $bUseCompression = True
        $iCompLevel = (GUICtrlRead($g_hComboCompression) = "Level 2") ? 2 : 1
    ElseIf GUICtrlRead($g_hRadioBase64LZNT) = $GUI_CHECKED Then
        $bUseBase64 = True
        $bUseCompression = True
        $iCompLevel = (GUICtrlRead($g_hComboCompression) = "Level 2") ? 2 : 1
    EndIf

    Local $sCode = _GenerateCodeBundle($g_aSelectedFiles, $bAddHelpers, $iChunkSize, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
    GUICtrlSetData($g_hEditOutput, $sCode)
    _GUICtrlStatusBar_SetText($iStatusBar, "Code generated successfully for " & UBound($g_aSelectedFiles) & " file(s) | " & StringLen($sCode) & " characters")
EndFunc   ;==>_GUI_HandleGenerateAll

; -------------------------------------------------------------------------------------------------
; Function:      _GUI_HandlePreviewSingle()
; Purpose:       Generates code for only the selected file.
; -------------------------------------------------------------------------------------------------
Func _GUI_HandlePreviewSingle()
    Local $iIndex = GUICtrlSendMsg($g_hListView, $LVM_GETNEXTITEM, -1, $LVNI_SELECTED)
    If $iIndex = -1 Then Return MsgBox(48, "Warning", "Please select a file from the list first.")
    GUICtrlSetData($g_hEditOutput, "Generating preview...")
    Sleep(10)
    Local $iChunkSize = _ValidateChunkSize(GUICtrlRead($g_hInputChunkSize))

    ; Determine encoding/compression from radio buttons
    Local $bUseHex = False, $bUseBase64 = False, $bUseCompression = False, $iCompLevel = 0
    If GUICtrlRead($g_hRadioHex) = $GUI_CHECKED Then
        $bUseHex = True
    ElseIf GUICtrlRead($g_hRadioBase64) = $GUI_CHECKED Then
        $bUseBase64 = True
    ElseIf GUICtrlRead($g_hRadioHexLZNT) = $GUI_CHECKED Then
        $bUseHex = True
        $bUseCompression = True
        $iCompLevel = (GUICtrlRead($g_hComboCompression) = "Level 2") ? 2 : 1
    ElseIf GUICtrlRead($g_hRadioBase64LZNT) = $GUI_CHECKED Then
        $bUseBase64 = True
        $bUseCompression = True
        $iCompLevel = (GUICtrlRead($g_hComboCompression) = "Level 2") ? 2 : 1
    EndIf

    Local $sOutput = "; Preview for: " & $g_aSelectedFiles[$iIndex][1] & @CRLF
    $sOutput &= "; Architecture: " & $g_aSelectedFiles[$iIndex][3] & @CRLF & @CRLF
    Local $sCode = _GenerateEncodedFunction($g_aSelectedFiles[$iIndex][0], $g_aSelectedFiles[$iIndex][4], $g_aSelectedFiles[$iIndex][1], $g_aSelectedFiles[$iIndex][3], $iChunkSize, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
    If GUICtrlRead($g_hCheckAddHelpers) = $GUI_CHECKED Then
        $sCode &= @CRLF & @CRLF & _GenerateHelperFunction($g_aSelectedFiles[$iIndex][4], $g_aSelectedFiles[$iIndex][1], $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
    EndIf
    GUICtrlSetData($g_hEditOutput, $sOutput & $sCode)
    _GUICtrlStatusBar_SetText($iStatusBar, "Preview generated for: " & $g_aSelectedFiles[$iIndex][1])
EndFunc   ;==>_GUI_HandlePreviewSingle

; -------------------------------------------------------------------------------------------------
; Function:      _GUI_HandleCopyToClipboard()
; Purpose:       Copies the output text to the clipboard.
; -------------------------------------------------------------------------------------------------
Func _GUI_HandleCopyToClipboard()
    Local $sCode = GUICtrlRead($g_hEditOutput)
    If StringStripWS($sCode, 8) = "" Then
        _GUICtrlStatusBar_SetText($iStatusBar, "No code to copy")
        Return MsgBox(48, "Warning", "No code to copy. Please generate code first.")
    EndIf
    _ClipBoard_SetData($sCode)
    _GUICtrlStatusBar_SetText($iStatusBar, "Code copied to clipboard | " & StringLen($sCode) & " characters")
    MsgBox(64, "Success", "Code copied to clipboard successfully!")
    GUICtrlSetData($g_hEditOutput, $sCode)
EndFunc   ;==>_GUI_HandleCopyToClipboard

; -------------------------------------------------------------------------------------------------
; Function:      _GUI_HandleSaveAll()
; Purpose:       Saves the generated code for all files into a single .au3 file.
; -------------------------------------------------------------------------------------------------
Func _GUI_HandleSaveAll()
    Local $sCode = GUICtrlRead($g_hEditOutput)
    If StringStripWS($sCode, 8) = "" Then Return MsgBox(48, "Warning", "No code to save. Please generate code first.")
    Local $sSaveFile = FileSaveDialog("Save Combined Code", @ScriptDir, "AutoIt Scripts (*.au3)", 16, "All_Embedded.au3")
    If @error Then Return
    If @error Or Not _SaveStringToFile($sSaveFile, $sCode) Then
        _GUICtrlStatusBar_SetText($iStatusBar, "Save failed: " & $sSaveFile)
        Return MsgBox(16, "Error", "Failed to save file: " & $sSaveFile)
    EndIf
    _GUICtrlStatusBar_SetText($iStatusBar, "File saved: " & $sSaveFile & " | " & _FormatFileSize(FileGetSize($sSaveFile)))
    MsgBox(64, "Success", "File saved successfully: " & $sSaveFile)
EndFunc   ;==>_GUI_HandleSaveAll

; -------------------------------------------------------------------------------------------------
; Function:      _GUI_HandleSaveSeparate()
; Purpose:       Saves the generated code for each file into its own separate .au3 file.
; -------------------------------------------------------------------------------------------------
Func _GUI_HandleSaveSeparate()
    If UBound($g_aSelectedFiles) = 0 Then Return MsgBox(48, "Warning", "No files to process.")
    Local $sSaveDir = FileSelectFolder("Select folder to save separate files", @ScriptDir)
    If @error Then Return
    Local $iChunkSize = _ValidateChunkSize(GUICtrlRead($g_hInputChunkSize))
    Local $bAddHelpers = (GUICtrlRead($g_hCheckAddHelpers) = $GUI_CHECKED)

    ; Determine encoding/compression from radio buttons
    Local $bUseHex = False, $bUseBase64 = False, $bUseCompression = False, $iCompLevel = 0
    If GUICtrlRead($g_hRadioHex) = $GUI_CHECKED Then
        $bUseHex = True
    ElseIf GUICtrlRead($g_hRadioBase64) = $GUI_CHECKED Then
        $bUseBase64 = True
    ElseIf GUICtrlRead($g_hRadioHexLZNT) = $GUI_CHECKED Then
        $bUseHex = True
        $bUseCompression = True
        $iCompLevel = (GUICtrlRead($g_hComboCompression) = "Level 2") ? 2 : 1
    ElseIf GUICtrlRead($g_hRadioBase64LZNT) = $GUI_CHECKED Then
        $bUseBase64 = True
        $bUseCompression = True
        $iCompLevel = (GUICtrlRead($g_hComboCompression) = "Level 2") ? 2 : 1
    EndIf

    Local $iSaved = 0
    For $i = 0 To UBound($g_aSelectedFiles) - 1
        Local $sFilePath = $g_aSelectedFiles[$i][0]
        Local $sFileName = $g_aSelectedFiles[$i][1]
        Local $sArch = $g_aSelectedFiles[$i][3]
        Local $sFuncName = $g_aSelectedFiles[$i][4]
        Local $sDrive, $sDir, $sNameOnly, $sExt
        _PathSplit($sFilePath, $sDrive, $sDir, $sNameOnly, $sExt)
        Local $sSaveFile = $sSaveDir & "\" & $sNameOnly & "_Embedded.au3"
        Local $sCode = "; Generated from: " & $sFileName & @CRLF
        $sCode &= "; Architecture: " & $sArch & @CRLF & @CRLF
        $sCode &= _GenerateEncodedFunction($sFilePath, $sFuncName, $sFileName, $sArch, $iChunkSize, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
        If $bAddHelpers Then
            $sCode &= _GenerateHelperFunction($sFuncName, $sFileName, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
        EndIf
        If _SaveStringToFile($sSaveFile, $sCode) Then $iSaved += 1
    Next
    _GUICtrlStatusBar_SetText($iStatusBar, "Saved " & $iSaved & " of " & UBound($g_aSelectedFiles) & " file(s) to: " & $sSaveDir)
    MsgBox(64, "Success", "Saved " & $iSaved & " of " & UBound($g_aSelectedFiles) & " files to:" & @CRLF & $sSaveDir)
EndFunc   ;==>_GUI_HandleSaveSeparate
#EndRegion ; *** GUI MODE FUNCTIONS ***

#Region ; *** COMMAND-LINE MODE FUNCTIONS ***

; -------------------------------------------------------------------------------------------------
; Function:      _RunCommandLineMode()
; Purpose:       Handles the script's execution when run from the command line.
; -------------------------------------------------------------------------------------------------
Func _RunCommandLineMode()
    Local $aFilePaths[0]
    For $i = 1 To $CmdLine[0]
        If FileExists($CmdLine[$i]) Then
            _ArrayAdd($aFilePaths, $CmdLine[$i])
        Else
            ConsoleWrite("! Warning: File not found - " & $CmdLine[$i] & @CRLF)
        EndIf
    Next
    If UBound($aFilePaths) = 0 Then
        ConsoleWrite("! Error: No valid files provided." & @CRLF & "  Usage: " & @ScriptName & " <file1> [file2] ..." & @CRLF)
        Exit 1
    EndIf
    Local $aFilesData[UBound($aFilePaths)][5]
    For $i = 0 To UBound($aFilePaths) - 1
        _PopulateFileInfo($aFilesData, $i, $aFilePaths[$i])
    Next
    ConsoleWrite("+ Generating code for " & UBound($aFilesData) & " file(s)..." & @CRLF)
    Local $sCode = _GenerateCodeBundle($aFilesData, True, 4000, True, False, False, 0)
    Local $sOutputFile
    If UBound($aFilesData) = 1 Then
        Local $sDrive, $sDir, $sFileName, $sExtension
        _PathSplit($aFilePaths[0], $sDrive, $sDir, $sFileName, $sExtension)
        $sOutputFile = $sDrive & $sDir & $sFileName & "_Embedded.au3"
    Else
        $sOutputFile = @ScriptDir & "\All_Embedded.au3"
    EndIf
    If _SaveStringToFile($sOutputFile, $sCode) Then
        ConsoleWrite("+ Success: Output saved to - " & $sOutputFile & @CRLF)
    Else
        ConsoleWrite("! Error: Could not create output file - " & $sOutputFile & @CRLF)
        Exit 1
    EndIf
EndFunc   ;==>_RunCommandLineMode
#EndRegion ; *** COMMAND-LINE MODE FUNCTIONS ***

#Region ; *** FILE AND DATA HANDLING ***

; -------------------------------------------------------------------------------------------------
; Function:      _AddFileToList($sFilePath)
; Purpose:       Adds a file's information to the global array and updates the GUI list.
;                Prevents duplicate files from being added.
; -------------------------------------------------------------------------------------------------
Func _AddFileToList($sFilePath)
    ; Validate file exists
    If Not FileExists($sFilePath) Then
        _GUICtrlStatusBar_SetText($iStatusBar, "File not found: " & $sFilePath)
        Return False
    EndIf
    
    ; Check for duplicate - exact path match
    For $i = 0 To UBound($g_aSelectedFiles) - 1
        If $g_aSelectedFiles[$i][0] = $sFilePath Then
            Local $sFileName = _GetFileName($sFilePath)
            _GUICtrlStatusBar_SetText($iStatusBar, "Duplicate skipped: " & $sFileName & " (already in list)")
            Return False
        EndIf
    Next
    
    ; Add new file
    Local $iUBound = UBound($g_aSelectedFiles)
    ReDim $g_aSelectedFiles[$iUBound + 1][5]
    _PopulateFileInfo($g_aSelectedFiles, $iUBound, $sFilePath)
    Local $sListViewItem = $g_aSelectedFiles[$iUBound][1] & "|" & $g_aSelectedFiles[$iUBound][2] & "|" & $g_aSelectedFiles[$iUBound][3] & "|" & $g_aSelectedFiles[$iUBound][4]
    GUICtrlCreateListViewItem($sListViewItem, $g_hListView)
    Return True
EndFunc   ;==>_AddFileToList

; -------------------------------------------------------------------------------------------------
; Function:      _PopulateFileInfo(ByRef $aArray, $iIndex, $sFilePath)
; Purpose:       Gathers file info and populates a row in the provided 2D array.
; -------------------------------------------------------------------------------------------------
Func _PopulateFileInfo(ByRef $aArray, $iIndex, $sFilePath)
    Local $sFileName = _GetFileName($sFilePath)
    Local $sArch = _DetectArchitecture($sFilePath)
    $aArray[$iIndex][0] = $sFilePath
    $aArray[$iIndex][1] = $sFileName
    $aArray[$iIndex][2] = _FormatFileSize(FileGetSize($sFilePath))
    $aArray[$iIndex][3] = $sArch
    $aArray[$iIndex][4] = "_GetBinData_" & _SanitizeName($sFileName) & "_" & _SanitizeName($sArch)
EndFunc   ;==>_PopulateFileInfo
#EndRegion ; *** FILE AND DATA HANDLING ***

#Region ; *** CORE CODE GENERATION ***

; -------------------------------------------------------------------------------------------------
; Function:      _GenerateCodeBundle(ByRef $aFiles, $bAddHelpers, $iChunkSize, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
; Purpose:       The main code generation engine. Creates the full script content.
; -------------------------------------------------------------------------------------------------
Func _GenerateCodeBundle(ByRef $aFiles, $bAddHelpers, $iChunkSize, $bUseHex = True, $bUseBase64 = False, $bUseCompression = False, $iCompLevel = 0)
    Local $sOutput = "; Generated by AutoIt Resource Embedder - TRONG.PRO" & @CRLF
    $sOutput &= "; Total files: " & UBound($aFiles) & @CRLF
    $sOutput &= "; Encoding: " & ($bUseHex ? "Hex " : "") & ($bUseBase64 ? "Base64 " : "") & @CRLF
    $sOutput &= "; Compression: " & ($bUseCompression And $iCompLevel > 0 ? "LZNT Level " & $iCompLevel : "None") & @CRLF
    $sOutput &= "; Generated on: " & @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF
    For $i = 0 To UBound($aFiles) - 1
        $sOutput &= _GenerateEncodedFunction($aFiles[$i][0], $aFiles[$i][4], $aFiles[$i][1], $aFiles[$i][3], $iChunkSize, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel) & @CRLF & @CRLF
    Next
    If $bAddHelpers Then
        If UBound($aFiles) = 1 Then
            $sOutput &= _GenerateHelperFunction($aFiles[0][4], $aFiles[0][1], $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
        Else
            $sOutput &= _GenerateMasterHelperFunctionFromArray($aFiles, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
        EndIf
    EndIf
    Return $sOutput
EndFunc   ;==>_GenerateCodeBundle

; -------------------------------------------------------------------------------------------------
; Function:      _GenerateEncodedFunction($sFilePath, $sFuncName, $sFileName, $sArch, $iChunkSize, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
; Purpose:       Reads a binary file and wraps its encoded content in an AutoIt function.
; -------------------------------------------------------------------------------------------------
Func _GenerateEncodedFunction($sFilePath, $sFuncName, $sFileName, $sArch, $iChunkSize = 4000, $bUseHex = True, $bUseBase64 = False, $bUseCompression = False, $iCompLevel = 0)
    Local $hFile = FileOpen($sFilePath, 16)
    If $hFile = -1 Then
        ConsoleWrite("! Error: Unable to open file in binary mode: " & $sFilePath & @CRLF)
        Return ""
    EndIf
    Local $bData = FileRead($hFile)
    FileClose($hFile)
    If @error Or $bData = "" Then
        ConsoleWrite("! Error reading binary data from file: " & $sFilePath & @CRLF)
        Return ""
    EndIf

    ; Apply compression if requested
    Local $bProcessedData = $bData
    If $bUseCompression And $iCompLevel > 0 Then
        Local $iEngine = ($iCompLevel = 2) ? 258 : 2 ; 2=Standard, 258=Maximum
        $bProcessedData = _LZNT_Compress($bData, 16, $iEngine, False) ; Updated library signature
        If @error Then
            ConsoleWrite("! Error: LZNT compression failed for file: " & $sFilePath & @CRLF)
            MsgBox(16, "Compression Error", "Failed to compress file: " & $sFileName & @CRLF & @CRLF & "Please try again or disable compression.")
            Return ""
        EndIf
        ConsoleWrite("+ Compressed " & $sFileName & ": " & _FormatFileSize(BinaryLen($bData)) & " → " & _FormatFileSize(BinaryLen($bProcessedData)) & @CRLF)
    EndIf

    ; Generate function header
    Local $sOutput = "Func " & $sFuncName & "()" & @CRLF
    $sOutput &= @TAB & '; This function holds the encoded data for ' & $sFileName & @CRLF
    $sOutput &= @TAB & '; File size: ' & _FormatFileSize(FileGetSize($sFilePath)) & @CRLF
    $sOutput &= @TAB & '; Architecture: ' & $sArch & @CRLF
    $sOutput &= @TAB & '; Encoding: ' & ($bUseHex ? "Hex " : "") & ($bUseBase64 ? "Base64 " : "") & @CRLF
    $sOutput &= @TAB & '; Compression: ' & ($bUseCompression And $iCompLevel > 0 ? "LZNT Level " & $iCompLevel : "None") & @CRLF
    $sOutput &= @TAB & '; Generated by AutoIt Resource Embedder' & @CRLF

    ; Generate Hex data if requested
    If $bUseHex Then
        Local $sHexWithPrefix = String($bProcessedData)
        Local $iHexLen = StringLen($sHexWithPrefix)
        $sOutput &= @TAB & "Local $sHexData = '" & StringMid($sHexWithPrefix, 1, $iChunkSize) & "'" & @CRLF
        For $i = $iChunkSize + 1 To $iHexLen Step $iChunkSize
            $sOutput &= @TAB & "$sHexData &= '" & StringMid($sHexWithPrefix, $i, $iChunkSize) & "'" & @CRLF
        Next
    EndIf

    ; Generate Base64 data if requested
    If $bUseBase64 Then
        Local $sBase64 = _Base64Encode($bProcessedData, 0) ; 0 = no line breaks
        If @error Or $sBase64 = "" Then
            ConsoleWrite("! Error: Base64 encoding failed for file: " & $sFilePath & @CRLF)
            MsgBox(16, "Encoding Error", "Failed to encode file to Base64: " & $sFileName & @CRLF & @CRLF & "Please try again or use Hex encoding.")
            Return ""
        EndIf
        Local $iB64Len = StringLen($sBase64)
        $sOutput &= @TAB & "Local $sBase64Data = '" & StringMid($sBase64, 1, $iChunkSize) & "'" & @CRLF
        For $i = $iChunkSize + 1 To $iB64Len Step $iChunkSize
            $sOutput &= @TAB & "$sBase64Data &= '" & StringMid($sBase64, $i, $iChunkSize) & "'" & @CRLF
        Next
    EndIf

    ; Return appropriate data based on encoding options
    $sOutput &= @CRLF
    If $bUseHex And $bUseBase64 Then
        $sOutput &= @TAB & '; Returns array: [0] = Hex, [1] = Base64' & @CRLF
        $sOutput &= @TAB & 'Local $aData[2] = [$sHexData, $sBase64Data]' & @CRLF
        $sOutput &= @TAB & 'Return $aData' & @CRLF
    ElseIf $bUseHex Then
        $sOutput &= @TAB & 'Return $sHexData' & @CRLF
    Else
        $sOutput &= @TAB & 'Return $sBase64Data' & @CRLF
    EndIf

    $sOutput &= "EndFunc   ;==>" & $sFuncName
    Return $sOutput
EndFunc   ;==>_GenerateEncodedFunction

; -------------------------------------------------------------------------------------------------
; Function:      _GenerateHelperFunction($sFuncName, $sOriginalFileName, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
; Purpose:       Generates a helper function to deploy a single embedded file with decode/decompress support.
; -------------------------------------------------------------------------------------------------
Func _GenerateHelperFunction($sFuncName, $sOriginalFileName, $bUseHex = True, $bUseBase64 = False, $bUseCompression = False, $iCompLevel = 0)
    Local $sHelperFunc = @CRLF & @CRLF

    ; Add Base64 decode function if needed
    If $bUseBase64 Then
        $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
        $sHelperFunc &= '; Base64 Decode Function (Unicode version - matches Base64.au3 encoder)' & @CRLF
        $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
        $sHelperFunc &= 'Func _Base64Decode($sB64String)' & @CRLF
        $sHelperFunc &= @TAB & '; Remove whitespace' & @CRLF
        $sHelperFunc &= @TAB & '$sB64String = StringRegExpReplace($sB64String, "\s", "")' & @CRLF
        $sHelperFunc &= @TAB & 'If $sB64String = "" Then Return SetError(1, 0, Binary(""))' & @CRLF
        $sHelperFunc &= @TAB & '; Get required buffer size' & @CRLF
        $sHelperFunc &= @TAB & 'Local $aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", "wstr", $sB64String, "dword", StringLen($sB64String), "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Or Not $aResult[0] Then Return SetError(2, 0, Binary(""))' & @CRLF
        $sHelperFunc &= @TAB & 'Local $iSize = $aResult[5]' & @CRLF
        $sHelperFunc &= @TAB & 'Local $tOutput = DllStructCreate("byte[" & $iSize & "]")' & @CRLF
        $sHelperFunc &= @TAB & '; Perform decoding' & @CRLF
        $sHelperFunc &= @TAB & '$aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", "wstr", $sB64String, "dword", StringLen($sB64String), "dword", 1, "struct*", $tOutput, "dword*", $iSize, "ptr", 0, "ptr", 0)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Or Not $aResult[0] Then Return SetError(3, 0, Binary(""))' & @CRLF
        $sHelperFunc &= @TAB & 'Return DllStructGetData($tOutput, 1)' & @CRLF
        $sHelperFunc &= 'EndFunc   ;==>_Base64Decode' & @CRLF & @CRLF
    EndIf

    ; Add LZNT decompress function if needed
    If $bUseCompression And $iCompLevel > 0 Then
        Local $iEngine = ($iCompLevel = 2) ? 258 : 2
        $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
        $sHelperFunc &= '; LZNT Decompress Function (Engine: ' & $iEngine & ', Level: ' & $iCompLevel & ')' & @CRLF
        $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
        $sHelperFunc &= 'Func _LZNT_Decompress($bCompressed)' & @CRLF
        $sHelperFunc &= @TAB & 'Local $tInput = DllStructCreate("byte[" & BinaryLen($bCompressed) & "]")' & @CRLF
        $sHelperFunc &= @TAB & 'DllStructSetData($tInput, 1, $bCompressed)' & @CRLF
        $sHelperFunc &= @TAB & 'Local $tOutput = DllStructCreate("byte[" & (BinaryLen($bCompressed) * 16) & "]")' & @CRLF
        $sHelperFunc &= @TAB & 'Local $aRet = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", "ushort", ' & $iEngine & ', "ptr", DllStructGetPtr($tOutput), "dword", DllStructGetSize($tOutput), "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), "dword*", 0)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Or $aRet[0] <> 0 Then Return SetError(1, 0, Binary(""))' & @CRLF
        $sHelperFunc &= @TAB & 'Local $tOut = DllStructCreate("byte[" & $aRet[6] & "]", DllStructGetPtr($tOutput))' & @CRLF
        $sHelperFunc &= @TAB & 'Return DllStructGetData($tOut, 1)' & @CRLF
        $sHelperFunc &= 'EndFunc   ;==>_LZNT_Decompress' & @CRLF & @CRLF
    EndIf

    ; Add WriteBinaryFile helper function
    $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
    $sHelperFunc &= '; Write Binary File Function' & @CRLF
    $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
    $sHelperFunc &= 'Func _WriteBinaryFile($sFilePath, $bBinaryData)' & @CRLF
    $sHelperFunc &= @TAB & 'If Not IsBinary($bBinaryData) Then Return SetError(1, 0, False)' & @CRLF
    $sHelperFunc &= @TAB & 'If BinaryLen($bBinaryData) = 0 Then Return SetError(2, 0, False)' & @CRLF
    $sHelperFunc &= @TAB & '; Remove existing file/folder' & @CRLF
    $sHelperFunc &= @TAB & 'If FileExists($sFilePath) Then' & @CRLF
    $sHelperFunc &= @TAB & @TAB & 'FileSetAttrib($sFilePath, "-RASH", 1)' & @CRLF
    $sHelperFunc &= @TAB & @TAB & 'DirRemove($sFilePath, 1)' & @CRLF
    $sHelperFunc &= @TAB & @TAB & 'FileDelete($sFilePath)' & @CRLF
    $sHelperFunc &= @TAB & 'EndIf' & @CRLF
    $sHelperFunc &= @TAB & '; Write binary data' & @CRLF
    $sHelperFunc &= @TAB & 'Local $hFile = FileOpen($sFilePath, 2 + 8 + 16) ; Write + Create + Binary' & @CRLF
    $sHelperFunc &= @TAB & 'If $hFile = -1 Then Return SetError(3, 0, False)' & @CRLF
    $sHelperFunc &= @TAB & 'FileWrite($hFile, $bBinaryData)' & @CRLF
    $sHelperFunc &= @TAB & 'FileClose($hFile)' & @CRLF
    $sHelperFunc &= @TAB & 'Return FileExists($sFilePath)' & @CRLF
    $sHelperFunc &= 'EndFunc   ;==>_WriteBinaryFile' & @CRLF & @CRLF

    ; Generate deployment function
    $sHelperFunc &= '; =================================================================' & @CRLF
    $sHelperFunc &= '; Helper function to deploy the file from encoded data.' & @CRLF
    $sHelperFunc &= '; Parameters: $sDestPath - File path to write (empty = return binary)' & @CRLF
    $sHelperFunc &= ';             $bReturnHex - Return hex string instead of binary (Default: False)' & @CRLF
    $sHelperFunc &= '; Encoding: ' & ($bUseHex ? "Hex " : "") & ($bUseBase64 ? "Base64 " : "") & @CRLF
    $sHelperFunc &= '; Compression: ' & ($bUseCompression And $iCompLevel > 0 ? "LZNT Level " & $iCompLevel : "None") & @CRLF
    $sHelperFunc &= '; =================================================================' & @CRLF
    $sHelperFunc &= 'Func _DeployFile($sDestPath = "", $bReturnHex = False)' & @CRLF
    $sHelperFunc &= @TAB & '; Get encoded data from main function' & @CRLF

    ; Handle data retrieval based on encoding options
    If $bUseHex And $bUseBase64 Then
        $sHelperFunc &= @TAB & 'Local $aData = ' & $sFuncName & '()' & @CRLF
        $sHelperFunc &= @TAB & 'If Not IsArray($aData) Then Return SetError(1, 0, "")' & @CRLF
        $sHelperFunc &= @TAB & 'Local $bBinary = Binary($aData[0]) ; Use Hex data' & @CRLF
    ElseIf $bUseHex Then
        $sHelperFunc &= @TAB & 'Local $sHexData = ' & $sFuncName & '()' & @CRLF
        $sHelperFunc &= @TAB & 'If $sHexData = "" Then Return SetError(1, 0, "")' & @CRLF
        $sHelperFunc &= @TAB & 'Local $bBinary = Binary($sHexData)' & @CRLF
    Else
        $sHelperFunc &= @TAB & 'Local $sBase64Data = ' & $sFuncName & '()' & @CRLF
        $sHelperFunc &= @TAB & 'If $sBase64Data = "" Then Return SetError(1, 0, "")' & @CRLF
        $sHelperFunc &= @TAB & 'Local $bBinary = _Base64Decode($sBase64Data)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Then Return SetError(2, 0, "")' & @CRLF
    EndIf

    ; Add decompression if needed
    If $bUseCompression And $iCompLevel > 0 Then
        $sHelperFunc &= @CRLF & @TAB & '; Decompress the data' & @CRLF
        $sHelperFunc &= @TAB & '$bBinary = _LZNT_Decompress($bBinary)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Then Return SetError(3, 0, "")' & @CRLF
    EndIf

    ; Return binary/hex or write to file
    $sHelperFunc &= @CRLF & @TAB & '; If no destination path, return binary or hex string' & @CRLF
    $sHelperFunc &= @TAB & 'If $sDestPath = "" Then' & @CRLF
    $sHelperFunc &= @TAB & @TAB & 'If $bReturnHex Then' & @CRLF
    $sHelperFunc &= @TAB & @TAB & @TAB & 'Return StringTrimLeft($bBinary, 2) ; Remove "0x" prefix' & @CRLF
    $sHelperFunc &= @TAB & @TAB & 'Else' & @CRLF
    $sHelperFunc &= @TAB & @TAB & @TAB & 'Return $bBinary' & @CRLF
    $sHelperFunc &= @TAB & @TAB & 'EndIf' & @CRLF
    $sHelperFunc &= @TAB & 'EndIf' & @CRLF
    $sHelperFunc &= @CRLF & @TAB & '; Write binary data to file' & @CRLF
    $sHelperFunc &= @TAB & 'If Not _WriteBinaryFile($sDestPath, $bBinary) Then Return SetError(4, 0, "")' & @CRLF
    $sHelperFunc &= @TAB & 'Return $sDestPath' & @CRLF
    $sHelperFunc &= 'EndFunc   ;==>_DeployFile' & @CRLF & @CRLF
    $sHelperFunc &= '; Example usage:' & @CRLF
    $sHelperFunc &= '; $bBinary = _DeployFile() ; Get binary data' & @CRLF
    $sHelperFunc &= '; $sHex = _DeployFile("", True) ; Get hex string' & @CRLF
    $sHelperFunc &= '; $sPath = _DeployFile(@TempDir & "\' & $sOriginalFileName & '") ; Write to file' & @CRLF

    Return $sHelperFunc
EndFunc   ;==>_GenerateHelperFunction

; -------------------------------------------------------------------------------------------------
; Function:      _GenerateMasterHelperFunctionFromArray(ByRef $aFiles, $bUseHex, $bUseBase64, $bUseCompression, $iCompLevel)
; Purpose:       Generates _GetBin() function with Switch/Case for all embedded files.
; -------------------------------------------------------------------------------------------------
Func _GenerateMasterHelperFunctionFromArray(ByRef $aFiles, $bUseHex = True, $bUseBase64 = False, $bUseCompression = False, $iCompLevel = 0)
    Local $sHelperFunc = @CRLF & @CRLF

    ; Add Base64 decode function if needed
    If $bUseBase64 Then
        $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
        $sHelperFunc &= '; Base64 Decode Function (Unicode version - matches Base64.au3 encoder)' & @CRLF
        $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
        $sHelperFunc &= 'Func _Base64Decode($sB64String)' & @CRLF
        $sHelperFunc &= @TAB & '; Remove whitespace' & @CRLF
        $sHelperFunc &= @TAB & '$sB64String = StringRegExpReplace($sB64String, "\s", "")' & @CRLF
        $sHelperFunc &= @TAB & 'If $sB64String = "" Then Return SetError(1, 0, Binary(""))' & @CRLF
        $sHelperFunc &= @TAB & '; Get required buffer size' & @CRLF
        $sHelperFunc &= @TAB & 'Local $aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", "wstr", $sB64String, "dword", StringLen($sB64String), "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Or Not $aResult[0] Then Return SetError(2, 0, Binary(""))' & @CRLF
        $sHelperFunc &= @TAB & 'Local $iSize = $aResult[5]' & @CRLF
        $sHelperFunc &= @TAB & 'Local $tOutput = DllStructCreate("byte[" & $iSize & "]")' & @CRLF
        $sHelperFunc &= @TAB & '; Perform decoding' & @CRLF
        $sHelperFunc &= @TAB & '$aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", "wstr", $sB64String, "dword", StringLen($sB64String), "dword", 1, "struct*", $tOutput, "dword*", $iSize, "ptr", 0, "ptr", 0)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Or Not $aResult[0] Then Return SetError(3, 0, Binary(""))' & @CRLF
        $sHelperFunc &= @TAB & 'Return DllStructGetData($tOutput, 1)' & @CRLF
        $sHelperFunc &= 'EndFunc   ;==>_Base64Decode' & @CRLF & @CRLF
    EndIf

    ; Add LZNT decompress function if needed
    If $bUseCompression And $iCompLevel > 0 Then
        Local $iEngine = ($iCompLevel = 2) ? 258 : 2
        $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
        $sHelperFunc &= '; LZNT Decompress Function (Engine: ' & $iEngine & ', Level: ' & $iCompLevel & ')' & @CRLF
        $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
        $sHelperFunc &= 'Func _LZNT_Decompress($bCompressed)' & @CRLF
        $sHelperFunc &= @TAB & 'Local $tInput = DllStructCreate("byte[" & BinaryLen($bCompressed) & "]")' & @CRLF
        $sHelperFunc &= @TAB & 'DllStructSetData($tInput, 1, $bCompressed)' & @CRLF
        $sHelperFunc &= @TAB & 'Local $tOutput = DllStructCreate("byte[" & (BinaryLen($bCompressed) * 16) & "]")' & @CRLF
        $sHelperFunc &= @TAB & 'Local $aRet = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", "ushort", ' & $iEngine & ', "ptr", DllStructGetPtr($tOutput), "dword", DllStructGetSize($tOutput), "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), "dword*", 0)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Or $aRet[0] <> 0 Then Return SetError(1, 0, Binary(""))' & @CRLF
        $sHelperFunc &= @TAB & 'Local $tOut = DllStructCreate("byte[" & $aRet[6] & "]", DllStructGetPtr($tOutput))' & @CRLF
        $sHelperFunc &= @TAB & 'Return DllStructGetData($tOut, 1)' & @CRLF
        $sHelperFunc &= 'EndFunc   ;==>_LZNT_Decompress' & @CRLF & @CRLF
    EndIf

    ; Add WriteBinaryFile helper function
    $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
    $sHelperFunc &= '; Write Binary File Function' & @CRLF
    $sHelperFunc &= '; -------------------------------------------------------------------------------------------------' & @CRLF
    $sHelperFunc &= 'Func _WriteBinaryFile($sFilePath, $bBinaryData)' & @CRLF
    $sHelperFunc &= @TAB & 'If Not IsBinary($bBinaryData) Then Return SetError(1, 0, False)' & @CRLF
    $sHelperFunc &= @TAB & 'If BinaryLen($bBinaryData) = 0 Then Return SetError(2, 0, False)' & @CRLF
    $sHelperFunc &= @TAB & '; Remove existing file/folder' & @CRLF
    $sHelperFunc &= @TAB & 'If FileExists($sFilePath) Then' & @CRLF
    $sHelperFunc &= @TAB & @TAB & 'FileSetAttrib($sFilePath, "-RASH", 1)' & @CRLF
    $sHelperFunc &= @TAB & @TAB & 'DirRemove($sFilePath, 1)' & @CRLF
    $sHelperFunc &= @TAB & @TAB & 'FileDelete($sFilePath)' & @CRLF
    $sHelperFunc &= @TAB & 'EndIf' & @CRLF
    $sHelperFunc &= @TAB & '; Write binary data' & @CRLF
    $sHelperFunc &= @TAB & 'Local $hFile = FileOpen($sFilePath, 2 + 8 + 16) ; Write + Create + Binary' & @CRLF
    $sHelperFunc &= @TAB & 'If $hFile = -1 Then Return SetError(3, 0, False)' & @CRLF
    $sHelperFunc &= @TAB & 'FileWrite($hFile, $bBinaryData)' & @CRLF
    $sHelperFunc &= @TAB & 'FileClose($hFile)' & @CRLF
    $sHelperFunc &= @TAB & 'Return FileExists($sFilePath)' & @CRLF
    $sHelperFunc &= 'EndFunc   ;==>_WriteBinaryFile' & @CRLF & @CRLF

    $sHelperFunc &= '; =================================================================' & @CRLF
    $sHelperFunc &= '; Helper function to get binary data by filename.' & @CRLF
    $sHelperFunc &= '; Usage: $bData = _GetBin("filename.ext")' & @CRLF
    $sHelperFunc &= '; Encoding: ' & ($bUseHex ? "Hex " : "") & ($bUseBase64 ? "Base64 " : "") & @CRLF
    $sHelperFunc &= '; Compression: ' & ($bUseCompression And $iCompLevel > 0 ? "LZNT Level " & $iCompLevel : "None") & @CRLF
    $sHelperFunc &= '; =================================================================' & @CRLF
    $sHelperFunc &= 'Func _GetBin($sName)' & @CRLF
    $sHelperFunc &= @TAB & 'Local $sData = ""' & @CRLF
    $sHelperFunc &= @TAB & 'Switch $sName' & @CRLF

    ; Generate Switch cases for each file
    For $i = 0 To UBound($aFiles) - 1
        Local $sFileName = $aFiles[$i][1]
        Local $sFuncName = $aFiles[$i][4]
        $sHelperFunc &= @TAB & @TAB & 'Case "' & $sFileName & '"' & @CRLF
        $sHelperFunc &= @TAB & @TAB & @TAB & '$sData = ' & $sFuncName & '()' & @CRLF
    Next

    $sHelperFunc &= @TAB & 'EndSwitch' & @CRLF
    $sHelperFunc &= @CRLF
    $sHelperFunc &= @TAB & '; Decode from encoding format to binary' & @CRLF
    $sHelperFunc &= @TAB & 'If $sData = "" Then Return SetError(1, 0, Binary(""))' & @CRLF
    $sHelperFunc &= @TAB & 'Local $bData' & @CRLF
    If $bUseBase64 Then
        $sHelperFunc &= @TAB & '$bData = _Base64Decode($sData)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Then Return SetError(2, 0, Binary(""))' & @CRLF
    Else
        $sHelperFunc &= @TAB & '$bData = Binary($sData) ; Hex to binary' & @CRLF
    EndIf

    ; Add decompression if needed
    If $bUseCompression And $iCompLevel > 0 Then
        $sHelperFunc &= @CRLF & @TAB & '; Decompress the data' & @CRLF
        $sHelperFunc &= @TAB & '$bData = _LZNT_Decompress($bData)' & @CRLF
        $sHelperFunc &= @TAB & 'If @error Then Return SetError(3, 0, Binary(""))' & @CRLF
    EndIf

    $sHelperFunc &= @CRLF
    $sHelperFunc &= @TAB & 'Return $bData' & @CRLF
    $sHelperFunc &= 'EndFunc   ;==>_GetBin' & @CRLF & @CRLF

    $sHelperFunc &= '; Example usage:' & @CRLF
    For $i = 0 To UBound($aFiles) - 1
        Local $sFileName = $aFiles[$i][1]
        $sHelperFunc &= '; $bData = _GetBin("' & $sFileName & '")' & @CRLF
        $sHelperFunc &= '; _WriteBinaryFile(@TempDir & "\\' & $sFileName & '", $bData)' & @CRLF
    Next

    Return $sHelperFunc
EndFunc   ;==>_GenerateMasterHelperFunctionFromArray
#EndRegion ; *** CORE CODE GENERATION ***

#Region ; *** PE HEADER AND ARCHITECTURE DETECTION ***

; -------------------------------------------------------------------------------------------------
; Function:      _DetectArchitecture($sFilePath)
; Purpose:       A wrapper that returns the architecture string for a file.
; -------------------------------------------------------------------------------------------------
Func _DetectArchitecture($sFilePath)
    Local $sArch = _DetectArchitecture_File($sFilePath)
    If @error Then Return "N/A"
    Return $sArch
EndFunc   ;==>_DetectArchitecture

; -------------------------------------------------------------------------------------------------
; Function:      _DetectArchitecture_File($sFilePath)
; Purpose:       Reads a file's PE headers to identify the target CPU architecture.
; -------------------------------------------------------------------------------------------------
Func _DetectArchitecture_File($sFilePath)
    If Not FileExists($sFilePath) Then Return SetError(1, 0, "FILE_NOT_FOUND")
    Local $hFile = FileOpen($sFilePath, 16)
    If $hFile = -1 Then Return SetError(2, 0, "CANNOT_OPEN_FILE")
    Local $bDOSHeader = FileRead($hFile, 64)
    If @error Then
        FileClose($hFile)
        Return SetError(3, 0, "CANNOT_READ_DOS_HEADER")
    EndIf
    If BinaryMid($bDOSHeader, 1, 2) <> "0x4D5A" Then
        FileClose($hFile)
        Return "Not PE"
    EndIf
    Local $iPEOffset = _BinaryToInt(BinaryMid($bDOSHeader, 61, 4))
    FileSetPos($hFile, $iPEOffset, $FILE_BEGIN)
    Local $bPESig = FileRead($hFile, 4)
    If @error Or $bPESig <> "0x50450000" Then
        FileClose($hFile)
        Return SetError(5, 0, "INVALID_PE_SIGNATURE")
    EndIf
    Local $bCOFF = FileRead($hFile, 2)
    FileClose($hFile)
    If @error Then Return SetError(6, 0, "CANNOT_READ_COFF_HEADER")
    Local $iMachine = _BinaryToInt($bCOFF)
    Switch $iMachine
        Case 0x014c
            Return "x86"
        Case 0x8664
            Return "x64"
        Case 0x01c0, 0x01c4
            Return "ARM"
        Case 0xAA64
            Return "ARM64"
        Case 0x0200
            Return "IA64"
        Case Else
            Return "UNKNOWN_0x" & Hex($iMachine, 4)
    EndSwitch
EndFunc   ;==>_DetectArchitecture_File

; -------------------------------------------------------------------------------------------------
; Function:      _BinaryToInt($bData)
; Purpose:       Converts a little-endian binary string to an integer value.
; -------------------------------------------------------------------------------------------------
Func _BinaryToInt($bData)
    Local $iResult = 0
    For $i = 1 To BinaryLen($bData)
        $iResult += Number(BinaryMid($bData, $i, 1)) * (256 ^ ($i - 1))
    Next
    Return $iResult
EndFunc   ;==>_BinaryToInt
#EndRegion ; *** PE HEADER AND ARCHITECTURE DETECTION ***

#Region ; *** UTILITY FUNCTIONS ***

; -------------------------------------------------------------------------------------------------
; Function:      _SanitizeName($sInput)
; Purpose:       Removes illegal characters from a string to make it a valid function name.
; -------------------------------------------------------------------------------------------------
Func _SanitizeName($sInput)
    Local $sCleaned = StringRegExpReplace($sInput, "[^a-zA-Z0-9_]", "")
    If StringLeft($sCleaned, 1) = "$" Then $sCleaned = StringTrimLeft($sCleaned, 1)
    Return $sCleaned
EndFunc   ;==>_SanitizeName

; -------------------------------------------------------------------------------------------------
; Function:      _GetFileName($sFilePath)
; Purpose:       Extracts the filename and extension from a full path.
; -------------------------------------------------------------------------------------------------
Func _GetFileName($sFilePath)
    Return StringRegExpReplace($sFilePath, "^.*\\", "")
EndFunc   ;==>_GetFileName

; -------------------------------------------------------------------------------------------------
; Function:      _FormatFileSize($iBytes)
; Purpose:       Converts a file size in bytes into a human-readable string (KB, MB, GB).
; -------------------------------------------------------------------------------------------------
Func _FormatFileSize($iBytes)
    If $iBytes < 1024 Then
        Return $iBytes & " B"
    ElseIf $iBytes < 1048576 Then
        Return Round($iBytes / 1024, 1) & " KB"
    ElseIf $iBytes < 1073741824 Then
        Return Round($iBytes / 1048576, 2) & " MB"
    Else
        Return Round($iBytes / 1073741824, 2) & " GB"
    EndIf
EndFunc   ;==>_FormatFileSize

; -------------------------------------------------------------------------------------------------
; Function:      _ValidateChunkSize($iChunkSize)
; Purpose:       Ensures the chunk size is within a valid range.
; -------------------------------------------------------------------------------------------------
Func _ValidateChunkSize($iChunkSize)
    ; First, check if the input from the GUI is a string containing only digits.
    If Not StringIsDigit($iChunkSize) Then
        Return 4000 ; If not, it's invalid, return the default value.
    EndIf
    ; If it is a digit string, convert it to a real number.
    Local $nChunkSize = Number($iChunkSize)
    If ($iChunkSize < 100) Or ($iChunkSize > 4000) Then
        Return 4000
    EndIf
    Return Int($iChunkSize)
EndFunc   ;==>_ValidateChunkSize

; -------------------------------------------------------------------------------------------------
; Function:      _SaveStringToFile($sFilePath, $sContent)
; Purpose:       A robust function to save a string to a file.
; Returns:       True on success, False on failure.
; -------------------------------------------------------------------------------------------------
Func _SaveStringToFile($sFilePath, $sContent)
    Local $hFile = FileOpen($sFilePath, 2)
    If $hFile = -1 Then Return False
    Local $bSuccess = FileWrite($hFile, $sContent)
    FileClose($hFile)
    Return $bSuccess
EndFunc   ;==>_SaveStringToFile
Func _LZNT_Compress($bInput, $iOrigSize = 16, $iEngine = 258, $bBase64 = False, $iLineLen = 1024)
    $bInput = Binary($bInput)
    If (BinaryLen($bInput) < 1) Then Return SetError(-1, 0, "")
    If $iEngine <> 2 And $iEngine <> 258 Then $iEngine = 258
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]")
    DllStructSetData($tInput, 1, $bInput)
    Local $aCall = DllCall("ntdll.dll", "int", "RtlGetCompressionWorkSpaceSize", _
            "ushort", $iEngine, "dword*", 0, "dword*", 0)
    If @error Or $aCall[0] Then Return SetError(1, 0, "")
    Local $tWork = DllStructCreate("byte[" & $aCall[2] & "]")
    If ($iOrigSize < 1) Then $iOrigSize = 16
    Local $iLen = $iOrigSize * DllStructGetSize($tInput)
    Local $tBuffer = DllStructCreate("byte[" & $iLen & "]")
    $aCall = DllCall("ntdll.dll", "int", "RtlCompressBuffer", _
            "ushort", $iEngine, _
            "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), _
            "ptr", DllStructGetPtr($tBuffer), "dword", DllStructGetSize($tBuffer), _
            "dword", 4096, "dword*", 0, "ptr", DllStructGetPtr($tWork))
    If @error Or $aCall[0] Then Return SetError(2, 0, "")
    Local $tOut = DllStructCreate("byte[" & $aCall[7] & "]", DllStructGetPtr($tBuffer))
    Local $bOut = DllStructGetData($tOut, 1)
    If $bBase64 Then Return SetError(0, DllStructGetSize($tInput), _Base64Encode($bOut, $iLineLen))
    Return SetError(0, DllStructGetSize($tInput), $bOut)
EndFunc   ;==>_LZNT_Compress

Func _LZNT_Decompress($vInput, $iOrigSize = 16, $iEngine = 258, $bBase64 = False)
    Local $bInput
    If $bBase64 Then
        $bInput = _Base64Decode($vInput)
    Else
        $bInput = $vInput
    EndIf
    $bInput = Binary($bInput)
    If (BinaryLen($bInput) < 1) Then Return SetError(-1, 0, "")
    If $iEngine <> 2 And $iEngine <> 258 Then $iEngine = 258
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]")
    DllStructSetData($tInput, 1, $bInput)
    If ($iOrigSize < 1) Then $iOrigSize = 16
    Local $iLen = $iOrigSize * DllStructGetSize($tInput)
    Local $tBuffer = DllStructCreate("byte[" & $iLen & "]")
    Local $aCall = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", _
            "ushort", $iEngine, _
            "ptr", DllStructGetPtr($tBuffer), "dword", DllStructGetSize($tBuffer), _
            "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), _
            "dword*", 0)
    If @error Or $aCall[0] Then Return SetError(1, 0, "")
    Local $tOut = DllStructCreate("byte[" & $aCall[6] & "]", DllStructGetPtr($tBuffer))
    Return SetError(0, $aCall[6], DllStructGetData($tOut, 1))
EndFunc   ;==>_LZNT_Decompress

Func _LZNT_CompressStr($sInput, $iOrigSize = 16, $iEncoding = 4, $iEngine = 2, $bBase64 = False, $iLineLen = 1024)
    Local $bData = StringToBinary($sInput, $iEncoding)
    Local $sReturn = _LZNT_Compress($bData, $iOrigSize, $iEngine, $bBase64, $iLineLen)
    Return SetError(@error, @extended, $sReturn)
EndFunc   ;==>_LZNT_CompressStr

Func _LZNT_DecompressStr($vInput, $iOrigSize = 16, $iEncoding = 4, $iEngine = 2, $bBase64 = False)
    Local $bData = _LZNT_Decompress($vInput, $iOrigSize, $iEngine, $bBase64)
    If @error Then Return SetError(1, 0, "")
    Return BinaryToString($bData, $iEncoding)
EndFunc   ;==>_LZNT_DecompressStr

Func _Base64Encode($bData, $iLineLen = 0)
    If ($iLineLen < 1) Then $iLineLen = 0
    $bData = Binary($bData)
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bData) & "]")
    DllStructSetData($tInput, 1, $bData)
    Local $iFlags = 0x40000001 ; CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF
    ; Get required buffer size
    Local $aResult = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _
            "struct*", $tInput, _
            "dword", DllStructGetSize($tInput), _
            "dword", $iFlags, _
            "ptr", 0, _
            "dword*", 0)
    If @error Or Not $aResult[0] Then Return SetError(1, 0, "")
    Local $iSize = $aResult[5]
    Local $tOutput = DllStructCreate("wchar[" & $iSize & "]")
    ; Perform encoding
    $aResult = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _
            "struct*", $tInput, _
            "dword", DllStructGetSize($tInput), _
            "dword", $iFlags, _
            "struct*", $tOutput, _
            "dword*", $iSize)
    If @error Or Not $aResult[0] Then Return SetError(2, 0, "")
    Local $sOut = DllStructGetData($tOutput, 1)
    ; Manual wrap for embedding in AutoIt source
    If ($iLineLen > 0) And (StringLen($sOut) > $iLineLen) Then
        Local $sWrapped = ""
        For $i = 1 To StringLen($sOut) Step $iLineLen
            $sWrapped &= StringMid($sOut, $i, $iLineLen) & @CRLF
        Next
        $sOut = StringTrimRight($sWrapped, 2)
    EndIf
    Return $sOut
EndFunc   ;==>_Base64Encode

Func _Base64EncodeStr($sInput, $iLineLen = 0, $iEncodeType = 4)
    If ($iLineLen < 1) Then $iLineLen = 0
    If ($iEncodeType > 4) Or ($iEncodeType < 1) Then $iEncodeType = 4
    Local $bBinary = StringToBinary($sInput, $iEncodeType)
    Local $sReturn = _Base64Encode($bBinary, $iLineLen)
    Return SetError(@error, @extended, $sReturn)
EndFunc   ;==>_Base64EncodeStr

Func _Base64Decode($sInput, $bReturnType = 0)
    If ($bReturnType > 4) Or ($bReturnType < 1) Then $bReturnType = 0
    ; Remove all whitespace and CRLF
    $sInput = StringRegExpReplace($sInput, "\s", "")
    If $sInput = "" Then Return SetError(1, 0, Binary(""))
    Local $iFlags = 0x1 ; CRYPT_STRING_BASE64
    ; Get required buffer size
    Local $aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _
            "wstr", $sInput, _
            "dword", StringLen($sInput), _
            "dword", $iFlags, _
            "ptr", 0, _
            "dword*", 0, _
            "ptr", 0, _
            "ptr", 0)
    If @error Or Not $aResult[0] Then Return SetError(2, 0, Binary(""))
    Local $iSize = $aResult[5]
    Local $tOutput = DllStructCreate("byte[" & $iSize & "]")
    ; Perform decoding
    $aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _
            "wstr", $sInput, _
            "dword", StringLen($sInput), _
            "dword", $iFlags, _
            "struct*", $tOutput, _
            "dword*", $iSize, _
            "ptr", 0, _
            "ptr", 0)
    If @error Or Not $aResult[0] Then Return SetError(3, 0, Binary(""))
    Local $bBinary = DllStructGetData($tOutput, 1)
    If ($bReturnType = 0) Then
        Return $bBinary
    Else
        ; Convert binary to string with specified encoding
        Return BinaryToString($bBinary, $bReturnType)
    EndIf
EndFunc   ;==>_Base64Decode

Func _Base64DecodeStr($sInput, $iDecodeType = 4)
    Local $sReturn = _Base64Decode($sInput, $iDecodeType)
    Return SetError(@error, @extended, $sReturn)
EndFunc   ;==>_Base64DecodeStr


#EndRegion ; *** UTILITY FUNCTIONS ***

 

 

Edited by Trong

Enjoy my work? Buy me a 🍻 or tip via ❤️ PayPal

  • Trong changed the title to AutoIt Resource Embedder

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...