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 
573 int 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