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/* Tell Microsoft Visual C++ 2005 (and newer) to leave us alone
11 * and let us use standard C functions the way we're supposed to.
12 * (These preprocessor symbols must appear before the first system
13 *  header include.)
14 */
15#if defined(_MSC_VER) && (_MSC_VER >= 1400)
16#  ifndef _CRT_SECURE_NO_WARNINGS
17#    define _CRT_SECURE_NO_WARNINGS
18#  endif
19#endif
20
21#include <windows.h>
22#include <stdio.h>
23#ifdef WIN32
24#  if defined(__LCC__)
25#    include <string.h>
26#    include <commdlg.h>
27#    include <dlgs.h>
28#  endif
29   #include <shlobj.h>
30#else
31   #include <mem.h>
32   #include <stdlib.h>
33   #include <dir.h>
34   #include <dlgs.h>
35   #include <ctype.h>
36   #include <commdlg.h>
37   #include <string.h>
38#endif
39#include "dialog.h"
40#ifndef UzpMatch
41#define UzpMatch match
42#endif
43#include "../structs.h"
44#include "../decs.h"
45
46LPUSERFUNCTIONS lpUserFunctions;
47HANDLE hUF       = (HANDLE)NULL;
48LPDCL lpDCL      = NULL;
49HANDLE hZUF      = (HANDLE)NULL;
50HANDLE hDCL      = (HANDLE)NULL;
51
52BOOL fDoAll = FALSE;
53
54char ** argv;
55
56HINSTANCE hInst;
57HWND hWnd;
58
59#ifndef TCHAR
60#define TCHAR char
61#endif
62
63#ifndef _MAX_PATH
64#define _MAX_PATH 260
65#endif
66
67int WINAPI password(LPSTR p, int n, LPCSTR m, LPCSTR name);
68int WINAPI DisplayBuf(TCHAR far *buf, unsigned long size);
69int WINAPI GetReplaceDlgRetVal(LPSTR filename, unsigned fnbufsiz);
70#ifdef Z_UINT8_DEFINED
71void WINAPI ReceiveDllMessage(z_uint8 ucsize, z_uint8 csiz,
72    unsigned cfactor, unsigned mo, unsigned dy, unsigned yr, unsigned hh,
73    unsigned mm, TCHAR c, LPCSTR filename, LPCSTR methbuf, unsigned long crc,
74    TCHAR fCrypt);
75#else
76void WINAPI ReceiveDllMessage(unsigned long ucsize, unsigned long csiz,
77    unsigned cfactor, unsigned mo, unsigned dy, unsigned yr, unsigned hh,
78    unsigned mm, TCHAR c, LPCSTR filename, LPCSTR methbuf, unsigned long crc,
79    TCHAR fCrypt);
80#endif
81void WINAPI ReceiveDllMessage_NO_INT64(unsigned long ucsize_low,
82    unsigned long ucsize_high, unsigned long csiz_low, unsigned long csiz_high,
83    unsigned cfactor, unsigned mo, unsigned dy, unsigned yr, unsigned hh,
84    unsigned mm, TCHAR c, LPCSTR filename, LPCSTR methbuf, unsigned long crc,
85    TCHAR fCrypt);
86
87char szAppName[_MAX_PATH];
88char szTarget[_MAX_PATH];
89char szThisApp[_MAX_PATH];
90int iReturn;
91
92DLGPROC fpProc;
93
94#ifndef MAX_PATH
95   #define MAX_PATH    _MAX_PATH            // maximum path =length
96#endif
97#define TRUE        1                       // true value
98#define FALSE       0                       // false value
99
100TCHAR   zfn[MAX_PATH],                      // zip filename and path
101        szHomeDir[MAX_PATH];                // Original directory
102
103/****************************************************************************
104
105    FUNCTION: Replace(HWND, WORD, WPARAM, LPARAM)
106
107    PURPOSE:  Processes messages for "Replace" dialog box
108
109    MESSAGES:
110
111    WM_INITDIALOG - initialize dialog box
112    WM_COMMAND    - Input received
113
114****************************************************************************/
115
116BOOL WINAPI ReplaceProc(HWND hReplaceDlg, WORD wMessage,
117                        WPARAM wParam, LPARAM lParam)
118{
119    static char __far *lpsz;
120    TCHAR szTemp[MAX_PATH];
121
122    switch (wMessage)
123    {
124    case WM_INITDIALOG:
125        lpsz = (char __far *)lParam;
126        wsprintf(szTemp, "Replace %s ?", (LPSTR)lpsz);
127        SetDlgItemText(hReplaceDlg, IDM_REPLACE_TEXT, szTemp);
128        return TRUE;
129
130    case WM_COMMAND:
131        switch (LOWORD(wParam))
132        {
133        case IDCANCEL:              /* ESC key      */
134        case IDOK:                  /* Enter key    */
135            EndDialog(hReplaceDlg, IDM_REPLACE_NO);
136            break;
137        case IDM_REPLACE_ALL:
138            fDoAll = TRUE;
139        case IDM_REPLACE_NONE:
140        case IDM_REPLACE_YES:
141        case IDM_REPLACE_NO:
142            EndDialog(hReplaceDlg, wParam);
143            break;
144        }
145        return TRUE;
146    }
147    return FALSE;
148}
149
150/****************************************************************************
151
152    FUNCTION: GetDirProc(HWND, unsigned, WPARAM, LPARAM)
153
154    PURPOSE:  Processes messages for "Set Reference Dir Procedure for
155              Update Archive" dialog box
156
157    MESSAGES:
158
159    WM_INITDIALOG - initialize dialog box
160    WM_COMMAND    - Input received
161
162****************************************************************************/
163#ifdef WIN32
164BOOL WINAPI
165GetDirProc(HWND hDlg, WORD wMessage, WPARAM wParam, LPARAM lParam)
166{
167   switch (wMessage) {
168   case WM_INITDIALOG:
169/*
170Common control identifiers for GetOpenFileName and GetSaveFileName
171Control identifier   Control Description
172cmb2                 Drop-down combo box that displays the current drive
173                     or folder, and that allows the user to select a
174                     drive or folder to open
175stc4                 Label for the cmb2 combo box
176lst1                 List box that displays the contents of the current drive or folder
177stc1                 Label for the lst1 list box
178edt1                 Edit control that displays the name of the current file, or in which the user can type the name of the file to open
179stc3                 Label for the edt1 edit control
180cmb1                 Drop-down combo box that displays the list of file type filters
181stc2                 Label for the cmb1 combo box
182chx1                 The read-only check box
183IDOK                 The OK command button (push button)
184IDCANCEL             The Cancel command button (push button)
185pshHelp              The Help command button (push button)
186
187*/
188      CommDlg_OpenSave_HideControl(GetParent(hDlg), cmb1);
189      CommDlg_OpenSave_HideControl(GetParent(hDlg), stc2);
190      CommDlg_OpenSave_HideControl(GetParent(hDlg), edt1);
191      CommDlg_OpenSave_HideControl(GetParent(hDlg), stc3);
192      CommDlg_OpenSave_SetControlText(GetParent(hDlg),
193            IDOK, "Set");
194      break;
195   default:
196         break;
197   }
198return DefWindowProc(hDlg, wMessage, wParam, lParam);
199}
200#else
201
202#ifdef __BORLANDC__
203#pragma argsused
204#endif
205
206BOOL WINAPI
207GetDirProc(HWND hwndDlg, WORD wMessage, WPARAM wParam, LPARAM lParam)
208{
209HWND hTemp;
210
211   switch (wMessage) {
212   case WM_INITDIALOG:
213      hTemp = GetDlgItem(hwndDlg, lst1);
214      EnableWindow(hTemp, FALSE);
215      ShowWindow(hTemp, SW_HIDE);
216      hTemp = GetDlgItem(hwndDlg, edt1);
217      EnableWindow(hTemp, FALSE);
218      ShowWindow(hTemp, SW_HIDE);
219      hTemp = GetDlgItem(hwndDlg, stc2);
220      EnableWindow(hTemp, FALSE);
221      ShowWindow(hTemp, SW_HIDE);
222      hTemp = GetDlgItem(hwndDlg, stc3);
223      EnableWindow(hTemp, FALSE);
224      ShowWindow(hTemp, SW_HIDE);
225      hTemp = GetDlgItem(hwndDlg, cmb1);
226      EnableWindow(hTemp, FALSE);
227      ShowWindow(hTemp, SW_HIDE);
228
229      break;
230   case WM_COMMAND:
231      switch (LOWORD(wParam)) {
232         case IDCANCEL:
233            EndDialog(hwndDlg, FALSE);
234            break;
235         case IDOK:
236            getcwd(szTarget, MAX_PATH);
237            EndDialog(hwndDlg, TRUE);
238            break;
239         }
240      default:
241         break;
242   }
243   return FALSE;
244}
245#endif /* !WIN32 */
246
247#ifdef __BORLANDC__
248#pragma argsused
249#endif
250
251BOOL FAR PASCAL InitDialogProc (HWND hDlg, WORD wMsg, WORD wParam, LONG lParam) {
252   BOOL fProcessed = TRUE;
253   TCHAR szMessage[256];
254
255   RECT rc;
256
257   switch (wMsg) {
258      case WM_INITDIALOG:
259
260         hWnd = hDlg;
261         SetWindowText(hDlg,(LPSTR) szAppName);
262         SetDlgItemText(hDlg,ID_TARGET,(LPSTR)szTarget);
263
264#ifdef WIN32
265         GetCurrentDirectory(MAX_PATH, szHomeDir);
266         SetCurrentDirectory(szTarget);
267#else
268         getcwd(szHomeDir, MAX_PATH);
269         chdir(szTarget);
270         setdisk(toupper(szTarget[0]) - 'A');
271#endif
272         GetWindowRect(hDlg, &rc);
273         SetWindowPos(hDlg, NULL,
274            (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
275            (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
276            0, 0, SWP_NOSIZE | SWP_NOZORDER);
277
278         break;
279
280      case WM_COMMAND:
281         switch (wParam) {
282
283            case ID_BROWSE :
284                {
285#ifndef WIN32
286                FARPROC lpGetDirProc;
287#endif
288                char szTemp[MAX_PATH]="mike_~@~*";
289                OPENFILENAME ofn;
290
291                memset(&ofn, '\0', sizeof(OPENFILENAME)); /* init struct */
292                ofn.lStructSize = sizeof(OPENFILENAME);
293                ofn.hwndOwner = hWnd;
294                ofn.hInstance = hInst;
295                ofn.lpstrFilter = NULL;
296                ofn.nFilterIndex = 1;
297
298                ofn.lpstrFile = szTemp;
299                ofn.nMaxFile = MAX_PATH;
300                ofn.lpstrFileTitle = NULL;
301                ofn.nMaxFileTitle = MAX_PATH; /* ignored ! */
302                ofn.lpstrTitle = (LPSTR)"Set Extraction Directory";
303                ofn.lpstrInitialDir = NULL;
304                ofn.Flags = OFN_ENABLEHOOK |
305#ifdef WIN32
306                            OFN_EXPLORER|
307#endif
308                            OFN_HIDEREADONLY|OFN_NOVALIDATE;
309#ifndef WIN32
310                lpGetDirProc = MakeProcInstance((FARPROC)GetDirProc, hInst);
311   #ifndef MSC
312                (UINT CALLBACK *)ofn.lpfnHook = (UINT CALLBACK *)lpGetDirProc;
313   #else
314                ofn.lpfnHook = lpGetDirProc;
315   #endif
316#else
317                ofn.lpfnHook = (LPOFNHOOKPROC)GetDirProc;
318#endif
319                ofn.lpTemplateName = "GETDIR";   /* see getfiles.dlg   */
320                if (!GetOpenFileName(&ofn))
321                   {
322                   break;
323                   }
324
325                ofn.lpstrFile[ofn.nFileOffset-1] = '\0';
326#ifdef WIN32
327                SetCurrentDirectory(ofn.lpstrFile);
328#else
329                getcwd(szTemp, MAX_PATH);
330                chdir(ofn.lpstrFile);
331                setdisk(toupper(ofn.lpstrFile[0]) - 'A');
332#endif
333                lstrcpy(szTarget,ofn.lpstrFile);
334                SetDlgItemText(hDlg,ID_TARGET,(LPSTR)szTarget);
335                }
336               break;
337
338            case IDOK:
339#ifdef WIN32
340               GetCurrentDirectory(_MAX_PATH,szTarget);
341#else
342               getcwd(szTarget, _MAX_PATH);
343#endif
344
345               lpDCL->ncflag = 0;
346               lpDCL->fQuiet = 0; // If not zero, no status messages will come through
347               lpDCL->ntflag = 0;
348               lpDCL->nvflag = 0;
349               lpDCL->nzflag = 0;
350               lpDCL->ndflag = 1;
351               lpDCL->naflag = 0;
352               lpDCL->nfflag = 0;
353               lpDCL->noflag = 0;
354               lpDCL->PromptToOverwrite = 1;
355               lpDCL->ExtractOnlyNewer = 0;
356               lpDCL->lpszZipFN = zfn;
357               lpDCL->lpszExtractDir = NULL;
358               iReturn = Wiz_SingleEntryUnzip(0, NULL, 0, NULL, lpDCL, lpUserFunctions);
359
360/* external return codes for unzip library */
361//#define PK_OK              0   /* no error */
362//#define PK_COOL            0   /* no error */
363//#define PK_WARN            1   /* warning error */
364//#define PK_ERR             2   /* error in zipfile */
365//#define PK_BADERR          3   /* severe error in zipfile */
366//#define PK_MEM             4   /* insufficient memory (during initialization) */
367//#define PK_MEM2            5   /* insufficient memory (password failure) */
368//#define PK_MEM3            6   /* insufficient memory (file decompression) */
369//#define PK_MEM4            7   /* insufficient memory (memory decompression) */
370//#define PK_MEM5            8   /* insufficient memory (not yet used) */
371//#define PK_NOZIP           9   /* zipfile not found */
372//#define PK_PARAM          10   /* bad or illegal parameters specified */
373//#define PK_FIND           11   /* no files found */
374//#define PK_DISK           50   /* disk full */
375//#define PK_EOF            51   /* unexpected EOF */
376
377//#define IZ_CTRLC          80   /* user hit ^C to terminate */
378//#define IZ_UNSUP          81   /* no files found: all unsup. compr/encrypt. */
379//#define IZ_BADPWD         82   /* no files found: all had bad password */
380
381/* return codes of password fetches (negative = user abort; positive = error) */
382//#define IZ_PW_ENTERED      0   /* got some password string; use/try it */
383//#define IZ_PW_CANCEL      -1   /* no password available (for this entry) */
384//#define IZ_PW_CANCELALL   -2   /* no password, skip any further pwd. request */
385//#define IZ_PW_ERROR        5   /* = PK_MEM2 : failure (no mem, no tty, ...) */
386               switch (iReturn) {
387                case PK_OK:
388                     wsprintf(szMessage, "%s", "All files extracted OK");
389                     break;
390                case PK_ERR:
391                     wsprintf(szMessage, "%s", "Warning occurred on one or more files");
392                     break;
393                case PK_BADERR:
394                     wsprintf(szMessage, "%s", "Error in archive");
395                     break;
396                case PK_MEM:
397                case PK_MEM2:
398                case PK_MEM3:
399                case PK_MEM4:
400                case PK_MEM5:
401                     wsprintf(szMessage, "%s", "Insufficient memory");
402                     break;
403                case PK_NOZIP:
404                     wsprintf(szMessage, "%s", "Archive not found");
405                     break;
406                case PK_FIND:
407                     wsprintf(szMessage, "%s", "No files found");
408                     break;
409                case PK_DISK:
410                     wsprintf(szMessage, "%s", "Disk full");
411                     break;
412                case PK_EOF:
413                     wsprintf(szMessage, "%s", "Unexpected end of file");
414                     break;
415                case IZ_UNSUP:
416                     wsprintf(szMessage, "%s", "No files found: All unsupported");
417                     break;
418                case IZ_BADPWD:
419                     wsprintf(szMessage, "%s", "No files found: Bad password");
420                     break;
421                default:
422                     wsprintf(szMessage, "%s", "Unknown error");
423                     break;
424                }
425               MessageBox(hDlg, szMessage, szAppName, MB_OK);
426/* Uncomment line below to have SFXWix terminate automatically
427   when done.
428 */
429//              EndDialog(hDlg, wParam);
430
431               break;
432               case IDCANCEL:
433                    EndDialog(hDlg, wParam);
434                    PostQuitMessage(0);
435                    exit(0); // ..and then quit
436                    break;
437         }
438         break;
439
440      default:
441         fProcessed = FALSE;
442         break;
443   }
444   return(fProcessed);
445}
446
447
448#define WasCancelled(hDlg) (!IsWindowEnabled(GetDlgItem(hDlg,IDCANCEL)))
449
450#ifdef __BORLANDC__
451#pragma argsused
452#endif
453int WINAPI password(LPSTR p, int n, LPCSTR m, LPCSTR name)
454{
455TCHAR sz[MAX_PATH];
456sprintf(sz, "%s is encrypted", name);
457MessageBox(hWnd, sz, "Encryption not supported", MB_OK);
458return IZ_PW_CANCELALL;
459}
460
461int WINAPI DisplayBuf(TCHAR far *buf, unsigned long size)
462{
463if ((buf[0] != '\n') && (buf[0] != '\r'))
464   SetDlgItemText(hWnd, ID_STATUS, buf);
465return (unsigned int) size;
466}
467
468#ifdef __BORLANDC__
469#pragma argsused
470#endif
471int WINAPI GetReplaceDlgRetVal(LPSTR filename, unsigned fnbufsiz)
472{
473#ifndef WIN32
474FARPROC lpfnprocReplace;
475#endif
476int ReplaceDlgRetVal;   /* replace dialog return value */
477
478#ifdef WIN32
479ReplaceDlgRetVal = DialogBoxParam(hInst, "Replace",
480   hWnd, (DLGPROC)ReplaceProc, (DWORD)filename);
481#else
482lpfnprocReplace = MakeProcInstance(ReplaceProc, hInst);
483ReplaceDlgRetVal = DialogBoxParam(hInst, "Replace",
484   hWnd, lpfnprocReplace, (DWORD)filename);
485FreeProcInstance(lpfnprocReplace);
486#endif
487return ReplaceDlgRetVal;
488}
489
490#ifdef __BORLANDC__
491#pragma argsused
492#endif
493#ifdef Z_UINT8_DEFINED
494void WINAPI ReceiveDllMessage(z_uint8 ucsize, z_uint8 csiz,
495    unsigned cfactor, unsigned mo, unsigned dy, unsigned yr, unsigned hh,
496    unsigned mm, TCHAR c, LPCSTR filename, LPCSTR methbuf, unsigned long crc,
497    TCHAR fCrypt)
498{
499}
500#else
501void WINAPI ReceiveDllMessage(unsigned long ucsize, unsigned long csiz,
502    unsigned cfactor, unsigned mo, unsigned dy, unsigned yr, unsigned hh,
503    unsigned mm, TCHAR c, LPCSTR filename, LPCSTR methbuf, unsigned long crc,
504    TCHAR fCrypt)
505{
506}
507#endif
508void WINAPI ReceiveDllMessage_NO_INT64(unsigned long ucsize_low,
509   unsigned long ucsize_high, unsigned long csiz_low, unsigned long csiz_high,
510   unsigned cfactor, unsigned mo, unsigned dy, unsigned yr, unsigned hh,
511   unsigned mm, TCHAR c, LPCSTR filename, LPCSTR methbuf, unsigned long crc,
512   TCHAR fCrypt)
513{
514}
515
516#ifdef __BORLANDC__
517#pragma argsused
518#endif
519
520int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
521                    LPSTR lpszCmdLine, int nCmdShow)
522{
523TCHAR *ptr = NULL;
524hInst = hInstance;
525
526hDCL = GlobalAlloc( GPTR, (DWORD)sizeof(DCL));
527if (!hDCL)
528   {
529   return 0;
530   }
531lpDCL = (LPDCL)GlobalLock(hDCL);
532if (!lpDCL)
533   {
534   return 0;
535   }
536
537hUF = GlobalAlloc( GPTR, (DWORD)sizeof(USERFUNCTIONS));
538if (!hUF)
539   {
540   return 0;
541   }
542lpUserFunctions = (LPUSERFUNCTIONS)GlobalLock(hUF);
543
544if (!lpUserFunctions)
545   {
546   return 0;
547   }
548
549lpUserFunctions->password = password;
550lpUserFunctions->print = DisplayBuf;
551lpUserFunctions->sound = NULL;
552lpUserFunctions->replace = GetReplaceDlgRetVal;
553lpUserFunctions->SendApplicationMessage = ReceiveDllMessage;
554lpUserFunctions->SendApplicationMessage_i32 = ReceiveDllMessage_NO_INT64;
555lpUserFunctions->ServCallBk = NULL;
556
557
558
559GetModuleFileName(hInstance,(LPSTR)szThisApp,sizeof(szThisApp));
560lstrcpy(zfn, szThisApp);
561
562ptr = strrchr(szThisApp, '\\');
563if (ptr != NULL)
564   {
565   lstrcpy(szAppName, ptr);
566   ptr[0] = '\0';
567   lstrcpy(szTarget, szThisApp);
568
569   iReturn = DialogBox(hInstance, MAKEINTRESOURCE(INITDIALOG),
570         (HWND)NULL, (DLGPROC)InitDialogProc);
571   DestroyWindow((HWND) INITDIALOG);
572
573#ifdef WIN32
574   SetCurrentDirectory(szHomeDir);
575#else
576   getcwd(szTarget, MAX_PATH);
577   chdir(szHomeDir);
578   setdisk(toupper(szHomeDir[0]) - 'A');
579#endif
580   }
581PostQuitMessage(0);
582return (0);
583}
584