source: trunk/dll/undel.c@ 907

Last change on this file since 907 was 907, checked in by Steven Levine, 18 years ago

Avoid out of memory traps in Compare Directories
Rework Compare Directories progress display for 2 second update rate
Start refactoring to reduce dependence on fm3dll.h
Add timer services (IsITimerExpired etc.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.1 KB
Line 
1
2/***********************************************************************
3
4 $Id: undel.c 907 2008-01-06 07:26:17Z stevenhl $
5
6 Copyright (c) 1993-98 M. Kimes
7 Copyright (c) 2004, 2006 Steven H. Levine
8
9 01 Aug 04 SHL Rework lstrip/rstrip usage
10 24 May 05 SHL Rework Win_Error usage
11 17 Jul 06 SHL Use Runtime_Error
12 29 Jul 06 SHL Use xfgets_bstripcr
13 03 Nov 06 SHL Count thread usage
14 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
15 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
16
17***********************************************************************/
18
19#include <stdlib.h>
20#include <string.h>
21#include <ctype.h>
22#include <process.h> // _beginthread
23
24#define INCL_DOS
25#define INCL_WIN
26#define INCL_LONGLONG
27
28#include "fm3dlg.h"
29#include "fm3str.h"
30#include "errutil.h" // Dos_Error...
31#include "strutil.h" // GetPString
32#include "fm3dll.h"
33
34#pragma data_seg(DATA2)
35
36static PSZ pszSrcFile = __FILE__;
37
38struct tempstruct
39{
40 HWND hwnd;
41 CHAR path[CCHMAXPATH];
42 BOOL inclsubdirs;
43};
44
45static VOID FillUndelListThread(VOID * arg)
46{
47 HWND hwnd;
48 CHAR s[CCHMAXPATH * 2];
49 CHAR *path;
50 HAB thab;
51 HMQ thmq;
52 FILE *fp;
53 HFILE oldstdout, newstdout;
54 struct tempstruct *undelinfo;
55 BOOL killme = FALSE;
56 FILESTATUS3 fsa;
57
58 undelinfo = (struct tempstruct *)arg;
59 hwnd = undelinfo->hwnd;
60 path = undelinfo->path;
61 DosError(FERR_DISABLEHARDERR);
62
63 thab = WinInitialize(0);
64 thmq = WinCreateMsgQueue(thab, 0);
65 if (thab && thmq) {
66 WinCancelShutdown(thmq, TRUE);
67 IncrThreadUsage();
68 WinSendDlgItemMsg(hwnd, UNDEL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
69 unlinkf("%s", "$UDELETE.#$#");
70 fp = xfopen("$UDELETE.#$#", "w", pszSrcFile, __LINE__);
71 if (!fp) {
72 Win_Error(NULLHANDLE, hwnd, pszSrcFile, __LINE__,
73 GetPString(IDS_REDIRECTERRORTEXT));
74 killme = TRUE;
75 goto Abort;
76 }
77 else {
78 newstdout = -1;
79 if (DosDupHandle(fileno(stdout), &newstdout)) {
80 saymsg(MB_CANCEL,
81 hwnd,
82 GetPString(IDS_MAYDAYTEXT), GetPString(IDS_REDIRECTERRORTEXT));
83 fclose(fp);
84 killme = TRUE;
85 goto Abort;
86 }
87 oldstdout = fileno(stdout);
88 DosDupHandle(fileno(fp), &oldstdout);
89 runemf2(SEPARATE | INVISIBLE | WINDOWED | BACKGROUND | WAIT,
90 hwnd, pszSrcFile, __LINE__,
91 NULL,
92 NULL,
93 "UNDELETE.COM %s /L%s",
94 path, (undelinfo->inclsubdirs) ? " /S" : NullStr);
95 oldstdout = fileno(stdout);
96 DosDupHandle(newstdout, &oldstdout);
97 DosClose(newstdout);
98 fclose(fp);
99 }
100 fp = xfopen("$UDELETE.#$#", "r", pszSrcFile, __LINE__);
101 if (fp) {
102 xfgets(s, sizeof(s), fp, pszSrcFile, __LINE__); // Skip 1st line
103 while (!feof(fp)) {
104 strset(s, 0);
105 if (!xfgets_bstripcr(s, CCHMAXPATH + 2, fp, pszSrcFile, __LINE__))
106 break;
107 if (*s) {
108 if (!strnicmp(s, "SYS3194: ", 9)) {
109
110 APIRET temp;
111
112 strcat(s, " ");
113 xfgets(&s[strlen(s)], CCHMAXPATH + 128 - strlen(s), fp,
114 pszSrcFile, __LINE__);
115 fclose(fp);
116 s[CCHMAXPATH + 128] = 0;
117 stripcr(s);
118 rstrip(s);
119 strcat(s, GetPString(IDS_ASKABOUTUNDELETEHELPTEXT));
120 temp = saymsg(MB_YESNOCANCEL | MB_ICONEXCLAMATION,
121 hwnd, GetPString(IDS_ERRORTEXT), "%s", s);
122 if (temp == MBID_YES)
123 runemf2(BACKGROUND | INVISIBLE | SEPARATE | WINDOWED,
124 hwnd, pszSrcFile, __LINE__,
125 NULL, NULL, "%s /C HELP UNDELETE", GetCmdSpec(FALSE));
126 if (temp == MBID_CANCEL)
127 killme = TRUE;
128 goto Abort;
129 }
130 else if (s[1] != ':')
131 continue;
132 else if ((SHORT)
133 WinSendDlgItemMsg(hwnd, UNDEL_LISTBOX, LM_SEARCHSTRING,
134 MPFROM2SHORT(0, LIT_FIRST),
135 MPFROMP(s)) < 0
136 && DosQueryPathInfo(s, FIL_STANDARD, &fsa,
137 (ULONG) sizeof(fsa)))
138 WinSendDlgItemMsg(hwnd, UNDEL_LISTBOX, LM_INSERTITEM,
139 MPFROM2SHORT(LIT_SORTASCENDING, 0), MPFROMP(s));
140 }
141 }
142 fclose(fp);
143 }
144 Abort:
145 ;
146 }
147 DosForceDelete("$UDELETE.#$#");
148 if (undelinfo)
149 free(undelinfo);
150 if (thmq) {
151 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
152 if (killme)
153 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
154 WinDestroyMsgQueue(thmq);
155 }
156 if (thab) {
157 DecrThreadUsage();
158 WinTerminate(thab);
159 }
160}
161
162MRESULT EXPENTRY UndeleteDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
163{
164 SHORT sSelect;
165 static BOOL listdone, changed = FALSE, refresh = FALSE;
166 static HPOINTER hptrIcon = (HPOINTER) 0;
167
168 switch (msg) {
169 case WM_INITDLG:
170 listdone = TRUE;
171 if (!mp2 || !*(CHAR *) mp2) {
172 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
173 WinDismissDlg(hwnd, 0);
174 break;
175 }
176 hptrIcon = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, UNDEL_FRAME);
177 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptrIcon), MPVOID);
178 WinSendDlgItemMsg(hwnd, UNDEL_ENTRY, EM_SETTEXTLIMIT,
179 MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
180 {
181 CHAR s[CCHMAXPATH];
182
183 strcpy(s, (CHAR *) mp2);
184 if (s[strlen(s) - 1] != '\\')
185 strcat(s, "\\");
186 strcat(s, "*");
187 WinSetDlgItemText(hwnd, UNDEL_ENTRY, s);
188 WinCheckButton(hwnd, UNDEL_SUBDIRS, TRUE);
189 FillPathListBox(hwnd, WinWindowFromID(hwnd, UNDEL_DRIVELIST), (HWND) 0,
190 s, TRUE);
191 }
192 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
193 break;
194
195 case UM_SETUP:
196 if (listdone) {
197
198 struct tempstruct *undelinfo;
199 CHAR s[CCHMAXPATH];
200
201 listdone = FALSE;
202 undelinfo = xmallocz(sizeof(struct tempstruct), pszSrcFile, __LINE__);
203 if (!undelinfo) {
204 listdone = TRUE;
205 WinDismissDlg(hwnd, 0);
206 }
207 else {
208 undelinfo->hwnd = hwnd;
209 WinQueryDlgItemText(hwnd,
210 UNDEL_ENTRY,
211 sizeof(undelinfo->path), undelinfo->path);
212 bstrip(undelinfo->path);
213 MakeFullName(undelinfo->path);
214 undelinfo->inclsubdirs = WinQueryButtonCheckstate(hwnd,
215 UNDEL_SUBDIRS);
216 sprintf(s,
217 GetPString(IDS_UNDELETETITLETEXT), toupper(*undelinfo->path));
218 WinSetWindowText(hwnd, s);
219 if (_beginthread(FillUndelListThread, NULL, 65536, (PVOID) undelinfo)
220 == -1) {
221 Runtime_Error(pszSrcFile, __LINE__,
222 GetPString(IDS_COULDNTSTARTTHREADTEXT));
223 free(undelinfo);
224 listdone = TRUE;
225 WinDismissDlg(hwnd, 0);
226 }
227 else
228 DosSleep(100);//05 Aug 07 GKY 500
229 }
230 refresh = FALSE;
231 }
232 else
233 refresh = TRUE;
234 changed = FALSE;
235 return 0;
236
237 case UM_CONTAINER_FILLED:
238 listdone = TRUE;
239 {
240 CHAR s[33];
241
242 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
243 UNDEL_LISTBOX,
244 LM_QUERYITEMCOUNT, MPVOID, MPVOID);
245 sprintf(s, "%d", sSelect);
246 WinSetDlgItemText(hwnd, UNDEL_COUNT, s);
247 if (refresh)
248 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
249 refresh = FALSE;
250 }
251 return 0;
252
253 case WM_CONTROL:
254 switch (SHORT1FROMMP(mp1)) {
255 case UNDEL_SUBDIRS:
256 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
257 break;
258
259 case UNDEL_ENTRY:
260 switch (SHORT2FROMMP(mp1)) {
261 case EN_CHANGE:
262 changed = TRUE;
263 break;
264 case EN_KILLFOCUS:
265 if (changed)
266 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
267 break;
268 }
269 break;
270
271 case UNDEL_DRIVELIST:
272 if (!listdone) {
273 Runtime_Error(pszSrcFile, __LINE__, "not listdone");
274 break;
275 }
276 switch (SHORT2FROMMP(mp1)) {
277 case CBN_ENTER:
278 {
279 CHAR s[CCHMAXPATH], drive, *p;
280
281 strset(s, 0);
282 WinQueryDlgItemText(hwnd, UNDEL_DRIVELIST, 3, s);
283 if (!isalpha(*s)) {
284 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
285 }
286 else {
287 drive = toupper(*s);
288 WinQueryDlgItemText(hwnd, UNDEL_ENTRY, sizeof(s), s);
289 *s = drive;
290 s[1] = ':';
291 s[2] = '\\';
292 p = strrchr(s + 2, '\\');
293 if (p) {
294 p++;
295 if (*p)
296 memmove(s + 3, p, strlen(p) + 1);
297 else {
298 s[3] = '*';
299 s[4] = 0;
300 }
301 }
302 else {
303 s[3] = '*';
304 s[4] = 0;
305 }
306 s[CCHMAXPATH - 1] = 0;
307 WinSetDlgItemText(hwnd, UNDEL_ENTRY, s);
308 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
309 }
310 }
311 break;
312 }
313 break;
314
315 case UNDEL_LISTBOX:
316 switch (SHORT2FROMMP(mp2)) {
317 case LN_ENTER:
318 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPFROMSHORT(TRUE), MPVOID);
319 break;
320 }
321 break;
322
323 default:
324 break;
325 }
326 return 0;
327
328 case WM_ADJUSTWINDOWPOS:
329 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
330 break;
331
332 case UM_STRETCH:
333 {
334 SWP swpC, swp, swpM, swpD, swpL, swpE;
335
336 WinQueryWindowPos(hwnd, &swp);
337 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
338 WinQueryWindowPos(WinWindowFromID(hwnd, UNDEL_LISTBOX), &swpC);
339 WinQueryWindowPos(WinWindowFromID(hwnd, UNDEL_MASKHDR), &swpM);
340 WinQueryWindowPos(WinWindowFromID(hwnd, UNDEL_DRVHDR), &swpD);
341 WinQueryWindowPos(WinWindowFromID(hwnd, UNDEL_DRIVELIST), &swpL);
342 WinQueryWindowPos(WinWindowFromID(hwnd, UNDEL_ENTRY), &swpE);
343 WinSetWindowPos(WinWindowFromID(hwnd, UNDEL_LISTBOX), HWND_TOP,
344 SysVal(SV_CXSIZEBORDER),
345 swpC.y,
346 swp.cx - (SysVal(SV_CXSIZEBORDER) * 2),
347 (swp.cy - swpC.y) - (SysVal(SV_CYTITLEBAR) +
348 SysVal(SV_CYSIZEBORDER) +
349 swpM.cy + 16),
350 SWP_MOVE | SWP_SIZE);
351 WinSetWindowPos(WinWindowFromID(hwnd, UNDEL_MASKHDR), HWND_TOP,
352 swpM.x,
353 (swp.cy - swpM.cy) - (SysVal(SV_CYTITLEBAR) +
354 SysVal(SV_CYSIZEBORDER) + 8),
355 swpM.cx, swpM.cy, SWP_MOVE | SWP_SIZE);
356 WinSetWindowPos(WinWindowFromID(hwnd, UNDEL_DRVHDR), HWND_TOP,
357 swpD.x,
358 (swp.cy - swpM.cy) - (SysVal(SV_CYTITLEBAR) +
359 SysVal(SV_CYSIZEBORDER) + 8),
360 swpD.cx, swpM.cy, SWP_MOVE | SWP_SIZE);
361 WinSetWindowPos(WinWindowFromID(hwnd, UNDEL_DRIVELIST), HWND_TOP,
362 swpL.x,
363 SysVal(SV_CYSIZEBORDER),
364 swpL.cx,
365 swp.cy - (SysVal(SV_CYTITLEBAR) +
366 (SysVal(SV_CYSIZEBORDER) * 2) + 6),
367 SWP_MOVE | SWP_SIZE);
368 WinSetWindowPos(WinWindowFromID(hwnd, UNDEL_ENTRY), HWND_TOP,
369 swpM.x + swpM.cx + 4,
370 (swp.cy - swpM.cy) - (SysVal(SV_CYTITLEBAR) +
371 SysVal(SV_CYSIZEBORDER) + 8),
372 swp.cx - ((swpM.x + swpM.cx + 4) +
373 (SysVal(SV_CXSIZEBORDER) + 8)),
374 swpM.cy + 2, SWP_MOVE | SWP_SIZE);
375 WinInvalidateRect(WinWindowFromID(hwnd, UNDEL_ENTRY), NULL, FALSE);
376 }
377 }
378 return 0;
379
380 case WM_COMMAND:
381 switch (SHORT1FROMMP(mp1)) {
382 case UNDEL_DEL:
383 case DID_OK:
384 if (changed || !listdone) {
385 Runtime_Error(pszSrcFile, __LINE__, "not done");
386 }
387 else {
388 sSelect = (USHORT) WinSendDlgItemMsg(hwnd, UNDEL_LISTBOX,
389 LM_QUERYSELECTION,
390 MPFROMSHORT(LIT_FIRST), MPVOID);
391 if (sSelect >= 0) {
392
393 FILE *fp;
394 CHAR s[CCHMAXPATH + 1];
395
396 DosForceDelete("\\FMUNDEL.CMD");
397 fp = xfopen("\\FMUNDEL.CMD", "w", pszSrcFile, __LINE__);
398 if (fp) {
399 while (sSelect >= 0) {
400 *s = 0;
401 WinSendDlgItemMsg(hwnd, UNDEL_LISTBOX, LM_QUERYITEMTEXT,
402 MPFROM2SHORT(sSelect, CCHMAXPATH),
403 MPFROMP(s));
404 if (SHORT1FROMMP(mp1) == UNDEL_DEL)
405 WinSendDlgItemMsg(hwnd, UNDEL_LISTBOX, LM_DELETEITEM,
406 MPFROM2SHORT(sSelect, 0), MPVOID);
407 if (*s) {
408 if (SHORT1FROMMP(mp1) == DID_OK)
409 fprintf(fp,
410 "IF NOT EXIST \"%s\" UNDELETE.COM \"%s\" /A\n",
411 s, s);
412 else
413 fprintf(fp, "UNDELETE.COM \"%s\" /F /A\n", s);
414 }
415 sSelect = (USHORT) WinSendDlgItemMsg(hwnd,
416 UNDEL_LISTBOX,
417 LM_QUERYSELECTION,
418 (SHORT1FROMMP(mp1) ==
419 DID_OK) ?
420 MPFROMSHORT(sSelect) :
421 MPFROMSHORT(LIT_FIRST),
422 MPVOID);
423 }
424 fprintf(fp, "DEL \\FMUNDEL.CMD /F\n");
425 fclose(fp);
426 runemf2(WINDOWED | BACKGROUND | SEPARATE | INVISIBLE,
427 hwnd, pszSrcFile, __LINE__,
428 NULL, NULL, "%s /C \\FMUNDEL.CMD", GetCmdSpec(FALSE));
429 }
430 }
431 if (SHORT1FROMMP(mp1) == DID_OK)
432 WinDismissDlg(hwnd, 0);
433 {
434 CHAR s[33];
435
436 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
437 UNDEL_LISTBOX,
438 LM_QUERYITEMCOUNT,
439 MPVOID, MPVOID);
440 sprintf(s, "%d", sSelect);
441 WinSetDlgItemText(hwnd, UNDEL_COUNT, s);
442 }
443 }
444 break;
445
446 case DID_CANCEL:
447 if (!listdone)
448 Runtime_Error(pszSrcFile, __LINE__, "is busy");
449 else
450 WinDismissDlg(hwnd, 0);
451 break;
452
453 case IDM_HELP:
454 saymsg(MB_ENTER | MB_ICONASTERISK,
455 hwnd,
456 GetPString(IDS_UNDELETEHELPTITLETEXT),
457 GetPString(IDS_UNDELETEHELPTEXT));
458 break;
459 }
460 return 0;
461
462 case WM_CLOSE:
463 if (!listdone) {
464 Runtime_Error(pszSrcFile, __LINE__, "not listdone");
465 return 0;
466 }
467 break;
468
469 case WM_DESTROY:
470 if (hptrIcon)
471 WinDestroyPointer(hptrIcon);
472 hptrIcon = (HPOINTER) 0;
473 break;
474 }
475 return WinDefDlgProc(hwnd, msg, mp1, mp2);
476}
477
478#pragma alloc_text(UNDELETE,FillUndelListThread,UndeleteDlgProc)
Note: See TracBrowser for help on using the repository browser.