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

📄 win32.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 3 页
字号:
    ltm.tm_isdst = -1;  /* let mktime determine if DST is in effect */    *ut = mktime(&ltm);    /* a cheap error check: mktime returns "(time_t)-1L" on conversion errors.     * Normally, we would have to apply a consistency check because "-1"     * could also be a valid time. But, it is quite unlikely to read back odd     * time numbers from file systems that store time stamps in DOS format.     * (The only known exception is creation time on VFAT partitions.)     */    return (*ut != (time_t)-1L);} /* end function VFatFileTime2utime() */#endif /* NT_TZBUG_WORKAROUND && W32_STAT_BANDAID */#if defined(NT_TZBUG_WORKAROUND) && !defined(NO_W32TIMES_IZFIX)local void utime2NtfsFileTime(time_t ut, FILETIME *pft){#ifndef NO_INT64    ULLNG64 NTtime;    /* NT_QUANTA_PER_UNIX is small enough so that "ut * NT_QUANTA_PER_UNIX"     * cannot overflow in 64-bit signed calculation, regardless whether "ut"     * is signed or unsigned.  */    NTtime = ((LLONG64)ut * NT_QUANTA_PER_UNIX) +             ((ULLNG64)UNIX_TIME_ZERO_LO + ((ULLNG64)UNIX_TIME_ZERO_HI << 32));    pft->dwLowDateTime = (DWORD)NTtime;    pft->dwHighDateTime = (DWORD)(NTtime >> 32);#else /* NO_INT64 (64-bit integer arithmetics may not be supported) */    unsigned int b1, b2, carry = 0;    unsigned long r0, r1, r2, r3;    long r4;            /* signed, to catch environments with signed time_t */    b1 = ut & 0xFFFF;    b2 = (ut >> 16) & 0xFFFF;       /* if ut is over 32 bits, too bad */    r1 = b1 * (NT_QUANTA_PER_UNIX & 0xFFFF);    r2 = b1 * (NT_QUANTA_PER_UNIX >> 16);    r3 = b2 * (NT_QUANTA_PER_UNIX & 0xFFFF);    r4 = b2 * (NT_QUANTA_PER_UNIX >> 16);    r0 = (r1 + (r2 << 16)) & 0xFFFFFFFFL;    if (r0 < r1)        carry++;    r1 = r0;    r0 = (r0 + (r3 << 16)) & 0xFFFFFFFFL;    if (r0 < r1)        carry++;    pft->dwLowDateTime = r0 + UNIX_TIME_ZERO_LO;    if (pft->dwLowDateTime < r0)        carry++;    pft->dwHighDateTime = r4 + (r2 >> 16) + (r3 >> 16)                            + UNIX_TIME_ZERO_HI + carry;#endif /* ?NO_INT64 */} /* end function utime2NtfsFileTime() */#endif /* NT_TZBUG_WORKAROUND && !NO_W32TIMES_IZFIX */#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, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,                 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);  if ( h != INVALID_HANDLE_VALUE ) {    BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);    CloseHandle(h);#ifdef USE_EF_UT_TIME    if (ftOK && (z_ut != NULL)) {      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;}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. */{#ifdef NT_TZBUG_WORKAROUND    FILETIME Modft;     /* File time type of Win32 API, `last modified' time */    HANDLE hFile;       /* File handle defined in Win32 API    */# ifdef __RSXNT__        /* RSXNT/EMX C rtl uses OEM charset */    char *ansi_name = (char *)alloca(strlen(f) + 1);    OemToAnsi(f, ansi_name);#   define Ansi_Fname  ansi_name# else#   define Ansi_Fname  f# endif    /* open a handle to the file to prepare setting the mod-time stamp */    hFile = CreateFile(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);    if ( hFile != INVALID_HANDLE_VALUE ) {        /* convert time_t modtime into WIN32 native 64bit format */# ifndef NO_W32TIMES_IZFIX        if (!FSusesLocalTime(f)) {            time_t ux_modtime = dos2unixtime(d);            utime2NtfsFileTime(ux_modtime, &Modft);        } else# endif /* !NO_W32TIMES_IZFIX */        {            FILETIME lft;            DosDateTimeToFileTime((WORD)(d >> 16),                                  (WORD)(d & 0xFFFFL),                                  &lft);            LocalFileTimeToFileTime(&lft, &Modft);        }        /* set Access and Modification times of the file to modtime */        SetFileTime(hFile, NULL, &Modft, &Modft);        CloseHandle(hFile);    }#else /* !NT_TZBUG_WORKAROUND */    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 /* ?NT_TZBUG_WORKAROUND */}#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

⌨️ 快捷键说明

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