source: trunk/dll/dirsize.c@ 1082

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

Changes so FM2 will use TMP/TEMP directory for all temp files; Replaced save_dir2 with global variable so BldFullPathName could easily replace code that performed the same function; Added #ifdef FORTIFY to free_ function that are only used when fortified.

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