Проблема Как правильно выгрузить dll при неправильном пароле (или ошибке) при использовании unarc.dll

sergey3695

Ветеран
Модератор
Код библиотеки
C++:
#include <windows.h>
#include <strsafe.h>
#include <shlwapi.h>

#define call __stdcall

static HMODULE unarc_dll = 0;

FARPROC LoadFromDLL(char *funcname)
{
    return GetProcAddress(unarc_dll, funcname);
}

typedef int Number;
typedef int call cbtype(char *what, Number int1, Number int2, char *str);

bool UnarcError = false;

/* ERRCODE unarc.dll
{ 
 FREEARC_OK=                             0;   (* ALL RIGHT *)
 FREEARC_ERRCODE_GENERAL=               -1;   (* Some error when (de)compressing *)
 FREEARC_ERRCODE_INVALID_COMPRESSOR=    -2;   (* Invalid compression method or parameters *)
 FREEARC_ERRCODE_ONLY_DECOMPRESS=       -3;   (* Program builded with FREEARC_DECOMPRESS_ONLY, so don't try to use compress *)
 FREEARC_ERRCODE_OUTBLOCK_TOO_SMALL=    -4;   (* Output block size in (de)compressMem is not enough for all output data *)
 FREEARC_ERRCODE_NOT_ENOUGH_MEMORY=     -5;   (* Can't allocate memory needed for (de)compression *)
 FREEARC_ERRCODE_READ=                  -6;   (* Error when reading data *)
 FREEARC_ERRCODE_BAD_COMPRESSED_DATA=   -7;   (* Data can't be decompressed *)
 FREEARC_ERRCODE_NOT_IMPLEMENTED=       -8;   (* Requested feature isn't supported *)
 FREEARC_ERRCODE_NO_MORE_DATA_REQUIRED= -9;   (* Required part of data was already decompressed *)
 FREEARC_ERRCODE_OPERATION_TERMINATED= -10;   (* Operation terminated by user *)
 FREEARC_ERRCODE_WRITE=                -11;   (* Error when writing data *)
 FREEARC_ERRCODE_BAD_CRC=              -12;   (* File failed CRC check *)
 FREEARC_ERRCODE_BAD_PASSWORD=         -13;   (* Password/keyfile failed checkcode test *)
 FREEARC_ERRCODE_BAD_HEADERS=          -14;   (* Archive headers are corrupted *)
 FREEARC_ERRCODE_INTERNAL=             -15;   (* It should never happen: implementation error. Please report this bug to developers! *)
}
*/

int call callback(char *what, Number int1, Number int2, char *str)
{
    if (!strcmp(what, "error") && (int1 < 0) && (int1 != -10))
    {
        wchar_t buf[16];
        wsprintf(buf, L"%i", abs(int1));
        MessageBox(NULL, buf, L"", MB_OK);
        if (UnarcError == FALSE)
            UnarcError = TRUE;
    }
    /*  switch (ArcErrCode)
        {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        //case 14:
        //case 15:
            UnarcError = true;
            break;
        default:
            UnarcError = false;
            break;
        }
    } */
    return UnarcError ? -127 : 0;
}

void call ISArcExtract(char *InName, char *OutPath, char *ExtractedPath, char *Password, char *CfgFile, char *WorkPath)
{
    if (PathFileExistsA(InName)) 
    {
        char CfgFileExt[MAX_PATH] = "-cfg";
        if (lstrlenA(CfgFile) > 0)
            StringCchCatA(CfgFileExt, MAX_PATH, CfgFile);
        char WorkPathExt[MAX_PATH] = "-w";
        if (lstrlenA(WorkPath) > 0)
            StringCchCatA(WorkPathExt, MAX_PATH, WorkPath);
        char ExtractedPathExt[MAX_PATH] = "-ap";
        if (lstrlenA(ExtractedPath) > 0)
            StringCchCatA(ExtractedPathExt, MAX_PATH, ExtractedPath);
        char OutPathExt[MAX_PATH] = "-dp";
        if (lstrlenA(OutPath) > 0)
            StringCchCatA(OutPathExt, MAX_PATH, OutPath);
        char PasswordExt[MAX_PATH] = "-p";
        if (lstrlenA(Password) > 2)
            StringCchCatA(PasswordExt, MAX_PATH, Password);
        // Load function from unarc.dll
        int(*FreeArcExtract) (cbtype *callback, ...) = (int(*) (cbtype *callback, ...)) LoadFromDLL("FreeArcExtract");
        if (!FreeArcExtract) MessageBox(NULL, L"Cannot load FreeArcExtract from unarc.dll!", L"", MB_OK);
        else {
            if (FreeArcExtract(callback, "l", PasswordExt, "--", InName, "", "", "", "", "", "") == 0)
            {
                FreeArcExtract(callback, "x", "-o+", CfgFileExt, PasswordExt, WorkPathExt, ExtractedPathExt, OutPathExt, "--", InName, "");
                //
                //wchar_t buf[16];
                //wsprintf(buf, L"%i", lstrlenA(InName));
                //MessageBox(NULL, buf, L"", MB_OK);
            }
        }
    } else MessageBox(NULL, L"It is not found any file specified for unarc.dll!", L"", MB_OK);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        // Get path
        WCHAR path[MAX_PATH];
        GetModuleFileName(hinstDLL, path, MAX_PATH);
        PathRemoveFileSpec(path);
        StringCchCat(path, MAX_PATH, L"\\unarc.dll");
        unarc_dll = LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    }
        break;

    case DLL_THREAD_ATTACH:
        break;

    case DLL_THREAD_DETACH:
    break;

    case DLL_PROCESS_DETACH:
    {
        // Unload unarc.dll
        if (unarc_dll)
        {
            void(*UnloadDLL) (void) = (void(*) (void)) LoadFromDLL("UnloadDLL");
            UnloadDLL;
            FreeLibrary(unarc_dll);
        }
    }
        break;
    }
    return TRUE;
}
Скрипт inno
code_language.pascal:
[Setup]
AppName=ReactIW4
AppVersion=1.3.2
DefaultDirName={pf}\ReactIW4
OutputDir=.

[Files]
Source: unarc.dll; DestDir: {tmp}; Flags: dontcopy deleteafterinstall
Source: ISFreeArcExtract.dll; DestDir: {tmp}; Flags: dontcopy deleteafterinstall

[UninstallDelete]
Type: filesandordirs; Name: {app}

[Code]
procedure ISArcExtract(InName, OutPath, ExtractedPath, Password, CfgFile, WorkPath: AnsiString); external 'ISArcExtract@files:ISFreeArcExtract.dll stdcall delayload';

function InitializeSetup(): Boolean;
begin
  if not FileExists(ExpandConstant('{tmp}\unarc.dll')) then ExtractTemporaryFile('unarc.dll');
  if not FileExists(ExpandConstant('{tmp}\ISFreeArcExtract.dll')) then ExtractTemporaryFile('ISFreeArcExtract.dll');
  Result:= True;
end;

procedure InitializeWizard();
begin
//
  ISArcExtract(ExpandConstant('{src}\data.arc'), ExpandConstant('{src}\tmp'), '', '123456', '', '');
end;
Проблема в том, что не пойму, как правильно выгрузить dll при неправильном пароле (или ошибке), то что свой поток нужен это понятно, где-то ошибка в коде?
 
Последнее редактирование:

Krinkels

Он где то тут
Администратор
Библиотека для библиотеки? Однако :)
По проблеме, в
C++:
int call callback(char *what, Number int1, Number int2, char *str)
нужно ловить "error", и сделать что то типа такого:
C++:
if( !lstrcmpiA( what, "error" ) && ( int1 < 0 ) && ( int1 != -10 ) )
{   
    if( UnarcError == FALSE )
    {       
        UnarcError = TRUE;
    }       
}
 

Krinkels

Он где то тут
Администратор
К стати:
Код:
MessageBox(NULL, buf, L"", MB_OK);
return -127;

// Этот код работать не будет
if (unarc_dll)
{
    void(*UnloadDLL) (void) = (void(*) (void)) LoadFromDLL("UnloadDLL");
    UnloadDLL;
    FreeLibrary(unarc_dll);
}
 

Krinkels

