⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win32.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  Copyright (c) 1990-2006 Info-ZIP.  All rights reserved.  See the accompanying file LICENSE, version 2005-Feb-10 or later  (the contents of which are also included in zip.h) for terms of use.  If, for some reason, all these files are missing, the Info-ZIP license  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html*//* * 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#if (defined(__MINGW32__) && !defined(USE_MINGW_GLOBBING))   int _CRT_glob = 0;   /* suppress command line globbing by C RTL */#endif#ifndef UTILextern int noisy;#ifndef NO_W32TIMES_IZFIX#if defined(NT_TZBUG_WORKAROUND)local int FSusesLocalTime(const char *path);#endif#if defined(USE_EF_UT_TIME) || defined(NT_TZBUG_WORKAROUND)local int NtfsFileTime2utime(const FILETIME *pft, time_t *ut);#endif#if defined(NT_TZBUG_WORKAROUND) && !defined(NO_W32TIMES_IZFIX)local void utime2NtfsFileTime(time_t ut, FILETIME *pft);#endif#endif /* !NO_W32TIMES_IZFIX */#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){  static char lastDrive = '\0';    /* cached drive of last GetVolumeInformation call */  static int lastDriveOldFAT = 0;  /* cached OldFAT value of last GetVolumeInformation call */  char root[4];  DWORD vfnsize;  DWORD vfsflags;    /*     * We separate FAT and HPFS+other file systems here.     * I consider other systems to be similar to HPFS/NTFS, i.e.     * support for long file names and being case sensitive to some extent.     */    strncpy(root, dir, 3);    if ( isalpha((uch)root[0]) && (root[1] == ':') ) {      root[0] = to_up(dir[0]);      root[2] = '\\';      root[3] = 0;    }    else {      root[0] = '\\';      root[1] = 0;    }    if (lastDrive == root[0]) {      return lastDriveOldFAT;    }    if ( !GetVolumeInformation(root, NULL, 0,                               NULL, &vfnsize, &vfsflags,                               NULL, 0)) {        fprintf(mesg, "zip diagnostic: GetVolumeInformation failed\n");        return(FALSE);    }    lastDrive = root[0];    lastDriveOldFAT = vfnsize <= 12;    return lastDriveOldFAT;}/* 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));}#if defined(NT_TZBUG_WORKAROUND) && !defined(NO_W32TIMES_IZFIX)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 && !NO_W32TIMES_IZFIX */#if defined(USE_EF_UT_TIME) || defined(NT_TZBUG_WORKAROUND)#if (defined(__GNUC__) || defined(ULONG_LONG_MAX))   typedef long long            LLONG64;   typedef unsigned long long   ULLNG64;#elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))   typedef __int64              LLONG64;   typedef unsigned __int64     ULLNG64;#elif (defined(_MSC_VER) && (_MSC_VER >= 1100))   typedef __int64              LLONG64;   typedef unsigned __int64     ULLNG64;#elif (defined(__IBMC__) && (__IBMC__ >= 350))   typedef __int64              LLONG64;   typedef unsigned __int64     ULLNG64;#else#  define NO_INT64#endif/* 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#ifndef NO_W32TIMES_IZFIXlocal 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 /* !NO_W32TIMES_IZFIX */#endif /* USE_EF_UT_TIME || NT_TZBUG_WORKAROUND */#if defined(NT_TZBUG_WORKAROUND) && defined(W32_STAT_BANDAID)local int VFatFileTime2utime(const FILETIME *pft, time_t *ut){    FILETIME lft;    SYSTEMTIME w32tm;    struct tm ltm;    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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -