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