Changelog: - use retCode smarter (undoing a few bits of myself) - add file_operation_invalid_handle(), file_operation_on_data(), file_operation_invalid_attr() instead of inline code
I put back the line the discussion was about - I thought about it and I probably was not thinking the right way; If there are still problems, please let me know
Sending here now as it wasn't applied: is there a problem with it or should I just re-submit ?
regards,
Joris
? .shlfile.diff.swp ? description-pak ? doc-pak ? shlfile.diff ? thisref.sh ? versions ? wine-current.deb ? wine-working.deb ? dlls/shell32/shlfileop.jh.0.c ? dlls/shell32/shlfileop.jh.c Index: dlls/shell32/shlfileop.c =================================================================== RCS file: /home/wine/wine/dlls/shell32/shlfileop.c,v retrieving revision 1.51 diff -u -p -r1.51 shlfileop.c --- dlls/shell32/shlfileop.c 14 Jan 2005 16:51:14 -0000 1.51 +++ dlls/shell32/shlfileop.c 22 Jan 2005 11:37:59 -0000 @@ -945,6 +945,65 @@ static int file_operation_checkFlags(SHF return 0; }
+static int file_operation_invalid_handle(long FuncSwitch, LPWSTR pFromFile, DWORD ToPathAttr, LPWSTR pTempFrom) +{ + BOOL b_Mask = (NULL != StrPBrkW(&pFromFile[1], wWildcardChars)); + if ((FO_DELETE == FuncSwitch) && (b_Mask)) + { + DWORD FromPathAttr; + pFromFile[0] = '\0'; + FromPathAttr = GetFileAttributesW(pTempFrom); + pFromFile[0] = '\'; + if (IsAttribDir(FromPathAttr)) + { + /* FO_DELETE with mask and without found is valid */ + return 0; + } + } + /* root (without mask) is also not allowed as source, tested in W98 */ + return ERROR_SHELL_INTERNAL_FILE_NOT_FOUND; +} + +static int file_operation_on_data(WIN32_FIND_DATAW *wfd,SHFILEOPSTRUCTW *nFileOp, LPWSTR pFromFile,LPWSTR pToFile) +{ + LPWSTR lpFileName = wfd->cAlternateFileName; + if (!lpFileName[0]) + lpFileName = wfd->cFileName; + if (IsDotDir(lpFileName) || + (IsAttribDir(wfd->dwFileAttributes) && (nFileOp->fFlags & FOF_FILESONLY))) + return 0; /* next name in pTempFrom(dir) */ + SHFileStrCpyCatW(&pToFile[1], lpFileName, NULL); + SHFileStrCpyCatW(&pFromFile[1], lpFileName, NULL); + return SHFileOperationW (nFileOp); +} + +static int file_operation_invalid_attr(LPWSTR pToFile,LPWSTR pTempTo, BOOL b_ToValid) +{ + DWORD ToPathAttr; + BOOL b_ToInvalidTail; + if (pToFile) + { + b_ToInvalidTail = (NULL != StrPBrkW(&pToFile[1], wWildcardChars)); + pToFile[0] = '\0'; + ToPathAttr = GetFileAttributesW(pTempTo); + if ((ToPathAttr == INVALID_FILE_ATTRIBUTES) && b_ToValid) + { + /* create dir must be here, sample target D:\y\ *.* create with RC=10003 */ + if (SHNotifyCreateDirectoryW(pTempTo, NULL)) + { + return 0x73;/* value unknown */ + } + ToPathAttr = GetFileAttributesW(pTempTo); + } + pToFile[0] = '\'; + if (b_ToInvalidTail) + { + return 0x10003; + } + } + return 0; +} + /************************************************************************* * SHFileOperationW [SHELL32.@] * @@ -964,7 +1023,6 @@ int WINAPI SHFileOperationW(LPSHFILEOPST LPWSTR pTempTo = NULL; LPWSTR pFromFile; LPWSTR pToFile = NULL; - LPWSTR lpFileName; int retCode = 0; DWORD ToAttr; DWORD ToPathAttr; @@ -986,8 +1044,6 @@ int WINAPI SHFileOperationW(LPSHFILEOPST long FuncSwitch = (nFileOp.wFunc & FO_MASK); long level= nFileOp.wFunc>>4;
- int ret; - /* default no error */ nFileOp.fAnyOperationsAborted = FALSE;
@@ -1016,10 +1072,9 @@ int WINAPI SHFileOperationW(LPSHFILEOPST * create dir 0 0 0 0 0 0 1 0 */
- ret = file_operation_checkFlags(nFileOp); - if (ret != 0) + retCode = file_operation_checkFlags(nFileOp); + if (retCode) { - retCode = ret; goto shfileop_end; }
@@ -1108,20 +1163,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPST hFind = FindFirstFileW(pFrom, &wfd); if (INVALID_HANDLE_VALUE == hFind) { - if ((FO_DELETE == FuncSwitch) && (b_Mask)) - { - DWORD FromPathAttr; - pFromFile[0] = '\0'; - FromPathAttr = GetFileAttributesW(pTempFrom); - pFromFile[0] = '\'; - if (IsAttribDir(FromPathAttr)) - { - /* FO_DELETE with mask and without found is valid */ - goto shfileop_end; - } - } - /* root (without mask) is also not allowed as source, tested in W98 */ - retCode = ERROR_SHELL_INTERNAL_FILE_NOT_FOUND; + retCode = file_operation_invalid_handle(FuncSwitch,pFromFile,ToPathAttr,pTempFrom); goto shfileop_end; }
@@ -1130,13 +1172,8 @@ int WINAPI SHFileOperationW(LPSHFILEOPST /* ??? b_Mask = (!SHFileStrICmpA(&pFromFile[1], &wfd.cFileName[0], HIGH_ADR, HIGH_ADR)); */ if (!pTo) /* FO_DELETE */ { - ret = file_operation_delete(&wfd,nFileOp,pFromFile,pTempFrom,&hFind); - /* if ret is not 0, nFileOp.fAnyOperationsAborted is TRUE */ - if (ret != 0) - { - retCode = ret; - goto shfileop_end; - } + retCode = file_operation_delete(&wfd,nFileOp,pFromFile,pTempFrom,&hFind); + /* if retCode is not 0, nFileOp.fAnyOperationsAborted is TRUE and while loop will end */ continue; } /* FO_DELETE ends, pTo must be always valid from here */
@@ -1202,15 +1239,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPST nFileOp.fFlags = (nFileOp.fFlags | FOF_MULTIDESTFILES); do { - lpFileName = wfd.cAlternateFileName; - if (!lpFileName[0]) - lpFileName = wfd.cFileName; - if (IsDotDir(lpFileName) || - (IsAttribDir(wfd.dwFileAttributes) && (nFileOp.fFlags & FOF_FILESONLY))) - continue; /* next name in pTempFrom(dir) */ - SHFileStrCpyCatW(&pToFile[1], lpFileName, NULL); - SHFileStrCpyCatW(&pFromFile[1], lpFileName, NULL); - retCode = SHFileOperationW (&nFileOp); + retCode = file_operation_on_data(&wfd,&nFileOp,pFromFile,pToFile); } while(!nFileOp.fAnyOperationsAborted && FindNextFileW(hFind, &wfd)); } FindClose(hFind); @@ -1222,27 +1251,9 @@ int WINAPI SHFileOperationW(LPSHFILEOPST /* only FO_COPY/FO_MOVE without mask, all others are (must be) solved */ if (IsAttribDir(wfd.dwFileAttributes) && (ToAttr == INVALID_FILE_ATTRIBUTES)) { - if (pToFile) - { - pToFile[0] = '\0'; - ToPathAttr = GetFileAttributesW(pTempTo); - if ((ToPathAttr == INVALID_FILE_ATTRIBUTES) && b_ToValid) - { - /* create dir must be here, sample target D:\y\ *.* create with RC=10003 */ - if (SHNotifyCreateDirectoryW(pTempTo, NULL)) - { - retCode = 0x73;/* value unknown */ - goto shfileop_end; - } - ToPathAttr = GetFileAttributesW(pTempTo); - } - pToFile[0] = '\'; - if (b_ToInvalidTail) - { - retCode = 0x10003; - goto shfileop_end; - } - } + retCode = file_operation_invalid_attr(pToFile,pTempTo,b_ToValid); + if (retCode) + goto shfileop_end; }
/* trailing BackSlash is ever removed and pToFile points to BackSlash before */