title: How to compile C program as dll in Mingw for use with Inno Setup & callback
body: <p>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:</p>
  
  <pre><code>function VolEx( filename, outputpath: String ): Integer; external 'VolExA@volex.dll stdcall';
  </code></pre>
  
  <p>I read through <a href="http://www.mingw.org/wiki/sampleDLL" rel="nofollow noreferrer">http://www.mingw.org/wiki/sampleDLL</a> but was having a hard time understanding all the ifdefs and extern "C" stuff.</p>
  
  <p>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 <a href="http://www.sherlocksoftware.org/page.php?id=54" rel="nofollow noreferrer">http://www.sherlocksoftware.org/page.php?id=54</a> ; something similar was done with FreeArc <a href="http://freearc.org/InnoSetup.aspx" rel="nofollow noreferrer">http://freearc.org/InnoSetup.aspx</a>)</p>
  
  <p>Volex.c (includes blast.c and blast.h from here: <a href="https://github.com/madler/zlib/tree/master/contrib/blast" rel="nofollow noreferrer">https://github.com/madler/zlib/tree/master/contrib/blast</a>)</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;limits.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;time.h&gt;
  #include &lt;utime.h&gt;
  #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-&gt;size &gt; inb-&gt;left ? inb-&gt;left : inb-&gt;size;
      len = fread(inb-&gt;buf, 1, len, inb-&gt;in);
      inb-&gt;left -= len;
      *buf = inb-&gt;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, &amp;inb, outf, out);
      fclose(out);
      if (stat(outPath, &amp;statbuf) &lt; 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, &amp;new_times) &lt; 0) {
          perror(outPath);
          return 1;
      }
      return err;
  }
  
  int main(int argc, char *argv[])
  {
      if ( argc != 3 )
      {
          printf( "Usage: %s &lt;vol&gt; &lt;output path&gt;", 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], &amp;statbuf) &lt; 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] &lt;&lt; 8) + ((unsigned long)(head[22]) &lt;&lt; 16) +
                 ((unsigned long)(head[23]) &lt;&lt; 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;
      }
  }
  </code></pre>