Changeset 9338 for trunk/src


Ignore:
Timestamp:
Oct 8, 2002, 6:42:59 PM (23 years ago)
Author:
sandervl
Message:

DT: SHFileOperationA updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/shell32/shlfileop.c

    r9244 r9338  
    11/*
    22 * SHFileOperation
     3 *
    34 * Copyright 2000 Juergen Schmied
    45 * Copyright 2002 Andriy Palamarchuk
     
    2223#define ICOM_CINTERFACE 1
    2324#include <odin.h>
     25#include "debugtools.h"
    2426#endif
    2527#include <string.h>
     28#ifdef __WIN32OS2__
    2629#include "debugtools.h"
     30#endif
     31#include "winreg.h"
    2732#include "shellapi.h"
    28 #include "shlwapi.h"
    29 
    3033#include "shlobj.h"
    3134#include "shresdef.h"
     
    3336#include "undocshell.h"
    3437#include "shlwapi.h"
    35 
    36 DEFAULT_DEBUG_CHANNEL(shell);
    37 
     38#include "wine/debug.h"
     39
     40WINE_DEFAULT_DEBUG_CHANNEL(shell);
    3841
    3942#ifdef __WIN32OS2__
     
    9598        }
    9699        else {
    97           FIXME("Called without a valid nKindOfDialog specified!");
     100          FIXME("Called without a valid nKindOfDialog specified!\n");
    98101          LoadStringA(shell32_hInstance, IDS_DELETEITEM_TEXT, szText,
    99102                sizeof(szText));
     
    202205}
    203206
     207#ifdef __WIN32OS2__
     208/*************************************************************************
     209 *
     210 * SHFileTyp (internal)
     211 *
     212 */
     213DWORD 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 */
     300BOOL 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
    204317/*************************************************************************
    205318 * SHFileOperationA                             [SHELL32.243]
     
    214327        LPSTR pTempTo;
    215328#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;
    240361
    241362/* default no error
     
    244365        nlpFileOp.fAnyOperationsAborted=FALSE;
    245366        level++;
    246         nlpFileOp.wFunc =  (level<<4) + (lpFileOp->wFunc & 15);
     367        nlpFileOp.wFunc =  (level<<4) + FuncSwitch;
    247368        if (level == 1)
    248369#endif
     
    261382                lpFileOp->fFlags & 0xf800 ? "MORE-UNKNOWN-Flags" : "");
    262383#ifdef __WIN32OS2__
    263         switch(lpFileOp->wFunc & 15) {
     384        switch(FuncSwitch) {
     385        case FO_MOVE:
     386                retCode = 0xb7;
     387                pToFuncTXT = "FO_MOVE";
    264388#else
    265389        switch(lpFileOp->wFunc) {
     390        case FO_MOVE:
    266391#endif
    267392        case FO_COPY:
     393        {
    268394                /* establish when pTo is interpreted as the name of the destination file
    269395                 * or the directory where the Fromfile should be copied to.
     
    283409                 */
    284410#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];
    287413/*
    288414 * FOF_MULTIDESTFILES, FOF_NOCONFIRMATION, FOF_FILESONLY                                        are             implemented
     
    292418 * if any other flag set, an error occurs
    293419 */ 
    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);
    295421//                      OFl = (OFl & (-1 - (FOF_MULTIDESTFILES | FOF_FILESONLY)));
    296422//                      OFl = (OFl ^ (FOF_SILENT | FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMMKDIR));
     
    300426                        if (OFl) {
    301427                                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);
    303429                                        nlpFileOp.fAnyOperationsAborted=TRUE;
    304430                                } 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);
    306432                                } /* endif */
    307433                        } /* endif */
    308434
    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));
    313437
    314438// need break at error before change sourcepointer
    315439                        while(!nlpFileOp.fAnyOperationsAborted && (pFrom+=lenFrom+1)[0]) {
    316 
    317                                 if (!withFileName && Multi && (pTo[lenTo+1]=='\0')) {
    318 // Win Bug ?
    319                                         Multi = FALSE;
    320                                 } /* endif */
    321440
    322441                                if (Multi) pTo += lenTo + 1;
    323442                                if(!pTo[0]) {
    324443                                                nlpFileOp.fAnyOperationsAborted=TRUE;
    325                                                 where = 213;
     444                                                where = 200;
    326445                                                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) {                     
    369459                                                nlpFileOp.fAnyOperationsAborted=TRUE;
    370460                                                where = 201;
     461                                                retCode=0x402;
    371462                                                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;
    394529                                                nlpFileOp.fAnyOperationsAborted=TRUE;
    395                                                 where = 202;
     530                                                where = 210 + TypisFile;
    396531                                                break;
    397532                                        }
    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) {
    400634                                        hFind = FindFirstFileA(pTempFrom, &wfd);
    401635                                        if (INVALID_HANDLE_VALUE == hFind) {
    402636                                                nlpFileOp.fAnyOperationsAborted=TRUE;
    403637                                                retCode=0x79;
    404                                                 where = 203;
     638                                                where = 224;
    405639                                                break;
    406640                                        }
    407641
    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);
    412643                                        nlpFileOp.fFlags = (nlpFileOp.fFlags & (-1 - (FOF_MULTIDESTFILES)));
    413644
    414645                                        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);
    416647                                                if (0==strcmp(wfd.cFileName,".")) continue;
    417648                                                if (0==strcmp(wfd.cFileName,"..")) continue;
    418649                                                if ((nlpFileOp.fFlags & FOF_FILESONLY) && (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)) {
    419                                                         continue;
     650                                                        continue; /* next name in pFrom(dir) */
    420651                                                } /* endif */
    421652
    422                                                 strcpy(pFromFile,wfd.cFileName);
     653                                                strcpy(&pFromFile[1],wfd.cFileName);
    423654                                                pTempFrom[strlen(pTempFrom)+1]='\0';
    424655
    425656                                                TempretCode = SHFileOperationA (&nlpFileOp);
    426657
    427                                                 if (nlpFileOp.fAnyOperationsAborted) {where = 204;break;}
     658                                                if (nlpFileOp.fAnyOperationsAborted) {where = 230;break;}
    428659
    429660                                        } 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                                }
    545662                        }
    546663                        break;
    547664#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 {
    548778                while(1) {
    549779                        if(!pFrom[0]) break;
     
    560790                            HeapFree(GetProcessHeap(), 0, pTempTo);
    561791                        }
     792                            if (lpFileOp->wFunc == FO_COPY)
    562793                        CopyFileA(pFrom, pTo, FALSE);
     794                            else
     795                                MoveFileA(pFrom, pTo);
    563796
    564797                        pFrom += strlen(pFrom) + 1;
    565798                        pTo += strlen(pTo) + 1;
    566799                }
     800                }
    567801                TRACE("Setting AnyOpsAborted=FALSE\n");
    568802                lpFileOp->fAnyOperationsAborted=FALSE;
    569803                return 0;
    570804#endif
     805        }
    571806
    572807        case FO_DELETE:
     
    667902                        }
    668903                        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 copy
    673                 TempretCode = SHFileOperationA (&nlpFileOp);
    674 
    675                 if (nlpFileOp.fAnyOperationsAborted) {
    676                         if (TempretCode == 0x75) {
    677 // not all, the most
    678                                 TempretCode = 0xD7;
    679                                 retCode = 0xD7;
    680                         } /* endif */
    681                         break;
    682                 }
    683 
    684                 nlpFileOp.wFunc = (level<<4) + FO_DELETE;
    685 
    686                 TempretCode = SHFileOperationA (&nlpFileOp);
    687 
    688904        case 0:
    689905                        break;
    690906#else
     907        {
     908                HANDLE          hFind;
     909                WIN32_FIND_DATAA wfd;
     910                char            szTemp[MAX_PATH];
     911                char            *file_name;
     912
    691913                TRACE("File Delete:\n");
    692914                while(1) {
    693915                        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                        }
    696942                        pFrom += strlen(pFrom) + 1;
    697943                }
     
    699945                lpFileOp->fAnyOperationsAborted=FALSE;
    700946                return 0;
     947        }
    701948#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);
    702959
    703960        default:
     
    717974        if (nlpFileOp.fAnyOperationsAborted) {
    718975                lpFileOp->fAnyOperationsAborted=TRUE;
    719                 if (TempretCode > retCode) {
     976                if (TempretCode > 0 /* retCode */) {
    720977                        retCode = TempretCode;
    721978                } /* endif */
     
    7881045
    7891046
    790 
Note: See TracChangeset for help on using the changeset viewer.