source: trunk/dll/objcnr.c@ 1673

Last change on this file since 1673 was 1673, checked in by Gregg Young, 13 years ago

Update to Doxygen comment style Ticket 55. Also some minor code cleanup.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1
2/***********************************************************************
3
4 $Id: objcnr.c 1673 2012-12-30 18:51:01Z gyoung $
5
6 Object containers
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2005, 2009 Steven H. Levine
10
11 24 May 05 SHL Rework for CNRITEM.szSubject
12 13 Jul 06 SHL Use Runtime_Error
13 01 Sep 06 SHL Do not complain for normal cancel
14 19 Oct 06 SHL Correct . and .. detect
15 03 Nov 06 SHL Renames
16 22 Mar 07 GKY Use QWL_USER
17 01 Aug 07 SHL Rework to sync with CNRITEM mods
18 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
19 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
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
22 14 Aug 07 SHL Revert ProcessDir DosSleep to 0
23 29 Feb 08 GKY Use xfree where appropriate
24 10 Dec 08 SHL Integrate exception handler support
25 08 Mar 09 GKY Additional strings move to PCSZs
26 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
27
28***********************************************************************/
29
30#include <stdlib.h>
31#include <string.h>
32#include <ctype.h>
33// #include <process.h> // _beginthread
34
35#define INCL_DOS
36#define INCL_WIN
37#define INCL_DOSERRORS
38#define INCL_LONGLONG
39
40#include "fm3dll.h"
41#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
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
47#include "fm3dlg.h"
48#include "fm3str.h"
49#include "errutil.h" // Dos_Error...
50#include "strutil.h" // GetPString
51#include "objcnr.h"
52#include "notify.h" // Notify
53#include "wrappers.h" // xDosFindNext
54#include "select.h" // ExpandAll
55#include "valid.h" // IsRoot
56#include "misc.h" // PostMsg
57#include "fortify.h"
58#include "excputil.h" // xbeginthread
59#include "pathutil.h" // AddBackslashToPath
60
61typedef struct
62{
63 CHAR *filename;
64 HWND hwndCnr;
65 CHAR *stopflag;
66}
67DIRSIZE;
68
69typedef struct
70{
71 CHAR *dirname;
72 CHAR stopflag;
73 BOOL dying;
74 BOOL working;
75}
76TEMP;
77
78#pragma data_seg(DATA1)
79
80static PSZ pszSrcFile = __FILE__;
81
82static HWND objcnrwnd;
83
84static VOID ProcessDir(HWND hwndCnr,
85 CHAR *filename,
86 PCNRITEM pciParent,
87 CHAR *stopflag)
88{
89 CHAR maskstr[CCHMAXPATH], *endpath, *p;
90 ULONG ulFindCnt, ulFindMax;
91 ULONG ulBufBytes;
92 HDIR hdir;
93 PFILEFINDBUF3L pffbArray;
94 APIRET rc;
95 RECORDINSERT ri;
96 PCNRITEM pciP;
97 HPOINTER hptr;
98
99 ulBufBytes = sizeof(FILEFINDBUF3L) * FilesToGet;
100 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
101 if (!pffbArray)
102 return; // Error already reported
103 strcpy(maskstr, filename);
104 AddBackslashToPath(maskstr);
105 //if (maskstr[strlen(maskstr) - 1] != '\\')
106 // strcat(maskstr, "\\");
107 endpath = &maskstr[strlen(maskstr)];
108 strcat(maskstr, "*");
109 hdir = HDIR_CREATE;
110 ulFindCnt = 1;
111 rc = xDosFindFirst(filename, &hdir,
112 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
113 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
114 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
115 if (!rc)
116 DosFindClose(hdir);
117 // work around furshluginer FAT root bug
118 else if (IsRoot(filename))
119 rc = 0;
120
121 if ((!rc && (pffbArray->attrFile & FILE_DIRECTORY))) {
122 pciP = WinSendMsg(hwndCnr,
123 CM_ALLOCRECORD,
124 MPFROMLONG(EXTRA_RECORD_BYTES),
125 MPFROMLONG(1));
126 if (!pciP) {
127 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
128 free(pffbArray);
129 return;
130 }
131 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
132 pciP->pszDispAttr = NullStr;
133 pciP->pszSubject = NullStr;
134 pciP->pszLongName = NullStr;
135 if (strlen(filename) < 4)
136 pciP->pszDisplayName = pciP->pszFileName;
137 else {
138 p = strrchr(pciP->pszFileName, '\\');
139 if (!p)
140 pciP->pszDisplayName = pciP->pszFileName;
141 else if (*(p + 1))
142 p++;
143 pciP->pszDisplayName = p;
144 }
145 pciP->rc.pszIcon = pciP->pszDisplayName;
146 if (fForceUpper)
147 strupr(pciP->pszFileName);
148 else if (fForceLower)
149 strlwr(pciP->pszFileName);
150 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
151 }
152 else {
153 free(pffbArray);
154 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
155 GetPString(IDS_CANTFINDDIRTEXT), filename);
156 return;
157 }
158
159 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
160 if (hptr)
161 pciP->rc.hptrIcon = hptr;
162
163 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) // OS/2 bug bug bug bug
164 pciP->rc.hptrIcon = hptrDir;
165
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;
171 ri.cRecordsInsert = 1;
172 ri.fInvalidateRecord = TRUE;
173 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
174 free(pffbArray);
175 return;
176 }
177 hdir = HDIR_CREATE;
178 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
179 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
180 ulFindMax = 1;
181 else
182 ulFindMax = FilesToGet;
183 ulFindCnt = ulFindMax;
184 rc = xDosFindFirst(maskstr, &hdir,
185 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
186 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
187 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
188 if (!rc) {
189 PFILEFINDBUF3L pffbFile;
190 ULONG x;
191
192 while (!rc) {
193 pffbFile = pffbArray;
194 for (x = 0; x < ulFindCnt; x++) {
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);
208 } // for
209 DosSleep(0); // Let's others at same priority get some work done
210 if (*stopflag)
211 break;
212 ulFindCnt = ulFindMax;
213 rc = xDosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
214 } // while
215 DosFindClose(hdir);
216 }
217
218 if (rc && rc != ERROR_NO_MORE_FILES) {
219 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
220 GetPString(IDS_CANTFINDDIRTEXT), filename);
221 }
222
223 free(pffbArray);
224 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
225 MPFROM2SHORT(1, 0));
226}
227
228static VOID FillCnrsThread(VOID * args)
229{
230 HAB hab;
231 HMQ hmq;
232 DIRSIZE *dirsize = (DIRSIZE *)args;
233
234# ifdef FORTIFY
235 Fortify_EnterScope();
236# endif
237 if (!dirsize) {
238 Runtime_Error(pszSrcFile, __LINE__, NULL);
239 return;
240 }
241
242 DosError(FERR_DISABLEHARDERR);
243
244 hab = WinInitialize(0);
245 if (hab) {
246 hmq = WinCreateMsgQueue(hab, 0);
247 if (hmq) {
248 WinCancelShutdown(hmq, TRUE);
249 ProcessDir(dirsize->hwndCnr, dirsize->filename, (PCNRITEM) NULL,
250 dirsize->stopflag);
251 DosPostEventSem(CompactSem);
252 WinDestroyMsgQueue(hmq);
253 }
254 WinTerminate(hab);
255 }
256 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
257 MPVOID, MPVOID);
258 free(dirsize);
259# ifdef FORTIFY
260 Fortify_LeaveScope();
261# endif
262}
263
264MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
265{
266 TEMP *data;
267
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,
273 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
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 }
288 data->dirname = (CHAR *)mp2;
289 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
290 if (*data->dirname)
291 WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
292 {
293 DIRSIZE *dirsize;
294# ifdef FORTIFY
295 Fortify_EnterScope();
296# endif
297 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
298 if (!dirsize) {
299 WinDismissDlg(hwnd, 0);
300 break;
301 }
302 dirsize->stopflag = (CHAR *)&data->stopflag;
303 dirsize->filename = data->dirname;
304 dirsize->hwndCnr = WinWindowFromID(hwnd, OBJCNR_CNR);
305 if (xbeginthread(FillCnrsThread,
306 65536 * 8,
307 dirsize,
308 pszSrcFile,
309 __LINE__) == -1)
310 {
311 free(dirsize);
312# ifdef FORTIFY
313 Fortify_LeaveScope();
314# endif
315 WinDismissDlg(hwnd, 0);
316 break;
317 }
318 else
319 data->working = TRUE;
320 }
321 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
322 break;
323
324 case UM_SETUP:
325 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
326 {
327 CNRINFO cnri;
328
329 memset(&cnri, 0, sizeof(CNRINFO));
330 cnri.cb = sizeof(CNRINFO);
331 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_QUERYCNRINFO,
332 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
333 cnri.cyLineSpacing = 0;
334 cnri.cxTreeIndent = 12L;
335 cnri.pszCnrTitle = (PSZ)GetPString(IDS_WORKINGTEXT);
336 cnri.flWindowAttr = CV_TREE | CV_FLOW |
337 CA_CONTAINERTITLE | CA_TITLESEPARATOR | CA_TREELINE;
338 if (WinQueryWindowUShort(hwnd, QWS_ID) == QTREE_FRAME)
339 cnri.flWindowAttr |= CV_MINI;
340 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
341 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
342 CMA_CXTREEINDENT));
343 }
344 return 0;
345
346 case UM_CONTAINER_FILLED:
347 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
348// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
349 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_INVALIDATERECORD, MPVOID,
350 MPFROM2SHORT(0, CMA_ERASE | CMA_INVALIDATE));
351 data = INSTDATA(hwnd);
352 if (data) {
353 data->working = FALSE;
354 if (data->dying)
355 WinDismissDlg(hwnd, 0);
356 {
357 PCNRITEM pci;
358 USHORT id;
359
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 }
380 }
381 }
382 return 0;
383
384 case WM_CONTROL:
385 switch (SHORT1FROMMP(mp1)) {
386 case OBJCNR_CNR:
387 if (SHORT2FROMMP(mp1) == CN_ENTER) {
388
389 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
390
391 if (pci && (INT) pci != -1)
392 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
393 }
394 break;
395 }
396 return 0;
397
398 case WM_COMMAND:
399 switch (SHORT1FROMMP(mp1)) {
400 case IDM_HELP:
401 if (hwndHelp) {
402
403 USHORT id;
404
405 id = WinQueryWindowUShort(hwnd, QWS_ID);
406
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));
415 }
416 break;
417
418 case OBJCNR_DESKTOP:
419 case DID_OK:
420 data = INSTDATA(hwnd);
421 if (data) {
422
423 PCNRITEM pci;
424
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);
440 }
441 break;
442
443 case DID_CANCEL:
444 data = INSTDATA(hwnd);
445 if (data) {
446 if (data->working) {
447 data->dying = (CHAR)TRUE;
448 data->stopflag = (CHAR)0xff;
449 break;
450 }
451 WinDismissDlg(hwnd, 0);
452 }
453 break;
454 }
455 return 0;
456
457 case WM_DESTROY:
458 objcnrwnd = (HWND) 0;
459 data = INSTDATA(hwnd);
460 xfree(data, pszSrcFile, __LINE__);
461 break;
462 }
463 return WinDefDlgProc(hwnd, msg, mp1, mp2);
464}
465
466#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.