source: trunk/dll/objcnr.c@ 785

Last change on this file since 785 was 783, checked in by Steven Levine, 18 years ago

Rework DosFindFirst/Next loops to optimize memory allocation and code paths
Adjust FilesToGet limits
Update configuration notebook scanning page
Start updating #pragma alloc_text positioning for OpenWatcom compatibility

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