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
Line 
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
9 Copyright (c) 2005, 2007 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
25***********************************************************************/
26
27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
30#include <process.h> // _beginthread
31
32#define INCL_DOS
33#define INCL_WIN
34#define INCL_DOSERRORS
35#define INCL_LONGLONG
36
37#include "fm3dll.h"
38#include "fm3dlg.h"
39#include "fm3str.h"
40#include "errutil.h" // Dos_Error...
41#include "strutil.h" // GetPString
42#include "objcnr.h"
43#include "notify.h" // Notify
44#include "wrappers.h" // xDosFindNext
45#include "select.h" // ExpandAll
46#include "valid.h" // IsRoot
47#include "misc.h" // PostMsg
48#include "fortify.h"
49
50typedef struct
51{
52 CHAR *filename;
53 HWND hwndCnr;
54 CHAR *stopflag;
55}
56DIRSIZE;
57
58typedef struct
59{
60 CHAR *dirname;
61 CHAR stopflag;
62 BOOL dying;
63 BOOL working;
64}
65TEMP;
66
67#pragma data_seg(DATA1)
68
69static PSZ pszSrcFile = __FILE__;
70
71static HWND objcnrwnd;
72
73static VOID ProcessDir(HWND hwndCnr,
74 CHAR *filename,
75 PCNRITEM pciParent,
76 CHAR *stopflag)
77{
78 CHAR maskstr[CCHMAXPATH], *endpath, *p;
79 ULONG ulFindCnt, ulFindMax;
80 ULONG ulBufBytes;
81 HDIR hdir;
82 PFILEFINDBUF3L pffbArray;
83 APIRET rc;
84 RECORDINSERT ri;
85 PCNRITEM pciP;
86 HPOINTER hptr;
87
88 ulBufBytes = sizeof(FILEFINDBUF3L) * FilesToGet;
89 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
90 if (!pffbArray)
91 return; // Error already reported
92 strcpy(maskstr, filename);
93 if (maskstr[strlen(maskstr) - 1] != '\\')
94 strcat(maskstr, "\\");
95 endpath = &maskstr[strlen(maskstr)];
96 strcat(maskstr, "*");
97 hdir = HDIR_CREATE;
98 ulFindCnt = 1;
99 rc = xDosFindFirst(filename, &hdir,
100 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
101 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
102 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
103 if (!rc)
104 DosFindClose(hdir);
105 // work around furshluginer FAT root bug
106 else if (IsRoot(filename))
107 rc = 0;
108
109 if ((!rc && (pffbArray->attrFile & FILE_DIRECTORY))) {
110 pciP = WinSendMsg(hwndCnr,
111 CM_ALLOCRECORD,
112 MPFROMLONG(EXTRA_RECORD_BYTES),
113 MPFROMLONG(1));
114 if (!pciP) {
115 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, "CM_ALLOCRECORD");
116 free(pffbArray);
117 return;
118 }
119 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
120 pciP->pszDispAttr = NullStr;
121 pciP->pszSubject = NullStr;
122 pciP->pszLongName = NullStr;
123 if (strlen(filename) < 4)
124 pciP->pszDisplayName = pciP->pszFileName;
125 else {
126 p = strrchr(pciP->pszFileName, '\\');
127 if (!p)
128 pciP->pszDisplayName = pciP->pszFileName;
129 else if (*(p + 1))
130 p++;
131 pciP->pszDisplayName = p;
132 }
133 pciP->rc.pszIcon = pciP->pszDisplayName;
134 if (fForceUpper)
135 strupr(pciP->pszFileName);
136 else if (fForceLower)
137 strlwr(pciP->pszFileName);
138 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
139 }
140 else {
141 free(pffbArray);
142 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
143 GetPString(IDS_CANTFINDDIRTEXT), filename);
144 return;
145 }
146
147 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
148 if (hptr)
149 pciP->rc.hptrIcon = hptr;
150
151 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) /* OS/2 bug bug bug bug */
152 pciP->rc.hptrIcon = hptrDir;
153
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;
159 ri.cRecordsInsert = 1;
160 ri.fInvalidateRecord = TRUE;
161 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
162 free(pffbArray);
163 return;
164 }
165 hdir = HDIR_CREATE;
166 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
167 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
168 ulFindMax = 1;
169 else
170 ulFindMax = FilesToGet;
171 ulFindCnt = ulFindMax;
172 rc = xDosFindFirst(maskstr, &hdir,
173 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
174 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
175 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
176 if (!rc) {
177 PFILEFINDBUF3L pffbFile;
178 ULONG x;
179
180 while (!rc) {
181 pffbFile = pffbArray;
182 for (x = 0; x < ulFindCnt; x++) {
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);
196 } // for
197 DosSleep(0); // Let's others at same priority get some work done
198 if (*stopflag)
199 break;
200 ulFindCnt = ulFindMax;
201 rc = xDosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
202 } // while
203 DosFindClose(hdir);
204 }
205
206 if (rc && rc != ERROR_NO_MORE_FILES) {
207 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
208 GetPString(IDS_CANTFINDDIRTEXT), filename);
209 }
210
211 free(pffbArray);
212 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
213 MPFROM2SHORT(1, 0));
214}
215
216static VOID FillCnrsThread(VOID * args)
217{
218 HAB hab;
219 HMQ hmq;
220 DIRSIZE *dirsize = (DIRSIZE *)args;
221
222# ifdef FORTIFY
223 Fortify_EnterScope();
224# endif
225 if (!dirsize) {
226 Runtime_Error(pszSrcFile, __LINE__, "no data");
227 return;
228 }
229
230 DosError(FERR_DISABLEHARDERR);
231
232 hab = WinInitialize(0);
233 if (hab) {
234 hmq = WinCreateMsgQueue(hab, 0);
235 if (hmq) {
236 WinCancelShutdown(hmq, TRUE);
237 ProcessDir(dirsize->hwndCnr, dirsize->filename, (PCNRITEM) NULL,
238 dirsize->stopflag);
239 DosPostEventSem(CompactSem);
240 WinDestroyMsgQueue(hmq);
241 }
242 WinTerminate(hab);
243 }
244 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
245 MPVOID, MPVOID);
246 free(dirsize);
247# ifdef FORTIFY
248 Fortify_LeaveScope();
249# endif
250}
251
252MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
253{
254 TEMP *data;
255
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,
261 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
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 }
276 data->dirname = (CHAR *)mp2;
277 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
278 if (*data->dirname)
279 WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
280 {
281 DIRSIZE *dirsize;
282# ifdef FORTIFY
283 Fortify_EnterScope();
284# endif
285 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
286 if (!dirsize) {
287 WinDismissDlg(hwnd, 0);
288 break;
289 }
290 dirsize->stopflag = (CHAR *)&data->stopflag;
291 dirsize->filename = data->dirname;
292 dirsize->hwndCnr = WinWindowFromID(hwnd, OBJCNR_CNR);
293 if (_beginthread(FillCnrsThread, NULL, 65536 * 8, (PVOID) dirsize) ==
294 -1) {
295 Runtime_Error(pszSrcFile, __LINE__,
296 GetPString(IDS_COULDNTSTARTTHREADTEXT));
297 free(dirsize);
298# ifdef FORTIFY
299 Fortify_LeaveScope();
300# endif
301 WinDismissDlg(hwnd, 0);
302 break;
303 }
304 else
305 data->working = TRUE;
306 }
307 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
308 break;
309
310 case UM_SETUP:
311 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
312 {
313 CNRINFO cnri;
314
315 memset(&cnri, 0, sizeof(CNRINFO));
316 cnri.cb = sizeof(CNRINFO);
317 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_QUERYCNRINFO,
318 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
319 cnri.cyLineSpacing = 0;
320 cnri.cxTreeIndent = 12L;
321 cnri.pszCnrTitle = GetPString(IDS_WORKINGTEXT);
322 cnri.flWindowAttr = CV_TREE | CV_FLOW |
323 CA_CONTAINERTITLE | CA_TITLESEPARATOR | CA_TREELINE;
324 if (WinQueryWindowUShort(hwnd, QWS_ID) == QTREE_FRAME)
325 cnri.flWindowAttr |= CV_MINI;
326 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
327 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
328 CMA_CXTREEINDENT));
329 }
330 return 0;
331
332 case UM_CONTAINER_FILLED:
333 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
334// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
335 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_INVALIDATERECORD, MPVOID,
336 MPFROM2SHORT(0, CMA_ERASE | CMA_INVALIDATE));
337 data = INSTDATA(hwnd);
338 if (data) {
339 data->working = FALSE;
340 if (data->dying)
341 WinDismissDlg(hwnd, 0);
342 {
343 PCNRITEM pci;
344 USHORT id;
345
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 }
366 }
367 }
368 return 0;
369
370 case WM_CONTROL:
371 switch (SHORT1FROMMP(mp1)) {
372 case OBJCNR_CNR:
373 if (SHORT2FROMMP(mp1) == CN_ENTER) {
374
375 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
376
377 if (pci && (INT) pci != -1)
378 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
379 }
380 break;
381 }
382 return 0;
383
384 case WM_COMMAND:
385 switch (SHORT1FROMMP(mp1)) {
386 case IDM_HELP:
387 if (hwndHelp) {
388
389 USHORT id;
390
391 id = WinQueryWindowUShort(hwnd, QWS_ID);
392
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));
401 }
402 break;
403
404 case OBJCNR_DESKTOP:
405 case DID_OK:
406 data = INSTDATA(hwnd);
407 if (data) {
408
409 PCNRITEM pci;
410
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);
426 }
427 break;
428
429 case DID_CANCEL:
430 data = INSTDATA(hwnd);
431 if (data) {
432 if (data->working) {
433 data->dying = (CHAR)TRUE;
434 data->stopflag = (CHAR)0xff;
435 break;
436 }
437 WinDismissDlg(hwnd, 0);
438 }
439 break;
440 }
441 return 0;
442
443 case WM_DESTROY:
444 objcnrwnd = (HWND) 0;
445 data = INSTDATA(hwnd);
446 xfree(data, pszSrcFile, __LINE__);
447 break;
448 }
449 return WinDefDlgProc(hwnd, msg, mp1, mp2);
450}
451
452#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.