source: trunk/dll/extract.c@ 1844

Last change on this file since 1844 was 1798, checked in by Gregg Young, 10 years ago

Fix case where fix to remove a leading quote from the extract path would remove the drive letter. Ticket [495]

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