source: trunk/dll/objcnr.c@ 1163

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

Ticket 187: Draft 1: Functions only

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