source: trunk/dll/objcnr.c@ 1036

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

fortify updates for threads dble free fix

  • 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 1017 2008-05-26 03:02:59Z 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 xfree(pffbArray, pszSrcFile, __LINE__);
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 xfree(pffbArray, pszSrcFile, __LINE__);
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 xfree(pffbArray, pszSrcFile, __LINE__);
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 xfree(pffbArray, pszSrcFile, __LINE__);
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 if (!dirsize) {
218 Runtime_Error(pszSrcFile, __LINE__, "no data");
219 return;
220 }
221
222 DosError(FERR_DISABLEHARDERR);
223
224 hab = WinInitialize(0);
225 if (hab) {
226 hmq = WinCreateMsgQueue(hab, 0);
227 if (hmq) {
228 WinCancelShutdown(hmq, TRUE);
229 ProcessDir(dirsize->hwndCnr, dirsize->filename, (PCNRITEM) NULL,
230 dirsize->stopflag);
231 DosPostEventSem(CompactSem);
232 WinDestroyMsgQueue(hmq);
233 }
234 WinTerminate(hab);
235 }
236 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
237 MPVOID, MPVOID);
238 xfree(dirsize, pszSrcFile, __LINE__);
239# ifdef FORTIFY
240 Fortify_LeaveScope();
241# endif
242}
243
244MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
245{
246 TEMP *data;
247
248 switch (msg) {
249 case WM_INITDLG:
250 if (objcnrwnd) {
251 Runtime_Error(pszSrcFile, __LINE__, "objcnrwnd set");
252 WinSetWindowPos(objcnrwnd, HWND_TOP, 0, 0, 0, 0,
253 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
254 WinDismissDlg(hwnd, 0);
255 break;
256 }
257 if (!mp2) {
258 Runtime_Error(pszSrcFile, __LINE__, "mp2 NULL");
259 WinDismissDlg(hwnd, 0);
260 break;
261 }
262 objcnrwnd = hwnd;
263 data = xmallocz(sizeof(TEMP), pszSrcFile, __LINE__);
264 if (!data) {
265 WinDismissDlg(hwnd, 0);
266 break;
267 }
268 data->dirname = (CHAR *)mp2;
269 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
270 if (*data->dirname)
271 WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
272 {
273 DIRSIZE *dirsize;
274# ifdef FORTIFY
275 Fortify_EnterScope();
276# endif
277 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
278 if (!dirsize) {
279 WinDismissDlg(hwnd, 0);
280 break;
281 }
282 dirsize->stopflag = (CHAR *)&data->stopflag;
283 dirsize->filename = data->dirname;
284 dirsize->hwndCnr = WinWindowFromID(hwnd, OBJCNR_CNR);
285 if (_beginthread(FillCnrsThread, NULL, 65536 * 8, (PVOID) dirsize) ==
286 -1) {
287 Runtime_Error(pszSrcFile, __LINE__,
288 GetPString(IDS_COULDNTSTARTTHREADTEXT));
289 xfree(dirsize, pszSrcFile, __LINE__);
290# ifdef FORTIFY
291 Fortify_LeaveScope();
292# endif
293 WinDismissDlg(hwnd, 0);
294 break;
295 }
296 else
297 data->working = TRUE;
298 }
299 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
300 break;
301
302 case UM_SETUP:
303 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
304 {
305 CNRINFO cnri;
306
307 memset(&cnri, 0, sizeof(CNRINFO));
308 cnri.cb = sizeof(CNRINFO);
309 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_QUERYCNRINFO,
310 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
311 cnri.cyLineSpacing = 0;
312 cnri.cxTreeIndent = 12L;
313 cnri.pszCnrTitle = GetPString(IDS_WORKINGTEXT);
314 cnri.flWindowAttr = CV_TREE | CV_FLOW |
315 CA_CONTAINERTITLE | CA_TITLESEPARATOR | CA_TREELINE;
316 if (WinQueryWindowUShort(hwnd, QWS_ID) == QTREE_FRAME)
317 cnri.flWindowAttr |= CV_MINI;
318 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
319 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
320 CMA_CXTREEINDENT));
321 }
322 return 0;
323
324 case UM_CONTAINER_FILLED:
325 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
326// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
327 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_INVALIDATERECORD, MPVOID,
328 MPFROM2SHORT(0, CMA_ERASE | CMA_INVALIDATE));
329 data = INSTDATA(hwnd);
330 if (data) {
331 data->working = FALSE;
332 if (data->dying)
333 WinDismissDlg(hwnd, 0);
334 {
335 PCNRITEM pci;
336 USHORT id;
337
338 id = WinQueryWindowUShort(hwnd, QWS_ID);
339 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
340 CM_QUERYRECORD,
341 MPVOID,
342 MPFROM2SHORT(CMA_FIRST,
343 CMA_ITEMORDER));
344 if (pci && (INT) pci != -1) {
345 ExpandAll(WinWindowFromID(hwnd, OBJCNR_CNR), TRUE, pci);
346 if (id == QTREE_FRAME)
347 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
348 CM_QUERYRECORD,
349 MPFROMP(pci),
350 MPFROM2SHORT(CMA_FIRSTCHILD,
351 CMA_ITEMORDER));
352 }
353 if ((!pci || (INT) pci == -1) && id == QTREE_FRAME) {
354 Notify(GetPString(IDS_NODIRSUNDERTEXT));
355 WinDismissDlg(hwnd, 0);
356 break;
357 }
358 }
359 }
360 return 0;
361
362 case WM_CONTROL:
363 switch (SHORT1FROMMP(mp1)) {
364 case OBJCNR_CNR:
365 if (SHORT2FROMMP(mp1) == CN_ENTER) {
366
367 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
368
369 if (pci && (INT) pci != -1)
370 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
371 }
372 break;
373 }
374 return 0;
375
376 case WM_COMMAND:
377 switch (SHORT1FROMMP(mp1)) {
378 case IDM_HELP:
379 if (hwndHelp) {
380
381 USHORT id;
382
383 id = WinQueryWindowUShort(hwnd, QWS_ID);
384
385 if (id == QTREE_FRAME)
386 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
387 MPFROM2SHORT(HELP_QUICKTREE, 0),
388 MPFROMSHORT(HM_RESOURCEID));
389 else
390 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
391 MPFROM2SHORT(HELP_OBJECTPATH, 0),
392 MPFROMSHORT(HM_RESOURCEID));
393 }
394 break;
395
396 case OBJCNR_DESKTOP:
397 case DID_OK:
398 data = INSTDATA(hwnd);
399 if (data) {
400
401 PCNRITEM pci;
402
403 if (data->working) {
404 Runtime_Error(pszSrcFile, __LINE__, "working unexpected");
405 break;
406 }
407 if (SHORT1FROMMP(mp1) == OBJCNR_DESKTOP) {
408 WinDismissDlg(hwnd, 2);
409 break;
410 }
411 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
412 CM_QUERYRECORDEMPHASIS,
413 MPFROMLONG(CMA_FIRST),
414 MPFROMSHORT(CRA_CURSORED));
415 if (pci && (INT) pci != -1)
416 strcpy(data->dirname, pci->pszFileName);
417 WinDismissDlg(hwnd, 1);
418 }
419 break;
420
421 case DID_CANCEL:
422 data = INSTDATA(hwnd);
423 if (data) {
424 if (data->working) {
425 data->dying = (CHAR)TRUE;
426 data->stopflag = (CHAR)0xff;
427 break;
428 }
429 WinDismissDlg(hwnd, 0);
430 }
431 break;
432 }
433 return 0;
434
435 case WM_DESTROY:
436 objcnrwnd = (HWND) 0;
437 data = INSTDATA(hwnd);
438 xfree(data, pszSrcFile, __LINE__);
439 break;
440 }
441 return WinDefDlgProc(hwnd, msg, mp1, mp2);
442}
443
444#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.