summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorLorry <lorry@roadtrain.codethink.co.uk>2012-07-20 19:30:57 +0100
committerLorry <lorry@roadtrain.codethink.co.uk>2012-07-20 19:30:57 +0100
commit04664087ad66f5614f82a2cfba3ae4eda15e792b (patch)
tree332090b15fd2db1b93abf40dccf06211d9aba297 /win32
downloadzip-04664087ad66f5614f82a2cfba3ae4eda15e792b.tar.gz
Tarball conversion
Diffstat (limited to 'win32')
-rw-r--r--win32/README.NT17
-rw-r--r--win32/README.TZ7
-rw-r--r--win32/README.txt10
-rw-r--r--win32/crc_i386.asm330
-rw-r--r--win32/crc_i386.c310
-rw-r--r--win32/crc_lcc.asm166
-rw-r--r--win32/gvmat64.asm513
-rw-r--r--win32/lm32_lcc.asm174
-rw-r--r--win32/makefile.a64134
-rw-r--r--win32/makefile.bor189
-rw-r--r--win32/makefile.dj112
-rw-r--r--win32/makefile.emx304
-rw-r--r--win32/makefile.gcc159
-rw-r--r--win32/makefile.ibm123
-rw-r--r--win32/makefile.lcc125
-rw-r--r--win32/makefile.w10197
-rw-r--r--win32/makefile.w32224
-rw-r--r--win32/makefile.wat197
-rw-r--r--win32/makenoas.w32219
-rw-r--r--win32/match32.asm192
-rw-r--r--win32/nt.c492
-rw-r--r--win32/nt.h75
-rw-r--r--win32/osdep.h617
-rw-r--r--win32/readme.a6442
-rw-r--r--win32/rsxntwin.h173
-rw-r--r--win32/vc6/ReadmeVC.txt10
-rw-r--r--win32/vc6/zip.dsp337
-rw-r--r--win32/vc6/zip.dsw65
-rw-r--r--win32/vc6/zipcloak.dsp264
-rw-r--r--win32/vc6/zipnote.dsp248
-rw-r--r--win32/vc6/zipsplit.dsp248
-rw-r--r--win32/vc6bz2/ReadVCBZ.txt19
-rw-r--r--win32/vc6bz2/zip.dsp381
-rw-r--r--win32/vc6bz2/zip.dsw65
-rw-r--r--win32/win32.c1488
-rw-r--r--win32/win32i64.c115
-rw-r--r--win32/win32zip.c1980
-rw-r--r--win32/win32zip.h42
-rw-r--r--win32/zip.def4
-rw-r--r--win32/zip.rc53
-rw-r--r--win32/zipup.h48
41 files changed, 10468 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/README.txt b/win32/README.txt
new file mode 100644
index 0000000..4d56445
--- /dev/null
+++ b/win32/README.txt
@@ -0,0 +1,10 @@
+Win32/README.txt
+27 June 2008
+
+The resource files zip.rc and windll.rc must not get edited and saved from
+MS Visual Studio. MS VS automatically re-adds its specific MFC-related resource
+infrastructure to the "xx.rc" files when saved after any modification. The
+dependancies on MFC related headers break the compilation process, when you
+try to use the freely available MS Visual Studio Express Editions (2005 or 2008)
+for building Zip. And, most third-party compilers also lack support for the
+propietary MFC environment.
diff --git a/win32/crc_i386.asm b/win32/crc_i386.asm
new file mode 100644
index 0000000..19998ff
--- /dev/null
+++ b/win32/crc_i386.asm
@@ -0,0 +1,330 @@
+;===========================================================================
+; Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2000-Apr-09 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. Last revised 07 Jan 2007.
+;
+; 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.)
+;
+; Revised 03-Jan-2006, Chr. Spieler
+; Enlarged unrolling loops to "do 16 bytes per turn"; optimized access to
+; data buffer in loop body (adjust pointer only once in loop body and use
+; offsets to access each item); added additional support for the "unfolded
+; tables" optimization variant (enabled by IZ_CRCOPTIM_UNFOLDTBL).
+;
+; Revised 07-Jan-2007, Chr. Spieler
+; Recognize additional conditional flag CRC_TABLE_ONLY that prevents
+; compilation of the crc32() function.
+;
+; 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,
+; or only the precomputed CRC_32_Table is needed.
+;
+ IFNDEF USE_ZLIB
+ IFNDEF CRC_TABLE_ONLY
+;
+ .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
+Do_CRC_byteof MACRO ofs
+ xor al, byte ptr [esi+ofs] ; c ^= *(buf+ofs)
+ Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
+ ENDM
+ IFNDEF NO_32_BIT_LOADS
+ IFDEF IZ_CRCOPTIM_UNFOLDTBL
+ ; the edx register is needed in crc calculation
+ SavLen EQU Arg3
+
+UpdCRC_dword MACRO
+ movzx ebx,al ; tmp = c & 0xFF
+ mov edx,[edi+ebx*4+3072] ; table[256*3+tmp]
+ movzx ebx,ah ; tmp = (c>>8) & 0xFF
+ shr eax,16 ;
+ xor edx,[edi+ebx*4+2048] ; ^ table[256*2+tmp]
+ movzx ebx,al ; tmp = (c>>16) & 0xFF
+ shr eax,8 ; tmp = (c>>24)
+ xor edx,[edi+ebx*4+1024] ; ^ table[256*1+tmp]
+ mov eax,[edi+eax*4] ; ^ table[256*0+tmp]
+ xor eax,edx ; ..
+ ENDM
+UpdCRC_dword_sh MACRO dwPtrIncr
+ movzx ebx,al ; tmp = c & 0xFF
+ mov edx,[edi+ebx*4+3072] ; table[256*3+tmp]
+ movzx ebx,ah ; tmp = (c>>8) & 0xFF
+ xor edx,[edi+ebx*4+2048] ; ^ table[256*2+tmp]
+ shr eax,16 ;
+ movzx ebx,al ; tmp = (c>>16) & 0xFF
+ add esi, 4*dwPtrIncr ; ((ulg *)buf) += dwPtrIncr
+ shr eax,8 ; tmp = (c>>24)
+ xor edx,[edi+ebx*4+1024] ; ^ table[256*1+tmp]
+ mov eax,[edi+eax*4] ; ^ table[256*0+tmp]
+ xor eax,edx ; ..
+ ENDM
+ ELSE ; IZ_CRCOPTIM_UNFOLDTBL
+ ; the edx register is not needed anywhere else
+ SavLen EQU edx
+
+UpdCRC_dword MACRO
+ Do_CRC
+ Do_CRC
+ Do_CRC
+ Do_CRC
+ ENDM
+UpdCRC_dword_sh MACRO dwPtrIncr
+ Do_CRC
+ Do_CRC
+ add esi, 4*dwPtrIncr ; ((ulg *)buf) += dwPtrIncr
+ Do_CRC
+ Do_CRC
+ ENDM
+ ENDIF ; ?IZ_CRCOPTIM_UNFOLDTBL
+Do_CRC_dword MACRO
+ xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
+ UpdCRC_dword_sh 1 ; ... ((ulg *)buf)++
+ ENDM
+Do_CRC_4dword MACRO
+ xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
+ UpdCRC_dword
+ xor eax, dword ptr [esi+4] ; c ^= *((ulg *)buf+1)
+ UpdCRC_dword
+ xor eax, dword ptr [esi+8] ; c ^= *((ulg *)buf+2)
+ UpdCRC_dword
+ xor eax, dword ptr [esi+12] ; c ^= *((ulg *)buf]+3
+ UpdCRC_dword_sh 4 ; ... ((ulg *)buf)+=4
+ 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 SavLen,ecx ; save current len for later
+ shr ecx,4 ; ecx = len / 16
+ jz No_Sixteens
+ IFNDEF NO_ALIGN
+; align loop head at start of 486 internal cache line !!
+ align 16
+ ENDIF
+Next_Sixteen:
+ IFNDEF NO_32_BIT_LOADS
+ Do_CRC_4dword
+ ELSE ; NO_32_BIT_LOADS
+ Do_CRC_byteof 0
+ Do_CRC_byteof 1
+ Do_CRC_byteof 2
+ Do_CRC_byteof 3
+ Do_CRC_byteof 4
+ Do_CRC_byteof 5
+ Do_CRC_byteof 6
+ Do_CRC_byteof 7
+ Do_CRC_byteof 8
+ Do_CRC_byteof 9
+ Do_CRC_byteof 10
+ Do_CRC_byteof 11
+ Do_CRC_byteof 12
+ Do_CRC_byteof 13
+ Do_CRC_byteof 14
+ Do_CRC_byteof 15
+ add esi, 16 ; buf += 16
+ ENDIF ; ?NO_32_BIT_LOADS
+ dec ecx
+ jnz Next_Sixteen
+No_Sixteens:
+ mov ecx,SavLen
+ and ecx,00000000FH ; ecx = len % 16
+ IFNDEF NO_32_BIT_LOADS
+ shr ecx,2 ; ecx = len / 4
+ jz SHORT No_Fours
+Next_Four:
+ Do_CRC_dword
+ dec ecx
+ jnz Next_Four
+No_Fours:
+ mov ecx,SavLen
+ and ecx,000000003H ; ecx = len % 4
+ ENDIF ; !NO_32_BIT_LOADS
+ 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++,crctab);
+ 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 ; !CRC_TABLE_ONLY
+ ENDIF ; !USE_ZLIB
+;
+end
diff --git a/win32/crc_i386.c b/win32/crc_i386.c
new file mode 100644
index 0000000..971ee66
--- /dev/null
+++ b/win32/crc_i386.c
@@ -0,0 +1,310 @@
+/*
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 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.c -- Microsoft 32-bit C/C++ adaptation of crc_i386.asm
+ * Created by Rodney Brown from crc_i386.asm, modified by Chr. Spieler.
+ * Last revised: 07-Jan-2007
+ *
+ * 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.)
+ *
+ * Revised 03-Jan-2006, Chr. Spieler
+ * Enlarged unrolling loops to "do 16 bytes per turn"; optimized access to
+ * data buffer in loop body (adjust pointer only once in loop body and use
+ * offsets to access each item); added additional support for the "unfolded
+ * tables" optimization variant (enabled by IZ_CRCOPTIM_UNFOLDTBL).
+ *
+ * Revised 07-Jan-2007, Chr. Spieler
+ * Recognize additional conditional flag CRC_TABLE_ONLY that prevents
+ * compilation of the crc32() function.
+ *
+ * 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"
+#include "../crc32.h"
+
+#if defined(ASM_CRC) && !defined(USE_ZLIB) && !defined(CRC_TABLE_ONLY)
+
+#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; }
+
+#define Do_CRC_byteof(ofs) { \
+ __asm { xor al, byte ptr [esi+(ofs)] }; \
+ Do_CRC; }
+
+#ifndef NO_32_BIT_LOADS
+#ifdef IZ_CRCOPTIM_UNFOLDTBL
+# define SavLen len /* the edx register is needed elsewhere */
+# define UpdCRC_dword { \
+ __asm { movzx ebx,al }; \
+ __asm { mov edx,[edi+ebx*4+3072] }; \
+ __asm { movzx ebx,ah }; \
+ __asm { shr eax,16 }; \
+ __asm { xor edx,[edi+ebx*4+2048] }; \
+ __asm { movzx ebx,al }; \
+ __asm { shr eax,8 }; \
+ __asm { xor edx,[edi+ebx*4+1024] }; \
+ __asm { mov eax,[edi+eax*4] }; \
+ __asm { xor eax,edx }; }
+# define UpdCRC_dword_sh(dwPtrIncr) { \
+ __asm { movzx ebx,al }; \
+ __asm { mov edx,[edi+ebx*4+3072] }; \
+ __asm { movzx ebx,ah }; \
+ __asm { xor edx,[edi+ebx*4+2048] }; \
+ __asm { shr eax,16 }; \
+ __asm { movzx ebx,al }; \
+ __asm { add esi, 4*dwPtrIncr }; \
+ __asm { shr eax,8 }; \
+ __asm { xor edx,[edi+ebx*4+1024] }; \
+ __asm { mov eax,[edi+eax*4] }; \
+ __asm { xor eax,edx }; }
+#else /* !IZ_CRCOPTIM_UNFOLDTBL */
+# define SavLen edx /* the edx register is free for use here */
+# define UpdCRC_dword { \
+ Do_CRC; \
+ Do_CRC; \
+ Do_CRC; \
+ Do_CRC; }
+# define UpdCRC_dword_sh(dwPtrIncr) { \
+ Do_CRC; \
+ Do_CRC; \
+ __asm { add esi, 4*(dwPtrIncr) }; \
+ Do_CRC; \
+ Do_CRC; }
+#endif /* ?IZ_CRCOPTIM_UNFOLDTBL */
+
+#define Do_CRC_dword { \
+ __asm { xor eax, dword ptr [esi] }; \
+ UpdCRC_dword_sh(1); }
+
+#define Do_CRC_4dword { \
+ __asm { xor eax, dword ptr [esi] }; \
+ UpdCRC_dword; \
+ __asm { xor eax, dword ptr [esi+4] }; \
+ UpdCRC_dword; \
+ __asm { xor eax, dword ptr [esi+8] }; \
+ UpdCRC_dword; \
+ __asm { xor eax, dword ptr [esi+12] }; \
+ UpdCRC_dword_sh(4); }
+#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 SavLen,ecx ;/* save current len for later */
+ shr ecx,4 ;/* ecx = len / 16 */
+ jz No_Sixteens
+; align loop head at start of 486 internal cache line !!
+ align 16
+Next_Sixteen:
+ }
+# ifndef NO_32_BIT_LOADS
+ Do_CRC_4dword ;
+# else /* NO_32_BIT_LOADS */
+ Do_CRC_byteof(0) ;
+ Do_CRC_byteof(1) ;
+ Do_CRC_byteof(2) ;
+ Do_CRC_byteof(3) ;
+ Do_CRC_byteof(4) ;
+ Do_CRC_byteof(5) ;
+ Do_CRC_byteof(6) ;
+ Do_CRC_byteof(7) ;
+ Do_CRC_byteof(8) ;
+ Do_CRC_byteof(9) ;
+ Do_CRC_byteof(10) ;
+ Do_CRC_byteof(11) ;
+ Do_CRC_byteof(12) ;
+ Do_CRC_byteof(13) ;
+ Do_CRC_byteof(14) ;
+ Do_CRC_byteof(15) ;
+ __asm { add esi,16 };
+# endif /* ?NO_32_BIT_LOADS */
+ __asm {
+ dec ecx
+ jnz Next_Sixteen
+No_Sixteens:
+ mov ecx,SavLen
+ and ecx,00000000FH ;/* ecx = len % 16 */
+# ifndef NO_32_BIT_LOADS
+ shr ecx,2
+ jz No_Fours
+Next_Four:
+ }
+ Do_CRC_dword ;
+ __asm {
+ dec ecx
+ jnz Next_Four
+No_Fours:
+ mov ecx,SavLen
+ and ecx,000000003H ;/* ecx = len % 4 */
+# endif /* !NO_32_BIT_LOADS */
+#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++,crctab);*/
+ __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 && !CRC_TABLE_ONLY */
diff --git a/win32/crc_lcc.asm b/win32/crc_lcc.asm
new file mode 100644
index 0000000..1538d32
--- /dev/null
+++ b/win32/crc_lcc.asm
@@ -0,0 +1,166 @@
+;===========================================================================
+; Copyright (c) 1990-2006 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2000-Apr-09 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_lcc.asm, optimized CRC calculation function for Zip and UnZip,
+; created by Paul Kienitz and Christian Spieler. Last revised 02 Jan 2006.
+;
+; 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 $4,%ecx
+ jz _$8
+_$7:
+ xorl (%esi),%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
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ xorl 4(%esi),%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
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ xorl 8(%esi),%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
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ xorl 12(%esi),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ addl $16,%esi
+ 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 $0x0f,%ecx
+ shrl $2,%ecx
+ jz _$10
+_$9:
+ xorl (%esi),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%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
+ decl %ecx
+ jnz _$9
+_$10:
+ movl %edx,%ecx
+ andl $0x03,%ecx
+ jz _$4
+_$11:
+ xorb (%esi),%al
+ incl %esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ decl %ecx
+ jnz _$11
+_$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..0450fe3
--- /dev/null
+++ b/win32/lm32_lcc.asm
@@ -0,0 +1,174 @@
+;===========================================================================
+; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 1999-Oct-05 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.cdrom.com/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..d2bc841
--- /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 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 crc32_.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 crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H) crc32.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) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.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) crc32.h
+ $(CC) -c $(UTILFLAGS) zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) util.c
+
+crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) crc32.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.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..10b4609
--- /dev/null
+++ b/win32/makefile.bor
@@ -0,0 +1,189 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# Borland C++ for Win32.
+# By E-Yen Tan.
+# Updated on 18 Dec 2005 by Cosmin Truta.
+# Last updated on 22 Jun 2008 by Christian Spieler.
+
+# 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
+
+# CPU type: 3 (i386), 4 (i486), 5 (Pentium), etc.
+CPU_TYP = 6
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+!IF $(USEASM)
+ASMOBJS = match32.obj
+CRCA_O = 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=ilink32
+LDFLAGS=
+
+# variables
+OBJZ1 = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj $(CRCA_O) globals.obj
+OBJZ2 = deflate.obj trees.obj $(ASMOBJS)
+OBJZS = win32zip.obj win32.obj win32i64.obj nt.obj
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS)
+
+OBJU = zipfile_.obj fileio_.obj util_.obj crc32_.obj $(CRCA_O) globals.obj \
+ win32_.obj win32i64.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.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 crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H) crc32.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) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.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
+
+win32i64.obj: win32/win32i64.c $(ZIP_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 crc32.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) crc32.h
+ $(CC) -c $(UTILFLAGS)$* zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$* fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$* util.c
+
+crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$* crc32.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.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 crc32.h
+ $(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
+
+zip.res: win32/zip.rc revision.h
+ $(RC) /l 0x409 /fo$@ /i win32 /d WIN32 win32/zip.rc
+
+# Split the command line to fit in the MS-DOS 128 byte limit by using
+# Borland-Make specific response file syntax:
+zip.exe: $(OBJZ) zip.res
+ $(LD) -Gn -x -c -ap -Tpe @&&|
+c0x32.obj $(OBJZ),$@,,import32.lib cw32.lib,,zip.res
+|
+
+zipcloak.exe: $(OBJC)
+ $(CC) $(LDFLAGS) @&&|
+$(OBJC)
+|
+
+zipnote.exe: $(OBJN)
+ $(CC) $(LDFLAGS) @&&|
+$(OBJN)
+|
+
+zipsplit.exe: $(OBJS)
+ $(CC) $(LDFLAGS) @&&|
+$(OBJS)
+|
+
+clean:
+ -del *.obj
+ -del *.res
+ -del *.exe
+ -del *.tds
diff --git a/win32/makefile.dj b/win32/makefile.dj
new file mode 100644
index 0000000..902c9ed
--- /dev/null
+++ b/win32/makefile.dj
@@ -0,0 +1,112 @@
+# 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 07 Jan 2007.
+
+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) $(CRCA_O)
+OBJZ2 = globals$(OBJ) deflate$(OBJ) trees$(OBJ) crypt$(OBJ) \
+ ttyio$(OBJ)
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS) $(OBJA)
+
+OBJU1 = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) crc32$(OBJ) globals$(OBJ)
+OBJU = $(OBJU1) $(OBJUS)
+
+OBJN = zipnote$(OBJ) $(OBJU)
+OBJS = zipsplit$(OBJ) $(OBJU)
+OBJC = zipcloak$(OBJ) crc32_$(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 crc32.h crypt.h ttyio.h
+zipfile$(OBJ): zipfile.c $(ZIP_H) crc32.h
+zipup$(OBJ): zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
+fileio$(OBJ): fileio.c $(ZIP_H) crc32.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) crc32.h
+crypt$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.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 crc32.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) crc32.h
+ $(CC) -c -I. $(CFLAGS) -DUTIL -o$@ zipfile.c
+
+fileio_$(OBJ): fileio.c $(ZIP_H) crc32.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
+
+crc32_$(OBJ): crc32.c $(ZIP_H) crc32.h
+ $(CC) -c -I. $(CFLAGS) -DUTIL -o$@ crc32.c
+
+crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.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..5f050ab
--- /dev/null
+++ b/win32/makefile.emx
@@ -0,0 +1,304 @@
+# 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 18th February 2007.
+#
+# 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" \
+ CRCA_O="crc_gcc.o" \
+ CRCAUO="crcgcc_.o" \
+ 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" \
+ CRCA_O="crc_gcc.o" \
+ CRCAUO="crcgcc_.o" \
+ 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" \
+ CRCA_O="crc_gcc.o" \
+ CRCAUO="crcgcc_.o" \
+ 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" \
+ CRCA_O="" \
+ CRCAUO="" \
+ 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" \
+ CRCA_O="crc_gcc.o" \
+ CRCAUO="crcgcc_.o" \
+ 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" \
+ CRCA_O="" \
+ CRCAUO="" \
+ 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
+CRCA_O=crc_gcc$(OBJ)
+CRCAUO=crcgcc_$(OBJ)
+OBJA=matchgcc$(OBJ)
+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) $(CRCA_O)
+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) crc32_$(OBJ) $(CRCAUO) \
+ globals$(OBJ)
+OBJUS = win32_$(OBJ)
+OBJU = $(OBJU1) $(OBJUS)
+
+OBJN = zipnote$(OBJ) $(OBJU)
+OBJS = zipsplit$(OBJ) $(OBJU)
+OBJC1 = zipcloak$(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 crc32.h crypt.h ttyio.h
+zipfile$(OBJ): zipfile.c $(ZIP_H) crc32.h
+zipup$(OBJ): zipup.c $(ZIP_H) revision.h crc32.h crypt.h $(ZIPUP_H)
+fileio$(OBJ): fileio.c $(ZIP_H) crc32.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) crc32.h
+crypt$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.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) crc32.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c
+
+fileio_$(OBJ): fileio.c $(ZIP_H) crc32.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ fileio.c
+
+util_$(OBJ): util.c $(ZIP_H)
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ util.c
+
+crc32_$(OBJ): crc32.c $(ZIP_H) crc32.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crc32.c
+
+crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.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
+
+crcgcc_$(OBJ): crc_i386.S # 32bit, GNU AS
+ $(AS) $(ASFLAGS) -DUTIL -x assembler-with-cpp -c -o $@ crc_i386.S
+
+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..d28c447
--- /dev/null
+++ b/win32/makefile.gcc
@@ -0,0 +1,159 @@
+# 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: 2008-Jun-22.
+#
+# 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
+CFLAGS=-O2 -Wall -DWIN32 -DFORCE_WIN32_OVER_UNIX
+ifndef USEZLIB
+CCFLAGS=$(CFLAGS) $(LOC)
+else
+CCFLAGS=$(CFLAGS) -DUSE_ZLIB $(LOC)
+endif
+UTILFLAGS=$(CCFLAGS) -DUTIL -o$@
+
+#AS=as
+AS=$(CC)
+ifndef USEZLIB
+ASDEFS=
+else
+ASDEFS=-DUSE_ZLIB
+endif
+ASFLAGS=-c $(ASDEFS) $(LOC)
+
+RC=windres
+
+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
+CRCA_O = crc_i386.o
+CRCAUO = crci386_.o
+OBJA = match.o $(CRCA_O)
+else
+CRCA_O =
+CRCAUO =
+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 globals.o
+OBJZ2 = deflate.o trees.o $(OBJA)
+OBJZS = win32.o win32zip.o win32i64.o nt.o
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS)
+
+OBJU1 = zipfile_.o fileio_.o util_.o crc32_.o $(CRCAUO) globals.o
+OBJUS = win32_.o win32i64.o
+OBJU = $(OBJU1) $(OBJUS)
+
+OBJN = zipnote.o $(OBJU)
+OBJS = zipsplit.o $(OBJU)
+OBJC1 = zipcloak.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 crc32.h crypt.h ttyio.h
+zipfile.o: zipfile.c $(ZIP_H) crc32.h
+zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h $(ZIPUP_H)
+fileio.o: fileio.c $(ZIP_H) crc32.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) crc32.h
+crypt.o: crypt.c $(ZIP_H) crypt.h crc32.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
+
+win32i64.o: win32/win32i64.c $(ZIP_H)
+ $(CC) -c $(CCFLAGS) -I. win32/win32i64.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 crc32.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) crc32.h
+ $(CC) -c $(UTILFLAGS) zipfile.c
+
+fileio_.o: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) fileio.c
+
+util_.o: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) util.c
+
+crc32_.o: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) crc32.c
+
+crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.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
+
+crci386_.o: crc_i386.S
+ $(AS) $(ASFLAGS) -DUTIL -o$@ crc_i386.S
+
+ziprc.o: win32/zip.rc revision.h
+ - $(RC) -o $@ win32/zip.rc
+
+zip.exe: $(OBJZ) ziprc.o
+ $(LD) $(LDFLAGS) $(OBJZ) ziprc.o $(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..3cd2975
--- /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 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 crc32_.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 crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H) crc32.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) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.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 crc32.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) crc32.h
+ $(CC) -c $(UTILFLAGS) zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) util.c
+
+crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) crc32.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.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..6c7e8b5
--- /dev/null
+++ b/win32/makefile.lcc
@@ -0,0 +1,125 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit using LCC-Win32.
+# By E-Yen Tan (3 June 1998).
+# Last updated 9 February 2008 (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
+CRCA_O = crc_lcc.obj
+OBJA = lm32_lcc.obj
+ASMFLG = -DASM_CRC -DASMV
+#else
+#CRCA_O =
+#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 $(CRCA_O) globals.obj
+OBJZ3 = deflate.obj trees.obj crypt.obj ttyio.obj
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZ3) $(OBJZS)
+
+OBJU1 = zipfile_.obj fileio_.obj util_.obj crc32_.obj globals.obj
+OBJU = $(OBJU1) $(OBJUS)
+
+OBJN = zipnote.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+OBJK = zipcloak.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 crc32.h crypt.h ttyio.h
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
+fileio.obj: fileio.c $(ZIP_H) crc32.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) crc32.h
+crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.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 crc32.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) crc32.h
+ $(CC) $(CFLAGS) -DUTIL -Fo$@ zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) $(CFLAGS) -DUTIL -Fo$@ fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) $(CFLAGS) -DUTIL -Fo$@ util.c
+
+crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) $(CFLAGS) -DUTIL -Fo$@ crc32.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..0463f3b
--- /dev/null
+++ b/win32/makefile.w10
@@ -0,0 +1,197 @@
+# WMAKE makefile for Windows 95 and Windows NT (Intel only)
+# using Watcom C/C++ v10.5+, by Paul Kienitz, last revised 22 Jun 2008.
+# 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 =
+asmco =
+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
+asmco = $(O)crc_i386.obj
+asmob = $(asmco) $(O)match32.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)crc32.obj $(asmob)
+OBJZ = $(OBJZ1) $(O)win32zip.obj $(O)win32.obj $(O)win32i64.obj $(O)nt.obj
+
+OBJU1 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)crc32_.obj $(asmco)
+OBJ_U = $(OBJU1) $(O)globals.obj $(O)win32_.obj $(O)win32i64_.obj
+
+OBJC = $(O)zipcloak.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
+rc = wrc
+# Use Pentium Pro timings, register args, static strings in code:
+cflags = -bt=NT -6r -zt -zq
+aflags = -bt=NT -mf -3 -zq
+rcflags= -bt=NT -DWIN32 -iwin32 -q
+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) $(O)zip.res
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJZ)}
+ $(rc) $(O)zip.res $@
+
+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)crc32.obj: crc32.c $(ZIP_H) crc32.h # only used if NOASM
+$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+$(O)deflate.obj: deflate.c $(ZIP_H)
+$(O)fileio.obj: fileio.c $(ZIP_H) crc32.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) crc32.h crypt.h revision.h ttyio.h
+$(O)zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32\zipup.h
+$(O)zipnote.obj: zipnote.c $(ZIP_H) revision.h
+$(O)zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.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)win32i64.obj: win32\win32i64.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\win32i64.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) crc32.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@
+
+$(O)fileio_.obj: fileio.c $(ZIP_H) crc32.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)crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crc32.c -fo=$@
+
+$(O)crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.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=$@
+
+$(O)win32i64_.obj: win32\win32i64.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL win32\win32i64.c -fo=$@
+
+$(O)zip.res: win32\zip.rc revision.h
+ $(rc) -r $(rcflags) -fo=$@ win32\zip.rc
+
+# 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..7afbf0e
--- /dev/null
+++ b/win32/makefile.w32
@@ -0,0 +1,224 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# 32-bit Microsoft Visual C++
+
+# To use, do "nmake -f makefile.w32"
+
+# Add "NOASM=1" to the nmake command to disable usage of assembler sources
+# 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)
+
+!IFNDEF debug
+NODEBUG=1
+!ENDIF
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+!IFDEF NOASM
+ASMOBJS =
+CRCA_O =
+CFLG_ASM = -DNO_ASM
+!ELSE
+ASMOBJS = match32.obj
+CRCA_O = crci386c.obj
+CFLG_ASM = -DASM_CRC
+!ENDIF
+
+!IFDEF USEBZ2
+LOC=$(LOC) -DBZIP2_SUPPORT
+!IFNDEF debug
+EXTLIB=$(EXTLIB) libbz2.lib
+!ELSE
+EXTLIB=$(EXTLIB) libbz2.lib
+!ENDIF
+!ENDIF
+
+!IFDEF USEZLIB
+LOC=$(LOC) -DUSE_ZLIB
+ASMOBJS=
+!IFNDEF debug
+EXTLIB=$(EXTLIB) zlib.lib
+!ELSE
+EXTLIB=$(EXTLIB) zlib.lib
+!ENDIF
+!ENDIF
+
+!IFDEF USEZLIB
+USE_MSVCRT=1
+!ELSE
+!IFDEF USEBZIP2
+USE_MSVCRT=1
+!ELSE
+USE_MSVCRT=0
+!ENDIF
+!ENDIF # USEZLIB
+
+!IF $(USE_MSVCRT) == 1
+CRTLIB=-MD
+!ELSE
+!IF "$(VS80COMNTOOLS)" == ""
+CRTLIB=-ML
+!ELSE
+# no single-threaded CRT static lib, only multi-threaded in VC8
+CRTLIB=-MT
+!ENDIF
+!ENDIF
+
+!IFDEF NODEBUG
+cdebug = -O2
+cdbgsz = -O1
+!ELSE
+cdebug = -Od
+cdbgsz = $(cdebug)
+!ENDIF
+
+# ------------- 32-bit Microsoft Visual C++ -------------
+CC=cl -nologo
+CFLAGS=-W3 $(cdebug) -DWIN32 $(CFLG_ASM) $(CRTLIB) $(LOC)
+UTILFLAGS=$(CFLAGS) -DUTIL -Fo$@
+
+# Remove "-coff" from ASFLAGS if you do not have MASM 6.11.
+
+AS=ml -nologo
+ASFLAGS=-c -coff -Cx
+
+RC=rc
+
+# 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=user32.lib advapi32.lib /OPT:NOWIN98 /INCREMENTAL:NO /PDB:$*.pdb $(EXTLIB)
+SYMS=/DEBUG:full /DEBUGTYPE:CV
+!IFDEF debug
+LDFLAGS=$(LDFLAGS) $(SYMS)
+CFLAGS=$(CFLAGS) /Zi
+!ELSE
+LDFLAGS=$(LDFLAGS) /RELEASE
+!IFDEF sym
+LDFLAGS=$(LDFLAGS) $(SYMS)
+CFLAGS=$(CFLAGS) /Zi
+!ENDIF
+!ENDIF
+
+# variables
+OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj $(CRCA_O) globals.obj
+
+OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj win32i64.obj
+
+OBJU = zipfile_.obj fileio_.obj util_.obj crc32_.obj $(CRCA_O) globals.obj \
+ win32_.obj win32i64.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.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 crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H) crc32.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) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+win32i64.obj: win32/win32i64.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) -I. win32/win32i64.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 crc32.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) crc32.h
+ $(CC) -c $(UTILFLAGS) zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) util.c
+
+crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) crc32.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.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) crc32.h
+ $(CC) -c $(CFLAGS) -I. -Fo$@ win32/crc_i386.c
+
+crc_i386.obj: win32/crc_i386.asm
+ $(AS) $(ASFLAGS) win32\crc_i386.asm
+
+match32.obj: win32/match32.asm
+ $(AS) $(ASFLAGS) win32\match32.asm
+
+zip.res: win32/zip.rc revision.h
+ $(RC) /l 0x409 /fo$@ /i win32 /d WIN32 win32/zip.rc
+
+zip.exe: $(OBJZ) $(OBJI) zip.res
+ $(LD) $(LDFLAGS) $(OBJZ) $(OBJI) zip.res
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) $(OBJC)
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) $(OBJN)
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS)
+
+clean:
+ -del *.obj
+ -del *.exe
diff --git a/win32/makefile.wat b/win32/makefile.wat
new file mode 100644
index 0000000..f13d580
--- /dev/null
+++ b/win32/makefile.wat
@@ -0,0 +1,197 @@
+# WMAKE makefile for Windows 95 and Windows NT (Intel only)
+# using Watcom C/C++ v11.0+, by Paul Kienitz, last revised 22 Jun 2008.
+# 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 =
+asmco =
+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
+asmco = $(O)crc_i386.obj
+asmob = $(asmco) $(O)match32.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)crc32.obj $(asmob)
+OBJZ = $(OBJZ1) $(O)win32zip.obj $(O)win32.obj $(O)win32i64.obj $(O)nt.obj
+
+OBJU1 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)crc32_.obj $(asmco)
+OBJ_U = $(OBJU1) $(O)globals.obj $(O)win32_.obj $(O)win32i64_.obj
+
+OBJC = $(O)zipcloak.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
+rc = wrc
+# Use Pentium Pro timings, register args, static strings in code:
+cflags = -bt=NT -6r -zt -zq
+aflags = -bt=NT -mf -3 -zq
+rcflags= -bt=NT -DWIN32 -iwin32 -q
+lflags = sys NT
+cvars = $+$(cvars)$- -DWIN32 $(variation)
+avars = $+$(avars)$- -DWATCOM_DSEG $(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) $(O)zip.res
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJZ)}
+ $(rc) $(O)zip.res $@
+
+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)crc32.obj: crc32.c $(ZIP_H) crc32.h # only used if NOASM
+$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+$(O)deflate.obj: deflate.c $(ZIP_H)
+$(O)fileio.obj: fileio.c $(ZIP_H) crc32.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) crc32.h crypt.h revision.h ttyio.h
+$(O)zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32\zipup.h
+$(O)zipnote.obj: zipnote.c $(ZIP_H) revision.h
+$(O)zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.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)win32i64.obj: win32\win32i64.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\win32i64.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) crc32.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@
+
+$(O)fileio_.obj: fileio.c $(ZIP_H) crc32.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)crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crc32.c -fo=$@
+
+$(O)crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.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=$@
+
+$(O)win32i64_.obj: win32\win32i64.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL win32\win32i64.c -fo=$@
+
+$(O)zip.res: win32\zip.rc revision.h
+ $(rc) -r $(rcflags) -fo=$@ win32\zip.rc
+
+# 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/makenoas.w32 b/win32/makenoas.w32
new file mode 100644
index 0000000..403b087
--- /dev/null
+++ b/win32/makenoas.w32
@@ -0,0 +1,219 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# 32-bit Microsoft Visual C++
+
+# To use, do "nmake -f makefile.w32"
+
+# This version disables assembly.
+# 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)
+
+!IFNDEF debug
+NODEBUG=1
+!ENDIF
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+#ASMOBJS = match32.obj
+CRCA_O = crci386c.obj
+CFLG_ASM = -DASM_CRC
+
+!IFDEF USEBZ2
+LOC=$(LOC) -DBZIP2_SUPPORT
+!IFNDEF debug
+EXTLIB=$(EXTLIB) libbz2.lib
+!ELSE
+EXTLIB=$(EXTLIB) libbz2.lib
+!ENDIF
+!ENDIF
+
+!IFDEF USEZLIB
+LOC=$(LOC) -DUSE_ZLIB
+ASMOBJS=
+!IFNDEF debug
+EXTLIB=$(EXTLIB) zlib.lib
+!ELSE
+EXTLIB=$(EXTLIB) zlib.lib
+!ENDIF
+!ENDIF
+
+!IFDEF USEZLIB
+USE_MSVCRT=1
+!ELSE
+!IFDEF USEBZIP2
+USE_MSVCRT=1
+!ELSE
+USE_MSVCRT=0
+!ENDIF
+!ENDIF # USEZLIB
+
+!IF $(USE_MSVCRT) == 1
+CRTLIB=-MD
+!ELSE
+!IF "$(VS80COMNTOOLS)" == ""
+CRTLIB=-ML
+!ELSE
+# no single-threaded CRT static lib, only multi-threaded in VC8
+CRTLIB=-MT
+!ENDIF
+!ENDIF
+
+!IFDEF NODEBUG
+cdebug = -O2
+cdbgsz = -O1
+!ELSE
+cdebug = -Od
+cdbgsz = $(cdebug)
+!ENDIF
+
+# ------------- 32-bit Microsoft Visual C++ -------------
+CC=cl -nologo
+CFLAGS=-W3 $(cdebug) -DWIN32 $(CFLG_ASM) $(CRTLIB) $(LOC) -DNO_ASM
+UTILFLAGS=$(CFLAGS) -DUTIL -Fo$@
+
+# Remove "-coff" from ASFLAGS if you do not have MASM 6.11.
+
+AS=ml -nologo
+ASFLAGS=-c -coff -Cx
+
+RC=rc
+
+# 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=user32.lib advapi32.lib /OPT:NOWIN98 /INCREMENTAL:NO /PDB:$*.pdb $(EXTLIB)
+SYMS=/DEBUG:full /DEBUGTYPE:CV
+!IFDEF debug
+LDFLAGS=$(LDFLAGS) $(SYMS)
+CFLAGS=$(CFLAGS) /Zi
+!ELSE
+LDFLAGS=$(LDFLAGS) /RELEASE
+!IFDEF sym
+LDFLAGS=$(LDFLAGS) $(SYMS)
+CFLAGS=$(CFLAGS) /Zi
+!ENDIF
+!ENDIF
+
+# variables
+OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj $(CRCA_O) globals.obj
+
+OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj win32i64.obj
+
+OBJU = zipfile_.obj fileio_.obj util_.obj crc32_.obj $(CRCA_O) globals.obj \
+ win32_.obj win32i64.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.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 crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H) crc32.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) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+win32i64.obj: win32/win32i64.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) -I. win32/win32i64.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 crc32.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) crc32.h
+ $(CC) -c $(UTILFLAGS) zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS) util.c
+
+crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) crc32.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.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) crc32.h
+ $(CC) -c $(CFLAGS) -I. -Fo$@ win32/crc_i386.c
+
+crc_i386.obj: win32/crc_i386.asm
+ $(AS) $(ASFLAGS) win32\crc_i386.asm
+
+match32.obj: win32/match32.asm
+ $(AS) $(ASFLAGS) win32\match32.asm
+
+zip.res: win32/zip.rc revision.h
+ $(RC) /l 0x409 /fo$@ /i win32 /d WIN32 win32/zip.rc
+
+zip.exe: $(OBJZ) $(OBJI) zip.res
+ $(LD) $(LDFLAGS) $(OBJZ) $(OBJI) zip.res
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) $(OBJC)
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) $(OBJN)
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS)
+
+clean:
+ -del *.obj
+ -del *.exe
diff --git a/win32/match32.asm b/win32/match32.asm
new file mode 100644
index 0000000..81db41f
--- /dev/null
+++ b/win32/match32.asm
@@ -0,0 +1,192 @@
+;===========================================================================
+; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2005-Feb-10 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
+;===========================================================================
+;
+; 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
+;
+; Adapted to work with OpenWatcom WASM by Chr. Spieler, 2005
+; (Define the symbol WATCOM_DSEG to activate the specific Watcom C
+; data segment naming convention.)
+;
+;==============================================================================
+;
+; 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 WATCOM_DSEG
+DGROUP group _BSS
+ endif
+
+ 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..aa0529f
--- /dev/null
+++ b/win32/nt.c
@@ -0,0 +1,492 @@
+/*
+ win32/nt.c - Zip 3
+
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+/*++
+
+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
+
+/* This macro definition is missing in old versions of MS' winbase.h. */
+#ifndef InterlockedExchangePointer
+# define InterlockedExchangePointer(Target, Value) \
+ (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value))
+#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)InterlockedExchangePointer((void *)&hZipInitMutex,
+ hMutex);
+
+ if(hOldMutex != NULL) {
+ /* somebody setup the mutex already */
+ InterlockedExchangePointer((void *)&hZipInitMutex,
+ 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..f722530
--- /dev/null
+++ b/win32/nt.h
@@ -0,0 +1,75 @@
+/*
+ win32/nt.h - Zip 3
+
+ Copyright (c) 1990-2003 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2003-May-08 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..eaf6507
--- /dev/null
+++ b/win32/osdep.h
@@ -0,0 +1,617 @@
+/*
+ win32/osdep.h
+
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+
+/* 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
+
+/* Tell Microsoft Visual C++ 2005 to leave us alone and
+ * let us use standard C functions the way we're supposed to.
+ */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+# ifndef _CRT_SECURE_NO_DEPRECATE
+# define _CRT_SECURE_NO_DEPRECATE
+# endif
+# ifndef _CRT_NONSTDC_NO_DEPRECATE
+# define _CRT_NONSTDC_NO_DEPRECATE
+# 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
+
+/* Get types and stat */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <io.h>
+
+#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, filter_match_case))
+#define BROKEN_FSEEK
+#ifndef __RSXNT__
+# define HAVE_FSEEKABLE
+#endif
+
+
+/* popen
+ *
+ * On Win32 must map to _popen() and _pclose()
+ */
+#define popen _popen
+#define pclose _pclose
+
+/* WIN32_OEM
+ *
+ * This enables storing paths in archives on WIN32 in OEM format
+ * which is more work but seems the standard now. It also enables
+ * converting paths in read DOS archives from assumed OEM to ANSI.
+ */
+#ifndef NO_WIN32_OEM
+# define WIN32_OEM
+#endif
+
+/* Large File Support
+ *
+ * If this is set it is assumed that the port
+ * supports 64-bit file calls. The types are
+ * defined here. Any local implementations are
+ * in Win32.c and the prototypes for the calls are
+ * in tailor.h. Note that a port must support
+ * these calls fully or should not set
+ * LARGE_FILE_SUPPORT.
+ */
+
+/* Note also that ZOFF_T_FORMAT_SIZE_PREFIX has to be defined here
+ or tailor.h will define defaults */
+
+/* If port has LARGE_FILE_SUPPORT then define here
+ to make large file support automatic unless overridden */
+
+
+#ifndef LARGE_FILE_SUPPORT
+# ifndef NO_LARGE_FILE_SUPPORT
+ /* MS C and VC */
+# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
+# define LARGE_FILE_SUPPORT
+# endif
+# if defined(__WATCOMC__)
+# define LARGE_FILE_SUPPORT
+# endif
+# endif
+#endif
+
+#ifdef LARGE_FILE_SUPPORT
+ /* 64-bit Large File Support */
+
+ /* Only types and the printf format stuff go here. Functions
+ go in tailor.h since ANSI prototypes are required and the OF define
+ is not defined here. */
+
+# if (defined(_MSC_VER) && (_MSC_VER >= 1100)) || defined(__MINGW32__)
+ /* MS C and VC, MinGW32 */
+ /* these compiler systems use the Microsoft C RTL */
+
+ /* base types for file offsets and file sizes */
+ typedef __int64 zoff_t;
+ typedef unsigned __int64 uzoff_t;
+
+ /* 64-bit stat struct */
+ typedef struct _stati64 z_stat;
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "I64"
+
+# elif (defined(__GNUC__) || defined(ULONG_LONG_MAX))
+ /* GNU C */
+
+ /* base types for file offsets and file sizes */
+ typedef long long zoff_t;
+ typedef unsigned long long uzoff_t;
+
+# ifdef __CYGWIN__
+ /* Use Cygwin's own stat struct */
+ typedef struct stat z_stat;
+# else
+ /* 64-bit stat struct */
+ typedef struct _stati64 z_stat;
+# endif
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
+
+# elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))
+ /* WATCOM C */
+
+ /* base types for file offsets and file sizes */
+ typedef __int64 zoff_t;
+ typedef unsigned __int64 uzoff_t;
+
+ /* 64-bit stat struct */
+ typedef struct _stati64 z_stat;
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
+
+# elif (defined(__IBMC__) && (__IBMC__ >= 350))
+ /* IBM C */
+
+ /* base types for file offsets and file sizes */
+ typedef __int64 zoff_t;
+ typedef unsigned __int64 uzoff_t;
+
+ /* 64-bit stat struct */
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "I64"
+
+# else
+# undef LARGE_FILE_SUPPORT
+# endif
+
+#endif
+
+#if 0
+# ifndef ZOFF_T_FORMAT_SIZE_PREFIX
+ /* unsupported WIN32 */
+
+ /* base types for file offsets and file sizes */
+ typedef long long zoff_t;
+ typedef unsigned long long uzoff_t;
+
+ /* 64-bit stat struct */
+ typedef struct stat z_stat;
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
+# endif
+#endif
+
+
+/* Automatically set ZIP64_SUPPORT if supported */
+
+/* MS C and VC */
+#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__WATCOMC__)
+# ifdef LARGE_FILE_SUPPORT
+# ifndef NO_ZIP64_SUPPORT
+# ifndef ZIP64_SUPPORT
+# define ZIP64_SUPPORT
+# endif
+# endif
+# endif
+#endif
+
+
+#ifndef LARGE_FILE_SUPPORT
+ /* No Large File Support */
+
+ /* base type for file offsets and file sizes */
+ typedef long zoff_t;
+ typedef unsigned long uzoff_t;
+
+ /* stat struct */
+ typedef struct stat z_stat;
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "l"
+#endif
+
+
+ /* UNICODE */
+#ifdef WIN32
+ /* assume wide character conversion functions */
+# ifndef UNICODE_SUPPORT
+# ifndef NO_UNICODE_SUPPORT
+# define UNICODE_SUPPORT
+# endif
+# endif
+#endif
+
+#if 0
+ /* this is now generic */
+# ifdef UNICODE_SUPPORT
+ /* Set up Unicode support - 9/27/05 EG */
+
+ /* type of wide string characters */
+# define zchar wchar_t
+
+ /* default char string used if a wide char can't be converted */
+# define zchar_default "_"
+
+# else
+# define zchar char
+# endif
+#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
+
+/* Microsoft C requires additional attributes attached to all RTL function
+ * declarations when linking against the CRTL dll.
+ */
+#ifdef MSC
+# ifdef IZ_IMP
+# undef IZ_IMP
+# endif
+# define IZ_IMP _CRTIMP
+#else
+# ifndef IZ_IMP
+# define IZ_IMP
+# endif
+#endif
+
+/* WIN32 runs solely on little-endian processors; enable support
+ * for the 32-bit optimized CRC-32 C code by default.
+ */
+#ifdef IZ_CRC_BE_OPTIMIZ
+# undef IZ_CRC_BE_OPTIMIZ
+#endif
+#if !defined(IZ_CRC_LE_OPTIMIZ) && !defined(NO_CRC_OPTIMIZ)
+# define IZ_CRC_LE_OPTIMIZ
+#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
+
+/* handlers for OEM <--> ANSI string conversions */
+#if defined(__RSXNT__) || defined(WIN32_CRT_OEM)
+ /* RSXNT uses OEM coded strings in functions supplied by C RTL */
+# ifdef CRTL_CP_IS_ISO
+# undef CRTL_CP_IS_ISO
+# endif
+# ifndef CRTL_CP_IS_OEM
+# define CRTL_CP_IS_OEM
+# endif
+#else
+ /* "real" native WIN32 compilers use ANSI coded strings in C RTL calls */
+# ifndef CRTL_CP_IS_ISO
+# define CRTL_CP_IS_ISO
+# endif
+# ifdef CRTL_CP_IS_OEM
+# undef CRTL_CP_IS_OEM
+# endif
+#endif
+
+#ifdef CRTL_CP_IS_ISO
+ /* C RTL's file system support assumes ANSI coded strings */
+# define ISO_TO_INTERN(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define OEM_TO_INTERN(src, dst) OemToAnsi(src, dst)
+# define INTERN_TO_ISO(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define INTERN_TO_OEM(src, dst) AnsiToOem(src, dst)
+# define _OEM_INTERN(str1) OEM_TO_INTERN(str1, str1)
+# define _ISO_INTERN(str1) {;}
+# define _INTERN_OEM(str1) INTERN_TO_OEM(str1, str1)
+# define _INTERN_ISO(str1) {;}
+#endif /* CRTL_CP_IS_ISO */
+#ifdef CRTL_CP_IS_OEM
+ /* C RTL's file system support assumes OEM coded strings */
+# define ISO_TO_INTERN(src, dst) AnsiToOem(src, dst)
+# define OEM_TO_INTERN(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define INTERN_TO_ISO(src, dst) OemToAnsi(src, dst)
+# define INTERN_TO_OEM(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define _OEM_INTERN(str1) {;}
+# define _ISO_INTERN(str1) ISO_TO_INTERN(str1, str1)
+# define _INTERN_OEM(str1) {;}
+# define _INTERN_ISO(str1) INTERN_TO_ISO(str1, str1)
+#endif /* CRTL_CP_IS_OEM */
+
+/* The following "OEM vs. ISO Zip entry names" code has been copied from UnZip.
+ * It should be applicable to the generic Zip code. However, currently only
+ * the Win32 port of Zip supplies the required charset conversion functions.
+ * (The Win32 port uses conversion functions supplied by the OS.)
+ */
+/* Convert filename (and file comment string) into "internal" charset.
+ * This macro assumes that Zip entry filenames are coded in OEM (IBM DOS)
+ * codepage when made on
+ * -> DOS (this includes 16-bit Windows 3.1) (FS_FAT_)
+ * -> OS/2 (FS_HPFS_)
+ * -> Win95/WinNT with Nico Mak's WinZip (FS_NTFS_ && hostver == "5.0")
+ * EXCEPTIONS:
+ * PKZIP for Windows 2.5, 2.6, and 4.0 flag their entries as "FS_FAT_", but
+ * the filename stored in the local header is coded in Windows ANSI (CP 1252
+ * resp. ISO 8859-1 on US and western Europe locale settings).
+ * Likewise, PKZIP for UNIX 2.51 flags its entries as "FS_FAT_", but the
+ * filenames stored in BOTH the local and the central header are coded
+ * in the local system's codepage (usually ANSI codings like ISO 8859-1,
+ * but could also be UTF-8 on "modern" setups...).
+ *
+ * All other ports are assumed to code zip entry filenames in ISO (8859-1
+ * on "Western" localisations).
+ */
+#define FS_FAT_ 0 /* filesystem used by MS-DOS, OS/2, Win32 */
+#define FS_HPFS_ 6 /* filesystem used by OS/2 (and NT 3.x) */
+#define FS_NTFS_ 11 /* filesystem used by Windows NT */
+#ifndef Ext_ASCII_TO_Native
+# define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \
+ if (((hostnum) == FS_FAT_ && \
+ !(((islochdr) || (isuxatt)) && \
+ ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
+ (hostnum) == FS_HPFS_ || \
+ ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \
+ _OEM_INTERN((string)); \
+ } else { \
+ _ISO_INTERN((string)); \
+ }
+#endif
+
+#if (defined(__RSXNT__) && defined(__CRTRSXNT__))
+# include <crtrsxnt.h>
+#endif
+
+#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__
+ IZ_IMP extern int *__p___mb_cur_max(void);
+# define MB_CUR_MAX (*__p___mb_cur_max())
+# else
+ IZ_IMP 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))
+ IZ_IMP 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__
+ IZ_IMP 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 UNICODE_SUPPORT
+# ifdef WIN32
+# define MATCHW dosmatchw
+# endif
+#endif
+
+#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(__CYGWIN__) || \
+ 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
+# ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ int zstat_zipwin32(const char *path, z_stat *buf);
+# else
+ int zstat_zipwin32(const char *path, struct stat *buf);
+# endif
+# ifdef UNICODE_SUPPORT
+# ifdef LARGE_FILE_SUPPORT
+ int zstat_zipwin32w(const wchar_t *pathw, struct _stati64 *buf);
+# else
+ int zstat_zipwin32w(const wchar_t *pathw, struct _stat *buf);
+# endif
+# endif
+# ifdef SSTAT
+# undef SSTAT
+# endif
+# define SSTAT zstat_zipwin32
+# ifdef UNICODE_SUPPORT
+# define SSTATW zstat_zipwin32w
+# endif
+#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__ */
+ /* Watcom C (like the other Win32 C compiler systems) does not support
+ * symlinks on Win32, but defines the S_IFLNK symbol nevertheless.
+ * However, the existence of this symbol is used as "symlinks supported"
+ * indicator in the generic Zip code (see tailor.h). So, for a simple
+ * work-around, this symbol is undefined here. */
+# ifdef S_IFLNK
+# undef S_IFLNK
+# endif
+# ifdef UNICODE_SUPPORT
+ /* Watcom C does not supply wide-char definitions in the "standard"
+ * headers like MSC; so we have to pull in a wchar-specific header.
+ */
+# include <wchar.h>
+# endif
+#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..a710a35
--- /dev/null
+++ b/win32/rsxntwin.h
@@ -0,0 +1,173 @@
+/*
+ win32/rsxntwin.h - Zip 3
+
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+/* 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 */
+
+#ifndef CP_UTF8
+# define CP_UTF8 65001 /* UTF-8 translation */
+#endif
+
+#endif /* !defined (_RSXNTWIN_H) */
+#endif /* __RSXNT__ */
diff --git a/win32/vc6/ReadmeVC.txt b/win32/vc6/ReadmeVC.txt
new file mode 100644
index 0000000..f0295cb
--- /dev/null
+++ b/win32/vc6/ReadmeVC.txt
@@ -0,0 +1,10 @@
+VC6 Readme
+
+This directory has a VC6 project list that can be used to compile Zip
+and the utilities. It does not include bzip2 support.
+
+The vc6bz2 directory provides a variant of this directory that includes
+the settings needed for including bzip2 support in Zip.
+
+Ed Gordon
+26 March 2007
diff --git a/win32/vc6/zip.dsp b/win32/vc6/zip.dsp
new file mode 100644
index 0000000..10acbe1
--- /dev/null
+++ b/win32/vc6/zip.dsp
@@ -0,0 +1,337 @@
+# 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" /FR /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 "NO_ASM" /D "WIN32" /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 Ignore_Export_Lib 0
+# 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" /FR /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=..\..\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=..\win32i64.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=..\zip.rc
+# 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=..\..\crc32.h
+# End Source File
+# 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)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zip - Win32 Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug"
+
+# PROP Exclude_From_Build 1
+
+!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)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zip - Win32 Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug"
+
+# PROP Exclude_From_Build 1
+
+!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..e09ccd7
--- /dev/null
+++ b/win32/vc6/zipcloak.dsp
@@ -0,0 +1,264 @@
+# 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 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 "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 ASM 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 "zipcloak - Win32 ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipcloak - Win32 ASM Release" (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 "UTIL" /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)" == "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 Ignore_Export_Lib 0
+# 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 "UTIL" /D "WIN32" /D "NO_ASM" /FR /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)" == "zipcloak - Win32 ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zipcloak___Win32_ASM_Debug"
+# PROP BASE Intermediate_Dir "zipcloak___Win32_ASM_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zipcloak___Win32_ASM_Debug"
+# PROP Intermediate_Dir "zipcloak___Win32_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /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)" == "zipcloak - Win32 ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zipcloak___Win32_ASM_Release"
+# PROP BASE Intermediate_Dir "zipcloak___Win32_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zipcloak___Win32_ASM_Release"
+# PROP Intermediate_Dir "zipcloak___Win32_ASM_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /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
+
+!ENDIF
+
+# Begin Target
+
+# Name "zipcloak - Win32 Release"
+# Name "zipcloak - Win32 Debug"
+# Name "zipcloak - Win32 ASM Debug"
+# Name "zipcloak - Win32 ASM Release"
+# 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=..\..\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=..\win32i64.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=..\..\crc32.h
+# End Source File
+# 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
+# Begin Group "Assembler Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\crc_i386.asm
+
+!IF "$(CFG)" == "zipcloak - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zipcloak - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zipcloak - Win32 ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipcloak___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)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zipcloak - Win32 ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipcloak___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
+
+!ENDIF
+
+# 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..a7f9f57
--- /dev/null
+++ b/win32/vc6/zipnote.dsp
@@ -0,0 +1,248 @@
+# 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 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 "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 ASM 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 "zipnote - Win32 ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipnote - Win32 ASM Release" (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 "UTIL" /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)" == "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 Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "NO_ASM" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /D "NO_ASM" /FR /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)" == "zipnote - Win32 ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zipnote___Win32_ASM_Debug"
+# PROP BASE Intermediate_Dir "zipnote___Win32_ASM_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zipnote___Win32_ASM_Debug"
+# PROP Intermediate_Dir "zipnote___Win32_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /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)" == "zipnote - Win32 ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zipnote___Win32_ASM_Release"
+# PROP BASE Intermediate_Dir "zipnote___Win32_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zipnote___Win32_ASM_Release"
+# PROP Intermediate_Dir "zipnote___Win32_ASM_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /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
+
+!ENDIF
+
+# Begin Target
+
+# Name "zipnote - Win32 Release"
+# Name "zipnote - Win32 Debug"
+# Name "zipnote - Win32 ASM Debug"
+# Name "zipnote - Win32 ASM Release"
+# 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=..\..\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=..\win32i64.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=..\..\crc32.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=..\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
+# Begin Group "Assembler Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\crc_i386.asm
+
+!IF "$(CFG)" == "zipnote - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zipnote - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zipnote - Win32 ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipnote___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)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zipnote - Win32 ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipnote___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
+
+!ENDIF
+
+# 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..ae5565d
--- /dev/null
+++ b/win32/vc6/zipsplit.dsp
@@ -0,0 +1,248 @@
+# 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 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 "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 ASM 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 "zipsplit - Win32 ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipsplit - Win32 ASM Release" (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 "UTIL" /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)" == "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 Ignore_Export_Lib 0
+# 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 "UTIL" /D "WIN32" /D "NO_ASM" /FR /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)" == "zipsplit - Win32 ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zipsplit___Win32_ASM_Debug"
+# PROP BASE Intermediate_Dir "zipsplit___Win32_ASM_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zipsplit___Win32_ASM_Debug"
+# PROP Intermediate_Dir "zipsplit___Win32_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /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)" == "zipsplit - Win32 ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zipsplit___Win32_ASM_Release"
+# PROP BASE Intermediate_Dir "zipsplit___Win32_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zipsplit___Win32_ASM_Release"
+# PROP Intermediate_Dir "zipsplit___Win32_ASM_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /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
+
+!ENDIF
+
+# Begin Target
+
+# Name "zipsplit - Win32 Release"
+# Name "zipsplit - Win32 Debug"
+# Name "zipsplit - Win32 ASM Debug"
+# Name "zipsplit - Win32 ASM Release"
+# 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=..\..\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=..\win32i64.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=..\..\crc32.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=..\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
+# Begin Group "Assembler Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\crc_i386.asm
+
+!IF "$(CFG)" == "zipsplit - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zipsplit - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zipsplit - Win32 ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipsplit___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)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zipsplit - Win32 ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipsplit___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
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/win32/vc6bz2/ReadVCBZ.txt b/win32/vc6bz2/ReadVCBZ.txt
new file mode 100644
index 0000000..3aafd6f
--- /dev/null
+++ b/win32/vc6bz2/ReadVCBZ.txt
@@ -0,0 +1,19 @@
+VC6bz2 Readme
+
+This directory has a VC6 project list that can be used to compile Zip
+and the utilities. The Zip project includes support for the bzip2
+compression method.
+
+To include bzip2 support, get a copy of the bzip2 source (bzip2-1.0.4
+or later from http://www.bzip.org/ for instance), expand the bzip2
+source into a directory, then copy the contents of the bzip2-1.0.4
+directory, for instance, into the zip bzip2 directory. Use this
+project to compile zip and bzip2 support should be included. See
+bzip2/install.txt for additional information.
+
+The vc6 directory is similar to this directory but does not include
+bzip2 support. Use that if you do not have a copy of bzip2 or do not
+need bzip2 support.
+
+Ed Gordon
+26 March 2007
diff --git a/win32/vc6bz2/zip.dsp b/win32/vc6bz2/zip.dsp
new file mode 100644
index 0000000..fee0af4
--- /dev/null
+++ b/win32/vc6bz2/zip.dsp
@@ -0,0 +1,381 @@
+# 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 Debug bzip2
+!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 Debug bzip2"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zip - Win32 ASM Release bzip2" (based on "Win32 (x86) Console Application")
+!MESSAGE "zip - Win32 ASM Debug bzip2" (based on "Win32 (x86) Console Application")
+!MESSAGE "zip - Win32 Release bzip2" (based on "Win32 (x86) Console Application")
+!MESSAGE "zip - Win32 Debug bzip2" (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 bzip2"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zip___Win32_ASM_Release_bzip2"
+# PROP BASE Intermediate_Dir "zip___Win32_ASM_Release_bzip2"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zip___Win32_ASM_Release_bzip2"
+# PROP Intermediate_Dir "zip___Win32_ASM_Release_bzip2"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "ASM_CRC" /D "ASMV" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../../bzip2" /D "ASM_CRC" /D "ASMV" /D "WIN32" /D "BZIP2_SUPPORT" /D "BZ_NO_STDIO" /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 bzip2"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zip___Win32_ASM_Debug_bzip2"
+# PROP BASE Intermediate_Dir "zip___Win32_ASM_Debug_bzip2"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zip___Win32_ASM_Debug_bzip2"
+# PROP Intermediate_Dir "zip___Win32_ASM_Debug_bzip2"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "ASM_CRC" /D "ASMV" /FR /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../bzip2" /D "ASM_CRC" /D "ASMV" /D "WIN32" /D "BZIP2_SUPPORT" /D "BZ_NO_STDIO" /FR /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 bzip2"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zip___Win32_Release_bzip2"
+# PROP BASE Intermediate_Dir "zip___Win32_Release_bzip2"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zip___Win32_Release_bzip2"
+# PROP Intermediate_Dir "zip___Win32_Release_bzip2"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NO_ASM" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../../bzip2" /D "NO_ASM" /D "WIN32" /D "BZIP2_SUPPORT" /D "BZ_NO_STDIO" /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 bzip2"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zip___Win32_Debug_bzip2"
+# PROP BASE Intermediate_Dir "zip___Win32_Debug_bzip2"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zip___Win32_Debug_bzip2"
+# PROP Intermediate_Dir "zip___Win32_Debug_bzip2"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "NO_ASM" /D "WIN32" /FR /FD /GZ /c
+# SUBTRACT BASE CPP /WX
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../bzip2" /D "NO_ASM" /D "WIN32" /D "BZIP2_SUPPORT" /D "BZ_NO_STDIO" /FR /FD /GZ /c
+# SUBTRACT CPP /WX
+# 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 bzip2"
+# Name "zip - Win32 ASM Debug bzip2"
+# Name "zip - Win32 Release bzip2"
+# Name "zip - Win32 Debug bzip2"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\bzip2\blocksort.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\bzlib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crc32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\crctable.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crypt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\decompress.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=..\..\bzip2\huffman.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\nt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\randtable.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=..\win32i64.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32zip.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zbz2err.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zip.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zip.rc
+# 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=..\..\bzip2\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crc32.h
+# End Source File
+# 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 bzip2"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Release_bzip2
+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 bzip2"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Debug_bzip2
+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 Release bzip2"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug bzip2"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\match32.asm
+
+!IF "$(CFG)" == "zip - Win32 ASM Release bzip2"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Release_bzip2
+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 bzip2"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Debug_bzip2
+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 Release bzip2"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug bzip2"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/win32/vc6bz2/zip.dsw b/win32/vc6bz2/zip.dsw
new file mode 100644
index 0000000..bab0fdd
--- /dev/null
+++ b/win32/vc6bz2/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"=..\vc6\zipcloak.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zipnote"=..\vc6\zipnote.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zipsplit"=..\vc6\zipsplit.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/win32/win32.c b/win32/win32.c
new file mode 100644
index 0000000..5798053
--- /dev/null
+++ b/win32/win32.c
@@ -0,0 +1,1488 @@
+/*
+ win32/win32.c - Zip 3
+
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+
+/*
+ * 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>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+/* for LARGE_FILE_SUPPORT but may not be needed */
+#include <io.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
+
+#if (defined(__MINGW32__) && !defined(USE_MINGW_GLOBBING))
+ int _CRT_glob = 0; /* suppress command line globbing by C RTL */
+#endif
+
+#ifndef UTIL
+
+extern int noisy;
+
+#ifdef NT_TZBUG_WORKAROUND
+local int FSusesLocalTime(const char *path);
+#ifdef UNICODE_SUPPORt
+local int FSusesLocalTimeW(const wchar_t *path);
+#endif
+#endif
+#if (defined(USE_EF_UT_TIME) || defined(NT_TZBUG_WORKAROUND))
+local int FileTime2utime(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(char *dir)
+{
+ static char lastDrive = '\0'; /* cached drive of last GetVolumeInformation call */
+ static int lastDriveOldFAT = 0; /* cached OldFAT value of last GetVolumeInformation call */
+ char root[4];
+ DWORD vfnsize;
+ DWORD vfsflags;
+
+ /*
+ * 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 (lastDrive == root[0]) {
+ return lastDriveOldFAT;
+ }
+
+ if ( !GetVolumeInformation(root, NULL, 0,
+ NULL, &vfnsize, &vfsflags,
+ NULL, 0)) {
+ fprintf(mesg, "zip diagnostic: GetVolumeInformation failed\n");
+ return(FALSE);
+ }
+
+ lastDrive = root[0];
+ lastDriveOldFAT = vfnsize <= 12;
+
+ return lastDriveOldFAT;
+}
+
+#ifdef UNICODE_SUPPORT
+int IsFileSystemOldFATW(wchar_t *dir)
+{
+ static wchar_t lastDrive = (wchar_t)'\0'; /* cached drive of last GetVolumeInformation call */
+ static int lastDriveOldFAT = 0; /* cached OldFAT value of last GetVolumeInformation call */
+ wchar_t root[4];
+ DWORD vfnsize;
+ DWORD vfsflags;
+
+ /*
+ * 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.
+ */
+
+ wcsncpy(root, dir, 3);
+ if ( iswalpha(root[0]) && (root[1] == (wchar_t)':') ) {
+ root[0] = towupper(dir[0]);
+ root[2] = (wchar_t)'\\';
+ root[3] = 0;
+ }
+ else {
+ root[0] = (wchar_t)'\\';
+ root[1] = 0;
+ }
+ if (lastDrive == root[0]) {
+ return lastDriveOldFAT;
+ }
+
+ if ( !GetVolumeInformationW(root, NULL, 0,
+ NULL, &vfnsize, &vfsflags,
+ NULL, 0)) {
+ fprintf(mesg, "zip diagnostic: GetVolumeInformation failed\n");
+ return(FALSE);
+ }
+
+ lastDrive = root[0];
+ lastDriveOldFAT = vfnsize <= 12;
+
+ return lastDriveOldFAT;
+}
+#endif
+
+
+/* access mode bits and time stamp */
+
+int GetFileMode(char *name)
+{
+DWORD dwAttr;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(name) + 1);
+
+ OemToAnsi(name, ansi_name);
+ name = ansi_name;
+#endif
+
+ dwAttr = GetFileAttributes(name);
+ if ( dwAttr == 0xFFFFFFFF ) {
+ zipwarn("reading file attributes failed: ", name);
+ /*
+ fprintf(mesg, "zip diagnostic: GetFileAttributes failed");
+ fflush();
+ */
+ 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 UNICODE_SUPPORT
+int GetFileModeW(wchar_t *namew)
+{
+DWORD dwAttr;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ wchar_t *ansi_namew = (wchar_t *)alloca((wcslen(namew) + 1) * sizeof(wchar_t));
+
+ CharToAnsiW(namew, ansi_namew);
+ namew = ansi_namew;
+#endif
+
+ dwAttr = GetFileAttributesW(namew);
+ if ( dwAttr == 0xFFFFFFFF ) {
+ char *name = wchar_to_local_string(namew);
+ zipwarn("reading file attributes failed: ", name);
+ free(name);
+ 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));
+}
+#endif
+
+
+int ClearArchiveBitW(wchar_t *namew)
+{
+DWORD dwAttr;
+ dwAttr = GetFileAttributesW(namew);
+ if ( dwAttr == 0xFFFFFFFF ) {
+ fprintf(mesg, "zip diagnostic: GetFileAttributes failed\n");
+ return(0);
+ }
+
+ if (!SetFileAttributesW(namew, (DWORD)(dwAttr & ~FILE_ATTRIBUTE_ARCHIVE))) {
+ fprintf(mesg, "zip diagnostic: SetFileAttributes failed\n");
+ perror("SetFileAttributes");
+ return(0);
+ }
+ return(1);
+}
+
+int ClearArchiveBit(char *name)
+{
+DWORD dwAttr;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(name) + 1);
+
+ OemToAnsi(name, ansi_name);
+ name = ansi_name;
+#endif
+
+ dwAttr = GetFileAttributes(name);
+ if ( dwAttr == 0xFFFFFFFF ) {
+ fprintf(mesg, "zip diagnostic: GetFileAttributes failed\n");
+ return(0);
+ }
+
+ if (!SetFileAttributes(name, (DWORD)(dwAttr & ~FILE_ATTRIBUTE_ARCHIVE))) {
+ fprintf(mesg, "zip diagnostic: SetFileAttributes failed\n");
+ perror("SetFileAttributes");
+ return(0);
+ }
+ return(1);
+}
+
+
+#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;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(path) + 1);
+
+ OemToAnsi(path, ansi_path);
+ path = 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() */
+
+# ifdef UNICODE_SUPPORT
+local int FSusesLocalTimeW(const wchar_t *path)
+{
+ wchar_t *tmp0;
+ wchar_t rootPathName[4];
+ wchar_t tmp1[MAX_PATH], tmp2[MAX_PATH];
+ DWORD volSerNo, maxCompLen, fileSysFlags;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ wchar_t *ansi_path = (wchar_t *)alloca((wcslen(path) + 1) * sizeof(wchar_t));
+
+ CharToAnsiW(path, ansi_path);
+ path = ansi_path;
+#endif
+
+ if (iswalpha(path[0]) && (path[1] == (wchar_t)':'))
+ tmp0 = (wchar_t *)path;
+ else
+ {
+ GetFullPathNameW(path, MAX_PATH, tmp1, &tmp0);
+ tmp0 = &tmp1[0];
+ }
+ wcsncpy(rootPathName, tmp0, 3); /* Build the root path name, */
+ rootPathName[3] = (wchar_t)'\0'; /* e.g. "A:/" */
+
+ GetVolumeInformationW(rootPathName, tmp1, (DWORD)MAX_PATH,
+ &volSerNo, &maxCompLen, &fileSysFlags,
+ tmp2, (DWORD)MAX_PATH);
+
+ /* Volumes in (V)FAT and (OS/2) HPFS format store file timestamps in
+ * local time!
+ */
+ return !wcsncmp(_wcsupr(tmp2), L"FAT", 3) ||
+ !wcsncmp(tmp2, L"VFAT", 4) ||
+ !wcsncmp(tmp2, L"HPFS", 4);
+
+} /* end function FSusesLocalTimeW() */
+# endif
+
+#endif /* NT_TZBUG_WORKAROUND */
+
+
+#if (defined(USE_EF_UT_TIME) || defined(NT_TZBUG_WORKAROUND))
+
+#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
+
+# define UNIX_TIME_ZERO_HI 0x019DB1DEUL
+# define UNIX_TIME_ZERO_LO 0xD53E8000UL
+# 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_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 FileTime2utime(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 FileTime2utime() */
+#endif /* USE_EF_UT_TIME || NT_TZBUG_WORKAROUND */
+
+
+#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;
+
+ FileTimeToLocalFileTime(pft, &lft);
+ 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(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, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 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)) {
+ FileTime2utime(&Modft, &(z_ut->mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ FileTime2utime(&Accft, &(z_ut->atime));
+ else
+ z_ut->atime = z_ut->mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ FileTime2utime(&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(char *name)
+{
+ return(NULL); /* volunteers ? */
+}
+
+#ifdef UNICODE_SUPPORT
+wchar_t *GetLongPathEAW(wchar_t *name)
+{
+ return(NULL); /* volunteers ? */
+}
+#endif
+
+
+int IsFileNameValid(x)
+char *x;
+{
+ WIN32_FIND_DATA fd;
+ HANDLE h;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(x) + 1);
+
+ OemToAnsi(x, ansi_name);
+ x = 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))
+#if defined(__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.0) 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.
+ *
+ * The 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.)
+ *
+ * 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".
+ *
+ * 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).
+ */
+/* 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. */
+
+#ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ int zstat_zipwin32(const char *path, z_stat *buf)
+#else
+ int zstat_zipwin32(const char *path, struct stat *buf)
+#endif
+{
+# ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ if (!zstat(path, buf))
+# else
+ if (!stat(path, buf))
+# endif
+ {
+#ifdef NT_TZBUG_WORKAROUND
+ /* stat was successful, now redo the time-stamp fetches */
+ int fs_uses_loctime = FSusesLocalTime(path);
+ HANDLE h;
+ FILETIME Modft, Accft, Creft;
+#if defined(__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, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (h != INVALID_HANDLE_VALUE) {
+ BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
+ CloseHandle(h);
+
+ if (ftOK) {
+ 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.
+ */
+ FileTime2utime(&Modft, &(buf->st_mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ FileTime2utime(&Accft, &(buf->st_atime));
+ else
+ buf->st_atime = buf->st_mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ FileTime2utime(&Creft, &(buf->st_ctime));
+ else
+ buf->st_ctime = buf->st_mtime;
+ Tracev((stdout,"NTFS, recalculated modtime %08lx\n",
+ buf->st_mtime));
+ } else {
+ /* 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 /* NT_TZBUG_WORKAROUND */
+ return 0;
+ }
+#ifdef W32_STATROOT_FIX
+ else
+ {
+ DWORD flags;
+#if defined(__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));
+#ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ memset(buf, 0, sizeof(z_stat));
+#else
+ memset(buf, 0, sizeof(struct stat));
+#endif
+ 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;
+}
+
+
+# ifdef UNICODE_SUPPORT
+
+int zstat_zipwin32w(const wchar_t *pathw, zw_stat *buf)
+{
+ if (!zwstat(pathw, buf))
+ {
+#ifdef NT_TZBUG_WORKAROUND
+ /* stat was successful, now redo the time-stamp fetches */
+ int fs_uses_loctime = FSusesLocalTimeW(pathw);
+ HANDLE h;
+ FILETIME Modft, Accft, Creft;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(pathw) + 1);
+
+ OemToAnsi(path, ansi_path);
+# define Ansi_Path ansi_path
+#else
+# define Ansi_Path pathw
+#endif
+
+ Trace((stdout, "stat(%s) finds modtime %08lx\n", pathw, buf->st_mtime));
+ h = CreateFileW(Ansi_Path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (h != INVALID_HANDLE_VALUE) {
+ BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
+ CloseHandle(h);
+
+ if (ftOK) {
+ 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.
+ */
+ FileTime2utime(&Modft, &(buf->st_mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ FileTime2utime(&Accft, &(buf->st_atime));
+ else
+ buf->st_atime = buf->st_mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ FileTime2utime(&Creft, &(buf->st_ctime));
+ else
+ buf->st_ctime = buf->st_mtime;
+ Tracev((stdout,"NTFS, recalculated modtime %08lx\n",
+ buf->st_mtime));
+ } else {
+ /* 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 /* NT_TZBUG_WORKAROUND */
+ return 0;
+ }
+#ifdef W32_STATROOT_FIX
+ else
+ {
+ DWORD flags;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(pathw) + 1);
+
+ OemToAnsi(path, ansi_path);
+# define Ansi_Path ansi_path
+#else
+# define Ansi_Path pathw
+#endif
+
+ flags = GetFileAttributesW(Ansi_Path);
+ if (flags != 0xFFFFFFFF && flags & FILE_ATTRIBUTE_DIRECTORY) {
+ Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n",
+ pathw));
+#ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ memset(buf, 0, sizeof(z_stat));
+#else
+ memset(buf, 0, sizeof(struct stat));
+#endif
+ 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
+
+
+#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", " (32-bit)", COMPILE_DATE);
+
+ return;
+
+} /* end function version_local() */
+#endif /* !WINDLL */
+
+
+/* --------------------------------------------------- */
+/* Large File Support
+ *
+ * Moved to Win32i64.c to avoid conflicts in same name functions
+ * in WiZ using UnZip and Zip libraries.
+ * 9/25/2003
+ */
+
+
+/* --------------------------------------------------- */
+/* Unicode Support for Win32
+ *
+ */
+
+#ifdef UNICODE_SUPPORT
+# if 0
+
+ /* get the wide command line and convert to argvw */
+ /* windows ignores argv and gets argvw separately */
+ zchar **get_wide_argv(argv)
+ char **argv;
+ {
+ int i;
+ int argc;
+ int size;
+ zchar **argvw = NULL;
+ zchar *commandline = NULL;
+ zchar **a = NULL;
+
+ commandline = GetCommandLineW();
+ a = CommandLineToArgvW(commandline, &argc);
+
+ if (a == NULL) {
+ /* failed */
+ ZIPERR(ZE_COMPERR, "get_wide_argv");
+ }
+
+ /* copy args so can use free_args() */
+ if ((argvw = (zchar **)malloc((argc + 1) * sizeof(zchar *))) == NULL) {
+ ZIPERR(ZE_MEM, "get_wide_argv");
+ }
+ for (i = 0; i < argc; i++) {
+ size = zstrlen(a[i]) + 1;
+ if ((argvw[i] = (zchar *)malloc(size * sizeof(zchar))) == NULL) {
+ ZIPERR(ZE_MEM, "get_wide_argv");
+ }
+ if ((argvw[i] = copy_zstring(a[i])) == NULL) {
+ ZIPERR(ZE_MEM, "get_wide_argv");
+ }
+ }
+ argvw[argc] = L'\0';
+
+ /* free original argvw */
+ LocalFree(a);
+
+ return argvw;
+ }
+# endif
+
+
+/* convert wide character string to multi-byte character string */
+/* win32 version */
+char *wide_to_local_string(wide_string)
+ zwchar *wide_string;
+{
+ int i;
+ wchar_t wc;
+ int bytes_char;
+ int default_used;
+ int wsize = 0;
+ int max_bytes = 9;
+ char buf[9];
+ char *buffer = NULL;
+ char *local_string = NULL;
+
+ if (wide_string == NULL)
+ return NULL;
+
+ for (wsize = 0; wide_string[wsize]; wsize++) ;
+
+ if (max_bytes < MB_CUR_MAX)
+ max_bytes = MB_CUR_MAX;
+
+ if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "wide_to_local_string");
+ }
+
+ /* convert it */
+ buffer[0] = '\0';
+ for (i = 0; i < wsize; i++) {
+ if (sizeof(wchar_t) < 4 && wide_string[i] > 0xFFFF) {
+ /* wchar_t probably 2 bytes */
+ /* could do surrogates if state_dependent and wctomb can do */
+ wc = zwchar_to_wchar_t_default_char;
+ } else {
+ wc = (wchar_t)wide_string[i];
+ }
+ /* Unter some vendor's C-RTL, the Wide-to-MultiByte conversion functions
+ * (like wctomb() et. al.) do not use the same codepage as the other
+ * string arguments I/O functions (fopen, mkdir, rmdir etc.).
+ * Therefore, we have to fall back to the underlying Win32-API call to
+ * achieve a consistent behaviour for all supported compiler environments.
+ * Failing RTLs are for example:
+ * Borland (locale uses OEM-CP as default, but I/O functions expect ANSI
+ * names)
+ * Watcom (only "C" locale, wctomb() always uses OEM CP)
+ * (in other words: all supported environments except the Microsoft RTLs)
+ */
+ bytes_char = WideCharToMultiByte(
+ CP_ACP, WC_COMPOSITECHECK,
+ &wc, 1,
+ (LPSTR)buf, sizeof(buf),
+ NULL, &default_used);
+ if (default_used)
+ bytes_char = -1;
+ if (unicode_escape_all) {
+ if (bytes_char == 1 && (uch)buf[0] <= 0x7f) {
+ /* ASCII */
+ strncat(buffer, buf, 1);
+ } else {
+ /* use escape for wide character */
+ char *e = wide_char_to_escape_string(wide_string[i]);
+ strcat(buffer, e);
+ free(e);
+ }
+ } else if (bytes_char > 0) {
+ /* multi-byte char */
+ strncat(buffer, buf, bytes_char);
+ } else {
+ /* no MB for this wide */
+ if (use_wide_to_mb_default) {
+ /* default character */
+ strcat(buffer, wide_to_mb_default_string);
+ } else {
+ /* use escape for wide character */
+ char *e = wide_char_to_escape_string(wide_string[i]);
+ strcat(buffer, e);
+ free(e);
+ }
+ }
+ }
+ if ((local_string = (char *)realloc(buffer, strlen(buffer) + 1)) == NULL) {
+ free(buffer);
+ ZIPERR(ZE_MEM, "wide_to_local_string");
+ }
+
+ return local_string;
+}
+
+/* convert multi-byte character string to wide character string */
+/* win32 version */
+zwchar *local_to_wide_string(local_string)
+ char *local_string;
+{
+ int wsize;
+ wchar_t *wc_string;
+ zwchar *wide_string;
+
+ /* for now try to convert as string - fails if a bad char in string */
+ wsize = MultiByteToWideChar(CP_ACP, 0,
+ local_string, -1, NULL, 0);
+ if (wsize == (size_t)-1) {
+ /* could not convert */
+ return NULL;
+ }
+
+ /* convert it */
+ if ((wc_string = (wchar_t *)malloc((wsize + 1) * sizeof(wchar_t))) == NULL) {
+ ZIPERR(ZE_MEM, "local_to_wide_string");
+ }
+ wsize = MultiByteToWideChar(CP_ACP, 0,
+ local_string, -1,
+ wc_string, wsize + 1);
+ wc_string[wsize] = (wchar_t) 0;
+
+ /* in case wchar_t is not zwchar */
+ if ((wide_string = (zwchar *)malloc((wsize + 1) * sizeof(zwchar))) == NULL) {
+ free(wc_string);
+ ZIPERR(ZE_MEM, "local_to_wide_string");
+ }
+ for (wsize = 0; (wide_string[wsize] = (zwchar)wc_string[wsize]); wsize++) ;
+ wide_string[wsize] = (zwchar)0;
+ free(wc_string);
+
+ return wide_string;
+}
+#endif /* UNICODE_SUPPORT */
+
+
+/*
+# if defined(UNICODE_SUPPORT) || defined(WIN32_OEM)
+*/
+/* convert oem to ansi character string */
+char *oem_to_local_string(local_string, oem_string)
+ char *local_string;
+ char *oem_string;
+{
+ /* convert OEM to ANSI character set */
+ OemToChar(oem_string, local_string);
+
+ return local_string;
+}
+/*
+# endif
+*/
+
+
+/*
+#if defined(UNICODE_SUPPORT) || defined(WIN32_OEM)
+*/
+/* convert local to oem character string */
+char *local_to_oem_string(oem_string, local_string)
+ char *oem_string;
+ char *local_string;
+{
+ /* convert to OEM display character set */
+ CharToOem(local_string, oem_string);
+ return oem_string;
+}
+/*
+#endif
+*/
+
diff --git a/win32/win32i64.c b/win32/win32i64.c
new file mode 100644
index 0000000..a07eb1a
--- /dev/null
+++ b/win32/win32i64.c
@@ -0,0 +1,115 @@
+/*
+ win32/win32i64.c - Zip 3
+
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2005-Feb-10 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
+*/
+
+#include "../zip.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <time.h>
+#include <ctype.h>
+#include <windows.h>
+/* for LARGE_FILE_SUPPORT but may not be needed */
+#include <io.h>
+
+
+/* --------------------------------------------------- */
+/* Large File Support
+ *
+ * Initial functions by E. Gordon and R. Nausedat
+ * 9/10/2003
+ *
+ * These implement 64-bit file support for Windows. The
+ * defines and headers are in win32/osdep.h.
+ *
+ * These moved from win32.c by Mike White to avoid conflicts
+ * in WiZ of same name functions in UnZip and Zip libraries.
+ * 9/25/04 EG
+ */
+
+#if defined(LARGE_FILE_SUPPORT) && !defined(__CYGWIN__)
+
+/* 64-bit buffered ftello
+ *
+ * Win32 does not provide a 64-bit buffered
+ * ftell (in the published api anyway) so below provides
+ * hopefully close version.
+ * We have not gotten _telli64 to work with buffered
+ * streams. Below cheats by using fgetpos improperly and
+ * may not work on other ports.
+ */
+
+zoff_t zftello(stream)
+ FILE *stream;
+{
+ fpos_t fpos = 0;
+
+ if (fgetpos(stream, &fpos) != 0) {
+ return -1L;
+ } else {
+ return fpos;
+ }
+}
+
+
+/* 64-bit buffered fseeko
+ *
+ * Win32 does not provide a 64-bit buffered
+ * fseeko so use _lseeki64 and fflush. Note
+ * that SEEK_CUR can lose track of location
+ * if fflush is done between the last buffered
+ * io and this call.
+ */
+
+int zfseeko(stream, offset, origin)
+ FILE *stream;
+ zoff_t offset;
+ int origin;
+{
+ zoff_t location;
+
+ location = zftello(stream);
+ fflush(stream);
+ if (origin == SEEK_CUR) {
+ /* instead of synching up lseek easier just to figure and
+ use an absolute offset */
+ offset = location + offset;
+ location = _lseeki64(fileno(stream), offset, SEEK_SET);
+ } else {
+ location = _lseeki64(fileno(stream), offset, origin);
+ }
+ if (location == -1L) {
+ return -1L;
+ } else {
+ return 0;
+ }
+}
+#endif /* Win32 LARGE_FILE_SUPPORT */
+
+#if 0
+FILE* zfopen(filename,mode)
+char *filename;
+char *mode;
+{
+FILE* fTemp;
+
+ fTemp = fopen(filename,mode);
+ if( fTemp == NULL )
+ return NULL;
+
+ /* sorry, could not make VC60 and its rtl work properly without setting the file buffer to NULL. the */
+ /* problem seems to be _telli64 which seems to return the max stream position, comments are welcome */
+ setbuf(fTemp,NULL);
+
+ return fTemp;
+}
+#endif
+/* --------------------------------------------------- */
diff --git a/win32/win32zip.c b/win32/win32zip.c
new file mode 100644
index 0000000..07c8886
--- /dev/null
+++ b/win32/win32zip.c
@@ -0,0 +1,1980 @@
+/*
+ win32/win32zip.c - Zip 3
+
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+#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
+#define WIN32_LEAN_AND_MEAN
+#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)
+
+
+#ifdef UNICODE_SUPPORT
+typedef struct zdirscanw {
+ HANDLE d_hFindFile;
+ int d_first;
+ WIN32_FIND_DATAW d_fdw;
+} zDIRSCANW;
+#endif
+
+typedef struct zdirscan {
+ HANDLE d_hFindFile;
+ int d_first;
+ WIN32_FIND_DATA d_fd;
+} zDIRSCAN;
+
+#define INVALID_WIN32_FILE_ATTRIBS ~0
+#ifdef UNICODE_SUPPORT
+#define GetDirAttribsW(d) ((d)->d_fdw.dwFileAttributes)
+#endif
+#define GetDirAttribs(d) ((d)->d_fd.dwFileAttributes)
+
+#include "../win32/win32zip.h"
+#include "../win32/nt.h"
+
+/* Local functions */
+local zDIRSCAN * OpenDirScan OF((ZCONST char *n));
+local struct zdirscan * GetNextDirEntry OF((zDIRSCAN *d));
+local void CloseDirScan OF((zDIRSCAN *d));
+
+#ifdef UNICODE_SUPPORT
+local zDIRSCANW * OpenDirScanW OF((ZCONST wchar_t *wn));
+local struct zdirscanw * GetNextDirEntryW OF((zDIRSCANW *dw));
+local void CloseDirScanW OF((zDIRSCANW *dw));
+#endif
+
+local char *readd OF((zDIRSCAN *));
+#ifdef UNICODE_SUPPORT
+local wchar_t *readdw OF((zDIRSCANW *));
+#endif
+
+local int wild_recurse OF((char *, char *));
+#ifdef UNICODE_SUPPORT
+local int wild_recursew OF((wchar_t *, wchar_t *));
+#endif
+
+#ifdef NTSD_EAS
+ local void GetSD OF((char *path, char **bufptr, ush *size,
+ char **cbufptr, ush *csize));
+#endif
+#ifdef USE_EF_UT_TIME
+ local int GetExtraTime OF((struct zlist far *z, iztimes *z_utim));
+#endif
+local int procname_win32 OF((char *n, int caseflag, DWORD attribs));
+#ifdef UNICODE_SUPPORT
+local int procname_win32w OF((wchar_t *n, int caseflag, DWORD attribs));
+#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[] = "*.*";
+
+
+#ifdef UNICODE_SUPPORT
+
+local zDIRSCANW *OpenDirScanW(nw)
+ZCONST wchar_t *nw; /* directory to open */
+/* Start searching for files in the MSDOS directory n */
+{
+ zDIRSCANW *dw; /* malloc'd return value */
+ wchar_t *pw; /* malloc'd temporary string */
+ wchar_t *qw;
+ size_t i;
+
+ if ((dw = (zDIRSCANW *)malloc(sizeof(zDIRSCANW))) == NULL) {
+ return NULL;
+ }
+
+ if ((pw = (wchar_t *)malloc(wcslen(nw) * sizeof(wchar_t) +
+ (2 + sizeof(wild_match_all)) * sizeof(wchar_t))) == NULL) {
+ if (dw != NULL) free((zvoid *)dw);
+ return NULL;
+ }
+ wcscpy(pw, nw);
+
+ qw = pw + wcslen(pw);
+ if ((qw - pw) > 0 && wcschr(pw, (wchar_t)':') == (qw - 1))
+ *qw++ = (wchar_t)'.';
+ if ((qw - pw) > 0 && wcschr(pw, (wchar_t)'/') != (qw - 1))
+ *qw++ = (wchar_t)'/';
+
+ for (i = 0; i < strlen(wild_match_all); i++) {
+ qw[i] = (wchar_t)wild_match_all[i];
+ }
+ qw[i] = (wchar_t)'\0';
+
+ dw->d_hFindFile = FindFirstFileW(pw, &dw->d_fdw);
+ free((zvoid *)pw);
+
+ if (dw->d_hFindFile == INVALID_HANDLE_VALUE)
+ {
+ free((zvoid *)dw);
+ return NULL;
+ }
+
+ dw->d_first = 1;
+ return dw;
+}
+
+#endif
+
+local zDIRSCAN *OpenDirScan(n)
+ZCONST char *n; /* directory to open */
+/* Start searching for files in the MSDOS directory n */
+{
+ zDIRSCAN *d; /* malloc'd return value */
+ char *p; /* malloc'd temporary string */
+ char *q;
+
+ if ((d = (zDIRSCAN *)malloc(sizeof(zDIRSCAN))) == 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);
+
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ OemToAnsi(p, p);
+#endif
+ d->d_hFindFile = FindFirstFile(p, &d->d_fd);
+ free((zvoid *)p);
+
+ if (d->d_hFindFile == INVALID_HANDLE_VALUE)
+ {
+ free((zvoid *)d);
+ return NULL;
+ }
+
+ d->d_first = 1;
+ return d;
+}
+
+
+#ifdef UNICODE_SUPPORT
+
+local struct zdirscanw *GetNextDirEntryW(dw)
+zDIRSCANW *dw; /* directory stream to read from */
+/* Return pointer to first or next directory entry, or NULL if end. */
+{
+ if (dw->d_first)
+ dw->d_first = 0;
+ else
+ {
+ if (!FindNextFileW(dw->d_hFindFile, &dw->d_fdw))
+ return NULL;
+ }
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ CharToOemW(dw->d_fdw.cFileName, dw->d_fdw.cFileName);
+#endif
+ return (struct zdirscanw *)dw;
+}
+
+#endif
+
+local struct zdirscan *GetNextDirEntry(d)
+zDIRSCAN *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
+ {
+ if (!FindNextFile(d->d_hFindFile, &d->d_fd))
+ return NULL;
+ }
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ AnsiToOem(d->d_fd.cFileName, d->d_fd.cFileName);
+#endif
+ return (struct zdirscan *)d;
+}
+
+local void CloseDirScan(d)
+zDIRSCAN *d; /* directory stream to close */
+{
+ FindClose(d->d_hFindFile);
+ free((zvoid *)d);
+}
+
+#ifdef UNICODE_SUPPORT
+
+local void CloseDirScanW(dw)
+zDIRSCANW *dw; /* directory stream to close */
+{
+ FindClose(dw->d_hFindFile);
+ free((zvoid *)dw);
+}
+
+#endif
+
+
+#ifdef UNICODE_SUPPORT
+
+local wchar_t *readdw(dw)
+ zDIRSCANW *dw; /* directory stream to read from */
+/* Return a pointer to the next name in the directory stream dw, or NULL if
+ no more entries or an error occurs. */
+{
+ struct zdirscanw *ew;
+
+ do
+ ew = GetNextDirEntryW(dw);
+ while (ew &&
+ ((!hidden_files && ew->d_fdw.dwFileAttributes & HIDD_SYS_BITS) ||
+ (only_archive_set &&
+ !(ew->d_fdw.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) &&
+ !(ew->d_fdw.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))));
+ if (ew == NULL)
+ return (wchar_t *) NULL;
+ return ew->d_fdw.cFileName;
+}
+
+#endif
+
+local char *readd(d)
+zDIRSCAN *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 zdirscan *e;
+
+ do
+ e = GetNextDirEntry(d);
+ while (e &&
+ ((!hidden_files && e->d_fd.dwFileAttributes & HIDD_SYS_BITS) ||
+ (only_archive_set &&
+ !(e->d_fd.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) &&
+ !(e->d_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))));
+ /* When a wide character that is not supported by the current character
+ set is found, FindFirstFile and FindNextFile return a "?" in that spot.
+ A question mark is illegal in file names, so this flags that something
+ needs to be done. It seems the fix is to use the 8.3 name in
+ this case, as that allows directory scans to continue.
+ */
+ if (e == NULL)
+ return (char *) NULL;
+ if (strchr(e->d_fd.cFileName, '?') && e->d_fd.cAlternateFileName) {
+ /* Have '?' in name, assume wide character we can't handle is in
+ the name and use short name if there is one.
+ */
+ return e->d_fd.cAlternateFileName;
+ }
+ return e->d_fd.cFileName;
+}
+
+
+#if 0
+/* scan for the file in p and return Windows long name */
+char *get_win32_longpath(p, n)
+ char *p; /* path to get short name path for */
+ char **n; /* pointer to name in returned path */
+{
+ char *q; /* return string */
+ char *c;
+ int is_dir = 0;
+ char *f;
+ char *fp;
+ int nr;
+ int fplen;
+ int fplen2;
+ HANDLE d_hFindFile;
+ WIN32_FIND_DATA d_fd;
+ int slashes = 0;
+ int returnslashes = 0;
+
+ if (p == NULL)
+ return NULL;
+
+ /* count path components */
+ for (f = p; *f; f++) {
+ if (*f == '/' || *f == '\\') {
+ slashes++;
+ }
+ }
+ /* Ignore trailing slash */
+ if (*p && (*(f - 1) == '/' || *(f - 1) == '\\'))
+ slashes--;
+
+ /* get the length of the full path */
+ fplen = GetFullPathName(p, 0, NULL, NULL);
+
+ if ((fp = malloc(fplen + 1)) == NULL) {
+ return NULL;
+ }
+ /* get full path */
+ fplen2 = GetFullPathName(p, fplen, fp, &f);
+ if (fplen2 > fplen) {
+ /* something changed */
+ free(fp);
+ return NULL;
+ }
+ c = fp + strlen(fp) - 1;
+ if (*c == '\\' || *c == '/') {
+ is_dir = 1;
+ *c = '\0';
+ }
+
+ d_hFindFile = FindFirstFile(fp, &d_fd);
+ free(fp);
+
+ if (d_hFindFile == INVALID_HANDLE_VALUE)
+ {
+ return NULL;
+ }
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ AnsiToOem(d->d_fd.cFileName, d->d_fd.cFileName);
+#endif
+
+ FindClose(d_hFindFile);
+
+ if (d_fd.cFileName == NULL) {
+ return NULL;
+ }
+
+ /* get the length of the full path */
+ fplen = GetFullPathName(d_fd.cFileName, 0, NULL, NULL);
+
+ if ((fp = malloc(fplen + 1)) == NULL) {
+ return NULL;
+ }
+ /* get full path */
+ fplen2 = GetFullPathName(d_fd.cFileName, fplen, fp, &f);
+ if (fplen2 > fplen) {
+ /* something changed */
+ free(fp);
+ return NULL;
+ }
+
+ /* characters from end to start of last component */
+ nr = 0;
+
+ /* find start of relative path we came in with */
+ for (f = fp + strlen(fp); f != fp; f--) {
+ if (*f == ':')
+ break;
+ if (*f == '/' || *f == '\\') {
+ returnslashes++;
+ /* convert \ to / */
+ *f = '/';
+ if (nr == 0)
+ /* first slash from end */
+ nr = strlen(fp) - (f - fp);
+ if (returnslashes > slashes)
+ break;
+ }
+ if (*f == '\\' && *(f + 1) == '\\')
+ break;
+ }
+ if (f != fp)
+ /* on slash in middle */
+ f++;
+
+ if ((q = malloc(strlen(f) + 2)) == NULL) {
+ return NULL;
+ }
+ strcpy(q, f);
+ *n = q + (strlen(q) - nr + 1);
+ if (is_dir) {
+ strcat(q, "/");
+ }
+ free(fp);
+
+ return q;
+}
+#endif
+
+
+#if 0
+/* scan for the file in p and return Windows UTF-8 name */
+char *get_win32_utf8path(p)
+ char *p; /* path to get utf-8 name for */
+{
+ char *q; /* return string */
+ char *r = NULL;
+ int is_dir = 0;
+ char *f;
+ char *fcp;
+ char *fp;
+ wchar_t *qw;
+ char *lastc = '\0';
+ int fplen;
+ int fplen2;
+ int ulen;
+ int ulenw;
+ HANDLE d_hFindFile;
+ WIN32_FIND_DATAW d_fd;
+ int pathslashes = 0;
+ int componentslashes = 0;
+ int slashes = 0;
+
+ if (p == NULL)
+ return NULL;
+
+ /* count path components */
+ for (f = p; *f; PREINCSTR(f)) {
+ if (*f == '/' || *f == '\\') {
+ slashes++;
+ }
+ lastc = f;
+ }
+ /* do not count trailing / */
+ if (*lastc == '/' || *lastc == '\\') {
+ is_dir = 1;
+ slashes--;
+ }
+
+ /* Get the short path (as a bad long path could cause FindFirstFile to fail) */
+
+ /* get the length of the short path */
+ fplen = GetShortPathName(p, NULL, 0);
+
+ if ((fp = malloc(fplen + 1)) == NULL) {
+ return NULL;
+ }
+ /* get short path */
+ fplen2 = GetShortPathName(p, fp, fplen);
+ if (fplen2 > fplen) {
+ /* something changed */
+ free(fp);
+ return NULL;
+ }
+
+ for (pathslashes = 0; pathslashes <= slashes; pathslashes++)
+ {
+
+ /* get component path */
+ if ((fcp = malloc(fplen + 1)) == NULL) {
+ return NULL;
+ }
+ strcpy(fcp, fp);
+ componentslashes = 0;
+ for (f = fcp; *f; PREINCSTR(f)) {
+ if (*f == '/' || *f == '\\') {
+ componentslashes++;
+ if (componentslashes > pathslashes)
+ break;
+ }
+ lastc = f;
+ }
+ *f = '\0';
+
+
+ /* Get information for the file, including wide path */
+
+ /* get length */
+ ulenw = MultiByteToWideChar(
+ CP_ACP, /* ANSI code page */
+ 0, /* flags for character-type options */
+ fcp, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0 ); /* buffer length (0 = return length) */
+ if (ulenw == 0) {
+ /* failed */
+ free(fcp);
+ free(fp);
+ return NULL;
+ }
+ ulenw++;
+ /* get length in bytes */
+ ulen = sizeof(wchar_t) * (ulenw + 1);
+ if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
+ free(fcp);
+ free(fp);
+ return NULL;
+ }
+ /* convert multibyte to wide */
+ ulen = MultiByteToWideChar(
+ CP_ACP, /* ANSI code page */
+ 0, /* flags for character-type options */
+ fcp, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ qw, /* buffer */
+ ulenw); /* buffer length (0 = return length) */
+ if (ulen == 0) {
+ /* failed */
+ free(qw);
+ free(fcp);
+ free(fp);
+ return 0;
+ }
+
+ d_hFindFile = FindFirstFileW(qw, &d_fd);
+ /* If this Win32 platform does not support Unicode wide paths
+ this returns INVALID_HANDLE_VALUE and the OS error is
+ "No such file or directory". We return NULL and go with
+ the UTF-8 version of z->iname in f->uname.
+ */
+ free(qw);
+ free(fcp);
+ FindClose(d_hFindFile);
+
+ if (d_hFindFile == INVALID_HANDLE_VALUE)
+ {
+ return NULL;
+ }
+
+ /* Get buffer length */
+ ulen = WideCharToMultiByte(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags */
+ d_fd.cFileName, /* string to convert */
+ -1, /* input chars (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0, /* size of buffer (0 = return needed size) */
+ NULL, /* default char */
+ NULL); /* used default char */
+ if (ulen == 0) {
+ /* failed */
+ return NULL;
+ }
+ ulen += 2;
+ if ((q = malloc(ulen + 1)) == NULL) {
+ return NULL;
+ }
+
+ /* Convert the Unicode string to UTF-8 */
+ if ((ulen = WideCharToMultiByte(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags */
+ d_fd.cFileName, /* string to convert */
+ -1, /* input chars (-1 = NULL terminated) */
+ q, /* buffer */
+ ulen, /* size of buffer (0 = return needed size) */
+ NULL, /* default char */
+ NULL)) == 0) /* used default char */
+ {
+ free(fp);
+ free(q);
+ return NULL;
+ }
+
+ if (r == NULL) {
+ /* first one */
+ r = q;
+ } else {
+ if ((r = realloc(r, strlen(r) + strlen(q) + 3)) == NULL) {
+ free(fp);
+ free(q);
+ return NULL;
+ }
+ strcat(r, "/");
+ strcat(r, q);
+ free(q);
+ }
+ }
+
+ free(fp);
+
+ if (is_dir) {
+ strcat(r, "/");
+ }
+
+ return r;
+}
+#endif
+
+
+#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. */
+
+
+#ifdef UNICODE_SUPPORT
+
+wchar_t *local_to_wchar_string(local_string)
+ char *local_string; /* path to get utf-8 name for */
+{
+ wchar_t *qw;
+ int ulen;
+ int ulenw;
+
+ if (local_string == NULL)
+ return NULL;
+
+ /* get length */
+ ulenw = MultiByteToWideChar(
+ CP_ACP, /* ANSI code page */
+ 0, /* flags for character-type options */
+ local_string, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0 ); /* buffer length (0 = return length) */
+ if (ulenw == 0) {
+ /* failed */
+ return NULL;
+ }
+ ulenw++;
+ /* get length in bytes */
+ ulen = sizeof(wchar_t) * (ulenw + 1);
+ if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
+ return NULL;
+ }
+ /* convert multibyte to wide */
+ ulen = MultiByteToWideChar(
+ CP_ACP, /* ANSI code page */
+ 0, /* flags for character-type options */
+ local_string, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ qw, /* buffer */
+ ulenw); /* buffer length (0 = return length) */
+ if (ulen == 0) {
+ /* failed */
+ free(qw);
+ return NULL;
+ }
+
+ return qw;
+}
+
+
+wchar_t *utf8_to_wchar_string(utf8_string)
+ char *utf8_string; /* path to get utf-8 name for */
+{
+ wchar_t *qw;
+ int ulen;
+ int ulenw;
+
+ if (utf8_string == NULL)
+ return NULL;
+
+ /* get length */
+ ulenw = MultiByteToWideChar(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags for character-type options */
+ utf8_string, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0 ); /* buffer length (0 = return length) */
+ if (ulenw == 0) {
+ /* failed */
+ return NULL;
+ }
+ ulenw++;
+ /* get length in bytes */
+ ulen = sizeof(wchar_t) * (ulenw + 1);
+ if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
+ return NULL;
+ }
+ /* convert multibyte to wide */
+ ulen = MultiByteToWideChar(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags for character-type options */
+ utf8_string, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ qw, /* buffer */
+ ulenw); /* buffer length (0 = return length) */
+ if (ulen == 0) {
+ /* failed */
+ free(qw);
+ return NULL;
+ }
+
+ return qw;
+}
+
+
+
+/* Convert wchar_t string to utf8 using Windows calls
+ so any characters needing more than one wchar_t are
+ are handled by Windows */
+char *wchar_to_utf8_string(wstring)
+ wchar_t *wstring;
+{
+ char *q; /* return string */
+ int ulen;
+
+ if (wstring == NULL)
+ return NULL;
+
+ /* Get buffer length */
+ ulen = WideCharToMultiByte(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags */
+ wstring, /* string to convert */
+ -1, /* input chars (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0, /* size of buffer (0 = return needed size) */
+ NULL, /* default char */
+ NULL); /* used default char */
+ if (ulen == 0) {
+ /* failed */
+ return NULL;
+ }
+ ulen += 2;
+ if ((q = malloc(ulen + 1)) == NULL) {
+ return NULL;
+ }
+
+ /* Convert the Unicode string to UTF-8 */
+ if ((ulen = WideCharToMultiByte(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags */
+ wstring, /* string to convert */
+ -1, /* input chars (-1 = NULL terminated) */
+ q, /* buffer */
+ ulen, /* size of buffer (0 = return needed size) */
+ NULL, /* default char */
+ NULL)) == 0) /* used default char */
+ {
+ free(q);
+ return NULL;
+ }
+
+ return q;
+}
+
+
+local int wild_recursew(whole, wildtail)
+ wchar_t *whole;
+ wchar_t *wildtail;
+{
+ zDIRSCANW *dirw;
+ wchar_t *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2;
+ extent newlen;
+ int amatch = 0, e = ZE_MISS;
+
+ if (!isshexpw(wildtail)) {
+ if (GetFileAttributesW(whole) != 0xFFFFFFFF) { /* file exists? */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ CharToOemW(whole, whole);
+#endif
+ return procnamew(whole, 0);
+ }
+ else
+ return ZE_MISS; /* woops, no wildcards! */
+ }
+
+ /* back up thru path components till existing dir found */
+ do {
+ name = wildtail + wcslen(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;
+ dirw = OpenDirScanW(whole);
+ } while (!dirw && subwild > wildtail);
+ wildtail = subwild; /* skip past non-wild components */
+
+ if ((subwild = wcschr(wildtail + 1, PATH_END)) != NULL) {
+ /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */
+ *(subwild++) = 0; /* wildtail = one component pattern */
+ newlen = wcslen(whole) + wcslen(subwild) + (ONENAMELEN + 2);
+ } else
+ newlen = wcslen(whole) + (ONENAMELEN + 1);
+ if (!dirw || ((newwhole = malloc(newlen * sizeof(wchar_t))) == NULL)) {
+ if (glue)
+ *glue = plug;
+ e = dirw ? ZE_MEM : ZE_MISS;
+ goto ohforgetit;
+ }
+ wcscpy(newwhole, whole);
+ newlen = wcslen(newwhole);
+ if (glue)
+ *glue = plug; /* repair damage to whole */
+ if (!isshexpw(wildtail)) {
+ e = ZE_MISS; /* non-wild name not found */
+ goto ohforgetit;
+ }
+
+ while ((name = readdw(dirw)) != NULL) {
+ if (wcscmp(name, L".") && wcscmp(name, L"..") &&
+ MATCHW(wildtail, name, 0)) {
+ wcscpy(newwhole + newlen, name);
+ if (subwild) {
+ name = newwhole + wcslen(newwhole);
+ *(name++) = (wchar_t)PATH_END;
+ wcscpy(name, subwild);
+ e = wild_recursew(newwhole, name);
+ } else
+ e = procname_win32w(newwhole, 0, GetDirAttribsW(dirw));
+ newwhole[newlen] = 0;
+ if (e == ZE_OK)
+ amatch = 1;
+ else if (e != ZE_MISS)
+ break;
+ }
+ }
+
+ ohforgetit:
+ if (dirw) CloseDirScanW(dirw);
+ if (subwild) *--subwild = PATH_END;
+ if (newwhole) free(newwhole);
+ if (e == ZE_MISS && amatch)
+ e = ZE_OK;
+ return e;
+}
+
+#endif
+
+
+local int wild_recurse(whole, wildtail)
+ char *whole;
+ char *wildtail;
+{
+ zDIRSCAN *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? */
+#if defined(__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 = OpenDirScan(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_win32(newwhole, 0, GetDirAttribs(dir));
+ newwhole[newlen] = 0;
+ if (e == ZE_OK)
+ amatch = 1;
+ else if (e != ZE_MISS)
+ break;
+ }
+ }
+
+ ohforgetit:
+ if (dir) CloseDirScan(dir);
+ if (subwild) *--subwild = PATH_END;
+ if (newwhole) free(newwhole);
+ if (e == ZE_MISS && amatch)
+ e = ZE_OK;
+ return e;
+}
+
+
+#ifdef UNICODE_SUPPORT
+int has_win32_wide() {
+ DWORD r;
+
+ /* test if we have wide function support */
+
+ /* check if already set */
+ if (no_win32_wide != -1)
+ return !no_win32_wide;
+
+ /* assume we don't */
+ no_win32_wide = 1;
+
+ /* get attributes for this directory */
+ r = GetFileAttributes(".");
+
+ /* r should be 16 = FILE_ATTRIBUTE_DIRECTORY */
+ if (r == FILE_ATTRIBUTE_DIRECTORY) {
+ /* now see if it works for the wide version */
+ r = GetFileAttributesW(L".");
+ /* if this fails then we probably don't have wide functions */
+ if (r == 0xFFFFFFFF) {
+ /* error is probably "This function is only valid in Win32 mode." */
+ } else if (r == FILE_ATTRIBUTE_DIRECTORY) {
+ /* worked, so assume we have wide support */
+ no_win32_wide = 0;
+ }
+ }
+
+ return !no_win32_wide;
+}
+#endif
+
+
+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 */
+#ifdef UNICODE_SUPPORT
+ wchar_t *pw; /* wide path */
+ wchar_t *qw; /* wide diskless path */
+#endif
+
+ 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 = '/';
+
+#ifdef UNICODE_SUPPORT
+ if (!no_win32_wide) {
+ /* wide char version */
+ pw = local_to_wchar_string(p);
+
+ /* Separate the disk part of the path */
+ if ((qw = wcschr(pw, ':')) != NULL) {
+ if (wcschr(++qw, ':')) /* sanity check for safety of wild_recurse */
+ return ZE_MISS;
+ } else
+ qw = pw;
+
+ /* Normalize bare disk names */
+ if (qw > pw && !*qw)
+ wcscpy(qw, L".");
+ } else {
+ /* multibyte version */
+ /* 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, ".");
+ }
+#else
+ /* multibyte version */
+ /* 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, ".");
+#endif
+
+ /* Here we go */
+#ifdef UNICODE_SUPPORT
+ if (!no_win32_wide) {
+ /* use wide Unicode directory scan */
+ e = wild_recursew(pw, qw);
+
+ free(pw);
+ } else {
+ /* use multibyte directory scan */
+ e = wild_recurse(p, q);
+ }
+#else
+ e = wild_recurse(p, q);
+#endif
+ free((zvoid *)p);
+ return e;
+}
+
+
+local int procname_win32(n, caseflag, attribs)
+ char *n; /* name to process */
+ int caseflag; /* true to force case-sensitive match */
+ DWORD attribs;
+/* 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 */
+ zDIRSCAN *d; /* directory stream from OpenDirScan() */
+ char *e; /* pointer to name from readd() */
+ int m; /* matched flag */
+ char *p; /* path for recursion */
+ z_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 (attribs != INVALID_WIN32_FILE_ATTRIBS)
+ {
+ /* Avoid calling stat() for performance reasons when it is already known
+ (from a previous directory scan) that the passed name corresponds to
+ a "real existing" file. The only information needed further down in
+ this function is the distinction between directory entries and other
+ (typically normal file) entries. This distinction can be derived from
+ the file's attributes that the directory lookup has already provided
+ "for free".
+ */
+ s.st_mode = ((attribs & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR : S_IFREG);
+ }
+ 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
+ )
+ {
+#ifdef UNICODE_SUPPORT
+ char *uname = NULL;
+#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->oname);
+ m = 0;
+ }
+ }
+#ifdef UNICODE_SUPPORT
+ /* also check escaped Unicode names */
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (z->zuname) {
+#ifdef WIN32
+ /* It seems something is lost in going from a listed
+ name from zip -su in a console window to using that
+ name in a command line. This kluge may fix it
+ and just takes zuname, converts to oem (i.e.ouname),
+ then converts it back which ends up not the same as
+ started with.
+ */
+ uname = z->wuname;
+#else
+ uname = z->zuname;
+#endif
+ if (MATCH(p, uname, caseflag))
+ {
+ z->mark = pcount ? filter(uname, caseflag) : 1;
+ if (verbose) {
+ fprintf(mesg, "zip diagnostic: %scluding %s\n",
+ z->mark ? "in" : "ex", z->oname);
+ fprintf(mesg, " Escaped Unicode: %s\n",
+ z->ouname);
+ }
+ m = 0;
+ }
+ }
+ }
+#endif
+ 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 exclusions in directory recurse but ignored for single file */
+ DWORD dwAttr;
+
+ dwAttr = GetFileMode(n);
+
+ if ((hidden_files ||
+ !(dwAttr & FILE_ATTRIBUTE_HIDDEN || dwAttr & FILE_ATTRIBUTE_SYSTEM)) &&
+ (!only_archive_set || (dwAttr & FILE_ATTRIBUTE_ARCHIVE)))
+ {
+ /* 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 = (char *) 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 = OpenDirScan(n)) != NULL)
+ {
+ while ((e = readd(d)) != NULL) {
+ if (strcmp(e, ".") && strcmp(e, ".."))
+ {
+ if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
+ {
+ CloseDirScan(d);
+ free((zvoid *)p);
+ return ZE_MEM;
+ }
+ strcat(strcpy(a, p), e);
+ if ((m = procname_win32(a, caseflag, GetDirAttribs(d)))
+ != ZE_OK) /* recurse on name */
+ {
+ if (m == ZE_MISS)
+ zipwarn("name not matched: ", a);
+ else
+ ziperr(m, a);
+ }
+ free((zvoid *)a);
+ }
+ }
+ CloseDirScan(d);
+ }
+ free((zvoid *)p);
+ } /* (s.st_mode & S_IFDIR) == 0) */
+ return ZE_OK;
+}
+
+
+#ifdef UNICODE_SUPPORT
+local int procname_win32w(nw, caseflag, attribs)
+ wchar_t *nw; /* name to process */
+ int caseflag; /* true to force case-sensitive match */
+ DWORD attribs;
+/* Process a name or sh expression to operate on (or exclude). Return
+ an error code in the ZE_ class. */
+{
+ wchar_t *aw; /* path and name for recursion */
+ zDIRSCANW *dw; /* directory stream from OpenDirScan() */
+ wchar_t *ew; /* pointer to name from readd() */
+ int m; /* matched flag */
+ wchar_t *pw; /* path for recursion */
+ zw_stat s; /* result of stat() */
+ struct zlist far *z; /* steps through zfiles list */
+
+ if (wcscmp(nw, L"-") == 0) /* if compressing stdin */
+ return newnamew(nw, 0, caseflag);
+ else if (attribs != INVALID_WIN32_FILE_ATTRIBS)
+ {
+ /* Avoid calling stat() for performance reasons when it is already known
+ (from a previous directory scan) that the passed name corresponds to
+ a "real existing" file. The only information needed further down in
+ this function is the distinction between directory entries and other
+ (typically normal file) entries. This distinction can be derived from
+ the file's attributes that the directory lookup has already provided
+ "for free".
+ */
+ s.st_mode = ((attribs & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR : S_IFREG);
+ }
+ else if (LSSTATW(nw, &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. */
+ || isshexpw(nw)
+#endif
+ )
+ {
+ wchar_t *unamew = NULL;
+ /* Not a file or directory--search for shell expression in zip file */
+ pw = ex2inw(nw, 0, (int *)NULL); /* shouldn't affect matching chars */
+ m = 1;
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (MATCHW(pw, z->znamew, caseflag))
+ {
+ z->mark = pcount ? filter(z->zname, caseflag) : 1;
+ if (verbose)
+ fprintf(mesg, "zip diagnostic: %scluding %s\n",
+ z->mark ? "in" : "ex", z->oname);
+ m = 0;
+ }
+ }
+ /* also check escaped Unicode names */
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (z->zuname) {
+ unamew = z->znamew;
+ if (MATCHW(pw, unamew, caseflag))
+ {
+ z->mark = pcount ? filter(z->iname, caseflag) : 1;
+ if (verbose) {
+ fprintf(mesg, "zip diagnostic: %scluding %s\n",
+ z->mark ? "in" : "ex", z->oname);
+ fprintf(mesg, " Escaped Unicode: %s\n",
+ z->ouname);
+ }
+ m = 0;
+ }
+ }
+ }
+ free((zvoid *)pw);
+ return m ? ZE_MISS : ZE_OK;
+ }
+
+ /* Live name--use if file, recurse if directory */
+ for (pw = nw; *pw; pw++) /* use / consistently */
+ if (*pw == (wchar_t)'\\')
+ *pw = (wchar_t)'/';
+ if ((s.st_mode & S_IFDIR) == 0)
+ {
+ /* add exclusions in directory recurse but ignored for single file */
+ DWORD dwAttr;
+
+ dwAttr = GetFileModeW(nw);
+
+ if ((hidden_files ||
+ !(dwAttr & FILE_ATTRIBUTE_HIDDEN || dwAttr & FILE_ATTRIBUTE_SYSTEM)) &&
+ (!only_archive_set || (dwAttr & FILE_ATTRIBUTE_ARCHIVE)))
+ {
+ /* add or remove name of file */
+ if ((m = newnamew(nw, 0, caseflag)) != ZE_OK)
+ return m;
+ }
+ } else {
+ /* Add trailing / to the directory name */
+ pw = (wchar_t *)malloc( (wcslen(nw)+2) * sizeof(wchar_t) );
+ if (pw == NULL)
+ return ZE_MEM;
+ if (wcscmp(nw, L".") == 0 || wcscmp(nw, L"/.") == 0) {
+ *pw = (wchar_t)'\0'; /* avoid "./" prefix and do not create zip entry */
+ } else {
+ wcscpy(pw, nw);
+ aw = pw + wcslen(pw);
+ if (pw[wcslen(pw) - 1] != (wchar_t)'/')
+ wcscpy(aw, L"/");
+ if (dirnames && (m = newnamew(pw, 1, caseflag)) != ZE_OK) {
+ free((zvoid *)pw);
+ return m;
+ }
+ }
+ /* recurse into directory */
+ if (recurse && (dw = OpenDirScanW(nw)) != NULL)
+ {
+ while ((ew = readdw(dw)) != NULL) {
+ if (wcscmp(ew, L".") && wcscmp(ew, L".."))
+ {
+ if ((aw = malloc((wcslen(pw) + wcslen(ew) + 1) * sizeof(wchar_t))) == NULL)
+ {
+ CloseDirScanW(dw);
+ free((zvoid *)pw);
+ return ZE_MEM;
+ }
+ wcscat(wcscpy(aw, pw), ew);
+ if ((m = procname_win32w(aw, caseflag, GetDirAttribsW(dw)))
+ != ZE_OK) /* recurse on name */
+ {
+ char *a;
+ char *ad;
+
+ a = wchar_to_local_string(aw);
+ ad = local_to_display_string(a);
+
+ if (m == ZE_MISS)
+ zipwarn("name not matched: ", ad);
+ else
+ ziperr(m, a);
+ free(ad);
+ free(a);
+ }
+ free((zvoid *)aw);
+ }
+ }
+ CloseDirScanW(dw);
+ }
+ free((zvoid *)pw);
+ } /* (s.st_mode & S_IFDIR) == 0) */
+ return ZE_OK;
+}
+#endif
+
+
+#ifdef UNICODE_SUPPORT
+int procnamew(nw, caseflag)
+ wchar_t *nw; /* name to process */
+ int caseflag; /* true to force case-sensitive match */
+{
+ return procname_win32w(nw, caseflag, INVALID_WIN32_FILE_ATTRIBS);
+}
+#endif
+
+int procname(n, caseflag)
+ char *n; /* name to process */
+ int caseflag; /* true to force case-sensitive match */
+{
+ return procname_win32(n, caseflag, INVALID_WIN32_FILE_ATTRIBS);
+}
+
+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 + MB_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;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ OemToAnsi(n, n);
+#endif
+ return n;
+}
+
+#ifdef UNICODE_SUPPORT
+wchar_t *ex2inw(xw, isdir, pdosflag)
+ wchar_t *xw; /* 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. */
+{
+ wchar_t *nw; /* internal file name (malloc'ed) */
+ wchar_t *tw; /* shortened name */
+ int dosflag;
+
+
+ dosflag = dosify || IsFileSystemOldFATW(xw);
+ if (!dosify && use_longname_ea && (tw = GetLongPathEAW(xw)) != NULL)
+ {
+ xw = tw;
+ dosflag = 0;
+ }
+
+ /* Find starting point in name before doing malloc */
+ /* Strip drive specification */
+ tw = *xw && iswascii(*xw) && *(xw + 1) == (wchar_t)':' ? xw + 2 : xw;
+ /* Strip "//host/share/" part of a UNC name */
+ if ((!wcsncmp(xw,L"//",2) || !wcsncmp(xw,L"\\\\",2)) &&
+ (xw[2] != (wchar_t)'\0' && xw[2] != (wchar_t)'/' && xw[2] != (wchar_t)'\\')) {
+ nw = xw + 2;
+ while (*nw != (wchar_t)'\0' && *nw != (wchar_t)'/' && *nw != (wchar_t)'\\')
+ nw++; /* strip host name */
+ if (*nw != (wchar_t)'\0') {
+ nw++;
+ while (*nw != (wchar_t)'\0' && *nw != (wchar_t)'/' && *nw != (wchar_t)'\\')
+ nw++; /* strip `share' name */
+ }
+ if (*nw != (wchar_t)'\0')
+ tw = nw++;
+ }
+ /* Strip leading "/" to convert an absolute path into a relative path */
+ while (*tw == (wchar_t)'/' || *tw == (wchar_t)'\\')
+ tw++;
+ /* Strip leading "./" as well as drive letter */
+ while (*tw == (wchar_t)'.' && (tw[1] == (wchar_t)'/' || tw[1] == (wchar_t)'\\'))
+ tw += 2;
+
+ /* Make changes, if any, to the copied name (leave original intact) */
+ for (nw = tw; *nw; nw++)
+ if (*nw == '\\')
+ *nw = '/';
+
+ if (!pathput)
+ tw = lastw(tw, PATH_END);
+
+ /* Malloc space for internal name and copy it */
+ if ((nw = malloc((wcslen(tw) + 1) * sizeof(wchar_t))) == NULL)
+ return NULL;
+ wcscpy(nw, tw);
+
+ if (dosify)
+ msnamew(nw);
+
+ /* Returned malloc'ed name */
+ if (pdosflag)
+ *pdosflag = dosflag;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ CharToAnsiW(nw, nw);
+#endif
+ return nw;
+}
+#endif
+
+
+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);
+# if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ AnsiToOem(x, x);
+# endif
+ return x;
+}
+
+#ifdef UNICODE_SUPPORT
+wchar_t *in2exw(nw)
+ wchar_t *nw; /* internal file name */
+/* Convert the zip file name to an external file name, returning the malloc'ed
+ string or NULL if not enough memory. */
+{
+ wchar_t *xw; /* external file name */
+
+ if ((xw = malloc((wcslen(nw) + 1 + PAD) * sizeof(wchar_t))) == NULL)
+ return NULL;
+ wcscpy(xw, nw);
+# if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ CharToOemW(xw, xw);
+# endif
+ return xw;
+}
+#endif
+
+
+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 */
+ zoff_t *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 */
+{
+ z_stat s; /* results of zstat() */
+
+ /* converted to malloc instead of using FNMAX - 11/8/04 EG */
+ 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 */
+
+ /* zip64 support 08/31/2003 R.Nausedat */
+ if (isstdin) {
+ if (zfstat(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) {
+#ifdef WIN32_OEM
+ /* When creating DOS-like archives with OEM-charset names, only the
+ standard FAT attributes should be used.
+ (Note: On a Win32 system, the UNIX style attributes from stat()
+ do not contain any additional information...)
+ */
+ *a = (isstdin ? 0L : (ulg)GetFileMode(name));
+#else
+ *a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileMode(name));
+#endif
+ }
+ if (n != NULL)
+ /* device return -1 */
+ *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 UNICODE_SUPPORT
+ulg filetimew(fw, a, n, t)
+ wchar_t *fw; /* name of file to get info on */
+ ulg *a; /* return value: file attributes */
+ zoff_t *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 */
+{
+ zw_stat sw; /* results of zstat() */
+
+ /* converted to malloc instead of using FNMAX - 11/8/04 EG */
+ wchar_t *namew;
+ unsigned int len = wcslen(fw);
+ int isstdin = !wcscmp(fw, L"-");
+ wchar_t *labelw = local_to_wchar_string(label);
+
+ if (labelw && wcscmp(fw, labelw) == 0) {
+ 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 ((namew = malloc((len + 1) * sizeof(wchar_t))) == NULL) {
+ ZIPERR(ZE_MEM, "filetime");
+ }
+ wcscpy(namew, fw);
+ if (wcsrchr(namew, (wchar_t)'/') == (namew + len - 1))
+ namew[len - 1] = '\0';
+ /* not all systems allow stat'ing a file with / appended */
+
+ /* zip64 support 08/31/2003 R.Nausedat */
+ if (isstdin) {
+ if (zwfstat(fileno(stdin), &sw) != 0) {
+ free(namew);
+ error("fstat(stdin)");
+ }
+ time((time_t *)&sw.st_mtime); /* some fstat()s return time zero */
+ } else if (LSSTATW(namew, &sw) != 0) {
+ /* Accept about any file kind including directories
+ * (stored with trailing / with -r option)
+ */
+ free(namew);
+ return 0;
+ }
+
+ if (a != NULL) {
+#ifdef WIN32_OEM
+ /* When creating DOS-like archives with OEM-charset names, only the
+ standard FAT attributes should be used.
+ (Note: On a Win32 system, the UNIX style attributes from stat()
+ do not contain any additional information...)
+ */
+ *a = (isstdin ? 0L : (ulg)GetFileModeW(namew));
+#else
+ *a = ((ulg)sw.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileModeW(namew));
+#endif
+ }
+ if (n != NULL)
+ /* device return -1 */
+ *n = (sw.st_mode & S_IFMT) == S_IFREG ? sw.st_size : -1L;
+ if (t != NULL) {
+ t->atime = sw.st_atime;
+ t->mtime = sw.st_mtime;
+ t->ctime = sw.st_ctime;
+ }
+ free(namew);
+
+ return unix2dostime((time_t *)&sw.st_mtime);
+}
+#endif
+
+
+
+#ifdef NTSD_EAS
+
+/* changed size, csize from size_t to ush 3/10/2005 EG */
+local void GetSD(char *path, char **bufptr, ush *size,
+ char **cbufptr, ush *csize)
+{
+ unsigned char stackbuffer[NTSD_BUFFERSIZE];
+ unsigned long bytes = NTSD_BUFFERSIZE;
+ unsigned char *buffer = stackbuffer;
+ unsigned char *DynBuffer = NULL;
+ ulg 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);
+
+ if (cbytes > 0x7FFF) {
+ sprintf(errbuf, "security info too large to store (%ld bytes), %d max", bytes, 0x7FFF);
+ zipwarn(errbuf, "");
+ zipwarn("security info not stored: ", path);
+ if(DynBuffer) free(DynBuffer);
+ return;
+ }
+
+ *size += EF_NTSD_L_LEN + (ush)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) {
+ sprintf(errbuf, " (%ld bytes security)", bytes);
+ zipmessage_nl(errbuf, 0);
+ }
+
+ 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..3d8bca5
--- /dev/null
+++ b/win32/win32zip.h
@@ -0,0 +1,42 @@
+/*
+ win32/win32zip.h - Zip 3
+
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+#ifndef _WIN32ZIP_H
+#define _WIN32ZIP_H
+
+/*
+ * NT specific functions for ZIP.
+ */
+
+int GetFileMode(char *name);
+#ifdef UNICODE_SUPPORT
+int GetFileModeW(wchar_t *name);
+#endif
+long GetTheFileTime(char *name, iztimes *z_times);
+
+int IsFileNameValid(char *name);
+int IsFileSystemOldFAT(char *dir);
+#ifdef UNICODE_SUPPORT
+int IsFileSystemOldFATW(wchar_t *dir);
+#endif
+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(char *name);
+#ifdef UNICODE_SUPPORT
+wchar_t *GetLongPathEAW(wchar_t *name);
+#endif
+
+#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/zip.rc b/win32/zip.rc
new file mode 100644
index 0000000..3ecb961
--- /dev/null
+++ b/win32/zip.rc
@@ -0,0 +1,53 @@
+#include <windows.h>
+#if (defined(WIN32) && !defined(__EMX__) && !defined(__MINGW32__))
+#include <winver.h>
+#endif
+#define IZ_VERSION_SYMBOLS_ONLY
+#include "../revision.h"
+#undef IZ_VERSION_SYMBOLS_ONLY
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION Z_MAJORVER,Z_MINORVER,Z_PATCHLEVEL,0
+ PRODUCTVERSION Z_MAJORVER,Z_MINORVER,Z_PATCHLEVEL,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+#ifdef _UNICODE
+ BLOCK "040904B0"
+#else
+ BLOCK "040904E4"
+#endif
+ BEGIN
+ VALUE "CompanyName", IZ_COMPANY_NAME "\0"
+ VALUE "FileDescription", "Info-ZIP Zip for Win32 console\0"
+ VALUE "FileVersion", VERSION "\0"
+ VALUE "InternalName", "zip\0"
+ VALUE "LegalCopyright", "Copyright © Info-ZIP 1997 - 2008\0"
+ VALUE "OriginalFilename", "zip.exe\0"
+ VALUE "ProductName", "Zip\0"
+ VALUE "ProductVersion", VERSION "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+#ifdef _UNICODE
+ VALUE "Translation", 0x409, 1200
+#else
+ VALUE "Translation", 0x409, 1252
+#endif
+ END
+END
diff --git a/win32/zipup.h b/win32/zipup.h
new file mode 100644
index 0000000..9505b56
--- /dev/null
+++ b/win32/zipup.h
@@ -0,0 +1,48 @@
+/*
+ win32/zipup.h - Zip 3
+
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 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
+*/
+#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
+#ifdef UNICODE_SUPPORT
+# if defined(__CYGWIN__) || defined(__IBMC__)
+# define zwopen(n,p) wopen(n,p)
+# else
+# define zwopen(n,p) _wsopen(n,p,_SH_DENYNO)
+# endif
+#endif
+
+#define zread(f,b,n) read(f,b,n)
+#define zclose(f) close(f)
+#define zerr(f) (k == (extent)(-1L))
+#define zstdin 0