source: trunk/dll/copyf.c@ 1439

Last change on this file since 1439 was 1439, checked in by Gregg Young, 16 years ago

Changes to allow high mem loading of dll; Refactor .LONGNAME and .SUBJECT EA fetch to FetchCommonEAs. Add szFSType to FillInRecordFromFSA use to bypass EA scan and size formatting for tree container; Fix labels/FS type to work on scan on NOPRESCAN Drives; Fixed dbl directory names on restore of dir cnrs; (Tickets 47, 339, 363, 368, 369, 370)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.5 KB
RevLine 
[29]1
2/***********************************************************************
3
4 $Id: copyf.c 1439 2009-07-12 21:57:04Z gyoung $
5
6 Copy functions
7
8 Copyright (c) 1993-98 M. Kimes
[1082]9 Copyright (c) 2001, 2008 Steven H.Levine
[29]10
[173]11 14 Sep 02 SHL Drop obsolete debug code
12 14 Oct 02 SHL Drop obsolete debug code
13 10 Nov 02 SHL docopyf - don't forget to terminate longname
[1163]14 optimize longname logic
[173]15 01 Aug 04 SHL Rework lstrip/rstrip usage
16 28 May 05 SHL Drop debug code
[347]17 14 Jul 06 SHL Use Runtime_Error
[793]18 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[827]19 01 Sep 07 GKY Use xDosSetPathInfo to fix case where FS3 buffer crosses 64k boundry
[985]20 29 Feb 08 GKY Use xfree where appropriate
[1082]21 19 Jul 08 GKY Modify MakeTempName for use making temp directory names
[1402]22 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
[1438]23 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
[1439]24 12 Jul 09 GKY Add xDosQueryAppType and xDoxAlloc... to allow FM/2 to load in high memory
[29]25
26***********************************************************************/
27
[907]28#include <stdlib.h>
29#include <string.h>
30#include <stdarg.h>
31#include <ctype.h>
32
[2]33#define INCL_DOS
34#define INCL_DOSERRORS
35#define INCL_WIN
[841]36#define INCL_LONGLONG
[2]37
[1188]38#include "fm3dll.h"
[1222]39#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
[1206]40#include "killproc.h" // Data declaration(s)
41#include "notebook.h" // Data declaration(s)
42#include "info.h" // Data declaration(s)
43#include "init.h" // Data declaration(s)
44#include "arccnrs.h"
[907]45#include "fm3str.h"
[1163]46#include "errutil.h" // Dos_Error...
47#include "strutil.h" // GetPString
48#include "copyf.h"
49#include "literal.h" // fixup
[1188]50#include "misc.h" // Broadcast
51#include "valid.h" // MakeFullName
52#include "wrappers.h" // xDosSetPathInfo
53#include "strips.h" // bstrip
[1438]54#include "fortify.h"
55#include "pathutil.h" // AddBackslashToPath
[2]56
[347]57static PSZ pszSrcFile = __FILE__;
58
[1188]59static CHAR *GetLongName(CHAR * oldname, CHAR * buffer);
60static CHAR *TruncName(CHAR * oldname, CHAR * buffer);
61
[1163]62//static CHAR default_disk(VOID);
63//static INT unlink_allf(CHAR * string, ...);
64
[2]65#ifndef WinMoveObject
[551]66HOBJECT APIENTRY WinMoveObject(HOBJECT hObjectofObject,
[1163]67 HOBJECT hObjectofDest, ULONG ulReserved);
[2]68#endif
69#ifndef WinCopyObject
[551]70HOBJECT APIENTRY WinCopyObject(HOBJECT hObjectofObject,
[1163]71 HOBJECT hObjectofDest, ULONG ulReserved);
[2]72#endif
73
[1082]74char *MakeTempName(char *buffer, char *temproot, INT type)
[347]75{
[843]76 FILESTATUS3 fs3;
[551]77 APIRET rc;
78 char *p, *o;
[2]79
[1438]80
81 if (strlen(buffer) > 3) // && buffer[strlen(buffer) - 1] != '\\')
82 AddBackslashToPath(buffer);
83 //strcat(buffer, "\\");
[2]84 p = o = buffer + strlen(buffer);
[1082]85 switch (type) {
86 case 0:
87 sprintf(p, "%08lx.%03lx", rand() & 4095L, mypid);
88 break;
89 case 1:
90 sprintf(p, "%s%04lx.%03lx", "$FM2", rand() & 4095L, mypid);
91 break;
92 case 2:
93 sprintf(p, "%s.%03x", temproot, (rand() & 4095));
94 break;
95 default:
96 break;
97 }
[2]98 p = buffer + (strlen(buffer) - 1);
[551]99 for (;;) {
[2]100 DosError(FERR_DISABLEHARDERR);
[843]101 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
[551]102 if (rc == ERROR_DISK_CHANGE) {
[2]103 DosError(FERR_ENABLEHARDERR);
[843]104 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
[2]105 }
[551]106 if (rc)
[2]107 break;
[551]108 Loop:
109 if (p < o) {
[2]110 *buffer = 0;
111 return NULL;
112 }
[551]113 if ((*p) + 1 < 'Z' + 1) {
[2]114 (*p)++;
[551]115 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
[1163]116 (*p)++;
[2]117 *p = toupper(*p);
118 }
119 else {
120 p--;
[551]121 if (p >= o && *p == '.')
[1163]122 p--;
[2]123 goto Loop;
124 }
125 }
126 return buffer;
127}
128
[551]129CHAR *TruncName(CHAR * oldname, CHAR * buffer)
[347]130{
[551]131 CHAR *p, *f, *s, *o;
[843]132 FILESTATUS3 fs3;
[551]133 APIRET rc;
[2]134
[551]135 if (!buffer || !oldname || !*oldname) {
136 if (buffer)
[2]137 *buffer = 0;
138 return NULL;
139 }
[551]140 strcpy(buffer, oldname);
141 f = strrchr(buffer, '\\');
142 if (!f)
143 f = strrchr(buffer, '/');
144 if (!f)
[2]145 f = buffer;
146 else
147 f++;
148 p = f;
149 o = p;
150 f = oldname + (f - buffer);
151 strupr(buffer);
[1163]152 while (*f == '.') /* skip leading '.'s */
[2]153 f++;
154 s = f;
[1163]155 while (*f && *f != '.' && f < s + 8) { /* skip past rootname */
[2]156 *p = toupper(*f);
157 p++;
158 f++;
159 }
[551]160 while (*f == '.')
[2]161 f++;
162 s = f;
[551]163 f = strrchr(f, '.');
164 if (f) {
165 while (*f == '.')
[2]166 f++;
167 }
[551]168 if (f && *(f + 1))
[2]169 s = f;
170 else
171 f = s;
[551]172 if (*f) {
[2]173 *p = '.';
174 p++;
[551]175 while (*f && *f != '.' && f < s + 3) {
[2]176 *p = toupper(*f);
177 p++;
178 f++;
179 }
180 }
181 *p = 0;
182
183 p = o;
[551]184 while (*p) {
185 if (strchr("*?<>\":/\\|+=;,[] ", *p) || *p < 0x20)
[2]186 *p = '_';
[551]187 if (*p == '.' && *(p + 1) == '.')
[2]188 *(p + 1) = '_';
189 p++;
190 }
191
192 p = o + (strlen(o) - 1);
[551]193 for (;;) {
[2]194 DosError(FERR_DISABLEHARDERR);
[843]195 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
[551]196 if (rc == ERROR_DISK_CHANGE) {
[2]197 DosError(FERR_ENABLEHARDERR);
[843]198 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
[2]199 }
[551]200 if (rc)
[2]201 break;
[551]202 Loop:
203 if (p < o) {
[2]204 *buffer = 0;
205 return NULL;
206 }
[551]207 if ((*p) + 1 < 'Z' + 1) {
[2]208 (*p)++;
[551]209 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
[1163]210 (*p)++;
[2]211 *p = toupper(*p);
212 }
213 else {
214 p--;
[551]215 if (p >= o && *p == '.')
[1163]216 p--;
[2]217 goto Loop;
218 }
219 }
220 return buffer;
221}
222
[551]223CHAR *GetLongName(CHAR * oldname, CHAR * longname)
[347]224{
[551]225 if (!longname)
[2]226 return NULL;
227 *longname = 0;
[551]228 if (!oldname || !*oldname)
[2]229 return NULL;
[551]230 if (IsFullName(oldname)) {
[2]231
[551]232 APIRET rc;
233 EAOP2 eaop;
[2]234 PGEA2LIST pgealist;
235 PFEA2LIST pfealist;
[551]236 PGEA2 pgea;
237 PFEA2 pfea;
238 CHAR *value;
[2]239
[551]240 strcpy(longname, oldname);
[2]241 value = longname;
[551]242 while (*value) {
243 if (*value == '/')
[1163]244 *value = '\\';
[2]245 value++;
246 }
[551]247 value = strrchr(longname, '\\');
248 if (value) {
[2]249 value++;
250 *value = 0;
251 }
[551]252 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
[347]253 if (pgealist) {
[2]254 pgea = &pgealist->list[0];
[551]255 strcpy(pgea->szName, LONGNAME);
[2]256 pgea->cbName = strlen(pgea->szName);
257 pgea->oNextEntryOffset = 0L;
258 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
[551]259 pfealist = xmallocz(1536, pszSrcFile, __LINE__);
[347]260 if (pfealist) {
[1163]261 pfealist->cbList = 1024;
262 eaop.fpGEA2List = pgealist;
263 eaop.fpFEA2List = pfealist;
264 eaop.oError = 0L;
265 DosError(FERR_DISABLEHARDERR);
266 rc = DosQueryPathInfo(oldname,
267 FIL_QUERYEASFROMLIST,
268 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
269 if (!rc) {
270 pfea = &eaop.fpFEA2List->list[0];
271 value = pfea->szName + pfea->cbName + 1;
272 value[pfea->cbValue] = 0;
273 if (*(USHORT *) value == EAT_ASCII)
274 strncat(longname,
275 value + (sizeof(USHORT) * 2),
276 CCHMAXPATH - strlen(longname));
277 longname[CCHMAXPATH - 1] = 0;
278 }
279 free(pfealist);
[2]280 }
[1039]281 free(pgealist);
[2]282 }
283 }
284 return longname;
285}
286
[551]287BOOL ZapLongName(char *filename)
[347]288{
[1438]289 return WriteLongName(filename, NullStr);
[2]290}
291
[551]292BOOL WriteLongName(CHAR * filename, CHAR * longname)
[347]293{
[551]294 APIRET rc;
295 EAOP2 eaop;
[2]296 PFEA2LIST pfealist = NULL;
[551]297 ULONG ealen;
298 USHORT len;
299 CHAR *eaval, *p;
[2]300
[551]301 if (!filename || !*filename || !longname)
[2]302 return FALSE;
[551]303 p = strrchr(longname, '\\');
304 if (p)
305 memmove(longname, p + 1, strlen(p + 1) + 1);
306 p = strrchr(longname, '/');
307 if (p)
308 memmove(longname, p + 1, strlen(p + 1) + 1);
[123]309 bstrip(longname);
[2]310 len = strlen(longname);
[551]311 if (len)
[2]312 ealen = sizeof(FEA2LIST) + 10 + len + 4;
313 else
314 ealen = sizeof(FEALIST) + 10;
[1438]315 rc = xDosAllocMem((PPVOID) & pfealist,
[1439]316 ealen + 32L, PAG_COMMIT | PAG_READ | PAG_WRITE,
317 pszSrcFile, __LINE__);
[347]318 if (rc)
[551]319 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
[1163]320 GetPString(IDS_OUTOFMEMORY));
[347]321 else {
[551]322 memset(pfealist, 0, ealen + 1);
[2]323 pfealist->cbList = ealen;
[841]324 pfealist->list[0].oNextEntryOffset = 0;
[2]325 pfealist->list[0].fEA = 0;
326 pfealist->list[0].cbName = 9;
[551]327 strcpy(pfealist->list[0].szName, LONGNAME);
328 if (len) {
[2]329 eaval = pfealist->list[0].szName + 10;
[551]330 *(USHORT *) eaval = (USHORT) EAT_ASCII;
[2]331 eaval += sizeof(USHORT);
[551]332 *(USHORT *) eaval = (USHORT) len;
[2]333 eaval += sizeof(USHORT);
[551]334 memcpy(eaval, longname, len);
[2]335 pfealist->list[0].cbValue = len + (sizeof(USHORT) * 2);
336 }
337 else
338 pfealist->list[0].cbValue = 0;
[551]339 eaop.fpGEA2List = (PGEA2LIST) 0;
[2]340 eaop.fpFEA2List = pfealist;
341 eaop.oError = 0L;
342 DosError(FERR_DISABLEHARDERR);
[827]343 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
[1163]344 &eaop, sizeof(eaop), DSPI_WRTTHRU);
[2]345 DosFreeMem(pfealist);
[551]346 if (rc)
[2]347 return FALSE;
348 }
349 return TRUE;
350}
351
[551]352BOOL AdjustWildcardName(CHAR * oldname, CHAR * newname)
[347]353{
[2]354 BOOL ret = FALSE;
355
[827]356 /* NOTE: newname should be CCHMAXPATH chars long! */
[2]357
[551]358 if (strchr(newname, '*') || strchr(newname, '?')) {
[2]359
[551]360 CHAR srce[CCHMAXPATHCOMP], dest[CCHMAXPATHCOMP], result[CCHMAXPATHCOMP],
[1321]361 *p;
[2]362
[551]363 p = strrchr(newname, '\\');
364 if (p && *(p + 1)) {
365 strcpy(dest, p + 1);
366 p = strrchr(oldname, '\\');
367 if (p && *(p + 1)) {
[1163]368 strcpy(srce, p + 1);
369 DosError(FERR_DISABLEHARDERR);
[1321]370 if (!DosEditName(1L, srce, dest, (PBYTE)result, (ULONG)sizeof(result))) {
[1163]371 p = strrchr(newname, '\\');
372 p++;
373 strcpy(p, result);
374 ret = TRUE;
375 }
[2]376 }
377 }
378 }
379 return ret;
380}
381
[1193]382#if 0 // JBS 11 Sep 08
[551]383CHAR default_disk(VOID)
[347]384{
[551]385 ULONG ulDriveNum, ulDriveMap;
[2]386
387 DosError(FERR_DISABLEHARDERR);
[551]388 DosQCurDisk(&ulDriveNum, &ulDriveMap);
389 return (CHAR) toupper((INT) ulDriveNum) + '@';
[2]390}
[1163]391#endif
[2]392
393#ifdef NEVER
394
[551]395APIRET docopyallf(INT type, CHAR * oldname, CHAR * newname, ...)
[347]396{
[847]397 FILEFINDBUF3 fb;
[551]398 ULONG nm;
399 HDIR hdir;
400 APIRET rc = 0;
401 CHAR *enddir, fullname[CCHMAXPATH];
[2]402
[551]403 va_start(ap, newname);
404 vsprintf(fullname, newname, ap);
[2]405 va_end(ap);
406
407 DosError(FERR_DISABLEHARDERR);
[847]408 if (!DosFindFirst(oldname)) {
[2]409 do {
410
411 /* build target name */
412
[551]413 if (fb.attrFile & FILE_DIRECTORY) {
[1163]414 DosError(FERR_ENABLEHARDERR);
415 rc = DosCreateDir();
416 if (rc == ERROR_INVALID_NAME || rc == ERROR_FILENAME_EXCED_RANGE) {
[2]417
[1163]418 /* truncate directory name */
419 /* create that directory */
420 /* update containers for name used */
[2]421
[1163]422 }
423 rc = docopyallf(type,, "%s",); /* recurse */
[2]424 }
425 else
[1402]426 // docopyf changed this won't work rc = docopyf(type,, "%s",); /* copy file */
[2]427 DosError(FERR_DISABLEHARDERR);
[847]428 } while (!rc && !DosFindNext());
[2]429 DosFindClose(hdir);
430 }
431 else
432 rc = ERROR_FILE_NOT_FOUND;
433 return rc;
434}
435
436#endif
437
[1402]438APIRET docopyf(INT type, CHAR *oldname, CHAR *newname)
[347]439{
[2]440 /*
441 * returns:
442 * 0: success
443 * -1: bad string parameter(s)
444 * -2: source didn't exist
445 * -3: bad type
[827]446 * anything else: API return
[2]447 */
448
[1402]449 CHAR longname[CCHMAXPATH], shortname[CCHMAXPATH];
[551]450 CHAR olddisk, newdisk, dir[CCHMAXPATH], *p, *pp;
451 APIRET ret = -1, rc;
[841]452 FILESTATUS3L st, st2, dummy;
[551]453 BOOL diskchange = FALSE, zaplong = FALSE;
[2]454
[1402]455 *shortname = *dir = 0;
[2]456
[1402]457 if (!oldname || !*oldname || !*newname) /* bad string args */
[551]458 return (APIRET) - 1;
[29]459
[2]460 DosError(FERR_DISABLEHARDERR);
[841]461 if (DosQueryPathInfo(oldname, FIL_STANDARDL, &st, sizeof(FILESTATUS3L)))
[1163]462 return (APIRET) - 2; /* no source */
[29]463
[1402]464 AdjustWildcardName(oldname, newname);
[2]465 MakeFullName(oldname);
[1402]466 MakeFullName(newname);
[1163]467 olddisk = toupper(*oldname); /* source drive */
[1402]468 newdisk = toupper(*newname); /* destination drive */
[551]469 if (!(driveflags[toupper(*oldname) - 'A'] & DRIVE_NOLONGNAMES))
[45]470 *longname = 0;
[551]471 else {
[45]472 GetLongName(oldname, longname);
[551]473 if (*longname) {
[2]474 p = RootName(longname);
[551]475 if (p != longname)
[1163]476 memmove(longname, p, strlen(p) + 1);
[2]477 }
[45]478 }
479 /* If root name changed make sure longname EA goes away */
480 p = RootName(oldname);
[1402]481 pp = RootName(newname);
[551]482 if (stricmp(p, pp)) {
[45]483 zaplong = TRUE;
[2]484 }
485
486 DosError(FERR_DISABLEHARDERR);
[551]487 switch (type) {
488 case WPSMOVE:
489 {
490 HOBJECT hobjsrc;
491 HOBJECT hobjdest;
[2]492
[551]493 ret = ERROR_FILE_NOT_FOUND;
494 hobjsrc = WinQueryObject(oldname);
495 if (hobjsrc) {
[1402]496 strcpy(dir, newname);
[1163]497 p = strrchr(dir, '\\');
498 if (p < dir + 3)
499 p++;
500 *p = 0;
501 ret = ERROR_PATH_NOT_FOUND;
502 hobjdest = WinQueryObject(dir);
503 if (hobjdest) {
504 ret = ERROR_GEN_FAILURE;
505 hobjsrc = WinMoveObject(hobjsrc, hobjdest, 0);
506 if (hobjsrc)
507 ret = 0;
508 }
[2]509 }
[551]510 }
511 return ret;
[2]512
[551]513 case WPSCOPY:
514 {
515 HOBJECT hobjsrc;
516 HOBJECT hobjdest;
[2]517
[551]518 ret = ERROR_FILE_NOT_FOUND;
519 hobjsrc = WinQueryObject(oldname);
520 if (hobjsrc) {
[1402]521 strcpy(dir, newname);
[1163]522 p = strrchr(dir, '\\');
523 if (p < dir + 3)
524 p++;
525 *p = 0;
526 ret = ERROR_PATH_NOT_FOUND;
527 hobjdest = WinQueryObject(dir);
528 if (hobjdest) {
529 ret = ERROR_GEN_FAILURE;
530 hobjsrc = WinCopyObject(hobjsrc, hobjdest, 0);
531 if (hobjsrc)
532 ret = 0;
533 }
[2]534 }
[551]535 }
536 return ret;
[2]537
[551]538 case MOVE:
539 *dir = 0;
[1163]540 if (olddisk == newdisk) { /* same drive */
[551]541 /* make temporary copy in case move fails */
[1402]542 if (IsFile(newname) != -1 && stricmp(oldname, newname)) {
543 strcpy(dir, newname);
[1438]544 AddBackslashToPath(dir);
545 //p = strrchr(dir, '\\');
546 //if (p)
547 // *p = 0;
548 //strcat(dir, "\\");
[1163]549 MakeTempName(dir, NULL, 0);
[1402]550 if (DosMove(newname, dir))
[1163]551 *dir = 0;
[2]552 }
[551]553 DosError(FERR_DISABLEHARDERR);
[1402]554 ret = DosMove(oldname, newname); /* move it */
[1163]555 if (ret && *dir) { /* failed -- clean up */
556 DosError(FERR_DISABLEHARDERR);
[1402]557 if (!DosMove(dir, newname))
[1163]558 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(dir), MPVOID);
[551]559 }
560 else if (!ret && *dir) {
[1163]561 if (!IsFile(dir)) {
562 if (!strchr(dir, '?') && !strchr(dir, '*'))
563 wipeallf("%s\\*", dir);
564 DosError(FERR_DISABLEHARDERR);
565 if (DosDeleteDir(dir)) {
566 make_deleteable(dir);
567 DosDeleteDir(dir);
568 }
569 }
570 else if (IsFile(dir) > 0) {
571 DosError(FERR_DISABLEHARDERR);
572 if (DosForceDelete(dir)) {
573 make_deleteable(dir);
574 DosForceDelete(dir);
575 }
576 if (zaplong)
577 ZapLongName(dir);
578 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(dir), MPVOID);
579 }
[551]580 }
581 }
[1163]582 else { /* different drives */
[551]583 DosError(FERR_DISABLEHARDERR);
[1402]584 ret = DosCopy(oldname, newname, DCPY_EXISTING); /* <=-NOTE! */
[551]585 if (ret == ERROR_DISK_CHANGE) {
[1163]586 DosError(FERR_ENABLEHARDERR);
[1402]587 ret = DosCopy(oldname, newname, DCPY_EXISTING);
[1163]588 diskchange = TRUE;
[551]589 }
590 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
[1402]591 if (TruncName(newname, shortname)) { /* make 8.3 filename */
[1163]592 DosError(FERR_DISABLEHARDERR);
593 ret = DosCopy(oldname, shortname, DCPY_EXISTING);
594 if (!ret) { /* success -- write longname ea */
[1402]595 WriteLongName(shortname, newname);
596 strcpy(newname, shortname);
[1163]597 /* broadcast fixup msg to windows */
598 Broadcast((HAB) 0,
599 hwndMain, UM_UPDATERECORD, MPFROMP(shortname), MPVOID);
600 }
601 }
[551]602 }
603 else if (!ret && *longname) {
[2]604
[1163]605 CHAR fixname[CCHMAXPATH];
[2]606
[1402]607 strcpy(fixname, newname);
[1163]608 p = strrchr(fixname, '\\');
609 if (p) {
610 p++;
611 *p = 0;
612 }
613 strcat(fixname, longname);
614 DosError(FERR_DISABLEHARDERR);
[1402]615 DosMove(newname, fixname);
616 strcpy(newname, fixname);
[1163]617 if (zaplong)
618 ZapLongName(fixname);
619 Broadcast((HAB) 0,
620 hwndMain, UM_UPDATERECORD, MPFROMP(fixname), MPVOID);
[2]621 }
[1163]622 if (!ret) { /* double-check success */
623 DosError(FERR_DISABLEHARDERR);
[1402]624 rc = DosQueryPathInfo(newname,
[1163]625 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
626 if (rc == ERROR_DISK_CHANGE) {
627 DosError(FERR_ENABLEHARDERR);
[1402]628 rc = DosQueryPathInfo(newname,
[1163]629 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
630 }
631 if (!rc && st2.cbFile == st.cbFile) { /* seems to have worked... */
632 DosError(FERR_DISABLEHARDERR);
633 if (diskchange) {
634 DosError(FERR_ENABLEHARDERR);
635 DosQueryPathInfo(oldname, FIL_STANDARDL, &dummy, sizeof(FILESTATUS3L)); /* force disk change */
636 }
637 if (!(st2.attrFile & FILE_DIRECTORY)) /* erase file */
[1402]638 unlinkf(oldname);
[1163]639 else { /* remove directory */
640 wipeallf("%s\\*", oldname);
641 DosError(FERR_DISABLEHARDERR);
642 if (DosDeleteDir(oldname)) {
643 make_deleteable(oldname);
644 DosDeleteDir(oldname);
645 }
646 }
647 }
[551]648 }
649 }
650 return ret;
[2]651
[551]652 case COPY:
653 DosError(FERR_DISABLEHARDERR);
[1402]654 ret = DosCopy(oldname, newname, DCPY_EXISTING); /* <=-NOTE! */
[551]655 if (ret == ERROR_DISK_CHANGE) {
656 DosError(FERR_ENABLEHARDERR);
[1402]657 ret = DosCopy(oldname, newname, DCPY_EXISTING);
[551]658 diskchange = TRUE;
659 }
660 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
[1402]661 if (TruncName(newname, shortname)) {
[1163]662 DosError((diskchange) ? FERR_ENABLEHARDERR : FERR_DISABLEHARDERR);
663 ret = DosCopy(oldname, shortname, DCPY_EXISTING);
664 if (!ret) {
[1402]665 WriteLongName(shortname, newname);
666 strcpy(newname, shortname);
[1163]667 Broadcast((HAB) 0,
668 hwndMain, UM_UPDATERECORD, MPFROMP(shortname), MPVOID);
669 }
[2]670 }
[551]671 }
672 else if (!ret && *longname) {
[2]673
[551]674 CHAR fixname[CCHMAXPATH];
[2]675
[1402]676 strcpy(fixname, newname);
[551]677 p = strrchr(fixname, '\\');
678 if (p) {
[1163]679 p++;
680 *p = 0;
[2]681 }
[551]682 strcat(fixname, longname);
683 DosError(FERR_DISABLEHARDERR);
[1402]684 DosMove(newname, fixname);
[551]685 if (zaplong)
[1163]686 ZapLongName(fixname);
[551]687 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(fixname), MPVOID);
688 }
689 return ret;
[2]690
[1163]691 default: /* shouldn't happen */
[551]692 Runtime_Error(pszSrcFile, __LINE__, "bad case %u", type);
693 break;
[2]694 }
[1163]695 return (APIRET) - 3; /* bad type */
[2]696}
697
[551]698INT make_deleteable(CHAR * filename)
[347]699{
[2]700 INT ret = -1;
[847]701 FILESTATUS3 fsi;
[2]702
703 DosError(FERR_DISABLEHARDERR);
[847]704 if (!DosQueryPathInfo(filename, FIL_STANDARD, &fsi, sizeof(fsi))) {
[2]705 fsi.attrFile = 0;
706 DosError(FERR_DISABLEHARDERR);
[847]707 if (!xDosSetPathInfo(filename, FIL_STANDARD, &fsi, sizeof(fsi), 0))
[2]708 ret = 0;
709 }
710 return ret;
711}
712
[827]713INT wipeallf(CHAR *string, ...)
[347]714{
[2]715 /* unlink everything from directory on down... */
716
[847]717 FILEFINDBUF3 *f;
[551]718 HDIR search_handle;
719 ULONG num_matches;
720 CHAR *p, *ss, *str;
721 CHAR s[CCHMAXPATH], mask[257];
722 va_list ap;
723 INT rc;
[2]724
[551]725 va_start(ap, string);
726 vsprintf(s, string, ap);
[2]727 va_end(ap);
728
[551]729 if (!*s)
[2]730 return -1;
731 p = s;
[551]732 while ((p = strchr(p, '/')) != NULL) {
[2]733 *p = '\\';
734 p++;
735 }
736
[551]737 str = xstrdup(s, pszSrcFile, __LINE__);
738 if (!str)
[2]739 return -1;
740
[1163]741 { /* safety net -- disallow deleting a root dir or partial name */
[2]742 CHAR temp;
743
[551]744 p = strrchr(str, '\\');
745 if (p) {
[2]746 p++;
747 temp = *p;
748 *p = 0;
[551]749 if (IsRoot(str) || !IsFullName(str)) {
[1163]750 /* under no circumstances! */
751 Runtime_Error(pszSrcFile, __LINE__, "bad name %s", str);
752 free(str);
753 return -1;
[2]754 }
755 *p = temp;
756 }
757 }
758
759 p = s;
[1163]760 p = strrchr(s, '\\'); /* strip s to just path */
[551]761 if (!p)
762 p = strrchr(s, ':');
763 if (p) {
[2]764 p++;
[551]765 strncpy(mask, p, 256);
[2]766 mask[256] = 0;
767 *p = 0;
768 }
769 else {
770 *mask = 0;
771 *s = 0;
772 }
773
[551]774 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
[847]775 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
[347]776 if (!ss || !f) {
[1009]777 xfree(ss, pszSrcFile, __LINE__);
778 xfree(f, pszSrcFile, __LINE__);
[1039]779 free(str);
[2]780 return -1;
781 }
782
783 search_handle = HDIR_CREATE;
[841]784 num_matches = 1;
[2]785
786 DosError(FERR_DISABLEHARDERR);
[847]787 if (!DosFindFirst(str, &search_handle, FILE_NORMAL | FILE_DIRECTORY |
[1163]788 FILE_SYSTEM | FILE_READONLY | FILE_HIDDEN | FILE_ARCHIVED,
789 f, sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
[2]790
[551]791 strcpy(ss, s);
[2]792 p = &ss[strlen(ss)];
793
794 do {
[551]795 strcpy(p, f->achName);
796 if (f->attrFile & FILE_DIRECTORY) {
[1163]797 if (strcmp(f->achName, ".") && strcmp(f->achName, "..")) {
798 wipeallf("%s/%s", ss, mask); /* recurse to wipe files */
799 DosError(FERR_DISABLEHARDERR);
800 if (DosDeleteDir(ss)) { /* remove directory */
801 make_deleteable(ss);
802 DosError(FERR_DISABLEHARDERR);
803 DosDeleteDir(ss);
804 }
805 }
[2]806 }
807 else {
[1163]808 DosError(FERR_DISABLEHARDERR);
809 if (DosForceDelete(ss)) {
810 make_deleteable(ss);
811 DosError(FERR_DISABLEHARDERR);
812 rc = (INT) DosForceDelete(ss);
813 if (rc)
814 return rc;
815 }
[2]816 }
[847]817 num_matches = 1;
[2]818 DosError(FERR_DISABLEHARDERR);
[847]819 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
[1163]820 &num_matches));
[2]821 DosFindClose(search_handle);
822 }
823
[1039]824 free(f);
825 free(ss);
826 free(str);
[2]827 return 0;
828}
829
[1193]830#if 0 // JBS 11 Sep 08
[551]831INT unlink_allf(CHAR * string, ...)
[347]832{
[2]833 /* wildcard delete */
834
[847]835 FILEFINDBUF3 *f;
[551]836 HDIR search_handle;
[2]837 ULONG num_matches;
[551]838 CHAR *p, *ss, *str;
839 CHAR s[CCHMAXPATH];
[2]840 va_list ap;
841
[551]842 va_start(ap, string);
843 vsprintf(s, string, ap);
[2]844 va_end(ap);
845
[551]846 if (!*s)
[2]847 return -1;
848 p = s;
[551]849 while ((p = strchr(p, '/')) != NULL) {
[2]850 *p = '\\';
851 p++;
852 }
853
[551]854 str = xstrdup(s, pszSrcFile, __LINE__);
[347]855 if (!str)
[2]856 return -1;
857
858 p = s;
[1163]859 p = strrchr(s, '\\'); /* strip s to just path */
[551]860 if (!p)
861 p = strrchr(s, ':');
862 if (p) {
[2]863 p++;
864 *p = 0;
865 }
866 else
867 *s = 0;
868
[551]869 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
[847]870 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
[347]871 if (!ss || !f) {
[1009]872 xfree(ss, pszSrcFile, __LINE__);
873 xfree(f, pszSrcFile, __LINE__);
[1039]874 free(str);
[2]875 return -1;
876 }
877
878 search_handle = HDIR_CREATE;
[838]879 num_matches = 1;
[2]880
881 DosError(FERR_DISABLEHARDERR);
[847]882 if (!DosFindFirst(str, &search_handle, FILE_NORMAL, f,
[1163]883 sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
[2]884
[551]885 strcpy(ss, s);
[2]886 p = &ss[strlen(ss)];
887
888 do {
[551]889 strcpy(p, f->achName);
890 unlinkf("%s", ss);
[838]891 num_matches = 1;
[2]892 DosError(FERR_DISABLEHARDERR);
[847]893 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
[1163]894 &num_matches));
[2]895 DosFindClose(search_handle);
896 }
897
[1039]898 free(f);
899 free(ss);
900 free(str);
[2]901 return 0;
902}
[1163]903#endif
[2]904
[1402]905INT unlinkf(CHAR *string)
[347]906{
[2]907
[1402]908 if (!strstr(string, ArcTempRoot)) {
[2]909 DosError(FERR_DISABLEHARDERR);
[1402]910 if (DosDelete(string)) {
911 make_deleteable(string);
[2]912 DosError(FERR_DISABLEHARDERR);
[1402]913 return DosDelete(string);
[2]914 }
915 }
916 else {
917 DosError(FERR_DISABLEHARDERR);
[1402]918 if (DosForceDelete(string)) {
919 make_deleteable(string);
[2]920 DosError(FERR_DISABLEHARDERR);
[1402]921 return DosForceDelete(string);
[2]922 }
923 }
924 return 0;
925}
[793]926
927#pragma alloc_text(LONGNAMES,TruncName,GetLongName,WriteLongName)
928#pragma alloc_text(LONGNAMES,ZapLongName,AdjustWildcardName)
[1082]929#pragma alloc_text(COPYF,default_disk,docopyf,MakeTempName)
[793]930#pragma alloc_text(UNLINKF,unlinkf,unlink_allf,make_deleteable,wipeallf)
Note: See TracBrowser for help on using the repository browser.