source: trunk/dll/copyf.c@ 1444

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

Rework of drivebar to rescan all drives and refresh media buttons and menu items grey out inappropriate menu items. Streamline Tree scan code and use semaphores to serialize access. Add NOEASUPPORT and LOCALHD driveflag; .LONGNAME usage fixes; (Tickets 377-386)

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