source: trunk/dll/undel.c@ 1570

Last change on this file since 1570 was 1554, checked in by Gregg Young, 15 years ago

Check that pTmpDir IsValid and recreate if not found; Fixes hangs caused by temp file creation failures. (Ticket 440)

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