?? win32.c
字號:
/* Copyright (c) 1990-2002 Info-ZIP. All rights reserved. See the accompanying file LICENSE, version 2000-Apr-09 or later (the contents of which are also included in unzip.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.c 32-bit Windows-specific (NT/95) routines for use with Info-ZIP's UnZip 5.3 and later. Contains: GetLoadPath() Opendir() Readdir() Closedir() process_defer_NT() process any deferred items SetSD() set security descriptor on file EvalExtraFields() evaluate and process and extra field NOW IsWinNT() indicate type of WIN32 platform test_NTSD() test integrity of NT security data utime2FileTime() FStampIsLocTime() FileTime2utime() VFatFileTime2utime() UTCtime2Localtime() NTtzbugWorkaround() getNTfiletime() SetFileSize() close_outfile() stamp_file() isfloppy() NTQueryVolInfo() IsVolumeOldFAT() do_wild() mapattr() mapname() maskDOSdevice() map2fat() checkdir() dateformat() version() screensize() zstat_win32() conv_to_rule() GetPlatformLocalTimezone() getch_win32() ---------------------------------------------------------------------------*/#define UNZIP_INTERNAL#include "../unzip.h"#include <windows.h> /* must be AFTER unzip.h to avoid struct G problems */#ifdef __RSXNT__# include "../win32/rsxntwin.h"#endif#include "../win32/nt.h"#ifndef FUNZIP /* most of this file is not used with fUnZip */#if (defined(__EMX__) || defined(__CYGWIN__))# define MKDIR(path,mode) mkdir(path,mode)#else# define MKDIR(path,mode) mkdir(path)#endif#ifdef HAVE_WORKING_DIRENT_H# undef HAVE_WORKING_DIRENT_H#endif/* The emxrtl dirent support of (__GO32__ || __EMX__) converts to lowercase! */#if defined(__CYGWIN__)# define HAVE_WORKING_DIRENT_H#endif#ifndef SFX# ifdef HAVE_WORKING_DIRENT_H# include <dirent.h> /* use readdir() */# define zdirent dirent# define zDIR DIR# define Opendir opendir# define Readdir readdir# define Closedir closedir# else /* !HAVE_WORKING_DIRENT_H */ typedef struct zdirent { char reserved [21]; char ff_attrib; short ff_ftime; short ff_fdate; long size; char d_name[MAX_PATH]; int d_first; HANDLE d_hFindFile; } zDIR; static zDIR *Opendir (const char *n); static struct zdirent *Readdir (zDIR *d); static void Closedir (zDIR *d);# endif /* ?HAVE_WORKING_DIRENT_H */#endif /* !SFX *//* Function prototypes */#ifdef NTSD_EAS static int SetSD(__GPRO__ char *path, PVOLUMECAPS VolumeCaps, uch *eb_ptr, unsigned eb_len); static int EvalExtraFields(__GPRO__ char *path, uch *ef_ptr, unsigned ef_len);#endif#if (defined(USE_EF_UT_TIME) || defined(NT_TZBUG_WORKAROUND) || \ defined(TIMESTAMP)) static void utime2FileTime(time_t ut, FILETIME *pft); static int FStampIsLocTime(__GPRO__ const char *path);#endif /* USE_EF_UT_TIME || NT_TZBUG_WORKAROUND || TIMESTAMP */#ifdef NT_TZBUG_WORKAROUND static int FileTime2utime(const FILETIME *pft, time_t *ut);#ifdef W32_STAT_BANDAID static int VFatFileTime2utime(const FILETIME *pft, time_t *ut);#endif static time_t UTCtime2Localtime(time_t utctime); static void NTtzbugWorkaround(time_t ut, FILETIME *pft);#endif /* NT_TZBUG_WORKAROUND */static int getNTfiletime (__GPRO__ FILETIME *pModFT, FILETIME *pAccFT, FILETIME *pCreFT);static int isfloppy (int nDrive);static int NTQueryVolInfo (__GPRO__ const char *name);static int IsVolumeOldFAT (__GPRO__ const char *name);static void maskDOSdevice (__GPRO__ char *pathcomp);static void map2fat (char *pathcomp, char **pEndFAT);#ifdef __MINGW32__ int _CRT_glob = 0; /* suppress command line globbing by C RTL */#endif#ifdef ACORN_FTYPE_NFS/* Acorn bits for NFS filetyping */typedef struct { uch ID[2]; uch size[2]; uch ID_2[4]; uch loadaddr[4]; uch execaddr[4]; uch attr[4];} RO_extra_block;#endif /* ACORN_FTYPE_NFS *//* static int created_dir; */ /* used by mapname(), checkdir() *//* static int renamed_fullpath; */ /* ditto *//* static int fnlen; */ /* ditto *//* static unsigned nLabelDrive; */ /* ditto */extern char Far TruncNTSD[]; /* in extract.c */#ifdef SFX/**************************//* Function GetLoadPath() *//**************************/char *GetLoadPath(__GPRO){#ifdef MSC extern char *_pgmptr; return _pgmptr;#else /* use generic API call */ GetModuleFileName(NULL, G.filename, FILNAMSIZ-1); _ISO_INTERN(G.filename); /* translate to codepage of C rtl's stdio */ return G.filename;#endif} /* end function GetLoadPath() */#else /* !SFX */#ifndef HAVE_WORKING_DIRENT_H/**********************/ /* Borrowed from ZIP 2.0 sources *//* Function Opendir() */ /* Difference: no special handling for *//**********************/ /* hidden or system files. */static zDIR *Opendir(n) const char *n; /* directory to open */{ zDIR *d; /* malloc'd return value */ char *p; /* malloc'd temporary string */ WIN32_FIND_DATA fd; extent len = strlen(n); /* Start searching for files in directory n */ if ((d = (zDIR *)malloc(sizeof(zDIR))) == NULL || (p = malloc(strlen(n) + 5)) == NULL) { if (d != (zDIR *)NULL) free((void *)d); return (zDIR *)NULL; } INTERN_TO_ISO(n, p); if (len > 0) { if (p[len-1] == ':') p[len++] = '.'; /* x: => x:. */ else if (p[len-1] == '/' || p[len-1] == '\\') --len; /* foo/ => foo */ } strcpy(p+len, "/*"); if (INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFile(p, &fd))) { free((zvoid *)d); free((zvoid *)p); return NULL; } strcpy(d->d_name, fd.cFileName); free((zvoid *)p); d->d_first = 1; return d;} /* end of function Opendir() *//**********************/ /* Borrowed from ZIP 2.0 sources *//* Function Readdir() */ /* Difference: no special handling for *//**********************/ /* hidden or system files. */static struct zdirent *Readdir(d) zDIR *d; /* directory stream from which to read */{ /* Return pointer to first or next directory entry, or NULL if end. */ if ( d->d_first ) d->d_first = 0; else { WIN32_FIND_DATA fd; if ( !FindNextFile(d->d_hFindFile, &fd) ) return NULL; ISO_TO_INTERN(fd.cFileName, d->d_name); } return (struct zdirent *)d;} /* end of function Readdir() *//***********************//* Function Closedir() */ /* Borrowed from ZIP 2.0 sources *//***********************/static void Closedir(d) zDIR *d; /* directory stream to close */{ FindClose(d->d_hFindFile); free(d);}#endif /* !HAVE_WORKING_DIRENT_H */#endif /* ?SFX */#ifdef NTSD_EAS/*********************************//* Function process_defer_NT() *//*********************************/void process_defer_NT(__G) __GDEF{ /* process deferred items */ DWORD dir, bytes; DWORD dirfail, bytesfail; ProcessDefer(&dir, &bytes, &dirfail, &bytesfail); if (!uO.tflag && (uO.qflag < 2)) { if (dir) Info(slide, 0, ((char *)slide, " updated: %lu directory entries with %lu bytes security", (ulg)dir, (ulg)bytes)); if (dirfail) Info(slide, 0, ((char *)slide, " failed: %lu directory entries with %lu bytes security", (ulg)dirfail, (ulg)bytesfail)); }}/**********************//* Function SetSD() */ /* return almost-PK errors *//**********************/static int SetSD(__G__ path, VolumeCaps, eb_ptr, eb_len) __GDEF char *path; PVOLUMECAPS VolumeCaps; uch *eb_ptr; unsigned eb_len;{ ulg ntsd_ucSize; uch *security_data; int error; if (eb_ptr == NULL || eb_len < EB_NTSD_L_LEN) return PK_OK; /* not a valid NTSD extra field: assume OK */ /* check if we know how to handle this version */ if (*(eb_ptr + (EB_HEADSIZE+EB_NTSD_VERSION)) > (uch)EB_NTSD_MAX_VER) return PK_OK; ntsd_ucSize = makelong(eb_ptr + (EB_HEADSIZE+EB_UCSIZE_P)); if (ntsd_ucSize > 0L && eb_len <= (EB_NTSD_L_LEN + EB_CMPRHEADLEN)) return IZ_EF_TRUNC; /* no compressed data! */ /* allocate storage for uncompressed data */ security_data = (uch *)malloc((extent)ntsd_ucSize); if (security_data == (uch *)NULL) return PK_MEM4; error = memextract(__G__ security_data, ntsd_ucSize, (eb_ptr + (EB_HEADSIZE+EB_NTSD_L_LEN)), (ulg)(eb_len - EB_NTSD_L_LEN)); if (error == PK_OK) { if (SecuritySet(path, VolumeCaps, security_data)) { error = PK_COOL; if (!uO.tflag && (uO.qflag < 2) && (!(VolumeCaps->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))) Info(slide, 0, ((char *)slide, " (%ld bytes security)", ntsd_ucSize)); } } free(security_data); return error;}/********************************/ /* scan extra fields for something *//* Function EvalExtraFields() */ /* we happen to know *//********************************/static int EvalExtraFields(__G__ path, ef_ptr, ef_len) __GDEF char *path; uch *ef_ptr; unsigned ef_len;{ int rc = PK_OK; if (!uO.X_flag) return PK_OK; /* user said don't process ACLs; for now, no other extra block types are handled here */ while (ef_len >= EB_HEADSIZE) { unsigned eb_id = makeword(EB_ID + ef_ptr); unsigned eb_len = makeword(EB_LEN + ef_ptr); if (eb_len > (ef_len - EB_HEADSIZE)) { /* discovered some extra field inconsistency! */ Trace((stderr, "EvalExtraFields: block length %u > rest ef_size %u\n", eb_len,
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -