source: trunk/dll/objcnr.c@ 1063

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

Fortify ifdef reformat

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: objcnr.c 1063 2008-07-11 03:33:36Z gyoung $
5
6 Object containers
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2005, 2007 Steven H. Levine
10
11 24 May 05 SHL Rework for CNRITEM.szSubject
12 13 Jul 06 SHL Use Runtime_Error
13 01 Sep 06 SHL Do not complain for normal cancel
14 19 Oct 06 SHL Correct . and .. detect
15 03 Nov 06 SHL Renames
16 22 Mar 07 GKY Use QWL_USER
17 01 Aug 07 SHL Rework to sync with CNRITEM mods
18 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
19 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
20 13 Aug 07 SHL Avoid realloc - not needed; sanitize code
21 13 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
22 14 Aug 07 SHL Revert ProcessDir DosSleep to 0
23 29 Feb 08 GKY Use xfree where appropriate
24
25***********************************************************************/
26
27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
30#include <process.h> // _beginthread
31
32#define INCL_DOS
33#define INCL_WIN
34#define INCL_DOSERRORS
35#define INCL_LONGLONG
36
37#include "fm3dlg.h"
38#include "fm3str.h"
39#include "errutil.h" // Dos_Error...
40#include "strutil.h" // GetPString
41#include "fm3dll.h"
42
43#include "fortify.h"
44
45typedef struct
46{
47 CHAR *filename;
48 HWND hwndCnr;
49 CHAR *stopflag;
50}
51DIRSIZE;
52
53typedef struct
54{
55 CHAR *dirname;
56 CHAR stopflag;
57 BOOL dying;
58 BOOL working;
59}
60TEMP;
61
62#pragma data_seg(DATA1)
63
64static PSZ pszSrcFile = __FILE__;
65
66static HWND objcnrwnd;
67
68static VOID ProcessDir(HWND hwndCnr,
69 CHAR *filename,
70 PCNRITEM pciParent,
71 CHAR *stopflag)
72{
73 CHAR maskstr[CCHMAXPATH], *endpath, *p;
74 ULONG ulFindCnt, ulFindMax;
75 ULONG ulBufBytes;
76 HDIR hdir;
77 PFILEFINDBUF3L pffbArray;
78 APIRET rc;
79 RECORDINSERT ri;
80 PCNRITEM pciP;
81 HPOINTER hptr;
82
83 ulBufBytes = sizeof(FILEFINDBUF3L) * FilesToGet;
84 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
85 if (!pffbArray)
86 return; // Error already reported
87 strcpy(maskstr, filename);
88 if (maskstr[strlen(maskstr) - 1] != '\\')
89 strcat(maskstr, "\\");
90 endpath = &maskstr[strlen(maskstr)];
91 strcat(maskstr, "*");
92 hdir = HDIR_CREATE;
93 ulFindCnt = 1;
94 rc = xDosFindFirst(filename, &hdir,
95 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
96 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
97 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
98 if (!rc)
99 DosFindClose(hdir);
100 // work around furshluginer FAT root bug
101 else if (IsRoot(filename))
102 rc = 0;
103
104 if ((!rc && (pffbArray->attrFile & FILE_DIRECTORY))) {
105 pciP = WinSendMsg(hwndCnr,
106 CM_ALLOCRECORD,
107 MPFROMLONG(EXTRA_RECORD_BYTES),
108 MPFROMLONG(1));
109 if (!pciP) {
110 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, "CM_ALLOCRECORD");
111 free(pffbArray);
112 return;
113 }
114 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
115 pciP->pszDispAttr = NullStr;
116 pciP->pszSubject = NullStr;
117 pciP->pszLongName = NullStr;
118 if (strlen(filename) < 4)
119 pciP->pszDisplayName = pciP->pszFileName;
120 else {
121 p = strrchr(pciP->pszFileName, '\\');
122 if (!p)
123 pciP->pszDisplayName = pciP->pszFileName;
124 else if (*(p + 1))
125 p++;
126 pciP->pszDisplayName = p;
127 }
128 pciP->rc.pszIcon = pciP->pszDisplayName;
129 if (fForceUpper)
130 strupr(pciP->pszFileName);
131 else if (fForceLower)
132 strlwr(pciP->pszFileName);
133 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
134 }
135 else {
136 free(pffbArray);
137 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
138 GetPString(IDS_CANTFINDDIRTEXT), filename);
139 return;
140 }
141
142 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
143 if (hptr)
144 pciP->rc.hptrIcon = hptr;
145
146 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) /* OS/2 bug bug bug bug */
147 pciP->rc.hptrIcon = hptrDir;
148
149 memset(&ri, 0, sizeof(RECORDINSERT));
150 ri.cb = sizeof(RECORDINSERT);
151 ri.pRecordOrder = (PRECORDCORE) CMA_END;
152 ri.pRecordParent = (PRECORDCORE) pciParent;
153 ri.zOrder = (USHORT) CMA_TOP;
154 ri.cRecordsInsert = 1;
155 ri.fInvalidateRecord = TRUE;
156 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
157 free(pffbArray);
158 return;
159 }
160 hdir = HDIR_CREATE;
161 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
162 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
163 ulFindMax = 1;
164 else
165 ulFindMax = FilesToGet;
166 ulFindCnt = ulFindMax;
167 rc = xDosFindFirst(maskstr, &hdir,
168 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
169 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
170 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
171 if (!rc) {
172 PFILEFINDBUF3L pffbFile;
173 ULONG x;
174
175 while (!rc) {
176 pffbFile = pffbArray;
177 for (x = 0; x < ulFindCnt; x++) {
178 if (*stopflag)
179 break;
180 if ((pffbFile->attrFile & FILE_DIRECTORY) &&
181 // Skip . and ..
182 (pffbFile->achName[0] != '.' ||
183 (pffbFile->achName[1] &&
184 (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
185 strcpy(endpath, pffbFile->achName);
186 ProcessDir(hwndCnr, maskstr, pciP, stopflag);
187 }
188 if (!pffbFile->oNextEntryOffset)
189 break;
190 pffbFile = (PFILEFINDBUF3L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
191 } // for
192 DosSleep(0); // Let's others at same priority get some work done
193 if (*stopflag)
194 break;
195 ulFindCnt = ulFindMax;
196 rc = xDosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
197 } // while
198 DosFindClose(hdir);
199 }
200
201 if (rc && rc != ERROR_NO_MORE_FILES) {
202 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
203 GetPString(IDS_CANTFINDDIRTEXT), filename);
204 }
205
206 free(pffbArray);
207 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
208 MPFROM2SHORT(1, 0));
209}
210
211static VOID FillCnrsThread(VOID * args)
212{
213 HAB hab;
214 HMQ hmq;
215 DIRSIZE *dirsize = (DIRSIZE *)args;
216
217# ifdef FORTIFY
218 Fortify_EnterScope();
219# endif
220 if (!dirsize) {
221 Runtime_Error(pszSrcFile, __LINE__, "no data");
222 return;
223 }
224
225 DosError(FERR_DISABLEHARDERR);
226
227 hab = WinInitialize(0);
228 if (hab) {
229 hmq = WinCreateMsgQueue(hab, 0);
230 if (hmq) {
231 WinCancelShutdown(hmq, TRUE);
232 ProcessDir(dirsize->hwndCnr, dirsize->filename, (PCNRITEM) NULL,
233 dirsize->stopflag);
234 DosPostEventSem(CompactSem);
235 WinDestroyMsgQueue(hmq);
236 }
237 WinTerminate(hab);
238 }
239 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
240 MPVOID, MPVOID);
241 free(dirsize);
242# ifdef FORTIFY
243 Fortify_LeaveScope();
244# endif
245}
246
247MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
248{
249 TEMP *data;
250
251 switch (msg) {
252 case WM_INITDLG:
253 if (objcnrwnd) {
254 Runtime_Error(pszSrcFile, __LINE__, "objcnrwnd set");
255 WinSetWindowPos(objcnrwnd, HWND_TOP, 0, 0, 0, 0,
256 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
257 WinDismissDlg(hwnd, 0);
258 break;
259 }
260 if (!mp2) {
261 Runtime_Error(pszSrcFile, __LINE__, "mp2 NULL");
262 WinDismissDlg(hwnd, 0);
263 break;
264 }
265 objcnrwnd = hwnd;
266 data = xmallocz(sizeof(TEMP), pszSrcFile, __LINE__);
267 if (!data) {
268 WinDismissDlg(hwnd, 0);
269 break;
270 }
271 data->dirname = (CHAR *)mp2;
272 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
273 if (*data->dirname)
274 WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
275 {
276 DIRSIZE *dirsize;
277# ifdef FORTIFY
278 Fortify_EnterScope();
279# endif
280 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
281 if (!dirsize) {
282 WinDismissDlg(hwnd, 0);
283 break;
284 }
285 dirsize->stopflag = (CHAR *)&data->stopflag;
286 dirsize->filename = data->dirname;
287 dirsize->hwndCnr = WinWindowFromID(hwnd, OBJCNR_CNR);
288 if (_beginthread(FillCnrsThread, NULL, 65536 * 8, (PVOID) dirsize) ==
289 -1) {
290 Runtime_Error(pszSrcFile, __LINE__,
291 GetPString(IDS_COULDNTSTARTTHREADTEXT));
292 free(dirsize);
293# ifdef FORTIFY
294 Fortify_LeaveScope();
295# endif
296 WinDismissDlg(hwnd, 0);
297 break;
298 }
299 else
300 data->working = TRUE;
301 }
302 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
303 break;
304
305 case UM_SETUP:
306 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
307 {
308 CNRINFO cnri;
309
310 memset(&cnri, 0, sizeof(CNRINFO));
311 cnri.cb = sizeof(CNRINFO);
312 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_QUERYCNRINFO,
313 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
314 cnri.cyLineSpacing = 0;
315 cnri.cxTreeIndent = 12L;
316 cnri.pszCnrTitle = GetPString(IDS_WORKINGTEXT);
317 cnri.flWindowAttr = CV_TREE | CV_FLOW |
318 CA_CONTAINERTITLE | CA_TITLESEPARATOR | CA_TREELINE;
319 if (WinQueryWindowUShort(hwnd, QWS_ID) == QTREE_FRAME)
320 cnri.flWindowAttr |= CV_MINI;
321 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
322 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
323 CMA_CXTREEINDENT));
324 }
325 return 0;
326
327 case UM_CONTAINER_FILLED:
328 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
329// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
330 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_INVALIDATERECORD, MPVOID,
331 MPFROM2SHORT(0, CMA_ERASE | CMA_INVALIDATE));
332 data = INSTDATA(hwnd);
333 if (data) {
334 data->working = FALSE;
335 if (data->dying)
336 WinDismissDlg(hwnd, 0);
337 {
338 PCNRITEM pci;
339 USHORT id;
340
341 id = WinQueryWindowUShort(hwnd, QWS_ID);
342 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
343 CM_QUERYRECORD,
344 MPVOID,
345 MPFROM2SHORT(CMA_FIRST,
346 CMA_ITEMORDER));
347 if (pci && (INT) pci != -1) {
348 ExpandAll(WinWindowFromID(hwnd, OBJCNR_CNR), TRUE, pci);
349 if (id == QTREE_FRAME)
350 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
351 CM_QUERYRECORD,
352 MPFROMP(pci),
353 MPFROM2SHORT(CMA_FIRSTCHILD,
354 CMA_ITEMORDER));
355 }
356 if ((!pci || (INT) pci == -1) && id == QTREE_FRAME) {
357 Notify(GetPString(IDS_NODIRSUNDERTEXT));
358 WinDismissDlg(hwnd, 0);
359 break;
360 }
361 }
362 }
363 return 0;
364
365 case WM_CONTROL:
366 switch (SHORT1FROMMP(mp1)) {
367 case OBJCNR_CNR:
368 if (SHORT2FROMMP(mp1) == CN_ENTER) {
369
370 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
371
372 if (pci && (INT) pci != -1)
373 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
374 }
375 break;
376 }
377 return 0;
378
379 case WM_COMMAND:
380 switch (SHORT1FROMMP(mp1)) {
381 case IDM_HELP:
382 if (hwndHelp) {
383
384 USHORT id;
385
386 id = WinQueryWindowUShort(hwnd, QWS_ID);
387
388 if (id == QTREE_FRAME)
389 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
390 MPFROM2SHORT(HELP_QUICKTREE, 0),
391 MPFROMSHORT(HM_RESOURCEID));
392 else
393 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
394 MPFROM2SHORT(HELP_OBJECTPATH, 0),
395 MPFROMSHORT(HM_RESOURCEID));
396 }
397 break;
398
399 case OBJCNR_DESKTOP:
400 case DID_OK:
401 data = INSTDATA(hwnd);
402 if (data) {
403
404 PCNRITEM pci;
405
406 if (data->working) {
407 Runtime_Error(pszSrcFile, __LINE__, "working unexpected");
408 break;
409 }
410 if (SHORT1FROMMP(mp1) == OBJCNR_DESKTOP) {
411 WinDismissDlg(hwnd, 2);
412 break;
413 }
414 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
415 CM_QUERYRECORDEMPHASIS,
416 MPFROMLONG(CMA_FIRST),
417 MPFROMSHORT(CRA_CURSORED));
418 if (pci && (INT) pci != -1)
419 strcpy(data->dirname, pci->pszFileName);
420 WinDismissDlg(hwnd, 1);
421 }
422 break;
423
424 case DID_CANCEL:
425 data = INSTDATA(hwnd);
426 if (data) {
427 if (data->working) {
428 data->dying = (CHAR)TRUE;
429 data->stopflag = (CHAR)0xff;
430 break;
431 }
432 WinDismissDlg(hwnd, 0);
433 }
434 break;
435 }
436 return 0;
437
438 case WM_DESTROY:
439 objcnrwnd = (HWND) 0;
440 data = INSTDATA(hwnd);
441 xfree(data, pszSrcFile, __LINE__);
442 break;
443 }
444 return WinDefDlgProc(hwnd, msg, mp1, mp2);
445}
446
447#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.