source: trunk/dll/copyf.c@ 1878

Last change on this file since 1878 was 1878, checked in by Gregg Young, 10 years ago

Remove some dead code and comments source files starting with A-D

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