VirtualBox

Changeset 42611 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 6, 2012 8:42:23 AM (12 years ago)
Author:
vboxsync
Message:

Guest Control 2.0: Update.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r42569 r42611  
    1026510265  <interface
    1026610266    name="IFile" extends="$unknown"
    10267     uuid="2615152d-35c0-4363-8325-ab7e1f2b8b34"
     10267    uuid="b3484293-b98b-4952-ae23-f18eca6a5ff9"
    1026810268    wsmap="managed"
    1026910269    >
     
    1027110271      TODO
    1027210272    </desc>
    10273    
     10273    <attribute name="creationMode" type="unsigned long" readonly="yes">
     10274      <desc>
     10275        TODO
     10276        <note>
     10277          TODO
     10278        </note>
     10279      </desc>
     10280    </attribute>
     10281    <attribute name="disposition" type="unsigned long" readonly="yes">
     10282      <desc>
     10283        TODO
     10284        <note>
     10285          TODO
     10286        </note>
     10287      </desc>
     10288    </attribute>
    1027410289    <attribute name="fileName" type="wstring" readonly="yes">
    1027510290      <desc>
  • trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h

    r42530 r42611  
    305305 * starting parameters around.
    306306 */
    307 struct GuestProcessInfo
    308 {
     307struct GuestProcessStartupInfo
     308{
     309    GuestProcessStartupInfo(void)
     310        : mFlags(ProcessCreateFlag_None),
     311          mPriority(ProcessPriority_Default),
     312          mTimeoutMS(30 * 1000 /* 30s timeout by default */) { }
     313
    309314    /** The process' friendly name. */
    310315    Utf8Str                     mName;
     
    317322    ProcessPriority_T           mPriority;
    318323    ProcessAffinity             mAffinity;
    319 
    320324};
    321325
  • trunk/src/VBox/Main/include/GuestFileImpl.h

    r42095 r42611  
    2424#include "GuestFsObjInfoImpl.h"
    2525
     26class GuestSession;
     27class GuestProcess;
     28
    2629/**
    2730 * TODO
     
    4346    DECLARE_EMPTY_CTOR_DTOR(GuestFile)
    4447
    45     HRESULT init(void);
     48    int     init(GuestSession *pSession, const Utf8Str &strPath, const Utf8Str &strOpenMode, const Utf8Str &strDisposition, uint32_t uCreationMode, int64_t iOffset);
    4649    void    uninit(void);
    4750    HRESULT FinalConstruct(void);
     
    4952    /** @}  */
    5053
    51     /** @name IDirectory interface.
     54    /** @name IFile interface.
    5255     * @{ */
     56    STDMETHOD(COMGETTER(CreationMode))(ULONG *aCreationMode);
     57    STDMETHOD(COMGETTER(Disposition))(ULONG *aDisposition);
    5358    STDMETHOD(COMGETTER(FileName))(BSTR *aFileName);
    5459    STDMETHOD(COMGETTER(InitialSize))(LONG64 *aInitialSize);
     
    5762
    5863    STDMETHOD(Close)(void);
    59     STDMETHOD(QueryInfo)(IGuestFsObjInfo **aInfo);
     64    STDMETHOD(QueryInfo)(IFsObjInfo **aInfo);
    6065    STDMETHOD(Read)(ULONG aToRead, ULONG *aRead, ComSafeArrayOut(BYTE, aData));
    6166    STDMETHOD(ReadAt)(LONG64 aOffset, ULONG aToRead, ULONG *aRead, ComSafeArrayOut(BYTE, aData));
     
    6671    /** @}  */
    6772
     73public:
     74    /** @name Public internal methods.
     75     * @{ */
     76    static uint32_t getDispositionFromString(const Utf8Str &strDisposition);
     77    static uint32_t getOpenModeFromString(const Utf8Str &strOpenMode);
     78    /** @}  */
     79
    6880private:
    6981
    7082    struct Data
    7183    {
    72         Utf8Str              mFileName;
    73         LONG64               mInitialSize;
    74         ULONG                mOpenMode;
    75         LONG64               mOffset;
     84        /** The associate session this file belongs to. */
     85        ComObjPtr<GuestSession> mSession;
     86        /** The process object this file is bound to. */
     87        ComObjPtr<GuestProcess> mProcess;
     88        uint32_t                mCreationMode;
     89        uint32_t                mDisposition;
     90        Utf8Str                 mFileName;
     91        int64_t                 mInitialSize;
     92        uint32_t                mOpenMode;
     93        int64_t                 mOffset;
    7694    } mData;
    7795};
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r42551 r42611  
    4545    DECLARE_EMPTY_CTOR_DTOR(GuestProcess)
    4646
    47     int     init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessInfo &aProcInfo);
     47    int     init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessStartupInfo &aProcInfo);
    4848    void    uninit(void);
    4949    HRESULT FinalConstruct(void);
     
    117117        GuestCtrlCallbacks       mCallbacks;
    118118        /** The process start information. */
    119         GuestProcessInfo         mProcess;
     119        GuestProcessStartupInfo  mProcess;
    120120        /** Exit code if process has been terminated. */
    121121        LONG                     mExitCode;
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r42566 r42611  
    205205    int                     dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData);
    206206    int                     fileClose(ComObjPtr<GuestFile> pFile);
     207    int                     fileOpenInternal(const Utf8Str &strPath, const Utf8Str &strOpenMode, const Utf8Str &strDisposition,
     208                                             uint32_t uCreationMode, int64_t iOffset, ComObjPtr<GuestFile> &pFile);
    207209    int                     fileQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData);
    208210    int                     fileQuerySizeInternal(const Utf8Str &strPath, int64_t *pllSize);
     
    212214    uint32_t                getProtocolVersion(void) { return mData.mProtocolVersion; }
    213215    int                     processClose(ComObjPtr<GuestProcess> pProcess);
    214     int                     processCreateExInteral(GuestProcessInfo &procInfo, ComObjPtr<GuestProcess> &pProgress);
     216    int                     processCreateExInteral(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProgress);
    215217    inline bool             processExists(uint32_t uProcessID, ComObjPtr<GuestProcess> *pProcess);
    216218    inline int              processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess);
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r42566 r42611  
    707707                 VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pHeader->u32ContextID)));
    708708#endif
    709     int rc = pGuest->dispatchToSession(pHeader->u32ContextID, u32Function, pvParms, cbParms);
     709
     710    bool fDispatch = true;
     711#ifdef DEBUG
     712    /*
     713     * Pre-check: If we got a status message with an error and VERR_TOO_MUCH_DATA
     714     *            it means that that guest could not handle the entire message
     715     *            because of its exceeding size. This should not happen on daily
     716     *            use but testcases might try this. It then makes no sense to dispatch
     717     *            this further because we don't have a valid context ID.
     718     */
     719    if (u32Function == GUEST_EXEC_SEND_STATUS)
     720    {
     721        PCALLBACKDATAEXECSTATUS pCallbackData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvParms);
     722        AssertPtr(pCallbackData);
     723        AssertReturn(sizeof(CALLBACKDATAEXECSTATUS) == cbParms, VERR_INVALID_PARAMETER);
     724        AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER);
     725
     726        if (   pCallbackData->u32Status == PROC_STS_ERROR
     727            && pCallbackData->u32Flags  == VERR_TOO_MUCH_DATA)
     728        {
     729            LogFlowFunc(("Requested command with too much data, skipping dispatching ...\n"));
     730
     731            Assert(pCallbackData->u32PID == 0);
     732            fDispatch = false;
     733        }
     734    }
     735#endif
     736    int rc = VINF_SUCCESS;
     737    if (fDispatch)
     738        rc = pGuest->dispatchToSession(pHeader->u32ContextID, u32Function, pvParms, cbParms);
    710739
    711740#ifdef VBOX_WITH_GUEST_CONTROL_LEGACY
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r42530 r42611  
    4747int GuestCtrlEvent::Cancel(void)
    4848{
    49     LogFlowThisFuncEnter();
    50 
    5149    int rc = VINF_SUCCESS;
    5250    if (!ASMAtomicReadBool(&fCompleted))
     
    5654            ASMAtomicXchgBool(&fCanceled, true);
    5755
    58             LogFlowThisFunc(("Cancelling ...\n"));
     56            LogFlowThisFunc(("Cancelling event ...\n"));
    5957            rc = hEventSem != NIL_RTSEMEVENT
    6058               ? RTSemEventSignal(hEventSem) : VINF_SUCCESS;
     
    6260    }
    6361
    64     LogFlowFuncLeaveRC(rc);
    6562    return rc;
    6663}
  • trunk/src/VBox/Main/src-client/GuestFileImpl.cpp

    r42478 r42611  
    2222*******************************************************************************/
    2323#include "GuestFileImpl.h"
     24#include "GuestSessionImpl.h"
    2425#include "GuestCtrlImplPrivate.h"
    2526
     
    5253/////////////////////////////////////////////////////////////////////////////
    5354
    54 HRESULT GuestFile::init(void)
     55int GuestFile::init(GuestSession *pSession, const Utf8Str &strPath,
     56                    const Utf8Str &strOpenMode, const Utf8Str &strDisposition, uint32_t uCreationMode,
     57                    int64_t iOffset)
    5558{
    5659    /* Enclose the state transition NotReady->InInit->Ready. */
     
    5861    AssertReturn(autoInitSpan.isOk(), E_FAIL);
    5962
     63    mData.mSession = pSession;
     64    mData.mCreationMode = uCreationMode;
     65    mData.mDisposition = getDispositionFromString(strDisposition);
     66    mData.mFileName = strPath;
     67    mData.mInitialSize = 0;
     68    mData.mOpenMode = getOpenModeFromString(strOpenMode);
     69    mData.mOffset = iOffset;
     70
     71    /** @todo Validate parameters! */
     72
    6073    /* Confirm a successful initialization when it's the case. */
    6174    autoInitSpan.setSucceeded();
    6275
    63     return S_OK;
     76    return VINF_SUCCESS;
    6477}
    6578
     
    7689    if (autoUninitSpan.uninitDone())
    7790        return;
     91
     92    mData.mSession->fileClose(this);
    7893}
    7994
     
    8196/////////////////////////////////////////////////////////////////////////////
    8297
     98STDMETHODIMP GuestFile::COMGETTER(CreationMode)(ULONG *aCreationMode)
     99{
     100#ifndef VBOX_WITH_GUEST_CONTROL
     101    ReturnComNotImplemented();
     102#else
     103    AutoCaller autoCaller(this);
     104    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     105
     106    CheckComArgOutPointerValid(aCreationMode);
     107
     108    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     109
     110    *aCreationMode = mData.mCreationMode;
     111
     112    return S_OK;
     113#endif /* VBOX_WITH_GUEST_CONTROL */
     114}
     115
     116STDMETHODIMP GuestFile::COMGETTER(Disposition)(ULONG *aDisposition)
     117{
     118#ifndef VBOX_WITH_GUEST_CONTROL
     119    ReturnComNotImplemented();
     120#else
     121    AutoCaller autoCaller(this);
     122    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     123
     124    CheckComArgOutPointerValid(aDisposition);
     125
     126    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     127
     128    *aDisposition = mData.mDisposition;
     129
     130    return S_OK;
     131#endif /* VBOX_WITH_GUEST_CONTROL */
     132}
     133
    83134STDMETHODIMP GuestFile::COMGETTER(FileName)(BSTR *aFileName)
    84135{
     
    89140    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    90141
    91     ReturnComNotImplemented();
     142    CheckComArgOutPointerValid(aFileName);
     143
     144    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     145
     146    mData.mFileName.cloneTo(aFileName);
     147
     148    return S_OK;
    92149#endif /* VBOX_WITH_GUEST_CONTROL */
    93150}
     
    101158    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    102159
    103     ReturnComNotImplemented();
     160    CheckComArgOutPointerValid(aInitialSize);
     161
     162    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     163
     164    *aInitialSize = mData.mInitialSize;
     165
     166    return S_OK;
    104167#endif /* VBOX_WITH_GUEST_CONTROL */
    105168}
     
    113176    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    114177
    115     ReturnComNotImplemented();
     178    CheckComArgOutPointerValid(aOffset);
     179
     180    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     181
     182    *aOffset = mData.mOffset;
     183
     184    return S_OK;
    116185#endif /* VBOX_WITH_GUEST_CONTROL */
    117186}
     
    125194    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    126195
    127     ReturnComNotImplemented();
    128 #endif /* VBOX_WITH_GUEST_CONTROL */
     196    CheckComArgOutPointerValid(aOpenMode);
     197
     198    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     199
     200    *aOpenMode = mData.mOpenMode;
     201
     202    return S_OK;
     203#endif /* VBOX_WITH_GUEST_CONTROL */
     204}
     205
     206// private methods
     207/////////////////////////////////////////////////////////////////////////////
     208
     209/* static */
     210uint32_t GuestFile::getDispositionFromString(const Utf8Str &strDisposition)
     211{
     212    return 0; /** @todo Implement me! */
     213}
     214
     215/* static */
     216uint32_t GuestFile::getOpenModeFromString(const Utf8Str &strOpenMode)
     217{
     218    return 0; /** @todo Implement me! */
    129219}
    130220
     
    144234}
    145235
    146 STDMETHODIMP GuestFile::QueryInfo(IGuestFsObjInfo **aInfo)
     236STDMETHODIMP GuestFile::QueryInfo(IFsObjInfo **aInfo)
    147237{
    148238#ifndef VBOX_WITH_GUEST_CONTROL
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r42551 r42611  
    104104/////////////////////////////////////////////////////////////////////////////
    105105
    106 int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessInfo &aProcInfo)
     106int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessStartupInfo &aProcInfo)
    107107{
    108108    LogFlowThisFunc(("aConsole=%p, aSession=%p, aProcessID=%RU32\n",
     
    178178    collection.detachTo(ComSafeArrayOutArg(aArguments));
    179179
    180     LogFlowFuncLeaveRC(S_OK);
    181180    return S_OK;
    182181#endif /* VBOX_WITH_GUEST_CONTROL */
     
    205204    arguments.detachTo(ComSafeArrayOutArg(aEnvironment));
    206205
    207     LogFlowFuncLeaveRC(S_OK);
    208206    return S_OK;
    209207#endif /* VBOX_WITH_GUEST_CONTROL */
     
    226224    mData.mProcess.mCommand.cloneTo(aExecutablePath);
    227225
    228     LogFlowFuncLeaveRC(S_OK);
    229226    return S_OK;
    230227#endif /* VBOX_WITH_GUEST_CONTROL */
     
    247244    *aExitCode = mData.mExitCode;
    248245
    249     LogFlowFuncLeaveRC(S_OK);
    250246    return S_OK;
    251247#endif /* VBOX_WITH_GUEST_CONTROL */
     
    268264    mData.mProcess.mName.cloneTo(aName);
    269265
    270     LogFlowFuncLeaveRC(S_OK);
    271266    return S_OK;
    272267#endif /* VBOX_WITH_GUEST_CONTROL */
     
    289284    *aPID = mData.mPID;
    290285
    291     LogFlowFuncLeaveRC(S_OK);
    292286    return S_OK;
    293287#endif /* VBOX_WITH_GUEST_CONTROL */
     
    308302    *aStatus = mData.mStatus;
    309303
    310     LogFlowFuncLeaveRC(S_OK);
    311304    return S_OK;
    312305#endif /* VBOX_WITH_GUEST_CONTROL */
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r42573 r42611  
    143143    int rc;
    144144
    145     /** @todo Make use of exception (+ finally block) here! */
     145    /** @todo Make use of exceptions (+ finally block) here! */
    146146
    147147    try
     
    152152            rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    153153                                     Utf8StrFmt(GuestSession::tr("Source file \"%s\" does not exist or is not a file"),
    154                                      mSource.c_str()));
     154                                                mSource.c_str()));
    155155        }
    156156        else
     
    163163                rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    164164                                         Utf8StrFmt(GuestSession::tr("Could not open source file \"%s\" for reading (%Rrc)"),
    165                                          mSource.c_str(), rc));
     165                                                    mSource.c_str(), rc));
    166166            }
    167167            else
     
    172172                {
    173173                    setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    174                                         Utf8StrFmt(GuestSession::tr("Could not query file size of \"%s\" (%Rrc)"),
    175                                         mSource.c_str(), rc));
     174                                        Utf8StrFmt(GuestSession::tr("Could not query file size of \"%s\": %Rrc"),
     175                                                   mSource.c_str(), rc));
    176176                }
    177177                else
    178178                {
    179                     GuestProcessInfo procInfo;
     179                    GuestProcessStartupInfo procInfo;
    180180                    procInfo.mName    = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to the guest to \"%s\" (%RU64 bytes)"),
    181                                                                     mSource.c_str(), mDest.c_str(), cbFileSize);
     181                                                   mSource.c_str(), mDest.c_str(), cbFileSize);
    182182                    procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_CAT);
    183183                    procInfo.mFlags   = ProcessCreateFlag_None;
     
    190190                    int rc = pSession->processCreateExInteral(procInfo, pProcess);
    191191                    if (RT_SUCCESS(rc))
     192                        rc = pProcess->startProcess();
     193                    if (RT_FAILURE(rc))
     194                    {
     195                        setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     196                                            Utf8StrFmt(GuestSession::tr("Unable to start guest process: %Rrc"), rc));
     197                    }
     198                    else
    192199                    {
    193200                        GuestProcessWaitResult waitRes;
     
    227234                                        setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    228235                                                            Utf8StrFmt(GuestSession::tr("Could not read from file \"%s\" (%Rrc)"),
    229                                                             mSource.c_str(), rc));
     236                                                                       mSource.c_str(), rc));
    230237                                        break;
    231238                                    }
     
    235242                                    setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    236243                                                        Utf8StrFmt(GuestSession::tr("Seeking file \"%s\" offset %RU64 failed: %Rrc"),
    237                                                         mSource.c_str(), cbWrittenTotal, rc));
     244                                                                   mSource.c_str(), cbWrittenTotal, rc));
    238245                                    break;
    239246                                }
     
    262269                                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    263270                                                    Utf8StrFmt(GuestSession::tr("Writing to file \"%s\" (offset %RU64) failed: %Rrc"),
    264                                                     mSource.c_str(), cbWrittenTotal, rc));
     271                                                               mSource.c_str(), cbWrittenTotal, rc));
    265272                                break;
    266273                            }
    267274
    268                             /* Safety first. */
    269                             Assert(cbRead <= cbToRead);
    270                             Assert(cbToRead >= cbRead);
    271 
    272275                            /* Only subtract bytes reported written by the guest. */
     276                            Assert(cbToRead >= cbWritten);
    273277                            cbToRead -= cbWritten;
    274278
     
    282286
    283287                            /* Update the progress. */
     288                            Assert(!mProgress.isNull());
    284289                            HRESULT hr = mProgress->SetCurrentOperationProgress((ULONG)(cbWrittenTotal * 100 / cbFileSize));
    285290                            if (FAILED(hr))
    286291                            {
    287292                                rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    288                                                          Utf8StrFmt(GuestSession::tr("Error updating the progress of copying files \"%s\" to \"%s\""),
    289                                                          mSource.c_str(), mDest.c_str()));
     293                                                         Utf8StrFmt(GuestSession::tr("Error updating the progress of copying file \"%s\" to \"%s\""),
     294                                                                    mSource.c_str(), mDest.c_str()));
    290295                                break;
    291296                            }
     
    310315                                rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    311316                                                         Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""),
    312                                                          mSource.c_str(), mDest.c_str()));
     317                                                                    mSource.c_str(), mDest.c_str()));
    313318                            }
    314319                            else if (cbWrittenTotal < cbFileSize)
     
    317322                                rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    318323                                                         Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed (%RU64/%RU64 bytes transfered)"),
    319                                                          mSource.c_str(), cbWrittenTotal, cbFileSize));
     324                                                                    mSource.c_str(), cbWrittenTotal, cbFileSize));
    320325                            }
    321                             else /* Yay, all went fine! */
    322                                 rc = setProgressSuccess();
     326                            else
     327                            {
     328                                ProcessStatus_T procStatus;
     329                                LONG exitCode;
     330                                if (   (   SUCCEEDED(pProcess->COMGETTER(Status(&procStatus)))
     331                                        && procStatus != ProcessStatus_TerminatedNormally)
     332                                    || (   SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode)))
     333                                        && exitCode != 0)
     334                                   )
     335                                {
     336                                    rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     337                                                             Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed with status %ld, exit code %d"),
     338                                                                        mSource.c_str(), procStatus, exitCode)); /**@todo Add stringify methods! */
     339                                }
     340                                else /* Yay, success! */
     341                                    rc = setProgressSuccess();
     342                            }
    323343                        }
     344
     345                        pSession->processClose(pProcess);
    324346                    } /* processCreateExInteral */
    325347                } /* RTFileGetSize */
     
    379401int SessionTaskCopyFrom::Run(void)
    380402{
    381     return 0;
     403    LogFlowThisFuncEnter();
     404
     405    ComObjPtr<GuestSession> pSession = mSession;
     406    Assert(!pSession.isNull());
     407
     408    AutoCaller autoCaller(pSession);
     409    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     410
     411    int rc;
     412
     413    /** @todo Make use of exceptions (+ finally block) here! */
     414
     415    try
     416    {
     417        /*
     418         * Note: There will be races between querying file size + reading the guest file's
     419         *       content because we currently *do not* lock down the guest file when doing the
     420         *       actual operations.
     421         ** @todo Implement guest file locking!
     422         */
     423        GuestFsObjData objData;
     424        rc = pSession->fileQueryInfoInternal(Utf8Str(mSource), objData);
     425        if (RT_FAILURE(rc))
     426        {
     427            setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     428                                Utf8StrFmt(GuestSession::tr("Querying guest file information for \"%s\" failed: %Rrc"),
     429                                mSource.c_str(), rc));
     430        }
     431        else if (objData.mType != FsObjType_File) /* Only single files are supported at the moment. */
     432        {
     433            rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     434                                     Utf8StrFmt(GuestSession::tr("Guest file \"%s\" is not a file"), mSource.c_str()));
     435        }
     436
     437        if (RT_SUCCESS(rc))
     438        {
     439            RTFILE fileDest;
     440            rc = RTFileOpen(&fileDest, mDest.c_str(),
     441                            RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE); /** @todo Use the correct open modes! */
     442            if (RT_FAILURE(rc))
     443            {
     444                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     445                                    Utf8StrFmt(GuestSession::tr("Error opening destination file \"%s\": %Rrc"),
     446                                               mDest.c_str(), rc));
     447            }
     448            else
     449            {
     450                GuestProcessStartupInfo procInfo;
     451                procInfo.mName    = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to the host to \"%s\" (%RI64 bytes)"),
     452                                                                mSource.c_str(), mDest.c_str(), objData.mObjectSize);
     453                procInfo.mCommand   = Utf8Str(VBOXSERVICE_TOOL_CAT);
     454                procInfo.mFlags     = ProcessCreateFlag_WaitForStdOut;
     455
     456                /* Set arguments.*/
     457                procInfo.mArguments.push_back(mSource); /* Which file to output? */
     458
     459                /* Startup process. */
     460                ComObjPtr<GuestProcess> pProcess;
     461                int rc = pSession->processCreateExInteral(procInfo, pProcess);
     462                if (RT_SUCCESS(rc))
     463                    rc = pProcess->startProcess();
     464                if (RT_FAILURE(rc))
     465                {
     466                    setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     467                                        Utf8StrFmt(GuestSession::tr("Unable to start guest process: %Rrc"), rc));
     468                }
     469                else
     470                {
     471                    GuestProcessWaitResult waitRes;
     472                    BYTE byBuf[_64K];
     473
     474                    BOOL fCanceled = FALSE;
     475                    uint64_t cbWrittenTotal = 0;
     476                    uint64_t cbToRead = objData.mObjectSize;
     477
     478                    for (;;)
     479                    {
     480                        rc = pProcess->waitFor(ProcessWaitForFlag_StdOut,
     481                                               30 * 1000 /* Timeout */, waitRes);
     482                        if (   RT_FAILURE(rc)
     483                            || waitRes.mResult != ProcessWaitResult_StdOut)
     484                        {
     485                            break;
     486                        }
     487
     488                        size_t cbRead;
     489                        rc = pProcess->readData(OUTPUT_HANDLE_ID_STDOUT, sizeof(byBuf),
     490                                                30 * 1000 /* Timeout */, byBuf, sizeof(byBuf),
     491                                                &cbRead);
     492                        if (RT_FAILURE(rc))
     493                        {
     494                            setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     495                                                Utf8StrFmt(GuestSession::tr("Reading from file \"%s\" (offset %RU64) failed: %Rrc"),
     496                                                mSource.c_str(), cbWrittenTotal, rc));
     497                            break;
     498                        }
     499
     500                        if (cbRead)
     501                        {
     502                            rc = RTFileWrite(fileDest, byBuf, cbRead, NULL /* No partial writes */);
     503                            if (RT_FAILURE(rc))
     504                            {
     505                                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     506                                                    Utf8StrFmt(GuestSession::tr("Error writing to file \"%s\" (%RU64 bytes left): %Rrc"),
     507                                                    mDest.c_str(), cbToRead, rc));
     508                                break;
     509                            }
     510
     511                            /* Only subtract bytes reported written by the guest. */
     512                            Assert(cbToRead >= cbRead);
     513                            cbToRead -= cbRead;
     514
     515                            /* Update total bytes written to the guest. */
     516                            cbWrittenTotal += cbRead;
     517                            Assert(cbWrittenTotal <= (uint64_t)objData.mObjectSize);
     518
     519                            /* Did the user cancel the operation above? */
     520                            if (   SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled)))
     521                                && fCanceled)
     522                                break;
     523
     524                            Assert(!mProgress.isNull());
     525                            HRESULT hr = mProgress->SetCurrentOperationProgress(cbWrittenTotal / ((uint64_t)objData.mObjectSize / 100.0));
     526                            if (FAILED(hr))
     527                            {
     528                                rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     529                                                         Utf8StrFmt(GuestSession::tr("Error updating the progress of copying file \"%s\" to \"%s\""),
     530                                                         mSource.c_str(), mDest.c_str()));
     531                                break;
     532                            }
     533
     534                            /* End of file reached? */
     535                            if (cbToRead == 0)
     536                                break;
     537                        }
     538                    } /* for */
     539
     540                    if (   !fCanceled
     541                        || RT_SUCCESS(rc))
     542                    {
     543                        /*
     544                         * Even if we succeeded until here make sure to check whether we really transfered
     545                         * everything.
     546                         */
     547                        if (   objData.mObjectSize > 0
     548                            && cbWrittenTotal == 0)
     549                        {
     550                            /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write
     551                             * to the destination -> access denied. */
     552                            rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     553                                                     Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""),
     554                                                     mSource.c_str(), mDest.c_str()));
     555                        }
     556                        else if (cbWrittenTotal < (uint64_t)objData.mObjectSize)
     557                        {
     558                            /* If we did not copy all let the user know. */
     559                            rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     560                                                     Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed (%RU64/%RU64 bytes transfered)"),
     561                                                     mSource.c_str(), cbWrittenTotal, objData.mObjectSize));
     562                        }
     563                        else
     564                        {
     565                            ProcessStatus_T procStatus;
     566                            LONG exitCode;
     567                            if (   (   SUCCEEDED(pProcess->COMGETTER(Status(&procStatus)))
     568                                    && procStatus != ProcessStatus_TerminatedNormally)
     569                                || (   SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode)))
     570                                    && exitCode != 0)
     571                               )
     572                            {
     573                                rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     574                                                         Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed with status %ld, exit code %d"),
     575                                                                    mSource.c_str(), procStatus, exitCode)); /**@todo Add stringify methods! */
     576                            }
     577                            else /* Yay, success! */
     578                                rc = setProgressSuccess();
     579                        }
     580                    }
     581
     582                    pSession->processClose(pProcess);
     583                }
     584
     585                RTFileClose(fileDest);
     586            }
     587        }
     588    }
     589    catch (int rc2)
     590    {
     591        rc = rc2;
     592    }
     593
     594    LogFlowFuncLeaveRC(rc);
     595    return rc;
    382596}
    383597
     
    764978                     strPath.c_str(), uMode, uFlags));
    765979
    766     GuestProcessInfo procInfo;
    767     procInfo.mName    = Utf8StrFmt(tr("Creating directory \"%s\"", strPath.c_str()));
    768     procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_MKDIR);
     980    GuestProcessStartupInfo procInfo;
     981    procInfo.mName      = Utf8StrFmt(tr("Creating directory \"%s\"", strPath.c_str()));
     982    procInfo.mCommand   = Utf8Str(VBOXSERVICE_TOOL_MKDIR);
    769983
    770984    int rc = VINF_SUCCESS;
     
    7891003    ComObjPtr<GuestProcess> pProcess;
    7901004    rc = processCreateExInteral(procInfo, pProcess);
     1005    if (RT_SUCCESS(rc))
     1006        rc = pProcess->startProcess();
    7911007    if (RT_SUCCESS(rc))
    7921008    {
     
    8151031    try
    8161032    {
     1033        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1034
    8171035        /* Create the directory object. */
    8181036        HRESULT hr = pDirectory.createObject();
     
    8271045        mData.mDirectories.push_back(pDirectory);
    8281046
    829         LogFlowFunc(("Added new directory (Session: %RU32) with process ID=%RU32\n",
    830                      mData.mId, mData.mNextProcessID));
     1047        LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n",
     1048                     strPath.c_str(), mData.mId));
    8311049    }
    8321050    catch (int rc2)
     
    8851103}
    8861104
     1105int GuestSession::fileOpenInternal(const Utf8Str &strPath, const Utf8Str &strOpenMode, const Utf8Str &strDisposition,
     1106                                   uint32_t uCreationMode, int64_t iOffset, ComObjPtr<GuestFile> &pFile)
     1107{
     1108    LogFlowThisFunc(("strPath=%s, strOpenMode=%s, strDisposition=%s, uCreationMode=%x, iOffset=%RI64\n",
     1109                     strPath.c_str(), strOpenMode.c_str(), strDisposition.c_str(), uCreationMode, iOffset));
     1110    int rc;
     1111
     1112    try
     1113    {
     1114        /* Create the directory object. */
     1115        HRESULT hr = pFile.createObject();
     1116        if (FAILED(hr)) throw VERR_COM_UNEXPECTED;
     1117
     1118        /* Note: There will be a race between creating and getting/initing the directory
     1119                 object here. */
     1120        rc = pFile->init(this /* Parent */,
     1121                         strPath, strOpenMode, strDisposition, uCreationMode, iOffset);
     1122        if (RT_FAILURE(rc)) throw rc;
     1123
     1124        /* Add the created directory to our vector. */
     1125        mData.mFiles.push_back(pFile);
     1126
     1127        LogFlowFunc(("Added new file \"%s\" (Session: %RU32\n",
     1128                     strPath.c_str(), mData.mId));
     1129    }
     1130    catch (int rc2)
     1131    {
     1132        rc = rc2;
     1133    }
     1134
     1135    LogFlowFuncLeaveRC(rc);
     1136    return rc;
     1137}
     1138
    8871139/* Note: Will work on directories and others, too. */
    8881140int GuestSession::fileQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData)
     
    8901142    LogFlowThisFunc(("strPath=%s\n", strPath.c_str()));
    8911143
    892     GuestProcessInfo procInfo;
    893     procInfo.mName    = Utf8StrFmt(tr("Querying info for \"%s\"", strPath.c_str()));
     1144    GuestProcessStartupInfo procInfo;
     1145    procInfo.mName    = Utf8StrFmt(tr("Querying info for \"%s\""), strPath.c_str());
    8941146    procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_STAT);
    8951147    procInfo.mFlags   = ProcessCreateFlag_WaitForStdOut;
     
    9041156    int rc = processCreateExInteral(procInfo, pProcess);
    9051157    if (RT_SUCCESS(rc))
     1158        rc = pProcess->startProcess();
     1159    if (RT_SUCCESS(rc))
    9061160    {
    9071161        GuestProcessWaitResult waitRes;
    9081162        BYTE byBuf[_64K];
    909         size_t cbRead;
     1163        size_t cbRead = 0;
    9101164
    9111165        for (;;)
     
    9141168                                   30 * 1000 /* Timeout */, waitRes);
    9151169            if (   RT_FAILURE(rc)
    916                 || waitRes.mResult != ProcessWaitResult_StdOut)
     1170                || waitRes.mResult == ProcessWaitResult_Terminate
     1171                || waitRes.mResult == ProcessWaitResult_Error
     1172                || waitRes.mResult == ProcessWaitResult_Timeout)
    9171173            {
    9181174                break;
     
    9251181                break;
    9261182
    927             rc = streamOut.AddData(byBuf, cbRead);
    928             if (RT_FAILURE(rc))
    929                 break;
    930         }
    931 
    932         LogFlowThisFunc(("rc=%Rrc, cbRead=%RU32, cbStreamOut=%RU32\n",
     1183            if (cbRead)
     1184            {
     1185                rc = streamOut.AddData(byBuf, cbRead);
     1186                if (RT_FAILURE(rc))
     1187                    break;
     1188            }
     1189        }
     1190
     1191        LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64, cbStreamOut=%RU32\n",
    9331192                         rc, cbRead, streamOut.GetSize()));
    9341193    }
     
    9991258}
    10001259
    1001 int GuestSession::processCreateExInteral(GuestProcessInfo &procInfo, ComObjPtr<GuestProcess> &pProcess)
     1260/**
     1261 * Creates but does *not* start the process yet. See GuestProcess::startProcess() or
     1262 * GuestProcess::startProcessAsync() for that.
     1263 *
     1264 * @return  IPRT status code.
     1265 * @param   procInfo
     1266 * @param   pProcess
     1267 */
     1268int GuestSession::processCreateExInteral(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProcess)
    10021269{
    10031270    LogFlowFunc(("mCmd=%s, mFlags=%x, mTimeoutMS=%RU32\n",
    10041271                 procInfo.mCommand.c_str(), procInfo.mFlags, procInfo.mTimeoutMS));
     1272#ifdef DEBUG
     1273    if (procInfo.mArguments.size())
     1274    {
     1275        LogFlowFunc(("Arguments:"));
     1276        ProcessArguments::const_iterator it = procInfo.mArguments.begin();
     1277        while (it != procInfo.mArguments.end())
     1278        {
     1279            LogFlow((" %s", (*it).c_str()));
     1280            it++;
     1281        }
     1282        LogFlow(("\n"));
     1283    }
     1284#endif
    10051285
    10061286    /* Validate flags. */
     
    13231603            fFlags |= flags[i];
    13241604
    1325         if (!(fFlags & DirectoryCreateFlag_Parents))
    1326             return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), fFlags);
     1605        if (fFlags)
     1606        {
     1607            if (!(fFlags & DirectoryCreateFlag_Parents))
     1608                return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), fFlags);
     1609        }
    13271610    }
    13281611
     
    13301613
    13311614    ComObjPtr <GuestDirectory> pDirectory;
    1332     int rc = directoryCreateInternal(Utf8Str(aPath), (uint32_t)aMode, (uint32_t)aFlags, pDirectory);
     1615    int rc = directoryCreateInternal(Utf8Str(aPath), (uint32_t)aMode, fFlags, pDirectory);
    13331616    if (RT_SUCCESS(rc))
    13341617    {
     
    16521935    LogFlowThisFuncEnter();
    16531936
    1654     AutoCaller autoCaller(this);
    1655     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    1656 
    1657     ReturnComNotImplemented();
     1937    if (RT_UNLIKELY((aPath) == NULL || *(aPath) == '\0'))
     1938        return setError(E_INVALIDARG, tr("No file to open specified"));
     1939    if (RT_UNLIKELY((aOpenMode) == NULL || *(aOpenMode) == '\0'))
     1940        return setError(E_INVALIDARG, tr("No open mode specified"));
     1941    if (RT_UNLIKELY((aDisposition) == NULL || *(aDisposition) == '\0'))
     1942        return setError(E_INVALIDARG, tr("No disposition mode specified"));
     1943
     1944    CheckComArgOutPointerValid(aFile);
     1945
     1946    AutoCaller autoCaller(this);
     1947    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     1948
     1949    /** @todo Validate open mode. */
     1950    /** @todo Validate disposition mode. */
     1951
     1952    /** @todo Validate creation mode. */
     1953    uint32_t uCreationMode = 0;
     1954
     1955    HRESULT hr = S_OK;
     1956
     1957    ComObjPtr <GuestFile> pFile;
     1958    int rc = fileOpenInternal(Utf8Str(aPath), Utf8Str(aOpenMode), Utf8Str(aDisposition),
     1959                              aCreationMode, aOffset, pFile);
     1960    if (RT_SUCCESS(rc))
     1961    {
     1962        /* Return directory object to the caller. */
     1963        hr = pFile.queryInterfaceTo(aFile);
     1964    }
     1965    else
     1966    {
     1967        switch (rc)
     1968        {
     1969            /** @todo Add more error info! */
     1970
     1971            default:
     1972               hr = setError(VBOX_E_IPRT_ERROR, tr("Directory creation failed: %Rrc"), rc);
     1973               break;
     1974        }
     1975    }
     1976
     1977    return hr;
    16581978#endif /* VBOX_WITH_GUEST_CONTROL */
    16591979}
     
    17862106    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    17872107
    1788     GuestProcessInfo procInfo;
    1789 
     2108    GuestProcessStartupInfo procInfo;
    17902109    procInfo.mCommand = Utf8Str(aCommand);
    1791     procInfo.mFlags = ProcessCreateFlag_None;
    17922110
    17932111    if (aArguments)
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