source: trunk/dll/objcnr.c@ 1009

Last change on this file since 1009 was 1009, checked in by Steven Levine, 17 years ago

Add xfree xstrdup Fortify support
Add MT capable Fortify scope logic

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