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