source: trunk/dll/objcnr.c@ 1438

Last change on this file since 1438 was 1438, checked in by Gregg Young, 16 years ago

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

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