"Fossies" - the Fresh Open Source Software Archive 
Member "uzexampl.c" (25 Jan 2009, 14167 Bytes) of package /windows/misc/unz600dn.zip:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "uzexampl.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
3
4 See the accompanying file LICENSE, version 2009-Jan-02 or later
5 (the contents of which are also included in unzip.h) for terms of use.
6 If, for some reason, all these files are missing, the Info-ZIP license
7 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
8 */
9 /*
10 This is a very simplistic example of how to load and make a call into the
11 dll. This has been compiled and tested for a 32-bit console version, but
12 not under 16-bit windows. However, the #ifdef's have been left in for the
13 16-bit code, simply as an example.
14
15 */
16
17 #ifndef WIN32 /* this code is currently only tested for 32-bit console */
18 # define WIN32
19 #endif
20
21 #if defined(__WIN32__) && !defined(WIN32)
22 # define WIN32
23 #endif
24
25 /* Tell Microsoft Visual C++ 2005 to leave us alone and
26 * let us use standard C functions the way we're supposed to.
27 */
28 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
29 # ifndef _CRT_SECURE_NO_WARNINGS
30 # define _CRT_SECURE_NO_WARNINGS
31 # endif
32 # ifndef _CRT_NONSTDC_NO_WARNINGS
33 # define _CRT_NONSTDC_NO_WARNINGS
34 # endif
35 #endif
36
37 #include <stddef.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <time.h>
41 #include <string.h>
42 #include "uzexampl.h"
43 #include "../unzvers.h"
44 #ifdef WIN32
45 # include <winver.h>
46 #else
47 # include <ver.h>
48 #endif
49
50 #ifndef _MAX_PATH
51 # define _MAX_PATH 260 /* max total file or directory name path */
52 #endif
53
54 #ifdef WIN32
55 #define UNZ_DLL_NAME "UNZIP32.DLL\0"
56 #else
57 #define UNZ_DLL_NAME "UNZIP16.DLL\0"
58 #endif
59
60 #define DLL_WARNING "Cannot find %s."\
61 " The Dll must be in the application directory, the path, "\
62 "the Windows directory or the Windows System directory."
63 #define DLL_VERSION_WARNING "%s has the wrong version number."\
64 " Insure that you have the correct dll's installed, and that "\
65 "an older dll is not in your path or Windows System directory."
66
67 int hFile; /* file handle */
68
69 LPUSERFUNCTIONS lpUserFunctions;
70 HANDLE hUF = (HANDLE)NULL;
71 LPDCL lpDCL = NULL;
72 HANDLE hDCL = (HANDLE)NULL;
73 HINSTANCE hUnzipDll;
74 HANDLE hZCL = (HANDLE)NULL;
75 #ifdef WIN32
76 DWORD dwPlatformId = 0xFFFFFFFF;
77 #endif
78 static ZCONST UzpVer *lpUzVersInfo = NULL;
79
80
81 /* Forward References */
82 int WINAPI DisplayBuf(LPSTR, unsigned long);
83 int WINAPI GetReplaceDlgRetVal(LPSTR, unsigned);
84 int WINAPI password(LPSTR, int, LPCSTR, LPCSTR);
85
86 ZCONST UzpVer * UZ_EXP UzpVersion OF((void));
87 _DLL_UZVER pUzpVersion;
88 _DLL_UNZIP pWiz_SingleEntryUnzip;
89
90 static void FreeUpMemory(void);
91
92 int main(int argc, char **argv)
93 {
94 int exfc, infc;
95 char **exfv, **infv;
96 char *x_opt;
97 DWORD dwVerInfoSize;
98 DWORD dwVerHnd;
99 char szFullPath[_MAX_PATH];
100 int retcode;
101 #ifdef WIN32
102 char *ptr;
103 #else
104 HFILE hfile;
105 OFSTRUCT ofs;
106 #endif
107 HANDLE hMem; /* handle to mem alloc'ed */
108
109 if (argc < 2) /* We must have an archive to unzip */
110 {
111 char *progname = strrchr(argv[0], '\\');
112
113 if (progname != NULL)
114 progname++;
115 else
116 {
117 progname = argv[0];
118 if (progname == NULL || *progname == '\0') progname = "example";
119 }
120 printf("usage: %s <zipfile> [entry1 [entry2 [...]]] [-x xentry1 [...]]",
121 progname);
122 return 0;
123 }
124
125 hDCL = GlobalAlloc( GPTR, (DWORD)sizeof(DCL));
126 if (!hDCL)
127 {
128 return -1;
129 }
130 lpDCL = (LPDCL)GlobalLock(hDCL);
131 if (!lpDCL)
132 {
133 GlobalFree(hDCL);
134 return -1;
135 }
136
137 hUF = GlobalAlloc( GPTR, (DWORD)sizeof(USERFUNCTIONS));
138 if (!hUF)
139 {
140 GlobalUnlock(hDCL);
141 GlobalFree(hDCL);
142 return -1;
143 }
144 lpUserFunctions = (LPUSERFUNCTIONS)GlobalLock(hUF);
145
146 if (!lpUserFunctions)
147 {
148 GlobalFree(hUF);
149 GlobalUnlock(hDCL);
150 GlobalFree(hDCL);
151 return -1;
152 }
153
154 lpUserFunctions->password = password;
155 lpUserFunctions->print = DisplayBuf;
156 lpUserFunctions->sound = NULL;
157 lpUserFunctions->replace = GetReplaceDlgRetVal;
158 lpUserFunctions->SendApplicationMessage = ReceiveDllMessage;
159
160 /* First we go look for the unzip dll */
161 #ifdef WIN32
162 if (SearchPath(
163 NULL, /* address of search path */
164 UNZ_DLL_NAME, /* address of filename */
165 NULL, /* address of extension */
166 _MAX_PATH, /* size, in characters, of buffer */
167 szFullPath, /* address of buffer for found filename */
168 &ptr /* address of pointer to file component */
169 ) == 0)
170 #else
171 hfile = OpenFile(UNZ_DLL_NAME, &ofs, OF_SEARCH);
172 if (hfile == HFILE_ERROR)
173 #endif
174 {
175 char str[256];
176 wsprintf (str, DLL_WARNING, UNZ_DLL_NAME);
177 printf("%s\n", str);
178 FreeUpMemory();
179 return -1;
180 }
181 #ifndef WIN32
182 else
183 lstrcpy(szFullPath, ofs.szPathName);
184 _lclose(hfile);
185 #endif
186
187 /* Now we'll check the unzip dll version information. Note that this is
188 not the same information as is returned from a call to UzpVersion()
189 */
190 dwVerInfoSize =
191 GetFileVersionInfoSize(szFullPath, &dwVerHnd);
192
193 if (dwVerInfoSize)
194 {
195 BOOL fRet, fRetName;
196 char str[256];
197 LPSTR lpstrVffInfo; /* Pointer to block to hold info */
198 LPSTR lszVer = NULL;
199 LPSTR lszVerName = NULL;
200 UINT cchVer = 0;
201
202 /* Get a block big enough to hold the version information */
203 hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
204 lpstrVffInfo = GlobalLock(hMem);
205
206 /* Get the version information */
207 if (GetFileVersionInfo(szFullPath, 0L, dwVerInfoSize, lpstrVffInfo))
208 {
209 fRet = VerQueryValue(lpstrVffInfo,
210 TEXT("\\StringFileInfo\\040904E4\\FileVersion"),
211 (LPVOID)&lszVer,
212 &cchVer);
213 fRetName = VerQueryValue(lpstrVffInfo,
214 TEXT("\\StringFileInfo\\040904E4\\CompanyName"),
215 (LPVOID)&lszVerName,
216 &cchVer);
217 if (!fRet || !fRetName ||
218 (lstrcmpi(lszVer, UNZ_DLL_VERSION) != 0) ||
219 (lstrcmpi(lszVerName, IZ_COMPANY_NAME) != 0))
220 {
221 wsprintf (str, DLL_VERSION_WARNING, UNZ_DLL_NAME);
222 printf("%s\n", str);
223 GlobalUnlock(hMem);
224 GlobalFree(hMem);
225 FreeUpMemory();
226 return -1;
227 }
228 }
229 /* free memory */
230 GlobalUnlock(hMem);
231 GlobalFree(hMem);
232 }
233 else
234 {
235 char str[256];
236 wsprintf (str, DLL_VERSION_WARNING, UNZ_DLL_NAME);
237 printf("%s\n", str);
238 FreeUpMemory();
239 return -1;
240 }
241 /* Okay, now we know that the dll exists, and has the proper version
242 * information in it. We can go ahead and load it.
243 */
244 hUnzipDll = LoadLibrary(UNZ_DLL_NAME);
245 #ifndef WIN32
246 if (hUnzipDll > HINSTANCE_ERROR)
247 #else
248 if (hUnzipDll != NULL)
249 #endif
250 {
251 pUzpVersion =
252 (_DLL_UZVER)GetProcAddress(hUnzipDll, "UzpVersion");
253 pWiz_SingleEntryUnzip =
254 (_DLL_UNZIP)GetProcAddress(hUnzipDll, "Wiz_SingleEntryUnzip");
255 }
256 else
257 {
258 char str[256];
259 wsprintf (str, "Could not load %s", UNZ_DLL_NAME);
260 printf("%s\n", str);
261 FreeUpMemory();
262 return -1;
263 }
264
265 /*
266 Before we actually start with the extraction process, we should first
267 check whether the API of the loaded dll is compatible with the API
268 definition used to compile this frontend program.
269 */
270 lpUzVersInfo = (*pUzpVersion)();
271
272 /* The UnZip WinDLL code may change quite frequently. To be safe, we
273 * require the DLL to be at least at the release level of this example
274 * frontend code.
275 */
276 # define UZDLL_MINVERS_MAJOR UZ_MAJORVER
277 # define UZDLL_MINVERS_MINOR UZ_MINORVER
278 # define UZDLL_MINVERS_PATCHLEVEL UZ_PATCHLEVEL
279 /* This UnZip DLL stub requires a DLL version of at least: */
280 if ( (lpUzVersInfo->unzip.major < UZDLL_MINVERS_MAJOR) ||
281 ((lpUzVersInfo->unzip.major == UZDLL_MINVERS_MAJOR) &&
282 ((lpUzVersInfo->unzip.minor < UZDLL_MINVERS_MINOR) ||
283 ((lpUzVersInfo->unzip.minor == UZDLL_MINVERS_MINOR) &&
284 (lpUzVersInfo->unzip.patchlevel < UZDLL_MINVERS_PATCHLEVEL)
285 )
286 )
287 ) )
288 {
289 char str[256];
290 wsprintf(str, "The version %u.%u%u of the loaded UnZip DLL is too old!",
291 lpUzVersInfo->unzip.major, lpUzVersInfo->unzip.minor,
292 lpUzVersInfo->unzip.patchlevel);
293 printf("%s\n", str);
294 FreeLibrary(hUnzipDll);
295 FreeUpMemory();
296 return -1;
297 }
298
299 if (lpUzVersInfo->structlen >=
300 (offsetof(UzpVer, dllapimin) + sizeof(_version_type)))
301 {
302 if ( (lpUzVersInfo->dllapimin.major > UZ_WINAPI_COMP_MAJOR) ||
303 ((lpUzVersInfo->dllapimin.major == UZ_WINAPI_COMP_MAJOR) &&
304 ((lpUzVersInfo->dllapimin.minor > UZ_WINAPI_COMP_MINOR) ||
305 ((lpUzVersInfo->dllapimin.minor == UZ_WINAPI_COMP_MINOR) &&
306 (lpUzVersInfo->dllapimin.patchlevel > UZ_WINAPI_COMP_REVIS)
307 )
308 )
309 ) )
310 {
311 char str[256];
312 wsprintf(str, "Found incompatible WinDLL API version %u.%u%u, aborting!",
313 lpUzVersInfo->dllapimin.major, lpUzVersInfo->dllapimin.minor,
314 lpUzVersInfo->dllapimin.patchlevel);
315 printf("%s\n", str);
316 FreeLibrary(hUnzipDll);
317 FreeUpMemory();
318 return -1;
319 }
320 }
321
322 /*
323 Here is where the actual extraction process begins. First we set up the
324 flags to be passed into the dll.
325 */
326 lpDCL->StructVersID = UZ_DCL_STRUCTVER; /* version of this structure */
327 lpDCL->ncflag = 0; /* write to stdout if true */
328 lpDCL->fQuiet = 0; /* we want all messages
329 1 = fewer messages,
330 2 = no messages */
331 lpDCL->ntflag = 0; /* test zip file if true */
332 lpDCL->nvflag = 0; /* give a verbose listing if true */
333 lpDCL->nzflag = 0; /* display zip file comment if true */
334 lpDCL->ndflag = 1; /* recreate directories != 0,
335 skip "../" if < 2 */
336 lpDCL->naflag = 0; /* do not convert CR to CRLF */
337 lpDCL->nfflag = 0; /* do not freshen existing files only */
338 lpDCL->noflag = 1; /* over-write all files if true */
339 lpDCL->nZIflag = 0; /* no ZipInfo output mode */
340 lpDCL->B_flag = 0; /* do not backup existing files */
341 lpDCL->C_flag = 0; /* do not match case-insensitive */
342 lpDCL->D_flag = 0; /* restore all timestamps */
343 lpDCL->U_flag = 0; /* do not disable UTF-8 support */
344 lpDCL->ExtractOnlyNewer = 0; /* do not extract only newer */
345 lpDCL->SpaceToUnderscore = 0; /* do not convert space to '_' in filenames */
346 lpDCL->PromptToOverwrite = 0; /* "overwrite all" selected -> no query mode */
347 lpDCL->lpszZipFN = argv[1]; /* the archive name */
348 lpDCL->lpszExtractDir = NULL; /* the directory to extract to.
349 This is set to NULL if you are extracting
350 to the current directory.
351 */
352 /*
353 As this is a quite short example, intended primarily to show how to
354 load and call in to the dll, the command-line parameters are only
355 parsed in a very simplistic way:
356 We assume that the command-line parameters after the zip archive
357 make up a list of file patterns:
358 " [file_i1] [file_i2] ... [file_iN] [-x file_x1 [file_x2] ...]".
359 We scan for an argument "-x"; all arguments in front are
360 "include file patterns", all arguments after are "exclude file patterns".
361 If no more arguments are given, we extract ALL files.
362
363 In summary, the example program should be run like:
364 example <archive.name> [files to include] [-x files to exclude]
365 ("<...> denotes mandatory arguments, "[...]" optional arguments)
366 */
367 x_opt = NULL;
368 if (argc > 2) {
369 infv = &argv[2];
370 for (infc = 0; infc < argc-2; infc++)
371 if (!strcmp("-x", infv[infc])) {
372 x_opt = infv[infc];
373 infv[infc] = NULL;
374 break;
375 }
376 exfc = argc - infc - 3;
377 if (exfc > 0)
378 exfv = &argv[infc+3];
379 else {
380 exfc = 0;
381 exfv = NULL;
382 }
383 } else {
384 infc = exfc = 0;
385 infv = exfv = NULL;
386 }
387 retcode = (*pWiz_SingleEntryUnzip)(infc, infv, exfc, exfv, lpDCL,
388 lpUserFunctions);
389 if (x_opt) {
390 infv[infc] = x_opt;
391 x_opt = NULL;
392 }
393
394 if (retcode != 0)
395 printf("Error unzipping (error/warning code %d)...\n", retcode);
396
397 FreeLibrary(hUnzipDll);
398 FreeUpMemory();
399 return retcode;
400 }
401
402 int WINAPI GetReplaceDlgRetVal(LPSTR filename, unsigned fnbufsiz)
403 {
404 /* This is where you will decide if you want to replace, rename etc existing
405 files.
406 */
407 return 1;
408 }
409
410 static void FreeUpMemory(void)
411 {
412 if (hUF)
413 {
414 GlobalUnlock(hUF);
415 GlobalFree(hUF);
416 }
417 if (hDCL)
418 {
419 GlobalUnlock(hDCL);
420 GlobalFree(hDCL);
421 }
422 }
423
424 /* This is a very stripped down version of what is done in Wiz. Essentially
425 what this function is for is to do a listing of an archive contents. It
426 is actually never called in this example, but a dummy procedure had to
427 be put in, so this was used.
428 */
429 #ifdef Z_UINT8_DEFINED
430 void WINAPI ReceiveDllMessage(z_uint8 ucsize, z_uint8 csiz,
431 unsigned cfactor, unsigned mo, unsigned dy, unsigned yr,
432 unsigned hh, unsigned mm, char c, LPCSTR filename,
433 LPCSTR methbuf, unsigned long crc, char fCrypt)
434 #else
435 void WINAPI ReceiveDllMessage(unsigned long ucsize, unsigned long csiz,
436 unsigned cfactor,
437 unsigned mo, unsigned dy, unsigned yr, unsigned hh, unsigned mm,
438 char c, LPCSTR filename, LPCSTR methbuf, unsigned long crc, char fCrypt)
439 #endif
440 {
441 char psLBEntry[_MAX_PATH];
442 char LongHdrStats[] =
443 "%7lu %7lu %4s %02u-%02u-%02u %02u:%02u %c%s";
444 char CompFactorStr[] = "%c%d%%";
445 char CompFactor100[] = "100%%";
446 char szCompFactor[10];
447 char sgn;
448
449 if (csiz > ucsize)
450 sgn = '-';
451 else
452 sgn = ' ';
453 if (cfactor == 100)
454 lstrcpy(szCompFactor, CompFactor100);
455 else
456 sprintf(szCompFactor, CompFactorStr, sgn, cfactor);
457 wsprintf(psLBEntry, LongHdrStats,
458 ucsize, csiz, szCompFactor, mo, dy, yr, hh, mm, c, filename);
459
460 printf("%s\n", psLBEntry);
461 }
462
463 /* Password entry routine - see password.c in the wiz directory for how
464 this is actually implemented in WiZ. If you have an encrypted file,
465 this will probably give you great pain.
466 */
467 int WINAPI password(LPSTR p, int n, LPCSTR m, LPCSTR name)
468 {
469 return 1;
470 }
471
472 /* Dummy "print" routine that simply outputs what is sent from the dll */
473 int WINAPI DisplayBuf(LPSTR buf, unsigned long size)
474 {
475 printf("%s", (char *)buf);
476 return (int)(unsigned int) size;
477 }