source: trunk/dll/extract.c@ 1791

Last change on this file since 1791 was 1791, checked in by Gregg Young, 11 years ago

Fix failure to remove leading quote on toogle of extract directory to and from using file name. Ticket [495]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.4 KB
Line 
1
2/***********************************************************************
3
4 $Id: extract.c 1791 2014-08-31 18:13:17Z gyoung $
5
6 Copyright (c) 1993-98 M. Kimes
7 Copyright (c) 2004, 2013 Steven H. Levine
8
9 01 Aug 04 SHL Rework lstrip/rstrip usage
10 05 Jun 05 SHL Use QWL_USER
11 17 Jul 06 SHL Use Runtime_Error
12 20 Dec 06 GKY Added checkbox to make default extract with directories
13 22 Mar 07 GKY Use QWL_USER
14 19 Apr 07 SHL Sync with AcceptOneDrop GetOneDrop mods
15 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
16 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory
17 29 Nov 08 GKY Add the option of creating a subdirectory from the arcname
18 for the extract path.
19 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
20 17 Jan 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
21 23 Oct 10 GKY Changes to populate and utilize a HELPTABLE for context specific help
22 11 Aug 13 GKY Fix directory create failure on extract to directory based on archive name
23 if the name needed quoting.
24 15 Feb 14 GKY Assure the title is blank on the execute dialog call with the "see" button
25 31 Aug 14 GKY Fix failure to remove leading quote on toogle of extract directory to and
26 from using file name.
27
28***********************************************************************/
29
30#include <string.h>
31#include <ctype.h>
32
33#define INCL_WIN
34#define INCL_DOS
35#define INCL_LONGLONG // dircnrs.h
36
37#include "fm3dll.h"
38#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
39#include "init.h" // Data declaration(s)
40#include "arccnrs.h" // Data declaration(s)
41#include "notebook.h" // Data declaration(s)
42#include "mainwnd.h" // Data declaration(s)
43#include "fm3dlg.h"
44#include "fm3str.h"
45#include "errutil.h" // Dos_Error...
46#include "strutil.h" // GetPString
47#include "cmdline.h" // CmdLineDlgProc
48#include "extract.h"
49#include "walkem.h" // WalkExtractDlgProc
50#include "droplist.h" // AcceptOneDrop, DropHelp, GetOneDrop
51#include "misc.h" // DrawTargetEmphasis
52#include "chklist.h" // PosOverOkay
53#include "mkdir.h" // SetDir
54#include "valid.h" // MakeValidDir
55#include "systemf.h" // runemf2
56#include "dirs.h" // save_dir2
57#include "strips.h" // bstrip
58
59#pragma data_seg(DATA1)
60
61static PSZ pszSrcFile = __FILE__;
62
63MRESULT EXPENTRY ExtractTextProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
64{
65 PFNWP oldproc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
66 static BOOL emphasized = FALSE;
67
68 switch (msg) {
69 case DM_DRAGOVER:
70 if (!emphasized) {
71 emphasized = TRUE;
72 DrawTargetEmphasis(hwnd, emphasized);
73 }
74 if (AcceptOneDrop(hwnd, mp1, mp2))
75 return MRFROM2SHORT(DOR_DROP, DO_MOVE);
76 return MRFROM2SHORT(DOR_NEVERDROP, 0);
77
78 case DM_DRAGLEAVE:
79 if (emphasized) {
80 emphasized = FALSE;
81 DrawTargetEmphasis(hwnd, emphasized);
82 }
83 break;
84
85 case DM_DROPHELP:
86 DropHelp(mp1, mp2, hwnd, GetPString(IDS_EXTDROPHELPTEXT));
87 return 0;
88
89 case DM_DROP:
90 {
91 char szFrom[CCHMAXPATH + 2];
92
93 if (emphasized) {
94 emphasized = FALSE;
95 DrawTargetEmphasis(hwnd, emphasized);
96 }
97 if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom)))
98 WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_COMMAND,
99 MPFROM2SHORT(IDM_SWITCH, 0), MPFROMP(szFrom));
100 }
101 return 0;
102 }
103 return (oldproc) ? oldproc(hwnd, msg, mp1, mp2) :
104 WinDefWindowProc(hwnd, msg, mp1, mp2);
105}
106
107MRESULT EXPENTRY ExtractDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
108{
109 EXTRDATA *arcdata = NULL;
110 ULONG size;
111 BOOL fFileNameExtPath;
112
113 switch (msg) {
114 case WM_INITDLG:
115 WinSetWindowPtr(hwnd, QWL_USER, mp2);
116 arcdata = (EXTRDATA *) mp2;
117 {
118 BOOL fDirectory = FALSE;
119 BOOL fRemember = FALSE;
120 PFNWP oldproc;
121
122 fFileNameExtPath = FALSE;
123 oldproc = WinSubclassWindow(WinWindowFromID(hwnd, EXT_DIRECTORY),
124 (PFNWP) ExtractTextProc);
125 if (oldproc)
126 WinSetWindowPtr(WinWindowFromID(hwnd, EXT_DIRECTORY),
127 QWL_USER, (PVOID) oldproc);
128 size = sizeof(BOOL);
129 PrfQueryProfileData(fmprof, FM3Str, "RememberExt",
130 (PVOID) & fRemember, &size);
131 size = sizeof(BOOL);
132 PrfQueryProfileData(fmprof, FM3Str, "DirectoryExt",
133 (PVOID) & fDirectory, &size);
134 size = sizeof(BOOL);
135 PrfQueryProfileData(fmprof, FM3Str, "FileNamePathExt",
136 (PVOID) & fFileNameExtPath, &size);
137 WinCheckButton(hwnd, EXT_REMEMBER, fRemember);
138 WinCheckButton(hwnd, EXT_AWDIRS, fDirectory);
139 WinCheckButton(hwnd, EXT_FILENAMEEXT, fFileNameExtPath);
140 WinSendDlgItemMsg(hwnd, EXT_DIRECTORY, EM_SETTEXTLIMIT,
141 MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
142 WinSendDlgItemMsg(hwnd, EXT_COMMAND, EM_SETTEXTLIMIT,
143 MPFROM2SHORT(256, 0), MPVOID);
144 WinSendDlgItemMsg(hwnd, EXT_MASK, EM_SETTEXTLIMIT,
145 MPFROM2SHORT(256, 0), MPVOID);
146 WinSendDlgItemMsg(hwnd, EXT_FILENAME, EM_SETTEXTLIMIT,
147 MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
148 if (arcdata->arcname && *arcdata->arcname)
149 WinSetDlgItemText(hwnd, EXT_FILENAME, arcdata->arcname);
150 else
151 WinSetDlgItemText(hwnd, EXT_FILENAME, (CHAR *) GetPString(IDS_EXTVARIOUSTEXT));
152
153 if (fFileNameExtPath && arcdata->arcname) {
154
155 CHAR FileName[CCHMAXPATH];
156 PSZ p;
157
158 strcpy(FileName, arcdata->arcname);
159 p = strrchr(FileName, '.');
160 if (p) {
161 *p = 0;
162 if (strchr(FileName, '\"'))
163 memmove(FileName, FileName + 1, strlen(FileName) + 1);
164 }
165 else {
166 p = FileName + strlen(arcdata->arcname);
167 p--;
168 *p = 0;
169 if (strchr(FileName, '\"') == strrchr(FileName, '\"'))
170 memmove(FileName , FileName + 1, strlen(FileName) + 1);
171 }
172 strcpy(arcdata->extractdir, FileName);
173 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
174 }
175 if (fDirectory) {
176 WinSendDlgItemMsg(hwnd, EXT_WDIRS, BM_SETCHECK,
177 MPFROM2SHORT(TRUE, 0), MPVOID);
178 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->exwdirs);
179 }
180 else {
181 WinSendDlgItemMsg(hwnd, EXT_NORMAL, BM_SETCHECK,
182 MPFROM2SHORT(TRUE, 0), MPVOID);
183 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->extract);
184
185 }
186 if (fRemember) {
187
188 CHAR textdir[CCHMAXPATH];
189
190 PrfQueryProfileString(fmprof, FM3Str, "Ext_ExtractDir", NULL, textdir, sizeof(textdir));
191 if (*textdir && !IsFile(textdir))
192 strcpy(arcdata->extractdir, textdir);
193 PrfQueryProfileString(fmprof, FM3Str, "Ext_Mask", NULL, textdir, sizeof(textdir));
194 WinSetDlgItemText(hwnd, EXT_MASK, textdir);
195 }
196 if (*extractpath && (!fRemember || !*arcdata->extractdir)) {
197 if (arcdata->arcname && *arcdata->arcname &&
198 !strcmp(extractpath, "*")) {
199
200 CHAR *p;
201
202 strcpy(arcdata->extractdir, arcdata->arcname);
203 p = strrchr(arcdata->extractdir, '\\');
204 if (p) {
205 if (p < arcdata->extractdir + 3)
206 p++;
207 *p = 0;
208 }
209 }
210 else
211 strcpy(arcdata->extractdir, extractpath);
212 }
213 if (!*arcdata->extractdir) {
214 if (*lastextractpath)
215 strcpy(arcdata->extractdir, lastextractpath);
216 else if (arcdata->arcname && *arcdata->arcname) {
217
218 CHAR *p;
219
220 strcpy(arcdata->extractdir, arcdata->arcname);
221 p = strrchr(arcdata->extractdir, '\\');
222 if (p) {
223 if (p < arcdata->extractdir + 3)
224 p++;
225 *p = 0;
226 }
227 }
228 if (!*arcdata->extractdir)
229 strcpy(arcdata->extractdir, pFM2SaveDirectory);
230 }
231 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
232 if (!arcdata->info->exwdirs)
233 WinEnableWindow(WinWindowFromID(hwnd, EXT_WDIRS), FALSE);
234 else if (fRemember) {
235 fRemember = FALSE;
236 size = sizeof(BOOL);
237 PrfQueryProfileData(fmprof, FM3Str, "Ext_WDirs",
238 (PVOID) &fRemember, &size);
239 if (fRemember)
240 PostMsg(WinWindowFromID(hwnd, EXT_WDIRS), BM_CLICK, MPVOID, MPVOID);
241 }
242 }
243 *arcdata->command = 0;
244 PosOverOkay(hwnd);
245 break;
246
247 case WM_ADJUSTWINDOWPOS:
248 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
249 break;
250
251 case UM_SETDIR:
252 PaintRecessedWindow(WinWindowFromID(hwnd, EXT_HELP), (HPS) 0, FALSE,
253 TRUE);
254 return 0;
255
256 case WM_CONTROL:
257 arcdata = (EXTRDATA *) WinQueryWindowPtr(hwnd, QWL_USER);
258 switch (SHORT1FROMMP(mp1)) {
259 case EXT_REMEMBER:
260 {
261 BOOL fRemember = WinQueryButtonCheckstate(hwnd, EXT_REMEMBER);
262 size = sizeof(BOOL);
263 PrfWriteProfileData(fmprof, FM3Str, "RememberExt",
264 (PVOID) &fRemember, size);
265 WinSendDlgItemMsg(hwnd, EXT_FILENAMEEXT, BM_SETCHECK,
266 MPFROM2SHORT(FALSE, 0), MPVOID);
267 }
268 break;
269
270 case EXT_AWDIRS:
271 {
272 BOOL fDirectory = WinQueryButtonCheckstate(hwnd, EXT_AWDIRS);
273 size = sizeof(BOOL);
274 PrfWriteProfileData(fmprof, FM3Str, "DirectoryExt",
275 (PVOID) &fDirectory, size);
276
277 if (fDirectory) {
278 WinSendDlgItemMsg(hwnd, EXT_WDIRS, BM_SETCHECK,
279 MPFROM2SHORT(TRUE, 0), MPVOID);
280 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->exwdirs);
281 }
282 else {
283 WinSendDlgItemMsg(hwnd, EXT_NORMAL, BM_SETCHECK,
284 MPFROM2SHORT(TRUE, 0), MPVOID);
285 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->extract);
286 }
287 }
288 break;
289
290 case EXT_FILENAMEEXT:
291 {
292 BOOL fFileNameExtPath = WinQueryButtonCheckstate(hwnd, EXT_FILENAMEEXT);
293 BOOL fRemember = WinQueryButtonCheckstate(hwnd, EXT_REMEMBER);
294 size = sizeof(BOOL);
295 PrfWriteProfileData(fmprof, FM3Str, "FileNamePathExt",
296 fRemember ? FALSE : (PVOID) &fFileNameExtPath, size);
297 if (fRemember) {
298 WinSendDlgItemMsg(hwnd, EXT_FILENAMEEXT, BM_SETCHECK,
299 MPFROM2SHORT(FALSE, 0), MPVOID);
300 break;
301 }
302 if (fFileNameExtPath && arcdata->arcname) {
303 CHAR FileName[CCHMAXPATH];
304 PSZ p;
305
306 strcpy(FileName, arcdata->arcname);
307 p = strrchr(FileName, '.');
308 if (p) {
309 *p = 0;
310 if (strchr(FileName, '\"'))
311 memmove(FileName, FileName + 1, strlen(FileName) + 1);
312 }
313 else {
314 p = FileName + strlen(arcdata->arcname);
315 p--;
316 *p = 0;
317 if (strchr(FileName, '\"') == strrchr(FileName, '\"'))
318 memmove(FileName, FileName + 1, strlen(FileName) + 1);
319 }
320 strcpy(arcdata->extractdir, FileName);
321 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
322 }
323 else {
324 *arcdata->extractdir = 0;
325 if (*extractpath) {
326 if (arcdata->arcname && *arcdata->arcname &&
327 !strcmp(extractpath, "*")) {
328
329 CHAR *p;
330
331 strcpy(arcdata->extractdir, arcdata->arcname);
332 p = strrchr(arcdata->extractdir, '\\');
333 if (p) {
334 if (p < arcdata->extractdir + 3)
335 p++;
336 *p = 0;
337 }
338 }
339 else
340 strcpy(arcdata->extractdir, extractpath);
341 }
342 if (!*arcdata->extractdir) {
343 if (arcdata->arcname && *arcdata->arcname) {
344
345 CHAR *p;
346
347 strcpy(arcdata->extractdir, arcdata->arcname);
348 p = strrchr(arcdata->extractdir, '\\');
349 if (p) {
350 if (p < arcdata->extractdir + 3)
351 p++;
352 *p = 0;
353 }
354 }
355 if (!*arcdata->extractdir)
356 strcpy(arcdata->extractdir, pFM2SaveDirectory);
357 }
358 if (strchr(arcdata->extractdir, '\"') == strrchr(arcdata->extractdir, '\"'))
359 memmove(arcdata->extractdir, arcdata->extractdir + 1,
360 strlen(arcdata->extractdir) + 1);
361 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
362 }
363 }
364 break;
365
366 case EXT_FILENAME:
367 if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
368 WinSetDlgItemText(hwnd, EXT_HELP, (CHAR *) GetPString(IDS_ARCDEFAULTHELPTEXT));
369 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
370 WinSetDlgItemText(hwnd, EXT_HELP, (CHAR *) GetPString(IDS_ARCARCNAMEHELPTEXT));
371 break;
372
373 case EXT_DIRECTORY:
374 if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
375 WinSetDlgItemText(hwnd, EXT_HELP, (CHAR *) GetPString(IDS_ARCDEFAULTHELPTEXT));
376 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
377 WinSetDlgItemText(hwnd, EXT_HELP, (CHAR *) GetPString(IDS_EXTEXTRACTDIRHELPTEXT));
378 break;
379
380 case EXT_COMMAND:
381 if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
382 WinSetDlgItemText(hwnd, EXT_HELP, (CHAR *) GetPString(IDS_ARCDEFAULTHELPTEXT));
383 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
384 WinSetDlgItemText(hwnd, EXT_HELP, (CHAR *) GetPString(IDS_ARCCMDHELPTEXT));
385 break;
386
387 case EXT_MASK:
388 if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
389 WinSetDlgItemText(hwnd, EXT_HELP, (CHAR *) GetPString(IDS_ARCDEFAULTHELPTEXT));
390 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
391 WinSetDlgItemText(hwnd, EXT_HELP, (CHAR *) GetPString(IDS_ARCMASKHELPTEXT));
392 break;
393
394 case EXT_NORMAL:
395 if ((BOOL) WinSendDlgItemMsg(hwnd, EXT_NORMAL, BM_QUERYCHECK,
396 MPVOID, MPVOID))
397 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->extract);
398 break;
399
400 case EXT_WDIRS:
401 if (arcdata->info->exwdirs) {
402 if ((BOOL) WinSendDlgItemMsg(hwnd, EXT_WDIRS, BM_QUERYCHECK,
403 MPVOID, MPVOID))
404 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->exwdirs);
405 }
406 break;
407 }
408 return 0;
409
410 case WM_COMMAND:
411 arcdata = (EXTRDATA *) WinQueryWindowPtr(hwnd, QWL_USER);
412 switch (SHORT1FROMMP(mp1)) {
413 case IDM_SWITCH:
414 if (mp2) {
415
416 CHAR tdir[CCHMAXPATH];
417
418 strcpy(tdir, (CHAR *) mp2);
419 MakeValidDir(tdir);
420 WinSetDlgItemText(hwnd, EXT_DIRECTORY, tdir);
421 }
422 break;
423
424 case DID_CANCEL:
425 arcdata->ret = 0;
426 WinDismissDlg(hwnd, 0);
427 break;
428 case DID_OK:
429 {
430 CHAR s[CCHMAXPATH + 1];
431 BOOL fRemember;
432
433 fRemember = WinQueryButtonCheckstate(hwnd, EXT_REMEMBER);
434 *s = 0;
435 WinQueryDlgItemText(hwnd, EXT_DIRECTORY, CCHMAXPATH, s);
436 bstrip(s);
437 if (*s) {
438 if (!SetDir(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
439 QW_OWNER), hwnd, s, fFileNameExtPath ? 1:0)) {
440 strcpy(arcdata->extractdir, s);
441 WinSetDlgItemText(hwnd, EXT_DIRECTORY, s);
442 if ((!isalpha(*s) || s[1] != ':') && *s != '.')
443 saymsg(MB_ENTER, hwnd,
444 GetPString(IDS_WARNINGTEXT),
445 GetPString(IDS_SPECIFYDRIVETEXT));
446 }
447 else
448 break;
449 strcpy(lastextractpath, s);
450 if (fRemember) {
451 PrfWriteProfileString(fmprof, FM3Str, "Ext_ExtractDir", s);
452 fRemember = WinQueryButtonCheckstate(hwnd, EXT_WDIRS);
453 size = sizeof(BOOL);
454 PrfWriteProfileData(fmprof, FM3Str, "Ext_WDirs",
455 (PVOID) &fRemember, size);
456 fRemember = TRUE;
457 }
458 *s = 0;
459 WinQueryDlgItemText(hwnd, EXT_COMMAND, 256, s);
460 if (*s) {
461 strcpy(arcdata->command, s);
462 *s = 0;
463 WinQueryDlgItemText(hwnd, EXT_MASK, 256, s);
464 *arcdata->masks = 0;
465 strcpy(arcdata->masks, s);
466 if (fRemember)
467 PrfWriteProfileString(fmprof, FM3Str, "Ext_Mask", s);
468 arcdata->ret = 1;
469 WinDismissDlg(hwnd, 1);
470 break;
471 }
472 }
473 }
474 if (!fErrorBeepOff)
475 DosBeep(50, 100); // Complain a refuse to quit
476 break;
477
478 case IDM_HELP:
479 case WM_HELP:
480 if (hwndHelp)
481 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
482 MPFROM2SHORT(HELP_EXTRACT, 0), MPFROMSHORT(HM_RESOURCEID));
483 break;
484
485 case EXT_WALK:
486 {
487 CHAR temp[CCHMAXPATH + 1];
488
489 strcpy(temp, arcdata->extractdir);
490 if (WinDlgBox(HWND_DESKTOP, WinQueryWindow(WinQueryWindow(hwnd,
491 QW_PARENT),
492 QW_OWNER),
493 WalkExtractDlgProc, FM3ModHandle, WALK_FRAME,
494 (PVOID) temp)) {
495 if (*temp && stricmp(temp, arcdata->extractdir)) {
496 strcpy(arcdata->extractdir, temp);
497 }
498 }
499 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
500 }
501 break;
502
503 case EXT_SEE:
504 {
505 CHAR s[1001], *p;
506 EXECARGS ex;
507
508 WinQueryDlgItemText(hwnd, EXT_COMMAND, 256, s);
509 lstrip(s);
510 if (!*s)
511 Runtime_Error(pszSrcFile, __LINE__, "no command");
512 else {
513 p = strchr(s, ' ');
514 if (p)
515 *p = 0; // Drop options
516 memset(&ex, 0, sizeof(EXECARGS));
517 ex.commandline = s;
518 ex.flags = WINDOWED | SEPARATEKEEP | MAXIMIZED;
519 *ex.path = 0;
520 *ex.environment = 0;
521 *ex.title = 0;
522 if (WinDlgBox(HWND_DESKTOP,
523 hwnd,
524 CmdLineDlgProc,
525 FM3ModHandle, EXEC_FRAME, MPFROMP(&ex)) && *s) {
526 runemf2(ex.flags,
527 hwnd, pszSrcFile, __LINE__,
528 NULL, (*ex.environment) ? ex.environment : NULL, "%s", s);
529 }
530 }
531 }
532 break;
533 }
534 return 0;
535
536 case WM_CLOSE:
537 break;
538 }
539 return WinDefDlgProc(hwnd, msg, mp1, mp2);
540}
541
542#pragma alloc_text(FMEXTRACT,ExtractTextProc,ExtractDlgProc)
Note: See TracBrowser for help on using the repository browser.