source: trunk/dll/objcnr.c@ 1188

Last change on this file since 1188 was 1188, checked in by John Small, 17 years ago

Ticket 187: Draft 2: Move remaining function declarations

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