c++error-handlingunrar

handling errors from unrar DLL


If you run the command-line version of unrar it logs out vital information when an archive fails to extract. I'm trying to do the same thing with the unrar DLL. I've already had to make some changes to the DLL source code to support registering my own callback to handle extraction progress properly. Now I want to handle error reporting properly. There is really no documentation on using unrar source.

So I have a working callback function that can be called

CommandData *Cmd
Cmd->ErrorCallback(ERAR_BAD_DATA, Arc.FileName, ArcFileName);

The function works great if I call it next to my progress DLL (so I know the callback works), but I just can't figure out where the errors are being handled. Specifically I'm after handling the code ERAR_BAD_DATA which I found is handled in extract.cpp ... but that code just doesn't seem to get run. I also found some calls to RarErrorToDll ... I put the callback there too, nothing.

Any help would be hugely appreciated.

for a bit of context, this is what I was previously doing to catch errors.

bool archiveCorrupt = false;
while((read_header_code = RARReadHeader(archive_data, &header_data)) == 0)
{
    process_file_code = RARProcessFile(archive_data, RAR_EXTRACT, m_output_dir, NULL);
    if(process_file_code)
    {
        qDebug() << "Error extracting volume!"
                 << header_data.ArcName << " "
                 << " with error: " << process_file_code;
        archiveCorrupt = true;
        break;
    }
}

The reason this approach doesn't work is that the error code process_file_code tells you what went wrong, but the archive name in header_data.ArcName is the archive that the file started in, not necessarily where the corruption was. I'm dealing with multi-part archives where one large file will span multiple archives ... so I need to know which archive(s) is corrupt, not just the archive the file started in.

EDIT:

Here is a link to the unrar source code

So I've discovered a place in extract.cpp line 670 that I can place the callback and it does return an error code to my app.

     ErrHandler.SetErrorCode(RARX_CRC);
#ifdef RARDLL
    Cmd->ErrorCallback(RARX_CRC, Arc.FileName, ArcFileName);

However, this has the same issue as before, where it returns the error at the end of processing the file extracting, rather than at the place where the CRC fails.

If I run the unrar command-line app that you can download from the rarlabs site, it seems to handle it properly and returns the correct error. I can't find text for those errors anywhere in the unrar source, so I can only assume that the unrar source doesn't actually build the unrar app they publish on their site.

Extracting from SL - Cinematic Guitars.part02.rar

...         SL - Cinematic Guitars/Cinematic Guitars/Samples/Cinematic Guitars_001.nkx  16%
SL - Cinematic Guitars/Cinematic Guitars/Samples/Cinematic Guitars_001.nkx : packed data CRC failed in volume SL - Cinematic Guitars.part02.rar

Solution

  • I eventually found the answer, after lots of trial and error.

    My issue was, I was comparing an old command line version of unrar to the newer source code when looking for the error messages. The error message has changed in the new source code and is now

    packed data checksum error in volume
    

    This is defined in loclang.hpp and called from uiconsole.cpp in the function uiMsgStore:Msg when the error code is UIERROR_CHECKSUMPACKED

    This gets called from volume.cpp on line 25

    I have added my callback here, and it catches the error perfectly.

    I hope this helps someone else if they ever have the misfortune of having to hack unrar source code.