Он где то тут
Администратор
Что нибудь типа такого:
C++:
int call ISArcExtract(char *InName, char *OutPath, char *ExtractedPath, char *Password, char *CfgFile, char *WorkPath)
{
    if(PathFileExistsA(InName))
    {
        char CfgFileExt[MAX_PATH] = "-cfg";
        if (lstrlenA(CfgFile) > 0)
            StringCchCatA(CfgFileExt, MAX_PATH, CfgFile);
        char WorkPathExt[MAX_PATH] = "-w";
        if (lstrlenA(WorkPath) > 0)
            StringCchCatA(WorkPathExt, MAX_PATH, WorkPath);
        char ExtractedPathExt[MAX_PATH] = "-ap";
        if (lstrlenA(ExtractedPath) > 0)
            StringCchCatA(ExtractedPathExt, MAX_PATH, ExtractedPath);
        char OutPathExt[MAX_PATH] = "-dp";
        if (lstrlenA(OutPath) > 0)
            StringCchCatA(OutPathExt, MAX_PATH, OutPath);
        char PasswordExt[MAX_PATH] = "-p";
        if (lstrlenA(Password) > 2)
            StringCchCatA(PasswordExt, MAX_PATH, Password);
        // Load function from unarc.dll
        int(*FreeArcExtract) (cbtype *callback, ...) = (int(*) (cbtype *callback, ...)) LoadFromDLL("FreeArcExtract");
        if (!FreeArcExtract)
        {
            MessageBox(NULL, L"Cannot load FreeArcExtract from unarc.dll!", L"", MB_OK);
            return 0;
        }

        if( FreeArcExtract( callback, "l", "--", InName, "", "", "", "", "", "", "" ) == 0 )
        {
            if (FreeArcExtract(callback, "l", PasswordExt, "--", InName, "", "", "", "", "", "") == 0)
            {
                FreeArcExtract(callback, "x", "-o+", CfgFileExt, PasswordExt, WorkPathExt, ExtractedPathExt, OutPathExt, "--", InName, "");
            }
        }
    }
    else
        MessageBox(NULL, L"It is not found any file specified for unarc.dll!", L"", MB_OK);
        
    if (unarc_dll)
    {
        void(*UnloadDLL) (void) = (void(*) (void)) LoadFromDLL("UnloadDLL");
        UnloadDLL;
        FreeLibrary(unarc_dll);
    }
        
    return 0;
}
ну и плюс нормальный
C++:
int call callback(char *what, Number int1, Number int2, char *str)
и не использовать "DLL_PROCESS_DETACH"
 

sergey3695

Ветеран
Модератор
Убрал не рабочий код, Подожду. Свой поток решит проблему, просто интересно, есть ли решение иное, возможно более правильное.
 

Shegorat

Lord of Madness
Администратор
@sergey3695, Если писать на плюсах, то можно использовав принцип RAII, сделать класс-лоадер для библиотеки, что-то типа такого
C++:
typedef int __stdcall IFreeArcExtract(cbtype* callback, ...);
typedef void __stdcall IUnloadDLL(void)
struct unarc_loader {
    IFreeArcExtract* mFreeArcExtract_ = nullptr;
    IUnloadDLL* mUnloadDLL_ = nullptr;
    HMODULE mInstance_ = 0;
    unarc_loader(char* path) {
        mInstance_ = LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
        if (mInstance_) {
            mFreeArcExtract_ = GetProcAddress(mInstance_, "FreeArcExtract");
            mUnloadDLL_ = GetProcAddress(mInstance_, "UnloadDLL");
        }
    }
    ~unarc_loader() {
        if (mUnloadDLL_)
            mUnloadDLL_();
        if (mInstance_)
            FreeLibrary(mInstance_);
    }
    bool success() {
        return mInstance_ && mFreeArcExtract_ && mUnloadDLL_;
    }
}
void call ISArcExtract(char *InName, char *OutPath, char *ExtractedPath, char *Password, char *CfgFile, char *WorkPath)
{
    unarc_loader unarc("formatted path");
    if (!unarc.success()) {
        MessageBox(NULL, L"Cannot load FreeArcExtract from unarc.dll!", L"", MB_OK);
        return -1;
    }
    ...
}
Тогда перед выходом из функции, неважно в каком месте, будет вызываться деструктор unarc_loader, выполняя всю работу по освобождению ресурсов за тебя. Ага, лень - двигатель прогресса. Ну и thread-safe, все дела. Хотя статик структуру с колбэком в инку всё равно придется делать.

Далее, вызывать LoadLibrary в DllMain не рекомендуется самими мелкомягкими, не безопасно и всё такое.
Ещё, проверять только на указанные коды ошибок тоже нельзя. У меня к примеру в некоторых cls есть кастомные ошибки. Поэтому всё, что не CLS_OK считаем ошибкой.
Перед передачей параметров в unarc.dll их необходимо преобразовать в utf-8, иначе не английские символы не поймёт.
 

