📄 win32.c
字号:
/* Copyright (c) 1990-2005 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/9x) routines for use with Info-ZIP's UnZip 5.3 and later. Contains: GetLoadPath() Opendir() Readdir() Closedir() SetSD() set security descriptor on file FindSDExtraField() extract SD e.f. block from extra field IsWinNT() indicate type of WIN32 platform test_NTSD() test integrity of NT security data utime2NtfsFileTime() utime2VFatFileTime() FStampIsLocTime() NtfsFileTime2utime() VFatFileTime2utime() getNTfiletime() SetFileSize() close_outfile() defer_dir_attribs() set_direc_attribs() stamp_file() isfloppy() NTQueryVolInfo() IsVolumeOldFAT() do_wild() mapattr() mapname() maskDOSdevice() map2fat() checkdir() dateformat() dateseparator() 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 *//* some non-MS runtime headers (e.g. lcc) may miss this definition */#ifndef FILE_WRITE_ATTRIBUTES# define FILE_WRITE_ATTRIBUTES 0x0100#endif#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 */#ifdef SET_DIR_ATTRIBtypedef struct NTdirattr { /* struct for holding unix style directory */ struct NTdirattr *next; /* info until can be sorted and set at end */ char *fn; /* filename of directory */ 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 */ int gotTime; unsigned perms; /* same as min_info.file_attr */#ifdef NTSD_EAS unsigned SDlen; /* length of SD data in buf */#endif char buf[1]; /* buffer stub for directory SD and name */} NTdirattr;#define NtAtt(d) ((NTdirattr *)d) /* typecast shortcut */#endif /* SET_DIR_ATTRIB *//* Function prototypes */#ifdef NTSD_EAS static int SetSD(__GPRO__ char *path, unsigned fperms, uch *eb_ptr, unsigned eb_len); static int FindSDExtraField(__GPRO__ uch *ef_ptr, unsigned ef_len, uch **p_ebSD_ptr, unsigned *p_ebSD_len);#endif#ifndef NO_W32TIMES_IZFIX static void utime2NtfsFileTime(time_t ut, FILETIME *pft);#endifstatic void utime2VFatFileTime(time_t ut, FILETIME *pft, int clipDosMin);#if (defined(W32_STAT_BANDAID) && !defined(NO_W32TIMES_IZFIX)) static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut);#endif#ifdef W32_STAT_BANDAID static int VFatFileTime2utime(const FILETIME *pft, time_t *ut);#endifstatic int FStampIsLocTime(__GPRO__ const char *path);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 SetSD() */ /* return almost-PK errors *//**********************/static int SetSD(__G__ path, fperms, eb_ptr, eb_len) __GDEF char *path; unsigned fperms; uch *eb_ptr; unsigned eb_len;{ ulg ntsd_ucSize; VOLUMECAPS VolumeCaps; uch *security_data; int error; 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! */ /* provide useful input */ VolumeCaps.dwFileAttributes = fperms; VolumeCaps.bUsePrivileges = (uO.X_flag > 1); /* check target volume capabilities - just fall through * and try if fail */ if (GetVolumeCaps(G.rootpath, path, &VolumeCaps) && !(VolumeCaps.dwFileSystemFlags & FS_PERSISTENT_ACLS)) return PK_OK; /* 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 && QCOND2) Info(slide, 0, ((char *)slide, " (%ld bytes security)", ntsd_ucSize)); } } free(security_data); return error;}/********************************/ /* scan extra fields for something *//* Function FindSDExtraField() */ /* we happen to know *//********************************//* Returns TRUE when a valid NTFS SD block is found. * Address and size of the NTSD e.f. block are passed up to the caller. * In case of more than one valid NTSD block in the e.f., the last block * found is passed up. * Returns FALSE and leaves the content of the ebSD_ptr and ebSD_len * parameters untouched when no valid NTFS SD block is found. */static int FindSDExtraField(__GPRO__ uch *ef_ptr, unsigned ef_len, uch **p_ebSD_ptr, unsigned *p_ebSD_len){ int rc = FALSE; if (!uO.X_flag) return FALSE; /* 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, "FindSDExtraField: block length %u > rest ef_size %u\n", eb_len, ef_len - EB_HEADSIZE)); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -