source: trunk/dll/copyf.c@ 1687

Last change on this file since 1687 was 1686, checked in by Gregg Young, 13 years ago

GKY Improvrd readonly check on delete to allow cancel and don't ask again options; Added saymsg2 for this purpose; Fixes to snapshot file. cs 1685 contained the COMP.C changes

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