source: trunk/dll/flesh.c@ 736

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

Comments

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