VirtualBox

Changeset 78666 in vbox for trunk/src


Ignore:
Timestamp:
May 22, 2019 3:27:27 PM (6 years ago)
Author:
vboxsync
Message:

Main/GuestControl: Better error message from copyToGuest and various related cleanups and todo notes. Tip: Pass objects like GuestSessionFsSourceSet by reference instead of copies all the time. bugref:9320

Location:
trunk/src/VBox/Main
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/GuestFileImpl.h

    r77587 r78666  
    6161    int             i_closeFile(int *pGuestRc);
    6262    EventSource    *i_getEventSource(void) { return mEventSource; }
     63    static const char *i_guestVrcToString(int guestRc);
    6364    static Utf8Str  i_guestErrorToString(int guestRc);
    6465    int             i_onFileNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
  • trunk/src/VBox/Main/include/GuestSessionImplTasks.h

    r77531 r78666  
    4747        : enmType(FsObjType_Unknown)
    4848        , enmPathStyle(PathStyle_Unknown)
    49         , fDryRun(false) { }
     49        , fDryRun(false) { } /** @todo r=bird: only half initialized. See comments in GuestSession::fileCopyToGuest(). */
    5050
    5151    Utf8Str     strSource;
     
    213213    int setProgressSuccess(void);
    214214    HRESULT setProgressErrorMsg(HRESULT hr, const Utf8Str &strMsg);
     215    HRESULT setProgressErrorMsg(HRESULT hrc, int vrc, const char *pszFormat, ...);
    215216
    216217    inline void setTaskDesc(const Utf8Str &strTaskDesc) throw()
     
    281282public:
    282283
    283     GuestSessionTaskCopyFrom(GuestSession *pSession, GuestSessionFsSourceSet vecSrc, const Utf8Str &strDest);
     284    GuestSessionTaskCopyFrom(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc, const Utf8Str &strDest);
    284285    virtual ~GuestSessionTaskCopyFrom(void);
    285286
     
    295296public:
    296297
    297     GuestSessionTaskCopyTo(GuestSession *pSession, GuestSessionFsSourceSet vecSrc, const Utf8Str &strDest);
     298    GuestSessionTaskCopyTo(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc, const Utf8Str &strDest);
    298299    virtual ~GuestSessionTaskCopyTo(void);
    299300
     
    309310public:
    310311
    311     GuestSessionTaskUpdateAdditions(GuestSession *pSession,
    312                                const Utf8Str &strSource, const ProcessArguments &aArguments,
    313                                uint32_t fFlags);
     312    GuestSessionTaskUpdateAdditions(GuestSession *pSession, const Utf8Str &strSource,
     313                                    const ProcessArguments &aArguments, uint32_t fFlags);
    314314    virtual ~GuestSessionTaskUpdateAdditions(void);
    315315    int Run(void);
  • trunk/src/VBox/Main/include/ProgressImpl.h

    r76562 r78666  
    139139                              const char *aText,
    140140                              va_list va);
     141    HRESULT i_notifyCompleteBoth(HRESULT aResultCode,
     142                                 int vrc,
     143                                 const GUID &aIID,
     144                                 const char *pcszComponent,
     145                                 const char *aText,
     146                                 ...);
     147    HRESULT i_notifyCompleteBothV(HRESULT aResultCode,
     148                                  int vrc,
     149                                  const GUID &aIID,
     150                                  const char *pcszComponent,
     151                                  const char *aText,
     152                                  va_list va);
    141153
    142154    bool i_setCancelCallback(void (*pfnCallback)(void *), void *pvUser);
  • trunk/src/VBox/Main/src-all/ProgressImpl.cpp

    r77252 r78666  
    412412    AssertComRCReturnRC(rc);
    413413    errorInfo->init(aResultCode, aIID, pcszComponent, text);
     414
     415    return notifyComplete(aResultCode, errorInfo);
     416}
     417
     418/**
     419 * Wrapper around Progress:notifyCompleteBothV.
     420 */
     421HRESULT Progress::i_notifyCompleteBoth(HRESULT aResultCode,
     422                                       int vrc,
     423                                       const GUID &aIID,
     424                                       const char *pcszComponent,
     425                                       const char *aText,
     426                                       ...)
     427{
     428    va_list va;
     429    va_start(va, aText);
     430    HRESULT hrc = i_notifyCompleteBothV(aResultCode, vrc, aIID, pcszComponent, aText, va);
     431    va_end(va);
     432    return hrc;
     433}
     434
     435/**
     436 * Marks the operation as complete and attaches full error info.
     437 *
     438 * @param aResultCode   Operation result (error) code, must not be S_OK.
     439 * @param vrc           VBox status code to associate with the error.
     440 * @param aIID          IID of the interface that defines the error.
     441 * @param pszComponent  Name of the component that generates the error.
     442 * @param pszFormat     Error message (must not be null), an RTStrPrintf-like
     443 *                      format string in UTF-8 encoding.
     444 * @param va            List of arguments for the format string.
     445 */
     446HRESULT Progress::i_notifyCompleteBothV(HRESULT aResultCode,
     447                                        int vrc,
     448                                        const GUID &aIID,
     449                                        const char *pszComponent,
     450                                        const char *pszFormat,
     451                                        va_list va)
     452{
     453    /* expected to be used only in case of error */
     454    Assert(FAILED(aResultCode));
     455
     456    Utf8Str text(pszFormat, va);
     457    ComObjPtr<VirtualBoxErrorInfo> errorInfo;
     458    HRESULT rc = errorInfo.createObject();
     459    AssertComRCReturnRC(rc);
     460    errorInfo->initEx(aResultCode, vrc, aIID, pszComponent, text);
    414461
    415462    return notifyComplete(aResultCode, errorInfo);
  • trunk/src/VBox/Main/src-client/GuestFileImpl.cpp

    r78234 r78666  
    396396}
    397397
    398 /* static */
    399 Utf8Str GuestFile::i_guestErrorToString(int rcGuest)
    400 {
    401     Utf8Str strError;
    402 
     398/* static */ const char *GuestFile::i_guestVrcToString(int rcGuest)
     399{
    403400    /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */
    404401    switch (rcGuest)
    405402    {
    406         case VERR_ACCESS_DENIED:
    407             strError += Utf8StrFmt(tr("Access denied"));
    408             break;
    409 
    410         case VERR_ALREADY_EXISTS:
    411             strError += Utf8StrFmt(tr("File already exists"));
    412             break;
    413 
    414         case VERR_FILE_NOT_FOUND:
    415             strError += Utf8StrFmt(tr("File not found"));
    416             break;
    417 
    418         case VERR_NET_HOST_NOT_FOUND:
    419             strError += Utf8StrFmt(tr("Host name not found"));
    420             break;
    421 
    422         case VERR_SHARING_VIOLATION:
    423             strError += Utf8StrFmt(tr("Sharing violation"));
    424             break;
    425 
    426         default:
    427             strError += Utf8StrFmt("%Rrc", rcGuest);
    428             break;
    429     }
    430 
    431     return strError;
     403        case VERR_ACCESS_DENIED:        return tr("Access denied");
     404        case VERR_ALREADY_EXISTS:       return tr("File already exists");
     405        case VERR_FILE_NOT_FOUND:       return tr("File not found");
     406        case VERR_NET_HOST_NOT_FOUND:   return tr("Host name not found");
     407        case VERR_SHARING_VIOLATION:    return tr("Sharing violation");
     408        default:                        return RTErrGetDefine(rcGuest);
     409    }
     410}
     411
     412/**
     413 * @todo r=bird: This is an absolutely cryptic way of reporting errors.  You may convert
     414 *               this to a const char * returning function for explaining rcGuest and
     415 *               use that as part of a _proper_ error message.  This alone extremely
     416 *               user unfriendly. E.g. which file is not found? One of the source files,
     417 *               a destination file, what are you referring to?!?
     418 *
     419 *               I've addressed one of these that annoyed me, you can do the rest of them.
     420 */
     421/* static */ Utf8Str GuestFile::i_guestErrorToString(int rcGuest)
     422{
     423    /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */
     424    return i_guestVrcToString(rcGuest);
    432425}
    433426
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r78234 r78666  
    793793
    794794    /* Validate stuff. */
    795     if (RT_UNLIKELY(SourceSet.size() == 0 || *(SourceSet[0].strSource.c_str()) == '\0')) /* At least one source must be present. */
    796         return setError(E_INVALIDARG, tr("No source(s) specified"));
    797     if (RT_UNLIKELY((strDestination.c_str()) == NULL || *(strDestination.c_str()) == '\0'))
     795/** @todo r=bird: these validations are better left to the caller.  The first one in particular as there is only one
     796 * of the four callers which supplies a user specified source set, making an assertion more appropriate and efficient
     797 * here. */
     798    if (RT_UNLIKELY(SourceSet.size() == 0)) /* At least one source must be present. */
     799        return setError(E_INVALIDARG, tr("No sources specified"));
     800    if (RT_UNLIKELY(SourceSet[0].strSource.isEmpty()))
     801        return setError(E_INVALIDARG, tr("First source entry is empty"));
     802    if (RT_UNLIKELY(strDestination.isEmpty()))
    798803        return setError(E_INVALIDARG, tr("No destination specified"));
    799804
     
    30273032    GuestSessionFsSourceSet SourceSet;
    30283033
     3034    /** @todo r=bird: The GuestSessionFsSourceSpec constructor does not zero the
     3035     *        members you aren't setting here and there are no hints about "input"
     3036     *        vs "task" members, so you have me worrying about using random stack by
     3037     *        accident somewhere...  For instance Type.File.phFile sure sounds like
     3038     *        an input field and thus a disaster waiting to happen. */
    30293039    GuestSessionFsSourceSpec source;
    30303040    source.strSource            = aSource;
  • trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp

    r77531 r78666  
    208208                                                  COM_IIDOF(IGuestSession),
    209209                                                  GuestSession::getStaticComponentName(),
     210                                                  /** @todo r=bird: i_notifyComplete takes a format string, so this is
     211                                                   *        potentially risky business if a user input mentioned by the message
     212                                                   *        text contains '%s'!  With code below for how to do this less
     213                                                   *        painfully and with fewer string copies. */
    210214                                                  strMsg.c_str());
    211215        if (FAILED(hr2))
     
    213217    }
    214218    return hr; /* Return original rc. */
     219}
     220
     221HRESULT GuestSessionTask::setProgressErrorMsg(HRESULT hrc, int vrc, const char *pszFormat, ...)
     222{
     223    LogFlowFunc(("hrc=%Rhrc, vrc=%Rrc, pszFormat=%s\n", hrc, vrc, pszFormat));
     224
     225    /* The progress object is optional. */
     226    if (!mProgress.isNull())
     227    {
     228        BOOL fCanceled;
     229        BOOL fCompleted;
     230        if (   SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled)))
     231            && !fCanceled
     232            && SUCCEEDED(mProgress->COMGETTER(Completed(&fCompleted)))
     233            && !fCompleted)
     234        {
     235            va_list va;
     236            va_start(va, pszFormat);
     237            HRESULT hrc2 = mProgress->i_notifyCompleteBothV(hrc, vrc, COM_IIDOF(IGuestSession),
     238                                                            GuestSession::getStaticComponentName(), pszFormat, va);
     239            va_end(va);
     240            if (FAILED(hrc2))
     241                hrc = hrc2;
     242        }
     243    }
     244    return hrc;
    215245}
    216246
     
    763793    int rcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    764794    int rc = mSession->i_fsQueryInfo(strDest, TRUE /* fFollowSymlinks */, dstObjData, &rcGuest);
    765     if (RT_FAILURE(rc))
    766     {
    767         switch (rc)
    768         {
    769             case VERR_GSTCTL_GUEST_ERROR:
    770                 if (rcGuest == VERR_FILE_NOT_FOUND) /* File might not exist on the guest yet. */
    771                 {
    772                     rc = VINF_SUCCESS;
    773                 }
    774                 else
    775                    setProgressErrorMsg(VBOX_E_IPRT_ERROR, GuestFile::i_guestErrorToString(rcGuest));
    776                 break;
    777 
    778             default:
    779                 setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    780                                     Utf8StrFmt(GuestSession::tr("Destination file lookup for \"%s\" failed: %Rrc"),
    781                                                strDest.c_str(), rc));
    782                 break;
    783         }
     795    if (rc == VERR_GSTCTL_GUEST_ERROR && rcGuest == VERR_FILE_NOT_FOUND) /* File might not exist on the guest yet. */
     796        rc = VINF_SUCCESS;
     797    else if (RT_FAILURE(rc))
     798    {
     799        setProgressErrorMsg(VBOX_E_IPRT_ERROR, rc == VERR_GSTCTL_GUEST_ERROR ? rcGuest : rc,
     800                            GuestSession::tr("Destination file lookup for \"%s\" failed: %Rrc"),
     801                            strDest.c_str(), rc == VERR_GSTCTL_GUEST_ERROR ? rcGuest : rc);
     802        return rc;
    784803    }
    785804    else
     
    791810                /* Build the final file name with destination path (on the host). */
    792811                char szDstPath[RTPATH_MAX];
     812                /** @todo r=bird: WTF IS THIS SUPPOSED TO BE?!? Use RTStrCopy, memcpy, or similar!
     813                 * Ever thought about modifying strDestFinal (it's 'Dst' not 'Dest' btw.)
     814                 * directly?  There are any number of append and insert methods in the
     815                 * RTCString/Utf8Str class for doing that! */
    793816                RTStrPrintf2(szDstPath, sizeof(szDstPath), "%s", strDest.c_str());
    794817
     818                /** @todo r=bird: You're totally ignoring the guest slash-style here! Callers
     819                 *        should have this info. */
    795820                if (   !strDest.endsWith("\\")
    796821                    && !strDest.endsWith("/"))
     
    848873    if (RT_FAILURE(rc))
    849874    {
    850         switch (rc)
    851         {
    852             case VERR_GSTCTL_GUEST_ERROR:
    853                 setProgressErrorMsg(VBOX_E_IPRT_ERROR, GuestFile::i_guestErrorToString(rcGuest));
    854                 break;
    855 
    856             default:
    857                 setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    858                                     Utf8StrFmt(GuestSession::tr("Destination file \"%s\" could not be opened: %Rrc"),
    859                                                strDestFinal.c_str(), rc));
    860                 break;
    861         }
    862     }
    863 
    864     if (RT_FAILURE(rc))
     875        setProgressErrorMsg(VBOX_E_IPRT_ERROR, rc == VERR_GSTCTL_GUEST_ERROR ? rcGuest : rc,
     876                            GuestSession::tr("Destination file \"%s\" could not be opened: %Rrc"),
     877                            strDestFinal.c_str(), rc == VERR_GSTCTL_GUEST_ERROR ? rcGuest : rc);
    865878        return rc;
     879    }
    866880
    867881    char szSrcReal[RTPATH_MAX];
     
    13831397}
    13841398
    1385 GuestSessionTaskCopyFrom::GuestSessionTaskCopyFrom(GuestSession *pSession, GuestSessionFsSourceSet vecSrc, const Utf8Str &strDest)
    1386                                                    : GuestSessionCopyTask(pSession)
     1399GuestSessionTaskCopyFrom::GuestSessionTaskCopyFrom(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc,
     1400                                                   const Utf8Str &strDest)
     1401    : GuestSessionCopyTask(pSession)
    13871402{
    13881403    m_strTaskName = "gctlCpyFrm";
     
    16291644}
    16301645
    1631 GuestSessionTaskCopyTo::GuestSessionTaskCopyTo(GuestSession *pSession, GuestSessionFsSourceSet vecSrc, const Utf8Str &strDest)
    1632                                                : GuestSessionCopyTask(pSession)
     1646GuestSessionTaskCopyTo::GuestSessionTaskCopyTo(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc,
     1647                                               const Utf8Str &strDest)
     1648    : GuestSessionCopyTask(pSession)
    16331649{
    16341650    m_strTaskName = "gctlCpyTo";
     
    18011817        if (pList->mSourceSpec.enmType == FsObjType_Directory)
    18021818        {
    1803             fCopyIntoExisting = pList->mSourceSpec.Type.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting;
     1819            fCopyIntoExisting = RT_BOOL(pList->mSourceSpec.Type.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting);
    18041820            fFollowSymlinks   = pList->mSourceSpec.Type.Dir.fFollowSymlinks;
    18051821
     
    18141830        else if (pList->mSourceSpec.enmType == FsObjType_File)
    18151831        {
    1816             fCopyIntoExisting = !RT_BOOL(pList->mSourceSpec.Type.File.fCopyFlags & FileCopyFlag_NoReplace);
     1832            fCopyIntoExisting = !(pList->mSourceSpec.Type.File.fCopyFlags & FileCopyFlag_NoReplace);
    18171833            fFollowSymlinks   = RT_BOOL(pList->mSourceSpec.Type.File.fCopyFlags & FileCopyFlag_FollowLinks);
    18181834        }
     
    19371953
    19381954int GuestSessionTaskUpdateAdditions::copyFileToGuest(GuestSession *pSession, RTVFS hVfsIso,
    1939                                                 Utf8Str const &strFileSource, const Utf8Str &strFileDest,
    1940                                                 bool fOptional)
     1955                                                     Utf8Str const &strFileSource, const Utf8Str &strFileDest,
     1956                                                     bool fOptional)
    19411957{
    19421958    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
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