Hi,
Attached is patch against Archive-Unzip-Burst-0.02_01 which seems to work with
both VC6 and MinGW.
If anyone would like to test, that would be good.
It is a direct lift from the info-zip dll usage example, although objects are
linked into Burst.dll rather than linking to an extenral unzip32.dll.
Regards
Mark
diff -ruw Burst.xs Burst.xs
--- Burst.xs 2007-09-05 16:19:54.000000000 +0100
+++ Burst.xs 2008-05-16 03:55:50.371125000 +0100
@@ -4,8 +4,171 @@
#include "ppport.h"
+# if (defined(_WIN32))
+
+#include "res/unzip-5.52/windll/structs.h"
+#include "res/unzip-5.52/windll/decs.h"
+
+
+LPUSERFUNCTIONS lpUserFunctions;
+HANDLE hUF = (HANDLE)NULL;
+LPDCL lpDCL = NULL;
+HANDLE hDCL = (HANDLE)NULL;
+HANDLE hZCL = (HANDLE)NULL;
+DWORD dwPlatformId = 0xFFFFFFFF;
+int WINAPI DisplayBuf(LPSTR, unsigned long);
+int WINAPI GetReplaceDlgRetVal(LPSTR);
+int WINAPI password(LPSTR, int, LPCSTR, LPCSTR);
+void WINAPI ReceiveDllMessage(unsigned long, unsigned long, unsigned,
+ unsigned, unsigned, unsigned, unsigned, unsigned,
+ char, LPSTR, LPSTR, unsigned long, char);
+
+static void FreeUpMemory(void);
+
+int
+UzpMain(int argc, char **argv)
+{
+ int r;
+ int exfc, infc;
+ char **exfv, **infv;
+
+ hDCL = GlobalAlloc( GPTR, (DWORD)sizeof(DCL));
+ if (!hDCL)
+ {
+ return 0;
+ }
+ lpDCL = (LPDCL)GlobalLock(hDCL);
+ if (!lpDCL)
+ {
+ GlobalFree(hDCL);
+ return 0;
+ }
+
+ hUF = GlobalAlloc( GPTR, (DWORD)sizeof(USERFUNCTIONS));
+ if (!hUF)
+ {
+ GlobalUnlock(hDCL);
+ GlobalFree(hDCL);
+ return 0;
+ }
+ lpUserFunctions = (LPUSERFUNCTIONS)GlobalLock(hUF);
+
+ if (!lpUserFunctions)
+ {
+ GlobalUnlock(hDCL);
+ GlobalFree(hDCL);
+ GlobalFree(hUF);
+ return 0;
+ }
+
+ lpUserFunctions->password = password;
+ lpUserFunctions->print = DisplayBuf;
+ lpUserFunctions->sound = NULL;
+ lpUserFunctions->replace = GetReplaceDlgRetVal;
+ lpUserFunctions->SendApplicationMessage = ReceiveDllMessage;
+
+ lpDCL->ncflag = 0; /* Write to stdout if true */
+ lpDCL->fQuiet = 2; /* 0 = We want all messages.
+ 1 = fewer messages,
+ 2 = no messages */
+ lpDCL->ntflag = 0; /* test zip file if true */
+ lpDCL->nvflag = 0; /* give a verbose listing if true */
+ lpDCL->nzflag = 0; /* display a zip file comment if true */
+ lpDCL->ndflag = 1; /* Recreate directories != 0, skip "../" if < 2 */
+ lpDCL->naflag = 0; /* Do not convert CR to CRLF */
+ lpDCL->nfflag = 0; /* Do not freshen existing files only */
+ lpDCL->noflag = 1; /* Over-write all files if true */
+ lpDCL->ExtractOnlyNewer = 0; /* Do not extract only newer */
+ lpDCL->PromptToOverwrite = 0; /* "Overwrite all" selected -> no query mode
*/
+ lpDCL->lpszZipFN = argv[3]; /* The archive name */
+ lpDCL->lpszExtractDir = NULL; /* The directory to extract to. This is set
+ to NULL if you are extracting to the
+ current directory.
+ */
+
+ infc = exfc = 0;
+ infv = exfv = NULL;
+
+ r = Wiz_SingleEntryUnzip(infc, infv, exfc, exfv, lpDCL, lpUserFunctions);
+ FreeUpMemory();
+ return r;
+}
+
+int WINAPI GetReplaceDlgRetVal(LPSTR filename)
+{
+ /* This is where you will decide if you want to replace, rename etc
existing
+ files.
+ */
+ return 1;
+}
+
+static void FreeUpMemory(void)
+{
+ if (hDCL)
+ {
+ GlobalUnlock(hDCL);
+ GlobalFree(hDCL);
+ }
+ if (hUF)
+ {
+ GlobalUnlock(hUF);
+ GlobalFree(hUF);
+ }
+}
+
+/* This is a very stripped down version of what is done in Wiz. Essentially
+ what this function is for is to do a listing of an archive contents. It
+ is actually never called in this example, but a dummy procedure had to
+ be put in, so this was used.
+ */
+void WINAPI ReceiveDllMessage(unsigned long ucsize, unsigned long csiz,
+ unsigned cfactor,
+ unsigned mo, unsigned dy, unsigned yr, unsigned hh, unsigned mm,
+ char c, LPSTR filename, LPSTR methbuf, unsigned long crc, char fCrypt)
+{
+ char psLBEntry[_MAX_PATH];
+ char LongHdrStats[] =
+ "%7lu %7lu %4s %02u-%02u-%02u %02u:%02u %c%s";
+ char CompFactorStr[] = "%c%d%%";
+ char CompFactor100[] = "100%%";
+ char szCompFactor[10];
+ char sgn;
+
+ if (csiz > ucsize)
+ sgn = '-';
+ else
+ sgn = ' ';
+ if (cfactor == 100)
+ lstrcpy(szCompFactor, CompFactor100);
+ else
+ sprintf(szCompFactor, CompFactorStr, sgn, cfactor);
+ wsprintf(psLBEntry, LongHdrStats,
+ ucsize, csiz, szCompFactor, mo, dy, yr, hh, mm, c, filename);
+
+ printf("%s\n", psLBEntry);
+}
+
+/* Password entry routine - see password.c in the wiz directory for how
+ this is actually implemented in WiZ. If you have an encrypted file,
+ this will probably give you great pain.
+ */
+int WINAPI password(LPSTR p, int n, LPCSTR m, LPCSTR name)
+{
+ return 1;
+}
+
+/* Dummy "print" routine that simply outputs what is sent from the dll */
+int WINAPI DisplayBuf(LPSTR buf, unsigned long size)
+{
+ printf("%s", (char *)buf);
+ return (int)(unsigned int) size;
+}
+
+#else
+
int UzpMain(int, char**);
+#endif
MODULE = Archive::Unzip::Burst PACKAGE = Archive::Unzip::Burst
@@ -26,3 +189,6 @@
OUTPUT:
RETVAL
+
+
+
diff -ruw Makefile.PL Makefile.PL
--- Makefile.PL 2007-09-05 16:22:16.000000000 +0100
+++ Makefile.PL 2008-05-16 04:21:37.605500000 +0100
@@ -3,10 +3,52 @@
use File::Spec;
use strict;
use warnings;
-use vars qw/$os $osmakefile $osmaketarget $osobjext/;
+use Config;
+use vars qw/$os $osmakefile $osmaketarget $osobjext @winobjs $windllcmd
$winsys/;
my $unzip = "unzip-5.52";
+if ( $^O =~ /^MSWin/i ) {
+
+ $winsys = ($Config::Config{cc} eq 'cl') ? 'vc' : 'mingw';
+
+ my $obprefix = 'res/unzip-5.52';
+
+ if( $winsys eq 'vc' ) {
+ @winobjs = qw (api crci386l crctabl cryptl explodel extractl fileiol
globalsl inflatel listl matchl ntl
+ processl unreducl unshrnkl win32l windll zipinfol);
+ $windllcmd = 'nmake -f win32/Makefile dll';
+ } else {
+ @winobjs = qw (api crc32l crc_i386 crctabl cryptl explodel extractl
fileiol globalsl inflatel listl matchl ntl
+ processl unreducl unshrnkl win32l windll zipinfol);
+ $windllcmd = 'mingw32-make -f win32/makefile.gcc dll';
+ }
+
+ my $oext = $Config::Config{obj_ext};
+
+ my $objects = 'Burst' . $oext;
+
+ $objects .= qq( $obprefix/$_$oext) for (@winobjs);
+
+
+ WriteMakefile(
+ NAME => 'Archive::Unzip::Burst',
+ VERSION_FROM => 'lib/Archive/Unzip/Burst.pm', # finds $VERSION
+ PREREQ_PM => {
+ 'File::Spec' => '0',
+ 'Cwd' => '0',
+ }, # e.g., Module::Name => 1.1
+ ($] >= 5.005 ? ## Add these new keywords supported since 5.005
+ (ABSTRACT_FROM => 'lib/Archive/Unzip/Burst.pm', # retrieve abstract
from module
+ AUTHOR => 'Steffen Mueller <[EMAIL PROTECTED]>') : ()),
+ LDFROM => $objects,
+ INC => '-I.', # e.g., '-I. -I/usr/include/other'
+ LICENSE => 'perl',
+
+ );
+
+} else {
+
my @OS = qw(
win32 os2 dos macos linux
);
@@ -61,7 +103,11 @@
LICENSE => 'perl',
);
+}
+
+
sub MY::postamble {
+ return "" if $^O =~ /^MSWin/i;
require File::Copy;
require File::Spec;
require Cwd;
diff -ruw res/Makefile.PL res/Makefile.PL
--- res/Makefile.PL 2007-09-05 16:19:54.000000000 +0100
+++ res/Makefile.PL 2008-05-16 04:07:25.371125000 +0100
@@ -1,17 +1,49 @@
use ExtUtils::MakeMaker;
use Config;
-use vars qw/$os $osmakefile $osmaketarget $osobjext/;
+use vars qw/$os $osmakefile $osmaketarget $osobjext @winobjs $windllcmd
$winsys/;
require File::Spec;
$Verbose = 1;
my $exe = $Config::Config{_exe};
my $o = $Config::Config{obj_ext};
+my $unzipdir = "unzip-5.52";
+
+my $toptargettext;
+
+if ( $^O =~ /^MSWin/i ) {
+ my $cleanfiles;
+
+ for(@winobjs) {
+ $cleanfiles .= qq($unzipdir/$_$o );
+ }
+
+ if( $winsys eq 'vc' ) {
+ $cleanfiles .= qq($unzipdir/windll.res $unzipdir/unzip32.lib
$unzipdir/unzip32.exp $unzipdir/unzip32.dll);
+ } else {
+ $cleanfiles .= qq($unzipdir/windllrc.o $unzipdir/windll.o
$unzipdir/unzip32.dll);
+ }
+
+ $toptargettext = "all :: dll
+pure_all :: dll
+dll :
+\tcd $unzipdir && $windllcmd
+";
+
+ WriteMakefile(
+ NAME => 'Archive::Unzip::Burst',
+ clean => {'FILES' => $cleanfiles },
+ test => { 'TESTS' => '' },
+ );
+
+
+} else {
+
+
+
if (not defined $os) {
die "The Makefile.PL in res/ is designed to be included by the main
Makefile.PL!";
}
-my $unzipdir = "unzip-5.52";
-
my $objects;
if ($os eq 'unix' or $os eq 'win32') {
$objects = join(' ', map {File::Spec->catfile($unzipdir, "$_$osobjext$o")}
qw|unzip crc32 crctab crypt envargs explode extract fileio globals inflate list
match process ttyio unreduce unshrink zipinfo api|, "$os");
@@ -20,6 +52,17 @@
die "Funny OS. Don't know what to link.";
}
+$toptargettext = "all :: static
+
+pure_all :: static
+
+static :: libmyunzip\$(LIB_EXT)
+
+libmyunzip\$(LIB_EXT): \$(O_FILES)
+ \$(AR) cr libmyunzip\$(LIB_EXT) $objects
+ \$(RANLIB) libmyunzip\$(LIB_EXT)
+";
+
WriteMakefile(
NAME => 'Archive::Unzip::Burst',
#SKIP => [qw(all static static_lib dynamic dynamic_lib)],
@@ -30,18 +73,14 @@
},
OBJECT => $objects,
);
-sub MY::top_targets {
- "
-all :: static
-pure_all :: static
-static :: libmyunzip\$(LIB_EXT)
+# \$(AR) cr libmyunzip\$(LIB_EXT) \$(O_FILES)
-libmyunzip\$(LIB_EXT): \$(O_FILES)
- \$(AR) cr libmyunzip\$(LIB_EXT) $objects
- \$(RANLIB) libmyunzip\$(LIB_EXT)
-";
}
-# \$(AR) cr libmyunzip\$(LIB_EXT) \$(O_FILES)
+sub MY::top_targets {
+ "
+$toptargettext
+";
+}