0,0 → 1,1075 |
/* |
Copyright (c) 1990-2009 Info-ZIP. All rights reserved. |
|
See the accompanying file LICENSE, version 2009-Jan-02 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 |
*/ |
/* Windows Info-ZIP Unzip DLL module |
* |
* Author: Mike White |
* |
* Original: 1996 |
* |
* This module has the entry points for "unzipping" a zip file. |
*/ |
|
/*--------------------------------------------------------------------------- |
|
This file is the WINDLL replacement for the generic ``main program source |
file'' unzip.c. |
|
See the general comments in the header part of unzip.c. |
|
Copyrights: see accompanying file "COPYING" in UnZip source distribution. |
(This software is free but NOT IN THE PUBLIC DOMAIN. There |
are some restrictions on commercial use.) |
|
---------------------------------------------------------------------------*/ |
|
#define __WINDLL_C /* identifies this source module */ |
|
#define WIN32_LEAN_AND_MEAN |
#define UNZIP_INTERNAL |
#include "../unzip.h" |
#include "../crypt.h" |
#include "../unzvers.h" |
#include "../windll/windll.h" |
#include "../windll/structs.h" |
#include "../consts.h" |
#include <malloc.h> |
|
/* Added type casts to prevent potential "type mismatch" error messages. */ |
#ifdef REENTRANT |
# undef __G |
# undef __G__ |
# define __G (Uz_Globs *)pG |
# define __G__ (Uz_Globs *)pG, |
#endif |
|
HANDLE hwildZipFN; |
HANDLE hInst; /* current instance */ |
HANDLE hDCL; |
int fNoPrinting = 0; |
extern jmp_buf dll_error_return; |
|
/* Helper function to release memory allocated by Wiz_SetOpts() */ |
static void FreeDllMem(__GPRO); |
|
/* For displaying status messages and error messages */ |
static int UZ_EXP DllMessagePrint(zvoid *pG, uch *buf, ulg size, int flag); |
|
#if 0 /* currently unused */ |
/* For displaying files extracted to the display window */ |
int DllDisplayPrint(zvoid *pG, uch *buf, ulg size, int flag); |
#endif /* never */ |
|
/* Callback function for status report and/or user interception */ |
static int UZ_EXP Wiz_StatReportCB(zvoid *pG, int fnflag, ZCONST char *zfn, |
ZCONST char *efn, ZCONST zvoid *details); |
|
/* Dummy sound function for those applications that don't use sound */ |
static void WINAPI DummySound(void); |
|
static int UnzipAllocMemory(unsigned, char *, char *, char ***, unsigned *); |
static int UnzipParseString(LPCSTR, unsigned *, char ***); |
static void UnzipFreeArguments(unsigned, char ***); |
|
#ifndef UNZIPLIB |
/* DLL Entry Point */ |
|
#ifdef __BORLANDC__ |
#pragma argsused |
/* Borland seems to want DllEntryPoint instead of DllMain like MSVC */ |
#define DllMain DllEntryPoint |
#endif |
#ifdef WIN32 |
BOOL WINAPI DllMain( HINSTANCE hInstance, |
DWORD dwReason, |
LPVOID plvReserved) |
#else |
int FAR PASCAL LibMain( HINSTANCE hInstance, |
WORD wDataSegment, |
WORD wHeapSize, |
LPSTR lpszCmdLine ) |
#endif |
{ |
#ifndef WIN32 |
/* The startup code for the DLL initializes the local heap(if there is one) |
* with a call to LocalInit which locks the data segment. |
*/ |
|
if ( wHeapSize != 0 ) |
{ |
UnlockData( 0 ); |
} |
hInst = hInstance; |
return 1; /* Indicate that the DLL was initialized successfully. */ |
#else |
BOOL rc = TRUE; |
switch( dwReason ) |
{ |
case DLL_PROCESS_ATTACH: |
// DLL is loaded. Do your initialization here. |
// If cannot init, set rc to FALSE. |
hInst = hInstance; |
break; |
|
case DLL_PROCESS_DETACH: |
// DLL is unloaded. Do your cleanup here. |
break; |
default: |
break; |
} |
return rc; |
#endif |
} |
|
#ifdef __BORLANDC__ |
#pragma argsused |
#endif |
int FAR PASCAL WEP ( int bSystemExit ) |
{ |
return 1; |
} |
#endif /* !UNZIPLIB */ |
|
static int UnzipAllocMemory(unsigned int i, char *cmd, char *str, |
char ***pargVee, unsigned int *pargCee) |
{ |
if (((*pargVee)[i] = (char *)malloc(sizeof(char) * strlen(cmd)+1 )) |
== NULL) |
{ |
if (pargCee != NULL) |
(*pargCee)++; |
UnzipFreeArguments(*pargCee, pargVee); |
fprintf(stdout, "Unable to allocate memory in unzip library at %s\n", |
str); |
return PK_MEM; |
} |
strcpy((*pargVee)[i], cmd); |
(*pargCee)++; |
return PK_OK; |
} |
|
static void UnzipFreeArguments(unsigned int argCee, char ***pargVee) |
{ |
unsigned i; |
|
/* Free the arguments in the arrays */ |
for (i = 0; i < argCee; i++) |
{ |
free ((*pargVee)[i]); |
(*pargVee)[i] = NULL; |
} |
|
/* Then free the arrays themselves */ |
free(*pargVee); |
} |
|
|
static int UnzipParseString(LPCSTR s, unsigned int *pargCee, char ***pargVee) |
{ |
unsigned int i = 0; |
char *str1, *str2, *str3; |
size_t size; |
|
str1 = (char *) malloc(lstrlen(s)+4); |
lstrcpy(str1, s); |
lstrcat(str1, " @"); |
|
str2 = strchr(str1, '\"'); // get first occurance of double quote |
|
while ((str3 = strchr(str1, '\t')) != NULL) |
{ |
str3[0] = ' '; // Change tabs into a single space |
} |
|
/* Note that if a quoted string contains multiple adjacent spaces, they |
will not be removed, because they could well point to a valid |
folder/file name. |
*/ |
while ((str2 = strchr(str1, '\"')) != NULL) |
{ |
// Found an opening double quote; get the corresponding closing quote |
str3 = strchr(str2+1, '\"'); |
if (str3 == NULL) |
{ |
free(str1); |
return PK_PARAM; /* Something is screwy with the |
string, bail out */ |
} |
str3[0] = '\0'; // terminate str2 with a NULL |
|
size = _msize(*pargVee); |
if ((*pargVee = (char **)realloc(*pargVee, size + sizeof(char *))) |
== NULL) |
{ |
fprintf(stdout, "Unable to allocate memory in unzip dll\n"); |
return PK_MEM; |
} |
// argCee is incremented in UnzipAllocMemory |
if (UnzipAllocMemory(i, str2+1, "Creating file list from string", |
pargVee, pargCee) != PK_OK) |
{ |
free(str1); |
return PK_MEM; |
} |
i++; |
str3+=2; // Point past the whitespace character |
str2[0] = '\0'; // Terminate str1 |
lstrcat(str1, str3); |
} // end while |
|
/* points to first occurance of a space */ |
str2 = strchr(str1, ' '); |
|
/* Go through the string character by character, looking for instances |
of two spaces together. Terminate when you find the trailing @ |
*/ |
while ((str2[0] != '\0') && (str2[0] != '@')) |
{ |
while ((str2[0] == ' ') && (str2[1] == ' ')) |
{ |
str3 = &str2[1]; |
str2[0] = '\0'; |
lstrcat(str1, str3); |
} |
str2++; |
} |
|
/* Do we still have a leading space? */ |
if (str1[0] == ' ') |
{ |
str3 = &str1[1]; |
lstrcpy(str1, str3); // Dump the leading space |
} |
|
|
/* Okay, now we have gotten rid of any tabs and replaced them with |
spaces, and have replaced multiple spaces with a single space. We |
couldn't do this before because the folder names could have actually |
contained these characters. |
*/ |
|
str2 = str3 = str1; |
|
while ((str2[0] != '\0') && (str3[0] != '@')) |
{ |
str3 = strchr(str2+1, ' '); |
str3[0] = '\0'; |
size = _msize(pargVee); |
if ((*pargVee = (char **)realloc(*pargVee, size + sizeof(char *))) |
== NULL) |
{ |
fprintf(stdout, "Unable to allocate memory in unzip dll\n"); |
return PK_MEM; |
} |
if (UnzipAllocMemory(i, str2, "Creating file list from string", |
pargVee, pargCee) != PK_OK) |
{ |
free(str1); |
return PK_MEM; |
} |
i++; |
str3++; |
str2 = str3; |
} |
free(str1); |
return PK_OK; |
} |
|
/* DLL calls */ |
|
BOOL WINAPI Wiz_Init(pG, lpUserFunc) |
zvoid *pG; |
LPUSERFUNCTIONS lpUserFunc; |
{ |
G.message = DllMessagePrint; |
G.statreportcb = Wiz_StatReportCB; |
if (lpUserFunc->sound == NULL) |
lpUserFunc->sound = DummySound; |
G.lpUserFunctions = lpUserFunc; |
|
SETLOCALE(LC_CTYPE, ""); |
|
if (!G.lpUserFunctions->print || |
!G.lpUserFunctions->sound || |
!G.lpUserFunctions->replace) |
return FALSE; |
|
return TRUE; |
} |
|
/* |
StructVersID = version of this structure (= UZ_DCL_STRUCTVER) |
ExtractOnlyNewer = TRUE for "update" without interaction |
(extract only newer/new files, without queries) |
SpaceToUnderscore = TRUE if convert space to underscore |
PromptToOverwrite = TRUE if prompt to overwrite is wanted |
fQuiet = quiet flag: |
0 = all messages, 1 = few messages, 2 = no messages |
ncflag = write to stdout if TRUE |
ntflag = test zip file |
nvflag = verbose listing |
nfflag = "freshen" (replace existing files by newer versions) |
nzflag = display zip file comment |
ndflag = controls (sub)directory recreation during extraction |
0 = junk paths from filenames |
1 = "safe" usage of paths in filenames (skip "../") |
2 = allow also unsafe path components (dir traversal) |
noflag = always overwriting existing files if TRUE |
naflag = do end-of-line translation |
nZIflag = get ZipInfo if TRUE |
B_flag = backup existing files if TRUE |
C_flag = be case insensitive if TRUE |
D_flag = controls restoration of timestamps |
0 = restore all timestamps (default) |
1 = skip restoration of timestamps for folders |
created on behalf of directory entries in the |
Zip archive |
2 = do not restore any timestamps; extracted files |
and directories get stamped with the current time |
U_flag = controls UTF-8 filename coding support |
0 = automatic UTF-8 translation enabled (default) |
1 = recognize UTF-8 coded names, but all non-ASCII |
characters are "escaped" into "#Uxxxx" |
2 = UTF-8 support is disabled, filename handling |
works exactly as in previous UnZip versions |
fPrivilege = 1 => restore ACLs in user mode, |
2 => try to use privileges for restoring ACLs |
lpszZipFN = zip file name |
lpszExtractDir = directory to extract to. This should be NULL if you |
are extracting to the current directory. |
*/ |
|
BOOL WINAPI Wiz_SetOpts(pG, lpDCL) |
zvoid *pG; |
LPDCL lpDCL; |
{ |
if (lpDCL->StructVersID != UZ_DCL_STRUCTVER) |
return FALSE; |
|
uO.qflag = lpDCL->fQuiet; /* Quiet flag */ |
G.pfnames = (char **)&fnames[0]; /* assign default file name vector */ |
G.pxnames = (char **)&fnames[1]; |
|
uO.jflag = (lpDCL->ndflag == 0); |
uO.ddotflag = (lpDCL->ndflag >= 2); |
uO.cflag = lpDCL->ncflag; |
uO.tflag = lpDCL->ntflag; |
uO.vflag = lpDCL->nvflag; |
uO.zflag = lpDCL->nzflag; |
uO.aflag = lpDCL->naflag; |
#ifdef UNIXBACKUP |
uO.B_flag = lpDCL->B_flag; |
#endif |
uO.C_flag = lpDCL->C_flag; |
uO.D_flag = lpDCL->D_flag; |
uO.U_flag = lpDCL->U_flag; |
uO.overwrite_all = lpDCL->noflag; |
uO.overwrite_none = !(lpDCL->noflag || lpDCL->PromptToOverwrite); |
uO.uflag = lpDCL->ExtractOnlyNewer || lpDCL->nfflag; |
uO.fflag = lpDCL->nfflag; |
#ifdef WIN32 |
uO.X_flag = lpDCL->fPrivilege; |
#endif |
uO.sflag = lpDCL->SpaceToUnderscore; /* Translate spaces to underscores? */ |
if (lpDCL->nZIflag) |
{ |
uO.zipinfo_mode = TRUE; |
uO.hflag = TRUE; |
uO.lflag = 10; |
uO.qflag = 2; |
} |
else |
{ |
uO.zipinfo_mode = FALSE; |
} |
|
G.extract_flag = (!uO.zipinfo_mode && |
!uO.cflag && !uO.tflag && !uO.vflag && !uO.zflag |
#ifdef TIMESTAMP |
&& !uO.T_flag |
#endif |
); |
|
if (lpDCL->lpszExtractDir != NULL && G.extract_flag) |
{ |
#ifndef CRTL_CP_IS_ISO |
char *pExDirRoot = (char *)malloc(strlen(lpDCL->lpszExtractDir)+1); |
|
if (pExDirRoot == NULL) |
return FALSE; |
ISO_TO_INTERN(lpDCL->lpszExtractDir, pExDirRoot); |
#else |
# define pExDirRoot lpDCL->lpszExtractDir |
#endif |
if (strlen(pExDirRoot) >= FILNAMSIZ) |
{ |
/* The supplied extract root path exceed the filename size limit. */ |
#ifndef CRTL_CP_IS_ISO |
free(pExDirRoot); |
#endif |
return FALSE; |
} |
uO.exdir = pExDirRoot; |
} |
else |
{ |
uO.exdir = (char *)NULL; |
} |
|
/* G.wildzipfn needs to be initialized so that do_wild does not wind |
up clearing out the zip file name when it returns in process.c |
*/ |
if (strlen(lpDCL->lpszZipFN) >= FILNAMSIZ) |
/* length of supplied archive name exceed the system's filename limit */ |
return FALSE; |
|
hwildZipFN = GlobalAlloc(GPTR, FILNAMSIZ); |
if (hwildZipFN == (HGLOBAL) NULL) |
return FALSE; |
|
G.wildzipfn = GlobalLock(hwildZipFN); |
lstrcpy(G.wildzipfn, lpDCL->lpszZipFN); |
_ISO_INTERN(G.wildzipfn); |
|
return TRUE; /* set up was OK */ |
} |
|
static void FreeDllMem(__GPRO) |
{ |
if (G.wildzipfn) { |
GlobalUnlock(hwildZipFN); |
G.wildzipfn = NULL; |
} |
if (hwildZipFN) |
hwildZipFN = GlobalFree(hwildZipFN); |
|
#ifndef CRTL_CP_IS_ISO |
if (uO.exdir != NULL) { |
free(uO.exdir); |
uO.exdir = NULL; |
} |
#endif |
|
uO.zipinfo_mode = FALSE; |
} |
|
int WINAPI Wiz_Unzip(pG, ifnc, ifnv, xfnc, xfnv) |
zvoid *pG; |
int ifnc; |
char **ifnv; |
int xfnc; |
char **xfnv; |
{ |
int retcode, f_cnt; |
#ifndef CRTL_CP_IS_ISO |
unsigned bufsize; |
char **intern_ifv = NULL, **intern_xfv = NULL; |
#endif |
|
if (ifnv == (char **)NULL && ifnc != 0) |
ifnc = 0; |
else |
for (f_cnt = 0; f_cnt < ifnc; f_cnt++) |
if (ifnv[f_cnt] == (char *)NULL) { |
ifnc = f_cnt; |
break; |
} |
if (xfnv == (char **)NULL && xfnc != 0) |
xfnc = 0; |
else |
for (f_cnt = 0; f_cnt < xfnc; f_cnt++) |
if (xfnv[f_cnt] == (char *)NULL) { |
xfnc = f_cnt; |
break; |
} |
|
G.process_all_files = (ifnc == 0 && xfnc == 0); /* for speed */ |
G.filespecs = ifnc; |
G.xfilespecs = xfnc; |
|
if (ifnc > 0) { |
for (f_cnt = ifnc; --f_cnt >= 0;) |
if (strlen(ifnv[f_cnt]) > ((WSIZE>>2) - 160)) { |
/* include filename pattern is too long for internal buffers */ |
FreeDllMem(__G); |
return PK_PARAM; |
} |
|
#ifdef CRTL_CP_IS_ISO |
G.pfnames = ifnv; |
#else /* !CRTL_CP_IS_ISO */ |
intern_ifv = (char **)malloc((ifnc+1)*sizeof(char **)); |
if (intern_ifv == (char **)NULL) |
{ |
FreeDllMem(__G); |
return PK_BADERR; |
} |
|
bufsize = 0; |
for (f_cnt = ifnc; --f_cnt >= 0;) |
bufsize += strlen(ifnv[f_cnt]) + 1; |
intern_ifv[0] = (char *)malloc(bufsize); |
if (intern_ifv[0] == (char *)NULL) |
{ |
free(intern_ifv); |
FreeDllMem(__G); |
return PK_BADERR; |
} |
|
for (f_cnt = 0; ; f_cnt++) |
{ |
ISO_TO_INTERN(ifnv[f_cnt], intern_ifv[f_cnt]); |
if ((f_cnt+1) >= ifnc) |
break; |
intern_ifv[f_cnt+1] = intern_ifv[f_cnt] + |
(strlen(intern_ifv[f_cnt]) + 1); |
} |
intern_ifv[ifnc] = (char *)NULL; |
G.pfnames = intern_ifv; |
#endif /* ?CRTL_CP_IS_ISO */ |
} |
|
if (xfnc > 0) { |
for (f_cnt = xfnc; --f_cnt >= 0;) |
if (strlen(xfnv[f_cnt]) > ((WSIZE>>2) - 160)) |
{ |
/* exclude filename pattern is too long for internal buffers */ |
#ifndef CRTL_CP_IS_ISO |
if (ifnc > 0) |
{ |
free(intern_ifv[0]); |
free(intern_ifv); |
} |
#endif |
FreeDllMem(__G); |
return PK_PARAM; |
} |
|
#ifdef CRTL_CP_IS_ISO |
G.pxnames = xfnv; |
#else /* !CRTL_CP_IS_ISO */ |
intern_xfv = (char **)malloc((xfnc+1)*sizeof(char **)); |
if (intern_xfv == (char **)NULL) |
{ |
if (ifnc > 0) |
{ |
free(intern_ifv[0]); |
free(intern_ifv); |
} |
FreeDllMem(__G); |
return PK_BADERR; |
} |
|
bufsize = 0; |
for (f_cnt = xfnc; --f_cnt >= 0;) |
bufsize += strlen(xfnv[f_cnt]) + 1; |
intern_xfv[0] = (char *)malloc(bufsize); |
if (intern_xfv[0] == (char *)NULL) |
{ |
free(intern_xfv); |
if (ifnc > 0) |
{ |
free(intern_ifv[0]); |
free(intern_ifv); |
} |
FreeDllMem(__G); |
return PK_BADERR; |
} |
|
for (f_cnt = 0; ; f_cnt++) |
{ |
ISO_TO_INTERN(xfnv[f_cnt], intern_xfv[f_cnt]); |
if ((f_cnt+1) >= xfnc) |
break; |
intern_xfv[f_cnt+1] = intern_xfv[f_cnt] + |
(strlen(intern_xfv[f_cnt]) + 1); |
} |
intern_xfv[xfnc] = (char *)NULL; |
G.pxnames = intern_xfv; |
#endif /* ?CRTL_CP_IS_ISO */ |
} |
|
/*--------------------------------------------------------------------------- |
Okey dokey, we have everything we need to get started. Let's roll. |
---------------------------------------------------------------------------*/ |
|
retcode = setjmp(dll_error_return); |
if (retcode) |
{ |
#ifndef CRTL_CP_IS_ISO |
if (xfnc > 0) |
{ |
free(intern_xfv[0]); |
free(intern_xfv); |
} |
if (ifnc > 0) |
{ |
free(intern_ifv[0]); |
free(intern_ifv); |
} |
#endif |
FreeDllMem(__G); |
return PK_BADERR; |
} |
|
retcode = process_zipfiles(__G); |
#ifndef CRTL_CP_IS_ISO |
if (xfnc > 0) |
{ |
free(intern_xfv[0]); |
free(intern_xfv); |
} |
if (ifnc > 0) |
{ |
free(intern_ifv[0]); |
free(intern_ifv); |
} |
#endif |
FreeDllMem(__G); |
return retcode; |
} |
|
|
/* |
ifnc = number of file names being passed. If all files are to be |
extracted, then this can be zero. |
ifnv = file names to be unarchived. Wildcard patterns are recognized |
and expanded. If all files are to be extracted, then this can |
be NULL. |
xfnc = number of "file names to be excluded from processing" being |
passed. If all files are to be extracted, set this to zero. |
xfnv = file names to be excluded from the unarchiving process. Wildcard |
characters are allowed and expanded. If all files are to be |
extracted, set this argument to NULL. |
lpDCL = pointer to a structure with the flags for setting the |
various options, as well as the zip file name. |
lpUserFunc = pointer to a structure that contains pointers to functions |
in the calling application, as well as sizes passed back to |
the calling application etc. |
*/ |
|
int WINAPI Wiz_SingleEntryUnzip(int ifnc, char **ifnv, int xfnc, char **xfnv, |
LPDCL lpDCL, LPUSERFUNCTIONS lpUserFunc) |
{ |
int retcode; |
CONSTRUCTGLOBALS(); |
|
if (!Wiz_Init((zvoid *)&G, lpUserFunc)) |
{ |
DESTROYGLOBALS(); |
return PK_BADERR; |
} |
|
if (lpDCL->lpszZipFN == NULL) |
{ |
/* Something has screwed up, we don't have a filename */ |
DESTROYGLOBALS(); |
return PK_NOZIP; |
} |
|
if (!Wiz_SetOpts((zvoid *)&G, lpDCL)) |
{ |
DESTROYGLOBALS(); |
return PK_MEM; |
} |
|
#ifdef SFX |
G.zipfn = lpDCL->lpszZipFN; |
G.argv0 = lpDCL->lpszZipFN; |
#endif |
|
/* Here is the actual call to "unzip" the files (or whatever else you |
* are doing.) |
*/ |
retcode = Wiz_Unzip((zvoid *)&G, ifnc, ifnv, xfnc, xfnv); |
|
DESTROYGLOBALS(); |
return retcode; |
} |
|
|
/* |
This calling wrapper provided a method to pass file lists as plain strings |
instead of the usual string arrays. For VB Users only... |
ifnc = number of file names being passed. If all files are to be |
extracted, then this can be zero. |
ExtList = Pointer to a list of file names to be extracted, separated by |
white space. If all files are to be extracted, then this should |
be NULL. Parameter ifnc should have an accurate count of the |
number of filenames being passed in. |
xfnc = number of "file names to be excluded from processing" being |
passed. If all files are to be extracted, set this to zero. |
ExcList = Pointer to a list of file names to be excluded from processing. |
Parameter xfnc should have an accurate count of the number of |
the number of filenames being passed in. |
lpDCL = pointer to a structure with the flags for setting the |
various options, as well as the zip file name. |
lpUserFunc = pointer to a structure that contains pointers to functions |
in the calling application, as well as sizes passed back to |
the calling application etc. |
*/ |
|
int WINAPI Wiz_SingleEntryUnzpList(unsigned int ifnc, LPCSTR ExtList, |
unsigned int xfnc, LPCSTR ExcList, |
LPDCL lpDCL, LPUSERFUNCTIONS lpUserFunc) |
{ |
int retcode; |
char **argVExt, **argVExc; |
unsigned int argCExt, argCExc; |
|
argCExt = argCExc = 0; |
|
if (ExtList != NULL) |
{ |
if ((argVExt = (char **)malloc((ifnc)*sizeof(char *))) == NULL) |
{ |
fprintf(stdout, "Unable to allocate memory in unzip dll\n"); |
return PK_MEM; |
} |
if ((retcode = UnzipParseString(ExtList, &argCExt, &argVExt)) != PK_OK) |
return retcode; |
} |
|
if (ExcList != NULL) |
{ |
if ((argVExc = (char **)malloc((ifnc)*sizeof(char *))) == NULL) |
{ |
fprintf(stdout, "Unable to allocate memory in unzip dll\n"); |
UnzipFreeArguments(argCExt, &argVExt); |
return PK_MEM; |
} |
if ((retcode = UnzipParseString(ExcList, &argCExc, &argVExc)) != PK_OK) |
{ |
UnzipFreeArguments(argCExt, &argVExt); |
return retcode; |
} |
} |
|
retcode = Wiz_SingleEntryUnzip(argCExt, argVExt, argCExc, argVExc, |
lpDCL, lpUserFunc); |
UnzipFreeArguments(argCExc, &argVExc); |
UnzipFreeArguments(argCExt, &argVExt); |
return retcode; |
} |
|
|
int win_fprintf(zvoid *pG, FILE *file, unsigned int size, char far *buffer) |
{ |
if ((file != stderr) && (file != stdout)) |
{ |
return write(fileno(file),(char far *)(buffer),size); |
} |
if (!fNoPrinting) |
return G.lpUserFunctions->print((LPSTR)buffer, size); |
return (int)size; |
} |
|
/********************************** |
* Function DllMessagePrint() * |
* * |
* Send messages to status window * |
**********************************/ |
#ifdef __BORLANDC__ |
#pragma argsused |
#endif |
static int UZ_EXP DllMessagePrint(pG, buf, size, flag) |
zvoid *pG; /* globals struct: always passed */ |
uch *buf; /* preformatted string to be printed */ |
ulg size; /* length of string (may include nulls) */ |
int flag; /* flag bits */ |
{ |
if (!fNoPrinting) |
return G.lpUserFunctions->print((LPSTR)buf, size); |
else |
return (int)size; |
} |
|
#if 0 /* currently unused */ |
/******************************** |
* Function DllDisplayPrint() * |
* * |
* Send files to display window * |
********************************/ |
#ifdef __BORLANDC__ |
#pragma argsused |
#endif |
int DllDisplayPrint(pG, buf, size, flag) |
zvoid *pG; /* globals struct: always passed */ |
uch *buf; /* preformatted string to be printed */ |
ulg size; /* length of string (may include nulls) */ |
int flag; /* flag bits */ |
{ |
return (!fNoPrinting |
? G.lpUserFunctions->print((LPSTR)buf, size) |
: (int)size); |
} |
#endif /* never */ |
|
|
/********************************** |
* Function UzpPassword() * |
* * |
* Prompt for decryption password * |
**********************************/ |
#ifdef __BORLANDC__ |
#pragma argsused |
#endif |
int UZ_EXP UzpPassword(pG, rcnt, pwbuf, size, zfn, efn) |
zvoid *pG; /* globals struct: always passed */ |
int *rcnt; /* retry counter */ |
char *pwbuf; /* buffer for password */ |
int size; /* size of password buffer */ |
ZCONST char *zfn; /* name of zip archiv */ |
ZCONST char *efn; /* name of archiv entry being processed */ |
{ |
#if CRYPT |
LPCSTR m; |
|
if (*rcnt == 0) { |
*rcnt = 2; |
m = "Enter password for: "; |
} else { |
(*rcnt)--; |
m = "Password incorrect--reenter: "; |
} |
|
return (*G.lpUserFunctions->password)((LPSTR)pwbuf, size, m, (LPCSTR)efn); |
#else /* !CRYPT */ |
return IZ_PW_ERROR; /* internal error, function should never get called */ |
#endif /* ?CRYPT */ |
} /* end function UzpPassword() */ |
|
/* Turn off all messages to the calling application */ |
void WINAPI Wiz_NoPrinting(int f) |
{ |
fNoPrinting = f; |
} |
|
/* Dummy sound function for those applications that don't use sound */ |
static void WINAPI DummySound(void) |
{ |
} |
|
/* Interface between WINDLL specific service callback functions and the |
generic DLL's "status report & user interception" callback */ |
#ifdef __BORLANDC__ |
#pragma argsused |
#endif |
static int WINAPI Wiz_StatReportCB(zvoid *pG, int fnflag, ZCONST char *zfn, |
ZCONST char *efn, ZCONST zvoid *details) |
{ |
int rval = UZ_ST_CONTINUE; |
|
switch (fnflag) { |
case UZ_ST_START_EXTRACT: |
if (G.lpUserFunctions->sound != NULL) |
(*G.lpUserFunctions->sound)(); |
break; |
case UZ_ST_FINISH_MEMBER: |
if ((G.lpUserFunctions->ServCallBk != NULL) && |
(*G.lpUserFunctions->ServCallBk)(efn, |
(details == NULL ? 0L : |
#ifdef Z_UINT8_DEFINED |
(z_uint8)(*((zusz_t *)details)) |
#else |
*((zusz_t *)details) |
#endif |
))) |
rval = UZ_ST_BREAK; |
else if (G.lpUserFunctions->ServCallBk_i32 != NULL) { |
unsigned long siz_u4L = 0L; |
unsigned long siz_u4H = 0L; |
if (details != NULL) { |
siz_u4L = (unsigned long)(*(zusz_t *)details); |
#ifdef ZIP64_SUPPORT |
siz_u4H = (unsigned long)((*(zusz_t *)details) >> 32); |
#endif |
} |
if ((*G.lpUserFunctions->ServCallBk_i32)(efn, siz_u4L, siz_u4H)) |
rval = UZ_ST_BREAK; |
} |
break; |
case UZ_ST_IN_PROGRESS: |
break; |
default: |
break; |
} |
return rval; |
} |
|
|
#ifndef SFX |
#ifndef __16BIT__ |
|
int WINAPI Wiz_UnzipToMemory(LPSTR zip, LPSTR file, |
LPUSERFUNCTIONS lpUserFunctions, UzpBuffer *retstr) |
{ |
int r; |
#ifndef CRTL_CP_IS_ISO |
char *intern_zip, *intern_file; |
#endif |
|
CONSTRUCTGLOBALS(); |
#ifndef CRTL_CP_IS_ISO |
intern_zip = (char *)malloc(strlen(zip)+1); |
if (intern_zip == NULL) { |
DESTROYGLOBALS(); |
return PK_MEM; |
} |
intern_file = (char *)malloc(strlen(file)+1); |
if (intern_file == NULL) { |
DESTROYGLOBALS(); |
free(intern_zip); |
return PK_MEM; |
} |
ISO_TO_INTERN(zip, intern_zip); |
ISO_TO_INTERN(file, intern_file); |
# define zip intern_zip |
# define file intern_file |
#endif |
if (!Wiz_Init((zvoid *)&G, lpUserFunctions)) { |
DESTROYGLOBALS(); |
return PK_BADERR; |
} |
G.redirect_data = 1; |
|
r = (unzipToMemory(__G__ zip, file, retstr) == PK_COOL); |
|
DESTROYGLOBALS(); |
#ifndef CRTL_CP_IS_ISO |
# undef file |
# undef zip |
free(intern_file); |
free(intern_zip); |
#endif |
if (!r && retstr->strlength) { |
free(retstr->strptr); |
retstr->strptr = NULL; |
} |
return r; |
} |
|
|
|
|
/* Purpose: Determine if file in archive contains the string szSearch |
|
Parameters: archive = archive name |
file = file contained in the archive. This cannot be |
a wildcard to be meaningful |
pattern = string to search for |
cmd = 0 - case-insensitive search |
1 - case-sensitve search |
2 - case-insensitive, whole words only |
3 - case-sensitive, whole words only |
SkipBin = if true, skip any files that have control |
characters other than CR, LF, or tab in the first |
100 characters. |
|
Returns: TRUE if a match is found |
FALSE if no match is found |
-1 on error |
|
Comments: This does not pretend to be as useful as the standard |
Unix grep, which returns the strings associated with a |
particular pattern, nor does it search past the first |
matching occurrence of the pattern. |
*/ |
|
int WINAPI Wiz_Grep(LPSTR archive, LPSTR file, LPSTR pattern, int cmd, |
int SkipBin, LPUSERFUNCTIONS lpUserFunctions) |
{ |
int retcode = FALSE, compare; |
ulg i, j, patternLen, buflen; |
char * sz, *p; |
UzpBuffer retstr; |
|
/* Turn off any windows printing functions, as they may not have been |
* identified yet. There is no requirement that we initialize the |
* dll with printing stuff for this. */ |
Wiz_NoPrinting(TRUE); |
|
if (!Wiz_UnzipToMemory(archive, file, lpUserFunctions, &retstr)) { |
Wiz_NoPrinting(FALSE); |
return -1; /* not enough memory, file not found, or other error */ |
} |
|
if (SkipBin) { |
if (retstr.strlength < 100) |
buflen = retstr.strlength; |
else |
buflen = 100; |
for (i = 0; i < buflen; i++) { |
if (iscntrl(retstr.strptr[i])) { |
if ((retstr.strptr[i] != 0x0A) && |
(retstr.strptr[i] != 0x0D) && |
(retstr.strptr[i] != 0x09)) |
{ |
/* OK, we now think we have a binary file of some sort */ |
free(retstr.strptr); |
Wiz_NoPrinting(FALSE); |
return FALSE; |
} |
} |
} |
} |
|
patternLen = strlen(pattern); |
|
if (retstr.strlength < patternLen) { |
free(retstr.strptr); |
Wiz_NoPrinting(FALSE); |
return FALSE; |
} |
|
sz = malloc(patternLen + 3); /* add two in case doing whole words only */ |
if (cmd > 1) { |
strcpy(sz, " "); |
strcat(sz, pattern); |
strcat(sz, " "); |
} else |
strcpy(sz, pattern); |
|
if ((cmd == 0) || (cmd == 2)) { |
for (i = 0; i < strlen(sz); i++) |
sz[i] = toupper(sz[i]); |
for (i = 0; i < retstr.strlength; i++) |
retstr.strptr[i] = toupper(retstr.strptr[i]); |
} |
|
for (i = 0; i < (retstr.strlength - patternLen); i++) { |
p = &retstr.strptr[i]; |
compare = TRUE; |
for (j = 0; j < patternLen; j++) { |
/* We cannot do strncmp here, as we may be dealing with a |
* "binary" file, such as a word processing file, or perhaps |
* even a true executable of some sort. */ |
if (p[j] != sz[j]) { |
compare = FALSE; |
break; |
} |
} |
if (compare == TRUE) { |
retcode = TRUE; |
break; |
} |
} |
|
free(sz); |
free(retstr.strptr); |
Wiz_NoPrinting(FALSE); /* Turn printing back on */ |
return retcode; |
} |
#endif /* !__16BIT__ */ |
|
int WINAPI Wiz_Validate(LPSTR archive, int AllCodes) |
{ |
return UzpValidate((char *)archive, AllCodes); |
} |
|
#endif /* !SFX */ |