source: trunk/dll/copyf.c@ 1628

Last change on this file since 1628 was 1628, checked in by Gregg Young, 14 years ago

Hard coded the flags for the xDosAlloc* wrappers and added a description for each of them.

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