chore: initial commit (extracted from Launchers monorepo)
Plugin: ns7zip v2.0.0 Architectures: x86-ansi, x86-unicode, amd64-unicode License: LGPL-2.1-or-later
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
// test_nsis7z.cpp
|
||||
// Emula la chiamata NSIS a nsis7z::ExtractWithFileCallback fuori da NSIS
|
||||
// Compila: cl /W3 /EHsc /DUNICODE /D_UNICODE test_nsis7z.cpp /link /OUT:test_nsis7z.exe
|
||||
// Uso: test_nsis7z.exe <archive.exe> <outdir> [skip1] [skip2] ...
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// ---- Replica di pluginapi.h ----
|
||||
|
||||
typedef struct _stack_t {
|
||||
struct _stack_t *next;
|
||||
wchar_t text[1];
|
||||
} stack_t;
|
||||
|
||||
enum {
|
||||
INST_0, INST_1, INST_2, INST_3, INST_4,
|
||||
INST_5, INST_6, INST_7, INST_8, INST_9,
|
||||
INST_R0, INST_R1, INST_R2, INST_R3, INST_R4,
|
||||
INST_R5, INST_R6, INST_R7, INST_R8, INST_R9,
|
||||
INST_CMDLINE, INST_INSTDIR, INST_OUTDIR, INST_EXEDIR, INST_LANG,
|
||||
__INST_LAST
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int exec_flags;
|
||||
int (__cdecl *ExecuteCodeSegment)(int, HWND);
|
||||
void (__cdecl *validate_filename)(wchar_t *);
|
||||
int (__cdecl *RegisterPluginCallback)(HMODULE, LPVOID);
|
||||
} extra_parameters;
|
||||
|
||||
// Tipo della funzione esportata dalla DLL
|
||||
typedef void (__cdecl *NSISPluginFunc)(
|
||||
HWND hwndParent,
|
||||
int string_size,
|
||||
wchar_t *variables,
|
||||
stack_t **stacktop,
|
||||
extra_parameters *extra
|
||||
);
|
||||
|
||||
// ---- Stato globale simulato ----
|
||||
|
||||
#define STRING_SIZE 4096
|
||||
#define NUM_VARS __INST_LAST
|
||||
|
||||
static wchar_t g_variables[NUM_VARS][STRING_SIZE];
|
||||
static stack_t *g_stacktop = NULL;
|
||||
|
||||
// ---- Callback simulato per il progresso ----
|
||||
|
||||
static int __cdecl FakeExecuteCodeSegment(int segment, HWND hwnd)
|
||||
{
|
||||
// La callback NSIS popa 3 valori dallo stack (completedSize, totalSize, fileName)
|
||||
// Li leggiamo e stampiamo
|
||||
if (g_stacktop)
|
||||
{
|
||||
stack_t *s1 = g_stacktop;
|
||||
stack_t *s2 = s1 ? s1->next : NULL;
|
||||
stack_t *s3 = s2 ? s2->next : NULL;
|
||||
|
||||
wprintf(L" [CB] completed=%s total=%s file=%s\n",
|
||||
s1 ? s1->text : L"?",
|
||||
s2 ? s2->text : L"?",
|
||||
s3 ? s3->text : L"?");
|
||||
|
||||
// Popa i 3 item
|
||||
for (int i = 0; i < 3 && g_stacktop; i++)
|
||||
{
|
||||
stack_t *tmp = g_stacktop;
|
||||
g_stacktop = g_stacktop->next;
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static extra_parameters g_extra = { 0, FakeExecuteCodeSegment, NULL, NULL };
|
||||
|
||||
// ---- Gestione stack ----
|
||||
|
||||
static void push_str(const wchar_t *str)
|
||||
{
|
||||
size_t len = wcslen(str);
|
||||
stack_t *item = (stack_t*)malloc(sizeof(stack_t) + len * sizeof(wchar_t));
|
||||
if (!item) { wprintf(L"OOM\n"); exit(1); }
|
||||
wcscpy_s(item->text, len + 1, str);
|
||||
item->next = g_stacktop;
|
||||
g_stacktop = item;
|
||||
}
|
||||
|
||||
// Imposta INST_OUTDIR (indice 22) nella variabile array
|
||||
static void set_outdir(const wchar_t *dir)
|
||||
{
|
||||
wcscpy_s(g_variables[INST_OUTDIR], STRING_SIZE, dir);
|
||||
}
|
||||
|
||||
// ---- Flat variables array per la DLL ----
|
||||
// La DLL riceve un puntatore a un array piatto: ogni slot e' STRING_SIZE wchar_t
|
||||
static wchar_t g_flat_vars[NUM_VARS * STRING_SIZE];
|
||||
|
||||
static void build_flat_vars()
|
||||
{
|
||||
memset(g_flat_vars, 0, sizeof(g_flat_vars));
|
||||
for (int i = 0; i < NUM_VARS; i++)
|
||||
wcscpy_s(g_flat_vars + i * STRING_SIZE, STRING_SIZE, g_variables[i]);
|
||||
}
|
||||
|
||||
// ---- main ----
|
||||
|
||||
int wmain(int argc, wchar_t *argv[])
|
||||
{
|
||||
if (argc < 3)
|
||||
{
|
||||
wprintf(L"Uso: test_nsis7z.exe <archive> <outdir> [skip1] [skip2] ...\n");
|
||||
wprintf(L"\nEsempio:\n");
|
||||
wprintf(L" test_nsis7z.exe \"C:\\tmp\\nsis.exe\" \"C:\\tmp\\out\" \"$PLUGINSDIR\" \"$PLUGINSDIR\\*\"\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const wchar_t *archive = argv[1];
|
||||
const wchar_t *outdir = argv[2];
|
||||
|
||||
/* Cerca la DLL nella directory del tool */
|
||||
wchar_t dllPath[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, dllPath, MAX_PATH);
|
||||
wchar_t *last = wcsrchr(dllPath, L'\\');
|
||||
if (last) *(last+1) = 0;
|
||||
wcscat_s(dllPath, MAX_PATH, L"nsis7z.dll");
|
||||
|
||||
wprintf(L"Carico DLL: %s\n", dllPath);
|
||||
HMODULE hDll = LoadLibraryW(dllPath);
|
||||
if (!hDll)
|
||||
{
|
||||
wprintf(L"ERRORE: LoadLibrary fallito (err=%lu)\n", GetLastError());
|
||||
return 2;
|
||||
}
|
||||
wprintf(L"DLL caricata OK\n");
|
||||
|
||||
NSISPluginFunc fnExtract = (NSISPluginFunc)GetProcAddress(hDll, "ExtractWithFileCallback");
|
||||
if (!fnExtract)
|
||||
{
|
||||
wprintf(L"ERRORE: GetProcAddress(ExtractWithFileCallback) fallito (err=%lu)\n", GetLastError());
|
||||
FreeLibrary(hDll);
|
||||
return 3;
|
||||
}
|
||||
wprintf(L"Funzione trovata OK\n");
|
||||
|
||||
// Prepara OUTDIR
|
||||
set_outdir(outdir);
|
||||
wprintf(L"OutDir = %s\n", outdir);
|
||||
|
||||
// Prepara stack NSIS (push in ordine inverso - l'ultimo pushato e' il primo poppato)
|
||||
// Ordine di pop nella DLL: 1) popint() = callback segment, 2..N) popstring() = skip patterns + ""
|
||||
// Per il callback usiamo segmento 1 (FakeExecuteCodeSegment ricevera' segmento-1 = 0)
|
||||
//
|
||||
// Push ordine (il primo push e' il fondo dello stack):
|
||||
// "" (terminatore skip)
|
||||
// skip[N-1] ... skip[0] (in reverse per avere l'ordine giusto al pop)
|
||||
// callback_int
|
||||
|
||||
// Prima: push terminatore
|
||||
push_str(L"");
|
||||
|
||||
// Push skip patterns in ordine inverso (argv[3..])
|
||||
for (int i = argc - 1; i >= 3; i--)
|
||||
push_str(argv[i]);
|
||||
|
||||
// Push archive path (popstring in EXTRACTFUNC macro)
|
||||
push_str(archive);
|
||||
|
||||
// Il callback viene poppato con popint() DENTRO ExtractWithFileCallback (dopo EXDLL_INIT e popstring(archive))
|
||||
// Dobbiamo quindi mettere sull'apice dello stack il valore int callback
|
||||
// Ma... push_str prima e poi push_str archive: l'archivio e' sul top, poi il callback
|
||||
// Riordino: prima il callback (fondo), poi archive (top)
|
||||
// Svuota e rifai nell'ordine corretto:
|
||||
|
||||
// Libera stack corrente
|
||||
while (g_stacktop) {
|
||||
stack_t *t = g_stacktop;
|
||||
g_stacktop = g_stacktop->next;
|
||||
free(t);
|
||||
}
|
||||
|
||||
// L'EXTRACTFUNC macro fa:
|
||||
// popstring(sArchive) <- primo pop = archive
|
||||
// Poi ExtractWithFileCallback fa:
|
||||
// g_progressCallback = popint() <- secondo pop = callback segment
|
||||
// PopSkipPatterns():
|
||||
// while popstring(buf)==0 && len>0 <- terzo+ pop = skip patterns, fino a ""
|
||||
//
|
||||
// Quindi push in ordine inverso (ultimo push = primo pop):
|
||||
// push "" (terminatore, ultimo da poppare)
|
||||
// push skip[n-1]..skip[0]
|
||||
// push "2" (callback segment: ExecuteCodeSegment(2-1=1,...) ma usiamo 1 -> exec(0))
|
||||
// push archive (primo da poppare)
|
||||
|
||||
// Push "" terminatore
|
||||
push_str(L"");
|
||||
// Push skip patterns
|
||||
for (int i = argc - 1; i >= 3; i--)
|
||||
push_str(argv[i]);
|
||||
// Push callback segment (1 -> FakeExecuteCodeSegment(0, ...))
|
||||
wchar_t segbuf[32];
|
||||
swprintf_s(segbuf, 32, L"%d", 1);
|
||||
push_str(segbuf);
|
||||
// Push archive (top of stack = first to pop)
|
||||
push_str(archive);
|
||||
|
||||
wprintf(L"\nChiamo ExtractWithFileCallback...\n");
|
||||
wprintf(L" archive = %s\n", archive);
|
||||
wprintf(L" outdir = %s\n", outdir);
|
||||
for (int i = 3; i < argc; i++)
|
||||
wprintf(L" skip[%d] = %s\n", i-3, argv[i]);
|
||||
wprintf(L"\n");
|
||||
|
||||
build_flat_vars();
|
||||
|
||||
__try
|
||||
{
|
||||
fnExtract(
|
||||
NULL, // hwndParent (NULL = no progress bar)
|
||||
STRING_SIZE, // string_size
|
||||
g_flat_vars, // variables (flat array)
|
||||
&g_stacktop, // stacktop
|
||||
&g_extra // extra
|
||||
);
|
||||
wprintf(L"\nESTRAZIONE COMPLETATA SENZA CRASH\n");
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
DWORD code = GetExceptionCode();
|
||||
wprintf(L"\nSEH EXCEPTION: 0x%08lX\n", code);
|
||||
switch(code)
|
||||
{
|
||||
case EXCEPTION_ACCESS_VIOLATION: wprintf(L" -> ACCESS VIOLATION\n"); break;
|
||||
case EXCEPTION_STACK_OVERFLOW: wprintf(L" -> STACK OVERFLOW\n"); break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION: wprintf(L" -> ILLEGAL INSTRUCTION\n"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(hDll);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Rebuilds the 7zip-19.00 directory from original sources.
|
||||
|
||||
.DESCRIPTION
|
||||
This script downloads 7-Zip 19.00 source code from 7-zip.org and merges it
|
||||
with the Nsis7z plugin files from the local archive to recreate the complete
|
||||
7zip-19.00 directory structure.
|
||||
|
||||
.NOTES
|
||||
Author: Simone
|
||||
Date: 2025-12-08
|
||||
|
||||
Sources:
|
||||
- 7-Zip 19.00 source: https://7-zip.org/a/7z1900-src.7z
|
||||
- Nsis7z plugin: docs\plugins\original\ns7zip\Nsis7z_19.00.7z
|
||||
#>
|
||||
|
||||
param(
|
||||
[switch]$Force,
|
||||
[string]$OutputPath = "$PSScriptRoot\7zip-19.00"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Paths
|
||||
$ScriptDir = $PSScriptRoot
|
||||
$TempDir = Join-Path $env:TEMP "nsis7z_rebuild_$(Get-Random)"
|
||||
$SevenZipSrcUrl = "https://7-zip.org/a/7z1900-src.7z"
|
||||
$Nsis7zArchive = Join-Path $ScriptDir "..\docs\plugins\original\ns7zip\Nsis7z_19.00.7z"
|
||||
|
||||
# Check if output already exists
|
||||
if (Test-Path $OutputPath) {
|
||||
if ($Force) {
|
||||
Write-Host "Removing existing directory: $OutputPath" -ForegroundColor Yellow
|
||||
Remove-Item -Path $OutputPath -Recurse -Force
|
||||
} else {
|
||||
Write-Error "Output directory already exists: $OutputPath. Use -Force to overwrite."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Check if Nsis7z archive exists
|
||||
if (-not (Test-Path $Nsis7zArchive)) {
|
||||
Write-Error "Nsis7z plugin archive not found: $Nsis7zArchive"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Create temp directory
|
||||
Write-Host "Creating temp directory: $TempDir" -ForegroundColor Cyan
|
||||
New-Item -ItemType Directory -Path $TempDir -Force | Out-Null
|
||||
|
||||
try {
|
||||
# Download 7-Zip source
|
||||
$SevenZipSrcFile = Join-Path $TempDir "7z1900-src.7z"
|
||||
Write-Host "Downloading 7-Zip 19.00 source from $SevenZipSrcUrl..." -ForegroundColor Cyan
|
||||
Invoke-WebRequest -Uri $SevenZipSrcUrl -OutFile $SevenZipSrcFile -UseBasicParsing
|
||||
|
||||
if (-not (Test-Path $SevenZipSrcFile)) {
|
||||
Write-Error "Failed to download 7-Zip source"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Download complete: $((Get-Item $SevenZipSrcFile).Length / 1KB) KB" -ForegroundColor Green
|
||||
|
||||
# Extract 7-Zip source
|
||||
Write-Host "Extracting 7-Zip source..." -ForegroundColor Cyan
|
||||
$ExtractDir = Join-Path $TempDir "extracted"
|
||||
& 7z x $SevenZipSrcFile -o"$ExtractDir" -y | Out-Null
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Failed to extract 7-Zip source"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Extract Nsis7z plugin
|
||||
Write-Host "Extracting Nsis7z plugin..." -ForegroundColor Cyan
|
||||
$PluginDir = Join-Path $TempDir "plugin"
|
||||
& 7z x $Nsis7zArchive -o"$PluginDir" -y | Out-Null
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Failed to extract Nsis7z plugin"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Merge: Copy plugin files into 7-Zip source tree
|
||||
Write-Host "Merging plugin files into 7-Zip source tree..." -ForegroundColor Cyan
|
||||
$PluginContrib = Join-Path $PluginDir "Contrib\nsis7z"
|
||||
Copy-Item -Path "$PluginContrib\*" -Destination $ExtractDir -Recurse -Force
|
||||
|
||||
# Move to final destination
|
||||
Write-Host "Moving to output directory: $OutputPath" -ForegroundColor Cyan
|
||||
Move-Item -Path $ExtractDir -Destination $OutputPath
|
||||
|
||||
# Verify
|
||||
$FileCount = (Get-ChildItem -Path $OutputPath -Recurse -File).Count
|
||||
Write-Host "`nSuccess! Rebuilt nsis7z1900-src with $FileCount files." -ForegroundColor Green
|
||||
Write-Host "Output: $OutputPath" -ForegroundColor Green
|
||||
|
||||
} finally {
|
||||
# Cleanup temp directory
|
||||
if (Test-Path $TempDir) {
|
||||
Write-Host "`nCleaning up temp files..." -ForegroundColor Cyan
|
||||
Remove-Item -Path $TempDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user