VirtualBox

Ignore:
Timestamp:
Mar 13, 2019 5:00:36 PM (6 years ago)
Author:
vboxsync
Message:

SharedFolders: Use RTFileOpenEx to get a more accurate SHFL_FILE_EXISTS/SHFL_FILE_CREATED/SHFL_FILE_REPLACED values to return to the guest. ticketref:9276

Location:
trunk/src/VBox/HostServices/SharedFolders
Files:
3 edited

Legend:

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

    r77276 r77685  
    369369static RTFILE testRTFileOpenpFile;
    370370
    371 extern int  testRTFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen)
     371extern int  testRTFileOpenEx(const char *pszFilename, uint64_t fOpen, PRTFILE phFile, PRTFILEACTION penmActionTaken)
    372372{
    373373 /* RTPrintf("%s, pszFilename=%s, fOpen=0x%llx\n", __PRETTY_FUNCTION__,
     
    377377    if (g_fFailIfNotLowercase && !RTStrIsLowerCased(strpbrk(pszFilename, "/\\")))
    378378        return VERR_FILE_NOT_FOUND;
    379     *pFile = testRTFileOpenpFile;
     379    *phFile = testRTFileOpenpFile;
     380    *penmActionTaken = RTFILEACTION_CREATED;
    380381    testRTFileOpenpFile = 0;
    381382    return VINF_SUCCESS;
  • trunk/src/VBox/HostServices/SharedFolders/teststubs.h

    r77276 r77685  
    2828
    2929#include <iprt/dir.h>
     30#include <iprt/file.h>
    3031#include <iprt/time.h>
    3132
     
    5455#define RTFileLock           testRTFileLock
    5556extern int testRTFileLock(RTFILE hFile, unsigned fLock, int64_t offLock, uint64_t cbLock);
    56 #define RTFileOpen           testRTFileOpen
    57 extern int testRTFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen);
     57#define RTFileOpenEx         testRTFileOpenEx
     58extern int testRTFileOpenEx(const char *pszFilename, uint64_t fOpen, PRTFILE phFile, PRTFILEACTION penmActionTaken);
    5859#define RTFileQueryInfo      testRTFileQueryInfo
    5960extern int testRTFileQueryInfo(RTFILE hFile, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs);
  • trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp

    r77248 r77685  
    211211 * @retval pfOpen     iprt create flags
    212212 */
    213 static int vbsfConvertFileOpenFlags(bool fWritable, unsigned fShflFlags, RTFMODE fMode, SHFLHANDLE handleInitial, uint32_t *pfOpen)
    214 {
    215     uint32_t fOpen = 0;
     213static int vbsfConvertFileOpenFlags(bool fWritable, unsigned fShflFlags, RTFMODE fMode, SHFLHANDLE handleInitial, uint64_t *pfOpen)
     214{
     215    uint64_t fOpen = 0;
    216216    int rc = VINF_SUCCESS;
    217217
     
    332332    switch (BIT_FLAG(fShflFlags, SHFL_CF_ACCESS_MASK_DENY))
    333333    {
    334     default:
    335     case SHFL_CF_ACCESS_DENYNONE:
    336         fOpen |= RTFILE_O_DENY_NONE;
    337         Log(("FLAG: SHFL_CF_ACCESS_DENYNONE\n"));
    338         break;
    339 
    340     case SHFL_CF_ACCESS_DENYREAD:
    341         fOpen |= RTFILE_O_DENY_READ;
    342         Log(("FLAG: SHFL_CF_ACCESS_DENYREAD\n"));
    343         break;
    344 
    345     case SHFL_CF_ACCESS_DENYWRITE:
    346         fOpen |= RTFILE_O_DENY_WRITE;
    347         Log(("FLAG: SHFL_CF_ACCESS_DENYWRITE\n"));
    348         break;
    349 
    350     case SHFL_CF_ACCESS_DENYALL:
    351         fOpen |= RTFILE_O_DENY_ALL;
    352         Log(("FLAG: SHFL_CF_ACCESS_DENYALL\n"));
    353         break;
     334        default:
     335        case SHFL_CF_ACCESS_DENYNONE:
     336            fOpen |= RTFILE_O_DENY_NONE;
     337            Log(("FLAG: SHFL_CF_ACCESS_DENYNONE\n"));
     338            break;
     339
     340        case SHFL_CF_ACCESS_DENYREAD:
     341            fOpen |= RTFILE_O_DENY_READ;
     342            Log(("FLAG: SHFL_CF_ACCESS_DENYREAD\n"));
     343            break;
     344
     345        case SHFL_CF_ACCESS_DENYWRITE:
     346            fOpen |= RTFILE_O_DENY_WRITE;
     347            Log(("FLAG: SHFL_CF_ACCESS_DENYWRITE\n"));
     348            break;
     349
     350        case SHFL_CF_ACCESS_DENYALL:
     351            fOpen |= RTFILE_O_DENY_ALL;
     352            Log(("FLAG: SHFL_CF_ACCESS_DENYALL\n"));
     353            break;
    354354    }
    355355
     
    357357    switch (BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_EXISTS))
    358358    {
    359     case SHFL_CF_ACT_OPEN_IF_EXISTS:
    360         if (SHFL_CF_ACT_CREATE_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
    361         {
    362             fOpen |= RTFILE_O_OPEN_CREATE;
    363             Log(("FLAGS: SHFL_CF_ACT_OPEN_IF_EXISTS and SHFL_CF_ACT_CREATE_IF_NEW\n"));
    364         }
    365         else if (SHFL_CF_ACT_FAIL_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
    366         {
    367             fOpen |= RTFILE_O_OPEN;
    368             Log(("FLAGS: SHFL_CF_ACT_OPEN_IF_EXISTS and SHFL_CF_ACT_FAIL_IF_NEW\n"));
    369         }
    370         else
    371         {
    372             Log(("FLAGS: invalid open/create action combination\n"));
     359        case SHFL_CF_ACT_OPEN_IF_EXISTS:
     360            if (SHFL_CF_ACT_CREATE_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
     361            {
     362                fOpen |= RTFILE_O_OPEN_CREATE;
     363                Log(("FLAGS: SHFL_CF_ACT_OPEN_IF_EXISTS and SHFL_CF_ACT_CREATE_IF_NEW\n"));
     364            }
     365            else if (SHFL_CF_ACT_FAIL_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
     366            {
     367                fOpen |= RTFILE_O_OPEN;
     368                Log(("FLAGS: SHFL_CF_ACT_OPEN_IF_EXISTS and SHFL_CF_ACT_FAIL_IF_NEW\n"));
     369            }
     370            else
     371            {
     372                Log(("FLAGS: invalid open/create action combination\n"));
     373                rc = VERR_INVALID_PARAMETER;
     374            }
     375            break;
     376        case SHFL_CF_ACT_FAIL_IF_EXISTS:
     377            if (SHFL_CF_ACT_CREATE_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
     378            {
     379                fOpen |= RTFILE_O_CREATE;
     380                Log(("FLAGS: SHFL_CF_ACT_FAIL_IF_EXISTS and SHFL_CF_ACT_CREATE_IF_NEW\n"));
     381            }
     382            else
     383            {
     384                Log(("FLAGS: invalid open/create action combination\n"));
     385                rc = VERR_INVALID_PARAMETER;
     386            }
     387            break;
     388        case SHFL_CF_ACT_REPLACE_IF_EXISTS:
     389            if (SHFL_CF_ACT_CREATE_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
     390            {
     391                fOpen |= RTFILE_O_CREATE_REPLACE;
     392                Log(("FLAGS: SHFL_CF_ACT_REPLACE_IF_EXISTS and SHFL_CF_ACT_CREATE_IF_NEW\n"));
     393            }
     394            else if (SHFL_CF_ACT_FAIL_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
     395            {
     396                fOpen |= RTFILE_O_OPEN | RTFILE_O_TRUNCATE;
     397                Log(("FLAGS: SHFL_CF_ACT_REPLACE_IF_EXISTS and SHFL_CF_ACT_FAIL_IF_NEW\n"));
     398            }
     399            else
     400            {
     401                Log(("FLAGS: invalid open/create action combination\n"));
     402                rc = VERR_INVALID_PARAMETER;
     403            }
     404            break;
     405        case SHFL_CF_ACT_OVERWRITE_IF_EXISTS:
     406            if (SHFL_CF_ACT_CREATE_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
     407            {
     408                fOpen |= RTFILE_O_CREATE_REPLACE;
     409                Log(("FLAGS: SHFL_CF_ACT_OVERWRITE_IF_EXISTS and SHFL_CF_ACT_CREATE_IF_NEW\n"));
     410            }
     411            else if (SHFL_CF_ACT_FAIL_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
     412            {
     413                fOpen |= RTFILE_O_OPEN | RTFILE_O_TRUNCATE;
     414                Log(("FLAGS: SHFL_CF_ACT_OVERWRITE_IF_EXISTS and SHFL_CF_ACT_FAIL_IF_NEW\n"));
     415            }
     416            else
     417            {
     418                Log(("FLAGS: invalid open/create action combination\n"));
     419                rc = VERR_INVALID_PARAMETER;
     420            }
     421            break;
     422        default:
    373423            rc = VERR_INVALID_PARAMETER;
    374         }
    375         break;
    376     case SHFL_CF_ACT_FAIL_IF_EXISTS:
    377         if (SHFL_CF_ACT_CREATE_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
    378         {
    379             fOpen |= RTFILE_O_CREATE;
    380             Log(("FLAGS: SHFL_CF_ACT_FAIL_IF_EXISTS and SHFL_CF_ACT_CREATE_IF_NEW\n"));
    381         }
    382         else
    383         {
    384             Log(("FLAGS: invalid open/create action combination\n"));
    385             rc = VERR_INVALID_PARAMETER;
    386         }
    387         break;
    388     case SHFL_CF_ACT_REPLACE_IF_EXISTS:
    389         if (SHFL_CF_ACT_CREATE_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
    390         {
    391             fOpen |= RTFILE_O_CREATE_REPLACE;
    392             Log(("FLAGS: SHFL_CF_ACT_REPLACE_IF_EXISTS and SHFL_CF_ACT_CREATE_IF_NEW\n"));
    393         }
    394         else if (SHFL_CF_ACT_FAIL_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
    395         {
    396             fOpen |= RTFILE_O_OPEN | RTFILE_O_TRUNCATE;
    397             Log(("FLAGS: SHFL_CF_ACT_REPLACE_IF_EXISTS and SHFL_CF_ACT_FAIL_IF_NEW\n"));
    398         }
    399         else
    400         {
    401             Log(("FLAGS: invalid open/create action combination\n"));
    402             rc = VERR_INVALID_PARAMETER;
    403         }
    404         break;
    405     case SHFL_CF_ACT_OVERWRITE_IF_EXISTS:
    406         if (SHFL_CF_ACT_CREATE_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
    407         {
    408             fOpen |= RTFILE_O_CREATE_REPLACE;
    409             Log(("FLAGS: SHFL_CF_ACT_OVERWRITE_IF_EXISTS and SHFL_CF_ACT_CREATE_IF_NEW\n"));
    410         }
    411         else if (SHFL_CF_ACT_FAIL_IF_NEW == BIT_FLAG(fShflFlags, SHFL_CF_ACT_MASK_IF_NEW))
    412         {
    413             fOpen |= RTFILE_O_OPEN | RTFILE_O_TRUNCATE;
    414             Log(("FLAGS: SHFL_CF_ACT_OVERWRITE_IF_EXISTS and SHFL_CF_ACT_FAIL_IF_NEW\n"));
    415         }
    416         else
    417         {
    418             Log(("FLAGS: invalid open/create action combination\n"));
    419             rc = VERR_INVALID_PARAMETER;
    420         }
    421         break;
    422     default:
    423         rc = VERR_INVALID_PARAMETER;
    424         Log(("FLAG: SHFL_CF_ACT_MASK_IF_EXISTS - invalid parameter\n"));
     424            Log(("FLAG: SHFL_CF_ACT_MASK_IF_EXISTS - invalid parameter\n"));
    425425    }
    426426
     
    456456    Log(("SHFL create flags %08x\n", pParms->CreateFlags));
    457457
    458     SHFLHANDLE      handle = SHFL_HANDLE_NIL;
    459     SHFLFILEHANDLE *pHandle = 0;
    460     /* Open or create a file. */
    461     uint32_t fOpen = 0;
    462     bool fNoError = false;
    463     static int cErrors;
     458    RTFILEACTION    enmActionTaken = RTFILEACTION_INVALID;
     459    SHFLHANDLE      handle         = SHFL_HANDLE_NIL;
     460    SHFLFILEHANDLE *pHandle        = NULL;
    464461
    465462    /* is the guest allowed to write to this share? */
     
    469466        fWritable = false;
    470467
     468    uint64_t fOpen = 0;
    471469    rc = vbsfConvertFileOpenFlags(fWritable, pParms->CreateFlags, pParms->Info.Attr.fMode, pParms->Handle, &fOpen);
    472470    if (RT_SUCCESS(rc))
     
    481479                pHandle->root = root;
    482480                pHandle->file.fOpenFlags = fOpen;
    483                 rc = RTFileOpen(&pHandle->file.Handle, pszPath, fOpen);
    484             }
    485         }
    486     }
     481                rc = RTFileOpenEx(pszPath, fOpen, &pHandle->file.Handle, &enmActionTaken);
     482            }
     483        }
     484    }
     485    bool fNoError = false;
    487486    if (RT_FAILURE(rc))
    488487    {
    489488        switch (rc)
    490489        {
    491         case VERR_FILE_NOT_FOUND:
    492             pParms->Result = SHFL_FILE_NOT_FOUND;
    493 
    494             /* This actually isn't an error, so correct the rc before return later,
    495                because the driver (VBoxSF.sys) expects rc = VINF_SUCCESS and checks the result code. */
    496             fNoError = true;
    497             break;
    498         case VERR_PATH_NOT_FOUND:
    499             pParms->Result = SHFL_PATH_NOT_FOUND;
    500 
    501             /* This actually isn't an error, so correct the rc before return later,
    502                because the driver (VBoxSF.sys) expects rc = VINF_SUCCESS and checks the result code. */
    503             fNoError = true;
    504             break;
    505         case VERR_ALREADY_EXISTS:
    506             RTFSOBJINFO info;
    507 
    508             /** @todo Possible race left here. */
    509             if (RT_SUCCESS(RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient))))
    510             {
     490            case VERR_FILE_NOT_FOUND:
     491                pParms->Result = SHFL_FILE_NOT_FOUND;
     492
     493                /* This actually isn't an error, so correct the rc before return later,
     494                   because the driver (VBoxSF.sys) expects rc = VINF_SUCCESS and checks the result code. */
     495                fNoError = true;
     496                break;
     497
     498            case VERR_PATH_NOT_FOUND:
     499                pParms->Result = SHFL_PATH_NOT_FOUND;
     500                fNoError = true; /* Not an error either (see above). */
     501                break;
     502
     503            case VERR_ALREADY_EXISTS:
     504            {
     505                RTFSOBJINFO info;
     506
     507                /** @todo Possible race left here. */
     508                if (RT_SUCCESS(RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient))))
     509                {
    511510#ifdef RT_OS_WINDOWS
    512                 info.Attr.fMode |= 0111;
    513 #endif
    514                 vbfsCopyFsObjInfoFromIprt(&pParms->Info, &info);
    515             }
    516             pParms->Result = SHFL_FILE_EXISTS;
    517 
    518             /* This actually isn't an error, so correct the rc before return later,
    519                because the driver (VBoxSF.sys) expects rc = VINF_SUCCESS and checks the result code. */
    520             fNoError = true;
    521             break;
    522         case VERR_TOO_MANY_OPEN_FILES:
    523             if (cErrors < 32)
    524             {
    525                 LogRel(("SharedFolders host service: Cannot open '%s' -- too many open files.\n", pszPath));
     511                    info.Attr.fMode |= 0111;
     512#endif
     513                    vbfsCopyFsObjInfoFromIprt(&pParms->Info, &info);
     514                }
     515                pParms->Result = SHFL_FILE_EXISTS;
     516
     517                /* This actually isn't an error, so correct the rc before return later,
     518                   because the driver (VBoxSF.sys) expects rc = VINF_SUCCESS and checks the result code. */
     519                fNoError = true;
     520                break;
     521            }
     522
     523            case VERR_TOO_MANY_OPEN_FILES:
     524            {
     525                static int s_cErrors;
     526                if (s_cErrors < 32)
     527                {
     528                    LogRel(("SharedFolders host service: Cannot open '%s' -- too many open files.\n", pszPath));
    526529#if defined RT_OS_LINUX || defined(RT_OS_SOLARIS)
    527                 if (cErrors < 1)
    528                     LogRel(("SharedFolders host service: Try to increase the limit for open files (ulimit -n)\n"));
    529 #endif
    530                 cErrors++;
    531             }
    532             pParms->Result = SHFL_NO_RESULT;
    533             break;
    534         default:
    535             pParms->Result = SHFL_NO_RESULT;
     530                    if (s_cErrors < 1)
     531                        LogRel(("SharedFolders host service: Try to increase the limit for open files (ulimit -n)\n"));
     532#endif
     533                    s_cErrors++;
     534                }
     535                pParms->Result = SHFL_NO_RESULT;
     536                break;
     537            }
     538
     539            default:
     540                pParms->Result = SHFL_NO_RESULT;
    536541        }
    537542    }
    538543    else
    539544    {
    540         /** @note The shared folder status code is very approximate, as the runtime
    541           *       does not really provide this information. */
    542         pParms->Result = SHFL_FILE_EXISTS;  /* We lost the information as to whether it was
    543                                                created when we eliminated the race. */
    544         if (   (   SHFL_CF_ACT_REPLACE_IF_EXISTS
    545                 == BIT_FLAG(pParms->CreateFlags, SHFL_CF_ACT_MASK_IF_EXISTS))
    546             || (   SHFL_CF_ACT_OVERWRITE_IF_EXISTS
    547                 == BIT_FLAG(pParms->CreateFlags, SHFL_CF_ACT_MASK_IF_EXISTS)))
     545        switch (enmActionTaken)
     546        {
     547            default:
     548                AssertFailed();
     549                RT_FALL_THRU();
     550            case RTFILEACTION_OPENED:
     551                pParms->Result = SHFL_FILE_EXISTS;
     552                break;
     553            case RTFILEACTION_CREATED:
     554                pParms->Result = SHFL_FILE_CREATED;
     555                break;
     556            case RTFILEACTION_REPLACED:
     557            case RTFILEACTION_TRUNCATED: /* not quite right */
     558                pParms->Result = SHFL_FILE_REPLACED;
     559                break;
     560        }
     561
     562        if (   (pParms->CreateFlags & SHFL_CF_ACT_MASK_IF_EXISTS) == SHFL_CF_ACT_REPLACE_IF_EXISTS
     563            || (pParms->CreateFlags & SHFL_CF_ACT_MASK_IF_EXISTS) == SHFL_CF_ACT_OVERWRITE_IF_EXISTS)
    548564        {
    549565            /* For now, we do not treat a failure here as fatal. */
    550             /** @todo Also set the size for SHFL_CF_ACT_CREATE_IF_NEW if
    551                      SHFL_CF_ACT_FAIL_IF_EXISTS is set. */
     566            /** @todo Also set the size for SHFL_CF_ACT_CREATE_IF_NEW if SHFL_CF_ACT_FAIL_IF_EXISTS is set. */
     567            /** @todo r=bird: Exactly document cbObject usage and see what we can get
     568             *        away with here.  I suspect it is only needed for windows and only
     569             *        with SHFL_FILE_CREATED and SHFL_FILE_REPLACED, and only if
     570             *        cbObject is non-zero. */
    552571            RTFileSetSize(pHandle->file.Handle, pParms->Info.cbObject);
    553             pParms->Result = SHFL_FILE_REPLACED;
    554         }
    555         if (   (   SHFL_CF_ACT_FAIL_IF_EXISTS
    556                 == BIT_FLAG(pParms->CreateFlags, SHFL_CF_ACT_MASK_IF_EXISTS))
    557             || (   SHFL_CF_ACT_CREATE_IF_NEW
    558                 == BIT_FLAG(pParms->CreateFlags, SHFL_CF_ACT_MASK_IF_NEW)))
    559         {
    560             pParms->Result = SHFL_FILE_CREATED;
    561572        }
    562573#if 0
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