예제 #1
0
int DnDURIList::RootFromURIData(const void *pvData, size_t cbData, uint32_t fFlags)
{
    Assert(fFlags == 0); RT_NOREF1(fFlags);
    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    AssertReturn(cbData, VERR_INVALID_PARAMETER);

    if (!RTStrIsValidEncoding(static_cast<const char *>(pvData)))
        return VERR_INVALID_PARAMETER;

    RTCList<RTCString> lstURI =
        RTCString(static_cast<const char *>(pvData), cbData - 1).split("\r\n");
    if (lstURI.isEmpty())
        return VINF_SUCCESS;

    int rc = VINF_SUCCESS;

    for (size_t i = 0; i < lstURI.size(); ++i)
    {
        /* Query the path component of a file URI. If this hasn't a
         * file scheme, NULL is returned. */
        const char *pszURI = lstURI.at(i).c_str();
        char *pszFilePath = RTUriFilePath(pszURI);
#ifdef DEBUG_andy
        LogFlowFunc(("pszURI=%s, pszFilePath=%s\n", pszURI, pszFilePath));
#endif
        if (pszFilePath)
        {
            rc = DnDPathSanitize(pszFilePath, strlen(pszFilePath));
            if (RT_SUCCESS(rc))
            {
                m_lstRoot.append(pszFilePath);
                m_cTotal++;
            }

            RTStrFree(pszFilePath);
        }
        else
            rc = VERR_INVALID_PARAMETER;

        if (RT_FAILURE(rc))
            break;
    }

    return rc;
}
예제 #2
0
int GuestDnDResponse::onDispatch(uint32_t u32Function, void *pvParms, uint32_t cbParms)
{
    LogFlowFunc(("u32Function=%RU32, pvParms=%p, cbParms=%RU32\n", u32Function, pvParms, cbParms));

    int rc = VERR_WRONG_ORDER; /* Play safe. */
    bool fTryCallbacks = false;

    switch (u32Function)
    {
        case DragAndDropSvc::GUEST_DND_CONNECT:
        {
            LogThisFunc(("Client connected\n"));

            /* Nothing to do here (yet). */
            rc = VINF_SUCCESS;
            break;
        }

        case DragAndDropSvc::GUEST_DND_DISCONNECT:
        {
            LogThisFunc(("Client disconnected\n"));
            rc = setProgress(100, DND_PROGRESS_CANCELLED, VINF_SUCCESS);
            break;
        }

        case DragAndDropSvc::GUEST_DND_HG_ACK_OP:
        {
            DragAndDropSvc::PVBOXDNDCBHGACKOPDATA pCBData = reinterpret_cast<DragAndDropSvc::PVBOXDNDCBHGACKOPDATA>(pvParms);
            AssertPtr(pCBData);
            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGACKOPDATA) == cbParms, VERR_INVALID_PARAMETER);
            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_ACK_OP == pCBData->hdr.uMagic, VERR_INVALID_PARAMETER);

            setDefAction(pCBData->uAction);
            rc = notifyAboutGuestResponse();
            break;
        }

        case DragAndDropSvc::GUEST_DND_HG_REQ_DATA:
        {
            DragAndDropSvc::PVBOXDNDCBHGREQDATADATA pCBData = reinterpret_cast<DragAndDropSvc::PVBOXDNDCBHGREQDATADATA>(pvParms);
            AssertPtr(pCBData);
            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGREQDATADATA) == cbParms, VERR_INVALID_PARAMETER);
            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_REQ_DATA == pCBData->hdr.uMagic, VERR_INVALID_PARAMETER);

            if (   pCBData->cbFormat  == 0
                || pCBData->cbFormat  > _64K /** @todo Make this configurable? */
                || pCBData->pszFormat == NULL)
            {
                rc = VERR_INVALID_PARAMETER;
            }
            else if (!RTStrIsValidEncoding(pCBData->pszFormat))
            {
                rc = VERR_INVALID_PARAMETER;
            }
            else
            {
                setFormats(GuestDnD::toFormatList(pCBData->pszFormat));
                rc = VINF_SUCCESS;
            }

            int rc2 = notifyAboutGuestResponse();
            if (RT_SUCCESS(rc))
                rc = rc2;
            break;
        }

        case DragAndDropSvc::GUEST_DND_HG_EVT_PROGRESS:
        {
            DragAndDropSvc::PVBOXDNDCBHGEVTPROGRESSDATA pCBData =
               reinterpret_cast<DragAndDropSvc::PVBOXDNDCBHGEVTPROGRESSDATA>(pvParms);
            AssertPtr(pCBData);
            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGEVTPROGRESSDATA) == cbParms, VERR_INVALID_PARAMETER);
            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_EVT_PROGRESS == pCBData->hdr.uMagic, VERR_INVALID_PARAMETER);

            rc = setProgress(pCBData->uPercentage, pCBData->uStatus, pCBData->rc);
            if (RT_SUCCESS(rc))
                rc = notifyAboutGuestResponse();
            break;
        }