sergey3695

Ветеран
Модератор
@Shegorat, не помогло. всё таки это unarc не корректно обрабатывает, как мне кажется.
Вот такой код пробовал
C++:
#include <windows.h>
#include <strsafe.h>
#include <shlwapi.h>

#define call __stdcall

static HMODULE unarc_dll = 0;

//FARPROC LoadFromDLL(char *funcname)
//{
//    return GetProcAddress(unarc_dll, funcname);
//}

typedef int Number;
typedef int call cbtype(char *what, Number int1, Number int2, char *str);

bool UnarcError = false;

/* ERRCODE unarc.dll
{
 FREEARC_OK=                             0;   (* ALL RIGHT *)
 FREEARC_ERRCODE_GENERAL=               -1;   (* Some error when (de)compressing *)
 FREEARC_ERRCODE_INVALID_COMPRESSOR=    -2;   (* Invalid compression method or parameters *)
 FREEARC_ERRCODE_ONLY_DECOMPRESS=       -3;   (* Program builded with FREEARC_DECOMPRESS_ONLY, so don't try to use compress *)
 FREEARC_ERRCODE_OUTBLOCK_TOO_SMALL=    -4;   (* Output block size in (de)compressMem is not enough for all output data *)
 FREEARC_ERRCODE_NOT_ENOUGH_MEMORY=     -5;   (* Can't allocate memory needed for (de)compression *)
 FREEARC_ERRCODE_READ=                  -6;   (* Error when reading data *)
 FREEARC_ERRCODE_BAD_COMPRESSED_DATA=   -7;   (* Data can't be decompressed *)
 FREEARC_ERRCODE_NOT_IMPLEMENTED=       -8;   (* Requested feature isn't supported *)
 FREEARC_ERRCODE_NO_MORE_DATA_REQUIRED= -9;   (* Required part of data was already decompressed *)
 FREEARC_ERRCODE_OPERATION_TERMINATED= -10;   (* Operation terminated by user *)
 FREEARC_ERRCODE_WRITE=                -11;   (* Error when writing data *)
 FREEARC_ERRCODE_BAD_CRC=              -12;   (* File failed CRC check *)
 FREEARC_ERRCODE_BAD_PASSWORD=         -13;   (* Password/keyfile failed checkcode test *)
 FREEARC_ERRCODE_BAD_HEADERS=          -14;   (* Archive headers are corrupted *)
 FREEARC_ERRCODE_INTERNAL=             -15;   (* It should never happen: implementation error. Please report this bug to developers! *)
}
*/

int call callback(char *what, Number int1, Number int2, char *str)
{
    if (!strcmp(what, "error") && (int1 < 0) && (int1 != -10))
    {
        wchar_t buf[16];
        wsprintf(buf, L"%i", abs(int1));
        MessageBox(NULL, buf, L"", MB_OK);
        if (UnarcError == FALSE)
            UnarcError = TRUE;
    }
    /*  switch (ArcErrCode)
        {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        //case 14:
        //case 15:
            UnarcError = true;
            break;
        default:
            UnarcError = false;
            break;
        }
    } */
    return UnarcError ? -127 : 0;
}

typedef int call IFreeArcExtract(cbtype* callback, ...);
typedef void call IUnloadDLL(void);
struct unarc_loader {
    IFreeArcExtract* mFreeArcExtract_ = nullptr;
    IUnloadDLL* mUnloadDLL_ = nullptr;
    HMODULE mInstance_ = 0;
    unarc_loader(wchar_t* path) {
        mInstance_ = LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
        if (mInstance_) {
            mFreeArcExtract_ = (IFreeArcExtract*)GetProcAddress(mInstance_, "FreeArcExtract");
            mUnloadDLL_ = (IUnloadDLL*)GetProcAddress(mInstance_, "UnloadDLL");
        }
    }
    ~unarc_loader() {
        if (mUnloadDLL_)
            mUnloadDLL_();
        if (mInstance_)
            FreeLibrary(mInstance_);
    }
    bool success() {
        return mInstance_ && mFreeArcExtract_ && mUnloadDLL_;
    }
};

static WCHAR path[MAX_PATH];

