source: trunk/dll/flesh.c@ 739

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

More ticket #24 updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 KB
Line 
1
2/***********************************************************************
3
4 $Id: flesh.c 739 2007-07-24 04:06:59Z 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 // 23 Jul 07 SHL fixme to ensure pszDisplay set appropriately
433 memset(&ri, 0, sizeof(RECORDINSERT));
434 ri.cb = sizeof(RECORDINSERT);
435 ri.pRecordOrder = (PRECORDCORE) CMA_END;
436 ri.pRecordParent = (PRECORDCORE) pciParent;
437 ri.zOrder = (ULONG) CMA_TOP;
438 ri.cRecordsInsert = 1L;
439 ri.fInvalidateRecord = TRUE;
440 if (!WinSendMsg(hwndCnr,
441 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
442 DosSleep(100L);
443 WinSetFocus(HWND_DESKTOP, hwndCnr);
444 if (WinIsWindow((HAB) 0, hwndCnr)) {
445 if (!WinSendMsg(hwndCnr,
446 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
447 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
448 GetPString(IDS_RECORDINSERTFAILEDTEXT));
449 WinSendMsg(hwndCnr,
450 CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(1));
451 }
452 else
453 ret = TRUE;
454 }
455 }
456 else
457 ret = TRUE;
458 }
459 }
460 else if (toupper(*str) > 'B' && str[1] == ':' && str[2] == '\\' &&
461 !str[3]) {
462
463 CHAR s[162];
464
465 sprintf(s,
466 GetPString(IDS_NOSUBDIRS2TEXT),
467 nm,
468 toupper(*pciParent->pszFileName),
469 (isremote) ? GetPString(IDS_NOSUBDIRS3TEXT) : NullStr);
470 Notify(s);
471 }
472 }
473 }
474 else if (toupper(*str) > 'B' && rc != ERROR_NO_MORE_FILES) {
475
476 CHAR s[CCHMAXPATH + 80];
477
478 sprintf(s, GetPString(IDS_SEARCHERRORTEXT), rc, str);
479 Notify(s);
480 }
481
482None:
483
484 DosError(FERR_DISABLEHARDERR);
485 return ret;
486}
Note: See TracBrowser for help on using the repository browser.