VirtualBox

Ignore:
Timestamp:
Aug 10, 2011 11:48:29 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73430
Message:

GuestCtrl: Update.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/GuestCtrlImplDir.cpp

    r38290 r38395  
    138138 *
    139139 * @return IPRT status code.
    140  * @param puHandle             Pointer where the handle gets stored to.
     140 * @param puHandle             Pointer where the handle gets stored to. Optional.
    141141 * @param uPID                 PID of guest process running the associated "vbox_ls".
    142  * @param pszDirectory         Directory the handle is assigned to.
    143  * @param pszFilter            Directory filter.  Optional.
     142 * @param aDirectory           Directory the handle is assigned to.
     143 * @param aFilter              Directory filter.  Optional.
    144144 * @param uFlags               Directory open flags.
    145145 *
    146146 */
    147147int Guest::directoryCreateHandle(ULONG *puHandle, ULONG uPID,
    148                                  const char *pszDirectory, const char *pszFilter, ULONG uFlags)
    149 {
    150     AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
    151     AssertPtrReturn(pszDirectory, VERR_INVALID_POINTER);
    152     /* pszFilter is optional. */
     148                                 IN_BSTR aDirectory, IN_BSTR aFilter, ULONG uFlags)
     149{
     150    AssertReturn(uPID, VERR_INVALID_PARAMETER);
     151    CheckComArgStrNotEmptyOrNull(aDirectory);
     152    /* aFilter is optional. */
     153    /* uFlags are optional. */
    153154
    154155    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    160161        uint32_t uHandleTry = ASMAtomicIncU32(&mNextDirectoryID);
    161162        GuestDirectoryMapIter it = mGuestDirectoryMap.find(uHandleTry);
    162         if (it == mGuestDirectoryMap.end())
    163         {
     163        if (it == mGuestDirectoryMap.end()) /* We found a free slot ... */
     164        {
     165            mGuestDirectoryMap[uHandleTry].mDirectory = aDirectory;
     166            mGuestDirectoryMap[uHandleTry].mFilter = aFilter;
     167            mGuestDirectoryMap[uHandleTry].mPID = uPID;
     168            mGuestDirectoryMap[uHandleTry].mFlags = uFlags;
     169            Assert(mGuestDirectoryMap.size());
     170
    164171            rc = VINF_SUCCESS;
    165             if (!RTStrAPrintf(&mGuestDirectoryMap[uHandleTry].mpszDirectory, pszDirectory))
    166                 rc = VERR_NO_MEMORY;
    167             else
    168             {
    169                 /* Filter is optional. */
    170                 if (pszFilter)
    171                 {
    172                     if (!RTStrAPrintf(&mGuestDirectoryMap[uHandleTry].mpszFilter, pszFilter))
    173                         rc = VERR_NO_MEMORY;
    174                 }
    175 
    176                 if (RT_SUCCESS(rc))
    177                 {
    178                     mGuestDirectoryMap[uHandleTry].mPID = uPID;
    179                     mGuestDirectoryMap[uHandleTry].mFlags = uFlags;
    180                     *puHandle = uHandleTry;
    181 
    182                     break;
    183                 }
    184             }
    185 
    186             if (RT_FAILURE(rc))
    187                 break;
    188 
    189             Assert(mGuestDirectoryMap.size());
     172
     173            if (puHandle)
     174                *puHandle = uHandleTry;
     175            break;
    190176        }
    191177    }
     
    208194    if (it != mGuestDirectoryMap.end())
    209195    {
    210         RTStrFree(it->second.mpszDirectory);
    211         RTStrFree(it->second.mpszFilter);
    212 
    213196        /* Destroy raw guest stream buffer - not used
    214197         * anymore. */
     
    220203}
    221204
     205STDMETHODIMP Guest::DirectoryExists(IN_BSTR aDirectory, IN_BSTR aUsername, IN_BSTR aPassword, BOOL *aExists)
     206{
     207#ifndef VBOX_WITH_GUEST_CONTROL
     208    ReturnComNotImplemented();
     209#else /* VBOX_WITH_GUEST_CONTROL */
     210    using namespace guestControl;
     211
     212    CheckComArgStrNotEmptyOrNull(aDirectory);
     213
     214    /* Do not allow anonymous executions (with system rights). */
     215    if (RT_UNLIKELY((aUsername) == NULL || *(aUsername) == '\0'))
     216        return setError(E_INVALIDARG, tr("No user name specified"));
     217
     218    return directoryExistsInternal(aDirectory,
     219                                   aUsername, aPassword, aExists);
     220#endif
     221}
     222
     223#ifdef VBOX_WITH_GUEST_CONTROL
     224HRESULT Guest::directoryExistsInternal(IN_BSTR aDirectory, IN_BSTR aUsername, IN_BSTR aPassword, BOOL *aExists)
     225{
     226    using namespace guestControl;
     227
     228    CheckComArgStrNotEmptyOrNull(aDirectory);
     229
     230    AutoCaller autoCaller(this);
     231    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     232
     233    RTFSOBJINFO objInfo;
     234    int rc;
     235    HRESULT hr = directoryQueryInfoInternal(aDirectory,
     236                                            aUsername, aPassword,
     237                                            &objInfo, RTFSOBJATTRADD_NOTHING, &rc);
     238    if (SUCCEEDED(hr))
     239    {
     240        switch (rc)
     241        {
     242            case VINF_SUCCESS:
     243                *aExists = TRUE;
     244                break;
     245
     246            case VERR_FILE_NOT_FOUND:
     247                *aExists = FALSE;
     248                break;
     249
     250            case VERR_NOT_FOUND:
     251                rc = setError(VBOX_E_IPRT_ERROR,
     252                              Guest::tr("Unable to query directory existence"));
     253                break;
     254
     255            default:
     256                AssertReleaseMsgFailed(("directoryExistsInternal: Unknown return value (%Rrc)\n", rc));
     257                break;
     258        }
     259    }
     260    return hr;
     261}
     262#endif
     263
    222264/**
    223265 * Gets the associated PID from a directory handle.
    224266 *
    225  * @return  uint32_t            Associated PID, 0 if handle not found/invalid.
    226  * @param   uHandle             Directory handle to get PID for.
     267 * @return  uint32_t                Associated PID, 0 if handle not found/invalid.
     268 * @param   uHandle                 Directory handle to get PID for.
    227269 */
    228270uint32_t Guest::directoryGetPID(uint32_t uHandle)
     
    237279}
    238280
     281/**
     282 * Returns the next directory entry of an open guest directory.
     283 * Returns VERR_NO_MORE_FILES if no more entries available.
     284 *
     285 * @return  IPRT status code.
     286 * @param   uHandle                 Directory handle to get entry for.
     287 * @param   streamBlock             Reference that receives the next stream block data.
     288 */
    239289int Guest::directoryGetNextEntry(uint32_t uHandle, GuestProcessStreamBlock &streamBlock)
    240290{
    241     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     291    // LOCK DOES NOT WORK HERE!?
     292    //AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    242293
    243294    GuestDirectoryMapIter it = mGuestDirectoryMap.find(uHandle);
    244295    if (it != mGuestDirectoryMap.end())
    245296    {
    246         HRESULT hr = executeStreamCollectBlock(it->second.mPID,
    247                                                it->second.mStream, streamBlock);
    248         if (FAILED(hr))
    249             return VERR_INVALID_PARAMETER; /** @todo Find better rc! */
    250 
    251         return VINF_SUCCESS;
     297        return executeStreamGetNextBlock(it->second.mPID,
     298                                         it->second.mStream, streamBlock);
    252299    }
    253300
     
    259306 * or not.
    260307 *
    261  * @return  bool                True if handle exists, false if not.
    262  * @param   uHandle             Directory handle to check.
     308 * @return  bool                    True if handle exists, false if not.
     309 * @param   uHandle                 Directory handle to check.
    263310 */
    264311bool Guest::directoryHandleExists(uint32_t uHandle)
     
    315362        return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags);
    316363
    317     HRESULT rc = S_OK;
     364    HRESULT hr = S_OK;
    318365    try
    319366    {
     
    354401
    355402        ULONG uPID;
    356         rc = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_LS).raw(), Bstr("Opening directory").raw(),
     403        /** @todo Don't wait for tool to finish! Might take a lot of time! */
     404        hr = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_LS).raw(), Bstr("Opening directory").raw(),
    357405                                   ComSafeArrayAsInParam(args),
    358406                                   ComSafeArrayAsInParam(env),
    359407                                   aUsername, aPassword,
    360408                                   NULL /* Progress */, &uPID);
    361         if (SUCCEEDED(rc))
     409        if (SUCCEEDED(hr))
    362410        {
    363411            /* Assign new directory handle ID. */
    364             int vrc = directoryCreateHandle(aHandle, uPID,
    365                                             Utf8Directory.c_str(),
    366                                             Utf8Filter.isEmpty() ? NULL : Utf8Filter.c_str(),
    367                                             aFlags);
    368             if (RT_FAILURE(vrc))
    369                 rc = setError(VBOX_E_IPRT_ERROR,
     412            ULONG uHandleNew;
     413            int vrc = directoryCreateHandle(&uHandleNew, uPID,
     414                                            aDirectory, aFilter, aFlags);
     415            if (RT_SUCCESS(vrc))
     416            {
     417                *aHandle = uHandleNew;
     418            }
     419            else
     420                hr = setError(VBOX_E_IPRT_ERROR,
    370421                              tr("Unable to create guest directory handle (%Rrc)"), vrc);
    371422        }
     
    373424    catch (std::bad_alloc &)
    374425    {
    375         rc = E_OUTOFMEMORY;
    376     }
    377     return rc;
     426        hr = E_OUTOFMEMORY;
     427    }
     428    return hr;
     429}
     430
     431HRESULT Guest::directoryQueryInfoInternal(IN_BSTR aDirectory,
     432                                          IN_BSTR aUsername, IN_BSTR aPassword,
     433                                          PRTFSOBJINFO aObjInfo, RTFSOBJATTRADD enmAddAttribs,
     434                                          int *pRC)
     435{
     436    using namespace guestControl;
     437
     438    /** @todo Search directory cache first? */
     439
     440    CheckComArgStrNotEmptyOrNull(aDirectory);
     441    /* aUsername is optional. */
     442    /* aPassword is optional. */
     443    /* aObjInfo is optional. */
     444
     445    AutoCaller autoCaller(this);
     446    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     447
     448    HRESULT hr = S_OK;
     449    try
     450    {
     451        Utf8Str Utf8Dir(aDirectory);
     452        Utf8Str Utf8Username(aUsername);
     453        Utf8Str Utf8Password(aPassword);
     454
     455        com::SafeArray<IN_BSTR> args;
     456        com::SafeArray<IN_BSTR> env;
     457
     458        /*
     459         * Prepare tool command line.
     460         */
     461
     462        /* We need to get output which is machine-readable in form
     463         * of "key=value\0..key=value\0\0". */
     464        args.push_back(Bstr("--machinereadable").raw());
     465
     466        /* Only the actual file name to chekc is needed for now. */
     467        args.push_back(Bstr(Utf8Dir).raw());
     468
     469        /*
     470         * Execute guest process.
     471         */
     472        ULONG uPID;
     473        hr = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_STAT).raw(), Bstr("Querying directory information").raw(),
     474                                   ComSafeArrayAsInParam(args),
     475                                   ComSafeArrayAsInParam(env),
     476                                   aUsername, aPassword,
     477                                   NULL /* Progress */, &uPID);
     478        if (SUCCEEDED(hr))
     479        {
     480            GuestCtrlStreamObjects streamObjs;
     481            hr = executeStreamParse(uPID, streamObjs);
     482            if (SUCCEEDED(hr))
     483            {
     484                int rc = VINF_SUCCESS;
     485
     486                GuestProcessStreamBlock *pBlock = streamObjs[0];
     487                AssertPtr(pBlock);
     488                const char *pszFsType = pBlock->GetString("ftype");
     489                if (!pszFsType) /* Attribute missing? */
     490                     rc = VERR_NOT_FOUND;
     491                if (   RT_SUCCESS(rc)
     492                    && strcmp(pszFsType, "d")) /* Directory? */
     493                {
     494                     rc = VERR_FILE_NOT_FOUND;
     495                }
     496                if (   RT_SUCCESS(rc)
     497                    && aObjInfo) /* Do we want object details? */
     498                {
     499                    hr = executeStreamQueryFsObjInfo(aDirectory, pBlock,
     500                                                     aObjInfo, enmAddAttribs);
     501                }
     502
     503                executeStreamFree(streamObjs);
     504
     505                if (pRC)
     506                    *pRC = rc;
     507            }
     508        }
     509    }
     510    catch (std::bad_alloc &)
     511    {
     512        hr = E_OUTOFMEMORY;
     513    }
     514    return hr;
    378515}
    379516#endif /* VBOX_WITH_GUEST_CONTROL */
     
    391528    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    392529
    393     HRESULT rc = S_OK;
     530    HRESULT hr = S_OK;
    394531    try
    395532    {
    396533        GuestProcessStreamBlock streamBlock;
    397         int vrc = directoryGetNextEntry(aHandle, streamBlock);
    398         if (RT_SUCCESS(vrc))
     534        int rc = directoryGetNextEntry(aHandle, streamBlock);
     535        if (RT_SUCCESS(rc))
    399536        {
    400537            ComObjPtr <GuestDirEntry> pDirEntry;
    401             rc = pDirEntry.createObject();
    402             ComAssertComRC(rc);
    403 
    404             rc = pDirEntry->init(this, streamBlock);
    405             if (SUCCEEDED(rc))
     538            hr = pDirEntry.createObject();
     539            ComAssertComRC(hr);
     540
     541            hr = pDirEntry->init(this, streamBlock);
     542            if (SUCCEEDED(hr))
    406543            {
    407544                pDirEntry.queryInterfaceTo(aDirEntry);
    408545            }
    409546            else
    410                 rc = setError(VBOX_E_IPRT_ERROR,
     547                hr = setError(VBOX_E_IPRT_ERROR,
    411548                              Guest::tr("Unable to init guest directory entry"));
    412549        }
     550        else if (rc == VERR_NO_MORE_FILES)
     551        {
     552            /* No more directory entries to read. */
     553            hr = E_ABORT; /** @todo Find/define a better rc! */
     554        }
    413555        else
    414             rc = setError(VBOX_E_IPRT_ERROR,
    415                           Guest::tr("Directory handle is invalid"));
     556            hr = setError(VBOX_E_IPRT_ERROR,
     557                          Guest::tr("Failed getting next directory entry (%Rrc)"), rc);
    416558    }
    417559    catch (std::bad_alloc &)
    418560    {
    419         rc = E_OUTOFMEMORY;
    420     }
    421     return rc;
    422 #endif
    423 }
    424 
     561        hr = E_OUTOFMEMORY;
     562    }
     563    return hr;
     564#endif
     565}
     566
Note: See TracChangeset for help on using the changeset viewer.

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