source: trunk/dll/objcnr.c@ 850

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

Rework large file support wrappers (ticket #41)
Add code to avoid NTFS driver small file read defect (ticket #159)
Add debug code to try to catch David's drive bar exception
Another attempt to correct newview fast viewer text load failure

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