#ifdef VBOX_WITH_DRAG_AND_DROP_GH
        case DragAndDropSvc::GUEST_DND_GH_ACK_PENDING:
        {
            DragAndDropSvc::PVBOXDNDCBGHACKPENDINGDATA pCBData =
               reinterpret_cast<DragAndDropSvc::PVBOXDNDCBGHACKPENDINGDATA>(pvParms);
            AssertPtr(pCBData);
            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBGHACKPENDINGDATA) == cbParms, VERR_INVALID_PARAMETER);
            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_ACK_PENDING == pCBData->hdr.uMagic, VERR_INVALID_PARAMETER);

            if (   pCBData->cbFormat  == 0
                || pCBData->cbFormat  > _64K /** @todo Make the maximum size configurable? */
                || pCBData->pszFormat == NULL)
            {
                rc = VERR_INVALID_PARAMETER;
            }
            else if (!RTStrIsValidEncoding(pCBData->pszFormat))
            {
                rc = VERR_INVALID_PARAMETER;
            }
            else
            {
                setFormats   (GuestDnD::toFormatList(pCBData->pszFormat));
                setDefAction (pCBData->uDefAction);
                setAllActions(pCBData->uAllActions);

                rc = VINF_SUCCESS;
            }

            int rc2 = notifyAboutGuestResponse();
            if (RT_SUCCESS(rc))
                rc = rc2;
            break;
        }
#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
        default:
            /* * Try if the event is covered by a registered callback. */
            fTryCallbacks = true;
            break;
    }

    /*
     * Try the host's installed callbacks (if any).
     */
    if (fTryCallbacks)
    {
        GuestDnDCallbackMap::const_iterator it = m_mapCallbacks.find(u32Function);
        if (it != m_mapCallbacks.end())
        {
            AssertPtr(it->second.pfnCallback);
            rc = it->second.pfnCallback(u32Function, pvParms, cbParms, it->second.pvUser);
        }
        else
        {
            LogFlowFunc(("No callback for function %RU32 defined (%zu callbacks total)\n", u32Function, m_mapCallbacks.size()));
            rc = VERR_NOT_SUPPORTED; /* Tell the guest. */
        }
    }

    LogFlowFunc(("Returning rc=%Rrc\n", rc));
    return rc;
}
예제 #3
0
/**
 * Runs a process, collecting the standard output and/or standard error.
 *
 *
 * @returns IPRT status code
 * @retval  VERR_NO_TRANSLATION if the output of the program isn't valid UTF-8
 *          or contains a nul character.
 * @retval  VERR_TOO_MUCH_DATA if the process produced too much data.
 *
 * @param   pszExec     Executable image to use to create the child process.
 * @param   papszArgs   Pointer to an array of arguments to the child.  The
 *                      array terminated by an entry containing NULL.
 * @param   hEnv        Handle to the environment block for the child.
 * @param   fFlags      A combination of RTPROCEXEC_FLAGS_XXX.  The @a
 *                      ppszStdOut and @a ppszStdErr parameters takes precedence
 *                      over redirection flags.
 * @param   pStatus     Where to return the status on success.
 * @param   ppszStdOut  Where to return the text written to standard output. If
 *                      NULL then standard output will not be collected and go
 *                      to the standard output handle of the process.
 *                      Free with RTStrFree, regardless of return status.
 * @param   ppszStdErr  Where to return the text written to standard error. If
 *                      NULL then standard output will not be collected and go
 *                      to the standard error handle of the process.
 *                      Free with RTStrFree, regardless of return status.
 */
