source: trunk/dll/flesh.c@ 858

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

Removed large file APIs from code where hey are not needed.

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