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
RevLine 
[159]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
[574]9 Copyright (c) 2005, 2007 Steven H. Levine
[159]10
11 24 May 05 SHL Rework for CNRITEM.szSubject
[349]12 13 Jul 06 SHL Use Runtime_Error
[488]13 01 Sep 06 SHL Do not complain for normal cancel
[517]14 19 Oct 06 SHL Correct . and .. detect
[531]15 03 Nov 06 SHL Renames
[574]16 22 Mar 07 GKY Use QWL_USER
[751]17 01 Aug 07 SHL Rework to sync with CNRITEM mods
[756]18 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
[775]19 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[783]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
[787]22 14 Aug 07 SHL Revert ProcessDir DosSleep to 0
[159]23
24***********************************************************************/
25
[2]26#define INCL_DOS
27#define INCL_WIN
[783]28#define INCL_DOSERRORS
[841]29#define INCL_LONGLONG
[349]30#include <os2.h>
[2]31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <ctype.h>
[689]36#include <process.h> // _beginthread
[349]37
[2]38#include "fm3dll.h"
39#include "fm3dlg.h"
40#include "fm3str.h"
41
[551]42typedef struct
43{
[2]44 CHAR *filename;
[551]45 HWND hwndCnr;
[2]46 CHAR *stopflag;
[551]47}
48DIRSIZE;
[2]49
[551]50typedef struct
51{
[2]52 CHAR *dirname;
[551]53 CHAR stopflag;
54 BOOL dying;
55 BOOL working;
56}
57TEMP;
[2]58
[349]59#pragma data_seg(DATA1)
[2]60
[349]61static PSZ pszSrcFile = __FILE__;
[2]62
[349]63static HWND objcnrwnd;
[2]64
[783]65static VOID ProcessDir(HWND hwndCnr,
66 CHAR *filename,
67 PCNRITEM pciParent,
68 CHAR *stopflag)
[349]69{
[551]70 CHAR maskstr[CCHMAXPATH], *endpath, *p;
[783]71 ULONG ulFindCnt, ulFindMax;
72 ULONG ulBufBytes;
[551]73 HDIR hdir;
[841]74 PFILEFINDBUF3L pffbArray;
[551]75 APIRET rc;
76 RECORDINSERT ri;
77 PCNRITEM pciP;
[783]78 HPOINTER hptr;
[2]79
[841]80 ulBufBytes = sizeof(FILEFINDBUF3L) * FilesToGet;
[783]81 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
82 if (!pffbArray)
83 return; // Error already reported
[551]84 strcpy(maskstr, filename);
85 if (maskstr[strlen(maskstr) - 1] != '\\')
86 strcat(maskstr, "\\");
[2]87 endpath = &maskstr[strlen(maskstr)];
[551]88 strcat(maskstr, "*");
[2]89 hdir = HDIR_CREATE;
[783]90 ulFindCnt = 1;
[838]91 rc = xDosFindFirst(filename, &hdir,
92 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
93 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
[841]94 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[551]95 if (!rc)
[2]96 DosFindClose(hdir);
[783]97 // work around furshluginer FAT root bug
98 else if (IsRoot(filename))
99 rc = 0;
[2]100
[783]101 if ((!rc && (pffbArray->attrFile & FILE_DIRECTORY))) {
[731]102 pciP = WinSendMsg(hwndCnr,
103 CM_ALLOCRECORD,
[751]104 MPFROMLONG(EXTRA_RECORD_BYTES),
[761]105 MPFROMLONG(1));
[551]106 if (!pciP) {
[783]107 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, "CM_ALLOCRECORD");
108 free(pffbArray);
[2]109 return;
110 }
[730]111 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
[751]112 pciP->pszDispAttr = NullStr;
113 pciP->pszSubject = NullStr;
[762]114 pciP->pszLongName = NullStr;
[551]115 if (strlen(filename) < 4)
[751]116 pciP->pszDisplayName = pciP->pszFileName;
[2]117 else {
[730]118 p = strrchr(pciP->pszFileName, '\\');
[551]119 if (!p)
[756]120 pciP->pszDisplayName = pciP->pszFileName;
[551]121 else if (*(p + 1))
122 p++;
[751]123 pciP->pszDisplayName = p;
[2]124 }
[751]125 pciP->rc.pszIcon = pciP->pszDisplayName;
[551]126 if (fForceUpper)
[730]127 strupr(pciP->pszFileName);
[551]128 else if (fForceLower)
[730]129 strlwr(pciP->pszFileName);
[2]130 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
131 }
132 else {
[783]133 free(pffbArray);
134 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
135 GetPString(IDS_CANTFINDDIRTEXT), filename);
[2]136 return;
137 }
138
[783]139 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
140 if (hptr)
141 pciP->rc.hptrIcon = hptr;
142
[551]143 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) /* OS/2 bug bug bug bug */
[2]144 pciP->rc.hptrIcon = hptrDir;
[783]145
[551]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;
[771]151 ri.cRecordsInsert = 1;
[551]152 ri.fInvalidateRecord = TRUE;
153 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
[783]154 free(pffbArray);
[2]155 return;
156 }
157 hdir = HDIR_CREATE;
[551]158 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
159 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
[783]160 ulFindMax = 1;
[2]161 else
[783]162 ulFindMax = FilesToGet;
163 ulFindCnt = ulFindMax;
[838]164 rc = xDosFindFirst(maskstr, &hdir,
165 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
166 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
[841]167 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[551]168 if (!rc) {
[841]169 PFILEFINDBUF3L pffbFile;
[551]170 ULONG x;
[2]171
[551]172 while (!rc) {
[783]173 pffbFile = pffbArray;
174 for (x = 0; x < ulFindCnt; x++) {
[551]175 if (*stopflag)
176 break;
177 if ((pffbFile->attrFile & FILE_DIRECTORY) &&
[517]178 // Skip . and ..
[551]179 (pffbFile->achName[0] != '.' ||
[517]180 (pffbFile->achName[1] &&
[551]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;
[841]187 pffbFile = (PFILEFINDBUF3L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
[783]188 } // for
[787]189 DosSleep(0); // Let's others at same priority get some work done
[551]190 if (*stopflag)
191 break;
[783]192 ulFindCnt = ulFindMax;
[850]193 rc = xDosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[783]194 } // while
[2]195 DosFindClose(hdir);
196 }
[783]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);
[551]204 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
205 MPFROM2SHORT(1, 0));
[2]206}
207
[551]208static VOID FillCnrsThread(VOID * args)
[349]209{
[551]210 HAB hab;
211 HMQ hmq;
[783]212 DIRSIZE *dirsize = (DIRSIZE *)args;
[2]213
[783]214 if (!dirsize) {
215 Runtime_Error(pszSrcFile, __LINE__, "no data");
[2]216 return;
[783]217 }
[2]218
219 DosError(FERR_DISABLEHARDERR);
220
221 hab = WinInitialize(0);
[551]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);
[2]228 DosPostEventSem(CompactSem);
229 WinDestroyMsgQueue(hmq);
230 }
231 WinTerminate(hab);
232 }
[551]233 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
234 MPVOID, MPVOID);
[2]235 free(dirsize);
236}
237
[551]238MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[349]239{
[2]240 TEMP *data;
241
[551]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;
[574]263 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
[551]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;
[2]273 }
[551]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;
[349]284 }
[551]285 else
286 data->working = TRUE;
287 }
288 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
289 break;
[2]290
[551]291 case UM_SETUP:
292 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
293 {
294 CNRINFO cnri;
[2]295
[551]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;
[2]312
[551]313 case UM_CONTAINER_FILLED:
314 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
[2]315// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
[551]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;
[2]326
[551]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 }
[2]347 }
[551]348 }
349 return 0;
[2]350
[551]351 case WM_CONTROL:
352 switch (SHORT1FROMMP(mp1)) {
353 case OBJCNR_CNR:
354 if (SHORT2FROMMP(mp1) == CN_ENTER) {
[2]355
[551]356 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
[2]357
[551]358 if (pci && (INT) pci != -1)
359 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
[2]360 }
[551]361 break;
362 }
363 return 0;
[2]364
[551]365 case WM_COMMAND:
366 switch (SHORT1FROMMP(mp1)) {
367 case IDM_HELP:
368 if (hwndHelp) {
[2]369
[551]370 USHORT id;
[2]371
[551]372 id = WinQueryWindowUShort(hwnd, QWS_ID);
[2]373
[551]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;
[2]384
[551]385 case OBJCNR_DESKTOP:
386 case DID_OK:
387 data = INSTDATA(hwnd);
388 if (data) {
[2]389
[551]390 PCNRITEM pci;
[2]391
[551]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)
[730]405 strcpy(data->dirname, pci->pszFileName);
[551]406 WinDismissDlg(hwnd, 1);
[2]407 }
[551]408 break;
[2]409
[551]410 case DID_CANCEL:
[2]411 data = INSTDATA(hwnd);
[551]412 if (data) {
413 if (data->working) {
[689]414 data->dying = (CHAR)TRUE;
415 data->stopflag = (CHAR)0xff;
[551]416 break;
417 }
418 WinDismissDlg(hwnd, 0);
419 }
[2]420 break;
[551]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;
[2]430 }
[551]431 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]432}
[783]433
434#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.