VirtualBox

Changeset 78704 in vbox


Ignore:
Timestamp:
May 24, 2019 1:10:26 AM (6 years ago)
Author:
vboxsync
Message:

SharedFoldersSvc: More VERR_FILE_NOT_FOUND/VERR_PATH_NOT_FOUND and some other tweaks for windows guests on non-windows hosts. FsPerf seems reasonably happy now. bugref:9172

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp

    r78703 r78704  
    5757#define SHFL_RT_LINK(pClient) ((pClient)->fu32Flags & SHFL_CF_SYMLINKS ? RTPATH_F_ON_LINK : RTPATH_F_FOLLOW_LINK)
    5858
     59/**
     60 * @todo find a better solution for supporting the execute bit for non-windows
     61 * guests on windows host. Search for "0111" to find all the relevant places.
     62 */
     63
    5964
    6065#ifndef RT_OS_WINDOWS
     66
    6167/**
    6268 * Helps to check if pszPath deserves a VERR_PATH_NOT_FOUND status when catering
     
    8490    return false;
    8591}
     92
     93/**
     94 * Helps to check if pszPath deserves a VERR_PATH_NOT_FOUND status when catering
     95 * to windows guests.
     96 */
     97static bool vbsfErrorStyleIsWindowsPathNotFound2(char *pszSrcPath, char *pszDstPath)
     98{
     99    /*
     100     * Do the source parent first.
     101     */
     102    size_t cchParent = RTPathParentLength(pszSrcPath);
     103    char chSaved = pszSrcPath[cchParent];
     104    pszSrcPath[cchParent] = '\0';
     105    RTFSOBJINFO ObjInfo;
     106    int vrc = RTPathQueryInfoEx(pszSrcPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     107    pszSrcPath[cchParent] = chSaved;
     108    if (   (RT_SUCCESS(vrc) && !RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
     109        || vrc == VERR_FILE_NOT_FOUND
     110        || vrc == VERR_PATH_NOT_FOUND)
     111        return true;
     112    if (RT_FAILURE(vrc))
     113        return false;
     114
     115    /*
     116     * The source itself.
     117     */
     118    vrc = RTPathQueryInfoEx(pszSrcPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     119    if (RT_SUCCESS(vrc))
     120    {
     121        /*
     122         * The source is fine, continue with the destination.
     123         */
     124        cchParent = RTPathParentLength(pszDstPath);
     125        chSaved = pszDstPath[cchParent];
     126        pszDstPath[cchParent] = '\0';
     127        vrc = RTPathQueryInfoEx(pszDstPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     128        pszDstPath[cchParent] = chSaved;
     129        if (   (RT_SUCCESS(vrc) && !RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
     130            || vrc == VERR_FILE_NOT_FOUND
     131            || vrc == VERR_PATH_NOT_FOUND)
     132            return true;
     133    }
     134    return false;
     135}
     136
     137/**
     138 * Helps checking if the specified path happens to exist but not be a directory.
     139 */
     140static bool vbsfErrorStyleIsWindowsNotADirectory(const char *pszPath)
     141{
     142    RTFSOBJINFO ObjInfo;
     143    int vrc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     144    if (RT_SUCCESS(vrc))
     145    {
     146        if (RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
     147            return false;
     148        return true;
     149    }
     150    return false;
     151}
     152
     153/**
     154 * Helps to check if pszPath deserves a VERR_INVALID_NAME status when catering
     155 * to windows guests.
     156 */
     157static bool vbsfErrorStyleIsWindowsInvalidNameForNonDir(char *pszPath)
     158{
     159    /*
     160     * This only applies to paths with trailing slashes.
     161     */
     162    size_t const cchPath = strlen(pszPath);
     163    if (cchPath > 0 && RTPATH_IS_SLASH(pszPath[cchPath - 1]))
     164    {
     165        /*
     166         * However it doesn't if an earlier path component is missing or not a file.
     167         */
     168        size_t cchParent = RTPathParentLength(pszPath);
     169        char chSaved = pszPath[cchParent];
     170        pszPath[cchParent] = '\0';
     171        RTFSOBJINFO ObjInfo;
     172        int vrc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     173        pszPath[cchParent] = chSaved;
     174        if (RT_SUCCESS(vrc) && RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
     175            return true;
     176    }
     177    return false;
     178}
     179
    86180#endif /* RT_OS_WINDOWS */
    87 
    88 
    89 /**
    90  * @todo find a better solution for supporting the execute bit for non-windows
    91  * guests on windows host. Search for "0111" to find all the relevant places.
    92  */
    93181
    94182void vbsfStripLastComponent(char *pszFullPath, uint32_t cbFullPathRoot)
     
    530618
    531619            case VERR_PATH_NOT_FOUND:
     620#ifndef RT_OS_WINDOWS
     621                if (   SHFL_CLIENT_NEED_WINDOWS_ERROR_STYLE_ADJUST_ON_POSIX(pClient)
     622                    && vbsfErrorStyleIsWindowsInvalidNameForNonDir(pszPath))
     623                {
     624                    rc = VERR_INVALID_NAME;
     625                    pParms->Result = SHFL_NO_RESULT;
     626                    break;
     627                }
     628#endif
    532629                pParms->Result = SHFL_PATH_NOT_FOUND;
    533630                fNoError = true; /* Not an error either (see above). */
     
    690787    {
    691788        pHandle->root = root;
    692         rc = VINF_SUCCESS;
    693789        pParms->Result = SHFL_FILE_EXISTS;  /* May be overwritten with SHFL_FILE_CREATED. */
    694790        /** @todo Can anyone think of a sensible, race-less way to do this?  Although
     
    708804            if (RT_FAILURE(rc))
    709805            {
     806                /** @todo we still return 'rc' as failure here, so this is mostly pointless.  */
    710807                switch (rc)
    711808                {
    712                 case VERR_ALREADY_EXISTS:
    713                     pParms->Result = SHFL_FILE_EXISTS;
    714                     break;
    715                 case VERR_PATH_NOT_FOUND:
    716                     pParms->Result = SHFL_PATH_NOT_FOUND;
    717                     break;
    718                 default:
    719                     pParms->Result = SHFL_NO_RESULT;
     809                    case VERR_ALREADY_EXISTS:
     810                        pParms->Result = SHFL_FILE_EXISTS;
     811                        break;
     812                    case VERR_PATH_NOT_FOUND:
     813                        pParms->Result = SHFL_PATH_NOT_FOUND;
     814                        break;
     815                    case VERR_FILE_NOT_FOUND: /* may happen on posix */
     816                        pParms->Result = SHFL_FILE_NOT_FOUND;
     817#ifndef RT_OS_WINDOWS
     818                        if (   SHFL_CLIENT_NEED_WINDOWS_ERROR_STYLE_ADJUST_ON_POSIX(pClient)
     819                            && vbsfErrorStyleIsWindowsPathNotFound(pszPath))
     820                        {
     821                            pParms->Result = SHFL_PATH_NOT_FOUND;
     822                            rc = VERR_PATH_NOT_FOUND;
     823                        }
     824#endif
     825                        break;
     826                    default:
     827                        pParms->Result = SHFL_NO_RESULT;
    720828                }
    721829            }
    722830        }
     831        else
     832            rc = VINF_SUCCESS;
    723833        if (   RT_SUCCESS(rc)
    724834            || (SHFL_CF_ACT_OPEN_IF_EXISTS == BIT_FLAG(pParms->CreateFlags, SHFL_CF_ACT_MASK_IF_EXISTS)))
     
    741851                switch (rc)
    742852                {
    743                 case VERR_FILE_NOT_FOUND:  /* Does this make sense? */
    744                     pParms->Result = SHFL_FILE_NOT_FOUND;
     853                    case VERR_FILE_NOT_FOUND:
     854                        pParms->Result = SHFL_FILE_NOT_FOUND;
    745855#ifndef RT_OS_WINDOWS
    746                     if (   SHFL_CLIENT_NEED_WINDOWS_ERROR_STYLE_ADJUST_ON_POSIX(pClient)
    747                         && vbsfErrorStyleIsWindowsPathNotFound(pszPath))
    748                     {
     856                        if (   SHFL_CLIENT_NEED_WINDOWS_ERROR_STYLE_ADJUST_ON_POSIX(pClient)
     857                            && vbsfErrorStyleIsWindowsPathNotFound(pszPath))
     858                        {
     859                            pParms->Result = SHFL_PATH_NOT_FOUND;
     860                            rc = VERR_PATH_NOT_FOUND;
     861                        }
     862#endif
     863                        break;
     864                    case VERR_PATH_NOT_FOUND:
    749865                        pParms->Result = SHFL_PATH_NOT_FOUND;
    750                         rc = VERR_PATH_NOT_FOUND;
    751                     }
    752 #endif
    753                     break;
    754                 case VERR_PATH_NOT_FOUND:
    755                     pParms->Result = SHFL_PATH_NOT_FOUND;
    756                     break;
    757                 case VERR_ACCESS_DENIED:
    758                     pParms->Result = SHFL_FILE_EXISTS;
    759                     break;
    760                 default:
    761                     pParms->Result = SHFL_NO_RESULT;
     866#ifndef RT_OS_WINDOWS
     867                        if (   SHFL_CLIENT_NEED_WINDOWS_ERROR_STYLE_ADJUST_ON_POSIX(pClient)
     868                            && vbsfErrorStyleIsWindowsNotADirectory(pszPath))
     869                        {
     870                            pParms->Result = SHFL_FILE_EXISTS;
     871                            rc = VERR_NOT_A_DIRECTORY;
     872                            break;
     873                        }
     874#endif
     875                        break;
     876                    case VERR_ACCESS_DENIED:
     877                        pParms->Result = SHFL_FILE_EXISTS;
     878                        break;
     879                    default:
     880                        pParms->Result = SHFL_NO_RESULT;
    762881                }
    763882            }
     
    22612380                else
    22622381                    rc = RTDirRemove(pszFullPath);
     2382
     2383#if 0 //ndef RT_OS_WINDOWS
     2384                /* There are a few adjustments to be made here: */
     2385                if (   rc == VERR_FILE_NOT_FOUND
     2386                    && SHFL_CLIENT_NEED_WINDOWS_ERROR_STYLE_ADJUST_ON_POSIX(pClient)
     2387                    && vbsfErrorStyleIsWindowsPathNotFound(pszFullPath))
     2388                    rc = VERR_PATH_NOT_FOUND;
     2389                else if (   rc == VERR_PATH_NOT_FOUND
     2390                         && SHFL_CLIENT_NEED_WINDOWS_ERROR_STYLE_ADJUST_ON_POSIX(pClient))
     2391                {
     2392                    if (flags & (SHFL_REMOVE_FILE | SHFL_REMOVE_SYMLINK))
     2393                    {
     2394                        size_t cchFullPath = strlen(pszFullPath);
     2395                        if (cchFullPath > 0 && RTPATH_IS_SLASH(pszFullPath[cchFullPath - 1]))
     2396                            rc = VERR_INVALID_NAME;
     2397                    }
     2398                    else if (vbsfErrorStyleIsWindowsNotADirectory(pszFullPath))
     2399                        rc = VERR_NOT_A_DIRECTORY;
     2400                }
     2401#endif
    22632402            }
    22642403            else
     
    23272466            {
    23282467                rc = RTFileMove(pszFullPathSrc, pszFullPathDest,
    2329                                   ((flags & SHFL_RENAME_REPLACE_IF_EXISTS) ? RTFILEMOVE_FLAGS_REPLACE : 0));
     2468                                ((flags & SHFL_RENAME_REPLACE_IF_EXISTS) ? RTFILEMOVE_FLAGS_REPLACE : 0));
    23302469            }
    23312470            else
     
    23332472                /* NT ignores the REPLACE flag and simply return and already exists error. */
    23342473                rc = RTDirRename(pszFullPathSrc, pszFullPathDest,
    2335                                    ((flags & SHFL_RENAME_REPLACE_IF_EXISTS) ? RTPATHRENAME_FLAGS_REPLACE : 0));
    2336             }
     2474                                 ((flags & SHFL_RENAME_REPLACE_IF_EXISTS) ? RTPATHRENAME_FLAGS_REPLACE : 0));
     2475            }
     2476#ifndef RT_OS_WINDOWS
     2477            if (   rc == VERR_FILE_NOT_FOUND
     2478                && SHFL_CLIENT_NEED_WINDOWS_ERROR_STYLE_ADJUST_ON_POSIX(pClient)
     2479                && vbsfErrorStyleIsWindowsPathNotFound2(pszFullPathSrc, pszFullPathDest))
     2480                rc = VERR_PATH_NOT_FOUND;
     2481#endif
    23372482        }
    23382483
     
    24912636    return VINF_SUCCESS;
    24922637}
     2638
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette