source: trunk/dll/dirsize.c@ 1067

Last change on this file since 1067 was 1067, checked in by Gregg Young, 17 years ago

Removed unnecessary strlens from WM_DRAWITEM; Streamlined FillInRecSizes; Removed spurious Fortify_Enterscope (perhaps fixing strlens trap); Minor cleanup of graph box appearence.

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