source: trunk/dll/copyf.c@ 1438

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

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

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