void call ISArcExtract(char *InName, char *OutPath, char *ExtractedPath, char *Password, char *CfgFile, char *WorkPath)
{
    unarc_loader unarc(path);
    if (!unarc.success()) {
        MessageBox(NULL, L"Cannot load FreeArcExtract from unarc.dll!", L"", MB_OK);
    }

    if (PathFileExistsA(InName))
    {
        char CfgFileExt[MAX_PATH] = "-cfg";
        if (lstrlenA(CfgFile) > 0)
            StringCchCatA(CfgFileExt, MAX_PATH, CfgFile);
        char WorkPathExt[MAX_PATH] = "-w";
        if (lstrlenA(WorkPath) > 0)
            StringCchCatA(WorkPathExt, MAX_PATH, WorkPath);
        char ExtractedPathExt[MAX_PATH] = "-ap";
        if (lstrlenA(ExtractedPath) > 0)
            StringCchCatA(ExtractedPathExt, MAX_PATH, ExtractedPath);
        char OutPathExt[MAX_PATH] = "-dp";
        if (lstrlenA(OutPath) > 0)
            StringCchCatA(OutPathExt, MAX_PATH, OutPath);
        char PasswordExt[MAX_PATH] = "-p";
        if (lstrlenA(Password) > 2)
            StringCchCatA(PasswordExt, MAX_PATH, Password);
        // Load function from unarc.dll
//        int(*FreeArcExtract) (cbtype *callback, ...) = (int(*) (cbtype *callback, ...)) LoadFromDLL("FreeArcExtract");
//        if (!FreeArcExtract) MessageBox(NULL, L"Cannot load FreeArcExtract from unarc.dll!", L"", MB_OK);
//        else {
            if (unarc.mFreeArcExtract_(callback, "l", PasswordExt, "--", InName, "", "", "", "", "", "") == 0)
            {
                unarc.mFreeArcExtract_(callback, "x", "-o+", CfgFileExt, PasswordExt, WorkPathExt, ExtractedPathExt, OutPathExt, "--", InName, "");
                //
                //wchar_t buf[16];
                //wsprintf(buf, L"%i", lstrlenA(InName));
                //MessageBox(NULL, buf, L"", MB_OK);
            }
//        }
    } else MessageBox(NULL, L"It is not found any file specified for unarc.dll!", L"", MB_OK);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        // Get path
        //WCHAR path[MAX_PATH];
        GetModuleFileName(hinstDLL, path, MAX_PATH);
        PathRemoveFileSpec(path);
        StringCchCat(path, MAX_PATH, L"\\unarc.dll");
//        unarc_dll = LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    }
        break;

    case DLL_THREAD_ATTACH:
        break;

    case DLL_THREAD_DETACH:
    break;

    case DLL_PROCESS_DETACH:
    {
        // Unload unarc.dll
        //if (unarc_dll)
        //{
        //    void(*UnloadDLL) (void) = (void(*) (void)) LoadFromDLL("UnloadDLL");
        //    UnloadDLL;
        //    FreeLibrary(unarc_dll);
        //}
    }
        break;
    }
    return TRUE;
}
 

sergey3695

Ветеран
Модератор
@Shegorat, если будет время, проверь данный момент. (выгрузить dll при неправильном пароле (или ошибке) при использовании unarc.dll)
Мне кажется, что проблема в unarc. Пытается удалить файл и не дает его освободить.
C++:
// This function cleans up the Compression Library
void compressionLib_cleanup (void)
{
  removeTemporaryFiles();
}

// Процедура экстренного выхода
void PROCESS::quit(int errcode)
{
  cmd->ok = FALSE;
  if (outfile.isopen())  outfile.close(), outfile.remove();
  arcinfo.arcfile.tryClose();
  compressionLib_cleanup();
  UI->Abort (cmd, errcode);
}
Не знаю, может и бред написал, но я что-то не знаю тогда в чем причина, такого поведения и не выгружается dll.
 

Shegorat

Lord of Madness
Администратор
Дамп или стектрейс есть? Я просто сейчас не понимаю, что именно у тебя неправильно.
Вообще unarc.dll не отбивает ошибку, при неверном пароле, а заново запрашивает его
Код:
Z:\fa>UnarcDllExample.exe x -dpunpacked -p1111 data_tor1.arc
callback("total", 140, 147686955, "")
callback("filename", 316, 331957042, "что-то с чем-то.db0")
Enter password:1
callback("password?", 2000, 0, "1")
Enter password:123
callback("password?", 2000, 0, "123")
Enter password:312
callback("password?", 2000, 0, "312")
Enter password:123
callback("password?", 2000, 0, "123")
Вообще советую глянуть сорцы UnarcDllExample
 

