- Timestamp:
- Oct 8, 2002, 6:42:59 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/shell32/shlfileop.c
r9244 r9338 1 1 /* 2 2 * SHFileOperation 3 * 3 4 * Copyright 2000 Juergen Schmied 4 5 * Copyright 2002 Andriy Palamarchuk … … 22 23 #define ICOM_CINTERFACE 1 23 24 #include <odin.h> 25 #include "debugtools.h" 24 26 #endif 25 27 #include <string.h> 28 #ifdef __WIN32OS2__ 26 29 #include "debugtools.h" 30 #endif 31 #include "winreg.h" 27 32 #include "shellapi.h" 28 #include "shlwapi.h"29 30 33 #include "shlobj.h" 31 34 #include "shresdef.h" … … 33 36 #include "undocshell.h" 34 37 #include "shlwapi.h" 35 36 DEFAULT_DEBUG_CHANNEL(shell); 37 38 #include "wine/debug.h" 39 40 WINE_DEFAULT_DEBUG_CHANNEL(shell); 38 41 39 42 #ifdef __WIN32OS2__ … … 95 98 } 96 99 else { 97 FIXME("Called without a valid nKindOfDialog specified! ");100 FIXME("Called without a valid nKindOfDialog specified!\n"); 98 101 LoadStringA(shell32_hInstance, IDS_DELETEITEM_TEXT, szText, 99 102 sizeof(szText)); … … 202 205 } 203 206 207 #ifdef __WIN32OS2__ 208 /************************************************************************* 209 * 210 * SHFileTyp (internal) 211 * 212 */ 213 DWORD SHFileTyp(LPSTR pFromTo, long *len, LPSTR pTemp, long *lenTemp, LPSTR *pFile, DWORD *PathAttr, DWORD *Attr) { 214 #define TypisBad -1 215 #define TypisUnkn 0 216 #define TypisNewPath 1 217 #define TypisRoot 2 218 #define TypisDirS 3 219 #define TypisDir 4 220 #define TypisFile 5 221 #define TypisName 6 222 #define TypisNameS 7 223 #define TypisMask 8 224 DWORD Typ = TypisUnkn; 225 DWORD i_Attr; 226 DWORD i_PathAttr; 227 BOOL i_Slash = FALSE; 228 LPSTR i_pFile; 229 LPSTR i_pLastSlash; 230 long i_lenTemp; 231 long i_len = *len = strlen(pFromTo); 232 if (i_len == 0) return TypisUnkn; 233 strcpy(pTemp,pFromTo); 234 *pFile = i_pFile = &pTemp[i_len]; 235 pTemp[i_len+1] = '\0'; 236 if (i_len == 0) return /* ?? */ TypisBad; 237 if (PathIsRootA(pFromTo)) Typ = TypisRoot; 238 i_pLastSlash = strrchr(pTemp,'\\'); 239 if (i_pLastSlash == NULL) return TypisBad /* ??? */; 240 i_Slash = (i_pLastSlash[1] == '\0'); 241 *lenTemp = i_lenTemp = strlen(pTemp) - i_Slash; 242 *pFile = i_pFile = &pTemp[i_lenTemp]; 243 if (Typ != TypisRoot) i_pFile[0] = '\0'; 244 *PathAttr = *Attr = i_PathAttr = i_Attr = GetFileAttributesA(pTemp); 245 if (i_Attr == -1) { 246 if (Typ == TypisRoot) Typ = TypisBad; 247 } else { 248 if (i_Attr & FILE_ATTRIBUTE_DIRECTORY) { 249 if (Typ == TypisUnkn) { 250 Typ = TypisDir; 251 if (i_Slash) Typ = TypisDirS; 252 } 253 } else { 254 if (Typ == TypisUnkn && !i_Slash) { 255 Typ = TypisFile; 256 } else Typ = TypisBad; 257 } 258 } 259 // is the directory exists with \*.* ? 260 i_pFile = strrchr(pTemp,'\\'); 261 if (NULL == i_pFile) Typ = TypisBad; 262 if (Typ == TypisUnkn || Typ == TypisFile) { 263 PathRemoveFileSpecA(pTemp); 264 // mask in Path ? 265 if (NULL != strpbrk(pTemp,"*?\0")) { 266 Typ = TypisBad; 267 } else { 268 while (-1 == (i_PathAttr = GetFileAttributesA(pTemp)) && !PathIsRootA(pTemp)) { 269 PathRemoveFileSpecA(pTemp); 270 Typ = TypisNewPath; 271 } 272 i_lenTemp = strlen(pTemp); 273 if (pTemp[i_lenTemp - 1] == '\\') i_lenTemp--; 274 *lenTemp = i_lenTemp; 275 *pFile = i_pFile = &pTemp[i_lenTemp]; 276 *PathAttr = i_PathAttr; 277 if (-1 == i_PathAttr || !(i_PathAttr & FILE_ATTRIBUTE_DIRECTORY)) Typ = TypisBad; 278 } 279 strcpy(pTemp,pFromTo); 280 if (Typ == TypisUnkn && i_PathAttr != -1 && (i_PathAttr & FILE_ATTRIBUTE_DIRECTORY)) { 281 if (NULL == strpbrk(i_pFile,"*?\0")) { 282 if (!i_Slash) { 283 *lenTemp = i_lenTemp = strlen(pTemp); 284 *pFile = &pTemp[i_lenTemp]; 285 Typ = TypisName; 286 } else Typ = TypisNameS; 287 } else Typ = TypisMask; 288 } 289 } 290 i_pLastSlash[0] = '\\'; 291 return Typ; 292 } 293 #else 294 /************************************************************************** 295 * SHELL_FileNamesMatch() 296 * 297 * Accepts two \0 delimited lists of the file names. Checks whether number of 298 * files in the both lists is the same. 299 */ 300 BOOL SHELL_FileNamesMatch(LPCSTR pszFiles1, LPCSTR pszFiles2) 301 { 302 while ((pszFiles1[strlen(pszFiles1) + 1] != '\0') && 303 (pszFiles2[strlen(pszFiles2) + 1] != '\0')) 304 { 305 pszFiles1 += strlen(pszFiles1) + 1; 306 pszFiles2 += strlen(pszFiles2) + 1; 307 } 308 309 return 310 ((pszFiles1[strlen(pszFiles1) + 1] == '\0') && 311 (pszFiles2[strlen(pszFiles2) + 1] == '\0')) || 312 ((pszFiles1[strlen(pszFiles1) + 1] != '\0') && 313 (pszFiles2[strlen(pszFiles2) + 1] != '\0')); 314 } 315 #endif 316 204 317 /************************************************************************* 205 318 * SHFileOperationA [SHELL32.243] … … 214 327 LPSTR pTempTo; 215 328 #ifdef __WIN32OS2__ 216 DWORD FromAttr; 217 DWORD ToAttr; 218 LPSTR pTempFrom = NULL; 219 LPSTR pFromFile; 220 LPSTR pToFile; 221 222 FILEOP_FLAGS OFl = ((FILEOP_FLAGS)lpFileOp->fFlags & 0x7ff); 223 BOOL Multi = TRUE; 224 BOOL withFileName = TRUE; 225 BOOL not_overwrite; 226 BOOL ToSingle; 227 BOOL BothDir; 228 BOOL ToWithoutBackSlash; 229 long lenFrom = -1; 230 long lenTo = -1; 231 long lenTempFrom; 232 long lenTempTo; 233 long retCode = 0x75; 234 long TempretCode = 0; 235 long where = 0; 236 SHFILEOPSTRUCTA nlpFileOp = *(lpFileOp); 237 long level= nlpFileOp.wFunc>>4; 238 HANDLE hFind; 239 WIN32_FIND_DATAA wfd; 329 DWORD FromAttr; 330 DWORD ToAttr; 331 DWORD FromPathAttr; 332 DWORD ToPathAttr; 333 DWORD FromTyp; 334 DWORD ToTyp = TypisBad; 335 DWORD zTyp; 336 LPSTR pFromFile; 337 LPSTR pToFile; 338 LPSTR pTempFrom = NULL; 339 LPSTR pToSlash; 340 LPSTR pToFuncTXT = "FO_COPY"; 341 FILEOP_FLAGS OFl = ((FILEOP_FLAGS)lpFileOp->fFlags & 0x7ff); 342 BOOL Multi = ((lpFileOp->fFlags & FOF_MULTIDESTFILES) != 0); 343 BOOL MakeDir = FALSE; 344 BOOL not_overwrite; 345 BOOL TargetisDir; 346 BOOL ask_overwrite; 347 BOOL ToSingle; 348 BOOL recurseinto; 349 long lenFrom = -1; 350 long lenTo = -1; 351 long lenTempFrom; 352 long lenTempTo; 353 long retCode = 0x75; 354 long TempretCode = 0; 355 long where = 0; 356 long FuncSwitch = (lpFileOp->wFunc & 15); 357 SHFILEOPSTRUCTA nlpFileOp = *(lpFileOp); 358 long level= nlpFileOp.wFunc>>4; 359 HANDLE hFind; 360 WIN32_FIND_DATAA wfd; 240 361 241 362 /* default no error … … 244 365 nlpFileOp.fAnyOperationsAborted=FALSE; 245 366 level++; 246 nlpFileOp.wFunc = (level<<4) + (lpFileOp->wFunc & 15);367 nlpFileOp.wFunc = (level<<4) + FuncSwitch; 247 368 if (level == 1) 248 369 #endif … … 261 382 lpFileOp->fFlags & 0xf800 ? "MORE-UNKNOWN-Flags" : ""); 262 383 #ifdef __WIN32OS2__ 263 switch(lpFileOp->wFunc & 15) { 384 switch(FuncSwitch) { 385 case FO_MOVE: 386 retCode = 0xb7; 387 pToFuncTXT = "FO_MOVE"; 264 388 #else 265 389 switch(lpFileOp->wFunc) { 390 case FO_MOVE: 266 391 #endif 267 392 case FO_COPY: 393 { 268 394 /* establish when pTo is interpreted as the name of the destination file 269 395 * or the directory where the Fromfile should be copied to. … … 283 409 */ 284 410 #ifdef __WIN32OS2__ 285 pTempFrom = HeapAlloc(GetProcessHeap(), 0, 3 * MAX_PATH+6);286 pTempTo= &pTempFrom[MAX_PATH+4];411 nlpFileOp.pFrom = pTempFrom = HeapAlloc(GetProcessHeap(), 0, 3 * MAX_PATH+6); 412 nlpFileOp.pTo = pTempTo = &pTempFrom[MAX_PATH+4]; 287 413 /* 288 414 * FOF_MULTIDESTFILES, FOF_NOCONFIRMATION, FOF_FILESONLY are implemented … … 292 418 * if any other flag set, an error occurs 293 419 */ 294 TRACE(__FUNCTION__" FO_COPY level=%d lpFileOp->fFlags=0x%x\n",level ,lpFileOp->fFlags);420 TRACE(__FUNCTION__" %s level=%d lpFileOp->fFlags=0x%x\n", pToFuncTXT, level, lpFileOp->fFlags); 295 421 // OFl = (OFl & (-1 - (FOF_MULTIDESTFILES | FOF_FILESONLY))); 296 422 // OFl = (OFl ^ (FOF_SILENT | FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMMKDIR)); … … 300 426 if (OFl) { 301 427 if (OFl & ( ~ (FOF_CONFIRMMOUSE | FOF_SILENT | FOF_RENAMEONCOLLISION | FOF_NOCONFIRMMKDIR))) { 302 TRACE(__FUNCTION__" FO_COPY level=%d lpFileOp->fFlags=0x%x not implemented, Aborted=TRUE, stub\n", level, OFl);428 TRACE(__FUNCTION__" %s level=%d lpFileOp->fFlags=0x%x not implemented, Aborted=TRUE, stub\n", pToFuncTXT, level, OFl); 303 429 nlpFileOp.fAnyOperationsAborted=TRUE; 304 430 } else { 305 TRACE(__FUNCTION__" FO_COPY level=%d lpFileOp->fFlags=0x%x not full implemented ,stub\n", level, OFl);431 TRACE(__FUNCTION__" %s level=%d lpFileOp->fFlags=0x%x not full implemented ,stub\n", pToFuncTXT, level, OFl); 306 432 } /* endif */ 307 433 } /* endif */ 308 434 309 not_overwrite = (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_RENAMEONCOLLISION)); 310 311 // fix for more then one source for one target 312 pToFile = pTempTo; 435 ask_overwrite = (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) && !(lpFileOp->fFlags & FOF_RENAMEONCOLLISION)); 436 not_overwrite = (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_RENAMEONCOLLISION)); 313 437 314 438 // need break at error before change sourcepointer 315 439 while(!nlpFileOp.fAnyOperationsAborted && (pFrom+=lenFrom+1)[0]) { 316 317 if (!withFileName && Multi && (pTo[lenTo+1]=='\0')) {318 // Win Bug ?319 Multi = FALSE;320 } /* endif */321 440 322 441 if (Multi) pTo += lenTo + 1; 323 442 if(!pTo[0]) { 324 443 nlpFileOp.fAnyOperationsAborted=TRUE; 325 where = 2 13;444 where = 200; 326 445 break; 327 } 328 329 TRACE(__FUNCTION__" FO_COPY level=%d From='%s' To='%s'\n", level, pFrom, pTo); 330 331 // fix for more then one source for one target 332 pToFile[0] = '\0'; 333 nlpFileOp.pTo = pTo; 334 335 lenFrom=strlen(pFrom); 336 strcpy(pTempFrom,pFrom); 337 FromAttr = GetFileAttributesA(pTempFrom); 338 339 if (Multi) { 340 lenTo = strlen(pTo); 341 // single targetdir !Multi 342 Multi = (Multi && (lpFileOp->fFlags & FOF_MULTIDESTFILES)); 343 // multi target, each one for one source. ? last target + more than one source (all source files an one dir as target) 344 345 ToSingle = ((pTo[lenTo+1]=='\0') || !Multi); 346 347 strcpy(pTempTo,pTo); 348 PathRemoveBackslashA(pTempTo); 349 ToWithoutBackSlash = (strlen(pTempTo)==lenTo); 350 ToAttr = GetFileAttributesA(pTempTo); 351 352 BothDir = (Multi && 353 ToWithoutBackSlash && 354 (-1 != (FromAttr | ToAttr)) && 355 (ToAttr & FromAttr & FILE_ATTRIBUTE_DIRECTORY)); 356 357 withFileName = (!BothDir && 358 (ToWithoutBackSlash || !ToSingle) && 359 (ToAttr == -1 || !(ToAttr & FILE_ATTRIBUTE_DIRECTORY))); 360 361 if (withFileName) { 362 // Target must not be an directory 363 PathRemoveFileSpecA(pTempTo); 364 ToAttr = GetFileAttributesA(pTempTo); 365 } 366 if ((ToAttr == -1) || 367 !(ToAttr & FILE_ATTRIBUTE_DIRECTORY) || 368 (!withFileName && !ToSingle) ) { 446 } /* endif */ 447 448 TRACE(__FUNCTION__" %s level=%d From='%s' To='%s'\n", pToFuncTXT, level, pFrom, pTo); 449 450 FromTyp = SHFileTyp(pFrom, &lenFrom, 451 pTempFrom, &lenTempFrom, 452 &pFromFile, 453 &FromPathAttr, &FromAttr); 454 455 // Check Source 456 if (FromTyp != TypisDir 457 && FromTyp != TypisFile 458 && FromTyp != TypisMask) { 369 459 nlpFileOp.fAnyOperationsAborted=TRUE; 370 460 where = 201; 461 retCode=0x402; 371 462 break; 372 } 373 lenTempTo = strlen(pTempTo); 374 withFileName = (((lenTempTo + 1) < lenTo) || (PathIsRootA(pTo) && lenTempTo < lenTo)); 375 PathAddBackslashA(pTempTo); 376 } 377 378 if (FromAttr == -1 || BothDir) { 379 // is Source an existing directory\*.* ? 380 if (FromAttr == -1) { 381 PathRemoveFileSpecA(pTempFrom); 382 FromAttr = GetFileAttributesA(pTempFrom); 383 } 384 385 PathAddBackslashA(pTempFrom); 386 lenTempFrom = strlen(pTempFrom); 387 pFromFile=&pTempFrom[lenTempFrom]; 388 389 if (FromAttr == -1 || 390 ((lenTempFrom==lenFrom) && !PathIsRootA(pFrom)) || 391 !(FromAttr & FILE_ATTRIBUTE_DIRECTORY) || 392 !((0==strcmp(&pFrom[lenTempFrom],"*.*")) || BothDir)) { 393 retCode=0x402; 463 } /* endif */ 464 zTyp = ToTyp; 465 ToTyp = SHFileTyp(pTo, &lenTo, 466 pTempTo, &lenTempTo, 467 &pToFile, 468 &ToPathAttr, &ToAttr); 469 470 // fix for more then one source for one target 471 if (ToTyp == TypisUnkn 472 && zTyp < TypisFile 473 && zTyp > TypisUnkn 474 && lenTo == 0) { 475 pToFile[0] = '\0'; 476 ToTyp = zTyp; 477 lenTo = strlen(pTempTo); 478 } /* endif */ 479 // recursiv creating from directorys are not valid for FO_MOVE. 480 if (FuncSwitch == FO_MOVE && ToTyp == TypisNewPath) ToTyp = TypisUnkn; 481 // Check Target 482 if (ToTyp == TypisMask) { 483 nlpFileOp.fAnyOperationsAborted=TRUE; 484 where = 202; 485 if (FromTyp != TypisMask) { 486 retCode=0x10003; 487 } else { 488 if ((lpFileOp->wFunc & 0xf) == FO_MOVE) TempretCode = 0x2; 489 } 490 break; 491 } /* endif */ 492 if (ToTyp == TypisBad) { 493 nlpFileOp.fAnyOperationsAborted=TRUE; 494 where = 203; 495 retCode=0x402; 496 break; 497 } /* endif */ 498 TargetisDir = (ToTyp == TypisDir || ToTyp == TypisDirS || ToTyp == TypisRoot); 499 ToSingle = (pTo[lenTo+1]=='\0'); 500 if (Multi && ToSingle) { 501 Multi = (!(pFrom[lenFrom+1]!='\0')); 502 } 503 504 switch(FromTyp) { 505 case TypisFile: { /* Source is File */ 506 if (ToTyp == TypisName) { 507 if (ToSingle && pFrom[lenFrom+1] == '\0') break; 508 if (Multi) break; 509 } 510 if (ToTyp == TypisFile) { 511 if (0 == strcmp(pTempFrom,pTempTo)) { /* target is the same as source ? */ 512 nlpFileOp.fAnyOperationsAborted=TRUE; 513 retCode = 0x71; 514 where = 221; 515 break; 516 } /* endif */ 517 if (ask_overwrite && SHELL_ConfirmDialog (ASK_OVERWRITE_FILE, pTempTo)) break; 518 if (!not_overwrite) break; 519 if (FuncSwitch == FO_MOVE && (!Multi)) TempretCode = 0x75; 520 } 521 if (!Multi && TargetisDir) { 522 strcpy(pToFile,pFromFile); 523 pTempTo[strlen(pTempTo)+1] = '\0'; 524 ToAttr = GetFileAttributesA(pTempTo); 525 if (ToAttr == -1) break; 526 if (!(ToAttr & FILE_ATTRIBUTE_DIRECTORY)) break; 527 } 528 if (FuncSwitch == FO_MOVE && (ToTyp == TypisUnkn || ToTyp == TypisName || ToTyp == TypisNameS)) TempretCode = 0x75; 394 529 nlpFileOp.fAnyOperationsAborted=TRUE; 395 where = 2 02;530 where = 210 + TypisFile; 396 531 break; 397 532 } 398 399 strcpy(pFromFile, "*.*"); 533 case TypisMask: { /* Source is Mask */ 534 if (TargetisDir) break; 535 nlpFileOp.fAnyOperationsAborted=TRUE; 536 where = 210 + TypisMask; 537 break; 538 } 539 case TypisRoot: /* Source is Root, only small test with this */ 540 case TypisDir: { /* Source is Dir */ 541 if (TargetisDir) { 542 // From Root to Root not full tested, also no Comparsion in W98 543 MakeDir = (!(lpFileOp->fFlags & FOF_MULTIDESTFILES) && ToTyp != TypisRoot); 544 break; 545 } 546 MakeDir = TRUE; 547 if ((ToTyp == TypisName || ToTyp == TypisNameS || ToTyp == TypisNewPath)) break; 548 nlpFileOp.fAnyOperationsAborted=TRUE; 549 where = 210 + TypisDir; 550 break; 551 } 552 default: { 553 nlpFileOp.fAnyOperationsAborted=TRUE; 554 where = 210 + FromTyp; 555 // retCode=0x750; 556 break; 557 } 558 } 559 if (nlpFileOp.fAnyOperationsAborted) { 560 if (FuncSwitch == FO_MOVE && (ToTyp == TypisUnkn || ToTyp == TypisName || ToTyp == TypisNameS)) TempretCode = 0x75; 561 break; 562 } 563 564 recurseinto = FALSE; 565 566 if (FuncSwitch == FO_MOVE && ToTyp == TypisName && (FromTyp == TypisDir || FromTyp == TypisFile)) { 567 if (':' == pTempFrom[1] && ':' == pTempTo[1] && pTempFrom[0] == pTempTo[0]) { 568 if (MoveFileA(pTempFrom, pTempTo)) continue; 569 } 570 } 571 if (FromTyp == TypisDir && TargetisDir && MakeDir) { 572 PathRemoveFileSpecA(pTempFrom); 573 lenTempTo = strlen(pTempFrom); 574 strcpy(pTempFrom,pFrom); 575 if (pTempFrom[lenTempTo-1] == '\\') lenTempTo--; 576 strcpy(pToFile,&pFrom[lenTempTo]); 577 lenTempTo = strlen(pTempTo); 578 pTempTo[lenTempTo+1] = '\0'; 579 } 580 581 if (MakeDir) { 582 pToSlash = NULL; 583 if ((ToTyp == TypisNameS || ToTyp == TypisNewPath)) { 584 pToSlash = strchr(&pToFile[1],'\\'); 585 if (NULL != pToSlash) pToSlash[0] = '\0'; 586 } 587 TRACE(__FUNCTION__" %s level=%d Creating Directory '%s'\n", pToFuncTXT, level, pTempTo); 588 SHCreateDirectory(NULL,pTempTo); 589 ToPathAttr = GetFileAttributesA(pTempTo); 590 if (NULL != pToSlash) pToSlash[0] = '\\'; 591 if (ToPathAttr == -1) { 592 nlpFileOp.fAnyOperationsAborted=TRUE; 593 retCode=0x10004; 594 where = 220; 595 break; 596 } 597 recurseinto = TRUE; 598 } 599 if (ToTyp != TypisNewPath) { 600 if (FromTyp == TypisDir || FromTyp == TypisRoot) { 601 strcpy(pFromFile,"\\*.*"); 602 pTempFrom[strlen(pTempFrom)+1] = '\0'; 603 recurseinto = TRUE; 604 } else { 605 if (FromTyp == TypisFile) { 606 if (TargetisDir) { 607 recurseinto = TRUE; 608 } else { 609 if (CopyFileA(pTempFrom, pTempTo, FALSE)) { 610 if (FuncSwitch == FO_COPY) continue; 611 if (DeleteFileA(pTempFrom)) continue; 612 } 613 nlpFileOp.fAnyOperationsAborted=TRUE; 614 where = 222; 615 break; 616 } 617 } /* endif */ 618 } 619 } 620 if (recurseinto) { 621 TRACE(__FUNCTION__" %s level=%d Entering into Directory '%s'\n", pToFuncTXT, level, pTempTo); 622 TempretCode = SHFileOperationA (&nlpFileOp); 623 if (nlpFileOp.fAnyOperationsAborted) {where = 223;break;} 624 if (FuncSwitch == FO_MOVE && FromTyp == TypisDir) { 625 if (!(RemoveDirectoryA(pFrom))) { 626 nlpFileOp.fAnyOperationsAborted=TRUE; 627 where = 100; 628 break; 629 } 630 } 631 continue; /* next pTo/pFrom */ 632 } 633 if (FromTyp == TypisMask) { 400 634 hFind = FindFirstFileA(pTempFrom, &wfd); 401 635 if (INVALID_HANDLE_VALUE == hFind) { 402 636 nlpFileOp.fAnyOperationsAborted=TRUE; 403 637 retCode=0x79; 404 where = 2 03;638 where = 224; 405 639 break; 406 640 } 407 641 408 nlpFileOp.pFrom = pTempFrom; 409 // single copy never with FOF_MULTIDESTFILES, I can use lpFileOp->pTo as nlpFileOp.pTo, 410 // I need no different targetarea for the name 411 TRACE(__FUNCTION__" FO_COPY level=%d Copy between Subdir %s -> %s'\n",level ,nlpFileOp.pFrom, nlpFileOp.pTo); 642 TRACE(__FUNCTION__" %s level=%d between Subdir %s -> %s'\n", pToFuncTXT, level, nlpFileOp.pFrom, nlpFileOp.pTo); 412 643 nlpFileOp.fFlags = (nlpFileOp.fFlags & (-1 - (FOF_MULTIDESTFILES))); 413 644 414 645 do { 415 TRACE(__FUNCTION__" FO_COPY level=%d find '%s'\n",level ,wfd.cFileName);646 TRACE(__FUNCTION__" %s level=%d find '%s'\n", pToFuncTXT, level, wfd.cFileName); 416 647 if (0==strcmp(wfd.cFileName,".")) continue; 417 648 if (0==strcmp(wfd.cFileName,"..")) continue; 418 649 if ((nlpFileOp.fFlags & FOF_FILESONLY) && (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)) { 419 continue; 650 continue; /* next name in pFrom(dir) */ 420 651 } /* endif */ 421 652 422 strcpy( pFromFile,wfd.cFileName);653 strcpy(&pFromFile[1],wfd.cFileName); 423 654 pTempFrom[strlen(pTempFrom)+1]='\0'; 424 655 425 656 TempretCode = SHFileOperationA (&nlpFileOp); 426 657 427 if (nlpFileOp.fAnyOperationsAborted) {where = 2 04;break;}658 if (nlpFileOp.fAnyOperationsAborted) {where = 230;break;} 428 659 429 660 } while(FindNextFileA(hFind, &wfd)); 430 431 FindClose(hFind); 432 if (nlpFileOp.fAnyOperationsAborted) {where = 205;break;} 433 continue; 434 } 435 436 lenTempTo = strlen(pTempTo); 437 pToFile = &pTempTo[lenTempTo]; 438 // Check Source 439 strcpy(pToFile,pTempFrom); 440 PathRemoveBackslashA(pToFile); 441 if (strlen(pToFile)<lenFrom) { 442 nlpFileOp.fAnyOperationsAborted=TRUE; 443 retCode=0x402; 444 where = 206; 445 break; 446 } /* endif */ 447 448 // target name in target or from source 449 pFromFile = NULL; 450 if (withFileName) { 451 if ((pFrom[lenFrom+1]=='\0') || (Multi && !(pTo[lenTo+1]=='\0'))) { 452 pFromFile = pTo; 453 } /* endif */ 454 } else { 455 // Multi Target 456 if (!Multi || !(pFrom[lenFrom+1]=='\0') || 457 // only target+\, target without \ has 0x402 458 (Multi && (FromAttr & ToAttr & FILE_ATTRIBUTE_DIRECTORY))) { 459 pFromFile = pTempFrom; 460 } 461 } /* endif */ 462 463 if (!pFromFile) { 464 nlpFileOp.fAnyOperationsAborted=TRUE; 465 where = 207; 466 break; 467 } /* endif */ 468 469 // move isolated target filename 470 strcpy(pToFile,pFromFile); 471 PathRemoveFileSpecA(pToFile); 472 PathAddBackslashA(pToFile); 473 474 strcpy(pToFile,&pFromFile[strlen(pToFile)]); 475 ToAttr = GetFileAttributesA(pTempTo); 476 477 if (FromAttr == -1) { 478 TRACE(__FUNCTION__" FO_COPY level=%d with Source %s not implementiert ,stub\n",level ,pTempFrom); 479 nlpFileOp.fAnyOperationsAborted=TRUE; 480 where = 208; 481 break; 482 } 483 if (FromAttr & FILE_ATTRIBUTE_DIRECTORY) { 484 if (ToAttr == -1) { 485 // Try to create an new Directory and enter in it 486 TRACE(__FUNCTION__" FO_COPY level=%d Creating Directory '%s'\n",level , pTempTo); 487 SHCreateDirectory(NULL,pTempTo); 488 ToAttr = GetFileAttributesA(pTempTo); 489 if (ToAttr == -1) { 490 nlpFileOp.fAnyOperationsAborted=TRUE; 491 retCode=0x10003; 492 where = 209; 493 break; 494 } 495 496 lenTempTo = strlen(pTempTo); 497 498 PathAddBackslashA(pTempFrom); 499 strcat(pTempFrom, "*.*"); 500 pTempFrom[strlen(pTempFrom)+1]='\0'; 501 nlpFileOp.pFrom = pTempFrom; 502 503 pTempTo[lenTempTo+1]='\0'; 504 nlpFileOp.pTo = pTempTo; 505 506 TRACE(__FUNCTION__" FO_COPY level=%d Entering Directory '%s'\n",level , nlpFileOp.pTo); 507 TempretCode = SHFileOperationA (&nlpFileOp); 508 509 if (nlpFileOp.fAnyOperationsAborted) {break;} 510 continue; 511 512 } else { 513 TRACE(__FUNCTION__" FO_COPY level=%d unexpected with %s -> %s ? ,stub\n",level ,pTempFrom,pTo); 514 nlpFileOp.fAnyOperationsAborted=TRUE; 515 where = 210; 516 retCode=0x77; 517 break; 518 519 } 520 521 } 522 523 if (!(ToAttr == -1) && (ToAttr & FILE_ATTRIBUTE_DIRECTORY)) { 524 nlpFileOp.fAnyOperationsAborted=TRUE; 525 where = 211; 526 break; 527 } 528 if (0==strcmp(pTempFrom, pTempTo)) { 529 nlpFileOp.fAnyOperationsAborted=TRUE; 530 retCode = 0x71; 531 where = 212; 532 break; 533 } 534 // first try to copy 535 if (CopyFileA(pTempFrom, pTempTo, not_overwrite)) continue; 536 537 if ((not_overwrite) && !(lpFileOp->fFlags & FOF_RENAMEONCOLLISION)) { 538 if (SHELL_ConfirmDialog (ASK_OVERWRITE_FILE, pTempTo)) 539 // second try to copy after confirm 540 if (CopyFileA(pTempFrom, pTempTo, FALSE)) continue; 541 } /* endif */ 542 543 nlpFileOp.fAnyOperationsAborted=TRUE; 544 where = 215; 661 } 545 662 } 546 663 break; 547 664 #else 665 int multifrom = pFrom[strlen(pFrom) + 1] != '\0'; 666 int destisdir = PathIsDirectoryA( pTo ); 667 int todir = 0; 668 669 if (lpFileOp->wFunc == FO_COPY) 670 TRACE("File Copy:\n"); 671 else 672 TRACE("File Move:\n"); 673 674 if( destisdir ) { 675 if ( !((lpFileOp->fFlags & FOF_MULTIDESTFILES) && !multifrom)) 676 todir = 1; 677 } else { 678 if ( !(lpFileOp->fFlags & FOF_MULTIDESTFILES) && multifrom) 679 todir = 1; 680 } 681 682 if ((pTo[strlen(pTo) + 1] != '\0') && 683 !(lpFileOp->fFlags & FOF_MULTIDESTFILES)) 684 { 685 WARN("Attempt to use multiple file names as a destination " 686 "without specifying FOF_MULTIDESTFILES\n"); 687 return 1; 688 } 689 690 if ((lpFileOp->fFlags & FOF_MULTIDESTFILES) && 691 !SHELL_FileNamesMatch(pTo, pFrom)) 692 { 693 WARN("Attempt to use multiple file names as a destination " 694 "with mismatching number of files in the source and " 695 "destination lists\n"); 696 return 1; 697 } 698 699 if ( todir ) { 700 char szTempFrom[MAX_PATH]; 701 char *fromfile; 702 int lenPTo; 703 if ( ! destisdir) { 704 TRACE(" creating directory %s\n",pTo); 705 SHCreateDirectory(NULL,pTo); 706 } 707 lenPTo = strlen(pTo); 708 while(1) { 709 HANDLE hFind; 710 WIN32_FIND_DATAA wfd; 711 712 if(!pFrom[0]) break; 713 TRACE(" From Pattern='%s'\n", pFrom); 714 if(INVALID_HANDLE_VALUE != (hFind = FindFirstFileA(pFrom, &wfd))) 715 { 716 do 717 { 718 if(strcasecmp(wfd.cFileName, ".") && strcasecmp(wfd.cFileName, "..")) 719 { 720 strcpy(szTempFrom, pFrom); 721 722 pTempTo = HeapAlloc(GetProcessHeap(), 0, 723 lenPTo + strlen(wfd.cFileName) + 5); 724 if (pTempTo) { 725 strcpy(pTempTo,pTo); 726 PathAddBackslashA(pTempTo); 727 strcat(pTempTo,wfd.cFileName); 728 729 fromfile = PathFindFileNameA(szTempFrom); 730 fromfile[0] = '\0'; 731 PathAddBackslashA(szTempFrom); 732 strcat(szTempFrom, wfd.cFileName); 733 TRACE(" From='%s' To='%s'\n", szTempFrom, pTempTo); 734 if(lpFileOp->wFunc == FO_COPY) 735 { 736 if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) 737 { 738 /* copy recursively */ 739 if(!(lpFileOp->fFlags & FOF_FILESONLY)) 740 { 741 SHFILEOPSTRUCTA shfo; 742 743 SHCreateDirectory(NULL,pTempTo); 744 PathAddBackslashA(szTempFrom); 745 strcat(szTempFrom, "*.*"); 746 szTempFrom[strlen(szTempFrom) + 1] = '\0'; 747 pTempTo[strlen(pTempTo) + 1] = '\0'; 748 memcpy(&shfo, lpFileOp, sizeof(shfo)); 749 shfo.pFrom = szTempFrom; 750 shfo.pTo = pTempTo; 751 SHFileOperationA(&shfo); 752 753 szTempFrom[strlen(szTempFrom) - 4] = '\0'; 754 } 755 } 756 else 757 CopyFileA(szTempFrom, pTempTo, FALSE); 758 } 759 else 760 { 761 /* move file/directory */ 762 MoveFileA(szTempFrom, pTempTo); 763 } 764 HeapFree(GetProcessHeap(), 0, pTempTo); 765 } 766 } 767 } while(FindNextFileA(hFind, &wfd)); 768 FindClose(hFind); 769 } 770 else 771 { 772 /* can't find file with specified name */ 773 break; 774 } 775 pFrom += strlen(pFrom) + 1; 776 } 777 } else { 548 778 while(1) { 549 779 if(!pFrom[0]) break; … … 560 790 HeapFree(GetProcessHeap(), 0, pTempTo); 561 791 } 792 if (lpFileOp->wFunc == FO_COPY) 562 793 CopyFileA(pFrom, pTo, FALSE); 794 else 795 MoveFileA(pFrom, pTo); 563 796 564 797 pFrom += strlen(pFrom) + 1; 565 798 pTo += strlen(pTo) + 1; 566 799 } 800 } 567 801 TRACE("Setting AnyOpsAborted=FALSE\n"); 568 802 lpFileOp->fAnyOperationsAborted=FALSE; 569 803 return 0; 570 804 #endif 805 } 571 806 572 807 case FO_DELETE: … … 667 902 } 668 903 break; 669 case FO_MOVE:670 TRACE(__FUNCTION__" FO_MOVE level=%d File\\Tree Move: simply (Copy/Delete)\n",level);671 nlpFileOp.wFunc = (level<<4) + FO_COPY;672 // not delete at error from copy673 TempretCode = SHFileOperationA (&nlpFileOp);674 675 if (nlpFileOp.fAnyOperationsAborted) {676 if (TempretCode == 0x75) {677 // not all, the most678 TempretCode = 0xD7;679 retCode = 0xD7;680 } /* endif */681 break;682 }683 684 nlpFileOp.wFunc = (level<<4) + FO_DELETE;685 686 TempretCode = SHFileOperationA (&nlpFileOp);687 688 904 case 0: 689 905 break; 690 906 #else 907 { 908 HANDLE hFind; 909 WIN32_FIND_DATAA wfd; 910 char szTemp[MAX_PATH]; 911 char *file_name; 912 691 913 TRACE("File Delete:\n"); 692 914 while(1) { 693 915 if(!pFrom[0]) break; 694 TRACE(" File='%s'\n", pFrom); 695 DeleteFileA(pFrom); 916 TRACE(" Pattern='%s'\n", pFrom); 917 if(INVALID_HANDLE_VALUE != (hFind = FindFirstFileA(pFrom, &wfd))) 918 { 919 do 920 { 921 if(strcasecmp(wfd.cFileName, ".") && strcasecmp(wfd.cFileName, "..")) 922 { 923 strcpy(szTemp, pFrom); 924 file_name = PathFindFileNameA(szTemp); 925 file_name[0] = '\0'; 926 PathAddBackslashA(szTemp); 927 strcat(szTemp, wfd.cFileName); 928 929 TRACE(" File='%s'\n", szTemp); 930 if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) 931 { 932 if(!(lpFileOp->fFlags & FOF_FILESONLY)) 933 SHELL_DeleteDirectoryA(szTemp, FALSE); 934 } 935 else 936 DeleteFileA(szTemp); 937 } 938 } while(FindNextFileA(hFind, &wfd)); 939 940 FindClose(hFind); 941 } 696 942 pFrom += strlen(pFrom) + 1; 697 943 } … … 699 945 lpFileOp->fAnyOperationsAborted=FALSE; 700 946 return 0; 947 } 701 948 #endif 949 case FO_RENAME: 950 TRACE("File Rename:\n"); 951 if (pFrom[strlen(pFrom) + 1] != '\0') 952 { 953 WARN("Attempt to rename more than one file\n"); 954 return 1; 955 } 956 lpFileOp->fAnyOperationsAborted = FALSE; 957 TRACE("From %s, To %s\n", pFrom, pTo); 958 return !MoveFileA(pFrom, pTo); 702 959 703 960 default: … … 717 974 if (nlpFileOp.fAnyOperationsAborted) { 718 975 lpFileOp->fAnyOperationsAborted=TRUE; 719 if (TempretCode > retCode) {976 if (TempretCode > 0 /* retCode */) { 720 977 retCode = TempretCode; 721 978 } /* endif */ … … 788 1045 789 1046 790
Note:
See TracChangeset
for help on using the changeset viewer.