source: trunk/dll/flesh.c@ 730

Last change on this file since 730 was 730, checked in by Gregg Young, 18 years ago

Preliminary work on variable sized container buffers. Removes szFileName etc. Builds fine but traps.

  • 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 730 2007-07-22 17:57:09Z gyoung $
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, TRUE, TRUE, NULL, dcd, NULL, NULL);
181 }
182 return TRUE;
183}
184
185BOOL UnFlesh(HWND hwndCnr, PCNRITEM pciParent)
186{
187 BOOL ret = FALSE;
188 PCNRITEM pciL;
189
190 if (!pciParent || !hwndCnr)
191 return FALSE;
192 for (;;) {
193 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
194 CM_QUERYRECORD,
195 MPFROMP(pciParent),
196 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
197 if (pciL && (INT) pciL != -1) {
198 ret = TRUE;
199 WinSendMsg(hwndCnr,
200 CM_REMOVERECORD, MPFROMP(&pciL), MPFROM2SHORT(1, CMA_FREE));
201 }
202 else
203 break;
204 }
205 if (ret) {
206 WinSendMsg(hwndCnr,
207 CM_INVALIDATERECORD,
208 MPFROMP(&pciParent),
209 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
210 }
211 return ret;
212}
213
214#define DDEPTH 16
215
216BOOL Stubby(HWND hwndCnr, PCNRITEM pciParent)
217{
218 /*
219 * this code is full of workarounds for screwed up LANs.
220 * let's hope all the current LAN programmers fall into
221 * a black hole and make way for people who can get it right...
222 */
223
224 BOOL ret = FALSE;
225 FILEFINDBUF3 ffb[DDEPTH];
226 PFILEFINDBUF3 pffb;
227 HDIR hDir = HDIR_CREATE;
228 ULONG nm, ulM = 1L, total = 0L, fl = MUST_HAVE_DIRECTORY;
229 CHAR str[CCHMAXPATH];
230 register INT len;
231 APIRET rc, prc;
232 BOOL isadir = FALSE, isremote = FALSE, includefiles = fFilesInTree;
233 ULONG ddepth = 3L;
234 static BOOL brokenlan = FALSE, isbroken = FALSE;
235 CHAR *f = 0;
236
237 if (!pciParent || !*pciParent->pszFileName || !hwndCnr)
238 return FALSE;
239
240 len = strlen(pciParent->pszFileName);
241 memcpy(str, pciParent->pszFileName, len + 1);
242 if (str[len - 1] != '\\')
243 str[len++] = '\\';
244 str[len++] = '*';
245 str[len] = 0;
246
247 if (!isalpha(*str) || str[1] != ':' || str[2] != '\\')
248 MakeFullName(str);
249
250 if (!isalpha(*str) ||
251 str[1] != ':' ||
252 str[2] != '\\' || ((driveflags[toupper(*str) - 'A'] & DRIVE_IGNORE)))
253 return FALSE;
254
255 if (isalpha(*str) && driveflags[toupper(*str) - 'A'] & DRIVE_INCLUDEFILES)
256 includefiles = TRUE;
257
258 if (!isalpha(*str) ||
259 str[1] != ':' ||
260 str[2] != '\\' || ((driveflags[toupper(*str) - 'A'] & DRIVE_REMOTE)))
261 isremote = TRUE;
262
263 if (isremote) {
264 ddepth = 14;
265 if (fRemoteBug) {
266 if (brokenlan) {
267 ddepth = (ULONG) - 1;
268 ddepth--;
269 }
270 ulM = 1L;
271 }
272 }
273 else if (isbroken)
274 ddepth = 14;
275
276 if (!isremote || !fRemoteBug)
277 ulM = (ddepth < 16L) ? ddepth : 1L;
278
279 nm = ulM;
280
281 DosError(FERR_DISABLEHARDERR);
282 if (includefiles)
283 fl = FILE_DIRECTORY;
284 rc = DosFindFirst(str,
285 &hDir,
286 FILE_NORMAL | fl |
287 FILE_READONLY | FILE_ARCHIVED |
288 FILE_SYSTEM | FILE_HIDDEN,
289 &ffb, ulM * sizeof(FILEFINDBUF3), &nm, FIL_STANDARD);
290 if (ulM == 1L && !rc) {
291 do {
292 pffb = &ffb[0];
293 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY) && !brokenlan) {
294 brokenlan = TRUE;
295 ddepth = (ULONG) - 1L;
296 ddepth--;
297 if (!NoBrokenNotify) {
298 prc = saymsg(MB_YESNO | MB_ICONEXCLAMATION,
299 HWND_DESKTOP,
300 GetPString(IDS_LANERRORTITLETEXT),
301 GetPString(IDS_LANERRORTEXT));
302 if (prc == MBID_NO) {
303 saymsg(MB_ENTER,
304 HWND_DESKTOP,
305 GetPString(IDS_LANERROR2TITLETEXT),
306 GetPString(IDS_LANERROR2TEXT));
307 NoBrokenNotify = 255L;
308 PrfWriteProfileData(fmprof,
309 FM3Str,
310 "NoBrokenNotify",
311 &NoBrokenNotify, sizeof(ULONG));
312 }
313 }
314 else {
315 NoBrokenNotify--;
316 PrfWriteProfileData(fmprof,
317 FM3Str,
318 "NoBrokenNotify",
319 &NoBrokenNotify, sizeof(ULONG));
320 }
321 }
322 if (*pffb->achName &&
323 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
324 // Skip . and ..
325 (pffb->achName[0] != '.' ||
326 (pffb->achName[1] &&
327 (pffb->achName[1] != '.' || pffb->achName[2])))) {
328 DosFindClose(hDir);
329 isadir = TRUE;
330 goto Interruptus;
331 }
332 nm = 1L;
333 DosError(FERR_DISABLEHARDERR);
334 } while (++total < ddepth && !(rc = (DosFindNext(hDir,
335 &ffb,
336 sizeof(FILEFINDBUF3),
337 &nm))));
338 DosFindClose(hDir);
339 if (toupper(*pciParent->pszFileName) > 'B' &&
340 (*(pciParent->pszFileName + 1)) == ':' &&
341 (*(pciParent->pszFileName + 2)) == '\\' && !(*(pciParent->pszFileName + 3))) {
342
343 CHAR s[132];
344
345 sprintf(s,
346 GetPString(IDS_NOSUBDIRSTEXT),
347 total, toupper(*pciParent->pszFileName));
348 if (rc && rc != ERROR_NO_MORE_FILES)
349 sprintf(&s[strlen(s)], GetPString(IDS_SEARCHERRORTEXT), rc, str);
350 else if (ddepth < 16L)
351 brokenlan = TRUE;
352 Notify(s);
353 }
354 goto None;
355 }
356
357 if (!rc) {
358 DosFindClose(hDir);
359 if (nm) {
360
361 register PBYTE fb = (PBYTE) & ffb[0];
362
363 for (len = 0; len < nm; len++) {
364 pffb = (PFILEFINDBUF3) fb;
365 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY)) {
366 if (!isbroken) {
367 isbroken = TRUE;
368 if (!NoBrokenNotify) {
369 prc = saymsg(MB_YESNO | MB_ICONEXCLAMATION,
370 HWND_DESKTOP,
371 GetPString(IDS_FSDERRORTITLETEXT),
372 GetPString(IDS_FSDERRORTEXT),
373 (isremote) ?
374 GetPString(IDS_REMOTETEXT) :
375 GetPString(IDS_LOCALTEXT), *str);
376 if (prc == MBID_NO) {
377 saymsg(MB_ENTER,
378 HWND_DESKTOP,
379 GetPString(IDS_FSDERROR2TITLETEXT),
380 GetPString(IDS_FSDERROR2TEXT));
381 NoBrokenNotify = 255L;
382 PrfWriteProfileData(fmprof,
383 FM3Str,
384 "NoBrokenNotify",
385 &NoBrokenNotify, sizeof(ULONG));
386 }
387 }
388 else {
389 NoBrokenNotify--;
390 PrfWriteProfileData(fmprof,
391 FM3Str,
392 "NoBrokenNotify",
393 &NoBrokenNotify, sizeof(ULONG));
394 }
395 }
396 }
397 if (*pffb->achName &&
398 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
399 // Skip . and ..
400 (pffb->achName[0] != '.' || (pffb->achName[1]
401 && (pffb->achName[1] != '.'
402 || pffb->achName[2])))) {
403 isadir = TRUE;
404 break;
405 }
406 fb += pffb->oNextEntryOffset;
407 }
408
409 Interruptus:
410
411 if (isadir) {
412
413 PCNRITEM pci;
414
415 pci = WinSendMsg(hwndCnr,
416 CM_ALLOCRECORD,
417 MPFROMLONG(EXTRA_RECORD_BYTES2), MPFROMLONG(1L));
418 if (!pci) {
419 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
420 GetPString(IDS_RECORDALLOCFAILEDTEXT));
421 }
422 else {
423 RECORDINSERT ri;
424 pci->pszFileName = xstrdup(f, pszSrcFile, __LINE__);
425 //pci->pszFileName = pci->szFileName;
426 pci->rc.pszIcon = pci->pszFileName;
427 memset(&ri, 0, sizeof(RECORDINSERT));
428 ri.cb = sizeof(RECORDINSERT);
429 ri.pRecordOrder = (PRECORDCORE) CMA_END;
430 ri.pRecordParent = (PRECORDCORE) pciParent;
431 ri.zOrder = (ULONG) CMA_TOP;
432 ri.cRecordsInsert = 1L;
433 ri.fInvalidateRecord = TRUE;
434 if (!WinSendMsg(hwndCnr,
435 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
436 DosSleep(100L);
437 WinSetFocus(HWND_DESKTOP, hwndCnr);
438 if (WinIsWindow((HAB) 0, hwndCnr)) {
439 if (!WinSendMsg(hwndCnr,
440 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
441 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
442 GetPString(IDS_RECORDINSERTFAILEDTEXT));
443 WinSendMsg(hwndCnr,
444 CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(1));
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.