source: trunk/dll/extract.c@ 1692

Last change on this file since 1692 was 1692, checked in by Gregg Young, 12 years ago

Fix failure to create directory from archive file name when the name had a space. Strip extra leading " in extract and remove it from the arc container since it wasn't selectable and doesn't really make sense in that context (at least to me) Ticket 495

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