source: trunk/dll/dirsize.c@ 1878

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

Remove some dead code and comments source files starting with A-D

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.4 KB
Line 
1
2/***********************************************************************
3
4 $Id: dirsize.c 1878 2015-10-11 22:24:39Z gyoung $
5
6 Directory sizes
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2015 Steven H. Levine
10
11 16 Oct 02 SHL Handle large partitions
12 12 Feb 03 SHL Use CBLIST_TO_EASIZE
13 21 Nov 03 SHL Avoid VAC \ after // bug (wierd)
14 21 Nov 03 SHL Correct minor typos
15 21 Nov 03 SHL Total drives >4GB better
16 24 May 05 SHL Rework for CNRITEM.szSubject
17 25 May 05 SHL Use ULONGLONG and CommaFmtULL
18 26 May 05 SHL More large file formatting updates
19 06 Jun 05 SHL Drop obsoletes
20 19 Jun 05 SHL More 64-bit math fixes
21 08 Aug 05 SHL Avoid Expand/Collapse hangs while working
22 17 Jul 06 SHL Use Runtime_Error
23 19 Oct 06 SHL Correct . and .. detect
24 18 Feb 07 GKY Add new drive type icons
25 22 Mar 07 GKY Use QWL_USER
26 23 Jul 07 SHL Sync with naming standards
27 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
28 03 Aug 07 SHL DirSizeProc; correct sizing and positioning to be deterministic
29 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
30 13 Aug 07 SHL ProcessDir: remove unneeded reallocs. Sanitize code
31 13 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
32 26 Aug 07 GKY DosSleep(1) in loops changed to (0)
33 29 Feb 08 GKY Use xfree where appropriate
34 29 Feb 08 GKY Add presparams & update appearence of "Sizes" dialog
35 07 Jul 08 GKY Fixed trap in PMCTLS (strlen) inadequate memory allocation
36 07 Jul 08 GKY Fixed trap by no longer allocating pci->pszLongName as flag but pointing isroot
37 version to NullStr and all others to NULL.
38 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory; use pTmpDir for temp files
39 03 Aug 08 GKY Reworked FillInRecSizes to use pci->pszDisplayName for display names and
40 created a more consitent string for passing to DRAWITEM. Finally (I hope) fixed
41 the strlen trap.
42 23 Aug 08 GKY Fix memory leak (failure to free cnritems)
43 10 Dec 08 SHL Integrate exception handler support
44 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
45 08 Mar 09 GKY Renamed commafmt.h i18nutil.h
46 08 Mar 09 GKY Additional strings move to PCSZs in init.c
47 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
48 13 Dec 09 GKY Fixed separate paramenters. Please note that appname should be used in
49 profile calls for user settings that work and are setable in more than one
50 miniapp; FM3Str should be used for setting only relavent to FM/2 or that
51 aren't user settable; realappname should be used for setting applicable to
52 one or more miniapp but not to FM/2
53 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10).
54 Mostly cast CHAR CONSTANT * as CHAR *.
55 20 Nov 10 GKY Check that pTmpDir IsValid and recreate if not found; Fixes hangs caused
56 by temp file creation failures.
57 12 Jun 11 GKY Added SleepIfNeeded in the container fill loop
58 20 Sep 15 GKY Move directory expansion to a thread. Split ExpandAll into ExpandAll and CollapseAll
59 to try to speed proccessing else where.
60
61***********************************************************************/
62
63#include <stdlib.h>
64#include <string.h>
65#include <ctype.h>
66// #include <process.h> // _beginthread
67
68#define INCL_DOS
69#define INCL_DOSERRORS
70#define INCL_WIN
71#define INCL_GPI
72#define INCL_LONGLONG
73
74#include "fm3dll.h"
75#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
76#include "draglist.h" // Data declaration(s)
77#include "init.h" // Data declaration(s)
78#include "notebook.h" // Data declaration(s)
79#include "mainwnd.h" // Data declaration(s)
80#include "newview.h" // Data declarations
81#include "fm3dlg.h"
82#include "fm3str.h"
83#include "dircnrs.h"
84#include "errutil.h" // Dos_Error...
85#include "strutil.h" // GetPString
86#include "filldir.h" // EmptyCnr...
87#include "dirsize.h"
88#include "select.h" // ExpandAll
89#include "valid.h" // CheckDrive
90#include "common.h" // OpenDirCnr
91#include "shadow.h" // OpenObject
92#include "presparm.h" // PresParamChanged
93#include "i18nutil.h" // commafmt
94#include "getnames.h" // export_filename
95#include "wrappers.h" // xDosFindNext
96#include "dirs.h" // save_dir2
97#include "misc.h" // PostMsg
98#include "fortify.h"
99#include "excputil.h" // xbeginthread
100#include "pathutil.h" // AddBackslashToPath
101#include "tmrsvcs.h"
102
103typedef struct
104{
105 CHAR *pszFileName;
106 HWND hwndCnr;
107 CHAR *pchStopFlag;
108 DIRCNRDATA *pDCD;
109} DIRSIZE;
110
111typedef struct
112{
113 HWND hwndCnr;
114 PCNRITEM pci;
115} EXPANDSIZE;
116
117typedef struct
118{
119 CHAR szDirName[CCHMAXPATH];
120 CHAR chStopFlag;
121 BOOL dying;
122 BOOL working;
123 HPOINTER hptr;
124} tState;
125
126static PSZ pszSrcFile = __FILE__;
127
128static SHORT APIENTRY SortSizeCnr(PMINIRECORDCORE p1,
129 PMINIRECORDCORE p2,
130 PVOID SortFlags)
131{
132 ULONGLONG size1;
133 ULONGLONG size2;
134
135 size1 = ((PCNRITEM) p1)->cbFile + ((PCNRITEM) p1)->easize;
136 size2 = ((PCNRITEM) p2)->cbFile + ((PCNRITEM) p2)->easize;
137 return (size1 < size2) ? 1 : (size1 == size2) ? 0 : -1;
138}
139
140static BOOL ProcessDir(HWND hwndCnr,
141 CHAR *pszFileName,
142 PCNRITEM pciParent,
143 CHAR *pchStopFlag,
144 BOOL top,
145 PULONGLONG pullTotalBytes)
146{
147 CHAR maskstr[CCHMAXPATH];
148 CHAR szBuf[CCHMAXPATH];
149 CHAR FileSystem[CCHMAXPATH];
150 CHAR *pEndMask;
151 register char *p;
152 register char *sp;
153 register char *pp;
154 ULONG ulFindCnt;
155 ULONGLONG ullCurDirBytes = 0;
156 ULONGLONG ullSubDirBytes = 0;
157 ULONGLONG ull;
158 HDIR hdir;
159 PFILEFINDBUF4L pffbArray;
160 APIRET rc;
161 RECORDINSERT ri;
162 PCNRITEM pci;
163 ULONG ulBufBytes;
164
165 *pullTotalBytes = 0; // In case we fail
166
167 CheckDrive(toupper(*pszFileName), FileSystem, NULL);
168 ulBufBytes = sizeof(FILEFINDBUF4L) * FilesToGet;
169 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
170 if (!pffbArray)
171 return FALSE; // Error already reported
172
173 strcpy(maskstr, pszFileName);
174 AddBackslashToPath(maskstr);
175 pEndMask = &maskstr[strlen(maskstr)]; // Point after last backslash
176 strcat(maskstr, "*");
177
178 hdir = HDIR_CREATE;
179 ulFindCnt = 1;
180 DosError(FERR_DISABLEHARDERR);
181 // Check directory exists
182 rc = xDosFindFirst(pszFileName, &hdir,
183 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
184 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
185 pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
186
187 if (!rc)
188 DosFindClose(hdir);
189
190 /**
191 * the "|| strlen(pszFileName) < 4 below works around an OS/2 bug
192 * that prevents FAT root directories from being found when
193 * requesting EASIZE. sheesh.
194 */
195 if (((!rc || rc == ERROR_NO_MORE_FILES) && (pffbArray->attrFile & FILE_DIRECTORY)) ||
196 strlen(pszFileName) < 4) {
197 if (*pchStopFlag) {
198 free(pffbArray);
199 return FALSE;
200 }
201 pci = WinSendMsg(hwndCnr, CM_ALLOCRECORD, MPFROMLONG(EXTRA_RECORD_BYTES),
202 MPFROMLONG(1));
203 if (!pci) {
204 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
205 xfree(pffbArray, pszSrcFile, __LINE__);
206 return FALSE;
207 }
208 if (!rc) {
209 ullCurDirBytes = pffbArray->cbFile;
210 ullCurDirBytes += CBLIST_TO_EASIZE(pffbArray->cbList);
211 }
212 else
213 DosError(FERR_DISABLEHARDERR);
214 pci->rc.hptrIcon = hptrDir;
215 pci->attrFile = 0;
216 pci->pszDispAttr = NULL;
217 pci->pszSubject = NULL;
218 } // if got something
219 else {
220 // No match
221 xfree(pffbArray, pszSrcFile, __LINE__);
222 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
223 GetPString(IDS_CANTFINDDIRTEXT), pszFileName);
224 return FALSE;
225 }
226
227 if (strlen(pszFileName) < 4 || top)
228 pci->pszFileName = xstrdup(pszFileName, pszSrcFile, __LINE__);
229 else {
230 p = strrchr(pszFileName, '\\');
231 if (!p)
232 p = pszFileName;
233 else
234 p++; // After last backslash
235 // Handle quoted names
236 // fixme to understand this - why lose path prefix?
237 sp = strchr(pszFileName, ' ') != NULL ? "\"" : NullStr;
238 pp = szBuf;
239 if (*sp)
240 *pp++ = *sp; // Need quotes
241 strcpy(pp, p);
242 if (*sp)
243 strcat(pp, sp);
244 pci->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
245 }
246 // Use pszDisplayname for display so no need to save length of pszFileName 03 Aug 08 GKY
247 pci->pszDisplayName = pci->pszFileName;
248 pci->rc.pszIcon = pci->pszFileName;
249 pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
250 if (fForceUpper)
251 strupr(pci->pszFileName);
252 else if (fForceLower)
253 strlwr(pci->pszFileName);
254 memset(&ri, 0, sizeof(RECORDINSERT));
255 ri.cb = sizeof(RECORDINSERT);
256 ri.pRecordOrder = (PRECORDCORE) CMA_END;
257 ri.pRecordParent = (PRECORDCORE) pciParent;
258 ri.zOrder = (USHORT) CMA_TOP;
259 ri.cRecordsInsert = 1;
260 ri.fInvalidateRecord = TRUE;
261 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
262 xfree(pffbArray, pszSrcFile, __LINE__);
263 return FALSE;
264 }
265
266 // Find files and directories in this directory
267 hdir = HDIR_CREATE;
268 // 13 Aug 07 SHL fixme to know if need to support fRemoteBug here like objcnr.c?
269 ulFindCnt = FilesToGet;
270 rc = xDosFindFirst(maskstr, &hdir,
271 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
272 FILE_SYSTEM | FILE_HIDDEN | FILE_DIRECTORY,
273 pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
274 if (!rc) {
275 PFILEFINDBUF4L pffbFile;
276 ULONG x;
277 ITIMER_DESC itdSleep = { 0 }; // 30 May 11 GKY
278
279 InitITimer(&itdSleep, 500);
280 while (!rc) {
281
282 priority_normal();
283 pffbFile = pffbArray;
284 for (x = 0; x < ulFindCnt; x++) {
285 // Total size skipping . and ..
286 if ((~pffbFile->attrFile & FILE_DIRECTORY) ||
287 (pffbFile->achName[0] != '.' ||
288 (pffbFile->achName[1] &&
289 (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
290 ullCurDirBytes += pffbFile->cbFile;
291 ullCurDirBytes += CBLIST_TO_EASIZE(pffbFile->cbList) & 0x3ff;
292
293 if (*pchStopFlag)
294 break;
295 if (~pffbFile->attrFile & FILE_DIRECTORY)
296 pci->attrFile++; // Bump file count
297 else {
298 // Recurse into subdir
299 strcpy(pEndMask, pffbFile->achName); // Append dirname to base dirname
300 ProcessDir(hwndCnr, maskstr, pci, pchStopFlag, FALSE, &ull);
301 ullSubDirBytes += ull;
302 }
303 }
304 if (!pffbFile->oNextEntryOffset)
305 break;
306 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
307
308 } // for matches
309 if (*pchStopFlag)
310 break;
311 DosSleep(0);
312 ulFindCnt = FilesToGet;
313 DosError(FERR_DISABLEHARDERR);
314 rc = xDosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
315 SleepIfNeeded(&itdSleep, 1);
316 } // while more found
317
318 DosFindClose(hdir);
319 priority_normal();
320 } // if got files or directories
321
322 if (rc && rc != ERROR_NO_MORE_FILES) {
323 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
324 GetPString(IDS_CANTFINDDIRTEXT), pszFileName);
325 }
326
327 xfree(pffbArray, pszSrcFile, __LINE__);
328
329 pci->cbFile = ullCurDirBytes;
330 pci->easize = ullSubDirBytes; // hack cough
331 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pci),
332 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
333
334 *pullTotalBytes = ullCurDirBytes + ullSubDirBytes;
335 return TRUE;
336}
337
338static VOID FillInRecSizes(HWND hwndCnr, PCNRITEM pciParent,
339 ULONGLONG ullTotalBytes, CHAR * pchStopFlag,
340 BOOL isroot)
341{
342 PCNRITEM pci = pciParent;
343 SHORT attrib = CMA_FIRSTCHILD;
344
345 if (pci) {
346
347 float fltPct = (float) 0.0;
348 CHAR szCurDir[80];
349 CHAR szSubDir[80];
350 CHAR szAllDir[80];
351 CHAR szBar[101];
352 CHAR szBuf[CCHMAXPATH + 341];
353
354 // cbFile = currect directory usage in bytes
355 // easize = subdirectory usage in bytes
356 CommaFmtULL(szCurDir, sizeof(szCurDir), pci->cbFile, 'K');
357 *szBar = 0;
358 pci->pszLongName = NULL;
359 memset(szBuf, 0, sizeof(szBuf));
360 if (ullTotalBytes) {
361 UINT cBar;
362
363 if (isroot) {
364 FSALLOCATE fsa;
365 APIRET rc;
366
367
368 memset(&fsa, 0, sizeof(fsa));
369 rc = DosQueryFSInfo(toupper(*pci->pszFileName) - '@', FSIL_ALLOC, &fsa,
370 sizeof(FSALLOCATE));
371 if (!rc) {
372 fltPct = (float) (ullTotalBytes * 100.0) /
373 ((float)fsa.cUnit * (fsa.cSectorUnit * fsa.cbSector));
374 }
375 // Need unique buffer 23 Jul 07 SHL
376 pci->pszLongName = NullStr;
377 }
378 else
379 fltPct = (float) (((float)pci->cbFile + pci->easize) * 100.0) / ullTotalBytes;
380
381 //Second line for graph reworked 03 AUG 08 GKY
382 memset(szBar, ' ', sizeof(szBar));
383 cBar = (UINT) fltPct / 2;
384 if (cBar && cBar * 2 != (UINT) fltPct)
385 szBar[cBar] = '=';
386 szBar[100] = 0;
387 }
388
389 pci->flags = (ULONG) fltPct;
390 CommaFmtULL(szSubDir, sizeof(szSubDir), pci->easize, 'K');
391 CommaFmtULL(szAllDir, sizeof(szAllDir), pci->cbFile + pci->easize, 'K');
392 sprintf(szBuf,
393 "%s %s + %s = %s (%.02lf%%%s)\r%s",
394 pci->pszFileName,
395 szCurDir,
396 szSubDir,
397 szAllDir,
398 fltPct,
399 isroot ? GetPString(IDS_OFDRIVETEXT) : NullStr,
400 szBar);
401 pci->pszDisplayName = xstrdup(szBuf, pszSrcFile, __LINE__);
402 // use DisplayName for display hopefully fixes "strlen" trap 02 AUG 08 GKY
403 if (pci->pszDisplayName) {
404# ifdef FORTIFY
405 Fortify_ChangeScope(pci->pszDisplayName, -1);
406 Fortify_ChangeScope(pci->pszFileName, -1);
407# endif
408 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pci), MPFROM2SHORT(1, 0));
409 }
410 isroot = FALSE;
411 }
412 else
413 attrib = CMA_FIRST;
414 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
415 MPFROM2SHORT(attrib, CMA_ITEMORDER));
416 while (pci && (INT) pci != -1) {
417 if (*pchStopFlag)
418 break;
419 FillInRecSizes(hwndCnr, pci, ullTotalBytes, pchStopFlag, isroot);
420 isroot = FALSE;
421 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
422 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
423 }
424}
425
426static VOID PrintToFile(HWND hwndCnr, ULONG indent, PCNRITEM pciParent,
427 FILE * fp)
428{
429 PCNRITEM pci;
430 CHAR *p;
431
432 if (!pciParent) {
433 pciParent = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(NULL),
434 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
435 indent = 0;
436 }
437 if (pciParent) {
438 p = strchr(pciParent->pszDisplayName, '\r'); // GKY use display name for display
439 if (p)
440 *p = 0;
441 fprintf(fp, "%*.*s%s %lu %s%s\n",
442 indent * 2, indent * 2, " ",
443 pciParent->pszDisplayName,
444 pciParent->attrFile,
445 GetPString(IDS_FILETEXT), &"s"[pciParent->attrFile == 1]);
446 if (p)
447 *p = '\r';
448 if (pciParent->rc.flRecordAttr & CRA_EXPANDED) {
449 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
450 MPFROM2SHORT(CMA_FIRSTCHILD,
451 CMA_ITEMORDER));
452 while (pci && (INT) pci != -1) {
453 DosSleep(0);
454 PrintToFile(hwndCnr, indent + 1, pci, fp);
455 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
456 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
457 } //while
458 }
459 }
460}
461
462static VOID FillCnrThread(VOID *args)
463{
464 HAB hab;
465 HMQ hmq;
466 DIRSIZE *dirsize = (DIRSIZE *)args;
467 HWND hwndCnr;
468 ULONGLONG ull;
469
470 if (!dirsize) {
471 Runtime_Error(pszSrcFile, __LINE__, NULL);
472 return;
473 }
474# ifdef FORTIFY
475 Fortify_EnterScope();
476 Fortify_BecomeOwner(dirsize); // We free dirsize
477# endif
478
479 hwndCnr = dirsize->hwndCnr;
480
481 DosError(FERR_DISABLEHARDERR);
482
483 // priority_normal();
484 hab = WinInitialize(0);
485 if (hab) {
486 hmq = WinCreateMsgQueue(hab, 0);
487 if (hmq) {
488 WinCancelShutdown(hmq, TRUE);
489 ProcessDir(hwndCnr, dirsize->pszFileName,
490 (PCNRITEM) NULL, dirsize->pchStopFlag, TRUE, &ull);
491 DosPostEventSem(CompactSem);
492 WinEnableWindowUpdate(hwndCnr, FALSE);
493 FillInRecSizes(hwndCnr, NULL, ull, dirsize->pchStopFlag, TRUE);
494 WinEnableWindowUpdate(hwndCnr, TRUE);
495 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
496 MPFROM2SHORT(0, CMA_ERASE | CMA_TEXTCHANGED));
497 WinDestroyMsgQueue(hmq);
498 }
499 WinTerminate(hab);
500 }
501
502 xfree(dirsize, pszSrcFile, __LINE__);
503 PostMsg(WinQueryWindow(hwndCnr, QW_PARENT),
504 UM_CONTAINER_FILLED, MPVOID, MPVOID);
505# ifdef FORTIFY
506 Fortify_LeaveScope();
507# endif
508}
509
510static VOID ExpandCnrThread(VOID *args)
511{
512 HAB hab;
513 HMQ hmq;
514 INT x = 0;
515 EXPANDSIZE *expandsize = (EXPANDSIZE *)args;
516
517 if (!expandsize) {
518 Runtime_Error(pszSrcFile, __LINE__, NULL);
519 return;
520 }
521# ifdef FORTIFY
522 Fortify_EnterScope();
523 Fortify_BecomeOwner(expandsize); // We free dirsize
524# endif
525
526 DosError(FERR_DISABLEHARDERR);
527
528 priority_idle();
529 hab = WinInitialize(0);
530 if (hab) {
531 hmq = WinCreateMsgQueue(hab, 0);
532 if (hmq) {
533 WinCancelShutdown(hmq, TRUE);
534 ExpandAll(expandsize->hwndCnr, x, expandsize->pci);
535 WinDestroyMsgQueue(hmq);
536 }
537 WinTerminate(hab);
538 }
539
540 xfree(expandsize, pszSrcFile, __LINE__);
541# ifdef FORTIFY
542 Fortify_LeaveScope();
543# endif
544}
545
546MRESULT EXPENTRY DirSizeProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
547{
548 tState *pState;
549 PCNRITEM pci;
550 CHAR szBytes[44];
551 CHAR sz[66];
552
553 switch (msg) {
554 case WM_INITDLG:
555 if (!mp2) {
556 WinDismissDlg(hwnd, 0);
557 break;
558 }
559# ifdef FORTIFY
560 Fortify_EnterScope();
561# endif
562 pState = xmallocz(sizeof(tState), pszSrcFile, __LINE__);
563 if (!pState) {
564 WinDismissDlg(hwnd, 0);
565 break;
566 }
567 strcpy(pState->szDirName, (CHAR *)mp2);
568 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) pState);
569 pState->hptr = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, DIRSIZE_ICON);
570 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(pState->hptr), MPVOID);
571 {
572 CHAR s[CCHMAXPATH + 81];
573 RestorePresParams(hwnd, PCSZ_DIRSIZES);
574 sprintf(s, GetPString(IDS_DIRSIZETITLETEXT), pState->szDirName);
575 WinSetWindowText(hwnd, s);
576 }
577 {
578 SWP swp;
579 ULONG size = sizeof(SWP);
580
581 PrfQueryProfileData(fmprof, FM3Str, "DirSizes.Position", (PVOID) &swp, &size);
582 swp.fl &= ~SWP_SIZE; // 04 Feb 09 SHL ignore saved size
583 WinSetWindowPos(hwnd,
584 HWND_TOP,
585 swp.x,
586 swp.y,
587 swp.cx,
588 swp.cy,
589 swp.fl);
590 }
591 {
592 DIRSIZE *dirsize;
593
594 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
595 if (!dirsize) {
596 WinDismissDlg(hwnd, 0);
597 break;
598 }
599 dirsize->pchStopFlag = (CHAR *)&pState->chStopFlag;
600 dirsize->pszFileName = pState->szDirName;
601 dirsize->hwndCnr = WinWindowFromID(hwnd, DSZ_CNR);
602 if (xbeginthread(FillCnrThread,
603 122880 * 5,
604 dirsize,
605 pszSrcFile,
606 __LINE__) == -1)
607 {
608 xfree(dirsize, pszSrcFile, __LINE__);
609 WinDismissDlg(hwnd, 0);
610 break;
611 }
612 pState->working = TRUE;
613 WinEnableWindow(WinWindowFromID(hwnd, DSZ_COLLAPSE), FALSE);
614 WinEnableWindow(WinWindowFromID(hwnd, DSZ_EXPAND), FALSE);
615 WinEnableWindow(WinWindowFromID(hwnd, DSZ_PRINT), FALSE);
616 }
617 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
618 break;
619
620 case UM_SETUP:
621 {
622 CNRINFO cnri;
623 FSALLOCATE fsa;
624 APIRET rc;
625
626 memset(&cnri, 0, sizeof(CNRINFO));
627 cnri.cb = sizeof(CNRINFO);
628 WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_QUERYCNRINFO,
629 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
630 cnri.cyLineSpacing = 0;
631 cnri.cxTreeIndent = 12;
632 cnri.flWindowAttr = CV_TREE | CV_FLOW | CA_TREELINE | CA_OWNERDRAW;
633 WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
634 MPFROMLONG(CMA_FLWINDOWATTR | CMA_TREEICON |
635 CMA_LINESPACING | CMA_CXTREEINDENT));
636 pState = INSTDATA(hwnd);
637 if (pState && isalpha(*pState->szDirName)) {
638 memset(&fsa, 0, sizeof(fsa));
639 rc =
640 DosQueryFSInfo(toupper(*pState->szDirName) - '@', FSIL_ALLOC, &fsa,
641 sizeof(FSALLOCATE));
642 if (!rc) {
643
644 CHAR s[132], tf[80], tb[80], tu[80];
645
646 CommaFmtULL(tf, sizeof(tf),
647 (ULONGLONG) fsa.cUnitAvail *
648 (fsa.cSectorUnit * fsa.cbSector), 'M');
649 CommaFmtULL(tb, sizeof(tb),
650 (ULONGLONG) fsa.cUnit *
651 (fsa.cSectorUnit * fsa.cbSector), 'M');
652 CommaFmtULL(tu, sizeof(tu),
653 (ULONGLONG) (fsa.cUnit - fsa.cUnitAvail) *
654 (fsa.cSectorUnit * fsa.cbSector), 'M');
655 sprintf(s, GetPString(IDS_FREESPACETEXT), tf, tb, tu);
656 WinSetDlgItemText(hwnd, DSZ_FREESPACE, s);
657 }
658 else
659 WinSetDlgItemText(hwnd, DSZ_FREESPACE, (CHAR *) GetPString(IDS_FREESPACEUTEXT));
660 }
661 }
662 return 0;
663
664 case UM_CONTAINER_FILLED:
665 pState = INSTDATA(hwnd);
666 if (!pState || pState->dying) {
667 if (pState)
668 pState->working = FALSE;
669 WinDismissDlg(hwnd, 0);
670 return 0;
671 }
672 pState->working = FALSE;
673 WinEnableWindow(WinWindowFromID(hwnd, DSZ_COLLAPSE), TRUE);
674 WinEnableWindow(WinWindowFromID(hwnd, DSZ_EXPAND), TRUE);
675 WinEnableWindow(WinWindowFromID(hwnd, DSZ_PRINT), TRUE);
676
677 pci = WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_QUERYRECORD, MPVOID,
678 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
679 if (pci && (INT) pci != -1)
680 WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_EXPANDTREE, MPFROMP(pci), MPVOID);
681 *sz = 0;
682 pci = WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_QUERYRECORDEMPHASIS,
683 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
684 if (pci && (INT) pci != -1) {
685 commafmt(szBytes, sizeof(szBytes), pci->attrFile);
686 sprintf(sz,
687 "%s %s%s",
688 szBytes, GetPString(IDS_FILETEXT), &"s"[pci->attrFile == 1]);
689 }
690 WinSetDlgItemText(hwnd, DSZ_NUMFILES, sz);
691
692 WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_SORTRECORD, MPFROMP(SortSizeCnr),
693 MPVOID);
694 if (!fAlertBeepOff)
695 DosBeep(500, 25); // Wake up user
696 return 0;
697
698 case WM_ADJUSTWINDOWPOS:
699 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
700 break;
701
702 case UM_STRETCH:
703 {
704 SWP swpC, swp;
705
706 WinQueryWindowPos(hwnd, &swp);
707 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
708 WinQueryWindowPos(WinWindowFromID(hwnd, DSZ_CNR), &swpC);
709 WinSetWindowPos(WinWindowFromID(hwnd, DSZ_CNR), HWND_TOP,
710 SysVal(SV_CXSIZEBORDER),
711 swpC.y,
712 swp.cx - (SysVal(SV_CXSIZEBORDER) * 2),
713 (swp.cy - swpC.y) - (SysVal(SV_CYTITLEBAR) +
714 SysVal(SV_CYSIZEBORDER)),
715 SWP_MOVE | SWP_SIZE);
716 }
717 }
718 return 0;
719
720 case WM_PRESPARAMCHANGED:
721 PresParamChanged(hwnd, PCSZ_DIRSIZES, mp1, mp2);
722 break;
723
724 case WM_DRAWITEM:
725 if (mp2) {
726
727 OWNERITEM *oi = mp2;
728 CNRDRAWITEMINFO *cnd;
729 PCNRITEM pci;
730
731 if (oi->idItem == CMA_TEXT) {
732
733 cnd = (CNRDRAWITEMINFO *)oi->hItem;
734
735 if (cnd) {
736 pci = (PCNRITEM)cnd->pRecord;
737
738 if (pci) {
739 POINTL aptl[TXTBOX_COUNT];
740 POINTL ptl;
741 PSZ p;
742 LONG clr;
743 LONG x;
744 LONG yBottom;
745 INT boxHeight;
746 p = strchr(pci->pszDisplayName, '\r');
747 if (p) {
748 // draw text
749 if (pci->pszLongName == NullStr) // is root record
750 GpiSetColor(oi->hps, CLR_DARKRED);
751 else if (!pci->cbFile) // no size
752 GpiSetColor(oi->hps, CLR_DARKGRAY);
753 else if (!pci->easize) // no size below
754 GpiSetColor(oi->hps, CLR_DARKBLUE);
755 else
756 GpiSetColor(oi->hps, CLR_BLACK);
757 GpiSetBackMix(oi->hps, BM_LEAVEALONE);
758 GpiSetMix(oi->hps, FM_OVERPAINT);
759
760 *p = 0; // Make 1 line high
761
762 // Calculate nominal graph box height based on font size
763 GpiQueryTextBox(oi->hps, p - pci->pszDisplayName,
764 pci->pszDisplayName, TXTBOX_COUNT, aptl);
765 boxHeight = aptl[TXTBOX_TOPRIGHT].y - aptl[TXTBOX_BOTTOMRIGHT].y;
766 boxHeight -= 4;
767
768 // Calculate nominal baseline of graph box
769 // rclItem.yBottom is at center of icon because it is
770 yBottom = oi->rclItem.yBottom - boxHeight + 3;
771
772 // Place text above graph box with a bit of whitespace between
773 ptl.x = oi->rclItem.xLeft;
774 ptl.y = yBottom + boxHeight + 6;
775 GpiCharStringAt(oi->hps, &ptl, p - pci->pszDisplayName,
776 pci->pszDisplayName);
777
778 *p = '\r'; // Restore
779
780 // draw the graph box
781 // draw black outline
782 GpiSetColor(oi->hps, CLR_BLACK);
783 ptl.x = oi->rclItem.xLeft;
784 ptl.y = yBottom + 2;
785 GpiMove(oi->hps, &ptl);
786 ptl.x = oi->rclItem.xLeft + 201;
787 ptl.y = yBottom + boxHeight;
788 GpiBox(oi->hps, DRO_OUTLINE, &ptl, 0, 0);
789 // fill with gray
790 GpiSetColor(oi->hps, CLR_PALEGRAY);
791 ptl.x = oi->rclItem.xLeft + 1;
792 ptl.y = yBottom + 3;
793 GpiMove(oi->hps, &ptl);
794 ptl.x = oi->rclItem.xLeft + 200;
795 ptl.y = yBottom + boxHeight - 1;
796 GpiBox(oi->hps, DRO_OUTLINEFILL, &ptl, 0, 0);
797
798 // draw shadow at bottom & right sides
799 GpiSetColor(oi->hps, CLR_DARKGRAY);
800 ptl.x = oi->rclItem.xLeft + 1;
801 ptl.y = yBottom + 3;
802 GpiMove(oi->hps, &ptl);
803 ptl.x = oi->rclItem.xLeft + 200;
804 GpiLine(oi->hps, &ptl);
805 ptl.y = yBottom + boxHeight - 1;
806 GpiLine(oi->hps, &ptl);
807
808 // draw highlight at top and left sides
809 GpiSetColor(oi->hps, CLR_WHITE);
810 ptl.x = oi->rclItem.xLeft + 1;
811 GpiLine(oi->hps, &ptl);
812 ptl.y = yBottom + 3;
813 GpiLine(oi->hps, &ptl);
814
815 // draw shadow of box
816 GpiSetColor(oi->hps, CLR_DARKGRAY);
817 ptl.x = oi->rclItem.xLeft + 2;
818 ptl.y = yBottom + boxHeight;
819 GpiMove(oi->hps, &ptl);
820 ptl.x = oi->rclItem.xLeft + 201;
821 GpiLine(oi->hps, &ptl);
822 ptl.y = yBottom + boxHeight - 2;
823 GpiLine(oi->hps, &ptl);
824 ptl.x--;
825 GpiMove(oi->hps, &ptl);
826 ptl.y = yBottom + 1;
827 GpiLine(oi->hps, &ptl);
828 ptl.x = oi->rclItem.xLeft + 2;
829 GpiLine(oi->hps, &ptl);
830
831 // fill box with graph bar, flags is integer %
832 if (pci->flags) {
833 if (pci->pszLongName == NullStr) // is root record
834 GpiSetColor(oi->hps, CLR_DARKGREEN);
835 else
836 GpiSetColor(oi->hps, CLR_RED);
837 ptl.x = oi->rclItem.xLeft + 2;
838 ptl.y = yBottom + 3;
839 GpiMove(oi->hps, &ptl);
840 ptl.x = oi->rclItem.xLeft + pci->flags * 2;
841 ptl.y = yBottom + boxHeight - 1;
842 GpiBox(oi->hps, DRO_OUTLINEFILL, &ptl, 0, 0);
843
844 // draw highlights and shadows on graph
845 if (pci->pszLongName == NullStr)
846 GpiSetColor(oi->hps, CLR_GREEN);
847 else
848 GpiSetColor(oi->hps, CLR_PALEGRAY);
849 if (pci->flags > 5) {
850 ptl.x = oi->rclItem.xLeft + 1;
851 ptl.y = yBottom + 3;
852 GpiMove(oi->hps, &ptl);
853 ptl.y = yBottom + boxHeight - 1;
854 GpiLine(oi->hps, &ptl);
855 }
856 else {
857 ptl.y = yBottom + boxHeight - 1;
858 GpiMove(oi->hps, &ptl);
859 }
860 ptl.x = oi->rclItem.xLeft + pci->flags * 2;
861 GpiLine(oi->hps, &ptl);
862 if (pci->pszLongName == NULL) {
863 GpiSetColor(oi->hps, CLR_DARKRED);
864 ptl.x = oi->rclItem.xLeft + 2;
865 ptl.y = yBottom + 3;
866 GpiMove(oi->hps, &ptl);
867 ptl.x = oi->rclItem.xLeft + pci->flags * 2;
868 GpiLine(oi->hps, &ptl);
869 }
870 }
871
872 // draw hash marks in box
873 GpiSetColor(oi->hps, CLR_WHITE);
874 clr = CLR_WHITE;
875 for (x = 1; x < 20; x++) {
876 if (clr == CLR_WHITE && x * 10 > pci->flags * 2) {
877 clr = CLR_BLACK;
878 GpiSetColor(oi->hps, CLR_BLACK);
879 }
880 ptl.x = oi->rclItem.xLeft + 1 + x * 10;
881 ptl.y = yBottom + boxHeight - 1;
882 GpiMove(oi->hps, &ptl);
883 switch (x) {
884 case 1:
885 case 3:
886 case 5:
887 case 7:
888 case 9:
889 case 11:
890 case 13:
891 case 15:
892 case 17:
893 case 19:
894 ptl.y -= 1;
895 break;
896 case 10:
897 ptl.y -= 4;
898 break;
899 case 2:
900 case 4:
901 case 6:
902 case 8:
903 case 12:
904 case 14:
905 case 16:
906 case 18:
907 ptl.y -= 2;
908 break;
909 }
910 GpiLine(oi->hps, &ptl);
911 } // for x
912 return MRFROMLONG(TRUE);
913 }
914 }
915 }
916 }
917 }
918 return FALSE; // Let PM draw
919
920 case WM_CONTROL:
921 switch (SHORT2FROMMP(mp1)) {
922 case CN_ENTER:
923 if (mp2) {
924 PCNRITEM pci = (PCNRITEM)((PNOTIFYRECORDENTER)mp2)->pRecord;
925 CHAR szFileName[CCHMAXPATH]; // 23 Jul 07 SHL
926 CHAR szTemp[CCHMAXPATH];
927
928 if (pci) {
929 *szFileName = 0;
930 while (pci && (INT) pci != -1) {
931 memset(szTemp, 0, sizeof(szTemp));
932 strcpy(szTemp, pci->pszFileName);
933 strrev(szTemp);
934 AddBackslashToPath(szFileName);
935 strcat(szFileName, szTemp);
936 pci = WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_QUERYRECORD,
937 MPFROMP(pci),
938 MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER));
939 }
940 strrev(szFileName);
941 if (!fVTreeOpensWPS)
942 OpenDirCnr((HWND)0,
943 hwndMain ? hwndMain : HWND_DESKTOP,
944 hwnd,
945 FALSE,
946 szFileName);
947 else {
948
949 ULONG size = sizeof(ULONG);
950 ULONG flWindowAttr = CV_ICON;
951 CHAR s[33];
952
953 strcpy(s, PCSZ_ICON);
954 PrfQueryProfileData(fmprof, appname, "DirflWindowAttr",
955 (PVOID) &flWindowAttr, &size);
956 if (flWindowAttr & CV_DETAIL) {
957 if (IsRoot(szFileName))
958 strcpy(s, PCSZ_TREE);
959 else
960 strcpy(s, Details);
961 }
962 OpenObject(szFileName, s, hwnd);
963 }
964 }
965 }
966 break;
967 case CN_EMPHASIS:
968 pState = INSTDATA(hwnd);
969 if (pState && !pState->working && mp2) {
970
971 PNOTIFYRECORDEMPHASIS pre = mp2;
972
973 pci = (PCNRITEM) ((pre) ? pre->pRecord : NULL);
974 if (pci && (pre->fEmphasisMask & CRA_SELECTED) &&
975 (pci->rc.flRecordAttr & CRA_SELECTED)) {
976 commafmt(szBytes, sizeof(szBytes), pci->attrFile);
977 sprintf(sz,
978 "%s %s%s",
979 szBytes,
980 GetPString(IDS_FILETEXT), &"s"[pci->attrFile == 1]);
981 WinSetDlgItemText(hwnd, DSZ_NUMFILES, sz);
982 }
983 }
984 break;
985 }
986 return 0;
987
988 case WM_COMMAND:
989 switch (SHORT1FROMMP(mp1)) {
990 case IDM_HELP:
991 if (hwndHelp)
992 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
993 MPFROM2SHORT(HELP_DIRSIZE, 0), MPFROMSHORT(HM_RESOURCEID));
994 break;
995
996 case DSZ_PRINT:
997 // Save button
998 pState = INSTDATA(hwnd);
999 if (!pState)
1000 Runtime_Error(pszSrcFile, __LINE__, NULL);
1001 else {
1002
1003 CHAR szFileName[CCHMAXPATH];
1004 FILE *fp;
1005 CHAR *modea = "a+";
1006
1007 if (pTmpDir && !IsValidDir(pTmpDir))
1008 DosCreateDir(pTmpDir, 0);
1009 //if (pTmpDir)
1010 // strcpy(szFileName, pTmpDir);
1011 else if (!pTmpDir)
1012 strcpy(szFileName, pFM2SaveDirectory);
1013 sprintf(&szFileName[strlen(szFileName)], "%s%csizes.Rpt", PCSZ_BACKSLASH,
1014 (pState) ? toupper(*pState->szDirName) : '+');
1015 if (export_filename(hwnd, szFileName, FALSE) && *szFileName) {
1016 if (stricmp(szFileName, "PRN") &&
1017 strnicmp(szFileName, "\\DEV\\LPT", 8) &&
1018 !strchr(szFileName, '.'))
1019 strcat(szFileName, ".RPT");
1020 fp = xfopen(szFileName, modea, pszSrcFile, __LINE__, TRUE);
1021 if (!fp) {
1022 saymsg(MB_CANCEL,
1023 hwnd,
1024 GetPString(IDS_ERRORTEXT),
1025 GetPString(IDS_COMPCANTOPENTEXT), szFileName);
1026 }
1027 else {
1028 WinSetPointer(HWND_DESKTOP, hptrBusy);
1029 PrintToFile(WinWindowFromID(hwnd, DSZ_CNR), 0, NULL, fp);
1030 fclose(fp);
1031 WinSetPointer(HWND_DESKTOP, hptrArrow);
1032 }
1033 }
1034 }
1035 break;
1036
1037 case DSZ_EXPAND:
1038 case DSZ_COLLAPSE:
1039 pState = INSTDATA(hwnd);
1040 if (pState) {
1041 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, DSZ_CNR,
1042 CM_QUERYRECORDEMPHASIS,
1043 MPFROMLONG(CMA_FIRST),
1044 MPFROMSHORT(CRA_CURSORED));
1045 if (pci) {
1046 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
1047 WinEnableWindow(WinWindowFromID(hwnd, IDM_HELP), FALSE);
1048 WinEnableWindow(WinWindowFromID(hwnd, DSZ_COLLAPSE), FALSE);
1049 WinEnableWindow(WinWindowFromID(hwnd, DSZ_EXPAND), FALSE);
1050 WinEnableWindow(WinWindowFromID(hwnd, DSZ_PRINT), FALSE);
1051 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
1052 if (SHORT1FROMMP(mp1) == DSZ_EXPAND) {
1053 EXPANDSIZE *expandsize;
1054
1055 expandsize = xmalloc(sizeof(EXPANDSIZE), pszSrcFile, __LINE__);
1056 if (expandsize) {
1057
1058 expandsize->pci = pci;
1059 expandsize->hwndCnr = WinWindowFromID(hwnd, DSZ_CNR);
1060 if (xbeginthread(ExpandCnrThread,
1061 122880 * 5,
1062 expandsize,
1063 pszSrcFile,
1064 __LINE__) == -1)
1065 xfree(expandsize, pszSrcFile, __LINE__);
1066 }
1067 }
1068 else
1069 CollapseAll(WinWindowFromID(hwnd, DSZ_CNR), pci);
1070 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), TRUE);
1071 WinEnableWindow(WinWindowFromID(hwnd, IDM_HELP), TRUE);
1072 WinEnableWindow(WinWindowFromID(hwnd, DSZ_COLLAPSE), TRUE);
1073 WinEnableWindow(WinWindowFromID(hwnd, DSZ_EXPAND), TRUE);
1074 WinEnableWindow(WinWindowFromID(hwnd, DSZ_PRINT), TRUE);
1075 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), TRUE);
1076 }
1077 }
1078 break;
1079
1080 case DID_OK:
1081 case DID_CANCEL:
1082 {
1083 SWP swp;
1084 ULONG size = sizeof(SWP);
1085
1086 WinQueryWindowPos(hwnd, &swp);
1087 PrfWriteProfileData(fmprof, FM3Str, "DirSizes.Position", (PVOID) &swp, size);
1088 }
1089 pState = INSTDATA(hwnd);
1090 if (!pState)
1091 Runtime_Error(pszSrcFile, __LINE__, NULL);
1092 else {
1093 if (pState->working) {
1094 pState->dying = TRUE;
1095 pState->chStopFlag = (CHAR)0xff;
1096 if (!fAlertBeepOff)
1097 DosBeep(1000, 100); // Complain?
1098 }
1099 else
1100 WinDismissDlg(hwnd, 0);
1101 }
1102 break;
1103 } // switch mp1
1104 return 0;
1105
1106 case WM_CLOSE:
1107 pState = INSTDATA(hwnd);
1108 if (pState)
1109 pState->chStopFlag = (CHAR)0xff;
1110 DosSleep(1);
1111 break;
1112
1113 case WM_DESTROY:
1114 pState = INSTDATA(hwnd);
1115 EmptyCnr(hwnd);
1116 if (pState) {
1117 pState->chStopFlag = (CHAR)0xff;
1118 if (pState->hptr)
1119 WinDestroyPointer(pState->hptr);
1120 DosSleep(16);
1121 xfree(pState, pszSrcFile, __LINE__); // Let's hope no one is still looking
1122# ifdef FORTIFY
1123 Fortify_LeaveScope();
1124# endif
1125 }
1126 DosPostEventSem(CompactSem);
1127 break;
1128 }
1129 return WinDefDlgProc(hwnd, msg, mp1, mp2);
1130}
1131
1132#pragma alloc_text(DIRSIZE,ProcessDir,FillCnrThread,DirSizeProc)
1133#pragma alloc_text(DIRSIZE2,PrintToFile,FillInRecSizes,SortSizeCnr)
1134
Note: See TracBrowser for help on using the repository browser.