📄 win32.c
字号:
(time_t)(60 * w32tm.wMinute + w32tm.wSecond)); return TRUE;#endif /* ?IZ_USE_INT64 */} /* end function NtfsFileTime2utime() */#endif /* W32_STAT_BANDAID && !NO_W32TIMES_IZFIX */#ifdef W32_STAT_BANDAID/*********************************//* Function VFatFileTime2utime() *//*********************************/static int VFatFileTime2utime(const FILETIME *pft, time_t *ut){ FILETIME lft;#ifndef HAVE_MKTIME WORD wDOSDate, wDOSTime;#else SYSTEMTIME w32tm; struct tm ltm;#endif if (!FileTimeToLocalFileTime(pft, &lft)) { /* if pft cannot be converted to local time, return current time */ return time(NULL); } FTTrace((stdout, "VFatFT2utime, feed for mktime()", 1, &lft));#ifndef HAVE_MKTIME /* This version of the FILETIME-to-UNIXTIME conversion function * uses DOS-DATE-TIME format as intermediate stage. For modification * and access times, this is no problem. But, the extra fine resolution * of the VFAT-stored creation time gets lost. */ if (!FileTimeToDosDateTime(&lft, &wDOSDate, &wDOSTime)) { static const FILETIME dosmin_ft = {DOSTIME_MIN_FT_LO, DOSTIME_MIN_FT_HI}; if (CompareFileTime(&lft, &dosmin_ft) <= 0) { /* underflow -> set to minimum DOS time */ wDOSDate = (WORD)((DWORD)DOSTIME_MINIMUM >> 16); wDOSTime = (WORD)DOSTIME_MINIMUM; } else { /* overflow -> set to maximum DOS time */ wDOSDate = (WORD)0xFF9F; /* 2107-12-31 */ wDOSTime = (WORD)0xBF7D; /* 23:59:58 */ } } TTrace((stdout,"DosDateTime is %04u-%02u-%02u %02u:%02u:%02u\n", (unsigned)((wDOSDate>>9)&0x7f)+1980,(unsigned)((wDOSDate>>5)&0x0f), (unsigned)(wDOSDate&0x1f),(unsigned)((wDOSTime>>11)&0x1f), (unsigned)((wDOSTime>>5)&0x3f),(unsigned)((wDOSTime<<1)&0x3e))); *ut = dos_to_unix_time(((ulg)wDOSDate << 16) | (ulg)wDOSTime); /* a cheap error check: dos_to_unix_time() only returns an odd time * when clipping at maximum time_t value. DOS_DATE_TIME values have * a resolution of 2 seconds and are therefore even numbers. */ return (((*ut)&1) == (time_t)0);#else /* HAVE_MKTIME */ FileTimeToSystemTime(&lft, &w32tm);#ifndef TIME_T_TYPE_DOUBLE /* 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; } }#endif /* !TIME_T_TYPE_DOUBLE */ 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);#endif /* ?HAVE_MKTIME */} /* end function VFatFileTime2utime() */#endif /* W32_STAT_BANDAID *//******************************//* Function FStampIsLocTime() *//******************************/static int FStampIsLocTime(__GPRO__ const char *path){ return (NTQueryVolInfo(__G__ path) ? G.lastVolLocTim : FALSE);}#ifndef NO_W32TIMES_IZFIX# define UTIME_2_IZFILETIME(ut, pft) \ if (fs_uses_loctime) {utime2VFatFileTime(ut, pft, TRUE);} \ else {utime2NtfsFileTime(ut, pft);}#else# define UTIME_2_IZFILETIME(ut, pft) \ utime2VFatFileTime(ut, pft, fs_uses_loctime);#endif/****************************/ /* Get the file time in a format that *//* Function getNTfiletime() */ /* can be used by SetFileTime() in NT *//****************************/static int getNTfiletime(__G__ pModFT, pAccFT, pCreFT) __GDEF FILETIME *pModFT; FILETIME *pAccFT; FILETIME *pCreFT;{#ifdef USE_EF_UT_TIME unsigned eb_izux_flg; iztimes z_utime; /* struct for Unix-style actime & modtime, + creatime */#endif int fs_uses_loctime = FStampIsLocTime(__G__ G.filename); /* Copy and/or convert time and date variables, if necessary; * return a flag indicating which time stamps are available. */#ifdef USE_EF_UT_TIME if (G.extra_field &&#ifdef IZ_CHECK_TZ G.tz_is_valid &&#endif ((eb_izux_flg = ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, &z_utime, NULL)) & EB_UT_FL_MTIME)) { TTrace((stderr, "getNTfiletime: Unix e.f. modif. time = %lu\n", z_utime.mtime)); UTIME_2_IZFILETIME(z_utime.mtime, pModFT) if (eb_izux_flg & EB_UT_FL_ATIME) { UTIME_2_IZFILETIME(z_utime.atime, pAccFT) } if (eb_izux_flg & EB_UT_FL_CTIME) { UTIME_2_IZFILETIME(z_utime.ctime, pCreFT) } return (int)eb_izux_flg; }#endif /* USE_EF_UT_TIME */#ifndef NO_W32TIMES_IZFIX if (!fs_uses_loctime) { time_t ux_modtime; ux_modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime); utime2NtfsFileTime(ux_modtime, pModFT); } else#endif /* NO_W32TIMES_IZFIX */ { FILETIME lft; DosDateTimeToFileTime((WORD)(G.lrec.last_mod_dos_datetime >> 16), (WORD)(G.lrec.last_mod_dos_datetime & 0xFFFFL), &lft); LocalFileTimeToFileTime(&lft, pModFT); } *pAccFT = *pModFT; return (EB_UT_FL_MTIME | EB_UT_FL_ATIME);} /* end function getNTfiletime() *//**************************//* Function SetFileSize() *//**************************/int SetFileSize(FILE *file, ulg filesize){#ifdef __RSXNT__ /* RSXNT environment lacks a translation function from C file pointer to Win32-API file handle. So, simply do nothing. */ return 0;#else /* !__RSXNT__ */ /* not yet verified, if that really creates an unfragmented file rommel@ars.de */ HANDLE os_fh; /* Win9x supports FAT file system, only; presetting file size does not help to prevent fragmentation. */ if (!IsWinNT()) return 0; /* Win32-API calls require access to the Win32 file handle. The interface function used to retrieve the Win32 handle for a file opened by the C rtl is non-standard and may not be available for every Win32 compiler environment. (see also win32/win32.c of the Zip distribution) */ os_fh = (HANDLE)_get_osfhandle(fileno(file)); /* move file pointer behind the last byte of the expected file size */ if (SetFilePointer(os_fh, filesize, 0, FILE_BEGIN) == 0xFFFFFFFF) return -1; /* extend/truncate file to the current position */ if (SetEndOfFile(os_fh) == 0) return -1; /* move file position pointer back to the start of the file! */ return (SetFilePointer(os_fh, 0, 0, FILE_BEGIN) == 0xFFFFFFFF) ? -1 : 0;#endif /* ?__RSXNT__ */} /* end function SetFileSize() *//****************************//* Function close_outfile() *//****************************/void close_outfile(__G) __GDEF{ FILETIME Modft; /* File time type defined in NT, `last modified' time */ FILETIME Accft; /* NT file time type, `last access' time */ FILETIME Creft; /* NT file time type, `file creation' time */ HANDLE hFile; /* File handle defined in NT */ int gotTime;#ifdef NTSD_EAS uch *ebSDptr; unsigned ebSDlen;#endif#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ char *ansi_name = (char *)alloca(strlen(G.filename) + 1); INTERN_TO_ISO(G.filename, ansi_name);# define Ansi_Fname ansi_name#else# define Ansi_Fname G.filename#endif /* Close the file and then re-open it using the Win32 * CreateFile call, so that the file can be created * with GENERIC_WRITE access, otherwise the SetFileTime * call will fail. */ fclose(G.outfile); /* don't set the time stamp and attributes on standard output */ if (uO.cflag) return; gotTime = getNTfiletime(__G__ &Modft, &Accft, &Creft); /* open a handle to the file before processing extra fields; we do this in case new security on file prevents us from updating time stamps */ hFile = CreateFile(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); /* sfield@microsoft.com: set attributes before time in case we decide to support other filetime members later. This also allows us to apply attributes before the security is changed, which may prevent this from succeeding otherwise. Also, since most files don't have any interesting attributes, only change them if something other than FILE_ATTRIBUTE_ARCHIVE appears in the attributes. This works well as an optimization because FILE_ATTRIBUTE_ARCHIVE gets applied to the file anyway, when it's created new. */ if((G.pInfo->file_attr & 0x7F) & ~FILE_ATTRIBUTE_ARCHIVE) { if (!SetFileAttributes(Ansi_Fname, G.pInfo->file_attr & 0x7F)) Info(slide, 1, ((char *)slide, "\nwarning (%d): could not set file attributes\n", (int)GetLastError())); }#ifdef NTSD_EAS /* set NTFS SD extra fields */ if (G.extra_field && /* zipfile extra field may have extended attribs */ FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length, &ebSDptr, &ebSDlen)) { int err = SetSD(__G__ Ansi_Fname, G.pInfo->file_attr, ebSDptr, ebSDlen); if (err == IZ_EF_TRUNC) { if (uO.qflag) Info(slide, 1, ((char *)slide, "%-22s ", FnFilter1(G.filename))); Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD), ebSDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), uO.qflag? "\n":"")); } }#endif /* NTSD_EAS */ if ( hFile == INVALID_HANDLE_VALUE ) Info(slide, 1, ((char *)slide, "\nCreateFile() error %d when trying set file time\n", (int)GetLastError())); else { if (gotTime) { FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL; FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL; FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL; if (!SetFileTime(hFile, pCreft, pAccft, pModft)) Info(slide, 0, ((char *)slide, "\nSetFileTime failed: %d\n", (int)GetLastError())); } CloseHandle(hFile); } return;#undef Ansi_Fname} /* end function close_outfile() */#ifdef SET_DIR_ATTRIBint defer_dir_attribs(__G__ pd) __GDEF direntry **pd;{ NTdirattr *d_entry;#ifdef NTSD_EAS uch *ebSDptr; unsigned ebSDlen;#endif /* Win9x does not support setting directory time stamps. */ if (!IsWinNT()) { *pd = (direntry *)NULL; return PK_OK; }#ifdef NTSD_EAS /* set extended attributes from extra fields */ if (G.extra_field && /* zipfile e.f. may have extended attribs */ FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length, &ebSDptr, &ebSDlen)) { /* ebSDlen contains the payload size of the e.f. block, but we store it including the e.b. header. */ ebSDlen += EB_HEADSIZE; } else { /* no NTSD e.f. block -> no space needed to allocate */ ebSDlen = 0; }#endif /* NTSD_EAS */ d_entry = (NTdirattr *)malloc(sizeof(NTdirattr)#ifdef NTSD_EAS + ebSDlen#endif + strlen(G.filename)); *pd = (direntry *)d_entry; if (d_entry == (NTdirattr *)NULL) { return PK_MEM; }#ifdef NTSD_EAS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -