source: trunk/dll/flesh.c@ 751

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

Sync rest of code with CNRITEM mods
Sync code with ARCITEM mods
Get compare dialog working
Still some issues with status display
Still some issues with directory sizes tree display
Heap check diagnostic code mostly enabled

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.7 KB
Line 
1
2/***********************************************************************
3
4 $Id: flesh.c 751 2007-08-02 23:05:48Z stevenhl $
5
6 Flesh
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2005, 2007 Steven H. Levine
10
11 24 May 05 SHL Rework Win_Error usage
12 25 May 05 SHL Rework for ProcessDirectory
13 28 May 05 SHL Clean while reading code
14 24 Oct 05 SHL Delete obsolete code
15 22 Jul 06 SHL Check more run time errors
16 19 Oct 06 SHL Stubby - correct . and .. detect
17 22 Mar 07 GKY Use QWL_USER
18 01 Aug 07 SHL Sync with CNRITEM mods
19
20***********************************************************************/
21
22#define INCL_DOS
23#define INCL_DOSERRORS
24#define INCL_WIN
25#include <os2.h>
26
27#include <stdarg.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <ctype.h>
32
33#include "fm3dll.h"
34#include "fm3str.h"
35
36#pragma data_seg(DATA1)
37
38static PSZ pszSrcFile = __FILE__;
39
40#pragma alloc_text(FLESH,Flesh,FleshEnv,Unflesh,Stubby)
41
42BOOL FleshEnv(HWND hwndCnr, PCNRITEM pciParent)
43{
44 PCNRITEM pciL;
45 DIRCNRDATA *dcd;
46 CHAR path[CCHMAXPATH + 12],
47 fullpath[CCHMAXPATH + 12], *env, *p, *pp, *var = NULL;
48
49 if (!pciParent || (INT) pciParent == -1 || !hwndCnr)
50 return FALSE;
51 dcd = (DIRCNRDATA *) WinQueryWindowPtr(hwndCnr, QWL_USER);
52 if (!dcd)
53 return FALSE;
54
55 strcpy(path, pciParent->pszFileName + 1);
56 if (stricmp(path, GetPString(IDS_ENVVARSTEXT) + 1))
57 UnFlesh(hwndCnr, pciParent);
58 if (*path) {
59 path[strlen(path) - 1] = 0;
60 if (!stricmp(path, "LIBPATH")) {
61 var = xmalloc(65536, pszSrcFile, __LINE__);
62 if (var)
63 LoadLibPath(var, 65536);
64 env = var;
65 }
66 else
67 env = getenv(path);
68 if (env && *env) {
69 p = env;
70 while (*p) {
71 pp = path;
72 while (*p == ';')
73 p++;
74 while (*p && *p != ';') {
75 *pp = *p;
76 p++;
77 pp++;
78 }
79 *pp = 0;
80 if (*path &&
81 strcmp(path, ".") &&
82 strcmp(path, ".\\") &&
83 strcmp(path, "..") &&
84 strcmp(path, "..\\") &&
85 strncmp(path, ".\\", 2) && strncmp(path, "..\\", 3)) {
86 if (!DosQueryPathInfo(path,
87 FIL_QUERYFULLNAME,
88 fullpath,
89 sizeof(fullpath)) && IsValidDir(fullpath)) {
90 pciL = FindCnrRecord(hwndCnr,
91 fullpath, pciParent, FALSE, FALSE, FALSE);
92 if (pciL) {
93 while (pciL && pciL != (PCNRITEM) - 1 && pciL != pciParent)
94 pciL = WinSendMsg(hwndCnr,
95 CM_QUERYRECORD,
96 MPFROMP(pciL),
97 MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER));
98 }
99 if (!pciL) {
100
101 RECORDINSERT ri;
102
103 pciL = WinSendMsg(hwndCnr,
104 CM_ALLOCRECORD,
105 MPFROMLONG(EXTRA_RECORD_BYTES),
106 MPFROMLONG(1));
107 if (pciL) {
108 pciL->pszFileName = xstrdup(fullpath, pszSrcFile, __LINE__);
109 pciL->rc.pszIcon = pciL->pszFileName;
110 if (!fNoIconsDirs &&
111 (!isalpha(*fullpath) ||
112 !(driveflags[toupper(*fullpath) - 'A'] &
113 DRIVE_NOLOADICONS)))
114 pciL->rc.hptrIcon = WinLoadFileIcon(fullpath, FALSE);
115 if (!pciL->rc.hptrIcon)
116 pciL->rc.hptrIcon = hptrDir;
117 pciL->attrFile = FILE_DIRECTORY;
118 pciL->pszDispAttr = FileAttrToString(pciL->attrFile);
119 memset(&ri, 0, sizeof(ri));
120 ri.cb = sizeof(ri);
121 ri.pRecordOrder = (PRECORDCORE) CMA_END;
122 ri.pRecordParent = (PRECORDCORE) pciParent;
123 ri.zOrder = (ULONG) CMA_TOP;
124 ri.cRecordsInsert = 1;
125 ri.fInvalidateRecord = FALSE;
126 if (!WinSendMsg(hwndCnr,
127 CM_INSERTRECORD, MPFROMP(pciL), MPFROMP(&ri)))
128 FreeCnrItem(hwndCnr, pciL);
129 }
130 }
131 }
132 }
133 }
134 }
135 if (var)
136 free(var);
137 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
138 CM_QUERYRECORD,
139 MPFROMP(pciParent),
140 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
141 while (pciL && (INT) pciL != -1) {
142 pciL->flags |= (RECFLAGS_NODRAG | RECFLAGS_UNDERENV);
143 WinSendMsg(hwndCnr,
144 CM_INVALIDATERECORD, MPFROMP(&pciL), MPFROM2SHORT(1, 0));
145 pciL = WinSendMsg(hwndCnr,
146 CM_QUERYRECORD,
147 MPFROMP(pciL), MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
148 }
149 }
150 return TRUE;
151}
152
153BOOL Flesh(HWND hwndCnr, PCNRITEM pciParent)
154{
155 PCNRITEM pciL;
156 DIRCNRDATA *dcd;
157 BOOL includefiles = fFilesInTree;
158
159 if (!pciParent || (INT) pciParent == -1 || !hwndCnr)
160 return FALSE;
161 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
162 CM_QUERYRECORD,
163 MPFROMP(pciParent),
164 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
165 if (!pciL || !*pciL->pszFileName) {
166 if (pciL && (INT) pciL != -1)
167 RemoveCnrItems(hwndCnr, pciL, 1, CMA_FREE);
168 dcd = INSTDATA(hwndCnr);
169 if (dcd && dcd->size != sizeof(DIRCNRDATA))
170 dcd = NULL;
171 if (driveflags[toupper(*pciParent->pszFileName) - 'A'] &
172 DRIVE_INCLUDEFILES)
173 includefiles = TRUE;
174 ProcessDirectory(hwndCnr,
175 pciParent,
176 pciParent->pszFileName,
177 includefiles, // filestoo
178 TRUE, // recurse
179 TRUE, // partial
180 NULL,
181 dcd,
182 NULL,
183 NULL);
184 }
185 return TRUE;
186}
187
188BOOL UnFlesh(HWND hwndCnr, PCNRITEM pciParent)
189{
190 BOOL ret = FALSE;
191 PCNRITEM pciL;
192
193 if (!pciParent || !hwndCnr)
194 return FALSE;
195 for (;;) {
196 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
197 CM_QUERYRECORD,
198 MPFROMP(pciParent),
199 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
200 if (pciL && (INT) pciL != -1) {
201 ret = TRUE;
202 RemoveCnrItems(hwndCnr, pciL, 1, CMA_FREE);
203 }
204 else
205 break;
206 }
207 if (ret) {
208 WinSendMsg(hwndCnr,
209 CM_INVALIDATERECORD,
210 MPFROMP(&pciParent),
211 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
212 }
213 return ret;
214}
215
216#define DDEPTH 16
217
218BOOL Stubby(HWND hwndCnr, PCNRITEM pciParent)
219{
220 /*
221 * this code is full of workarounds for screwed up LANs.
222 * let's hope all the current LAN programmers fall into
223 * a black hole and make way for people who can get it right...
224 */
225
226 BOOL ret = FALSE;
227 FILEFINDBUF3 ffb[DDEPTH];
228 PFILEFINDBUF3 pffb;
229 HDIR hDir = HDIR_CREATE;
230 ULONG nm, ulM = 1L, total = 0L, fl = MUST_HAVE_DIRECTORY;
231 CHAR str[CCHMAXPATH];
232 register INT len;
233 APIRET rc, prc;
234 BOOL isadir = FALSE, isremote = FALSE, includefiles = fFilesInTree;
235 ULONG ddepth = 3L;
236 static BOOL brokenlan = FALSE, isbroken = FALSE;
237
238 if (!pciParent || !*pciParent->pszFileName || !hwndCnr)
239 return FALSE;
240
241 len = strlen(pciParent->pszFileName);
242 memcpy(str, pciParent->pszFileName, len + 1);
243 if (str[len - 1] != '\\')
244 str[len++] = '\\';
245 str[len++] = '*';
246 str[len] = 0;
247
248 if (!isalpha(*str) || str[1] != ':' || str[2] != '\\')
249 MakeFullName(str);
250
251 if (!isalpha(*str) ||
252 str[1] != ':' ||
253 str[2] != '\\' || ((driveflags[toupper(*str) - 'A'] & DRIVE_IGNORE)))
254 return FALSE;
255
256 if (isalpha(*str) && driveflags[toupper(*str) - 'A'] & DRIVE_INCLUDEFILES)
257 includefiles = TRUE;
258
259 if (!isalpha(*str) ||
260 str[1] != ':' ||
261 str[2] != '\\' || ((driveflags[toupper(*str) - 'A'] & DRIVE_REMOTE)))
262 isremote = TRUE;
263
264 if (isremote) {
265 ddepth = 14;
266 if (fRemoteBug) {
267 if (brokenlan) {
268 ddepth = (ULONG) - 1;
269 ddepth--;
270 }
271 ulM = 1L;
272 }
273 }
274 else if (isbroken)
275 ddepth = 14;
276
277 if (!isremote || !fRemoteBug)
278 ulM = (ddepth < 16L) ? ddepth : 1L;
279
280 nm = ulM;
281
282 DosError(FERR_DISABLEHARDERR);
283 if (includefiles)
284 fl = FILE_DIRECTORY;
285 rc = DosFindFirst(str,
286 &hDir,
287 FILE_NORMAL | fl |
288 FILE_READONLY | FILE_ARCHIVED |
289 FILE_SYSTEM | FILE_HIDDEN,
290 &ffb, ulM * sizeof(FILEFINDBUF3), &nm, FIL_STANDARD);
291 if (ulM == 1L && !rc) {
292 do {
293 pffb = &ffb[0];
294 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY) && !brokenlan) {
295 brokenlan = TRUE;
296 ddepth = (ULONG) - 1L;
297 ddepth--;
298 if (!NoBrokenNotify) {
299 prc = saymsg(MB_YESNO | MB_ICONEXCLAMATION,
300 HWND_DESKTOP,
301 GetPString(IDS_LANERRORTITLETEXT),
302 GetPString(IDS_LANERRORTEXT));
303 if (prc == MBID_NO) {
304 saymsg(MB_ENTER,
305 HWND_DESKTOP,
306 GetPString(IDS_LANERROR2TITLETEXT),
307 GetPString(IDS_LANERROR2TEXT));
308 NoBrokenNotify = 255L;
309 PrfWriteProfileData(fmprof,
310 FM3Str,
311 "NoBrokenNotify",
312 &NoBrokenNotify, sizeof(ULONG));
313 }
314 }
315 else {
316 NoBrokenNotify--;
317 PrfWriteProfileData(fmprof,
318 FM3Str,
319 "NoBrokenNotify",
320 &NoBrokenNotify, sizeof(ULONG));
321 }
322 }
323 if (*pffb->achName &&
324 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
325 // Skip . and ..
326 (pffb->achName[0] != '.' ||
327 (pffb->achName[1] &&
328 (pffb->achName[1] != '.' || pffb->achName[2])))) {
329 DosFindClose(hDir);
330 isadir = TRUE;
331 goto Interruptus;
332 }
333 nm = 1L;
334 DosError(FERR_DISABLEHARDERR);
335 } while (++total < ddepth && !(rc = (DosFindNext(hDir,
336 &ffb,
337 sizeof(FILEFINDBUF3),
338 &nm))));
339 DosFindClose(hDir);
340 if (toupper(*pciParent->pszFileName) > 'B' &&
341 (*(pciParent->pszFileName + 1)) == ':' &&
342 (*(pciParent->pszFileName + 2)) == '\\' && !(*(pciParent->pszFileName + 3))) {
343
344 CHAR s[132];
345
346 sprintf(s,
347 GetPString(IDS_NOSUBDIRSTEXT),
348 total, toupper(*pciParent->pszFileName));
349 if (rc && rc != ERROR_NO_MORE_FILES)
350 sprintf(&s[strlen(s)], GetPString(IDS_SEARCHERRORTEXT), rc, str);
351 else if (ddepth < 16L)
352 brokenlan = TRUE;
353 Notify(s);
354 }
355 goto None;
356 }
357
358 if (!rc) {
359 DosFindClose(hDir);
360 if (nm) {
361
362 register PBYTE fb = (PBYTE) & ffb[0];
363
364 for (len = 0; len < nm; len++) {
365 pffb = (PFILEFINDBUF3) fb;
366 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY)) {
367 if (!isbroken) {
368 isbroken = TRUE;
369 if (!NoBrokenNotify) {
370 prc = saymsg(MB_YESNO | MB_ICONEXCLAMATION,
371 HWND_DESKTOP,
372 GetPString(IDS_FSDERRORTITLETEXT),
373 GetPString(IDS_FSDERRORTEXT),
374 (isremote) ?
375 GetPString(IDS_REMOTETEXT) :
376 GetPString(IDS_LOCALTEXT), *str);
377 if (prc == MBID_NO) {
378 saymsg(MB_ENTER,
379 HWND_DESKTOP,
380 GetPString(IDS_FSDERROR2TITLETEXT),
381 GetPString(IDS_FSDERROR2TEXT));
382 NoBrokenNotify = 255L;
383 PrfWriteProfileData(fmprof,
384 FM3Str,
385 "NoBrokenNotify",
386 &NoBrokenNotify, sizeof(ULONG));
387 }
388 }
389 else {
390 NoBrokenNotify--;
391 PrfWriteProfileData(fmprof,
392 FM3Str,
393 "NoBrokenNotify",
394 &NoBrokenNotify, sizeof(ULONG));
395 }
396 }
397 }
398 if (*pffb->achName &&
399 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
400 // Skip . and ..
401 (pffb->achName[0] != '.' || (pffb->achName[1]
402 && (pffb->achName[1] != '.'
403 || pffb->achName[2])))) {
404 isadir = TRUE;
405 break;
406 }
407 fb += pffb->oNextEntryOffset;
408 }
409
410 Interruptus:
411
412 if (isadir) {
413
414 PCNRITEM pci;
415
416 pci = WinSendMsg(hwndCnr,
417 CM_ALLOCRECORD,
418 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1L));
419 if (!pci) {
420 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
421 GetPString(IDS_RECORDALLOCFAILEDTEXT));
422 }
423 else {
424 RECORDINSERT ri;
425 pci->pszFileName = NullStr;
426 pci->pszDisplayName = pci->pszFileName;
427 pci->rc.pszIcon = pci->pszDisplayName;
428 memset(&ri, 0, sizeof(RECORDINSERT));
429 ri.cb = sizeof(RECORDINSERT);
430 ri.pRecordOrder = (PRECORDCORE) CMA_END;
431 ri.pRecordParent = (PRECORDCORE) pciParent;
432 ri.zOrder = (ULONG) CMA_TOP;
433 ri.cRecordsInsert = 1L;
434 ri.fInvalidateRecord = TRUE;
435 if (!WinSendMsg(hwndCnr,
436 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
437 DosSleep(100);
438 WinSetFocus(HWND_DESKTOP, hwndCnr);
439 if (WinIsWindow((HAB)0, hwndCnr)) {
440 if (!WinSendMsg(hwndCnr,
441 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
442 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
443 GetPString(IDS_RECORDINSERTFAILEDTEXT));
444 FreeCnrItem(hwndCnr, pci);
445 }
446 else
447 ret = TRUE;
448 }
449 }
450 else
451 ret = TRUE;
452 }
453 }
454 else if (toupper(*str) > 'B' && str[1] == ':' && str[2] == '\\' &&
455 !str[3]) {
456
457 CHAR s[162];
458
459 sprintf(s,
460 GetPString(IDS_NOSUBDIRS2TEXT),
461 nm,
462 toupper(*pciParent->pszFileName),
463 (isremote) ? GetPString(IDS_NOSUBDIRS3TEXT) : NullStr);
464 Notify(s);
465 }
466 }
467 }
468 else if (toupper(*str) > 'B' && rc != ERROR_NO_MORE_FILES) {
469
470 CHAR s[CCHMAXPATH + 80];
471
472 sprintf(s, GetPString(IDS_SEARCHERRORTEXT), rc, str);
473 Notify(s);
474 }
475
476None:
477
478 DosError(FERR_DISABLEHARDERR);
479 return ret;
480}
Note: See TracBrowser for help on using the repository browser.