sergey3695

Ветеран
Модератор
Вообще unarc.dll не отбивает ошибку, при неверном пароле, а заново запрашивает его
C++:
MessageBoxA(NULL, str, "", MB_OK);
Безымянный.jpg
Я же написал, если будет время, попробуй выгрузить библиотеку при неправильном пароле.
советую глянуть сорцы UnarcDllExample
видел я это. как себе это представляешь? введите пароль заново, но потом все равно надо закрыть все, что-то вернув.
Дамп или стектрейс есть?
нету.
в inno видно *** exit code: 0xC0000005.
Если ошибка у меня, напиши рабочий пример. Попробуй собрать dll, вызвав FreeArcExtract(callback, "l", PasswordExt, "--", InName, "", "", "", "", "", "") == 0) и выгрузить unarc потом. Тут явно не у меня проблема просто. (у меня, но не из-за меня =) ).
Попробовал ISFreeArcExtract v.4.2. Все в темпе остается, если пароль не верный.
 

Shegorat

Lord of Madness
Администратор
Воот, теперь я тебя понял. Проблема не в unarc.dll.
видел я это. как себе это представляешь? введите пароль заново, но потом все равно надо закрыть все, что-то вернув.
Тебе нужно понять как работает unarc.dll и как происходит работа с колбэком.

Теперь к сути вопроса. Тебе в коллбэке, если what == "password?" необходимо вернуть FREEARC_ERRCODE_OPERATION_TERMINATED, ну либо литеру 'q'. Типа
Код:
if (strequ(what, "password?"))
    return FREEARC_ERRCODE_OPERATION_TERMINATED;
Тогда, unarc корректно завершит обработку. Кстати в ISFreeArcExtract этот кейс не обрабатывается, но это исправляется просто
Форматирование (BB-код):
function FreeArcCallback(what: PAnsiChar; Mb, int2: Integer; str: PAnsiChar): Integer;
begin
  case string(what) of
    'origsize': origsize:= Mb;
    'total_files': Null;
    'filename': begin
                  Progress.CurName:= OemToAnsiStr(str);
                  Progress.FilesCount:= Progress.FilesCount + 1;
                end;
    'read': Null;
    'write': lastMb:= Mb;
    'error': if (Mb = -2) then CompressMethod:= str;
    'password?': CancelCode:= -10;
  end;
  UpdateStatus();
  if (GetKeyState(VK_ESCAPE) < 0) then
    WizardForm.Close;
  AppProcessMessage;
  Result:= CancelCode;
end;

Ну если так надо, могу написать полный код, но не щас.

P.S. Но проверить корректность обработки ошибок в unarc.dll таки надо
 

sergey3695

Ветеран
Модератор
но это исправляется просто
Все в темпе остается.
могу написать полный код
достаточно сюда вставить нужный код, работа с колбэком при не правильном пароле. Не нужен мне класс-лоадер и т.п. т.к. я собираю без crt. (а то как-то 4 кб вырастают в 232 кб). Про utf-8 да, согласен, добавлю.
не к спеху.
у меня такое ощущение, что тебе как будто нечем собрать библиотеку и проверить свой код на работоспособность. может проблема у меня в системе (это ну я прям не знаю).
@Krinkels, проверишь код из отсюда, просто собери и попробуй, есть ли в inno *** exit code: 0xC0000005? Ну или файл прикрепил.
 

Вложения

Последнее редактирование:

Shegorat

Lord of Madness
Администратор
@sergey3695, ты какую unarc.dll используешь? Вот ванильный ISFreeArcExtract v.4.2b. Добавил только лог коллбэка
1615463987425.png

Всё корректно завершается. Вот как должен выглядеть PROCESS::quit, откуда ты взял код я не знаю.
C++:
// Процедура экстренного прекращения работы (для exe) или экстренного выхода (для dll)
bool PROCESS::quit (int errcode, char* errmsg)
{
  cmd->ok = FALSE;
  if (outfile.isopen())  outfile.close(), outfile.remove(), included = FALSE;
#ifndef FREEARC_LIBRARY
  arcinfo.arcfile.tryClose();
  compressionLib_cleanup();
#endif
  UI->Abort (cmd, errcode, errmsg);
  return cmd->ok;
}

P.S. твой код у меня не собирается ни на одном gcc
 
Сверху