source: trunk/dll/copyf.c@ 1741

Last change on this file since 1741 was 1741, checked in by Gregg Young, 12 years ago

Fix warn readonly yes don't ask to work when recursing directories.

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