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
RevLine 
[159]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
[574]9 Copyright (c) 2005, 2007 Steven H. Levine
[159]10
11 24 May 05 SHL Rework for CNRITEM.szSubject
[349]12 13 Jul 06 SHL Use Runtime_Error
[488]13 01 Sep 06 SHL Do not complain for normal cancel
[517]14 19 Oct 06 SHL Correct . and .. detect
[531]15 03 Nov 06 SHL Renames
[574]16 22 Mar 07 GKY Use QWL_USER
[751]17 01 Aug 07 SHL Rework to sync with CNRITEM mods
[756]18 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
[775]19 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[783]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
[787]22 14 Aug 07 SHL Revert ProcessDir DosSleep to 0
[985]23 29 Feb 08 GKY Use xfree where appropriate
[159]24
25***********************************************************************/
26
[907]27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
30#include <process.h> // _beginthread
31
[2]32#define INCL_DOS
33#define INCL_WIN
[783]34#define INCL_DOSERRORS
[841]35#define INCL_LONGLONG
[2]36
37#include "fm3dlg.h"
38#include "fm3str.h"
[907]39#include "errutil.h" // Dos_Error...
40#include "strutil.h" // GetPString
41#include "fm3dll.h"
[2]42
[1017]43#include "fortify.h"
44
[551]45typedef struct
46{
[2]47 CHAR *filename;
[551]48 HWND hwndCnr;
[2]49 CHAR *stopflag;
[551]50}
51DIRSIZE;
[2]52
[551]53typedef struct
54{
[2]55 CHAR *dirname;
[551]56 CHAR stopflag;
57 BOOL dying;
58 BOOL working;
59}
60TEMP;
[2]61
[349]62#pragma data_seg(DATA1)
[2]63
[349]64static PSZ pszSrcFile = __FILE__;
[2]65
[349]66static HWND objcnrwnd;
[2]67
[783]68static VOID ProcessDir(HWND hwndCnr,
69 CHAR *filename,
70 PCNRITEM pciParent,
71 CHAR *stopflag)
[349]72{
[551]73 CHAR maskstr[CCHMAXPATH], *endpath, *p;
[783]74 ULONG ulFindCnt, ulFindMax;
75 ULONG ulBufBytes;
[551]76 HDIR hdir;
[841]77 PFILEFINDBUF3L pffbArray;
[551]78 APIRET rc;
79 RECORDINSERT ri;
80 PCNRITEM pciP;
[783]81 HPOINTER hptr;
[2]82
[841]83 ulBufBytes = sizeof(FILEFINDBUF3L) * FilesToGet;
[783]84 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
85 if (!pffbArray)
86 return; // Error already reported
[551]87 strcpy(maskstr, filename);
88 if (maskstr[strlen(maskstr) - 1] != '\\')
89 strcat(maskstr, "\\");
[2]90 endpath = &maskstr[strlen(maskstr)];
[551]91 strcat(maskstr, "*");
[2]92 hdir = HDIR_CREATE;
[783]93 ulFindCnt = 1;
[838]94 rc = xDosFindFirst(filename, &hdir,
95 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
96 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
[841]97 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[551]98 if (!rc)
[2]99 DosFindClose(hdir);
[783]100 // work around furshluginer FAT root bug
101 else if (IsRoot(filename))
102 rc = 0;
[2]103
[783]104 if ((!rc && (pffbArray->attrFile & FILE_DIRECTORY))) {
[731]105 pciP = WinSendMsg(hwndCnr,
106 CM_ALLOCRECORD,
[751]107 MPFROMLONG(EXTRA_RECORD_BYTES),
[761]108 MPFROMLONG(1));
[551]109 if (!pciP) {
[783]110 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, "CM_ALLOCRECORD");
[1009]111 xfree(pffbArray, pszSrcFile, __LINE__);
[2]112 return;
113 }
[730]114 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
[751]115 pciP->pszDispAttr = NullStr;
116 pciP->pszSubject = NullStr;
[762]117 pciP->pszLongName = NullStr;
[551]118 if (strlen(filename) < 4)
[751]119 pciP->pszDisplayName = pciP->pszFileName;
[2]120 else {
[730]121 p = strrchr(pciP->pszFileName, '\\');
[551]122 if (!p)
[756]123 pciP->pszDisplayName = pciP->pszFileName;
[551]124 else if (*(p + 1))
125 p++;
[751]126 pciP->pszDisplayName = p;
[2]127 }
[751]128 pciP->rc.pszIcon = pciP->pszDisplayName;
[551]129 if (fForceUpper)
[730]130 strupr(pciP->pszFileName);
[551]131 else if (fForceLower)
[730]132 strlwr(pciP->pszFileName);
[2]133 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
134 }
135 else {
[1009]136 xfree(pffbArray, pszSrcFile, __LINE__);
[783]137 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
138 GetPString(IDS_CANTFINDDIRTEXT), filename);
[2]139 return;
140 }
141
[783]142 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
143 if (hptr)
144 pciP->rc.hptrIcon = hptr;
145
[551]146 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) /* OS/2 bug bug bug bug */
[2]147 pciP->rc.hptrIcon = hptrDir;
[783]148
[551]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;
[771]154 ri.cRecordsInsert = 1;
[551]155 ri.fInvalidateRecord = TRUE;
156 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
[1009]157 xfree(pffbArray, pszSrcFile, __LINE__);
[2]158 return;
159 }
160 hdir = HDIR_CREATE;
[551]161 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
162 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
[783]163 ulFindMax = 1;
[2]164 else
[783]165 ulFindMax = FilesToGet;
166 ulFindCnt = ulFindMax;
[838]167 rc = xDosFindFirst(maskstr, &hdir,
168 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
169 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
[841]170 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[551]171 if (!rc) {
[841]172 PFILEFINDBUF3L pffbFile;
[551]173 ULONG x;
[2]174
[551]175 while (!rc) {
[783]176 pffbFile = pffbArray;
177 for (x = 0; x < ulFindCnt; x++) {
[551]178 if (*stopflag)
179 break;
180 if ((pffbFile->attrFile & FILE_DIRECTORY) &&
[517]181 // Skip . and ..
[551]182 (pffbFile->achName[0] != '.' ||
[517]183 (pffbFile->achName[1] &&
[551]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;
[841]190 pffbFile = (PFILEFINDBUF3L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
[783]191 } // for
[787]192 DosSleep(0); // Let's others at same priority get some work done
[551]193 if (*stopflag)
194 break;
[783]195 ulFindCnt = ulFindMax;
[850]196 rc = xDosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[783]197 } // while
[2]198 DosFindClose(hdir);
199 }
[783]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
[1009]206 xfree(pffbArray, pszSrcFile, __LINE__);
[551]207 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
208 MPFROM2SHORT(1, 0));
[2]209}
210
[551]211static VOID FillCnrsThread(VOID * args)
[349]212{
[551]213 HAB hab;
214 HMQ hmq;
[783]215 DIRSIZE *dirsize = (DIRSIZE *)args;
[2]216
[783]217 if (!dirsize) {
218 Runtime_Error(pszSrcFile, __LINE__, "no data");
[2]219 return;
[783]220 }
[2]221
222 DosError(FERR_DISABLEHARDERR);
223
224 hab = WinInitialize(0);
[551]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);
[2]231 DosPostEventSem(CompactSem);
232 WinDestroyMsgQueue(hmq);
233 }
234 WinTerminate(hab);
235 }
[551]236 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
237 MPVOID, MPVOID);
[1009]238 xfree(dirsize, pszSrcFile, __LINE__);
[1017]239# ifdef FORTIFY
240 Fortify_LeaveScope();
241# endif
[2]242}
243
[551]244MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[349]245{
[2]246 TEMP *data;
247
[551]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 }
[1009]268 data->dirname = (CHAR *)mp2;
[574]269 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
[551]270 if (*data->dirname)
271 WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
272 {
273 DIRSIZE *dirsize;
[1017]274# ifdef FORTIFY
275 Fortify_EnterScope();
276# endif
[551]277 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
278 if (!dirsize) {
279 WinDismissDlg(hwnd, 0);
280 break;
[2]281 }
[1009]282 dirsize->stopflag = (CHAR *)&data->stopflag;
[551]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));
[1017]289 xfree(dirsize, pszSrcFile, __LINE__);
290# ifdef FORTIFY
291 Fortify_LeaveScope();
292# endif
[551]293 WinDismissDlg(hwnd, 0);
294 break;
[349]295 }
[551]296 else
297 data->working = TRUE;
298 }
299 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
300 break;
[2]301
[551]302 case UM_SETUP:
303 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
304 {
305 CNRINFO cnri;
[2]306
[551]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;
[2]323
[551]324 case UM_CONTAINER_FILLED:
325 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
[2]326// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
[551]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;
[2]337
[551]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 }
[2]358 }
[551]359 }
360 return 0;
[2]361
[551]362 case WM_CONTROL:
363 switch (SHORT1FROMMP(mp1)) {
364 case OBJCNR_CNR:
365 if (SHORT2FROMMP(mp1) == CN_ENTER) {
[2]366
[551]367 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
[2]368
[551]369 if (pci && (INT) pci != -1)
370 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
[2]371 }
[551]372 break;
373 }
374 return 0;
[2]375
[551]376 case WM_COMMAND:
377 switch (SHORT1FROMMP(mp1)) {
378 case IDM_HELP:
379 if (hwndHelp) {
[2]380
[551]381 USHORT id;
[2]382
[551]383 id = WinQueryWindowUShort(hwnd, QWS_ID);
[2]384
[551]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;
[2]395
[551]396 case OBJCNR_DESKTOP:
397 case DID_OK:
398 data = INSTDATA(hwnd);
399 if (data) {
[2]400
[551]401 PCNRITEM pci;
[2]402
[551]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)
[730]416 strcpy(data->dirname, pci->pszFileName);
[551]417 WinDismissDlg(hwnd, 1);
[2]418 }
[551]419 break;
[2]420
[551]421 case DID_CANCEL:
[2]422 data = INSTDATA(hwnd);
[551]423 if (data) {
424 if (data->working) {
[689]425 data->dying = (CHAR)TRUE;
426 data->stopflag = (CHAR)0xff;
[551]427 break;
428 }
429 WinDismissDlg(hwnd, 0);
430 }
[2]431 break;
[551]432 }
433 return 0;
434
435 case WM_DESTROY:
436 objcnrwnd = (HWND) 0;
437 data = INSTDATA(hwnd);
[1009]438 xfree(data, pszSrcFile, __LINE__);
[551]439 break;
[2]440 }
[551]441 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]442}
[783]443
444#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.