-1

I have the following program that's been written with lots of help. It will explode PKWare DCL compressed .vol archives (file id RESLIST) and extract the files to the specified output folder giving the extracted files the modification date of the original .vol file. It's meant to be used in an Inno Setup installer and I'd like to see if I can compile it as a .dll library I can import in my .iss script ie:

function VolEx( filename, outputpath: String ): Integer; external 'VolExA@volex.dll stdcall';

I read through http://www.mingw.org/wiki/sampleDLL but was having a hard time understanding all the ifdefs and extern "C" stuff.

Additionally I'd like it to be able to change the WizardForm.FilenameLabel.Caption in my installer to match the file currently being extracted (I understand this needs InnoTools InnoCallback http://www.sherlocksoftware.org/page.php?id=54 ; something similar was done with FreeArc http://freearc.org/InnoSetup.aspx)

Volex.c (includes blast.c and blast.h from here: https://github.com/madler/zlib/tree/master/contrib/blast)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/stat.h>
#include <time.h>
#include <utime.h>
#include "blast.h"

#define local static
#define VOLID "RESLIST"

struct inbuf {
    unsigned long left;
    unsigned char *buf;
    unsigned size;
    FILE *in;
};

struct stat statbuf;
time_t mtime;
time_t voltime;
struct utimbuf new_times;

local unsigned inf(void *how, unsigned char **buf)
{
    unsigned len;
    struct inbuf *inb = how;

    len = inb->size > inb->left ? inb->left : inb->size;
    len = fread(inb->buf, 1, len, inb->in);
    inb->left -= len;
    *buf = inb->buf;
    return len;
}

local int outf(void *how, unsigned char *buf, unsigned len)
{
    return fwrite(buf, 1, len, (FILE *)how) != len;
}

#define BUFSIZE 16384   /* must fit in unsigned */

local int extract(char *name, unsigned long len, FILE *in, char *path, time_t prevtime)
{
    int err;
    FILE *out;
    struct inbuf inb;
    unsigned char buf[BUFSIZE];

    inb.left = len;
    inb.buf = buf;
    inb.size = BUFSIZE;
    inb.in = in;
    mkdir(path);
    char outPath[strlen(path) + 20];
    strcpy(outPath, path);
    strcat(outPath, "\\");
    strcat(outPath, name);
    out = fopen(outPath, "wb");
    if (out == NULL)
        return 2;
    err = blast(inf, &inb, outf, out);
    fclose(out);
    if (stat(outPath, &statbuf) < 0) {
        perror(outPath);
        return 1;
    }
    mtime = statbuf.st_mtime; /* seconds since the epoch */

    new_times.actime = statbuf.st_atime; /* keep atime unchanged */
    new_times.modtime = prevtime;    /* set mtime to current time */
    if (utime(outPath, &new_times) < 0) {
        perror(outPath);
        return 1;
    }
    return err;
}

int main(int argc, char *argv[])
{
    if ( argc != 3 )
    {
        printf( "Usage: %s <vol> <output path>", argv[0] );
        return 1;
    }
    else
    {
        FILE *in = fopen(argv[1],"rb");
        unsigned long off, next;
        int err;
        unsigned char head[24];

        if (stat(argv[1], &statbuf) < 0) {
            perror(argv[1]);
            return 1;
        }
        voltime = statbuf.st_mtime; /* seconds since the epoch */

        if (fread(head, 1, 8, in) != 8 || memcmp(head, VOLID, 8)) {
            fprintf(stderr, "not the expected .vol format\n");
            return 1;
        }
        off = 8;
        while ((next = fread(head, 1, 24, in)) == 24) {
            off += 24;
            next = head[20] + (head[21] << 8) + ((unsigned long)(head[22]) << 16) +
               ((unsigned long)(head[23]) << 24);

            head[20] = 0;
            err = extract((char *)head, next - off, in, argv[2], voltime);
            if (err) {
                fprintf(stderr, "extraction error %d on %s\n", err, head);
                return 1;
            }
            off = next;
        }
        if (next)
            fprintf(stderr, "%lu bytes ignored at the end\n", next);
        return 0;
    }
}
Andy
  • 49,085
  • 60
  • 166
  • 233
user477276
  • 367
  • 5
  • 20
  • 1
    Why don't you just extract the files on your dev computer and repack them using normal Inno [Files] entries? Inno's compression is usually better than most alternatives (especially if you increase the settings). Then everything is handled for you and you don't need to do anything fancy. – Miral Aug 30 '13 at 23:09
  • The installer is meant as an update/patch, and the files to be extracted are located on a CD-ROM. – user477276 Sep 03 '13 at 03:24
  • And? All that means is that you have two choices: leave the files separate and uncompressed and use the external flag (thereby allowing the user to independently access the files, or to enable a "run with disc in without installing" option), or compress them in some way. In neither case is there any reason to look at external compression tools. – Miral Sep 04 '13 at 21:06
  • This is for a replacement installer for a 32-bit game which used a 16-bit installer which also installs the latest patch. The files need to decompressed in order for the game to run, so yes an external decompression tool is needed if I want to be able to distribute it for others to use. – user477276 Sep 05 '13 at 07:16
  • Ah, I see now. You want to use the original game disc, not repack everything. Fair enough. – Miral Sep 05 '13 at 20:38
  • 1
    Do not revert that edit. The text removed is not required. – Andy Jul 29 '19 at 20:13

1 Answers1

1

Assuming that you are using ANSI Inno Setup, the following Inno signature:

function VolEx( filename, outputpath: String ): Integer; external 'VolExA@volex.dll stdcall';

will require the following C signature in your DLL code:

int __stdcall __declspec(dllexport) VolExA(const char *filename, const char *outputpath);

(If you're compiling the DLL as C++ rather than C then you will also need an extern "C" at the beginning.)

You will need to declare this function in your DLL and move the appropriate code from "main" above into it, then remove the main function and compile as a DLL instead of a console app.

Get this part working first before worrying about feedback via callbacks -- submit a separate question for that if you have trouble with it.

Miral
  • 12,637
  • 4
  • 53
  • 93