1/*
2  win32/osdep.h
3
4  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
5
6  See the accompanying file LICENSE, version 2007-Mar-4 or later
7  (the contents of which are also included in zip.h) for terms of use.
8  If, for some reason, all these files are missing, the Info-ZIP license
9  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
10*/
11
12/* Automatic setting of the common Microsoft C idenfifier MSC.
13 * NOTE: Watcom also defines M_I*86 !
14 */
15#if defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__))
16#  ifndef MSC
17#    define MSC                 /* This should work for older MSC, too!  */
18#  endif
19#endif
20
21/* Tell Microsoft Visual C++ 2005 to leave us alone and
22 * let us use standard C functions the way we're supposed to.
23 */
24#if defined(_MSC_VER) && (_MSC_VER >= 1400)
25#  ifndef _CRT_SECURE_NO_DEPRECATE
26#    define _CRT_SECURE_NO_DEPRECATE
27#  endif
28#  ifndef _CRT_NONSTDC_NO_DEPRECATE
29#    define _CRT_NONSTDC_NO_DEPRECATE
30#  endif
31#endif
32
33#if defined(__WATCOMC__) && defined(__386__)
34#  define WATCOMC_386
35#endif
36
37#if (defined(__CYGWIN32__) && !defined(__CYGWIN__))
38#  define __CYGWIN__            /* compatibility for CygWin B19 and older */
39#endif
40
41/* enable multibyte character set support by default */
42#ifndef _MBCS
43#  define _MBCS
44#endif
45#if defined(__CYGWIN__)
46#  undef _MBCS
47#endif
48
49/* Get types and stat */
50#include <sys/types.h>
51#include <sys/stat.h>
52#include <io.h>
53
54#ifndef MSDOS
55/*
56 * Windows 95 (and Windows NT) file systems are (to some extend)
57 * extensions of MSDOS. Common features include for example:
58 *      FAT or (FAT like) file systems,
59 *      '\\' as directory separator in paths,
60 *      "\r\n" as record (line) terminator in text files, ...
61 */
62#  define MSDOS
63/* inherit MS-DOS file system etc. stuff */
64#endif
65
66#define USE_CASE_MAP
67#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \
68                     procname(n, filter_match_case))
69#define BROKEN_FSEEK
70#ifndef __RSXNT__
71#  define HAVE_FSEEKABLE
72#endif
73
74
75/* popen
76 *
77 * On Win32 must map to _popen() and _pclose()
78 */
79#define popen _popen
80#define pclose _pclose
81
82/* WIN32_OEM
83 *
84 * This enables storing paths in archives on WIN32 in OEM format
85 * which is more work but seems the standard now.  It also enables
86 * converting paths in read DOS archives from assumed OEM to ANSI.
87 */
88#ifndef NO_WIN32_OEM
89#  define WIN32_OEM
90#endif
91
92/* Large File Support
93 *
94 *  If this is set it is assumed that the port
95 *  supports 64-bit file calls.  The types are
96 *  defined here.  Any local implementations are
97 *  in Win32.c and the prototypes for the calls are
98 *  in tailor.h.  Note that a port must support
99 *  these calls fully or should not set
100 *  LARGE_FILE_SUPPORT.
101 */
102
103/* Note also that ZOFF_T_FORMAT_SIZE_PREFIX has to be defined here
104   or tailor.h will define defaults */
105
106/* If port has LARGE_FILE_SUPPORT then define here
107   to make large file support automatic unless overridden */
108
109
110#ifndef LARGE_FILE_SUPPORT
111# ifndef NO_LARGE_FILE_SUPPORT
112    /* MS C and VC */
113#   if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
114#     define LARGE_FILE_SUPPORT
115#   endif
116#   if defined(__WATCOMC__)
117#     define LARGE_FILE_SUPPORT
118#   endif
119# endif
120#endif
121
122#ifdef LARGE_FILE_SUPPORT
123  /* 64-bit Large File Support */
124
125  /* Only types and the printf format stuff go here.  Functions
126     go in tailor.h since ANSI prototypes are required and the OF define
127     is not defined here. */
128
129# if (defined(_MSC_VER) && (_MSC_VER >= 1100)) || defined(__MINGW32__)
130    /* MS C and VC, MinGW32 */
131    /* these compiler systems use the Microsoft C RTL */
132
133    /* base types for file offsets and file sizes */
134    typedef __int64             zoff_t;
135    typedef unsigned __int64    uzoff_t;
136
137    /* 64-bit stat struct */
138    typedef struct _stati64 z_stat;
139
140    /* printf format size prefix for zoff_t values */
141#   define ZOFF_T_FORMAT_SIZE_PREFIX "I64"
142
143# elif (defined(__GNUC__) || defined(ULONG_LONG_MAX))
144    /* GNU C */
145
146    /* base types for file offsets and file sizes */
147    typedef long long           zoff_t;
148    typedef unsigned long long  uzoff_t;
149
150#  ifdef __CYGWIN__
151    /* Use Cygwin's own stat struct */
152     typedef struct stat z_stat;
153#  else
154    /* 64-bit stat struct */
155    typedef struct _stati64 z_stat;
156#  endif
157
158    /* printf format size prefix for zoff_t values */
159#   define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
160
161# elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))
162    /* WATCOM C */
163
164    /* base types for file offsets and file sizes */
165    typedef __int64             zoff_t;
166    typedef unsigned __int64    uzoff_t;
167
168    /* 64-bit stat struct */
169    typedef struct _stati64 z_stat;
170
171    /* printf format size prefix for zoff_t values */
172#   define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
173
174# elif (defined(__IBMC__) && (__IBMC__ >= 350))
175    /* IBM C */
176
177    /* base types for file offsets and file sizes */
178    typedef __int64             zoff_t;
179    typedef unsigned __int64    uzoff_t;
180
181    /* 64-bit stat struct */
182
183    /* printf format size prefix for zoff_t values */
184#   define ZOFF_T_FORMAT_SIZE_PREFIX "I64"
185
186# else
187#   undef LARGE_FILE_SUPPORT
188# endif
189
190#endif
191
192#if 0
193# ifndef ZOFF_T_FORMAT_SIZE_PREFIX
194    /* unsupported WIN32 */
195
196    /* base types for file offsets and file sizes */
197    typedef long long           zoff_t;
198    typedef unsigned long long  uzoff_t;
199
200    /* 64-bit stat struct */
201    typedef struct stat z_stat;
202
203    /* printf format size prefix for zoff_t values */
204#   define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
205# endif
206#endif
207
208
209/* Automatically set ZIP64_SUPPORT if supported */
210
211/* MS C and VC */
212#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__WATCOMC__)
213# ifdef LARGE_FILE_SUPPORT
214#   ifndef NO_ZIP64_SUPPORT
215#     ifndef ZIP64_SUPPORT
216#       define ZIP64_SUPPORT
217#     endif
218#   endif
219# endif
220#endif
221
222
223#ifndef LARGE_FILE_SUPPORT
224  /* No Large File Support */
225
226  /* base type for file offsets and file sizes */
227  typedef long zoff_t;
228  typedef unsigned long uzoff_t;
229
230  /* stat struct */
231  typedef struct stat z_stat;
232
233  /* printf format size prefix for zoff_t values */
234# define ZOFF_T_FORMAT_SIZE_PREFIX "l"
235#endif
236
237
238  /* UNICODE */
239#ifdef WIN32
240  /* assume wide character conversion functions */
241# ifndef UNICODE_SUPPORT
242#   ifndef NO_UNICODE_SUPPORT
243#     define UNICODE_SUPPORT
244#   endif
245# endif
246#endif
247
248#if 0
249  /* this is now generic */
250# ifdef UNICODE_SUPPORT
251  /* Set up Unicode support - 9/27/05 EG */
252
253  /* type of wide string characters */
254#  define zchar wchar_t
255
256  /* default char string used if a wide char can't be converted */
257#  define zchar_default "_"
258
259# else
260#  define zchar char
261# endif
262#endif
263
264
265/* File operations--use "b" for binary if allowed or fixed length 512 on VMS
266 *                  use "S" for sequential access on NT to prevent the NT
267 *                  file cache eating up memory with large .zip files
268 */
269#define FOPR "rb"
270#define FOPM "r+b"
271#define FOPW "wbS"
272
273#if (defined(__CYGWIN__) && !defined(NO_MKTIME))
274#  define NO_MKTIME             /* Cygnus' mktime() implementation is buggy */
275#endif
276#if (!defined(NT_TZBUG_WORKAROUND) && !defined(NO_NT_TZBUG_WORKAROUND))
277#  define NT_TZBUG_WORKAROUND
278#endif
279#if (defined(UTIL) && defined(NT_TZBUG_WORKAROUND))
280#  undef NT_TZBUG_WORKAROUND    /* the Zip utilities do not use time-stamps */
281#endif
282#if !defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)
283#  define USE_EF_UT_TIME
284#endif
285#if (!defined(NO_NTSD_EAS) && !defined(NTSD_EAS))
286#  define NTSD_EAS
287#endif
288
289#if (defined(NTSD_EAS) && !defined(ZP_NEED_MEMCOMPR))
290#  define ZP_NEED_MEMCOMPR
291#endif
292
293#ifdef WINDLL
294# ifndef NO_ASM
295#   define NO_ASM
296# endif
297# ifndef MSWIN
298#   define MSWIN
299# endif
300# ifndef REENTRANT
301#   define REENTRANT
302# endif
303#endif /* WINDLL */
304
305/* Enable use of optimized x86 assembler version of longest_match() for
306   MSDOS, WIN32 and OS2 per default.  */
307#if !defined(NO_ASM) && !defined(ASMV)
308#  define ASMV
309#endif
310
311/* Enable use of optimized x86 assembler version of crc32() for
312   MSDOS, WIN32 and OS2 per default.  */
313#if !defined(NO_ASM) && !defined(ASM_CRC)  && !defined(NO_ASM_CRC)
314#  define ASM_CRC
315#endif
316
317#if !defined(__GO32__) && !defined(__EMX__) && !defined(__CYGWIN__)
318#  define NO_UNISTD_H
319#endif
320
321/* Microsoft C requires additional attributes attached to all RTL function
322 * declarations when linking against the CRTL dll.
323 */
324#ifdef MSC
325#  ifdef IZ_IMP
326#    undef IZ_IMP
327#  endif
328#  define IZ_IMP _CRTIMP
329#else
330# ifndef IZ_IMP
331#   define IZ_IMP
332# endif
333#endif
334
335/* WIN32 runs solely on little-endian processors; enable support
336 * for the 32-bit optimized CRC-32 C code by default.
337 */
338#ifdef IZ_CRC_BE_OPTIMIZ
339#  undef IZ_CRC_BE_OPTIMIZ
340#endif
341#if !defined(IZ_CRC_LE_OPTIMIZ) && !defined(NO_CRC_OPTIMIZ)
342#  define IZ_CRC_LE_OPTIMIZ
343#endif
344
345/* the following definitions are considered as "obsolete" by Microsoft and
346 * might be missing in some versions of <windows.h>
347 */
348#ifndef AnsiToOem
349#  define AnsiToOem CharToOemA
350#endif
351#ifndef OemToAnsi
352#  define OemToAnsi OemToCharA
353#endif
354
355/* handlers for OEM <--> ANSI string conversions */
356#if defined(__RSXNT__) || defined(WIN32_CRT_OEM)
357   /* RSXNT uses OEM coded strings in functions supplied by C RTL */
358#  ifdef CRTL_CP_IS_ISO
359#    undef CRTL_CP_IS_ISO
360#  endif
361#  ifndef CRTL_CP_IS_OEM
362#    define CRTL_CP_IS_OEM
363#  endif
364#else
365   /* "real" native WIN32 compilers use ANSI coded strings in C RTL calls */
366#  ifndef CRTL_CP_IS_ISO
367#    define CRTL_CP_IS_ISO
368#  endif
369#  ifdef CRTL_CP_IS_OEM
370#    undef CRTL_CP_IS_OEM
371#  endif
372#endif
373
374#ifdef CRTL_CP_IS_ISO
375   /* C RTL's file system support assumes ANSI coded strings */
376#  define ISO_TO_INTERN(src, dst)  {if ((src) != (dst)) strcpy((dst), (src));}
377#  define OEM_TO_INTERN(src, dst)  OemToAnsi(src, dst)
378#  define INTERN_TO_ISO(src, dst)  {if ((src) != (dst)) strcpy((dst), (src));}
379#  define INTERN_TO_OEM(src, dst)  AnsiToOem(src, dst)
380#  define _OEM_INTERN(str1) OEM_TO_INTERN(str1, str1)
381#  define _ISO_INTERN(str1) {;}
382#  define _INTERN_OEM(str1) INTERN_TO_OEM(str1, str1)
383#  define _INTERN_ISO(str1) {;}
384#endif /* CRTL_CP_IS_ISO */
385#ifdef CRTL_CP_IS_OEM
386   /* C RTL's file system support assumes OEM coded strings */
387#  define ISO_TO_INTERN(src, dst)  AnsiToOem(src, dst)
388#  define OEM_TO_INTERN(src, dst)  {if ((src) != (dst)) strcpy((dst), (src));}
389#  define INTERN_TO_ISO(src, dst)  OemToAnsi(src, dst)
390#  define INTERN_TO_OEM(src, dst)  {if ((src) != (dst)) strcpy((dst), (src));}
391#  define _OEM_INTERN(str1) {;}
392#  define _ISO_INTERN(str1) ISO_TO_INTERN(str1, str1)
393#  define _INTERN_OEM(str1) {;}
394#  define _INTERN_ISO(str1) INTERN_TO_ISO(str1, str1)
395#endif /* CRTL_CP_IS_OEM */
396
397/* The following "OEM vs. ISO Zip entry names" code has been copied from UnZip.
398 * It should be applicable to the generic Zip code. However, currently only
399 * the Win32 port of Zip supplies the required charset conversion functions.
400 * (The Win32 port uses conversion functions supplied by the OS.)
401 */
402/* Convert filename (and file comment string) into "internal" charset.
403 * This macro assumes that Zip entry filenames are coded in OEM (IBM DOS)
404 * codepage when made on
405 *  -> DOS (this includes 16-bit Windows 3.1)  (FS_FAT_)
406 *  -> OS/2                                    (FS_HPFS_)
407 *  -> Win95/WinNT with Nico Mak's WinZip      (FS_NTFS_ && hostver == "5.0")
408 * EXCEPTIONS:
409 *  PKZIP for Windows 2.5, 2.6, and 4.0 flag their entries as "FS_FAT_", but
410 *  the filename stored in the local header is coded in Windows ANSI (CP 1252
411 *  resp. ISO 8859-1 on US and western Europe locale settings).
412 *  Likewise, PKZIP for UNIX 2.51 flags its entries as "FS_FAT_", but the
413 *  filenames stored in BOTH the local and the central header are coded
414 *  in the local system's codepage (usually ANSI codings like ISO 8859-1,
415 *  but could also be UTF-8 on "modern" setups...).
416 *
417 * All other ports are assumed to code zip entry filenames in ISO (8859-1
418 * on "Western" localisations).
419 */
420#define FS_FAT_           0    /* filesystem used by MS-DOS, OS/2, Win32 */
421#define FS_HPFS_          6    /* filesystem used by OS/2 (and NT 3.x) */
422#define FS_NTFS_          11   /* filesystem used by Windows NT */
423#ifndef Ext_ASCII_TO_Native
424#  define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \
425    if (((hostnum) == FS_FAT_ && \
426         !(((islochdr) || (isuxatt)) && \
427           ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
428        (hostnum) == FS_HPFS_ || \
429        ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \
430        _OEM_INTERN((string)); \
431    } else { \
432        _ISO_INTERN((string)); \
433    }
434#endif
435
436#if (defined(__RSXNT__) && defined(__CRTRSXNT__))
437#  include <crtrsxnt.h>
438#endif
439
440#ifdef _MBCS
441#  if (!defined(__EMX__) && !defined(__MINGW32__) && !defined(__CYGWIN__))
442#    include <stdlib.h>
443#    include <mbstring.h>
444#  endif
445#  if (defined(__MINGW32__) && !defined(MB_CUR_MAX))
446#    ifdef __MSVCRT__
447       IZ_IMP extern int *__p___mb_cur_max(void);
448#      define MB_CUR_MAX (*__p___mb_cur_max())
449#    else
450       IZ_IMP extern int *_imp____mb_cur_max_dll;
451#      define MB_CUR_MAX (*_imp____mb_cur_max_dll)
452#    endif
453#  endif
454#  if (defined(__LCC__) && !defined(MB_CUR_MAX))
455     IZ_IMP extern int *_imp____mb_cur_max;
456#    define MB_CUR_MAX (*_imp____mb_cur_max)
457#  endif
458#endif
459
460#ifdef __LCC__
461#  include <time.h>
462#  ifndef tzset
463#    define tzset _tzset
464#  endif
465#  ifndef utime
466#    define utime _utime
467#  endif
468#endif
469#ifdef __MINGW32__
470   IZ_IMP extern void _tzset(void);     /* this is missing in <time.h> */
471#  ifndef tzset
472#    define tzset _tzset
473#  endif
474#endif
475#if (defined(__RSXNT__) || defined(__EMX__)) && !defined(tzset)
476#  define tzset _tzset
477#endif
478#ifdef W32_USE_IZ_TIMEZONE
479#  ifdef __BORLANDC__
480#    define tzname tzname
481#    define IZTZ_DEFINESTDGLOBALS
482#  endif
483#  ifndef tzset
484#    define tzset _tzset
485#  endif
486#  ifndef timezone
487#    define timezone _timezone
488#  endif
489#  ifndef daylight
490#    define daylight _daylight
491#  endif
492#  ifndef tzname
493#    define tzname _tzname
494#  endif
495#  if (!defined(NEED__ISINDST) && !defined(__BORLANDC__))
496#    define NEED__ISINDST
497#  endif
498#  ifdef IZTZ_GETLOCALETZINFO
499#    undef IZTZ_GETLOCALETZINFO
500#  endif
501#  define IZTZ_GETLOCALETZINFO GetPlatformLocalTimezone
502#endif /* W32_USE_IZ_TIMEZONE */
503
504#ifdef MATCH
505#  undef MATCH
506#endif
507#define MATCH dosmatch          /* use DOS style wildcard matching */
508#ifdef UNICODE_SUPPORT
509# ifdef WIN32
510#   define MATCHW dosmatchw
511# endif
512#endif
513
514#ifdef ZCRYPT_INTERNAL
515#  ifdef WINDLL
516#    define ZCR_SEED2     (unsigned)3141592654L /* use PI as seed pattern */
517#  else
518#    include <process.h>        /* getpid() declaration for srand seed */
519#  endif
520#endif
521
522/* Up to now, all versions of Microsoft C runtime libraries lack the support
523 * for customized (non-US) switching rules between daylight saving time and
524 * standard time in the TZ environment variable string.
525 * But non-US timezone rules are correctly supported when timezone information
526 * is read from the OS system settings in the Win32 registry.
527 * The following work-around deletes any TZ environment setting from
528 * the process environment.  This results in a fallback of the RTL time
529 * handling code to the (correctly interpretable) OS system settings, read
530 * from the registry.
531 */
532#ifdef USE_EF_UT_TIME
533# if (defined(__WATCOMC__) || defined(__CYGWIN__) || \
534      defined(W32_USE_IZ_TIMEZONE))
535#   define iz_w32_prepareTZenv()
536# else
537#   define iz_w32_prepareTZenv()        putenv("TZ=")
538# endif
539#endif
540
541/* This patch of stat() is useful for at least three compilers.  It is   */
542/* difficult to take a stat() of a root directory under Windows95, so  */
543/* zstat_zipwin32() detects that case and fills in suitable values.    */
544#ifndef __RSXNT__
545#  ifndef W32_STATROOT_FIX
546#    define W32_STATROOT_FIX
547#  endif
548#endif /* !__RSXNT__ */
549
550#if (defined(NT_TZBUG_WORKAROUND) || defined(W32_STATROOT_FIX))
551#  define W32_STAT_BANDAID
552#  ifdef LARGE_FILE_SUPPORT         /* E. Gordon 9/12/03 */
553   int zstat_zipwin32(const char *path, z_stat *buf);
554#  else
555   int zstat_zipwin32(const char *path, struct stat *buf);
556#  endif
557#  ifdef UNICODE_SUPPORT
558#   ifdef LARGE_FILE_SUPPORT
559     int zstat_zipwin32w(const wchar_t *pathw, struct _stati64 *buf);
560#   else
561     int zstat_zipwin32w(const wchar_t *pathw, struct _stat *buf);
562#   endif
563#  endif
564#  ifdef SSTAT
565#    undef SSTAT
566#  endif
567#  define SSTAT zstat_zipwin32
568#  ifdef UNICODE_SUPPORT
569#    define SSTATW zstat_zipwin32w
570#  endif
571#endif /* NT_TZBUG_WORKAROUND || W32_STATROOT_FIX */
572
573int getch_win32(void);
574
575#ifdef __GNUC__
576# define IZ_PACKED      __attribute__((packed))
577#else
578# define IZ_PACKED
579#endif
580
581/* for some (all ?) versions of IBM C Set/2 and IBM C Set++ */
582#ifndef S_IFMT
583#  define S_IFMT 0xF000
584#endif /* !S_IFMT */
585
586#ifdef __WATCOMC__
587#  include <stdio.h>    /* PATH_MAX is defined here */
588#  define NO_MKTEMP
589
590/* Get asm routines to link properly without using "__cdecl": */
591#  ifdef __386__
592#    ifdef ASMV
593#      pragma aux match_init    "_*" parm caller [] modify []
594#      pragma aux longest_match "_*" parm caller [] value [eax] \
595                                      modify [eax ecx edx]
596#    endif
597#    if defined(ASM_CRC) && !defined(USE_ZLIB)
598#      pragma aux crc32         "_*" parm caller [] value [eax] modify [eax]
599#      pragma aux get_crc_table "_*" parm caller [] value [eax] \
600                                      modify [eax ecx edx]
601#    endif /* ASM_CRC && !USE_ZLIB */
602#  endif /* __386__ */
603   /* Watcom C (like the other Win32 C compiler systems) does not support
604    * symlinks on Win32, but defines the S_IFLNK symbol nevertheless.
605    * However, the existence of this symbol is used as "symlinks supported"
606    * indicator in the generic Zip code (see tailor.h). So, for a simple
607    * work-around, this symbol is undefined here. */
608#  ifdef S_IFLNK
609#    undef S_IFLNK
610#  endif
611#  ifdef UNICODE_SUPPORT
612     /* Watcom C does not supply wide-char definitions in the "standard"
613      * headers like MSC; so we have to pull in a wchar-specific header.
614      */
615#    include <wchar.h>
616#  endif
617#endif /* __WATCOMC__ */
618