source: trunk/dll/undel.c@ 1846

Last change on this file since 1846 was 1846, checked in by John Small, 10 years ago

Ticket #524: Ensure no "highmem-unsafe" functions are called directly
Calls to unsafe Dos... functions have been changed to call the wrapped xDos... functions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.5 KB
RevLine 
[123]1
2/***********************************************************************
3
4 $Id: undel.c 1846 2015-08-12 20:31:54Z jbs $
5
6 Copyright (c) 1993-98 M. Kimes
[1335]7 Copyright (c) 2004, 2008 Steven H. Levine
[123]8
[145]9 01 Aug 04 SHL Rework lstrip/rstrip usage
10 24 May 05 SHL Rework Win_Error usage
[328]11 17 Jul 06 SHL Use Runtime_Error
[406]12 29 Jul 06 SHL Use xfgets_bstripcr
[528]13 03 Nov 06 SHL Count thread usage
[775]14 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[793]15 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[985]16 29 Feb 08 GKY Use xfree where appropriate
[1075]17 16 JUL 08 GKY Use TMP directory for temp files
[1335]18 10 Dec 08 SHL Integrate exception handler support
[1402]19 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
20 08 Mar 09 GKY Additional strings move to PCSZs
[1438]21 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
[1554]22 20 Nov 10 GKY Check that pTmpDir IsValid and recreate if not found; Fixes hangs caused
23 by temp file creation failures.
[123]24
25***********************************************************************/
26
[2]27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
[1335]30// #include <process.h> // _beginthread
[328]31
[907]32#define INCL_DOS
33#define INCL_WIN
34#define INCL_LONGLONG
35
[1185]36#include "fm3dll.h"
[1227]37#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
38#include "undel.h"
[1214]39#include "init.h" // Data declaration(s)
40#include "mainwnd.h" // Data declaration(s)
[2]41#include "fm3dlg.h"
42#include "fm3str.h"
[907]43#include "errutil.h" // Dos_Error...
44#include "strutil.h" // GetPString
[1335]45#include "pathutil.h" // BldFullPathName
[1161]46#include "walkem.h" // FillPathListBox
[1185]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
[1038]54#include "fortify.h"
[1335]55#include "excputil.h" // xbeginthread
[2]56
57#pragma data_seg(DATA2)
[328]58
59static PSZ pszSrcFile = __FILE__;
60
[551]61struct tempstruct
62{
[2]63 HWND hwnd;
64 CHAR path[CCHMAXPATH];
65 BOOL inclsubdirs;
66};
67
[551]68static VOID FillUndelListThread(VOID * arg)
[328]69{
[551]70 HWND hwnd;
[1073]71 CHAR s[CCHMAXPATH * 2], szTempFile[CCHMAXPATH];
[551]72 CHAR *path;
73 HAB thab;
74 HMQ thmq;
[2]75 FILE *fp;
[551]76 HFILE oldstdout, newstdout;
[2]77 struct tempstruct *undelinfo;
[551]78 BOOL killme = FALSE;
[847]79 FILESTATUS3 fsa;
[1544]80 CHAR *mode = "w";
[2]81
82 undelinfo = (struct tempstruct *)arg;
83 hwnd = undelinfo->hwnd;
84 path = undelinfo->path;
85 DosError(FERR_DISABLEHARDERR);
86
[1038]87# ifdef FORTIFY
88 Fortify_EnterScope();
[1063]89# endif
[2]90 thab = WinInitialize(0);
[551]91 thmq = WinCreateMsgQueue(thab, 0);
[528]92 if (thab && thmq) {
[551]93 WinCancelShutdown(thmq, TRUE);
[528]94 IncrThreadUsage();
[551]95 WinSendDlgItemMsg(hwnd, UNDEL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
[1554]96 if (pTmpDir && !IsValidDir(pTmpDir))
97 DosCreateDir(pTmpDir, 0);
[1075]98 BldFullPathName(szTempFile, pTmpDir, "$UDELETE.#$#");
[1402]99 unlinkf(szTempFile);
[1544]100 fp = xfopen(szTempFile, mode, pszSrcFile, __LINE__, FALSE);
[328]101 if (!fp) {
[551]102 Win_Error(NULLHANDLE, hwnd, pszSrcFile, __LINE__,
103 GetPString(IDS_REDIRECTERRORTEXT));
[328]104 killme = TRUE;
105 goto Abort;
106 }
107 else {
[2]108 newstdout = -1;
[1846]109 if (xDosDupHandle(fileno(stdout), &newstdout)) {
[551]110 saymsg(MB_CANCEL,
111 hwnd,
112 GetPString(IDS_MAYDAYTEXT), GetPString(IDS_REDIRECTERRORTEXT));
113 fclose(fp);
114 killme = TRUE;
115 goto Abort;
[2]116 }
117 oldstdout = fileno(stdout);
[1846]118 xDosDupHandle(fileno(fp), &oldstdout);
[2]119 runemf2(SEPARATE | INVISIBLE | WINDOWED | BACKGROUND | WAIT,
[888]120 hwnd, pszSrcFile, __LINE__,
[551]121 NULL,
122 NULL,
123 "UNDELETE.COM %s /L%s",
124 path, (undelinfo->inclsubdirs) ? " /S" : NullStr);
[2]125 oldstdout = fileno(stdout);
[1846]126 xDosDupHandle(newstdout, &oldstdout);
[2]127 DosClose(newstdout);
128 fclose(fp);
129 }
[1544]130 mode = "r";
131 fp = xfopen(szTempFile, mode, pszSrcFile, __LINE__, FALSE);
[328]132 if (fp) {
[551]133 xfgets(s, sizeof(s), fp, pszSrcFile, __LINE__); // Skip 1st line
[406]134 while (!feof(fp)) {
[551]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)) {
[2]140
[551]141 APIRET temp;
[2]142
[551]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,
[1402]152 hwnd, GetPString(IDS_ERRORTEXT), s);
[551]153 if (temp == MBID_YES)
154 runemf2(BACKGROUND | INVISIBLE | SEPARATE | WINDOWED,
[888]155 hwnd, pszSrcFile, __LINE__,
[551]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
[847]167 && DosQueryPathInfo(s, FIL_STANDARD, &fsa,
[551]168 (ULONG) sizeof(fsa)))
169 WinSendDlgItemMsg(hwnd, UNDEL_LISTBOX, LM_INSERTITEM,
170 MPFROM2SHORT(LIT_SORTASCENDING, 0), MPFROMP(s));
171 }
[2]172 }
173 fclose(fp);
174 }
[551]175 Abort:
[528]176 ;
177 }
[1846]178 xDosForceDelete(szTempFile);
[1009]179 xfree(undelinfo, pszSrcFile, __LINE__);
[528]180 if (thmq) {
[551]181 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[528]182 if (killme)
[551]183 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
[2]184 WinDestroyMsgQueue(thmq);
[528]185 }
186 if (thab) {
187 DecrThreadUsage();
[2]188 WinTerminate(thab);
189 }
[1038]190# ifdef FORTIFY
[1063]191 Fortify_LeaveScope();
192# endif
[2]193}
194
[551]195MRESULT EXPENTRY UndeleteDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[328]196{
[551]197 SHORT sSelect;
198 static BOOL listdone, changed = FALSE, refresh = FALSE;
199 static HPOINTER hptrIcon = (HPOINTER) 0;
[2]200
[551]201 switch (msg) {
202 case WM_INITDLG:
203 listdone = TRUE;
[1009]204 if (!mp2 || !*(CHAR *)mp2) {
[1398]205 Runtime_Error(pszSrcFile, __LINE__, NULL);
[551]206 WinDismissDlg(hwnd, 0);
[2]207 break;
[551]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];
[2]215
[1009]216 strcpy(s, (CHAR *)mp2);
[1438]217 AddBackslashToPath(s);
218 //if (s[strlen(s) - 1] != '\\')
219 // strcat(s, "\\");
[551]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;
[2]228
[551]229 case UM_SETUP:
230 if (listdone) {
[2]231
[551]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);
[1335]253 if (xbeginthread(FillUndelListThread,
254 65536,
255 undelinfo,
256 pszSrcFile,
257 __LINE__) == -1)
258 {
[1039]259 free(undelinfo);
[551]260 listdone = TRUE;
261 WinDismissDlg(hwnd, 0);
[328]262 }
[551]263 else
[771]264 DosSleep(100);//05 Aug 07 GKY 500
[2]265 }
[551]266 refresh = FALSE;
267 }
268 else
269 refresh = TRUE;
270 changed = FALSE;
271 return 0;
[2]272
[551]273 case UM_CONTAINER_FILLED:
274 listdone = TRUE;
275 {
276 CHAR s[33];
[2]277
[551]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;
[2]288
[551]289 case WM_CONTROL:
290 switch (SHORT1FROMMP(mp1)) {
291 case UNDEL_SUBDIRS:
292 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
293 break;
[2]294
[551]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;
[2]304 }
305 break;
306
[551]307 case UNDEL_DRIVELIST:
308 if (!listdone) {
309 Runtime_Error(pszSrcFile, __LINE__, "not listdone");
310 break;
[2]311 }
[551]312 switch (SHORT2FROMMP(mp1)) {
313 case CBN_ENTER:
314 {
315 CHAR s[CCHMAXPATH], drive, *p;
[2]316
[551]317 strset(s, 0);
318 WinQueryDlgItemText(hwnd, UNDEL_DRIVELIST, 3, s);
319 if (!isalpha(*s)) {
[1398]320 Runtime_Error(pszSrcFile, __LINE__, NULL);
[328]321 }
322 else {
[551]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;
[2]350
[551]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;
[2]358
[551]359 default:
360 break;
361 }
362 return 0;
[2]363
[551]364 case WM_ADJUSTWINDOWPOS:
365 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
366 break;
[2]367
[551]368 case UM_STRETCH:
369 {
370 SWP swpC, swp, swpM, swpD, swpL, swpE;
[2]371
[551]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);
[2]412 }
[551]413 }
414 return 0;
[2]415
[551]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");
[328]422 }
[551]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;
[1846]430 CHAR s[CCHMAXPATH + 1];
431 CHAR *modew = "w";
[551]432
[1846]433 xDosForceDelete("\\FMUNDEL.CMD");
[1544]434 fp = xfopen("\\FMUNDEL.CMD", modew, pszSrcFile, __LINE__, FALSE);
[551]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,
[888]464 hwnd, pszSrcFile, __LINE__,
[551]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 }
[328]481 break;
[2]482
[551]483 case DID_CANCEL:
484 if (!listdone)
485 Runtime_Error(pszSrcFile, __LINE__, "is busy");
486 else
487 WinDismissDlg(hwnd, 0);
[2]488 break;
[551]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;
[2]511 }
[551]512 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]513}
[793]514
515#pragma alloc_text(UNDELETE,FillUndelListThread,UndeleteDlgProc)
Note: See TracBrowser for help on using the repository browser.