int RTProcExecToString(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags,
                       PRTPROCSTATUS pStatus, char **ppszStdOut, char **ppszStdErr)
{
    int rc2;

    /*
     * Clear output arguments (no returning failure here, simply crash!).
     */
    AssertPtr(pStatus);
    pStatus->enmReason = RTPROCEXITREASON_ABEND;
    pStatus->iStatus   = RTEXITCODE_FAILURE;
    AssertPtrNull(ppszStdOut);
    if (ppszStdOut)
        *ppszStdOut = NULL;
    AssertPtrNull(ppszStdOut);
    if (ppszStdErr)
        *ppszStdErr = NULL;

    /*
     * Check input arguments.
     */
    AssertReturn(!(fFlags & ~RTPROCEXEC_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);

    /*
     * Do we need a standard input bitbucket?
     */
    int         rc = VINF_SUCCESS;
    PRTHANDLE   phChildStdIn = NULL;
    RTHANDLE    hChildStdIn;
    hChildStdIn.enmType = RTHANDLETYPE_FILE;
    hChildStdIn.u.hFile = NIL_RTFILE;
    if ((fFlags & RTPROCEXEC_FLAGS_STDIN_NULL) && RT_SUCCESS(rc))
    {
        phChildStdIn = &hChildStdIn;
        rc = RTFileOpenBitBucket(&hChildStdIn.u.hFile, RTFILE_O_READ);
    }

    /*
     * Create the output pipes / bitbuckets.
     */
    RTPIPE      hPipeStdOutR  = NIL_RTPIPE;
    PRTHANDLE   phChildStdOut = NULL;
    RTHANDLE    hChildStdOut;
    hChildStdOut.enmType = RTHANDLETYPE_PIPE;
    hChildStdOut.u.hPipe = NIL_RTPIPE;
    if (ppszStdOut && RT_SUCCESS(rc))
    {
        phChildStdOut = &hChildStdOut;
        rc = RTPipeCreate(&hPipeStdOutR, &hChildStdOut.u.hPipe, 0 /*fFlags*/);
    }
    else if ((fFlags & RTPROCEXEC_FLAGS_STDOUT_NULL) && RT_SUCCESS(rc))
    {
        phChildStdOut = &hChildStdOut;
        hChildStdOut.enmType = RTHANDLETYPE_FILE;
        hChildStdOut.u.hFile = NIL_RTFILE;
        rc = RTFileOpenBitBucket(&hChildStdOut.u.hFile, RTFILE_O_WRITE);
    }

    RTPIPE      hPipeStdErrR  = NIL_RTPIPE;
    PRTHANDLE   phChildStdErr = NULL;
    RTHANDLE    hChildStdErr;
    hChildStdErr.enmType = RTHANDLETYPE_PIPE;
    hChildStdErr.u.hPipe = NIL_RTPIPE;
    if (ppszStdErr && RT_SUCCESS(rc))
    {
        phChildStdErr = &hChildStdErr;
        rc = RTPipeCreate(&hPipeStdErrR, &hChildStdErr.u.hPipe, 0 /*fFlags*/);
    }
    else if ((fFlags & RTPROCEXEC_FLAGS_STDERR_NULL) && RT_SUCCESS(rc))
    {
        phChildStdErr = &hChildStdErr;
        hChildStdErr.enmType = RTHANDLETYPE_FILE;
        hChildStdErr.u.hFile = NIL_RTFILE;
        rc = RTFileOpenBitBucket(&hChildStdErr.u.hFile, RTFILE_O_WRITE);
    }

    if (RT_SUCCESS(rc))
    {
        RTPOLLSET hPollSet;
        rc = RTPollSetCreate(&hPollSet);
        if (RT_SUCCESS(rc))
        {
            if (hPipeStdOutR != NIL_RTPIPE && RT_SUCCESS(rc))
                rc = RTPollSetAddPipe(hPollSet, hPipeStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 1);
            if (hPipeStdErrR != NIL_RTPIPE)
                rc = RTPollSetAddPipe(hPollSet, hPipeStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 2);
        }
        if (RT_SUCCESS(rc))
        {
            /*
             * Create the process.
             */
            RTPROCESS hProc;
            rc = RTProcCreateEx(g_szSvnPath,
                                papszArgs,
                                RTENV_DEFAULT,
                                0 /*fFlags*/,
                                NULL /*phStdIn*/,
                                phChildStdOut,
                                phChildStdErr,
                                NULL /*pszAsUser*/,
                                NULL /*pszPassword*/,
                                &hProc);
            rc2 = RTHandleClose(&hChildStdErr); AssertRC(rc2);
            rc2 = RTHandleClose(&hChildStdOut); AssertRC(rc2);

            if (RT_SUCCESS(rc))
            {
                /*
                 * Process output and wait for the process to finish.
                 */
                size_t cbStdOut  = 0;
                size_t offStdOut = 0;
                size_t cbStdErr  = 0;
                size_t offStdErr = 0;
                for (;;)
                {
                    if (hPipeStdOutR != NIL_RTPIPE)
                        rc = rtProcProcessOutput(rc, &hPipeStdOutR, &cbStdOut, &offStdOut, ppszStdOut, hPollSet, 1);
                    if (hPipeStdErrR != NIL_RTPIPE)
                        rc = rtProcProcessOutput(rc, &hPipeStdErrR, &cbStdErr, &offStdErr, ppszStdErr, hPollSet, 2);
                    if (hPipeStdOutR == NIL_RTPIPE && hPipeStdErrR == NIL_RTPIPE)
                        break;

                    if (hProc != NIL_RTPROCESS)
                    {
                        rc2 = RTProcWait(hProc, RTPROCWAIT_FLAGS_NOBLOCK, pStatus);
                        if (rc2 != VERR_PROCESS_RUNNING)
                        {
                            if (RT_FAILURE(rc2))
                                rc = rc2;
                            hProc = NIL_RTPROCESS;
                        }
                    }

                    rc2 = RTPoll(hPollSet, 10000, NULL, NULL);
                    Assert(RT_SUCCESS(rc2) || rc2 == VERR_TIMEOUT);
                }

                if (RT_SUCCESS(rc))
                {
                    if (   (ppszStdOut && *ppszStdOut && !RTStrIsValidEncoding(*ppszStdOut))
                        || (ppszStdErr && *ppszStdErr && !RTStrIsValidEncoding(*ppszStdErr)) )
                        rc = VERR_NO_TRANSLATION;
                }

                /*
                 * No more output, just wait for it to finish.
                 */
                if (hProc != NIL_RTPROCESS)
                {
                    rc2 = RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, pStatus);
                    if (RT_FAILURE(rc2))
                        rc = rc2;
                }
            }
            RTPollSetDestroy(hPollSet);
        }
    }

    rc2 = RTHandleClose(&hChildStdErr); AssertRC(rc2);
    rc2 = RTHandleClose(&hChildStdOut); AssertRC(rc2);
    rc2 = RTHandleClose(&hChildStdIn);  AssertRC(rc2);
    rc2 = RTPipeClose(hPipeStdErrR);    AssertRC(rc2);
    rc2 = RTPipeClose(hPipeStdOutR);    AssertRC(rc2);
    return rc;
}