summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorKim Kibum <kb0929.kim@samsung.com>2012-08-24 14:34:26 +0900
committerKim Kibum <kb0929.kim@samsung.com>2012-08-24 14:34:26 +0900
commit4acc22dd2f30f063c7b07fdbc911384feeda58eb (patch)
treea78b9ba604297cddb9a23424ccc8abfc6ae7ba94 /win32
parent3101b2a7be8f0e3cc6ff469ce2597945c862264b (diff)
downloadzip-4acc22dd2f30f063c7b07fdbc911384feeda58eb.tar.gz
zip-4acc22dd2f30f063c7b07fdbc911384feeda58eb.tar.bz2
zip-4acc22dd2f30f063c7b07fdbc911384feeda58eb.zip
upload source
Diffstat (limited to 'win32')
-rw-r--r--win32/README.NT17
-rw-r--r--win32/README.TZ7
-rw-r--r--win32/crc_i386.asm241
-rw-r--r--win32/crc_i386.c228
-rw-r--r--win32/crc_lcc.asm119
-rw-r--r--win32/gvmat64.asm513
-rw-r--r--win32/lm32_lcc.asm174
-rw-r--r--win32/makefile.a64134
-rw-r--r--win32/makefile.bor179
-rw-r--r--win32/makefile.dj110
-rw-r--r--win32/makefile.emx291
-rw-r--r--win32/makefile.gcc142
-rw-r--r--win32/makefile.ibm123
-rw-r--r--win32/makefile.lcc123
-rw-r--r--win32/makefile.w10181
-rw-r--r--win32/makefile.w32147
-rw-r--r--win32/makefile.wat181
-rw-r--r--win32/match32.asm184
-rw-r--r--win32/nt.c482
-rw-r--r--win32/nt.h73
-rw-r--r--win32/osdep.h271
-rw-r--r--win32/readme.a6442
-rw-r--r--win32/rsxntwin.h166
-rw-r--r--win32/vc6/zip.dsp328
-rw-r--r--win32/vc6/zip.dsw65
-rw-r--r--win32/vc6/zipcloak.dsp164
-rw-r--r--win32/vc6/zipnote.dsp144
-rw-r--r--win32/vc6/zipsplit.dsp144
-rw-r--r--win32/win32.c989
-rw-r--r--win32/win32zip.c782
-rw-r--r--win32/win32zip.h33
-rw-r--r--win32/zip.def4
-rw-r--r--win32/zipup.h37
33 files changed, 6818 insertions, 0 deletions
diff --git a/win32/README.NT b/win32/README.NT
new file mode 100644
index 0000000..d2b31f7
--- /dev/null
+++ b/win32/README.NT
@@ -0,0 +1,17 @@
+From: Michael Tibbott <tibbott@classifieds2000.com>
+Subject: Zip on Windows NT problem - here's the answer
+Date: Wed, 10 Dec 1997 15:24:29 -0800
+
+If you're running NT Server (I am not sure about NT Workstation) then you
+should do the following to prevent zip/unzip from page swapping itself to
+death. And as an added bonus, the zip was about 6% faster.
+
+- open the network control panel
+
+- Click on the services tab
+
+- double-click on the server item to open its properties
+
+- Click the "maximize throughput for network applications" radio button
+
+- save and reboot
diff --git a/win32/README.TZ b/win32/README.TZ
new file mode 100644
index 0000000..ddce3f8
--- /dev/null
+++ b/win32/README.TZ
@@ -0,0 +1,7 @@
+From: paul.kienitz@shelter.sf.ca.us (Paul Kienitz)
+> It looks like I don't have to create a tzset() kluge for Watcom to check
+> the win32 API timezone information after all -- their new 10.6 release has
+> corrected this oversight. The TZ variable overrides the API. So the only
+> win32-related patch I want to make for Zip is just to use USE_EF_UT_TIME
+> unconditionally. With this in place, timezone stuff is working flawlessly
+> with or without TZ being set.
diff --git a/win32/crc_i386.asm b/win32/crc_i386.asm
new file mode 100644
index 0000000..7693d75
--- /dev/null
+++ b/win32/crc_i386.asm
@@ -0,0 +1,241 @@
+;===========================================================================
+; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2004-May-22 or later
+; (the contents of which are also included in zip.h) for terms of use.
+; If, for some reason, all these files are missing, the Info-ZIP license
+; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+;===========================================================================
+; crc_i386.asm, optimized CRC calculation function for Zip and UnZip,
+; created by Paul Kienitz and Christian Spieler.
+;
+; Revised 06-Oct-96, Scott Field (sfield@microsoft.com)
+; fixed to assemble with masm by not using .model directive which makes
+; assumptions about segment alignment. Also,
+; avoid using loop, and j[e]cxz where possible. Use mov + inc, rather
+; than lodsb, and other misc. changes resulting in the following performance
+; increases:
+;
+; unrolled loops NO_UNROLLED_LOOPS
+; *8 >8 <8 *8 >8 <8
+;
+; +54% +42% +35% +82% +52% +25%
+;
+; first item in each table is input buffer length, even multiple of 8
+; second item in each table is input buffer length, > 8
+; third item in each table is input buffer length, < 8
+;
+; Revised 02-Apr-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au)
+; Incorporated Rodney Brown's 32-bit-reads optimization as found in the
+; UNIX AS source crc_i386.S. This new code can be disabled by defining
+; the macro symbol NO_32_BIT_LOADS.
+;
+; Revised 12-Oct-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au)
+; Incorporated Rodney Brown's additional tweaks for 32-bit-optimized CPUs
+; (like the Pentium Pro, Pentium II, and probably some Pentium clones).
+; This optimization is controlled by the macro symbol __686 and is disabled
+; by default. (This default is based on the assumption that most users
+; do not yet work on a Pentium Pro or Pentium II machine ...)
+;
+; Revised 25-Mar-98, Cosmin Truta (cosmint@cs.ubbcluj.ro)
+; Working without .model directive caused tasm32 version 5.0 to produce
+; bad object code. The optimized alignments can be optionally disabled
+; by defining NO_ALIGN, thus allowing to use .model flat. There is no need
+; to define this macro if using other versions of tasm.
+;
+; Revised 16-Jan-2005, Cosmin Truta (cosmint@cs.ubbcluj.ro)
+; Enabled the 686 build by default, because there are hardly any pre-686 CPUs
+; in serious use nowadays. (See the 12-Oct-97 note above.)
+;
+; FLAT memory model assumed.
+;
+; Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
+; This results in shorter code at the expense of reduced performance.
+;
+;==============================================================================
+;
+; Do NOT assemble this source if external crc32 routine from zlib gets used.
+;
+ IFNDEF USE_ZLIB
+;
+ .386p
+ name crc_i386
+
+ IFDEF NO_ALIGN
+ .model flat
+ ENDIF
+
+ IFNDEF PRE_686
+ IFNDEF __686
+__686 EQU 1 ; optimize for Pentium Pro, Pentium II and compatible CPUs
+ ENDIF
+ ENDIF
+
+extrn _get_crc_table:near ; ZCONST ulg near *get_crc_table(void);
+
+;
+ IFNDEF NO_STD_STACKFRAME
+ ; Use a `standard' stack frame setup on routine entry and exit.
+ ; Actually, this option is set as default, because it results
+ ; in smaller code !!
+STD_ENTRY MACRO
+ push ebp
+ mov ebp,esp
+ ENDM
+
+ Arg1 EQU 08H[ebp]
+ Arg2 EQU 0CH[ebp]
+ Arg3 EQU 10H[ebp]
+
+STD_LEAVE MACRO
+ pop ebp
+ ENDM
+
+ ELSE ; NO_STD_STACKFRAME
+
+STD_ENTRY MACRO
+ ENDM
+
+ Arg1 EQU 18H[esp]
+ Arg2 EQU 1CH[esp]
+ Arg3 EQU 20H[esp]
+
+STD_LEAVE MACRO
+ ENDM
+
+ ENDIF ; ?NO_STD_STACKFRAME
+
+; These two (three) macros make up the loop body of the CRC32 cruncher.
+; registers modified:
+; eax : crc value "c"
+; esi : pointer to next data byte (or dword) "buf++"
+; registers read:
+; edi : pointer to base of crc_table array
+; scratch registers:
+; ebx : index into crc_table array
+; (requires upper three bytes = 0 when __686 is undefined)
+ IFNDEF __686 ; optimize for 386, 486, Pentium
+Do_CRC MACRO
+ mov bl,al ; tmp = c & 0xFF
+ shr eax,8 ; c = (c >> 8)
+ xor eax,[edi+ebx*4] ; ^ table[tmp]
+ ENDM
+ ELSE ; __686 : optimize for Pentium Pro, Pentium II and compatible CPUs
+Do_CRC MACRO
+ movzx ebx,al ; tmp = c & 0xFF
+ shr eax,8 ; c = (c >> 8)
+ xor eax,[edi+ebx*4] ; ^ table[tmp]
+ ENDM
+ ENDIF ; ?__686
+Do_CRC_byte MACRO
+ xor al, byte ptr [esi] ; c ^= *buf
+ inc esi ; buf++
+ Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
+ ENDM
+ IFNDEF NO_32_BIT_LOADS
+Do_CRC_dword MACRO
+ xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
+ add esi, 4 ; ((ulg *)buf)++
+ Do_CRC
+ Do_CRC
+ Do_CRC
+ Do_CRC
+ ENDM
+ ENDIF ; !NO_32_BIT_LOADS
+
+ IFNDEF NO_ALIGN
+_TEXT segment use32 para public 'CODE'
+ ELSE
+_TEXT segment use32
+ ENDIF
+ assume CS: _TEXT
+
+ public _crc32
+_crc32 proc near ; ulg crc32(ulg crc, ZCONST uch *buf, extent len)
+ STD_ENTRY
+ push edi
+ push esi
+ push ebx
+ push edx
+ push ecx
+
+ mov esi,Arg2 ; 2nd arg: uch *buf
+ sub eax,eax ;> if (!buf)
+ test esi,esi ;> return 0;
+ jz fine ;> else {
+
+ call _get_crc_table
+ mov edi,eax
+ mov eax,Arg1 ; 1st arg: ulg crc
+ IFNDEF __686
+ sub ebx,ebx ; ebx=0; make bl usable as a dword
+ ENDIF
+ mov ecx,Arg3 ; 3rd arg: extent len
+ not eax ;> c = ~crc;
+
+ test ecx,ecx
+ IFNDEF NO_UNROLLED_LOOPS
+ jz bail
+ IFNDEF NO_32_BIT_LOADS
+align_loop:
+ test esi,3 ; align buf pointer on next
+ jz SHORT aligned_now ; dword boundary
+ Do_CRC_byte
+ dec ecx
+ jnz align_loop
+aligned_now:
+ ENDIF ; !NO_32_BIT_LOADS
+ mov edx,ecx ; save len in edx
+ shr ecx,3 ; ecx = len / 8
+ jz SHORT No_Eights
+ IFNDEF NO_ALIGN
+; align loop head at start of 486 internal cache line !!
+ align 16
+ ENDIF
+Next_Eight:
+ IFNDEF NO_32_BIT_LOADS
+ Do_CRC_dword
+ Do_CRC_dword
+ ELSE ; NO_32_BIT_LOADS
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ ENDIF ; ?NO_32_BIT_LOADS
+ dec ecx
+ jnz Next_Eight
+No_Eights:
+ mov ecx,edx
+ and ecx,000000007H ; ecx = len % 8
+ ENDIF ; !NO_UNROLLED_LOOPS
+ jz SHORT bail ;> if (len)
+ IFNDEF NO_ALIGN
+; align loop head at start of 486 internal cache line !!
+ align 16
+ ENDIF
+loupe: ;> do {
+ Do_CRC_byte ; c = CRC32(c, *buf++);
+ dec ecx ;> } while (--len);
+ jnz loupe
+
+bail: ;> }
+ not eax ;> return ~c;
+fine:
+ pop ecx
+ pop edx
+ pop ebx
+ pop esi
+ pop edi
+ STD_LEAVE
+ ret
+_crc32 endp
+
+_TEXT ends
+;
+ ENDIF ; !USE_ZLIB
+;
+end
diff --git a/win32/crc_i386.c b/win32/crc_i386.c
new file mode 100644
index 0000000..e8a2faf
--- /dev/null
+++ b/win32/crc_i386.c
@@ -0,0 +1,228 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* crc_i386.c -- Microsoft 32-bit C/C++ adaptation of crc_i386.asm
+ * Created by Rodney Brown from crc_i386.asm, modified by Chr. Spieler.
+ *
+ * Original coded (in crc_i386.asm) and put into the public domain
+ * by Paul Kienitz and Christian Spieler.
+ *
+ * Revised 06-Oct-96, Scott Field (sfield@microsoft.com)
+ * fixed to assemble with masm by not using .model directive which makes
+ * assumptions about segment alignment. Also,
+ * avoid using loop, and j[e]cxz where possible. Use mov + inc, rather
+ * than lodsb, and other misc. changes resulting in the following performance
+ * increases:
+ *
+ * unrolled loops NO_UNROLLED_LOOPS
+ * *8 >8 <8 *8 >8 <8
+ *
+ * +54% +42% +35% +82% +52% +25%
+ *
+ * first item in each table is input buffer length, even multiple of 8
+ * second item in each table is input buffer length, > 8
+ * third item in each table is input buffer length, < 8
+ *
+ * Revised 02-Apr-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au)
+ * Incorporated Rodney Brown's 32-bit-reads optimization as found in the
+ * UNIX AS source crc_i386.S. This new code can be disabled by defining
+ * the macro symbol NO_32_BIT_LOADS.
+ *
+ * Revised 12-Oct-97, Chr. Spieler, based on Rodney Brown (rdb@cmutual.com.au)
+ * Incorporated Rodney Brown's additional tweaks for 32-bit-optimized CPUs
+ * (like the Pentium Pro, Pentium II, and probably some Pentium clones).
+ * This optimization is controlled by the macro symbol __686 and is disabled
+ * by default. (This default is based on the assumption that most users
+ * do not yet work on a Pentium Pro or Pentium II machine ...)
+ *
+ * Revised 16-Nov-97, Chr. Spieler: Made code compatible with Borland C++
+ * 32-bit, removed unneeded kludge for potentially unknown movzx mnemonic,
+ * confirmed correct working with MS VC++ (32-bit).
+ *
+ * Revised 22-May-98, Peter Kunath, Chr. Spieler: The 16-Nov-97 revision broke
+ * MSVC 5.0. Inside preprocessor macros, each instruction is enclosed in its
+ * own __asm {...} construct. For MSVC, a "#pragma warning" was added to
+ * shut up the "no return value" warning message.
+ *
+ * Revised 13-Dec-98, Chr. Spieler: Modified path to "zip.h" header file.
+ *
+ * Revised 16-Jan-2005, Cosmin Truta: Added the ASM_CRC guard, for easier
+ * switching between ASM vs. non-ASM builds, when handling makefiles.
+ * Also enabled the 686 build by default, because there are hardly any
+ * pre-686 CPUs in serious use nowadays. (See the 12-Oct-97 note above.)
+ *
+ * FLAT memory model assumed.
+ *
+ * Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
+ * This results in shorter code at the expense of reduced performance.
+ *
+ */
+
+#include "../zip.h"
+
+#if defined(ASM_CRC) && !defined(USE_ZLIB)
+
+#if !defined(PRE_686) && !defined(__686)
+# define __686
+#endif
+
+#ifndef ZCONST
+# define ZCONST const
+#endif
+
+/* Select wether the following inline-assember code is supported. */
+#if (defined(_MSC_VER) && _MSC_VER >= 700)
+#if (defined(_M_IX86) && _M_IX86 >= 300)
+# define MSC_INLINE_ASM_32BIT_SUPPORT
+ /* Disable warning for no return value, typical of asm functions */
+# pragma warning( disable : 4035 )
+#endif
+#endif
+
+#if (defined(__BORLANDC__) && __BORLANDC__ >= 452)
+# define MSC_INLINE_ASM_32BIT_SUPPORT
+#endif
+
+#ifdef MSC_INLINE_ASM_32BIT_SUPPORT
+/* This code is intended for Microsoft C/C++ (32-bit) compatible compilers. */
+
+/*
+ * These two (three) macros make up the loop body of the CRC32 cruncher.
+ * registers modified:
+ * eax : crc value "c"
+ * esi : pointer to next data byte (or dword) "buf++"
+ * registers read:
+ * edi : pointer to base of crc_table array
+ * scratch registers:
+ * ebx : index into crc_table array
+ * (requires upper three bytes = 0 when __686 is undefined)
+ */
+#ifndef __686
+#define Do_CRC { \
+ __asm { mov bl, al }; \
+ __asm { shr eax, 8 }; \
+ __asm { xor eax, [edi+ebx*4] }; }
+#else /* __686 */
+#define Do_CRC { \
+ __asm { movzx ebx, al }; \
+ __asm { shr eax, 8 }; \
+ __asm { xor eax, [edi+ebx*4] }; }
+#endif /* ?__686 */
+
+#define Do_CRC_byte { \
+ __asm { xor al, byte ptr [esi] }; \
+ __asm { inc esi }; \
+ Do_CRC; }
+
+#ifndef NO_32_BIT_LOADS
+#define Do_CRC_dword { \
+ __asm { xor eax, dword ptr [esi] }; \
+ __asm { add esi, 4 }; \
+ Do_CRC; \
+ Do_CRC; \
+ Do_CRC; \
+ Do_CRC; }
+#endif /* !NO_32_BIT_LOADS */
+
+/* ========================================================================= */
+ulg crc32(crc, buf, len)
+ ulg crc; /* crc shift register */
+ ZCONST uch *buf; /* pointer to bytes to pump through */
+ extent len; /* number of bytes in buf[] */
+/* Run a set of bytes through the crc shift register. If buf is a NULL
+ pointer, then initialize the crc shift register contents instead.
+ Return the current crc in either case. */
+{
+ __asm {
+ push edx
+ push ecx
+
+ mov esi,buf ;/* 2nd arg: uch *buf */
+ sub eax,eax ;/*> if (!buf) */
+ test esi,esi ;/*> return 0; */
+ jz fine ;/*> else { */
+
+ call get_crc_table
+ mov edi,eax
+ mov eax,crc ;/* 1st arg: ulg crc */
+#ifndef __686
+ sub ebx,ebx ;/* ebx=0; => bl usable as a dword */
+#endif
+ mov ecx,len ;/* 3rd arg: extent len */
+ not eax ;/*> c = ~crc; */
+
+ test ecx,ecx
+#ifndef NO_UNROLLED_LOOPS
+ jz bail
+# ifndef NO_32_BIT_LOADS
+align_loop:
+ test esi,3 ;/* align buf pointer on next */
+ jz aligned_now ;/* dword boundary */
+ }
+ Do_CRC_byte ;
+ __asm {
+ dec ecx
+ jnz align_loop
+aligned_now:
+# endif /* !NO_32_BIT_LOADS */
+ mov edx,ecx ;/* save len in edx */
+ shr ecx,3 ;/* ecx = len / 8 */
+ jz No_Eights
+; align loop head at start of 486 internal cache line !!
+ align 16
+Next_Eight:
+ }
+# ifndef NO_32_BIT_LOADS
+ Do_CRC_dword ;
+ Do_CRC_dword ;
+# else /* NO_32_BIT_LOADS */
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+# endif /* ?NO_32_BIT_LOADS */
+ __asm {
+ dec ecx
+ jnz Next_Eight
+No_Eights:
+ mov ecx,edx
+ and ecx,000000007H ;/* ecx = len % 8 */
+
+#endif /* !NO_UNROLLED_LOOPS */
+ jz bail ;/*> if (len) */
+; align loop head at start of 486 internal cache line !!
+ align 16
+loupe: ;/*> do { */
+ }
+ Do_CRC_byte ;/* c = CRC32(c, *buf++); */
+ __asm {
+ dec ecx ;/*> } while (--len); */
+ jnz loupe
+
+bail: ;/*> } */
+ not eax ;/*> return ~c; */
+fine:
+ pop ecx
+ pop edx
+ }
+#ifdef NEED_RETURN
+ return _EAX;
+#endif
+}
+#endif /* MSC_INLINE_ASM_32BIT_SUPPORT */
+#if (defined(_MSC_VER) && _MSC_VER >= 700)
+#if (defined(_M_IX86) && _M_IX86 >= 300)
+ /* Reenable missing return value warning */
+# pragma warning( default : 4035 )
+#endif
+#endif
+#endif /* ASM_CRC && !USE_ZLIB */
diff --git a/win32/crc_lcc.asm b/win32/crc_lcc.asm
new file mode 100644
index 0000000..3c7a41c
--- /dev/null
+++ b/win32/crc_lcc.asm
@@ -0,0 +1,119 @@
+;===========================================================================
+; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2004-May-22 or later
+; (the contents of which are also included in zip.h) for terms of use.
+; If, for some reason, both of these files are missing, the Info-ZIP license
+; also may be found at: ftp://ftp.info-zip.org/pub/infozip/licen; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+;===========================================================================
+; crc_lcc.asm, optimized CRC calculation function for Zip and UnZip,
+; created by Paul Kienitz and Christian Spieler. Last revised 24 Dec 98.
+;
+; The code in this file has been copied verbatim from crc_i386.{asm|S};
+; only the assembler syntax and metacommands have been adapted to
+; the habits of the free LCC-Win32 C compiler package.
+; This version of the code uses the "optimized for i686" variant of
+; crc_i386.{asm|S}.
+; IMPORTANT NOTE to the Info-ZIP editors:
+; The TAB characters in this source file are required by the parser of
+; the LCC-Win32 assembler program and MUST NOT be removed!!
+;
+; For more information (and a revision log), look into the original
+; source files.
+;
+ .text
+ .file "crc32.c"
+ .text
+ .type _crc32,function
+_crc32:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %ecx
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ .line 34
+ .line 37
+ movl 12(%ebp),%esi
+ subl %eax,%eax
+ testl %esi,%esi
+ jz _$3
+ .line 39
+ call _get_crc_table
+ movl %eax,%edi
+ .line 41
+ movl 8(%ebp),%eax
+ movl 16(%ebp),%ecx
+ notl %eax
+ testl %ecx,%ecx
+ jz _$4
+_$5:
+ testl $3,%esi
+ jz _$6
+ xorb (%esi),%al
+ incl %esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ decl %ecx
+ jnz _$5
+_$6:
+ movl %ecx,%edx
+ shrl $3,%ecx
+ jz _$8
+_$7:
+ xorl (%esi),%eax
+ addl $4,%esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ xorl (%esi),%eax
+ addl $4,%esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ decl %ecx
+ jnz _$7
+_$8:
+ movl %edx,%ecx
+ andl $7,%ecx
+ jz _$4
+_$9:
+ xorb (%esi),%al
+ incl %esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ decl %ecx
+ jnz _$9
+_$4:
+ xorl $0xffffffff,%eax
+_$3:
+ .line 52
+ popl %edi
+ popl %esi
+ popl %ebx
+ leave
+ ret
+_$34:
+ .size _crc32,_$34-_crc32
+ .globl _crc32
+ .extern _get_crc_table
diff --git a/win32/gvmat64.asm b/win32/gvmat64.asm
new file mode 100644
index 0000000..4b5aa4d
--- /dev/null
+++ b/win32/gvmat64.asm
@@ -0,0 +1,513 @@
+;uInt longest_match_x64(
+; deflate_state *s,
+; IPos cur_match); /* current match */
+
+; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86
+; Copyright (C) 1995-2005 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+;
+; File written by Gilles Vollant, by converting to assembly the longest_match
+; from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+;
+; and by taking inspiration on asm686 with masm, optimised assembly code
+; from Brian Raiter, written 1998
+;
+; http://www.zlib.net
+; http://www.winimage.com/zLibDll
+; http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; to compile this file for infozip Zip, I use option:
+; ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm
+;
+; to compile this file for zLib, I use option:
+; ml64.exe /Flgvmat64 /c /Zi gvmat64.asm
+; Be carrefull to adapt zlib1222add below to your version of zLib
+; (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change
+; value of zlib1222add later)
+;
+; This file compile with Microsoft Macro Assembler (x64) for AMD64
+;
+; ml64.exe is given with Visual Studio 2005 and Windows 2003 server DDK
+;
+; (you can get Windows 2003 server DDK with ml64 and cl for AMD64 from
+; http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)
+;
+
+
+;uInt longest_match(s, cur_match)
+; deflate_state *s;
+; IPos cur_match; /* current match */
+.code
+longest_match PROC
+
+
+;LocalVarsSize equ 88
+ LocalVarsSize equ 72
+
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
+; free register : r14,r15
+; register can be saved : rsp
+
+ chainlenwmask equ rsp + 8 - LocalVarsSize ; high word: current chain len
+ ; low word: s->wmask
+;window equ rsp + xx - LocalVarsSize ; local copy of s->window ; stored in r10
+;windowbestlen equ rsp + xx - LocalVarsSize ; s->window + bestlen , use r10+r11
+;scanstart equ rsp + xx - LocalVarsSize ; first two bytes of string ; stored in r12w
+;scanend equ rsp + xx - LocalVarsSize ; last two bytes of string use ebx
+;scanalign equ rsp + xx - LocalVarsSize ; dword-misalignment of string r13
+;bestlen equ rsp + xx - LocalVarsSize ; size of best match so far -> r11d
+;scan equ rsp + xx - LocalVarsSize ; ptr to string wanting match -> r9
+IFDEF INFOZIP
+ELSE
+ nicematch equ (rsp + 16 - LocalVarsSize) ; a good enough match size
+ENDIF
+
+save_rdi equ rsp + 24 - LocalVarsSize
+save_rsi equ rsp + 32 - LocalVarsSize
+save_rbx equ rsp + 40 - LocalVarsSize
+save_rbp equ rsp + 48 - LocalVarsSize
+save_r12 equ rsp + 56 - LocalVarsSize
+save_r13 equ rsp + 64 - LocalVarsSize
+;save_r14 equ rsp + 72 - LocalVarsSize
+;save_r15 equ rsp + 80 - LocalVarsSize
+
+
+
+; all the +4 offsets are due to the addition of pending_buf_size (in zlib
+; in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, remove the +4).
+; Note : these value are good with a 8 bytes boundary pack structure
+
+
+ MAX_MATCH equ 258
+ MIN_MATCH equ 3
+ MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
+
+
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+; all the +zlib1222add offsets are due to the addition of fields
+; in zlib in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+
+
+IFDEF INFOZIP
+
+_DATA SEGMENT
+COMM window_size:DWORD
+; WMask ; 7fff
+COMM window:BYTE:010040H
+COMM prev:WORD:08000H
+; MatchLen : unused
+; PrevMatch : unused
+COMM strstart:DWORD
+COMM match_start:DWORD
+; Lookahead : ignore
+COMM prev_length:DWORD ; PrevLen
+COMM max_chain_length:DWORD
+COMM good_match:DWORD
+COMM nice_match:DWORD
+prev_ad equ OFFSET prev
+window_ad equ OFFSET window
+nicematch equ nice_match
+_DATA ENDS
+WMask equ 07fffh
+
+ELSE
+
+ IFNDEF zlib1222add
+ zlib1222add equ 0
+ ENDIF
+dsWSize equ 56+zlib1222add+(zlib1222add/2)
+dsWMask equ 64+zlib1222add+(zlib1222add/2)
+dsWindow equ 72+zlib1222add
+dsPrev equ 88+zlib1222add
+dsMatchLen equ 128+zlib1222add
+dsPrevMatch equ 132+zlib1222add
+dsStrStart equ 140+zlib1222add
+dsMatchStart equ 144+zlib1222add
+dsLookahead equ 148+zlib1222add
+dsPrevLen equ 152+zlib1222add
+dsMaxChainLen equ 156+zlib1222add
+dsGoodMatch equ 172+zlib1222add
+dsNiceMatch equ 176+zlib1222add
+
+window_size equ [ rcx + dsWSize]
+WMask equ [ rcx + dsWMask]
+window_ad equ [ rcx + dsWindow]
+prev_ad equ [ rcx + dsPrev]
+strstart equ [ rcx + dsStrStart]
+match_start equ [ rcx + dsMatchStart]
+Lookahead equ [ rcx + dsLookahead] ; 0ffffffffh on infozip
+prev_length equ [ rcx + dsPrevLen]
+max_chain_length equ [ rcx + dsMaxChainLen]
+good_match equ [ rcx + dsGoodMatch]
+nice_match equ [ rcx + dsNiceMatch]
+ENDIF
+
+; parameter 1 in r8(deflate state s), param 2 in rdx (cur match)
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
+
+
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+
+;;; Retrieve the function arguments. r8d will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
+
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
+
+ mov [save_rdi],rdi
+ mov [save_rsi],rsi
+ mov [save_rbx],rbx
+ mov [save_rbp],rbp
+IFDEF INFOZIP
+ mov r8d,ecx
+ELSE
+ mov r8d,edx
+ENDIF
+ mov [save_r12],r12
+ mov [save_r13],r13
+; mov [save_r14],r14
+; mov [save_r15],r15
+
+
+;;; uInt wmask = s->w_mask;
+;;; unsigned chain_length = s->max_chain_length;
+;;; if (s->prev_length >= s->good_match) {
+;;; chain_length >>= 2;
+;;; }
+
+ mov edi, prev_length
+ mov esi, good_match
+ mov eax, WMask
+ mov ebx, max_chain_length
+ cmp edi, esi
+ jl LastMatchGood
+ shr ebx, 2
+LastMatchGood:
+
+;;; chainlen is decremented once beforehand so that the function can
+;;; use the sign flag instead of the zero flag for the exit test.
+;;; It is then shifted into the high word, to make room for the wmask
+;;; value, which it will always accompany.
+
+ dec ebx
+ shl ebx, 16
+ or ebx, eax
+
+;;; on zlib only
+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+IFDEF INFOZIP
+ mov [chainlenwmask], ebx
+; on infozip nice_match = [nice_match]
+ELSE
+ mov eax, nice_match
+ mov [chainlenwmask], ebx
+ mov r10d, Lookahead
+ cmp r10d, eax
+ cmovnl r10d, eax
+ mov [nicematch],r10d
+ENDIF
+
+;;; register Bytef *scan = s->window + s->strstart;
+ mov r10, window_ad
+ mov ebp, strstart
+ lea r13, [r10 + rbp]
+
+;;; Determine how many bytes the scan ptr is off from being
+;;; dword-aligned.
+
+ mov r9,r13
+ neg r13
+ and r13,3
+
+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
+IFDEF INFOZIP
+ mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1))
+ELSE
+ mov eax, window_size
+ sub eax, MIN_LOOKAHEAD
+ENDIF
+ xor edi,edi
+ sub ebp, eax
+
+ mov r11d, prev_length
+
+ cmovng ebp,edi
+
+;;; int best_len = s->prev_length;
+
+
+;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+ lea rsi,[r10+r11]
+
+;;; register ush scan_start = *(ushf*)scan;
+;;; register ush scan_end = *(ushf*)(scan+best_len-1);
+;;; Posf *prev = s->prev;
+
+ movzx r12d,word ptr [r9]
+ movzx ebx, word ptr [r9 + r11 - 1]
+
+ mov rdi, prev_ad
+
+;;; Jump into the main loop.
+
+ mov edx, [chainlenwmask]
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+
+LookupLoop1:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+ sub edx, 00010000h
+ js LeaveNow
+
+LoopEntry1:
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+
+LookupLoop2:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+ sub edx, 00010000h
+ js LeaveNow
+
+LoopEntry2:
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+
+LookupLoop4:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+ sub edx, 00010000h
+ js LeaveNow
+
+LoopEntry4:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ jnz LookupLoop1
+ jmp LookupLoopIsZero
+
+
+;;; do {
+;;; match = s->window + cur_match;
+;;; if (*(ushf*)(match+best_len-1) != scan_end ||
+;;; *(ushf*)match != scan_start) continue;
+;;; [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;; && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; r8d = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+
+LookupLoop:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+ sub edx, 00010000h
+ js LeaveNow
+
+LoopEntry:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ jnz LookupLoop1
+LookupLoopIsZero:
+ cmp r12w, word ptr [r10 + r8]
+ jnz LookupLoop1
+
+
+;;; Store the current value of chainlen.
+ mov [chainlenwmask], edx
+
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+
+ lea rsi,[r8+r10]
+ mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8)
+ lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8]
+ lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8]
+
+ prefetcht1 [rsi+rdx]
+ prefetcht1 [rdi+rdx]
+
+
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust rdx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (rsi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+
+
+LoopCmps:
+ mov rax, [rsi + rdx]
+ xor rax, [rdi + rdx]
+ jnz LeaveLoopCmps
+
+ mov rax, [rsi + rdx + 8]
+ xor rax, [rdi + rdx + 8]
+ jnz LeaveLoopCmps8
+
+
+ mov rax, [rsi + rdx + 8+8]
+ xor rax, [rdi + rdx + 8+8]
+ jnz LeaveLoopCmps16
+
+ add rdx,8+8+8
+
+ jmp short LoopCmps
+LeaveLoopCmps16: add rdx,8
+LeaveLoopCmps8: add rdx,8
+LeaveLoopCmps:
+
+ test eax, 0000FFFFh
+ jnz LenLower
+
+ test eax,0ffffffffh
+
+ jnz LenLower32
+
+ add rdx,4
+ shr rax,32
+ or ax,ax
+ jnz LenLower
+
+LenLower32:
+ shr eax,16
+ add rdx,2
+LenLower: sub al, 1
+ adc rdx, 0
+;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+;;; then automatically accept it as the best possible match and leave.
+
+ lea rax, [rdi + rdx]
+ sub rax, r9
+ cmp eax, MAX_MATCH
+ jge LenMaximum
+
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+;///////////////////////////////////
+
+ cmp eax, r11d
+ jg LongerMatch
+
+ lea rsi,[r10+r11]
+
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ jmp LookupLoop
+
+;;; s->match_start = cur_match;
+;;; best_len = len;
+;;; if (len >= nice_match) break;
+;;; scan_end = *(ushf*)(scan+best_len-1);
+
+LongerMatch:
+ mov r11d, eax
+ mov match_start, r8d
+ cmp eax, [nicematch]
+ jge LeaveNow
+
+ lea rsi,[r10+rax]
+
+ movzx ebx, word ptr [r9 + rax - 1]
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ jmp LookupLoop
+
+;;; Accept the current string, with the maximum possible length.
+
+LenMaximum:
+ mov r11d,MAX_MATCH
+ mov match_start, r8d
+
+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+;;; return s->lookahead;
+
+LeaveNow:
+IFDEF INFOZIP
+ mov eax,r11d
+ELSE
+ mov eax, Lookahead
+ cmp r11d, eax
+ cmovng eax, r11d
+ENDIF
+
+;;; Restore the stack and return from whence we came.
+
+
+ mov rsi,[save_rsi]
+ mov rdi,[save_rdi]
+ mov rbx,[save_rbx]
+ mov rbp,[save_rbp]
+ mov r12,[save_r12]
+ mov r13,[save_r13]
+; mov r14,[save_r14]
+; mov r15,[save_r15]
+
+
+ ret 0
+; please don't remove this string !
+; Your can freely use gvmat64 in any free or commercial app
+; but it is far better don't remove the string in the binary!
+ db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
+longest_match ENDP
+
+match_init PROC
+ ret 0
+match_init ENDP
+
+
+END
diff --git a/win32/lm32_lcc.asm b/win32/lm32_lcc.asm
new file mode 100644
index 0000000..2fde1a4
--- /dev/null
+++ b/win32/lm32_lcc.asm
@@ -0,0 +1,174 @@
+;===========================================================================
+; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2004-May-22 or later
+; (the contents of which are also included in zip.h) for terms of use.
+; If, for some reason, both of these files are missing, the Info-ZIP license
+; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+;===========================================================================
+; match32.asm by Jean-loup Gailly.
+
+; match32.asm, optimized version of longest_match() in deflate.c
+; To be used only with 32 bit flat model. To simplify the code, the option
+; -DDYN_ALLOC is not supported.
+; This file is only optional. If you don't have an assembler, use the
+; C version (add -DNO_ASM to CFLAGS in makefile and remove match.o
+; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is
+; assembled with an equivalent -DWSIZE=<whatever>.
+;
+; Win32 (Windows NT) version - 1994/04/13 by Steve Salisbury
+; * works with Microsoft MASM 6.1X and Microsoft Visual C++ / 32-bit edition
+;
+; The code in this file has been copied verbatim from match32.{asm|S};
+; only the assembler syntax and metacommands have been adapted to
+; the habits of the free LCC-Win32 C compiler package.
+; IMPORTANT NOTE to the Info-ZIP editors:
+; The TAB characters in this source file are required by the parser of
+; the LCC-Win32 assembler program and MUST NOT be removed!!
+;
+;==============================================================================
+;
+; Do NOT assemble this source if external crc32 routine from zlib gets used.
+;
+
+
+;/* This version is for 386 Unix or OS/2 in 32 bit mode.
+; * Warning: it uses the AT&T syntax: mov source,dest
+; * This file is only optional. If you want to force the C version,
+; * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
+; * If you have reduced WSIZE in (g)zip.h, then make sure this is
+; * assembled with an equivalent -DWSIZE=<whatever>.
+; * This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
+; */
+
+ .text
+ .file "match.S"
+
+
+ .text
+ .type _match_init,function
+
+_match_init:
+ ret
+_$98:
+ .size _match_init,_$98-_match_init
+ .globl _match_init
+
+;/*-----------------------------------------------------------------------
+; * Set match_start to the longest match starting at the given string and
+; * return its length. Matches shorter or equal to prev_length are discarded,
+; * in which case the result is equal to prev_length and match_start is
+; * garbage.
+; * IN assertions: cur_match is the head of the hash chain for the current
+; * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+; */
+
+ .align 4
+ .type _longest_match,function
+
+_longest_match: ;/* int longest_match(cur_match) */
+
+; cur_match equ 20(%esp)
+; /* return address */ /* esp+16 */
+ push %ebp
+ push %edi
+;/* esp+8 */
+ push %esi
+;/* esp+4 */
+ push %ebx
+;/* esp */
+
+;/*
+; * match equ esi
+; * scan equ edi
+; * chain_length equ ebp
+; * best_len equ ebx
+; * limit equ edx
+; */
+ mov 20(%esp),%esi
+ mov _strstart,%edx
+ mov _max_chain_length,%ebp
+ mov %edx,%edi
+ sub $(32768-262),%edx
+ cld
+ jae limit_ok
+ sub %edx,%edx
+limit_ok:
+ add $2+_window,%edi
+ mov _prev_length,%ebx
+ movw -2(%edi),%cx
+ movw -3(%ebx,%edi),%ax
+ cmp _good_match,%ebx
+ jb do_scan
+ shr $2,%ebp
+ jmp do_scan
+
+ .align 4
+long_loop:
+;/* at this point, edi == scan+2, esi == cur_match */
+ movw -3(%ebx,%edi),%ax
+ movw -2(%edi),%cx
+short_loop:
+;/*
+; * at this point, di == scan+2, si == cur_match,
+; * ax = scan[best_len-1..best_len] and cx = scan[0..1]
+; */
+ and $(32768-1), %esi
+ dec %ebp
+ movw _prev(,%esi,2),%si
+ jz the_end
+ cmp %edx,%esi
+ jbe the_end
+do_scan:
+ cmpw _window-1(%ebx,%esi),%ax
+ jne short_loop
+ cmpw _window(%esi),%cx
+ jne short_loop
+
+ add $2+_window,%esi
+ mov $((258>>1)-1),%ecx
+ mov %edi,%eax
+ repe; cmpsw
+;/* loop until mismatch */
+ je maxmatch
+;/* match of length MAX_MATCH? */
+mismatch:
+ movb -2(%edi),%cl
+ xchg %edi,%eax
+ subb -2(%esi),%cl
+ sub %edi,%eax
+ sub $2+_window,%esi
+ sub %eax,%esi
+ subb $1,%cl
+ adc $0,%eax
+ cmp %ebx,%eax
+ jle long_loop
+ mov %esi,_match_start
+ mov %eax,%ebx
+ cmp _nice_match,%eax
+; /* len >= nice_match ? */
+ jl long_loop
+the_end:
+ mov %ebx,%eax
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+ ret
+ .align 4
+maxmatch:
+ cmpsb
+ jmp mismatch
+_$99:
+
+ .size _longest_match,_$99-_longest_match
+ .globl _longest_match
+
+ .extern _nice_match
+ .extern _good_match
+ .extern _max_chain_length
+ .extern _match_start
+ .extern _strstart
+ .extern _prev_length
+ .extern _prev
+ .extern _window
diff --git a/win32/makefile.a64 b/win32/makefile.a64
new file mode 100644
index 0000000..521950e
--- /dev/null
+++ b/win32/makefile.a64
@@ -0,0 +1,134 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# 32-bit Microsoft Visual C++
+
+# To use, do "nmake -f makefile.w32"
+
+# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if
+# you do not have masm 6.1X.
+
+# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM)
+# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added
+# to the declaration of LOC here:
+LOC = $(LOCAL_ZIP)
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+ASMOBJS = gvmat64.obj
+
+# ------------- 32-bit Microsoft Visual C++ -------------
+CC=cl -nologo
+CFLAGS=-W3 -O2 -DNO_ASM_CRC -DASMV -DWIN32 $(LOC)
+UTILFLAGS=$(CFLAGS) -DUTIL -Fo$@
+
+# Remove "-coff" from ASFLAGS if you do not have MASM 6.11.
+
+AS=ml64 -nologo
+ASFLAGS= /c /Zi /DINFOZIP
+
+# If you build 16-bit executables with MS Visual C++ v1.0/1.5 and link them
+# with the /KNOWEAS switch, you can build dual-mode MS-DOS/Win32 executables
+# by passing the -stub switch to the 32-bit linker to specify the 16-bit part.
+
+LD=link -nologo
+LDFLAGS=advapi32.lib
+
+# variables
+OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj crctab.obj globals.obj
+
+OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj
+
+OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj win32_.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.obj crctab.obj crypt_.obj ttyio.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
+
+ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zips: $(ZIPS)
+
+zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+util.obj: util.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+globals.obj: globals.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crctab.obj: crctab.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+win32zip.obj: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) -c $(CFLAGS) -I. win32/win32zip.c
+
+win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(CFLAGS) -I. win32/win32.c
+
+nt.obj: win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) -c $(CFLAGS) -I. win32/nt.c
+
+zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipnote.obj: zipnote.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile_.obj: zipfile.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) util.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(UTILFLAGS) crypt.c
+
+win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(UTILFLAGS) -I. win32/win32.c
+
+gvmat64.obj: win32/gvmat64.asm
+ $(AS) $(ASFLAGS) win32\gvmat64.asm
+
+zip.exe: $(OBJZ) $(OBJI)
+ $(LD) $(LDFLAGS) $(OBJZ) $(OBJI)
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) $(OBJC)
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) $(OBJN)
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS)
diff --git a/win32/makefile.bor b/win32/makefile.bor
new file mode 100644
index 0000000..5f70b81
--- /dev/null
+++ b/win32/makefile.bor
@@ -0,0 +1,179 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# Borland C++ for Windows 9x/NT
+# By E-Yen Tan. Last updated on 24 Jan 2005.
+
+# To use, do "make -fwin32\makefile.bor"
+
+# Add -DNO_ASM to LOC and comment out the ASMOBJS definition below
+# if you do not have tasm32.
+
+# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM)
+# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added
+# to the declaration of LOC here:
+!IF $(USEASM)
+LOC = $(LOCAL_ZIP)
+!ELSE
+LOC = -DNO_ASM $(LOCAL_ZIP)
+!ENDIF
+
+# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 6
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+!IF $(USEASM)
+ASMOBJS = match32.obj crc_i386.obj
+!ENDIF
+
+ASCPUFLAG = __$(CPU_TYP)86
+
+VPATH=.;win32
+CC = bcc32
+CFLAGS=-w -w-aus -w-ccc -w-par -w-sig -O2 -I. -DWIN32 $(LOC)
+UTILFLAGS=-DUTIL $(CFLAGS) -o
+
+!ifdef USETASM16
+AS=tasm
+!else
+AS=tasm32
+!endif
+ASFLAGS=-ml -t -m2 -D$(ASCPUFLAG) $(LOC)
+
+LD=$(CC)
+LDFLAGS=
+
+# variables
+OBJZ1 = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj crctab.obj globals.obj
+OBJZ2 = deflate.obj trees.obj $(ASMOBJS)
+OBJZS = win32zip.obj win32.obj nt.obj
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS)
+
+OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj win32_.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.obj crctab.obj crypt_.obj ttyio.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
+
+ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zips: $(ZIPS)
+
+zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+util.obj: util.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+globals.obj: globals.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crctab.obj: crctab.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+win32zip.obj: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) -c $(CFLAGS) win32/$*.c
+
+win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(CFLAGS) win32/$*.c
+
+nt.obj: win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) -c $(CFLAGS) win32/$*.c
+
+zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipnote.obj: zipnote.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile_.obj: zipfile.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$* zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$* fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$* util.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(UTILFLAGS)$* crypt.c
+
+win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(UTILFLAGS)$* win32/win32.c
+
+!ifdef USEMASM
+crc_i386.obj: win32/crc_i386.asm
+ masm -ml win32/crc_i386.asm,$@;
+!else
+!ifndef ASMOVERBCC32
+crc_i386.obj: win32/crc_i386.asm
+ $(AS) $(ASFLAGS) win32\crc_i386.asm, $@ ;
+!else
+crc_i386.obj: win32/crc_i386.c
+ $(CC) -c $(CFLAGS) -o$@ win32/crc_i386.c
+!endif
+!endif
+
+!ifdef USEMASM
+match32.obj: win32/match32.asm
+ masm -ml win32/match32.asm,$@;
+!else
+match32.obj: win32/match32.asm
+ $(AS) $(ASFLAGS) win32\match32.asm, $@ ;
+!endif
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+zip.exe: $(OBJZ)
+ echo $(OBJZ1) > zip.rsp
+ echo $(OBJZ2) >> zip.rsp
+ echo $(OBJZS) >> zip.rsp
+ $(LD) $(LDFLAGS) @zip.rsp
+ del zip.rsp
+
+zipcloak.exe: $(OBJC)
+ echo $(OBJC) > zipc.rsp
+ $(LD) $(LDFLAGS) @zipc.rsp
+ del zipc.rsp
+
+zipnote.exe: $(OBJN)
+ echo $(OBJN) > zipn.rsp
+ $(LD) $(LDFLAGS) @zipn.rsp
+ del zipn.rsp
+
+zipsplit.exe: $(OBJS)
+ echo $(OBJS) > zips.rsp
+ $(LD) $(LDFLAGS) @zips.rsp
+ del zips.rsp
+
+clean:
+ del *.obj
+ del *.exe
+ del *.tds
diff --git a/win32/makefile.dj b/win32/makefile.dj
new file mode 100644
index 0000000..ead72e0
--- /dev/null
+++ b/win32/makefile.dj
@@ -0,0 +1,110 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit
+# for djgpp 2.01 and RSXNTDJ 1.3.1 under Windows 95 / Windows NT
+# Derived from makefile.os2 by E-Yen Tan. Last updated 22 May 1998.
+
+CC = gcc -O2 -m486 -Wall -Zwin32
+CFLAGS = -DWIN32 -DASM_CRC $(LOCAL_ZIP)
+AS = gcc
+ASFLAGS = -Di386
+LDFLAGS = -o ./
+LDFLAGS2 =
+OBJ=.o
+
+CRC32=crc_gcc
+OBJA = matchgcc.o
+OBJZS = win32.o win32zip.o nt.o
+OBJUS = win32_.o
+OSDEP_H = win32/osdep.h
+
+ADVAPI32 = adv32
+ADVAPI32LIB = lib$(ADVAPI32).a
+L_ADVAPI32 = -l$(ADVAPI32)
+
+OBJZ1 = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \
+ $(CRC32)$(OBJ) crctab$(OBJ)
+OBJZ2 = globals$(OBJ) deflate$(OBJ) trees$(OBJ) crypt$(OBJ) \
+ ttyio$(OBJ)
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS) $(OBJA)
+
+OBJU1 = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) globals$(OBJ)
+OBJU = $(OBJU1) $(OBJUS)
+
+OBJN = zipnote$(OBJ) $(OBJU)
+OBJS = zipsplit$(OBJ) $(OBJU)
+OBJC = zipcloak$(OBJ) crctab$(OBJ) crypt_$(OBJ) ttyio$(OBJ) $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
+
+# rules
+
+.SUFFIXES: .c $(OBJ)
+
+.c$(OBJ):
+ $(CC) -c -I. $(CFLAGS) $<
+
+.asm$(OBJ):
+ $(AS) $(ASFLAGS) $<
+
+all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zip$(OBJ): zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zipfile$(OBJ): zipfile.c $(ZIP_H)
+zipup$(OBJ): zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
+fileio$(OBJ): fileio.c $(ZIP_H)
+util$(OBJ): util.c $(ZIP_H)
+globals$(OBJ): globals.c $(ZIP_H)
+deflate$(OBJ): deflate.c $(ZIP_H)
+trees$(OBJ): trees.c $(ZIP_H)
+crc32$(OBJ): crc32.c $(ZIP_H)
+crctab$(OBJ): crctab.c $(ZIP_H)
+crypt$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h
+ttyio$(OBJ): ttyio.c $(ZIP_H) crypt.h ttyio.h
+
+win32zip$(OBJ): win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) -c -I. $(CFLAGS) win32/win32zip.c
+
+win32$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c -I. $(CFLAGS) win32/win32.c
+
+nt$(OBJ): win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) -c -I. $(CFLAGS) win32/nt.c
+
+crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS
+ $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o$@ crc_i386.S
+
+matchgcc$(OBJ): match.S
+ $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o$@ match.S
+
+zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+zipnote$(OBJ): zipnote.c $(ZIP_H) revision.h
+zipsplit$(OBJ): zipsplit.c $(ZIP_H) revision.h
+
+zipfile_$(OBJ): zipfile.c $(ZIP_H)
+ $(CC) -c -I. $(CFLAGS) -DUTIL -o$@ zipfile.c
+
+fileio_$(OBJ): fileio.c $(ZIP_H)
+ $(CC) -c -I. $(CFLAGS) -DUTIL -o$@ fileio.c
+
+util_$(OBJ): util.c $(ZIP_H) os2/os2zip.h
+ $(CC) -c -I. $(CFLAGS) -DUTIL -o$@ util.c
+
+crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c -I. $(CFLAGS) -DUTIL -o$@ crypt.c
+
+win32_$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c -I. $(CFLAGS) -DUTIL -o$@ win32/win32.c
+
+$(ADVAPI32LIB):
+ makelib "$(windir)/system/advapi32.dll" -o ./$@
+
+zip.exe: $(OBJZ) $(ADVAPI32LIB)
+ $(CC) $(LDFLAGS)$@ $(OBJZ) $(L_ADVAPI32) $(LDFLAGS2)
+
+zipcloak.exe: $(OBJC)
+ $(CC) $(LDFLAGS)$@ $(OBJC) $(LDFLAGS2)
+
+zipnote.exe: $(OBJN)
+ $(CC) $(LDFLAGS)$@ $(OBJN) $(LDFLAGS2)
+
+zipsplit.exe: $(OBJS)
+ $(CC) $(LDFLAGS)$@ $(OBJS) $(LDFLAGS2)
diff --git a/win32/makefile.emx b/win32/makefile.emx
new file mode 100644
index 0000000..197a8ea
--- /dev/null
+++ b/win32/makefile.emx
@@ -0,0 +1,291 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit
+# using emx 0.9c+rsxnt for Windows 95/98 and Windows NT and emx 0.9c for DOS.
+# By Kai-Uwe Rommel, Chr. Spieler, E-Yen Tan (and others).
+# Last updated 30th June 1998.
+#
+# Supported Make utilities:
+# - Microsoft/IBM nmake (e.g. from MSC 6.0 or newer)
+# - dmake 3.8 or higher
+# - GNU make, at least version 3.68 (GNUish 16-bit port, RSXNT Make 3.75,
+# DJGPP v1.12 Make 3.71, some versions of DJGPP v2.x 32-bit Make;
+# current DJGPP v2.01 Make 3.76.1 does NOT work)
+# - NOT watcom make
+# The "smart" Make utilities mentioned below are Christian Spieler's
+# enhanced version of GNUish 16-bit Make (3.74) and his adaption of these
+# GNU Make sources to EMX (32-bit).
+
+# Supported 32-bit C Compilers (created programs run under WinNT/Win95 only):
+# - GNU gcc (emx/rsxnt kit 0.9c or newer)
+
+# Supported Cross-Compilers for MS-DOS:
+# - GNU gcc (emx kit 0.9c or newer, 32-bit)
+
+# Supported Assemblers:
+# - GNU as with GNU gcc
+
+
+# To use, enter "make/nmake/dmake -f win32/makefile.emx"
+# (this makefile depends on its name being "win32/makefile.emx").
+
+# Add -DDYN_ALLOC to ASFLAGS if you have defined it in tailor.h or CFLAGS
+
+# Note: assembly language modules are really only supported for
+# GNU gcc 32-bit compilation.
+
+
+default:
+ @echo "Enter $(MAKE) -f win32/makefile.emx target"
+ @echo "where target is one of:"
+ @echo " gcc gccso gccdyn gccdebug gcczl gccdos gccdoszl"
+ @echo " -----------------------------------------------"
+ @echo "Or, specify a specific target for a partial build,"
+ @echo "This uses >gcc< setup (win32 statically linked binary)"
+
+# emx 0.9c, gcc, PE format, statically linked C runtime and rsxnt.dll
+gcc: all
+
+# emx 0.9c, gcc, PE format, statically linked C runtime, standalone
+gccso:
+ $(MAKE) -f win32/makefile.emx all \
+ CC="gcc -Zwin32 -Zsys -O2 -m486 -Wall" \
+ CFLAGS="-DWIN32 -DASM_CRC" \
+ AS="gcc -Zwin32" \
+ ASFLAGS="-Di386" \
+ LDFLAGS="-o ./" \
+ LDFLAGS2="-ladvapi32 -s" \
+ OUT="-o" \
+ OBJ=".o" \
+ CRC32="crc_gcc" \
+ OBJA="matchgcc.o" \
+ DEF="win32/zip.def"
+
+# emx 0.9c, gcc, PE format, dynamically linked C runtime and rsxnt.dll
+gccdyn:
+ $(MAKE) -f win32/makefile.emx all \
+ CC="gcc -Zwin32 -Zcrtdll=crtrsxnt -O2 -m486 -Wall" \
+ CFLAGS="-DWIN32 -DASM_CRC" \
+ AS="gcc -Zwin32" \
+ ASFLAGS="-Di386" \
+ LDFLAGS="-o ./" \
+ LDFLAGS2="-ladvapi32 -s" \
+ OUT="-o" \
+ OBJ=".o" \
+ CRC32="crc_gcc" \
+ OBJA="matchgcc.o" \
+ DEF="win32/zip.def"
+
+# emx 0.9c, gcc, PE format, with debug info for gdb
+gccdebug:
+ $(MAKE) -f win32/makefile.emx all \
+ CC="gcc -Zwin32 -O2 -g -Wall" \
+ CFLAGS="-DWIN32 -DASM_CRC" \
+ AS="gcc -Zwin32" \
+ ASFLAGS="-Di386" \
+ LDFLAGS="-o ./" \
+ LDFLAGS2="-ladvapi32 -Zsmall-conv" \
+ OUT="-o" \
+ OBJ=".o" \
+ CRC32="crc_gcc" \
+ OBJA="matchgcc.o" \
+ DEF="win32/zip.def"
+
+# emx 0.9c, gcc, PE format,, statically linked zlib, C runtime, and rsxnt.dll
+gcczl:
+ $(MAKE) -f win32/makefile.emx all \
+ CC="gcc -Zwin32 -O2 -m486 -Wall" \
+ CFLAGS="-DWIN32 -DUSE_ZLIB" \
+ AS="gcc -Zwin32" \
+ ASFLAGS="-Di386 -DUSE_ZLIB" \
+ LDFLAGS="-o ./" \
+ LDFLAGS2="-L. -lzlib -ladvapi32 -s" \
+ OUT="-o" \
+ OBJ=".o" \
+ CRC32="crc32" \
+ OBJA="" \
+ DEF="win32/zip.def"
+
+# emx 0.9c, gcc, a.out format, for MS-DOS
+gccdos:
+ $(MAKE) -f win32/makefile.emx all \
+ CC="gcc -O2 -m486 -Wall" \
+ CFLAGS="-DDOS -DMSDOS -DASM_CRC" \
+ AS="gcc" \
+ ASFLAGS="-Di386" \
+ LDFLAGS="-o ./" \
+ LDFLAGS2="-s -Zsmall-conv" \
+ OUT="-o" \
+ OBJ=".o" \
+ CRC32="crc_gcc" \
+ OBJA="matchgcc.o" \
+ OBJZS="msdos.o" \
+ OBJUS="msdos_.o" \
+ OSDEP_H="msdos/osdep.h" \
+ ZIPUP_H="msdos/zipup.h"
+
+# emx 0.9c, gcc, a.out format, for MS-DOS, using zlib
+gccdoszl:
+ $(MAKE) -f win32/makefile.emx all \
+ CC="gcc -O2 -m486 -Wall" \
+ CFLAGS="-DDOS -DMSDOS -DUSE_ZLIB" \
+ AS="gcc" \
+ ASFLAGS="-Di386 -DUSE_ZLIB" \
+ LDFLAGS="-o ./" \
+ LDFLAGS2="-L. -lzlib -s -Zsmall-conv" \
+ OUT="-o" \
+ OBJ=".o" \
+ CRC32="crc32" \
+ OBJA="" \
+ OBJZS="msdos.o" \
+ OBJUS="msdos_.o" \
+ OSDEP_H="msdos/osdep.h" \
+ ZIPUP_H="msdos/zipup.h"
+
+# VPATH = .;win32
+
+# variables
+
+#default settings for target dependent macros:
+
+# the "gcc" (statically linked Win32 executables) target:
+CC=gcc -Zwin32 -O2 -m486 -Wall
+CFLAGS=-DWIN32 -DASM_CRC
+AS=gcc -Zwin32
+ASFLAGS=-Di386
+LDFLAGS=-o ./
+LDFLAGS2=-ladvapi32 -s -Zsmall-conv
+OUT=-o
+OBJ=.o
+CRC32=crc_gcc
+OBJA=matchgcc.o
+OSDEP_H=win32/osdep.h
+ZIPUP_H=win32/zipup.h
+DEF=win32/zip.def
+
+DIRSEP = /
+AS_DIRSEP = /
+RM = del
+LOCAL_OPTS = $(LOCAL_ZIP)
+CCFLAGS = $(CFLAGS) $(LOCAL_OPTS)
+
+
+OBJZ1 = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \
+ $(CRC32)$(OBJ) crctab$(OBJ)
+OBJZ2 = globals$(OBJ) deflate$(OBJ) trees$(OBJ) crypt$(OBJ) \
+ ttyio$(OBJ)
+OBJZS = win32zip$(OBJ) win32$(OBJ) nt$(OBJ)
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS) $(OBJA)
+
+OBJU1 = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) globals$(OBJ)
+OBJUS = win32_$(OBJ)
+OBJU = $(OBJU1) $(OBJUS)
+
+OBJN = zipnote$(OBJ) $(OBJU)
+OBJS = zipsplit$(OBJ) $(OBJU)
+OBJC1 = zipcloak$(OBJ) crctab$(OBJ) crypt_$(OBJ) ttyio$(OBJ)
+OBJC = $(OBJC1) $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
+
+# rules
+
+.SUFFIXES: .c $(OBJ)
+
+.c$(OBJ):
+ $(CC) -c -I. $(CCFLAGS) $(OUT)$@ $<
+
+# targets
+
+all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zip$(OBJ): zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zipfile$(OBJ): zipfile.c $(ZIP_H)
+zipup$(OBJ): zipup.c $(ZIP_H) revision.h crypt.h $(ZIPUP_H)
+fileio$(OBJ): fileio.c $(ZIP_H)
+util$(OBJ): util.c $(ZIP_H)
+globals$(OBJ): globals.c $(ZIP_H)
+deflate$(OBJ): deflate.c $(ZIP_H)
+trees$(OBJ): trees.c $(ZIP_H)
+crc32$(OBJ): crc32.c $(ZIP_H)
+crctab$(OBJ): crctab.c $(ZIP_H)
+crypt$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h
+ttyio$(OBJ): ttyio.c $(ZIP_H) crypt.h ttyio.h
+
+msdos$(OBJ): msdos/msdos.c $(ZIP_H)
+ $(CC) -c -I. $(CCFLAGS) msdos$(DIRSEP)msdos.c
+
+win32zip$(OBJ): win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32zip.c
+
+win32$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32.c
+
+nt$(OBJ): win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)nt.c
+
+crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS
+ $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S
+
+matchgcc$(OBJ): match.S
+ $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S
+
+zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+zipnote$(OBJ): zipnote.c $(ZIP_H) revision.h
+zipsplit$(OBJ): zipsplit.c $(ZIP_H) revision.h
+
+zipfile_$(OBJ): zipfile.c $(ZIP_H)
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c
+
+fileio_$(OBJ): fileio.c $(ZIP_H)
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ fileio.c
+
+util_$(OBJ): util.c $(ZIP_H)
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ util.c
+
+crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crypt.c
+
+msdos_$(OBJ): msdos/msdos.c $(ZIP_H)
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ msdos$(DIRSEP)msdos.c
+
+win32_$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ win32$(DIRSEP)win32.c
+
+zip.exe: $(OBJZ)
+# for DUMB make utilities, uncomment the following commands:
+ -@$(RM) zip.rsp
+ @for %%f in ($(OBJZ1)) do echo %%f >> zip.rsp
+ @for %%f in ($(OBJZ2)) do echo %%f >> zip.rsp
+ @for %%f in ($(OBJZS) $(OBJA)) do echo %%f >> zip.rsp
+ $(CC) $(LDFLAGS)$@ @zip.rsp $(LDFLAGS2)
+ @$(RM) zip.rsp
+# smart make utilities (like well done ports of GNU Make) can use this:
+# $(CC) $(LDFLAGS)$@ $(OBJZ) $(LDFLAGS2)
+
+zipcloak.exe: $(OBJC)
+# for DUMB make utilities, uncomment the following commands:
+ -@$(RM) zipcloak.rsp
+ @for %%f in ($(OBJC1)) do echo %%f >> zipcloak.rsp
+ @for %%f in ($(OBJU1)) do echo %%f >> zipcloak.rsp
+ @for %%f in ($(OBJUS)) do echo %%f >> zipcloak.rsp
+ $(CC) $(LDFLAGS)$@ @zipcloak.rsp $(LDFLAGS2)
+ @$(RM) zipcloak.rsp
+# smart make utilities (like well done ports of GNU Make) can use this:
+# $(CC) $(LDFLAGS)$@ $(OBJC) $(LDFLAGS2)
+
+zipnote.exe: $(OBJN)
+# for DUMB make utilities, uncomment the following commands:
+ -@$(RM) zipnote.rsp
+ @for %%f in ($(OBJN)) do echo %%f >> zipnote.rsp
+ $(CC) $(LDFLAGS)$@ @zipnote.rsp $(LDFLAGS2)
+ @$(RM) zipnote.rsp
+# smart make utilities (like well done ports of GNU Make) can use this:
+# $(CC) $(LDFLAGS)$@ $(OBJN) $(LDFLAGS2)
+
+zipsplit.exe: $(OBJS)
+# for DUMB make utilities, uncomment the following commands:
+ -@$(RM) zipsplit.rsp
+ @for %%f in ($(OBJN)) do echo %%f >> zipsplit.rsp
+ $(CC) $(LDFLAGS)$@ @zipsplit.rsp $(LDFLAGS2)
+ @$(RM) zipsplit.rsp
+# smart make utilities (like well done ports of GNU Make) can use this:
+# $(CC) $(LDFLAGS)$@ $(OBJS) $(LDFLAGS2)
diff --git a/win32/makefile.gcc b/win32/makefile.gcc
new file mode 100644
index 0000000..6e924ad
--- /dev/null
+++ b/win32/makefile.gcc
@@ -0,0 +1,142 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for port of gcc producing
+# native Win32-Intel binaries. Derived from makefile.w32.
+# Currently supported implementations: Cygwin and MinGW.
+# Authors: Cosmin Truta, Christian Spieler, and possibly others.
+# Last updated: 2005-Jan-24.
+#
+# To use, do "make -f win32/makefile.gcc".
+
+# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM)
+# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added
+# to the declaration of LOC here:
+LOC = $(LOCAL_ZIP)
+
+# ------------ GNU C ------------
+CC=gcc
+ifndef USEZLIB
+CFLAGS=-O2 -Wall -DWIN32
+else
+CFLAGS=-O2 -Wall -DWIN32 -DUSE_ZLIB
+endif
+CCFLAGS=$(CFLAGS) $(LOC)
+UTILFLAGS=$(CCFLAGS) -DUTIL -o$@
+
+#AS=as
+AS=$(CC)
+ifndef USEZLIB
+ASDEFS=
+else
+ASDEFS=-DUSE_ZLIB
+endif
+ASFLAGS=-c $(ASDEFS) $(LOC)
+
+LD=$(CC)
+LDFLAGS=-o$@ -s
+ifndef USEZLIB
+LIBS=-luser32 -ladvapi32
+else
+LIBS=-L. -lz -luser32 -ladvapi32
+endif
+
+OSDEP_H = win32/osdep.h
+ZIPUP_H = win32/zipup.h
+
+# variables
+ifndef USEZLIB
+OBJA = match.o crc_i386.o
+else
+OBJA =
+endif
+#use second definition for linking against libz
+
+OBJZ1 = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \
+ crc32.o crctab.o globals.o
+OBJZ2 = deflate.o trees.o $(OBJA)
+OBJZS = win32.o win32zip.o nt.o
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS)
+
+OBJU1 = zipfile_.o fileio_.o util_.o globals.o
+OBJUS = win32_.o
+OBJU = $(OBJU1) $(OBJUS)
+
+OBJN = zipnote.o $(OBJU)
+OBJS = zipsplit.o $(OBJU)
+OBJC1 = zipcloak.o crctab.o crypt_.o ttyio.o
+OBJC = $(OBJC1) $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
+
+ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+# rules
+
+.SUFFIXES: .c .o
+
+.c.o:
+ $(CC) -c $(CCFLAGS) -I. -o$@ $<
+
+# targets
+
+zips: $(ZIPS)
+
+zip.o: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zipfile.o: zipfile.c $(ZIP_H)
+zipup.o: zipup.c $(ZIP_H) revision.h crypt.h $(ZIPUP_H)
+fileio.o: fileio.c $(ZIP_H)
+util.o: util.c $(ZIP_H)
+globals.o: globals.c $(ZIP_H)
+deflate.o: deflate.c $(ZIP_H)
+trees.o: trees.c $(ZIP_H)
+crc32.o: crc32.c $(ZIP_H)
+crctab.o: crctab.c $(ZIP_H)
+crypt.o: crypt.c $(ZIP_H) crypt.h ttyio.h
+ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h
+
+win32zip.o: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) -c $(CCFLAGS) -I. win32/win32zip.c
+
+win32.o: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(CCFLAGS) -I. win32/win32.c
+
+nt.o: win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) -c $(CCFLAGS) -I. win32/nt.c
+
+zipcloak.o: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+zipnote.o: zipnote.c $(ZIP_H) revision.h
+zipsplit.o: zipsplit.c $(ZIP_H) revision.h
+
+zipfile_.o: zipfile.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) zipfile.c
+
+fileio_.o: fileio.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) fileio.c
+
+util_.o: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) util.c
+
+crypt_.o: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(UTILFLAGS) crypt.c
+
+win32_.o: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(UTILFLAGS) -I. win32/win32.c
+
+match.o: match.S
+ $(AS) $(ASFLAGS) match.S
+
+crc_i386.o: crc_i386.S
+ $(AS) $(ASFLAGS) crc_i386.S
+
+zip.exe: $(OBJZ)
+ $(LD) $(LDFLAGS) $(OBJZ) $(LIBS)
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) $(OBJC) $(LIBS)
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) $(OBJN)
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS)
+
+clean:
+ rm -f *.o $(ZIPS)
diff --git a/win32/makefile.ibm b/win32/makefile.ibm
new file mode 100644
index 0000000..74acfd9
--- /dev/null
+++ b/win32/makefile.ibm
@@ -0,0 +1,123 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# 32-bit IBM Visual Age C++
+
+# To use, do "nmake -f win32\makefile.ibm"
+
+# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM)
+# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added
+# to the declaration of LOC here:
+LOC = $(LOCAL_ZIP)
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+# ASMOBJS = match32.obj
+
+# ------------- 32-bit IBM Visual Age C++ -------------
+CC=icc -q -O
+CFLAGS=-W0 -DWIN32 -Sm -DNO_ASM -DNO_MKTEMP $(LOC)
+UTILFLAGS=$(CFLAGS) -DUTIL -Fo$@
+LDFLAGS=
+LIBS=advapi32.lib
+AS=ml -nologo
+ASFLAGS=-c -Cx
+
+# variables
+OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj crctab.obj globals.obj
+
+OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj
+
+OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj win32_.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.obj crctab.obj crypt_.obj ttyio.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
+
+ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zips: $(ZIPS)
+
+zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+util.obj: util.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+globals.obj: globals.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crctab.obj: crctab.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+win32zip.obj: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) -c $(CFLAGS) -I. win32/win32zip.c
+
+win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(CFLAGS) -I. win32/win32.c
+
+nt.obj: win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) -c $(CFLAGS) -I. win32/nt.c
+
+zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipnote.obj: zipnote.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile_.obj: zipfile.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) util.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(UTILFLAGS) crypt.c
+
+win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(UTILFLAGS) -I. win32/win32.c
+
+match32.obj: win32/match32.asm
+ $(AS) $(ASFLAGS) win32\match32.asm
+
+zip.exe: $(OBJZ) $(OBJI)
+ $(CC) -Fe $@ $(LDFLAGS) $(OBJZ) $(OBJI) $(LIBS)
+
+zipcloak.exe: $(OBJC)
+ $(CC) -Fe $@ $(LDFLAGS) $(OBJC) $(LIBS)
+
+zipnote.exe: $(OBJN)
+ $(CC) -Fe $@ $(LDFLAGS) $(OBJN) $(LIBS)
+
+zipsplit.exe: $(OBJS)
+ $(CC) -Fe $@ $(LDFLAGS) $(OBJS) $(LIBS)
diff --git a/win32/makefile.lcc b/win32/makefile.lcc
new file mode 100644
index 0000000..b40e77c
--- /dev/null
+++ b/win32/makefile.lcc
@@ -0,0 +1,123 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit using LCC-Win32.
+# By E-Yen Tan (3 June 1998).
+# Last updated 21 December 1998 (Christian Spieler).
+
+# This compiler evaluates #include locations relative to current working dir,
+# not relative to the location of the file containing the #include directive.
+# As a consequence, a "-Iwin32" option is required to allow compilation of
+# the WIN32 specific sources.
+
+CC = lcc
+# -O caused a segmentation violation with previous versions of lcc, but
+# now the optimizer seems to be fixed.
+CCFLAGS = -zp8 -O -DWIN32
+AS = lcc
+ASFLAGS =
+LD = lcclnk
+LDFLAGS = -s
+
+# Optional macros should be declared below.
+# LCC's Make will not read the LOCAL_ZIP environment variable.
+LOC = $(ASMFLG)
+
+# Options to select optimized assembler code for CRC32 calculation.
+#ifdef USEASM
+CRC32 = crc_lcc
+OBJA = lm32_lcc.obj
+ASMFLG = -DASM_CRC -DASMV
+#else
+#CRC32 = crc32
+#OBJA =
+#ASMFLG = -DNO_ASM
+#endif
+
+CFLAGS = $(CCFLAGS) $(LOC)
+
+OBJZS = win32.obj win32zip.obj nt.obj $(OBJA)
+OBJUS = win32_.obj
+
+OBJZ1 = zip.obj zipfile.obj zipup.obj fileio.obj util.obj
+OBJZ2 = $(CRC32).obj crctab.obj globals.obj
+OBJZ3 = deflate.obj trees.obj crypt.obj ttyio.obj
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZ3) $(OBJZS)
+
+OBJU1 = zipfile_.obj fileio_.obj util_.obj globals.obj
+OBJU = $(OBJU1) $(OBJUS)
+
+OBJN = zipnote.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+OBJK = zipcloak.obj crctab.obj crypt_.obj ttyio.obj
+OBJC = $(OBJK) $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
+
+# rules
+
+.SUFFIXES: .c .obj
+
+.c.obj:
+ $(CC) $(CFLAGS) $<
+
+.asm.obj:
+ $(AS) $(ASFLAGS) $<
+
+all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zipfile.obj: zipfile.c $(ZIP_H)
+zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
+fileio.obj: fileio.c $(ZIP_H)
+util.obj: util.c $(ZIP_H)
+globals.obj: globals.c $(ZIP_H)
+deflate.obj: deflate.c $(ZIP_H)
+trees.obj: trees.c $(ZIP_H)
+crc32.obj: crc32.c $(ZIP_H)
+crctab.obj: crctab.c $(ZIP_H)
+crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+
+win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) $(CFLAGS) -Iwin32 -Fo$@ win32/win32.c
+
+win32zip.obj: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) $(CFLAGS) -Iwin32 -Fo$@ win32/win32zip.c
+
+nt.obj: win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) $(CFLAGS) -Iwin32 -Fo$@ win32/nt.c
+
+crc_lcc.obj: win32/crc_lcc.asm
+ $(AS) $(ASFLAGS) -Fo$@ win32/crc_lcc.asm
+
+lm32_lcc.obj: win32/lm32_lcc.asm
+ $(AS) $(ASFLAGS) -Fo$@ win32/lm32_lcc.asm
+
+zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+zipnote.obj: zipnote.c $(ZIP_H) revision.h
+zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+
+zipfile_.obj: zipfile.c $(ZIP_H)
+ $(CC) $(CFLAGS) -DUTIL -Fo$@ zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H)
+ $(CC) $(CFLAGS) -DUTIL -Fo$@ fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) $(CFLAGS) -DUTIL -Fo$@ util.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) $(CFLAGS) -DUTIL -Fo$@ crypt.c
+
+win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) $(CFLAGS) -DUTIL -Iwin32 -Fo$@ win32/win32.c
+
+zip.exe: $(OBJZ)
+ $(LD) $(LDFLAGS) -o $@ $(OBJZ)
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) -o $@ $(OBJC)
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) -o $@ $(OBJN)
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) -o $@ $(OBJS)
diff --git a/win32/makefile.w10 b/win32/makefile.w10
new file mode 100644
index 0000000..b5244fc
--- /dev/null
+++ b/win32/makefile.w10
@@ -0,0 +1,181 @@
+# WMAKE makefile for Windows 95 and Windows NT (Intel only)
+# using Watcom C/C++ v10.5+, by Paul Kienitz, last revised 22 Feb 05.
+# Makes Zip.exe, ZipNote.exe, ZipCloak.exe, and ZipSplit.exe.
+#
+# Invoke from Zip source dir with "WMAKE -F WIN32\MAKEFILE.WAT [targets]"
+# To build with debug info use "WMAKE DEBUG=1 ..."
+# To build without any assembly modules use "WMAKE NOASM=1 ..."
+#
+# Other options to be fed to the compiler can be specified in an environment
+# variable called LOCAL_ZIP. One possibility "-DDYN_ALLOC", but currently
+# this is not supported unless NOASM is also used.
+
+variation = $(%LOCAL_ZIP)
+
+# Stifle annoying "Delete this file?" questions when errors occur:
+.ERASE
+
+.EXTENSIONS:
+.EXTENSIONS: .exe .obj .c .h .asm
+
+# We maintain multiple sets of object files in different directories so that
+# we can compile msdos, dos/4gw, and win32 versions of Zip without their
+# object files interacting. The following var must be a directory name
+# ending with a backslash. All object file names must include this macro
+# at the beginning, for example "$(O)foo.obj".
+
+!ifdef DEBUG
+OBDIR = od32w
+!else
+OBDIR = ob32w
+!endif
+O = $(OBDIR)\ # comment here so backslash won't continue the line
+
+# The assembly hot-spot code in crc_i386.asm and match32.asm is optional.
+# This section controls its usage.
+
+!ifdef NOASM
+asmob = $(O)crc32.obj # C source
+cvars = $+$(cvars)$- -DNO_ASM # otherwise ASM_CRC might default on!
+# "$+$(foo)$-" means expand foo as it has been defined up to now; normally,
+# this make defers inner expansion until the outer macro is expanded.
+!else # !NOASM
+asmob = $(O)match32.obj $(O)crc_i386.obj
+cvars = $+$(cvars)$- -DASMV -DASM_CRC
+!endif
+
+# Our object files. OBJZ is for Zip, OBJC is for ZipCloak, OBJN is for
+# ZipNote, and OBJS is for ZipSplit:
+
+OBJZ3 = $(O)zip.obj $(O)crypt.obj $(O)ttyio.obj $(O)trees.obj $(O)zipup.obj
+OBJZ2 = $(OBJZ3) $(O)util.obj $(O)zipfile.obj $(O)fileio.obj $(O)deflate.obj
+OBJZ1 = $(OBJZ2) $(O)globals.obj $(O)crctab.obj $(asmob)
+OBJZ = $(OBJZ1) $(O)win32zip.obj $(O)win32.obj $(O)nt.obj
+
+OBJU1 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)globals.obj
+OBJ_U = $(OBJU1) $(O)win32_.obj
+
+OBJC = $(O)zipcloak.obj $(O)crctab.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U)
+
+OBJN = $(O)zipnote.obj $(OBJ_U)
+
+OBJS = $(O)zipsplit.obj $(OBJ_U)
+
+# Common header files included by all C sources:
+
+ZIP_H = zip.h ziperr.h tailor.h win32\osdep.h
+
+# Now we have to pick out the proper compiler and options for it.
+
+cc = wcc386
+link = wlink
+asm = wasm
+# Use Pentium timings, register args, static strings in code:
+cflags = -bt=NT -5r -zt -zq
+aflags = -bt=NT -mf -3 -zq
+lflags = sys NT
+cvars = $+$(cvars)$- -DWIN32 $(variation)
+avars = $+$(avars)$- $(variation)
+
+# Specify optimizations, or a nonoptimized debugging version:
+
+!ifdef DEBUG
+cdebug = -od -d2
+ldebug = d w all op symf
+!else
+cdebug = -s -oeilrt -zp4
+# note: -ol+ does not help. -oa helps slightly but might be dangerous.
+ldebug = op el
+!endif
+
+# How to compile sources:
+.c.obj:
+ $(cc) $(cdebug) $(cflags) $(cvars) $< -fo=$@
+
+# Here we go! By default, make all targets:
+all: Zip.exe ZipNote.exe ZipCloak.exe ZipSplit.exe
+
+# Convenient shorthand options for single targets:
+z: Zip.exe .SYMBOLIC
+n: ZipNote.exe .SYMBOLIC
+c: ZipCloak.exe .SYMBOLIC
+s: ZipSplit.exe .SYMBOLIC
+
+Zip.exe: $(OBDIR) $(OBJZ)
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJZ)}
+
+ZipNote.exe: $(OBDIR) $(OBJN)
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJN)}
+
+ZipCloak.exe: $(OBDIR) $(OBJC)
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJC)}
+
+ZipSplit.exe: $(OBDIR) $(OBJS)
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJS)}
+
+# Source dependencies:
+
+$(O)crctab.obj: crctab.c $(ZIP_H)
+$(O)crc32.obj: crc32.c $(ZIP_H) # only used if NOASM
+$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+$(O)deflate.obj: deflate.c $(ZIP_H)
+$(O)fileio.obj: fileio.c $(ZIP_H)
+$(O)globals.obj: globals.c $(ZIP_H)
+$(O)trees.obj: trees.c $(ZIP_H)
+$(O)ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+$(O)util.obj: util.c $(ZIP_H)
+$(O)zip.obj: zip.c $(ZIP_H) crypt.h revision.h ttyio.h
+$(O)zipfile.obj: zipfile.c $(ZIP_H)
+$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32\zipup.h
+$(O)zipnote.obj: zipnote.c $(ZIP_H) revision.h
+$(O)zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+$(O)zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+
+# Special case object files:
+
+$(O)win32.obj: win32\win32.c $(ZIP_H) win32\win32zip.h
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\win32.c -fo=$@
+
+$(O)win32zip.obj: win32\win32zip.c $(ZIP_H) win32\win32zip.h win32\nt.h
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\win32zip.c -fo=$@
+
+$(O)nt.obj: win32\nt.c $(ZIP_H) win32\nt.h
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\nt.c -fo=$@
+
+$(O)match32.obj: win32\match32.asm
+ $(asm) $(aflags) $(avars) win32\match32.asm -fo=$@
+
+$(O)crc_i386.obj: win32\crc_i386.asm
+ $(asm) $(aflags) $(avars) win32\crc_i386.asm -fo=$@
+
+# Variant object files for ZipNote, ZipCloak, and ZipSplit:
+
+$(O)zipfile_.obj: zipfile.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@
+
+$(O)fileio_.obj: fileio.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL fileio.c -fo=$@
+
+$(O)util_.obj: util.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL util.c -fo=$@
+
+$(O)crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crypt.c -fo=$@
+
+$(O)win32_.obj: win32\win32.c $(ZIP_H) win32\win32zip.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL win32\win32.c -fo=$@
+
+# Creation of subdirectory for intermediate files
+$(OBDIR):
+ -mkdir $@
+
+# Unwanted file removal:
+
+clean: .SYMBOLIC
+ del $(O)*.obj
+
+cleaner: clean .SYMBOLIC
+ del Zip.exe
+ del ZipNote.exe
+ del ZipCloak.exe
+ del ZipSplit.exe
diff --git a/win32/makefile.w32 b/win32/makefile.w32
new file mode 100644
index 0000000..538a614
--- /dev/null
+++ b/win32/makefile.w32
@@ -0,0 +1,147 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# 32-bit Microsoft Visual C++
+
+# To use, do "nmake -f makefile.w32"
+
+# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if
+# you do not have masm 6.1X.
+
+# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM)
+# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added
+# to the declaration of LOC here:
+LOC = $(LOCAL_ZIP)
+
+# To avoid using the optimized assembler routines in Zip, comment
+# out the ASMOBJS macro below, and add -DNO_ASM to LOC above.
+ASMOBJS = match32.obj crc_i386.obj
+
+# ------------- 32-bit Microsoft Visual C++ -------------
+CC=cl -nologo
+CFLAGS=-W3 -O2 -DWIN32 $(LOC)
+UTILFLAGS=$(CFLAGS) -DUTIL -Fo$@
+
+# Remove "-coff" from ASFLAGS if you do not have MASM 6.11.
+
+AS=ml -nologo
+ASFLAGS=-c -coff -Cx
+
+# If you build 16-bit executables with MS Visual C++ v1.0/1.5 and link them
+# with the /KNOWEAS switch, you can build dual-mode MS-DOS/Win32 executables
+# by passing the -stub switch to the 32-bit linker to specify the 16-bit part.
+
+LD=link -nologo
+#LDFLAGS=-stub:zipdos.exe
+LDFLAGS=
+
+# variables
+OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj crctab.obj globals.obj
+
+OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj
+
+OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj win32_.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.obj crctab.obj crypt_.obj ttyio.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
+
+LIBS = advapi32.lib
+
+ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zips: $(ZIPS)
+
+zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+util.obj: util.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+globals.obj: globals.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crctab.obj: crctab.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+win32zip.obj: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) -c $(CFLAGS) -I. win32/win32zip.c
+
+win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(CFLAGS) -I. win32/win32.c
+
+nt.obj: win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) -c $(CFLAGS) -I. win32/nt.c
+
+zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipnote.obj: zipnote.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile_.obj: zipfile.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) util.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(UTILFLAGS) crypt.c
+
+win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(UTILFLAGS) -I. win32/win32.c
+
+crci386c.obj: win32/crc_i386.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) -I. -Fo$@ win32/crc_i386.c
+
+crc_i386.obj: win32/crc_i386.c $(ZIP_H)
+ $(AS) $(ASFLAGS) win32\crc_i386.asm
+
+match32.obj: win32/match32.asm
+ $(AS) $(ASFLAGS) win32\match32.asm
+
+zip.exe: $(OBJZ) $(OBJI)
+ $(LD) $(LDFLAGS) $(OBJZ) $(OBJI) $(LIBS)
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) $(OBJC) $(LIBS)
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) $(OBJN) $(LIBS)
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS) $(LIBS)
+
+clean:
+ del *.obj
+ del *.exe
diff --git a/win32/makefile.wat b/win32/makefile.wat
new file mode 100644
index 0000000..93b41e0
--- /dev/null
+++ b/win32/makefile.wat
@@ -0,0 +1,181 @@
+# WMAKE makefile for Windows 95 and Windows NT (Intel only)
+# using Watcom C/C++ v11.0+, by Paul Kienitz, last revised 22 Feb 05.
+# Makes Zip.exe, ZipNote.exe, ZipCloak.exe, and ZipSplit.exe.
+#
+# Invoke from Zip source dir with "WMAKE -F WIN32\MAKEFILE.WAT [targets]"
+# To build with debug info use "WMAKE DEBUG=1 ..."
+# To build without any assembly modules use "WMAKE NOASM=1 ..."
+#
+# Other options to be fed to the compiler can be specified in an environment
+# variable called LOCAL_ZIP. One possibility "-DDYN_ALLOC", but currently
+# this is not supported unless NOASM is also used.
+
+variation = $(%LOCAL_ZIP)
+
+# Stifle annoying "Delete this file?" questions when errors occur:
+.ERASE
+
+.EXTENSIONS:
+.EXTENSIONS: .exe .obj .c .h .asm
+
+# We maintain multiple sets of object files in different directories so that
+# we can compile msdos, dos/4gw, and win32 versions of Zip without their
+# object files interacting. The following var must be a directory name
+# ending with a backslash. All object file names must include this macro
+# at the beginning, for example "$(O)foo.obj".
+
+!ifdef DEBUG
+OBDIR = od32w
+!else
+OBDIR = ob32w
+!endif
+O = $(OBDIR)\ # comment here so backslash won't continue the line
+
+# The assembly hot-spot code in crc_i386.asm and match32.asm is optional.
+# This section controls its usage.
+
+!ifdef NOASM
+asmob = $(O)crc32.obj # C source
+cvars = $+$(cvars)$- -DNO_ASM # otherwise ASM_CRC might default on!
+# "$+$(foo)$-" means expand foo as it has been defined up to now; normally,
+# this make defers inner expansion until the outer macro is expanded.
+!else # !NOASM
+asmob = $(O)match32.obj $(O)crc_i386.obj
+cvars = $+$(cvars)$- -DASMV -DASM_CRC
+!endif
+
+# Our object files. OBJZ is for Zip, OBJC is for ZipCloak, OBJN is for
+# ZipNote, and OBJS is for ZipSplit:
+
+OBJZ3 = $(O)zip.obj $(O)crypt.obj $(O)ttyio.obj $(O)trees.obj $(O)zipup.obj
+OBJZ2 = $(OBJZ3) $(O)util.obj $(O)zipfile.obj $(O)fileio.obj $(O)deflate.obj
+OBJZ1 = $(OBJZ2) $(O)globals.obj $(O)crctab.obj $(asmob)
+OBJZ = $(OBJZ1) $(O)win32zip.obj $(O)win32.obj $(O)nt.obj
+
+OBJU1 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)globals.obj
+OBJ_U = $(OBJU1) $(O)win32_.obj
+
+OBJC = $(O)zipcloak.obj $(O)crctab.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U)
+
+OBJN = $(O)zipnote.obj $(OBJ_U)
+
+OBJS = $(O)zipsplit.obj $(OBJ_U)
+
+# Common header files included by all C sources:
+
+ZIP_H = zip.h ziperr.h tailor.h win32\osdep.h
+
+# Now we have to pick out the proper compiler and options for it.
+
+cc = wcc386
+link = wlink
+asm = wasm
+# Use Pentium Pro timings, register args, static strings in code:
+cflags = -bt=NT -6r -zt -zq
+aflags = -bt=NT -mf -3 -zq
+lflags = sys NT
+cvars = $+$(cvars)$- -DWIN32 $(variation)
+avars = $+$(avars)$- $(variation)
+
+# Specify optimizations, or a nonoptimized debugging version:
+
+!ifdef DEBUG
+cdebug = -od -d2
+ldebug = d w all op symf
+!else
+cdebug = -s -obhikl+rt -oe=100 -zp8
+# -oa helps slightly but might be dangerous.
+ldebug = op el
+!endif
+
+# How to compile sources:
+.c.obj:
+ $(cc) $(cdebug) $(cflags) $(cvars) $[@ -fo=$@
+
+# Here we go! By default, make all targets:
+all: Zip.exe ZipNote.exe ZipCloak.exe ZipSplit.exe
+
+# Convenient shorthand options for single targets:
+z: Zip.exe .SYMBOLIC
+n: ZipNote.exe .SYMBOLIC
+c: ZipCloak.exe .SYMBOLIC
+s: ZipSplit.exe .SYMBOLIC
+
+Zip.exe: $(OBDIR) $(OBJZ)
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJZ)}
+
+ZipNote.exe: $(OBDIR) $(OBJN)
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJN)}
+
+ZipCloak.exe: $(OBDIR) $(OBJC)
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJC)}
+
+ZipSplit.exe: $(OBDIR) $(OBJS)
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJS)}
+
+# Source dependencies:
+
+$(O)crctab.obj: crctab.c $(ZIP_H)
+$(O)crc32.obj: crc32.c $(ZIP_H) # only used if NOASM
+$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+$(O)deflate.obj: deflate.c $(ZIP_H)
+$(O)fileio.obj: fileio.c $(ZIP_H)
+$(O)globals.obj: globals.c $(ZIP_H)
+$(O)trees.obj: trees.c $(ZIP_H)
+$(O)ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+$(O)util.obj: util.c $(ZIP_H)
+$(O)zip.obj: zip.c $(ZIP_H) crypt.h revision.h ttyio.h
+$(O)zipfile.obj: zipfile.c $(ZIP_H)
+$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32\zipup.h
+$(O)zipnote.obj: zipnote.c $(ZIP_H) revision.h
+$(O)zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+$(O)zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+
+# Special case object files:
+
+$(O)win32.obj: win32\win32.c $(ZIP_H) win32\win32zip.h
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\win32.c -fo=$@
+
+$(O)win32zip.obj: win32\win32zip.c $(ZIP_H) win32\win32zip.h win32\nt.h
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\win32zip.c -fo=$@
+
+$(O)nt.obj: win32\nt.c $(ZIP_H) win32\nt.h
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\nt.c -fo=$@
+
+$(O)match32.obj: win32\match32.asm
+ $(asm) $(aflags) $(avars) win32\match32.asm -fo=$@
+
+$(O)crc_i386.obj: win32\crc_i386.asm
+ $(asm) $(aflags) $(avars) win32\crc_i386.asm -fo=$@
+
+# Variant object files for ZipNote, ZipCloak, and ZipSplit:
+
+$(O)zipfile_.obj: zipfile.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@
+
+$(O)fileio_.obj: fileio.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL fileio.c -fo=$@
+
+$(O)util_.obj: util.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL util.c -fo=$@
+
+$(O)crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crypt.c -fo=$@
+
+$(O)win32_.obj: win32\win32.c $(ZIP_H) win32\win32zip.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL win32\win32.c -fo=$@
+
+# Creation of subdirectory for intermediate files
+$(OBDIR):
+ -mkdir $@
+
+# Unwanted file removal:
+
+clean: .SYMBOLIC
+ del $(O)*.obj
+
+cleaner: clean .SYMBOLIC
+ del Zip.exe
+ del ZipNote.exe
+ del ZipCloak.exe
+ del ZipSplit.exe
diff --git a/win32/match32.asm b/win32/match32.asm
new file mode 100644
index 0000000..5d4e8b5
--- /dev/null
+++ b/win32/match32.asm
@@ -0,0 +1,184 @@
+;===========================================================================
+; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2004-May-22 or later
+; (the contents of which are also included in zip.h) for terms of use.
+; If, for some reason, both of these files are missing, the Info-ZIP license
+; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+;===========================================================================
+;
+; match32.asm by Jean-loup Gailly.
+
+; match32.asm, optimized version of longest_match() in deflate.c
+; To be used only with 32 bit flat model. To simplify the code, the option
+; -DDYN_ALLOC is not supported.
+; This file is only optional. If you don't have an assembler, use the
+; C version (add -DNO_ASM to CFLAGS in makefile and remove match.o
+; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is
+; assembled with an equivalent -DWSIZE=<whatever>.
+;
+; Win32 (Windows NT) version - 1994/04/13 by Steve Salisbury
+; * works with Microsoft MASM 6.1X and Microsoft Visual C++ / 32-bit edition
+;
+; Adapted to work with Borland Turbo Assembler 5.0 by Cosmin Truta, 1997
+;
+;==============================================================================
+;
+; Do NOT assemble this source if external crc32 routine from zlib gets used.
+;
+ IFNDEF USE_ZLIB
+;
+ .386p
+ ifdef ASM_NEW
+ .MODEL FLAT
+ endif
+
+ name match
+
+ ifdef ASM_NEW
+_BSS segment public use32
+ else
+_BSS segment public use32 'DATA'
+ endif
+ extrn _match_start : dword
+ extrn _prev_length : dword
+ extrn _good_match : dword
+ ifndef FULL_SEARCH
+ extrn _nice_match : dword
+ endif
+ extrn _strstart : dword
+ extrn _max_chain_length : dword
+ extrn _prev : word
+ extrn _window : byte
+_BSS ends
+
+ ifdef ASM_NEW
+_TEXT segment public use32
+ else
+_TEXT segment para public use32 'CODE'
+ endif
+ assume CS: _TEXT
+ assume DS: _BSS, ES: _BSS, FS: _BSS
+ public _match_init
+ public _longest_match
+
+ ifndef WSIZE
+ WSIZE equ 32768 ; keep in sync with zip.h !
+ endif
+ MIN_MATCH equ 3
+ MAX_MATCH equ 258
+ MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
+ MAX_DIST equ (WSIZE-MIN_LOOKAHEAD)
+
+; initialize or check the variables used in match.asm.
+
+_match_init proc near
+ ret
+_match_init endp
+
+; -----------------------------------------------------------------------
+; Set match_start to the longest match starting at the given string and
+; return its length. Matches shorter or equal to prev_length are discarded,
+; in which case the result is equal to prev_length and match_start is
+; garbage.
+; IN assertions: cur_match is the head of the hash chain for the current
+; string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+
+; int longest_match(cur_match)
+
+_longest_match proc near
+
+ cur_match equ dword ptr [esp+20]
+ ; return address ; esp+16
+ push ebp ; esp+12
+ push edi ; esp+8
+ push esi ; esp+4
+ push ebx ; esp
+
+; match equ esi
+; scan equ edi
+; chain_length equ ebp
+; best_len equ ebx
+; limit equ edx
+
+ mov esi,cur_match
+ mov edx,_strstart
+ mov ebp,_max_chain_length ; chain_length = max_chain_length
+ mov edi,edx
+ sub edx,MAX_DIST ; limit = strstart-MAX_DIST
+ cld ; string ops increment esi and edi
+ jae short limit_ok
+ sub edx,edx ; limit = NIL
+limit_ok:
+ add edi,2+offset _window ; edi = offset(window + strstart + 2)
+ mov ebx,_prev_length ; best_len = prev_length
+ mov cx,[edi-2] ; cx = scan[0..1]
+ mov ax,[ebx+edi-3] ; ax = scan[best_len-1..best_len]
+ cmp ebx,_good_match ; do we have a good match already?
+ jb short do_scan
+ shr ebp,2 ; chain_length >>= 2
+ jmp short do_scan
+
+ align 4 ; align destination of branch
+long_loop:
+; at this point, edi == scan+2, esi == cur_match
+ mov ax,[ebx+edi-3] ; ax = scan[best_len-1..best_len]
+ mov cx,[edi-2] ; cx = scan[0..1]
+short_loop:
+; at this point, edi == scan+2, esi == cur_match,
+; ax = scan[best_len-1..best_len] and cx = scan[0..1]
+ and esi,WSIZE-1
+ dec ebp ; --chain_length
+ mov si,_prev[esi+esi] ; cur_match = prev[cur_match]
+ ; top word of esi is still 0
+ jz short the_end
+ cmp esi,edx ; cur_match <= limit ?
+ jbe short the_end
+do_scan:
+ cmp ax,word ptr _window[ebx+esi-1] ; check match at best_len-1
+ jne short_loop
+ cmp cx,word ptr _window[esi] ; check min_match_length match
+ jne short_loop
+
+ lea esi,_window[esi+2] ; esi = match
+ mov ecx,(MAX_MATCH-2)/2 ; scan for at most MAX_MATCH bytes
+ mov eax,edi ; eax = scan+2
+ repe cmpsw ; loop until mismatch
+ je short maxmatch ; match of length MAX_MATCH?
+mismatch:
+ mov cl,[edi-2] ; mismatch on first or second byte?
+ xchg eax,edi ; edi = scan+2, eax = end of scan
+ sub cl,[esi-2] ; cl = 0 if first bytes equal
+ sub eax,edi ; eax = len
+ sub esi,2+offset _window ; esi = match - (2 + offset(window))
+ sub esi,eax ; esi = cur_match (= match - len)
+ sub cl,1 ; set carry if cl == 0 (can't use DEC)
+ adc eax,0 ; eax = carry ? len+1 : len
+ cmp eax,ebx ; len > best_len ?
+ jle long_loop
+ mov _match_start,esi ; match_start = cur_match
+ mov ebx,eax ; ebx = best_len = len
+ ifdef FULL_SEARCH
+ cmp eax,MAX_MATCH ; len >= MAX_MATCH ?
+ else
+ cmp eax,_nice_match ; len >= nice_match ?
+ endif
+ jl long_loop
+the_end:
+ mov eax,ebx ; result = eax = best_len
+ pop ebx
+ pop esi
+ pop edi
+ pop ebp
+ ret
+maxmatch: ; come here if maximum match
+ cmpsb ; increment esi and edi
+ jmp mismatch ; force match_length = MAX_LENGTH
+
+_longest_match endp
+
+_TEXT ends
+;
+ ENDIF ; !USE_ZLIB
+;
+end
diff --git a/win32/nt.c b/win32/nt.c
new file mode 100644
index 0000000..6a757b8
--- /dev/null
+++ b/win32/nt.c
@@ -0,0 +1,482 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*++
+
+Copyright (c) 1996 Scott Field
+
+Module Name:
+
+ nt.c (formerly nt_zip.c)
+
+Abstract:
+
+ This module implements WinNT security descriptor operations for the
+ Win32 Info-ZIP project. Operation such as querying file security,
+ using/querying local and remote privileges. The contents of this module
+ are only relevant when the code is running on Windows NT, and the target
+ volume supports persistent Acl storage.
+
+ User privileges that allow accessing certain privileged aspects of the
+ security descriptor (such as the Sacl) are only used if the user specified
+ to do so.
+
+ In the future, this module may be expanded to support storage of
+ OS/2 EA data, Macintosh resource forks, and hard links, which are all
+ supported by NTFS.
+
+Author:
+
+ Scott Field (sfield@microsoft.com) 27-Sep-96
+
+--*/
+
+#include "../zip.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#ifdef __RSXNT__
+# include "../win32/rsxntwin.h"
+#endif
+#include "../win32/nt.h"
+
+#ifdef NTSD_EAS /* This file is only needed for NTSD handling */
+
+/* Borland C++ does not define FILE_SHARE_DELETE. Others also? */
+#ifndef FILE_SHARE_DELETE
+# define FILE_SHARE_DELETE 0x00000004
+#endif
+
+/* private prototypes */
+
+static BOOL Initialize(VOID);
+#if 0 /* currently unused */
+static BOOL Shutdown(VOID);
+#endif
+static VOID GetRemotePrivilegesGet(CHAR *FileName, PDWORD dwRemotePrivileges);
+static VOID InitLocalPrivileges(VOID);
+
+
+BOOL bZipInitialized = FALSE; /* module level stuff initialized? */
+HANDLE hZipInitMutex = NULL; /* prevent multiple initialization */
+
+BOOL g_bBackupPrivilege = FALSE; /* for local get file security override */
+BOOL g_bZipSaclPrivilege = FALSE; /* for local get sacl operations, only when
+ backup privilege not present */
+
+/* our single cached volume capabilities structure that describes the last
+ volume root we encountered. A single entry like this works well in the
+ zip/unzip scenario for a number of reasons:
+ 1. typically one extraction path during unzip.
+ 2. typically process one volume at a time during zip, and then move
+ on to the next.
+ 3. no cleanup code required and no memory leaks.
+ 4. simple code.
+
+ This approach should be reworked to a linked list approach if we expect to
+ be called by many threads which are processing a variety of input/output
+ volumes, since lock contention and stale data may become a bottleneck. */
+
+VOLUMECAPS g_VolumeCaps;
+CRITICAL_SECTION VolumeCapsLock;
+
+
+static BOOL Initialize(VOID)
+{
+ HANDLE hMutex;
+ HANDLE hOldMutex;
+
+ if(bZipInitialized) return TRUE;
+
+ hMutex = CreateMutex(NULL, TRUE, NULL);
+ if(hMutex == NULL) return FALSE;
+
+ hOldMutex = (HANDLE)InterlockedExchange((LPLONG)&hZipInitMutex, (LONG)hMutex);
+
+ if(hOldMutex != NULL) {
+ /* somebody setup the mutex already */
+ InterlockedExchange((LPLONG)&hZipInitMutex, (LONG)hOldMutex);
+
+ CloseHandle(hMutex); /* close new, un-needed mutex */
+
+ /* wait for initialization to complete and return status */
+ WaitForSingleObject(hOldMutex, INFINITE);
+ ReleaseMutex(hOldMutex);
+
+ return bZipInitialized;
+ }
+
+ /* initialize module level resources */
+
+ InitializeCriticalSection( &VolumeCapsLock );
+ memset(&g_VolumeCaps, 0, sizeof(VOLUMECAPS));
+
+ InitLocalPrivileges();
+
+ bZipInitialized = TRUE;
+
+ ReleaseMutex(hMutex); /* release correct mutex */
+
+ return TRUE;
+}
+
+#if 0 /* currently not used ! */
+static BOOL Shutdown(VOID)
+{
+ /* really need to free critical sections, disable enabled privilges, etc,
+ but doing so brings up possibility of race conditions if those resources
+ are about to be used. The easiest way to handle this is let these
+ resources be freed when the process terminates... */
+
+ return TRUE;
+}
+#endif /* never */
+
+
+static VOID GetRemotePrivilegesGet(char *FileName, PDWORD dwRemotePrivileges)
+{
+ HANDLE hFile;
+
+ *dwRemotePrivileges = 0;
+
+ /* see if we have the SeBackupPrivilege */
+
+ hFile = CreateFileA(
+ FileName,
+ ACCESS_SYSTEM_SECURITY | GENERIC_READ | READ_CONTROL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+
+ if(hFile != INVALID_HANDLE_VALUE) {
+ /* no remote way to determine SeBackupPrivilege -- just try a read
+ to simulate it */
+ SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
+ PSECURITY_DESCRIPTOR sd;
+ DWORD cbBuf = 0;
+
+ GetKernelObjectSecurity(hFile, si, NULL, cbBuf, &cbBuf);
+
+ if(ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
+ if((sd = HeapAlloc(GetProcessHeap(), 0, cbBuf)) != NULL) {
+ if(GetKernelObjectSecurity(hFile, si, sd, cbBuf, &cbBuf)) {
+ *dwRemotePrivileges |= OVERRIDE_BACKUP;
+ }
+ HeapFree(GetProcessHeap(), 0, sd);
+ }
+ }
+
+ CloseHandle(hFile);
+ } else {
+
+ /* see if we have the SeSecurityPrivilege */
+ /* note we don't need this if we have SeBackupPrivilege */
+
+ hFile = CreateFileA(
+ FileName,
+ ACCESS_SYSTEM_SECURITY,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* maximum sharing */
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL
+ );
+
+ if(hFile != INVALID_HANDLE_VALUE) {
+ CloseHandle(hFile);
+ *dwRemotePrivileges |= OVERRIDE_SACL;
+ }
+ }
+}
+
+
+BOOL ZipGetVolumeCaps(
+ char *rootpath, /* filepath, or NULL */
+ char *name, /* filename associated with rootpath */
+ PVOLUMECAPS VolumeCaps /* result structure describing capabilities */
+ )
+{
+ char TempRootPath[MAX_PATH + 1];
+ DWORD cchTempRootPath = 0;
+ BOOL bSuccess = TRUE; /* assume success until told otherwise */
+
+ if(!bZipInitialized) if(!Initialize()) return FALSE;
+
+ /* process the input path to produce a consistent path suitable for
+ compare operations and also suitable for certain picky Win32 API
+ that don't like forward slashes */
+
+ if(rootpath != NULL && rootpath[0] != '\0') {
+ DWORD i;
+
+ cchTempRootPath = lstrlen(rootpath);
+ if(cchTempRootPath > MAX_PATH) return FALSE;
+
+ /* copy input, converting forward slashes to back slashes as we go */
+
+ for(i = 0 ; i <= cchTempRootPath ; i++) {
+ if(rootpath[i] == '/') TempRootPath[i] = '\\';
+ else TempRootPath[i] = rootpath[i];
+ }
+
+ /* check for UNC and Null terminate or append trailing \ as appropriate */
+
+ /* possible valid UNCs we are passed follow:
+ \\machine\foo\bar (path is \\machine\foo\)
+ \\machine\foo (path is \\machine\foo\)
+ \\machine\foo\
+ \\.\c$\ (FIXFIX: Win32API doesn't like this - GetComputerName())
+ LATERLATER: handling mounted DFS drives in the future will require
+ slightly different logic which isn't available today.
+ This is required because directories can point at
+ different servers which have differing capabilities.
+ */
+
+ if(TempRootPath[0] == '\\' && TempRootPath[1] == '\\') {
+ DWORD slash = 0;
+
+ for(i = 2 ; i < cchTempRootPath ; i++) {
+ if(TempRootPath[i] == '\\') {
+ slash++;
+
+ if(slash == 2) {
+ i++;
+ TempRootPath[i] = '\0';
+ cchTempRootPath = i;
+ break;
+ }
+ }
+ }
+
+ /* if there was only one slash found, just tack another onto the end */
+
+ if(slash == 1 && TempRootPath[cchTempRootPath] != '\\') {
+ TempRootPath[cchTempRootPath] = TempRootPath[0]; /* '\' */
+ TempRootPath[cchTempRootPath+1] = '\0';
+ cchTempRootPath++;
+ }
+
+ } else {
+
+ if(TempRootPath[1] == ':') {
+
+ /* drive letter specified, truncate to root */
+ TempRootPath[2] = '\\';
+ TempRootPath[3] = '\0';
+ cchTempRootPath = 3;
+ } else {
+
+ /* must be file on current drive */
+ TempRootPath[0] = '\0';
+ cchTempRootPath = 0;
+ }
+
+ }
+
+ } /* if path != NULL */
+
+ /* grab lock protecting cached entry */
+ EnterCriticalSection( &VolumeCapsLock );
+
+ if(!g_VolumeCaps.bValid || lstrcmpi(g_VolumeCaps.RootPath, TempRootPath) != 0) {
+
+ /* no match found, build up new entry */
+
+ DWORD dwFileSystemFlags;
+ DWORD dwRemotePrivileges = 0;
+ BOOL bRemote = FALSE;
+
+ /* release lock during expensive operations */
+ LeaveCriticalSection( &VolumeCapsLock );
+
+ bSuccess = GetVolumeInformation(
+ (TempRootPath[0] == '\0') ? NULL : TempRootPath,
+ NULL, 0,
+ NULL, NULL,
+ &dwFileSystemFlags,
+ NULL, 0);
+
+ /* only if target volume supports Acls, and we were told to use
+ privileges do we need to go out and test for the remote case */
+
+ if(bSuccess && (dwFileSystemFlags & FS_PERSISTENT_ACLS) && VolumeCaps->bUsePrivileges) {
+ if(GetDriveType( (TempRootPath[0] == '\0') ? NULL : TempRootPath ) == DRIVE_REMOTE) {
+ bRemote = TRUE;
+
+ /* make a determination about our remote capabilities */
+
+ GetRemotePrivilegesGet(name, &dwRemotePrivileges);
+ }
+ }
+
+ /* always take the lock again, since we release it below */
+ EnterCriticalSection( &VolumeCapsLock );
+
+ /* replace the existing data if successful */
+ if(bSuccess) {
+
+ lstrcpynA(g_VolumeCaps.RootPath, TempRootPath, cchTempRootPath+1);
+ g_VolumeCaps.bProcessDefer = FALSE;
+ g_VolumeCaps.dwFileSystemFlags = dwFileSystemFlags;
+ g_VolumeCaps.bRemote = bRemote;
+ g_VolumeCaps.dwRemotePrivileges = dwRemotePrivileges;
+ g_VolumeCaps.bValid = TRUE;
+ }
+ }
+
+ if(bSuccess) {
+ /* copy input elements */
+ g_VolumeCaps.bUsePrivileges = VolumeCaps->bUsePrivileges;
+ g_VolumeCaps.dwFileAttributes = VolumeCaps->dwFileAttributes;
+
+ /* give caller results */
+ memcpy(VolumeCaps, &g_VolumeCaps, sizeof(VOLUMECAPS));
+ } else {
+ g_VolumeCaps.bValid = FALSE;
+ }
+
+ LeaveCriticalSection( &VolumeCapsLock ); /* release lock */
+
+ return bSuccess;
+}
+
+BOOL SecurityGet(
+ char *resource,
+ PVOLUMECAPS VolumeCaps,
+ unsigned char *buffer,
+ DWORD *cbBuffer
+ )
+{
+ HANDLE hFile;
+ DWORD dwDesiredAccess;
+ DWORD dwFlags;
+ PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)buffer;
+ SECURITY_INFORMATION RequestedInfo;
+ BOOL bBackupPrivilege = FALSE;
+ BOOL bSaclPrivilege = FALSE;
+ BOOL bSuccess = FALSE;
+
+ DWORD cchResourceLen;
+
+ if(!bZipInitialized) if(!Initialize()) return FALSE;
+
+ /* see if we are dealing with a directory */
+ /* rely on the fact resource has a trailing [back]slash, rather
+ than calling expensive GetFileAttributes() */
+
+ cchResourceLen = lstrlenA(resource);
+
+ if(resource[cchResourceLen-1] == '/' || resource[cchResourceLen-1] == '\\')
+ VolumeCaps->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+
+ /* setup privilege usage based on if told we can use privileges, and if so,
+ what privileges we have */
+
+ if(VolumeCaps->bUsePrivileges) {
+ if(VolumeCaps->bRemote) {
+ /* use remotely determined privileges */
+ if(VolumeCaps->dwRemotePrivileges & OVERRIDE_BACKUP)
+ bBackupPrivilege = TRUE;
+
+ if(VolumeCaps->dwRemotePrivileges & OVERRIDE_SACL)
+ bSaclPrivilege = TRUE;
+ } else {
+ /* use local privileges */
+ bBackupPrivilege = g_bBackupPrivilege;
+ bSaclPrivilege = g_bZipSaclPrivilege;
+ }
+ }
+
+ /* always try to read the basic security information: Dacl, Owner, Group */
+
+ dwDesiredAccess = READ_CONTROL;
+
+ RequestedInfo = OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION;
+
+ /* if we have the SeBackupPrivilege or SeSystemSecurityPrivilege, read
+ the Sacl, too */
+
+ if(bBackupPrivilege || bSaclPrivilege) {
+ dwDesiredAccess |= ACCESS_SYSTEM_SECURITY;
+ RequestedInfo |= SACL_SECURITY_INFORMATION;
+ }
+
+ dwFlags = 0;
+
+ /* if we have the backup privilege, specify that */
+ /* opening a directory requires FILE_FLAG_BACKUP_SEMANTICS */
+
+ if(bBackupPrivilege || (VolumeCaps->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ dwFlags |= FILE_FLAG_BACKUP_SEMANTICS;
+
+ hFile = CreateFileA(
+ resource,
+ dwDesiredAccess,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* maximum sharing */
+ NULL,
+ OPEN_EXISTING,
+ dwFlags,
+ NULL
+ );
+
+ if(hFile == INVALID_HANDLE_VALUE) return FALSE;
+
+ if(GetKernelObjectSecurity(hFile, RequestedInfo, sd, *cbBuffer, cbBuffer)) {
+ *cbBuffer = GetSecurityDescriptorLength( sd );
+ bSuccess = TRUE;
+ }
+
+ CloseHandle(hFile);
+
+ return bSuccess;
+}
+
+static VOID InitLocalPrivileges(VOID)
+{
+ HANDLE hToken;
+ TOKEN_PRIVILEGES tp;
+
+ /* try to enable some interesting privileges that give us the ability
+ to get some security information that we normally cannot.
+
+ note that enabling privileges is only relevant on the local machine;
+ when accessing files that are on a remote machine, any privileges
+ that are present on the remote machine get enabled by default. */
+
+ if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
+ return;
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ /* try to enable SeBackupPrivilege.
+ if this succeeds, we can read all aspects of the security descriptor */
+
+ if(LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &tp.Privileges[0].Luid)) {
+ if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL) &&
+ GetLastError() == ERROR_SUCCESS) g_bBackupPrivilege = TRUE;
+ }
+
+ /* try to enable SeSystemSecurityPrivilege if SeBackupPrivilege not present.
+ if this succeeds, we can read the Sacl */
+
+ if(!g_bBackupPrivilege &&
+ LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tp.Privileges[0].Luid)) {
+
+ if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL) &&
+ GetLastError() == ERROR_SUCCESS) g_bZipSaclPrivilege = TRUE;
+ }
+
+ CloseHandle(hToken);
+}
+#endif /* NTSD_EAS */
diff --git a/win32/nt.h b/win32/nt.h
new file mode 100644
index 0000000..72b83af
--- /dev/null
+++ b/win32/nt.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+#ifndef _NT_ZIP_H
+#define _NT_ZIP_H
+
+/* central header for EF_NTSD "SD" extra field */
+
+#define EF_NTSD_MAX_VER_SUPPORT (0)
+ /* describes maximum ver# we know how to handle */
+
+typedef struct
+{
+ USHORT nID;
+ USHORT nSize;
+ ULONG lSize;
+}
+EF_NTSD_C_HEADER, *PEF_NTSD_C_HEADER;
+
+#define EF_NTSD_C_LEN (sizeof(EF_NTSD_C_HEADER))
+
+/* local header for EF_NTSD "SD" extra field */
+
+#pragma pack(1) /* bytes following structure immediately follow BYTE Version */
+
+typedef struct
+{
+ USHORT nID; /* tag for this extra block type */
+ USHORT nSize; /* total data size for this block */
+ ULONG lSize; /* uncompressed security descriptor data size */
+ BYTE Version; /* Version of uncompressed security descriptor data format */
+}
+IZ_PACKED EF_NTSD_L_HEADER, *PEF_NTSD_L_HEADER;
+
+#pragma pack()
+
+/* ...followed by... */
+/* SHORT CType; compression type */
+/* ULONG EACRC; CRC value for uncompressed security descriptor data */
+/* <var.> Variable length data */
+
+
+#define EF_NTSD_L_LEN (EF_NTSD_C_LEN + sizeof(BYTE))
+ /* avoid alignment size computation */
+
+#define NTSD_BUFFERSIZE (1024) /* threshold to cause malloc() */
+
+#define OVERRIDE_BACKUP 1 /* we have SeBackupPrivilege on remote */
+#define OVERRIDE_RESTORE 2 /* we have SeRestorePrivilege on remote */
+#define OVERRIDE_SACL 4 /* we have SeSystemSecurityPrivilege on remote */
+
+typedef struct {
+ BOOL bValid; /* are our contents valid? */
+ BOOL bProcessDefer; /* process deferred entry yet? */
+ BOOL bUsePrivileges; /* use privilege overrides? */
+ DWORD dwFileSystemFlags; /* describes target file system */
+ BOOL bRemote; /* is volume remote? */
+ DWORD dwRemotePrivileges; /* relevant only on remote volumes */
+ DWORD dwFileAttributes;
+ char RootPath[MAX_PATH+1]; /* path to network / filesystem */
+} VOLUMECAPS, *PVOLUMECAPS, *LPVOLUMECAPS;
+
+BOOL SecurityGet(char *resource, PVOLUMECAPS VolumeCaps, unsigned char *buffer,
+ DWORD *cbBuffer);
+BOOL ZipGetVolumeCaps(char *rootpath, char *name, PVOLUMECAPS VolumeCaps);
+
+#endif /* _NT_ZIP_H */
+
diff --git a/win32/osdep.h b/win32/osdep.h
new file mode 100644
index 0000000..a867088
--- /dev/null
+++ b/win32/osdep.h
@@ -0,0 +1,271 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* Automatic setting of the common Microsoft C idenfifier MSC.
+ * NOTE: Watcom also defines M_I*86 !
+ */
+#if defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__))
+# ifndef MSC
+# define MSC /* This should work for older MSC, too! */
+# endif
+#endif
+
+#if defined(__WATCOMC__) && defined(__386__)
+# define WATCOMC_386
+#endif
+
+#if (defined(__CYGWIN32__) && !defined(__CYGWIN__))
+# define __CYGWIN__ /* compatibility for CygWin B19 and older */
+#endif
+
+/* enable multibyte character set support by default */
+#ifndef _MBCS
+# define _MBCS
+#endif
+#if defined(__CYGWIN__)
+# undef _MBCS
+#endif
+
+#ifndef MSDOS
+/*
+ * Windows 95 (and Windows NT) file systems are (to some extend)
+ * extensions of MSDOS. Common features include for example:
+ * FAT or (FAT like) file systems,
+ * '\\' as directory separator in paths,
+ * "\r\n" as record (line) terminator in text files, ...
+ */
+# define MSDOS
+/* inherit MS-DOS file system etc. stuff */
+#endif
+
+#define USE_CASE_MAP
+#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \
+ procname(n, 1))
+#define BROKEN_FSEEK
+#ifndef __RSXNT__
+# define HAVE_FSEEKABLE
+#endif
+
+/* File operations--use "b" for binary if allowed or fixed length 512 on VMS
+ * use "S" for sequential access on NT to prevent the NT
+ * file cache eating up memory with large .zip files
+ */
+#define FOPR "rb"
+#define FOPM "r+b"
+#define FOPW "wbS"
+
+#if (defined(__CYGWIN__) && !defined(NO_MKTIME))
+# define NO_MKTIME /* Cygnus' mktime() implementation is buggy */
+#endif
+#if (!defined(NT_TZBUG_WORKAROUND) && !defined(NO_NT_TZBUG_WORKAROUND))
+# define NT_TZBUG_WORKAROUND
+#endif
+#if (defined(UTIL) && defined(NT_TZBUG_WORKAROUND))
+# undef NT_TZBUG_WORKAROUND /* the Zip utilities do not use time-stamps */
+#endif
+#if !defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)
+# define USE_EF_UT_TIME
+#endif
+#if (!defined(NO_NTSD_EAS) && !defined(NTSD_EAS))
+# define NTSD_EAS
+#endif
+
+#if (defined(NTSD_EAS) && !defined(ZP_NEED_MEMCOMPR))
+# define ZP_NEED_MEMCOMPR
+#endif
+
+#ifdef WINDLL
+# ifndef NO_ASM
+# define NO_ASM
+# endif
+# ifndef MSWIN
+# define MSWIN
+# endif
+# ifndef REENTRANT
+# define REENTRANT
+# endif
+#endif /* WINDLL */
+
+/* Enable use of optimized x86 assembler version of longest_match() for
+ MSDOS, WIN32 and OS2 per default. */
+#if !defined(NO_ASM) && !defined(ASMV)
+# define ASMV
+#endif
+
+/* Enable use of optimized x86 assembler version of crc32() for
+ MSDOS, WIN32 and OS2 per default. */
+#if !defined(NO_ASM) && !defined(ASM_CRC) && !defined(NO_ASM_CRC)
+# define ASM_CRC
+#endif
+
+#if !defined(__GO32__) && !defined(__EMX__) && !defined(__CYGWIN__)
+# define NO_UNISTD_H
+#endif
+
+/* the following definitions are considered as "obsolete" by Microsoft and
+ * might be missing in some versions of <windows.h>
+ */
+#ifndef AnsiToOem
+# define AnsiToOem CharToOemA
+#endif
+#ifndef OemToAnsi
+# define OemToAnsi OemToCharA
+#endif
+
+#if (defined(__RSXNT__) && defined(__CRTRSXNT__))
+# include <crtrsxnt.h>
+#endif
+
+/* Get types and stat */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <io.h>
+#ifdef _MBCS
+# if (!defined(__EMX__) && !defined(__MINGW32__) && !defined(__CYGWIN__))
+# include <stdlib.h>
+# include <mbstring.h>
+# endif
+# if (defined(__MINGW32__) && !defined(MB_CUR_MAX))
+# ifdef __MSVCRT__
+ extern int *__p___mb_cur_max(void);
+# define MB_CUR_MAX (*__p___mb_cur_max())
+# else
+ extern int *_imp____mb_cur_max_dll;
+# define MB_CUR_MAX (*_imp____mb_cur_max_dll)
+# endif
+# endif
+# if (defined(__LCC__) && !defined(MB_CUR_MAX))
+ extern int *_imp____mb_cur_max;
+# define MB_CUR_MAX (*_imp____mb_cur_max)
+# endif
+#endif
+
+#ifdef __LCC__
+# include <time.h>
+# ifndef tzset
+# define tzset _tzset
+# endif
+# ifndef utime
+# define utime _utime
+# endif
+#endif
+#ifdef __MINGW32__
+ extern void _tzset(void); /* this is missing in <time.h> */
+# ifndef tzset
+# define tzset _tzset
+# endif
+#endif
+#if (defined(__RSXNT__) || defined(__EMX__)) && !defined(tzset)
+# define tzset _tzset
+#endif
+#ifdef W32_USE_IZ_TIMEZONE
+# ifdef __BORLANDC__
+# define tzname tzname
+# define IZTZ_DEFINESTDGLOBALS
+# endif
+# ifndef tzset
+# define tzset _tzset
+# endif
+# ifndef timezone
+# define timezone _timezone
+# endif
+# ifndef daylight
+# define daylight _daylight
+# endif
+# ifndef tzname
+# define tzname _tzname
+# endif
+# if (!defined(NEED__ISINDST) && !defined(__BORLANDC__))
+# define NEED__ISINDST
+# endif
+# ifdef IZTZ_GETLOCALETZINFO
+# undef IZTZ_GETLOCALETZINFO
+# endif
+# define IZTZ_GETLOCALETZINFO GetPlatformLocalTimezone
+#endif /* W32_USE_IZ_TIMEZONE */
+
+#ifdef MATCH
+# undef MATCH
+#endif
+#define MATCH dosmatch /* use DOS style wildcard matching */
+
+#ifdef ZCRYPT_INTERNAL
+# ifdef WINDLL
+# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */
+# else
+# include <process.h> /* getpid() declaration for srand seed */
+# endif
+#endif
+
+/* Up to now, all versions of Microsoft C runtime libraries lack the support
+ * for customized (non-US) switching rules between daylight saving time and
+ * standard time in the TZ environment variable string.
+ * But non-US timezone rules are correctly supported when timezone information
+ * is read from the OS system settings in the Win32 registry.
+ * The following work-around deletes any TZ environment setting from
+ * the process environment. This results in a fallback of the RTL time
+ * handling code to the (correctly interpretable) OS system settings, read
+ * from the registry.
+ */
+#ifdef USE_EF_UT_TIME
+# if (defined(__WATCOMC__) || defined(W32_USE_IZ_TIMEZONE))
+# define iz_w32_prepareTZenv()
+# else
+# define iz_w32_prepareTZenv() putenv("TZ=")
+# endif
+#endif
+
+/* This patch of stat() is useful for at least three compilers. It is */
+/* difficult to take a stat() of a root directory under Windows95, so */
+/* zstat_zipwin32() detects that case and fills in suitable values. */
+#ifndef __RSXNT__
+# ifndef W32_STATROOT_FIX
+# define W32_STATROOT_FIX
+# endif
+#endif /* !__RSXNT__ */
+
+#if (defined(NT_TZBUG_WORKAROUND) || defined(W32_STATROOT_FIX))
+# define W32_STAT_BANDAID
+ int zstat_zipwin32(const char *path, struct stat *buf);
+# ifdef SSTAT
+# undef SSTAT
+# endif
+# define SSTAT zstat_zipwin32
+#endif /* NT_TZBUG_WORKAROUND || W32_STATROOT_FIX */
+
+int getch_win32(void);
+
+#ifdef __GNUC__
+# define IZ_PACKED __attribute__((packed))
+#else
+# define IZ_PACKED
+#endif
+
+/* for some (all ?) versions of IBM C Set/2 and IBM C Set++ */
+#ifndef S_IFMT
+# define S_IFMT 0xF000
+#endif /* !S_IFMT */
+
+#ifdef __WATCOMC__
+# include <stdio.h> /* PATH_MAX is defined here */
+# define NO_MKTEMP
+
+/* Get asm routines to link properly without using "__cdecl": */
+# ifdef __386__
+# ifdef ASMV
+# pragma aux match_init "_*" parm caller [] modify []
+# pragma aux longest_match "_*" parm caller [] value [eax] \
+ modify [eax ecx edx]
+# endif
+# if defined(ASM_CRC) && !defined(USE_ZLIB)
+# pragma aux crc32 "_*" parm caller [] value [eax] modify [eax]
+# pragma aux get_crc_table "_*" parm caller [] value [eax] \
+ modify [eax ecx edx]
+# endif /* ASM_CRC && !USE_ZLIB */
+# endif /* __386__ */
+#endif /* __WATCOMC__ */
diff --git a/win32/readme.a64 b/win32/readme.a64
new file mode 100644
index 0000000..54b2750
--- /dev/null
+++ b/win32/readme.a64
@@ -0,0 +1,42 @@
+readme.x64
+==========
+
+[Note - the gvmat64.asm longest_match routine in Windows 64-bit assembler
+and makefile.a64 used to compile it were provided at the last minute and
+are currently untested by Info-ZIP. They are provided to allow testing of
+this optimization which is planned for inclusion in Zip 3.0.
+USE AT YOUR OWN RISK. That said, thanks Gilles for providing this
+optimization and we plan to better support it in Zip 3.0. 2/28/2005 EG]
+
+makefile.asm64 is a makefile for 64 bits optimized version of zip for
+Microsoft Windows running on AMD64 (Athlon64/Opteron) and Intel EM64T
+(the Pentium 4 and Xeon with 64 bits extension)
+
+makefile.asm64 contain a makefile for 64 Microsoft C++ for Windows 64 bits,
+extended edition (for both AMD64 and Intel EM64T), included in Visual
+Studio 2005
+
+to compile it, start the C++ AMD64 build environnement prompt,
+go to the zip source directory and start
+
+ nmake -a -f makefile.a64
+
+This makefile uses gvmat64.asm, which is the optimized longest_match written
+in assembly code for AMD64/Intel EM64T
+
+gvmat64.asm was tested by Gilles Vollant on AMD64 with infozip, and also tested
+with a lot of file with zLib 1.2.2 on both AMD64 and Intel EM64T processor.
+
+It was written by Gilles Vollant, by modifiying the longest_match
+from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+and modifying asm686 (1998), optimised assembly code from Brian Raiter,
+(see http://www.muppetlabs.com/~breadbox/software/assembly.html)
+
+
+Gilles Vollant
+info@winimage.com
+
+http://www.winimage.com
+http://www.winimage.com/zLibdll
+
+
diff --git a/win32/rsxntwin.h b/win32/rsxntwin.h
new file mode 100644
index 0000000..3df30e8
--- /dev/null
+++ b/win32/rsxntwin.h
@@ -0,0 +1,166 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* rsxntwin.h
+ *
+ * fills some gaps in the rsxnt 1.3 win32 header files (<windows.h>) that are
+ * required for compiling Info-ZIP sources for Win NT / Win 95
+ */
+
+#ifdef __RSXNT__
+#if !defined (_RSXNTWIN_H)
+#define _RSXNTWIN_H
+
+#ifdef TFUNCT /* TFUNCT is undefined when MSSDK headers are used */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PASCAL __stdcall
+
+#define ANYSIZE_ARRAY 1
+
+#ifndef TIME_ZONE_ID_UNKNOWN
+# define TIME_ZONE_ID_UNKNOWN 0
+#endif
+#ifndef TIME_ZONE_ID_INVALID
+# define TIME_ZONE_ID_INVALID (DWORD)0xFFFFFFFFL
+#endif
+
+#define FILE_ATTRIBUTE_HIDDEN 0x00000002
+#define FILE_ATTRIBUTE_SYSTEM 0x00000004
+
+#define FILE_SHARE_DELETE 0x00000004
+
+#define FILE_PERSISTENT_ACLS 0x00000008
+
+#define HFILE_ERROR ((HFILE)-1)
+
+#define FS_PERSISTENT_ACLS FILE_PERSISTENT_ACLS
+
+
+BOOL WINAPI DosDateTimeToFileTime(WORD, WORD, LPFILETIME);
+
+
+#ifndef SetVolumeLabel
+#define SetVolumeLabel TFUNCT(SetVolumeLabel)
+#endif
+BOOL WINAPI SetVolumeLabel(LPCTSTR, LPCTSTR);
+
+
+#ifndef GetDriveType
+#define GetDriveType TFUNCT(GetDriveType)
+#endif
+DWORD GetDriveType(LPCTSTR);
+
+#define DRIVE_UNKNOWN 0
+#define DRIVE_REMOVABLE 2
+#define DRIVE_FIXED 3
+#define DRIVE_REMOTE 4
+#define DRIVE_CDROM 5
+#define DRIVE_RAMDISK 6
+
+#ifndef SearchPath
+#define SearchPath TFUNCT(SearchPath)
+#endif
+BOOL WINAPI SearchPath(LPCTSTR, LPCTSTR, LPCTSTR, UINT, LPTSTR, LPTSTR *);
+
+#define ERROR_SUCCESS 0
+#define ERROR_INSUFFICIENT_BUFFER 122
+
+LONG WINAPI InterlockedExchange(LPLONG, LONG);
+
+#define ACCESS_SYSTEM_SECURITY 0x01000000L
+
+typedef PVOID PSECURITY_DESCRIPTOR;
+typedef PVOID PSID;
+typedef struct _ACL {
+ BYTE AclRevision;
+ BYTE Sbz1;
+ WORD AclSize;
+ WORD AceCount;
+ WORD Sbz2;
+} ACL;
+typedef ACL *PACL;
+
+typedef struct _LUID {
+ DWORD LowPart;
+ LONG HighPart;
+} LUID, *PLUID;
+
+typedef struct _LUID_AND_ATTRIBUTES {
+ LUID Luid;
+ DWORD Attributes;
+ } LUID_AND_ATTRIBUTES, * PLUID_AND_ATTRIBUTES;
+
+typedef struct _TOKEN_PRIVILEGES {
+ DWORD PrivilegeCount;
+ LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
+} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
+
+#define TOKEN_QUERY 0x0008
+#define TOKEN_ADJUST_PRIVILEGES 0x0020
+
+BOOL WINAPI OpenProcessToken(HANDLE, DWORD, PHANDLE);
+BOOL WINAPI AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD,
+ PTOKEN_PRIVILEGES, PDWORD);
+
+#ifndef LookupPrivilegeValue
+#define LookupPrivilegeValue TFUNCT(LookupPrivilegeValue)
+#endif
+BOOL WINAPI LookupPrivilegeValue(LPCTSTR, LPCTSTR, PLUID);
+
+typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION;
+#define OWNER_SECURITY_INFORMATION 0x00000001L
+#define GROUP_SECURITY_INFORMATION 0x00000002L
+#define DACL_SECURITY_INFORMATION 0x00000004L
+#define SACL_SECURITY_INFORMATION 0x00000008L
+
+typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
+#define SE_DACL_PRESENT 0x0004
+#define SE_SACL_PRESENT 0x0010
+
+#define SE_PRIVILEGE_ENABLED 0x00000002L
+
+#define SE_SECURITY_NAME TEXT("SeSecurityPrivilege")
+#define SE_BACKUP_NAME TEXT("SeBackupPrivilege")
+#define SE_RESTORE_NAME TEXT("SeRestorePrivilege")
+
+BOOL WINAPI GetKernelObjectSecurity(HANDLE, SECURITY_INFORMATION,
+ PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
+BOOL WINAPI SetKernelObjectSecurity(HANDLE, SECURITY_INFORMATION,
+ PSECURITY_DESCRIPTOR);
+BOOL WINAPI IsValidSid(PSID);
+BOOL WINAPI IsValidAcl(PACL);
+BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR);
+BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
+DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR);
+BOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,
+ PSECURITY_DESCRIPTOR_CONTROL, LPDWORD);
+BOOL WINAPI SetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,
+ SECURITY_DESCRIPTOR_CONTROL, SECURITY_DESCRIPTOR_CONTROL);
+BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,
+ LPBOOL, PACL *, LPBOOL);
+BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR, BOOL, PACL, BOOL);
+BOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,
+ LPBOOL, PACL *, LPBOOL);
+BOOL WINAPI SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR, BOOL, PACL, BOOL);
+BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR, PSID *, LPBOOL);
+BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR, PSID, BOOL);
+BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR, PSID *, LPBOOL);
+BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR, PSID, BOOL);
+VOID WINAPI InitializeCriticalSection();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TFUNCT */
+#endif /* !defined (_RSXNTWIN_H) */
+#endif /* __RSXNT__ */
diff --git a/win32/vc6/zip.dsp b/win32/vc6/zip.dsp
new file mode 100644
index 0000000..f82b335
--- /dev/null
+++ b/win32/vc6/zip.dsp
@@ -0,0 +1,328 @@
+# Microsoft Developer Studio Project File - Name="zip" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=zip - Win32 ASM Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zip.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zip.mak" CFG="zip - Win32 ASM Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zip - Win32 ASM Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "zip - Win32 ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zip - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "zip - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "zip - Win32 ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zip___Win32_ASM_Release"
+# PROP BASE Intermediate_Dir "zip___Win32_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zip___Win32_ASM_Release"
+# PROP Intermediate_Dir "zip___Win32_ASM_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "ASM_CRC" /D "ASMV" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "zip - Win32 ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zip___Win32_ASM_Debug"
+# PROP BASE Intermediate_Dir "zip___Win32_ASM_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zip___Win32_ASM_Debug"
+# PROP Intermediate_Dir "zip___Win32_ASM_Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "ASM_CRC" /D "ASMV" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "zip - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zip___Win32_Release"
+# PROP BASE Intermediate_Dir "zip___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zip___Win32_Release"
+# PROP Intermediate_Dir "zip___Win32_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NO_ASM" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zip___Win32_Debug"
+# PROP BASE Intermediate_Dir "zip___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zip___Win32_Debug"
+# PROP Intermediate_Dir "zip___Win32_Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "NO_ASM" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "zip - Win32 ASM Release"
+# Name "zip - Win32 ASM Debug"
+# Name "zip - Win32 Release"
+# Name "zip - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\crc32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crctab.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crypt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\deflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\fileio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\globals.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\nt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\trees.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ttyio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\util.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32zip.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zip.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipup.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\crypt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ebcdic.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\nt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\osdep.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\revision.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\tailor.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ttyio.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ziperr.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\zipup.h
+# End Source File
+# End Group
+# Begin Group "Assembler Files"
+
+# PROP Default_Filter "asm;obj"
+# Begin Source File
+
+SOURCE=..\crc_i386.asm
+
+!IF "$(CFG)" == "zip - Win32 ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Release
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zip - Win32 ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Debug
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+!ELSEIF "$(CFG)" == "zip - Win32 Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug"
+
+# PROP Exclude_From_Build 1
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\match32.asm
+
+!IF "$(CFG)" == "zip - Win32 ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Release
+InputPath=..\match32.asm
+InputName=match32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zip - Win32 ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Debug
+InputPath=..\match32.asm
+InputName=match32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+!ELSEIF "$(CFG)" == "zip - Win32 Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug"
+
+# PROP Exclude_From_Build 1
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/win32/vc6/zip.dsw b/win32/vc6/zip.dsw
new file mode 100644
index 0000000..681d183
--- /dev/null
+++ b/win32/vc6/zip.dsw
@@ -0,0 +1,65 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "zip"=".\zip.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zipcloak"=".\zipcloak.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zipnote"=".\zipnote.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zipsplit"=".\zipsplit.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/win32/vc6/zipcloak.dsp b/win32/vc6/zipcloak.dsp
new file mode 100644
index 0000000..dac83fa
--- /dev/null
+++ b/win32/vc6/zipcloak.dsp
@@ -0,0 +1,164 @@
+# Microsoft Developer Studio Project File - Name="zipcloak" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=zipcloak - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zipcloak.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zipcloak.mak" CFG="zipcloak - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zipcloak - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipcloak - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "zipcloak - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zipcloak___Win32_Release"
+# PROP BASE Intermediate_Dir "zipcloak___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zipcloak___Win32_Release"
+# PROP Intermediate_Dir "zipcloak___Win32_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "zipcloak - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zipcloak___Win32_Debug"
+# PROP BASE Intermediate_Dir "zipcloak___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zipcloak___Win32_Debug"
+# PROP Intermediate_Dir "zipcloak___Win32_Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "UTIL" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "zipcloak - Win32 Release"
+# Name "zipcloak - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\crctab.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crypt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\fileio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\globals.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ttyio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\util.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipcloak.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipfile.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\crypt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ebcdic.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\osdep.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\revision.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\tailor.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ttyio.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ziperr.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/win32/vc6/zipnote.dsp b/win32/vc6/zipnote.dsp
new file mode 100644
index 0000000..e32e2f1
--- /dev/null
+++ b/win32/vc6/zipnote.dsp
@@ -0,0 +1,144 @@
+# Microsoft Developer Studio Project File - Name="zipnote" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=zipnote - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zipnote.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zipnote.mak" CFG="zipnote - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zipnote - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipnote - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "zipnote - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zipnote___Win32_Release"
+# PROP BASE Intermediate_Dir "zipnote___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zipnote___Win32_Release"
+# PROP Intermediate_Dir "zipnote___Win32_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "zipnote - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zipnote___Win32_Debug"
+# PROP BASE Intermediate_Dir "zipnote___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zipnote___Win32_Debug"
+# PROP Intermediate_Dir "zipnote___Win32_Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "UTIL" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "zipnote - Win32 Release"
+# Name "zipnote - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\fileio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\globals.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\util.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipnote.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\ebcdic.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\osdep.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\revision.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\tailor.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ziperr.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/win32/vc6/zipsplit.dsp b/win32/vc6/zipsplit.dsp
new file mode 100644
index 0000000..aec7139
--- /dev/null
+++ b/win32/vc6/zipsplit.dsp
@@ -0,0 +1,144 @@
+# Microsoft Developer Studio Project File - Name="zipsplit" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=zipsplit - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zipsplit.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zipsplit.mak" CFG="zipsplit - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zipsplit - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipsplit - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "zipsplit - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zipsplit___Win32_Release"
+# PROP BASE Intermediate_Dir "zipsplit___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zipsplit___Win32_Release"
+# PROP Intermediate_Dir "zipsplit___Win32_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "zipsplit - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zipsplit___Win32_Debug"
+# PROP BASE Intermediate_Dir "zipsplit___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zipsplit___Win32_Debug"
+# PROP Intermediate_Dir "zipsplit___Win32_Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "UTIL" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "zipsplit - Win32 Release"
+# Name "zipsplit - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\fileio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\globals.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\util.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipsplit.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\ebcdic.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\osdep.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\revision.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\tailor.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ziperr.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/win32/win32.c b/win32/win32.c
new file mode 100644
index 0000000..88bd565
--- /dev/null
+++ b/win32/win32.c
@@ -0,0 +1,989 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ * WIN32 specific functions for ZIP.
+ *
+ * The WIN32 version of ZIP heavily relies on the MSDOS and OS2 versions,
+ * since we have to do similar things to switch between NTFS, HPFS and FAT.
+ */
+
+
+#include "../zip.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <time.h>
+#include <ctype.h>
+#include <windows.h>
+#ifdef __RSXNT__
+# include <alloca.h>
+# include "../win32/rsxntwin.h"
+#endif
+#include "../win32/win32zip.h"
+
+#define A_RONLY 0x01
+#define A_HIDDEN 0x02
+#define A_SYSTEM 0x04
+#define A_LABEL 0x08
+#define A_DIR 0x10
+#define A_ARCHIVE 0x20
+
+
+#define EAID 0x0009
+
+
+#ifndef UTIL
+
+extern int noisy;
+
+#ifdef NT_TZBUG_WORKAROUND
+local int FSusesLocalTime(const char *path);
+#endif
+#if (defined(USE_EF_UT_TIME) || \
+ (defined(NT_TZBUG_WORKAROUND) && !defined(NO_W32TIMES_IZFIX)))
+local int NtfsFileTime2utime(const FILETIME *pft, time_t *ut);
+#endif
+#if (defined(NT_TZBUG_WORKAROUND) && defined(W32_STAT_BANDAID))
+local int VFatFileTime2utime(const FILETIME *pft, time_t *ut);
+#endif
+
+
+/* FAT / HPFS detection */
+
+int IsFileSystemOldFAT(const char *dir)
+{
+ char root[4];
+ char vname[128];
+ DWORD vnamesize = sizeof(vname);
+ DWORD vserial;
+ DWORD vfnsize;
+ DWORD vfsflags;
+ char vfsname[128];
+ DWORD vfsnamesize = sizeof(vfsname);
+
+ /*
+ * We separate FAT and HPFS+other file systems here.
+ * I consider other systems to be similar to HPFS/NTFS, i.e.
+ * support for long file names and being case sensitive to some extent.
+ */
+
+ strncpy(root, dir, 3);
+ if ( isalpha((uch)root[0]) && (root[1] == ':') ) {
+ root[0] = to_up(dir[0]);
+ root[2] = '\\';
+ root[3] = 0;
+ }
+ else {
+ root[0] = '\\';
+ root[1] = 0;
+ }
+
+ if ( !GetVolumeInformation(root, vname, vnamesize,
+ &vserial, &vfnsize, &vfsflags,
+ vfsname, vfsnamesize)) {
+ fprintf(mesg, "zip diagnostic: GetVolumeInformation failed\n");
+ return(FALSE);
+ }
+
+ return vfnsize <= 12;
+}
+
+
+/* access mode bits and time stamp */
+
+int GetFileMode(const char *name)
+{
+DWORD dwAttr;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(name) + 1);
+
+ OemToAnsi(name, ansi_name);
+ name = (const char *)ansi_name;
+#endif
+
+ dwAttr = GetFileAttributes(name);
+ if ( dwAttr == 0xFFFFFFFF ) {
+ fprintf(mesg, "zip diagnostic: GetFileAttributes failed\n");
+ return(0x20); /* the most likely, though why the error? security? */
+ }
+ return(
+ (dwAttr&FILE_ATTRIBUTE_READONLY ? A_RONLY :0)
+ | (dwAttr&FILE_ATTRIBUTE_HIDDEN ? A_HIDDEN :0)
+ | (dwAttr&FILE_ATTRIBUTE_SYSTEM ? A_SYSTEM :0)
+ | (dwAttr&FILE_ATTRIBUTE_DIRECTORY ? A_DIR :0)
+ | (dwAttr&FILE_ATTRIBUTE_ARCHIVE ? A_ARCHIVE :0));
+}
+
+
+#ifdef NT_TZBUG_WORKAROUND
+local int FSusesLocalTime(const char *path)
+{
+ char *tmp0;
+ char rootPathName[4];
+ char tmp1[MAX_PATH], tmp2[MAX_PATH];
+ DWORD volSerNo, maxCompLen, fileSysFlags;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(path) + 1);
+
+ OemToAnsi(path, ansi_path);
+ path = (const char *)ansi_path;
+#endif
+
+ if (isalpha((uch)path[0]) && (path[1] == ':'))
+ tmp0 = (char *)path;
+ else
+ {
+ GetFullPathName(path, MAX_PATH, tmp1, &tmp0);
+ tmp0 = &tmp1[0];
+ }
+ strncpy(rootPathName, tmp0, 3); /* Build the root path name, */
+ rootPathName[3] = '\0'; /* e.g. "A:/" */
+
+ GetVolumeInformation((LPCTSTR)rootPathName, (LPTSTR)tmp1, (DWORD)MAX_PATH,
+ &volSerNo, &maxCompLen, &fileSysFlags,
+ (LPTSTR)tmp2, (DWORD)MAX_PATH);
+
+ /* Volumes in (V)FAT and (OS/2) HPFS format store file timestamps in
+ * local time!
+ */
+ return !strncmp(strupr(tmp2), "FAT", 3) ||
+ !strncmp(tmp2, "VFAT", 4) ||
+ !strncmp(tmp2, "HPFS", 4);
+
+} /* end function FSusesLocalTime() */
+#endif /* NT_TZBUG_WORKAROUND */
+
+
+#if (defined(USE_EF_UT_TIME) || \
+ (defined(NT_TZBUG_WORKAROUND) && !defined(NO_W32TIMES_IZFIX)))
+
+#if (defined(__GNUC__) || defined(ULONG_LONG_MAX))
+ typedef long long LLONG64;
+ typedef unsigned long long ULLNG64;
+#elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))
+ typedef __int64 LLONG64;
+ typedef unsigned __int64 ULLNG64;
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1100))
+ typedef __int64 LLONG64;
+ typedef unsigned __int64 ULLNG64;
+#elif (defined(__IBMC__) && (__IBMC__ >= 350))
+ typedef __int64 LLONG64;
+ typedef unsigned __int64 ULLNG64;
+#else
+# define NO_INT64
+#endif
+
+/* scale factor and offset for conversion time_t -> FILETIME */
+# define NT_QUANTA_PER_UNIX 10000000L
+# define FTQUANTA_PER_UT_L (NT_QUANTA_PER_UNIX & 0xFFFF)
+# define FTQUANTA_PER_UT_H (NT_QUANTA_PER_UNIX >> 16)
+# define UNIX_TIME_ZERO_HI 0x019DB1DEUL
+# define UNIX_TIME_ZERO_LO 0xD53E8000UL
+/* special FILETIME values for bound-checks */
+# define UNIX_TIME_UMAX_HI 0x0236485EUL
+# define UNIX_TIME_UMAX_LO 0xD4A5E980UL
+# define UNIX_TIME_SMIN_HI 0x0151669EUL
+# define UNIX_TIME_SMIN_LO 0xD53E8000UL
+# define UNIX_TIME_SMAX_HI 0x01E9FD1EUL
+# define UNIX_TIME_SMAX_LO 0xD4A5E980UL
+
+local int NtfsFileTime2utime(const FILETIME *pft, time_t *ut)
+{
+#ifndef NO_INT64
+ ULLNG64 NTtime;
+
+ NTtime = ((ULLNG64)pft->dwLowDateTime +
+ ((ULLNG64)pft->dwHighDateTime << 32));
+
+ /* underflow and overflow handling */
+#ifdef CHECK_UTIME_SIGNED_UNSIGNED
+ if ((time_t)0x80000000L < (time_t)0L)
+ {
+ if (NTtime < ((ULLNG64)UNIX_TIME_SMIN_LO +
+ ((ULLNG64)UNIX_TIME_SMIN_HI << 32))) {
+ *ut = (time_t)LONG_MIN;
+ return FALSE;
+ }
+ if (NTtime > ((ULLNG64)UNIX_TIME_SMAX_LO +
+ ((ULLNG64)UNIX_TIME_SMAX_HI << 32))) {
+ *ut = (time_t)LONG_MAX;
+ return FALSE;
+ }
+ }
+ else
+#endif /* CHECK_UTIME_SIGNED_UNSIGNED */
+ {
+ if (NTtime < ((ULLNG64)UNIX_TIME_ZERO_LO +
+ ((ULLNG64)UNIX_TIME_ZERO_HI << 32))) {
+ *ut = (time_t)0;
+ return FALSE;
+ }
+ if (NTtime > ((ULLNG64)UNIX_TIME_UMAX_LO +
+ ((ULLNG64)UNIX_TIME_UMAX_HI << 32))) {
+ *ut = (time_t)ULONG_MAX;
+ return FALSE;
+ }
+ }
+
+ NTtime -= ((ULLNG64)UNIX_TIME_ZERO_LO +
+ ((ULLNG64)UNIX_TIME_ZERO_HI << 32));
+ *ut = (time_t)(NTtime / (unsigned long)NT_QUANTA_PER_UNIX);
+ return TRUE;
+#else /* NO_INT64 (64-bit integer arithmetics may not be supported) */
+ /* nonzero if `y' is a leap year, else zero */
+# define leap(y) (((y)%4 == 0 && (y)%100 != 0) || (y)%400 == 0)
+ /* number of leap years from 1970 to `y' (not including `y' itself) */
+# define nleap(y) (((y)-1969)/4 - ((y)-1901)/100 + ((y)-1601)/400)
+ /* daycount at the end of month[m-1] */
+ static ZCONST ush ydays[] =
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+
+ time_t days;
+ SYSTEMTIME w32tm;
+
+ /* underflow and overflow handling */
+#ifdef CHECK_UTIME_SIGNED_UNSIGNED
+ if ((time_t)0x80000000L < (time_t)0L)
+ {
+ if ((pft->dwHighDateTime < UNIX_TIME_SMIN_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_SMIN_HI) &&
+ (pft->dwLowDateTime < UNIX_TIME_SMIN_LO))) {
+ *ut = (time_t)LONG_MIN;
+ return FALSE;
+ if ((pft->dwHighDateTime > UNIX_TIME_SMAX_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_SMAX_HI) &&
+ (pft->dwLowDateTime > UNIX_TIME_SMAX_LO))) {
+ *ut = (time_t)LONG_MAX;
+ return FALSE;
+ }
+ }
+ else
+#endif /* CHECK_UTIME_SIGNED_UNSIGNED */
+ {
+ if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) &&
+ (pft->dwLowDateTime < UNIX_TIME_ZERO_LO))) {
+ *ut = (time_t)0;
+ return FALSE;
+ }
+ if ((pft->dwHighDateTime > UNIX_TIME_UMAX_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_UMAX_HI) &&
+ (pft->dwLowDateTime > UNIX_TIME_UMAX_LO))) {
+ *ut = (time_t)ULONG_MAX;
+ return FALSE;
+ }
+ }
+
+ FileTimeToSystemTime(pft, &w32tm);
+
+ /* set `days' to the number of days into the year */
+ days = w32tm.wDay - 1 + ydays[w32tm.wMonth-1] +
+ (w32tm.wMonth > 2 && leap (w32tm.wYear));
+
+ /* now set `days' to the number of days since 1 Jan 1970 */
+ days += 365 * (time_t)(w32tm.wYear - 1970) +
+ (time_t)(nleap(w32tm.wYear));
+
+ *ut = (time_t)(86400L * days + 3600L * (time_t)w32tm.wHour +
+ (time_t)(60 * w32tm.wMinute + w32tm.wSecond));
+ return TRUE;
+#endif /* ?NO_INT64 */
+} /* end function NtfsFileTime2utime() */
+#endif /* USE_EF_UT_TIME || (NT_TZBUG_WORKAROUND && !NO_W32TIMES_IZFIX) */
+
+
+#if (defined(NT_TZBUG_WORKAROUND) && defined(W32_STAT_BANDAID))
+
+local int VFatFileTime2utime(const FILETIME *pft, time_t *ut)
+{
+ FILETIME lft;
+ SYSTEMTIME w32tm;
+ struct tm ltm;
+
+ if (!FileTimeToLocalFileTime(pft, &lft)) {
+ /* if pft cannot be converted to local time, return current time */
+ return time(NULL);
+ }
+ FileTimeToSystemTime(&lft, &w32tm);
+ /* underflow and overflow handling */
+ /* TODO: The range checks are not accurate, the actual limits may
+ * be off by one daylight-saving-time shift (typically 1 hour),
+ * depending on the current state of "is_dst".
+ */
+#ifdef CHECK_UTIME_SIGNED_UNSIGNED
+ if ((time_t)0x80000000L < (time_t)0L)
+ {
+ if ((pft->dwHighDateTime < UNIX_TIME_SMIN_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_SMIN_HI) &&
+ (pft->dwLowDateTime < UNIX_TIME_SMIN_LO))) {
+ *ut = (time_t)LONG_MIN;
+ return FALSE;
+ if ((pft->dwHighDateTime > UNIX_TIME_SMAX_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_SMAX_HI) &&
+ (pft->dwLowDateTime > UNIX_TIME_SMAX_LO))) {
+ *ut = (time_t)LONG_MAX;
+ return FALSE;
+ }
+ }
+ else
+#endif /* CHECK_UTIME_SIGNED_UNSIGNED */
+ {
+ if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) &&
+ (pft->dwLowDateTime < UNIX_TIME_ZERO_LO))) {
+ *ut = (time_t)0;
+ return FALSE;
+ }
+ if ((pft->dwHighDateTime > UNIX_TIME_UMAX_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_UMAX_HI) &&
+ (pft->dwLowDateTime > UNIX_TIME_UMAX_LO))) {
+ *ut = (time_t)ULONG_MAX;
+ return FALSE;
+ }
+ }
+ ltm.tm_year = w32tm.wYear - 1900;
+ ltm.tm_mon = w32tm.wMonth - 1;
+ ltm.tm_mday = w32tm.wDay;
+ ltm.tm_hour = w32tm.wHour;
+ ltm.tm_min = w32tm.wMinute;
+ ltm.tm_sec = w32tm.wSecond;
+ ltm.tm_isdst = -1; /* let mktime determine if DST is in effect */
+ *ut = mktime(&ltm);
+
+ /* a cheap error check: mktime returns "(time_t)-1L" on conversion errors.
+ * Normally, we would have to apply a consistency check because "-1"
+ * could also be a valid time. But, it is quite unlikely to read back odd
+ * time numbers from file systems that store time stamps in DOS format.
+ * (The only known exception is creation time on VFAT partitions.)
+ */
+ return (*ut != (time_t)-1L);
+
+} /* end function VFatFileTime2utime() */
+#endif /* NT_TZBUG_WORKAROUND && W32_STAT_BANDAID */
+
+
+#if 0 /* Currently, this is not used at all */
+
+long GetTheFileTime(const char *name, iztimes *z_ut)
+{
+ HANDLE h;
+ FILETIME Modft, Accft, Creft, lft;
+ WORD dh, dl;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(name) + 1);
+
+ OemToAnsi(name, ansi_name);
+ name = ansi_name;
+#endif
+
+ h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if ( h != INVALID_HANDLE_VALUE ) {
+ BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
+ CloseHandle(h);
+#ifdef USE_EF_UT_TIME
+ if (ftOK && (z_ut != NULL)) {
+ NtfsFileTime2utime(&Modft, &(z_ut->mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ NtfsFileTime2utime(&Accft, &(z_ut->atime));
+ else
+ z_ut->atime = z_ut->mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ NtfsFileTime2utime(&Creft, &(z_ut->ctime));
+ else
+ z_ut->ctime = z_ut->mtime;
+ }
+#endif
+ FileTimeToLocalFileTime(&ft, &lft);
+ FileTimeToDosDateTime(&lft, &dh, &dl);
+ return(dh<<16) | dl;
+ }
+ else
+ return 0L;
+}
+
+#endif /* never */
+
+
+void ChangeNameForFAT(char *name)
+{
+ char *src, *dst, *next, *ptr, *dot, *start;
+ static char invalid[] = ":;,=+\"[]<>| \t";
+
+ if ( isalpha((uch)name[0]) && (name[1] == ':') )
+ start = name + 2;
+ else
+ start = name;
+
+ src = dst = start;
+ if ( (*src == '/') || (*src == '\\') )
+ src++, dst++;
+
+ while ( *src )
+ {
+ for ( next = src; *next && (*next != '/') && (*next != '\\'); next++ );
+
+ for ( ptr = src, dot = NULL; ptr < next; ptr++ )
+ if ( *ptr == '.' )
+ {
+ dot = ptr; /* remember last dot */
+ *ptr = '_';
+ }
+
+ if ( dot == NULL )
+ for ( ptr = src; ptr < next; ptr++ )
+ if ( *ptr == '_' )
+ dot = ptr; /* remember last _ as if it were a dot */
+
+ if ( dot && (dot > src) &&
+ ((next - dot <= 4) ||
+ ((next - src > 8) && (dot - src > 3))) )
+ {
+ if ( dot )
+ *dot = '.';
+
+ for ( ptr = src; (ptr < dot) && ((ptr - src) < 8); ptr++ )
+ *dst++ = *ptr;
+
+ for ( ptr = dot; (ptr < next) && ((ptr - dot) < 4); ptr++ )
+ *dst++ = *ptr;
+ }
+ else
+ {
+ if ( dot && (next - src == 1) )
+ *dot = '.'; /* special case: "." as a path component */
+
+ for ( ptr = src; (ptr < next) && ((ptr - src) < 8); ptr++ )
+ *dst++ = *ptr;
+ }
+
+ *dst++ = *next; /* either '/' or 0 */
+
+ if ( *next )
+ {
+ src = next + 1;
+
+ if ( *src == 0 ) /* handle trailing '/' on dirs ! */
+ *dst = 0;
+ }
+ else
+ break;
+ }
+
+ for ( src = start; *src != 0; ++src )
+ if ( (strchr(invalid, *src) != NULL) || (*src == ' ') )
+ *src = '_';
+}
+
+char *GetLongPathEA(const char *name)
+{
+ return(NULL); /* volunteers ? */
+}
+
+int IsFileNameValid(x)
+const char *x;
+{
+ WIN32_FIND_DATA fd;
+ HANDLE h;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(x) + 1);
+
+ OemToAnsi(x, ansi_name);
+ x = (const char *)ansi_name;
+#endif
+
+ if ((h = FindFirstFile(x, &fd)) == INVALID_HANDLE_VALUE)
+ return FALSE;
+ FindClose(h);
+ return TRUE;
+}
+
+char *getVolumeLabel(drive, vtime, vmode, vutim)
+ int drive; /* drive name: 'A' .. 'Z' or '\0' for current drive */
+ ulg *vtime; /* volume label creation time (DOS format) */
+ ulg *vmode; /* volume label file mode */
+ time_t *vutim;/* volume label creationtime (UNIX format) */
+
+/* If a volume label exists for the given drive, return its name and
+ pretend to set its time and mode. The returned name is static data. */
+{
+ char rootpath[4];
+ static char vol[14];
+ DWORD fnlen, flags;
+
+ *vmode = A_ARCHIVE | A_LABEL; /* this is what msdos returns */
+ *vtime = dostime(1980, 1, 1, 0, 0, 0); /* no true date info available */
+ *vutim = dos2unixtime(*vtime);
+ strcpy(rootpath, "x:\\");
+ rootpath[0] = (char)drive;
+ if (GetVolumeInformation(drive ? rootpath : NULL, vol, 13, NULL,
+ &fnlen, &flags, NULL, 0))
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ return (AnsiToOem(vol, vol), vol);
+#else
+ return vol;
+#endif
+ else
+ return NULL;
+}
+
+#endif /* !UTIL */
+
+
+
+int ZipIsWinNT(void) /* returns TRUE if real NT, FALSE if Win95 or Win32s */
+{
+ static DWORD g_PlatformId = 0xFFFFFFFF; /* saved platform indicator */
+
+ if (g_PlatformId == 0xFFFFFFFF) {
+ /* note: GetVersionEx() doesn't exist on WinNT 3.1 */
+ if (GetVersion() < 0x80000000)
+ g_PlatformId = TRUE;
+ else
+ g_PlatformId = FALSE;
+ }
+ return (int)g_PlatformId;
+}
+
+
+#ifndef UTIL
+#ifdef __WATCOMC__
+# include <io.h>
+# define _get_osfhandle _os_handle
+/* gaah -- Watcom's docs claim that _get_osfhandle exists, but it doesn't. */
+#endif
+
+#ifdef HAVE_FSEEKABLE
+/*
+ * return TRUE if file is seekable
+ */
+int fseekable(fp)
+FILE *fp;
+{
+ return GetFileType((HANDLE)_get_osfhandle(fileno(fp))) == FILE_TYPE_DISK;
+}
+#endif /* HAVE_FSEEKABLE */
+#endif /* !UTIL */
+
+
+#if 0 /* seems to be never used; try it out... */
+char *StringLower(char *szArg)
+{
+ char *szPtr;
+/* unsigned char *szPtr; */
+ for ( szPtr = szArg; *szPtr; szPtr++ )
+ *szPtr = lower[*szPtr];
+ return szArg;
+}
+#endif /* never */
+
+
+
+#ifdef W32_STAT_BANDAID
+
+/* All currently known variants of WIN32 operating systems (Windows 95/98,
+ * WinNT 3.x, 4.0, 5.x) have a nasty bug in the OS kernel concerning
+ * conversions between UTC and local time: In the time conversion functions
+ * of the Win32 API, the timezone offset (including seasonal daylight saving
+ * shift) between UTC and local time evaluation is erratically based on the
+ * current system time. The correct evaluation must determine the offset
+ * value as it {was/is/will be} for the actual time to be converted.
+ *
+ * Newer versions of MS C runtime lib's stat() returns utc time-stamps so
+ * that localtime(timestamp) corresponds to the (potentially false) local
+ * time shown by the OS' system programs (Explorer, command shell dir, etc.)
+ * The RSXNT port follows the same strategy, but fails to recognize the
+ * access-time attribute.
+ *
+ * For the NTFS file system (and other filesystems that store time-stamps
+ * as UTC values), this results in st_mtime (, st_{c|a}time) fields which
+ * are not stable but vary according to the seasonal change of "daylight
+ * saving time in effect / not in effect".
+ *
+ * Other C runtime libs (CygWin, or the crtdll.dll supplied with Win9x/NT
+ * return the unix-time equivalent of the UTC FILETIME values as got back
+ * from the Win32 API call. This time, return values from NTFS are correct
+ * whereas utimes from files on (V)FAT volumes vary according to the DST
+ * switches.
+ *
+ * To achieve timestamp consistency of UTC (UT extra field) values in
+ * Zip archives, the Info-ZIP programs require work-around code for
+ * proper time handling in stat() (and other time handling routines).
+ *
+ * However, nowadays most other programs on Windows systems use the
+ * time conversion strategy of Microsofts C runtime lib "msvcrt.dll".
+ * To improve interoperability in environments where a "consistent" (but
+ * false) "UTC<-->LocalTime" conversion is preferred over "stable" time
+ * stamps, the Info-ZIP specific time conversion handling can be
+ * deactivated by defining the preprocessor flag NO_W32TIMES_IZFIX.
+ */
+/* stat() functions under Windows95 tend to fail for root directories. *
+ * Watcom and Borland, at least, are affected by this bug. Watcom made *
+ * a partial fix for 11.0 but still missed some cases. This substitute *
+ * detects the case and fills in reasonable values. Otherwise we get *
+ * effects like failure to extract to a root dir because it's not found. */
+
+int zstat_zipwin32(const char *path, struct stat *buf)
+{
+ if (!stat(path, buf))
+ {
+#if (!defined(UTIL) && defined(NT_TZBUG_WORKAROUND))
+ /* stat was successful, now redo the time-stamp fetches */
+#ifndef NO_W32TIMES_IZFIX
+ int fs_uses_loctime = FSusesLocalTime(path);
+#endif
+ HANDLE h;
+ FILETIME Modft, Accft, Creft;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(path) + 1);
+
+ OemToAnsi(path, ansi_path);
+# define Ansi_Path ansi_path
+#else
+# define Ansi_Path path
+#endif
+
+ Trace((stdout, "stat(%s) finds modtime %08lx\n", path, buf->st_mtime));
+ h = CreateFile(Ansi_Path, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h != INVALID_HANDLE_VALUE) {
+ BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
+ CloseHandle(h);
+
+ if (ftOK) {
+#ifndef NO_W32TIMES_IZFIX
+ if (!fs_uses_loctime) {
+ /* On a filesystem that stores UTC timestamps, we refill
+ * the time fields of the struct stat buffer by directly
+ * using the UTC values as returned by the Win32
+ * GetFileTime() API call.
+ */
+ NtfsFileTime2utime(&Modft, &(buf->st_mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ NtfsFileTime2utime(&Accft, &(buf->st_atime));
+ else
+ buf->st_atime = buf->st_mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ NtfsFileTime2utime(&Creft, &(buf->st_ctime));
+ else
+ buf->st_ctime = buf->st_mtime;
+ Tracev((stdout,"NTFS, recalculated modtime %08lx\n",
+ buf->st_mtime));
+ } else
+#endif /* NO_W32TIMES_IZFIX */
+ {
+ /* On VFAT and FAT-like filesystems, the FILETIME values
+ * are converted back to the stable local time before
+ * converting them to UTC unix time-stamps.
+ */
+ VFatFileTime2utime(&Modft, &(buf->st_mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ VFatFileTime2utime(&Accft, &(buf->st_atime));
+ else
+ buf->st_atime = buf->st_mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ VFatFileTime2utime(&Creft, &(buf->st_ctime));
+ else
+ buf->st_ctime = buf->st_mtime;
+ Tracev((stdout, "VFAT, recalculated modtime %08lx\n",
+ buf->st_mtime));
+ }
+ }
+ }
+# undef Ansi_Path
+#endif /* !UTIL && NT_TZBUG_WORKAROUND */
+ return 0;
+ }
+#ifdef W32_STATROOT_FIX
+ else
+ {
+ DWORD flags;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(path) + 1);
+
+ OemToAnsi(path, ansi_path);
+# define Ansi_Path ansi_path
+#else
+# define Ansi_Path path
+#endif
+
+ flags = GetFileAttributes(Ansi_Path);
+ if (flags != 0xFFFFFFFF && flags & FILE_ATTRIBUTE_DIRECTORY) {
+ Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n",
+ path));
+ memset(buf, 0, sizeof(struct stat));
+ buf->st_atime = buf->st_ctime = buf->st_mtime =
+ dos2unixtime(DOSTIME_MINIMUM);
+ /* !!! you MUST NOT add a cast to the type of "st_mode" here;
+ * !!! different compilers do not agree on the "st_mode" size!
+ * !!! (And, some compiler may not declare the "mode_t" type
+ * !!! identifier, so you cannot use it, either.)
+ */
+ buf->st_mode = S_IFDIR | S_IREAD |
+ ((flags & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE);
+ return 0;
+ } /* assumes: stat() won't fail on non-dirs without good reason */
+# undef Ansi_Path
+ }
+#endif /* W32_STATROOT_FIX */
+ return -1;
+}
+
+#endif /* W32_STAT_BANDAID */
+
+
+
+#ifdef W32_USE_IZ_TIMEZONE
+#include "timezone.h"
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule);
+
+static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule)
+{
+ if (lpw32tm->wYear != 0) {
+ ptrule->r_type = JULIAN_DAY;
+ ptrule->r_day = ydays[lpw32tm->wMonth - 1] + lpw32tm->wDay;
+ } else {
+ ptrule->r_type = MONTH_NTH_DAY_OF_WEEK;
+ ptrule->r_mon = lpw32tm->wMonth;
+ ptrule->r_day = lpw32tm->wDayOfWeek;
+ ptrule->r_week = lpw32tm->wDay;
+ }
+ ptrule->r_time = (long)lpw32tm->wHour * SECSPERHOUR +
+ (long)(lpw32tm->wMinute * SECSPERMIN) +
+ (long)lpw32tm->wSecond;
+}
+
+int GetPlatformLocalTimezone(register struct state * ZCONST sp,
+ void (*fill_tzstate_from_rules)(struct state * ZCONST sp_res,
+ ZCONST struct rule * ZCONST start,
+ ZCONST struct rule * ZCONST end))
+{
+ TIME_ZONE_INFORMATION tzinfo;
+ DWORD res;
+
+ /* read current timezone settings from registry if TZ envvar missing */
+ res = GetTimeZoneInformation(&tzinfo);
+ if (res != TIME_ZONE_ID_INVALID)
+ {
+ struct rule startrule, stoprule;
+
+ conv_to_rule(&(tzinfo.StandardDate), &stoprule);
+ conv_to_rule(&(tzinfo.DaylightDate), &startrule);
+ sp->timecnt = 0;
+ sp->ttis[0].tt_abbrind = 0;
+ if ((sp->charcnt =
+ WideCharToMultiByte(CP_ACP, 0, tzinfo.StandardName, -1,
+ sp->chars, sizeof(sp->chars), NULL, NULL))
+ == 0)
+ sp->chars[sp->charcnt++] = '\0';
+ sp->ttis[1].tt_abbrind = sp->charcnt;
+ sp->charcnt +=
+ WideCharToMultiByte(CP_ACP, 0, tzinfo.DaylightName, -1,
+ sp->chars + sp->charcnt,
+ sizeof(sp->chars) - sp->charcnt, NULL, NULL);
+ if ((sp->charcnt - sp->ttis[1].tt_abbrind) == 0)
+ sp->chars[sp->charcnt++] = '\0';
+ sp->ttis[0].tt_gmtoff = - (tzinfo.Bias + tzinfo.StandardBias)
+ * MINSPERHOUR;
+ sp->ttis[1].tt_gmtoff = - (tzinfo.Bias + tzinfo.DaylightBias)
+ * MINSPERHOUR;
+ sp->ttis[0].tt_isdst = 0;
+ sp->ttis[1].tt_isdst = 1;
+ sp->typecnt = (startrule.r_mon == 0 && stoprule.r_mon == 0) ? 1 : 2;
+
+ if (sp->typecnt > 1)
+ (*fill_tzstate_from_rules)(sp, &startrule, &stoprule);
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif /* W32_USE_IZ_TIMEZONE */
+
+
+
+#ifndef WINDLL
+/* This replacement getch() function was originally created for Watcom C
+ * and then additionally used with CYGWIN. Since UnZip 5.4, all other Win32
+ * ports apply this replacement rather that their supplied getch() (or
+ * alike) function. There are problems with unabsorbed LF characters left
+ * over in the keyboard buffer under Win95 (and 98) when ENTER was pressed.
+ * (Under Win95, ENTER returns two(!!) characters: CR-LF.) This problem
+ * does not appear when run on a WinNT console prompt!
+ */
+
+/* Watcom 10.6's getch() does not handle Alt+<digit><digit><digit>. */
+/* Note that if PASSWD_FROM_STDIN is defined, the file containing */
+/* the password must have a carriage return after the word, not a */
+/* Unix-style newline (linefeed only). This discards linefeeds. */
+
+int getch_win32(void)
+{
+ HANDLE stin;
+ DWORD rc;
+ unsigned char buf[2];
+ int ret = -1;
+ DWORD odemode = ~(DWORD)0;
+
+# ifdef PASSWD_FROM_STDIN
+ stin = GetStdHandle(STD_INPUT_HANDLE);
+# else
+ stin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (stin == INVALID_HANDLE_VALUE)
+ return -1;
+# endif
+ if (GetConsoleMode(stin, &odemode))
+ SetConsoleMode(stin, ENABLE_PROCESSED_INPUT); /* raw except ^C noticed */
+ if (ReadFile(stin, &buf, 1, &rc, NULL) && rc == 1)
+ ret = buf[0];
+ /* when the user hits return we get CR LF. We discard the LF, not the CR,
+ * because when we call this for the first time after a previous input
+ * such as the one for "replace foo? [y]es, ..." the LF may still be in
+ * the input stream before whatever the user types at our prompt. */
+ if (ret == '\n')
+ if (ReadFile(stin, &buf, 1, &rc, NULL) && rc == 1)
+ ret = buf[0];
+ if (odemode != ~(DWORD)0)
+ SetConsoleMode(stin, odemode);
+# ifndef PASSWD_FROM_STDIN
+ CloseHandle(stin);
+# endif
+ return ret;
+}
+
+
+
+/******************************/
+/* Function version_local() */
+/******************************/
+
+void version_local()
+{
+ static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s.\n\n";
+#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__DJGPP__))
+ char buf[80];
+#if (defined(_MSC_VER) && (_MSC_VER > 900))
+ char buf2[80];
+#endif
+#endif
+
+/* Define the compiler name and version strings */
+#if defined(_MSC_VER) /* MSC == MSVC++, including the SDK compiler */
+ sprintf(buf, "Microsoft C %d.%02d ", _MSC_VER/100, _MSC_VER%100);
+# define COMPILER_NAME1 buf
+# if (_MSC_VER == 800)
+# define COMPILER_NAME2 "(Visual C++ v1.1)"
+# elif (_MSC_VER == 850)
+# define COMPILER_NAME2 "(Windows NT v3.5 SDK)"
+# elif (_MSC_VER == 900)
+# define COMPILER_NAME2 "(Visual C++ v2.x)"
+# elif (_MSC_VER > 900)
+ sprintf(buf2, "(Visual C++ v%d.%d)", _MSC_VER/100 - 6, _MSC_VER%100/10);
+# define COMPILER_NAME2 buf2
+# else
+# define COMPILER_NAME2 "(bad version)"
+# endif
+#elif defined(__WATCOMC__)
+# if (__WATCOMC__ % 10 > 0)
+/* We do this silly test because __WATCOMC__ gives two digits for the */
+/* minor version, but Watcom packaging prefers to show only one digit. */
+ sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100,
+ __WATCOMC__ % 100);
+# else
+ sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100,
+ (__WATCOMC__ % 100) / 10);
+# endif /* __WATCOMC__ % 10 > 0 */
+# define COMPILER_NAME1 buf
+# define COMPILER_NAME2 ""
+#elif defined(__TURBOC__)
+# ifdef __BORLANDC__
+# define COMPILER_NAME1 "Borland C++"
+# if (__BORLANDC__ == 0x0452) /* __BCPLUSPLUS__ = 0x0320 */
+# define COMPILER_NAME2 " 4.0 or 4.02"
+# elif (__BORLANDC__ == 0x0460) /* __BCPLUSPLUS__ = 0x0340 */
+# define COMPILER_NAME2 " 4.5"
+# elif (__BORLANDC__ == 0x0500) /* __TURBOC__ = 0x0500 */
+# define COMPILER_NAME2 " 5.0"
+# elif (__BORLANDC__ == 0x0520) /* __TURBOC__ = 0x0520 */
+# define COMPILER_NAME2 " 5.2 (C++ Builder 1.0)"
+# elif (__BORLANDC__ == 0x0530) /* __BCPLUSPLUS__ = 0x0530 */
+# define COMPILER_NAME2 " 5.3 (C++ Builder 3.0)"
+# elif (__BORLANDC__ == 0x0540) /* __BCPLUSPLUS__ = 0x0540 */
+# define COMPILER_NAME2 " 5.4 (C++ Builder 4.0)"
+# elif (__BORLANDC__ == 0x0550) /* __BCPLUSPLUS__ = 0x0550 */
+# define COMPILER_NAME2 " 5.5 (C++ Builder 5.0)"
+# elif (__BORLANDC__ == 0x0551) /* __BCPLUSPLUS__ = 0x0551 */
+# define COMPILER_NAME2 " 5.5.1 (C++ Builder 5.0.1)"
+# elif (__BORLANDC__ == 0x0560) /* __BCPLUSPLUS__ = 0x0560 */
+# define COMPILER_NAME2 " 5.6 (C++ Builder 6)"
+# else
+# define COMPILER_NAME2 " later than 5.6"
+# endif
+# else /* !__BORLANDC__ */
+# define COMPILER_NAME1 "Turbo C"
+# if (__TURBOC__ >= 0x0400) /* Kevin: 3.0 -> 0x0401 */
+# define COMPILER_NAME2 "++ 3.0 or later"
+# elif (__TURBOC__ == 0x0295) /* [661] vfy'd by Kevin */
+# define COMPILER_NAME2 "++ 1.0"
+# endif
+# endif /* __BORLANDC__ */
+#elif defined(__GNUC__)
+# ifdef __RSXNT__
+# if (defined(__DJGPP__) && !defined(__EMX__))
+ sprintf(buf, "rsxnt(djgpp v%d.%02d) / gcc ",
+ __DJGPP__, __DJGPP_MINOR__);
+# define COMPILER_NAME1 buf
+# elif defined(__DJGPP__)
+ sprintf(buf, "rsxnt(emx+djgpp v%d.%02d) / gcc ",
+ __DJGPP__, __DJGPP_MINOR__);
+# define COMPILER_NAME1 buf
+# elif (defined(__GO32__) && !defined(__EMX__))
+# define COMPILER_NAME1 "rsxnt(djgpp v1.x) / gcc "
+# elif defined(__GO32__)
+# define COMPILER_NAME1 "rsxnt(emx + djgpp v1.x) / gcc "
+# elif defined(__EMX__)
+# define COMPILER_NAME1 "rsxnt(emx)+gcc "
+# else
+# define COMPILER_NAME1 "rsxnt(unknown) / gcc "
+# endif
+# elif defined(__CYGWIN__)
+# define COMPILER_NAME1 "Cygnus win32 / gcc "
+# elif defined(__MINGW32__)
+# define COMPILER_NAME1 "mingw32 / gcc "
+# else
+# define COMPILER_NAME1 "gcc "
+# endif
+# define COMPILER_NAME2 __VERSION__
+#elif defined(__LCC__)
+# define COMPILER_NAME1 "LCC-Win32"
+# define COMPILER_NAME2 ""
+#else
+# define COMPILER_NAME1 "unknown compiler (SDK?)"
+# define COMPILER_NAME2 ""
+#endif
+
+/* Define the compile date string */
+#ifdef __DATE__
+# define COMPILE_DATE " on " __DATE__
+#else
+# define COMPILE_DATE ""
+#endif
+
+ printf(CompiledWith, COMPILER_NAME1, COMPILER_NAME2,
+ "\nWindows 9x / Windows NT/2K/XP/2K3", " (32-bit)", COMPILE_DATE);
+
+ return;
+
+} /* end function version_local() */
+#endif /* !WINDLL */
diff --git a/win32/win32zip.c b/win32/win32zip.c
new file mode 100644
index 0000000..b9d5e2d
--- /dev/null
+++ b/win32/win32zip.c
@@ -0,0 +1,782 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+#ifndef UTIL /* this file contains nothing used by UTIL */
+
+#include "../zip.h"
+
+#include <ctype.h>
+#if !defined(__EMX__) && !defined(__CYGWIN__)
+#include <direct.h> /* for rmdir() */
+#endif
+#include <time.h>
+
+#ifndef __BORLANDC__
+#include <sys/utime.h>
+#else
+#include <utime.h>
+#endif
+#include <windows.h> /* for findfirst/findnext stuff */
+#ifdef __RSXNT__
+# include "../win32/rsxntwin.h"
+#endif
+
+#include <io.h>
+
+#define PAD 0
+#define PATH_END '/'
+#define HIDD_SYS_BITS (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)
+
+
+typedef struct zdirent {
+ ush d_date, d_time;
+ ulg d_size;
+ char d_attr;
+ char d_name[MAX_PATH];
+ int d_first;
+ HANDLE d_hFindFile;
+} zDIR;
+
+#include "../win32/win32zip.h"
+#include "../win32/nt.h"
+
+/* Local functions */
+local zDIR *Opendir OF((ZCONST char *n));
+local struct zdirent *Readdir OF((zDIR *d));
+local void Closedir OF((zDIR *d));
+
+local char *readd OF((zDIR *));
+local int wild_recurse OF((char *, char *));
+#ifdef NTSD_EAS
+ local void GetSD OF((char *path, char **bufptr, size_t *size,
+ char **cbufptr, size_t *csize));
+#endif
+#ifdef USE_EF_UT_TIME
+ local int GetExtraTime OF((struct zlist far *z, iztimes *z_utim));
+#endif
+
+/* Module level variables */
+extern char *label /* = NULL */ ; /* defined in fileio.c */
+local ulg label_time = 0;
+local ulg label_mode = 0;
+local time_t label_utim = 0;
+
+/* Module level constants */
+local ZCONST char wild_match_all[] = "*.*";
+
+local zDIR *Opendir(n)
+ZCONST char *n; /* directory to open */
+/* Start searching for files in the MSDOS directory n */
+{
+ zDIR *d; /* malloc'd return value */
+ char *p; /* malloc'd temporary string */
+ char *q;
+ WIN32_FIND_DATA fd;
+
+ if ((d = (zDIR *)malloc(sizeof(zDIR))) == NULL ||
+ (p = malloc(strlen(n) + (2 + sizeof(wild_match_all)))) == NULL) {
+ if (d != NULL) free((zvoid *)d);
+ return NULL;
+ }
+ strcpy(p, n);
+ q = p + strlen(p);
+ if ((q - p) > 0 && MBSRCHR(p, ':') == (q - 1))
+ *q++ = '.';
+ if ((q - p) > 0 && MBSRCHR(p, '/') != (q - 1))
+ *q++ = '/';
+ strcpy(q, wild_match_all);
+
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ OemToAnsi(p, p);
+#endif
+ d->d_hFindFile = FindFirstFile(p, &fd);
+ free((zvoid *)p);
+
+ if (d->d_hFindFile == INVALID_HANDLE_VALUE)
+ {
+ free((zvoid *)d);
+ return NULL;
+ }
+
+ strcpy(d->d_name, fd.cFileName);
+ d->d_attr = (unsigned char) fd.dwFileAttributes;
+ d->d_first = 1;
+ return d;
+}
+
+local struct zdirent *Readdir(d)
+zDIR *d; /* directory stream to read from */
+/* Return pointer to first or next directory entry, or NULL if end. */
+{
+ if (d->d_first)
+ d->d_first = 0;
+ else
+ {
+ WIN32_FIND_DATA fd;
+
+ if (!FindNextFile(d->d_hFindFile, &fd))
+ return NULL;
+ strcpy(d->d_name, fd.cFileName);
+ d->d_attr = (unsigned char) fd.dwFileAttributes;
+ }
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ AnsiToOem(d->d_name, d->d_name);
+#endif
+ return (struct zdirent *)d;
+}
+
+local void Closedir(d)
+zDIR *d; /* directory stream to close */
+{
+ FindClose(d->d_hFindFile);
+ free((zvoid *)d);
+}
+
+
+local char *readd(d)
+zDIR *d; /* directory stream to read from */
+/* Return a pointer to the next name in the directory stream d, or NULL if
+ no more entries or an error occurs. */
+{
+ struct zdirent *e;
+
+ do
+ e = Readdir(d);
+ while (!hidden_files && e && e->d_attr & HIDD_SYS_BITS);
+ return e == NULL ? (char *) NULL : e->d_name;
+}
+
+
+#define ONENAMELEN 255
+
+/* whole is a pathname with wildcards, wildtail points somewhere in the */
+/* middle of it. All wildcards to be expanded must come AFTER wildtail. */
+
+local int wild_recurse(whole, wildtail)
+char *whole;
+char *wildtail;
+{
+ zDIR *dir;
+ char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2;
+ extent newlen;
+ int amatch = 0, e = ZE_MISS;
+
+ if (!isshexp(wildtail)) {
+ if (GetFileAttributes(whole) != 0xFFFFFFFF) { /* file exists? */
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ AnsiToOem(whole, whole);
+#endif
+ return procname(whole, 0);
+ }
+ else
+ return ZE_MISS; /* woops, no wildcards! */
+ }
+
+ /* back up thru path components till existing dir found */
+ do {
+ name = wildtail + strlen(wildtail) - 1;
+ for (;;)
+ if (name-- <= wildtail || *name == PATH_END) {
+ subwild = name + 1;
+ plug2 = *subwild;
+ *subwild = 0;
+ break;
+ }
+ if (glue)
+ *glue = plug;
+ glue = subwild;
+ plug = plug2;
+ dir = Opendir(whole);
+ } while (!dir && subwild > wildtail);
+ wildtail = subwild; /* skip past non-wild components */
+
+ if ((subwild = MBSCHR(wildtail + 1, PATH_END)) != NULL) {
+ /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */
+ *(subwild++) = 0; /* wildtail = one component pattern */
+ newlen = strlen(whole) + strlen(subwild) + (ONENAMELEN + 2);
+ } else
+ newlen = strlen(whole) + (ONENAMELEN + 1);
+ if (!dir || ((newwhole = malloc(newlen)) == NULL)) {
+ if (glue)
+ *glue = plug;
+ e = dir ? ZE_MEM : ZE_MISS;
+ goto ohforgetit;
+ }
+ strcpy(newwhole, whole);
+ newlen = strlen(newwhole);
+ if (glue)
+ *glue = plug; /* repair damage to whole */
+ if (!isshexp(wildtail)) {
+ e = ZE_MISS; /* non-wild name not found */
+ goto ohforgetit;
+ }
+
+ while ((name = readd(dir)) != NULL) {
+ if (strcmp(name, ".") && strcmp(name, "..") &&
+ MATCH(wildtail, name, 0)) {
+ strcpy(newwhole + newlen, name);
+ if (subwild) {
+ name = newwhole + strlen(newwhole);
+ *(name++) = PATH_END;
+ strcpy(name, subwild);
+ e = wild_recurse(newwhole, name);
+ } else
+ e = procname(newwhole, 0);
+ newwhole[newlen] = 0;
+ if (e == ZE_OK)
+ amatch = 1;
+ else if (e != ZE_MISS)
+ break;
+ }
+ }
+
+ ohforgetit:
+ if (dir) Closedir(dir);
+ if (subwild) *--subwild = PATH_END;
+ if (newwhole) free(newwhole);
+ if (e == ZE_MISS && amatch)
+ e = ZE_OK;
+ return e;
+}
+
+int wild(w)
+char *w; /* path/pattern to match */
+/* If not in exclude mode, expand the pattern based on the contents of the
+ file system. Return an error code in the ZE_ class. */
+{
+ char *p; /* path */
+ char *q; /* diskless path */
+ int e; /* result */
+
+ if (volume_label == 1) {
+ volume_label = 2;
+ label = getVolumeLabel((w != NULL && isascii((uch)w[0]) && w[1] == ':')
+ ? to_up(w[0]) : '\0',
+ &label_time, &label_mode, &label_utim);
+ if (label != NULL)
+ (void)newname(label, 0, 0);
+ if (w == NULL || (isascii((uch)w[0]) && w[1] == ':' && w[2] == '\0'))
+ return ZE_OK;
+ /* "zip -$ foo a:" can be used to force drive name */
+ }
+ /* special handling of stdin request */
+ if (strcmp(w, "-") == 0) /* if compressing stdin */
+ return newname(w, 0, 0);
+
+ /* Allocate and copy pattern, leaving room to add "." if needed */
+ if ((p = malloc(strlen(w) + 2)) == NULL)
+ return ZE_MEM;
+ strcpy(p, w);
+
+ /* Normalize path delimiter as '/' */
+ for (q = p; *q; INCSTR(q)) /* use / consistently */
+ if (*q == '\\')
+ *q = '/';
+
+ /* Separate the disk part of the path */
+ if ((q = MBSCHR(p, ':')) != NULL) {
+ if (MBSCHR(++q, ':')) /* sanity check for safety of wild_recurse */
+ return ZE_MISS;
+ } else
+ q = p;
+
+ /* Normalize bare disk names */
+ if (q > p && !*q)
+ strcpy(q, ".");
+
+ /* Here we go */
+ e = wild_recurse(p, q);
+ free((zvoid *)p);
+ return e;
+}
+
+int procname(n, caseflag)
+char *n; /* name to process */
+int caseflag; /* true to force case-sensitive match */
+/* Process a name or sh expression to operate on (or exclude). Return
+ an error code in the ZE_ class. */
+{
+ char *a; /* path and name for recursion */
+ zDIR *d; /* directory stream from opendir() */
+ char *e; /* pointer to name from readd() */
+ int m; /* matched flag */
+ char *p; /* path for recursion */
+ struct stat s; /* result of stat() */
+ struct zlist far *z; /* steps through zfiles list */
+
+ if (strcmp(n, "-") == 0) /* if compressing stdin */
+ return newname(n, 0, caseflag);
+ else if (LSSTAT(n, &s)
+#ifdef __TURBOC__
+ /* For this compiler, stat() succeeds on wild card names! */
+ /* Unfortunately, this causes failure on names containing */
+ /* square bracket characters, which are legal in win32. */
+ || isshexp(n)
+#endif
+ )
+ {
+ /* Not a file or directory--search for shell expression in zip file */
+ p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */
+ m = 1;
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (MATCH(p, z->iname, caseflag))
+ {
+ z->mark = pcount ? filter(z->zname, caseflag) : 1;
+ if (verbose)
+ fprintf(mesg, "zip diagnostic: %scluding %s\n",
+ z->mark ? "in" : "ex", z->name);
+ m = 0;
+ }
+ }
+ free((zvoid *)p);
+ return m ? ZE_MISS : ZE_OK;
+ }
+
+ /* Live name--use if file, recurse if directory */
+ for (p = n; *p; INCSTR(p)) /* use / consistently */
+ if (*p == '\\')
+ *p = '/';
+ if ((s.st_mode & S_IFDIR) == 0)
+ {
+ /* add or remove name of file */
+ if ((m = newname(n, 0, caseflag)) != ZE_OK)
+ return m;
+ } else {
+ /* Add trailing / to the directory name */
+ if ((p = malloc(strlen(n)+2)) == NULL)
+ return ZE_MEM;
+ if (strcmp(n, ".") == 0 || strcmp(n, "/.") == 0) {
+ *p = '\0'; /* avoid "./" prefix and do not create zip entry */
+ } else {
+ strcpy(p, n);
+ a = p + strlen(p);
+ if (lastchar(p) != '/')
+ strcpy(a, "/");
+ if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) {
+ free((zvoid *)p);
+ return m;
+ }
+ }
+ /* recurse into directory */
+ if (recurse && (d = Opendir(n)) != NULL)
+ {
+ while ((e = readd(d)) != NULL) {
+ if (strcmp(e, ".") && strcmp(e, ".."))
+ {
+ if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
+ {
+ Closedir(d);
+ free((zvoid *)p);
+ return ZE_MEM;
+ }
+ strcat(strcpy(a, p), e);
+ if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */
+ {
+ if (m == ZE_MISS)
+ zipwarn("name not matched: ", a);
+ else
+ ziperr(m, a);
+ }
+ free((zvoid *)a);
+ }
+ }
+ Closedir(d);
+ }
+ free((zvoid *)p);
+ } /* (s.st_mode & S_IFDIR) == 0) */
+ return ZE_OK;
+}
+
+char *ex2in(x, isdir, pdosflag)
+char *x; /* external file name */
+int isdir; /* input: x is a directory */
+int *pdosflag; /* output: force MSDOS file attributes? */
+/* Convert the external file name to a zip file name, returning the malloc'ed
+ string or NULL if not enough memory. */
+{
+ char *n; /* internal file name (malloc'ed) */
+ char *t; /* shortened name */
+ int dosflag;
+
+
+ dosflag = dosify || IsFileSystemOldFAT(x);
+ if (!dosify && use_longname_ea && (t = GetLongPathEA(x)) != NULL)
+ {
+ x = t;
+ dosflag = 0;
+ }
+
+ /* Find starting point in name before doing malloc */
+ /* Strip drive specification */
+ t = *x && isascii((uch)*x) && *(x + 1) == ':' ? x + 2 : x;
+ /* Strip "//host/share/" part of a UNC name */
+ if ((!strncmp(x,"//",2) || !strncmp(x,"\\\\",2)) &&
+ (x[2] != '\0' && x[2] != '/' && x[2] != '\\')) {
+ n = x + 2;
+ while (*n != '\0' && *n != '/' && *n != '\\')
+ INCSTR(n); /* strip host name */
+ if (*n != '\0') {
+ INCSTR(n);
+ while (*n != '\0' && *n != '/' && *n != '\\')
+ INCSTR(n); /* strip `share' name */
+ }
+ if (*n != '\0')
+ t = n + CLEN(n);
+ }
+ /* Strip leading "/" to convert an absolute path into a relative path */
+ while (*t == '/' || *t == '\\')
+ t++;
+ /* Strip leading "./" as well as drive letter */
+ while (*t == '.' && (t[1] == '/' || t[1] == '\\'))
+ t += 2;
+
+ /* Make changes, if any, to the copied name (leave original intact) */
+ for (n = t; *n; INCSTR(n))
+ if (*n == '\\')
+ *n = '/';
+
+ if (!pathput)
+ t = last(t, PATH_END);
+
+ /* Malloc space for internal name and copy it */
+ if ((n = malloc(strlen(t) + 1)) == NULL)
+ return NULL;
+ strcpy(n, t);
+
+ if (dosify)
+ msname(n);
+
+ /* Returned malloc'ed name */
+ if (pdosflag)
+ *pdosflag = dosflag;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ OemToAnsi(n, n);
+#endif
+ return n;
+}
+
+
+char *in2ex(n)
+char *n; /* internal file name */
+/* Convert the zip file name to an external file name, returning the malloc'ed
+ string or NULL if not enough memory. */
+{
+ char *x; /* external file name */
+
+ if ((x = malloc(strlen(n) + 1 + PAD)) == NULL)
+ return NULL;
+ strcpy(x, n);
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ AnsiToOem(x, x);
+#endif
+ return x;
+}
+
+
+void stamp(f, d)
+char *f; /* name of file to change */
+ulg d; /* dos-style time to change it to */
+/* Set last updated and accessed time of file f to the DOS time d. */
+{
+#if defined(__TURBOC__) && !defined(__BORLANDC__)
+ int h; /* file handle */
+
+ if ((h = open(f, 0)) != -1)
+ {
+ setftime(h, (struct ftime *)&d);
+ close(h);
+ }
+#else /* !__TURBOC__ */
+
+ struct utimbuf u; /* argument for utime() */
+
+ /* Convert DOS time to time_t format in u.actime and u.modtime */
+ u.actime = u.modtime = dos2unixtime(d);
+
+ /* Set updated and accessed times of f */
+ utime(f, &u);
+#endif /* ?__TURBOC__ */
+}
+
+
+ulg filetime(f, a, n, t)
+char *f; /* name of file to get info on */
+ulg *a; /* return value: file attributes */
+long *n; /* return value: file size */
+iztimes *t; /* return value: access, modific. and creation times */
+/* If file *f does not exist, return 0. Else, return the file's last
+ modified date and time as an MSDOS date and time. The date and
+ time is returned in a long with the date most significant to allow
+ unsigned integer comparison of absolute times. Also, if a is not
+ a NULL pointer, store the file attributes there, with the high two
+ bytes being the Unix attributes, and the low byte being a mapping
+ of that to DOS attributes. If n is not NULL, store the file size
+ there. If t is not NULL, the file's access, modification and creation
+ times are stored there as UNIX time_t values.
+ If f is "-", use standard input as the file. If f is a device, return
+ a file size of -1 */
+{
+ struct stat s; /* results of stat() */
+ char *name;
+ unsigned int len = strlen(f);
+ int isstdin = !strcmp(f, "-");
+
+ if (f == label) {
+ if (a != NULL)
+ *a = label_mode;
+ if (n != NULL)
+ *n = -2L; /* convention for a label name */
+ if (t != NULL)
+ t->atime = t->mtime = t->ctime = label_utim;
+ return label_time;
+ }
+
+ if ((name = malloc(len + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "filetime");
+ }
+ strcpy(name, f);
+ if (MBSRCHR(name, '/') == (name + len - 1))
+ name[len - 1] = '\0';
+ /* not all systems allow stat'ing a file with / appended */
+
+ if (isstdin) {
+ if (fstat(fileno(stdin), &s) != 0) {
+ free(name);
+ error("fstat(stdin)");
+ }
+ time((time_t *)&s.st_mtime); /* some fstat()s return time zero */
+ } else if (LSSTAT(name, &s) != 0) {
+ /* Accept about any file kind including directories
+ * (stored with trailing / with -r option)
+ */
+ free(name);
+ return 0;
+ }
+
+ if (a != NULL) {
+ *a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileMode(name));
+ }
+ if (n != NULL)
+ *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L;
+ if (t != NULL) {
+ t->atime = s.st_atime;
+ t->mtime = s.st_mtime;
+ t->ctime = s.st_ctime;
+ }
+
+ free(name);
+
+ return unix2dostime((time_t *)&s.st_mtime);
+}
+
+
+#ifdef NTSD_EAS
+
+local void GetSD(char *path, char **bufptr, size_t *size,
+ char **cbufptr, size_t *csize)
+{
+ unsigned char stackbuffer[NTSD_BUFFERSIZE];
+ unsigned long bytes = NTSD_BUFFERSIZE;
+ unsigned char *buffer = stackbuffer;
+ unsigned char *DynBuffer = NULL;
+ long cbytes;
+ PEF_NTSD_L_HEADER pLocalHeader;
+ PEF_NTSD_C_HEADER pCentralHeader;
+ VOLUMECAPS VolumeCaps;
+
+ /* check target volume capabilities */
+ if (!ZipGetVolumeCaps(path, path, &VolumeCaps) ||
+ !(VolumeCaps.dwFileSystemFlags & FS_PERSISTENT_ACLS)) {
+ return;
+ }
+
+ VolumeCaps.bUsePrivileges = use_privileges;
+ VolumeCaps.dwFileAttributes = 0;
+ /* should set to file attributes, if possible */
+
+ if (!SecurityGet(path, &VolumeCaps, buffer, (LPDWORD)&bytes)) {
+
+ /* try to malloc the buffer if appropriate */
+ if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ DynBuffer = malloc(bytes);
+ if(DynBuffer == NULL) return;
+
+ buffer = DynBuffer; /* switch to the new buffer and try again */
+
+ if(!SecurityGet(path, &VolumeCaps, buffer, (LPDWORD)&bytes)) {
+ free(DynBuffer);
+ return;
+ }
+
+ } else {
+ return; /* bail */
+ }
+ }
+
+ /* # bytes to compress: compress type, CRC, data bytes */
+ cbytes = (2 + 4 + EB_DEFLAT_EXTRA) + bytes;
+
+
+ /* our two possible failure points. don't allow trashing of any data
+ if either fails - notice that *size and *csize don't get updated.
+ *bufptr leaks if malloc() was used and *cbufptr alloc fails - this
+ isn't relevant because it's probably indicative of a bigger problem. */
+
+ if(*size)
+ *bufptr = realloc(*bufptr, *size + EF_NTSD_L_LEN + cbytes);
+ else
+ *bufptr = malloc(EF_NTSD_L_LEN + cbytes);
+
+ if(*csize)
+ *cbufptr = realloc(*cbufptr, *csize + EF_NTSD_C_LEN);
+ else
+ *cbufptr = malloc(EF_NTSD_C_LEN);
+
+ if(*bufptr == NULL || *cbufptr == NULL) {
+ if(DynBuffer) free(DynBuffer);
+ return;
+ }
+
+ /* local header */
+
+ pLocalHeader = (PEF_NTSD_L_HEADER) (*bufptr + *size);
+
+ cbytes = memcompress(((char *)pLocalHeader + EF_NTSD_L_LEN), cbytes,
+ (char *)buffer, bytes);
+
+ *size += EF_NTSD_L_LEN + cbytes;
+
+ pLocalHeader->nID = EF_NTSD;
+ pLocalHeader->nSize = (USHORT)(EF_NTSD_L_LEN - EB_HEADSIZE
+ + cbytes);
+ pLocalHeader->lSize = bytes; /* uncompressed size */
+ pLocalHeader->Version = 0;
+
+ /* central header */
+
+ pCentralHeader = (PEF_NTSD_C_HEADER) (*cbufptr + *csize);
+ *csize += EF_NTSD_C_LEN;
+
+ pCentralHeader->nID = EF_NTSD;
+ pCentralHeader->nSize = EF_NTSD_C_LEN - EB_HEADSIZE; /* sbz */
+ pCentralHeader->lSize = bytes;
+
+ if (noisy)
+ printf(" (%ld bytes security)", bytes);
+
+ if(DynBuffer) free(DynBuffer);
+}
+#endif /* NTSD_EAS */
+
+
+#ifdef USE_EF_UT_TIME
+
+#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(3))
+#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1))
+
+local int GetExtraTime(struct zlist far *z, iztimes *z_utim)
+{
+ char *eb_l_ptr;
+ char *eb_c_ptr;
+ ulg ultime;
+ /* brain-dead IBM compiler defines time_t as "double", so we have to convert
+ * it into unsigned long integer number...
+ */
+
+#ifdef IZ_CHECK_TZ
+ if (!zp_tz_is_valid) return ZE_OK; /* skip silently if no valid TZ info */
+#endif
+
+ if(z->ext)
+ eb_l_ptr = realloc(z->extra, (z->ext + EB_L_UT_SIZE));
+ else
+ eb_l_ptr = malloc(EB_L_UT_SIZE);
+
+ if (eb_l_ptr == NULL)
+ return ZE_MEM;
+
+ if(z->cext)
+ eb_c_ptr = realloc(z->cextra, (z->cext + EB_C_UT_SIZE));
+ else
+ eb_c_ptr = malloc(EB_C_UT_SIZE);
+
+ if (eb_c_ptr == NULL)
+ return ZE_MEM;
+
+ z->extra = eb_l_ptr;
+ eb_l_ptr += z->ext;
+ z->ext += EB_L_UT_SIZE;
+
+ eb_l_ptr[0] = 'U';
+ eb_l_ptr[1] = 'T';
+ eb_l_ptr[2] = EB_UT_LEN(3); /* length of data part of e.f. */
+ eb_l_ptr[3] = 0;
+ eb_l_ptr[4] = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME;
+ ultime = (ulg)z_utim->mtime;
+ eb_l_ptr[5] = (char)(ultime);
+ eb_l_ptr[6] = (char)(ultime >> 8);
+ eb_l_ptr[7] = (char)(ultime >> 16);
+ eb_l_ptr[8] = (char)(ultime >> 24);
+ ultime = (ulg)z_utim->atime;
+ eb_l_ptr[9] = (char)(ultime);
+ eb_l_ptr[10] = (char)(ultime >> 8);
+ eb_l_ptr[11] = (char)(ultime >> 16);
+ eb_l_ptr[12] = (char)(ultime >> 24);
+ ultime = (ulg)z_utim->ctime;
+ eb_l_ptr[13] = (char)(ultime);
+ eb_l_ptr[14] = (char)(ultime >> 8);
+ eb_l_ptr[15] = (char)(ultime >> 16);
+ eb_l_ptr[16] = (char)(ultime >> 24);
+
+ z->cextra = eb_c_ptr;
+ eb_c_ptr += z->cext;
+ z->cext += EB_C_UT_SIZE;
+
+ memcpy(eb_c_ptr, eb_l_ptr, EB_C_UT_SIZE);
+ eb_c_ptr[EB_LEN] = EB_UT_LEN(1);
+
+ return ZE_OK;
+}
+
+#endif /* USE_EF_UT_TIME */
+
+
+
+int set_extra_field(z, z_utim)
+ struct zlist far *z;
+ iztimes *z_utim;
+ /* create extra field and change z->att if desired */
+{
+
+#ifdef NTSD_EAS
+ if(ZipIsWinNT()) {
+ /* store SECURITY_DECRIPTOR data in local header,
+ and size only in central headers */
+ GetSD(z->name, &z->extra, &z->ext, &z->cextra, &z->cext);
+ }
+#endif /* NTSD_EAS */
+
+#ifdef USE_EF_UT_TIME
+ /* store extended time stamps in both headers */
+ return GetExtraTime(z, z_utim);
+#else /* !USE_EF_UT_TIME */
+ return ZE_OK;
+#endif /* ?USE_EF_UT_TIME */
+}
+
+int deletedir(d)
+char *d; /* directory to delete */
+/* Delete the directory *d if it is empty, do nothing otherwise.
+ Return the result of rmdir(), delete(), or system().
+ For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]).
+ */
+{
+ return rmdir(d);
+}
+
+#endif /* !UTIL */
diff --git a/win32/win32zip.h b/win32/win32zip.h
new file mode 100644
index 0000000..8ecb74c
--- /dev/null
+++ b/win32/win32zip.h
@@ -0,0 +1,33 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+#ifndef _WIN32ZIP_H
+#define _WIN32ZIP_H
+
+/*
+ * NT specific functions for ZIP.
+ */
+
+int GetFileMode(const char *name);
+#if 0 /* never used */
+long GetTheFileTime(const char *name, iztimes *z_times);
+#endif
+
+int IsFileNameValid(const char *name);
+int IsFileSystemOldFAT(const char *dir);
+void ChangeNameForFAT(char *name);
+
+char *getVolumeLabel(int drive, ulg *vtime, ulg *vmode, time_t *vutim);
+
+#if 0 /* never used ?? */
+char *StringLower(char *);
+#endif
+
+char *GetLongPathEA(const char *name);
+
+#endif /* _WIN32ZIP_H */
diff --git a/win32/zip.def b/win32/zip.def
new file mode 100644
index 0000000..105e4b9
--- /dev/null
+++ b/win32/zip.def
@@ -0,0 +1,4 @@
+;module-definition file for Windows Zip DLL -- used by link.exe
+DESCRIPTION 'The world-famous zip utilities from Info-ZIP'
+
+
diff --git a/win32/zipup.h b/win32/zipup.h
new file mode 100644
index 0000000..f65c41e
--- /dev/null
+++ b/win32/zipup.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+#ifndef __CYGWIN__
+# include <share.h>
+#endif
+#ifndef O_RDONLY
+# define O_RDONLY 0
+#endif
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+#if (defined(_SH_DENYNO) && !defined(SH_DENYNO))
+# define SH_DENYNO _SH_DENYNO
+#endif
+#if (defined(SH_DENYNO) && !defined(_SH_DENYNO))
+# define _SH_DENYNO SH_DENYNO
+#endif
+#define fhow (O_RDONLY|O_BINARY)
+#define fbad (-1)
+typedef int ftype;
+#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__EMX__)
+# define zopen(n,p) sopen(n,p,SH_DENYNO)
+#elif defined(__CYGWIN__) || defined(__IBMC__)
+# define zopen(n,p) open(n,p)
+#else
+# define zopen(n,p) _sopen(n,p,_SH_DENYNO)
+#endif
+#define zread(f,b,n) read(f,b,n)
+#define zclose(f) close(f)
+#define zerr(f) (k == (extent)(-1L))
+#define zstdin 0