source: trunk/dll/dirsize.c@ 959

Last change on this file since 959 was 959, checked in by Gregg Young, 18 years ago

Use xfree where appropriate. Check that buffer exists following all xmallocs. Stopped at eas.c with xfree checking. One remaining xmalloc without test in dirsize.c

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