source: trunk/dll/objcnr.c@ 1402

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

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

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