示例#1
0
int DnDHGSendFilePrivate::currentMessage(uint32_t uMsg, uint32_t cParms,
                                         VBOXHGCMSVCPARM paParms[])
{
    if (!m_pNextMsg)
        return VERR_NO_DATA;

    int rc = m_pNextMsg->getData(uMsg, cParms, paParms);
    clearNextMsg();
    if (RT_FAILURE(rc))
        return rc;

    uint32_t cbRead;
    if (RT_SUCCESS(rc))
    {
        /* Get buffer size + pointer to buffer from guest side. */
        uint32_t cbToRead = paParms[2].u.pointer.size; /* cbData */
        Assert(cbToRead);
        void *pvBuf = paParms[2].u.pointer.addr; /* pvData */
        AssertPtr(pvBuf);

        rc = m_URIObject.Read(pvBuf, cbToRead, &cbRead);
        LogFlowFunc(("Read %RU32 bytes (%RU32 bytes buffer) for \"%s\", rc=%Rrc\n",
                     cbRead, cbToRead, m_URIObject.GetDestPath().c_str(), rc));

        if (RT_LIKELY(RT_SUCCESS(rc)))
        {
            /* Tell the guest the actual size read. */
            paParms[3].setUInt32((uint32_t)cbRead); /* cbData */
        }
    }

    if (RT_SUCCESS(rc))
    {
        if (!m_URIObject.IsComplete())
        {
            try
            {
                /* More data needed to send over. Prepare the next message. */
                m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5 /* cParms */,
                                               m_aSkelParms);
            }
            catch(std::bad_alloc &)
            {
                rc = VERR_NO_MEMORY;
            }
        }

        /* Advance progress info. */
        if (   RT_SUCCESS(rc)
            && m_pfnProgressCallback)
        {
            rc = m_pfnProgressCallback(cbRead, m_pvProgressUser);
        }
    }

    return rc;
}
示例#2
0
int DnDHGSendFilePrivate::currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
    if (!m_pNextMsg)
        return VERR_NO_DATA;

    int rc = m_pNextMsg->getData(uMsg, cParms, paParms);
    clearNextMsg();
    if (RT_FAILURE(rc))
        return rc;

    if (!m_hCurFile)
    {
        rc = RTFileOpen(&m_hCurFile, m_strHostPath.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_ALL);
        if (RT_FAILURE(rc))
            return rc;
    }

    /* How big is the pointer provided by the guest? */
    uint32_t cbToRead = paParms[2].u.pointer.size;
    size_t cbRead;
    rc = RTFileRead(m_hCurFile, paParms[2].u.pointer.addr, cbToRead, &cbRead);
    if (RT_FAILURE(rc))
    {
        /* On error, immediately close the file. */
        RTFileClose(m_hCurFile);
        m_hCurFile = 0;
        return rc;
    }
    m_cbDone += cbRead;
    /* Tell the guest the actual size. */
    paParms[3].setUInt32(cbRead);
    /* Check if we are done. */
    if (m_cbSize == m_cbDone)
    {
        RTFileClose(m_hCurFile);
        m_hCurFile = 0;
    }
    else
    {
        /* More data! Prepare the next message. */
        m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5, m_paSkelParms);
    }

    /* Advance progress info */
    if (   RT_SUCCESS(rc)
        && m_pfnProgressCallback)
        rc = m_pfnProgressCallback(cbRead, m_pvProgressUser);

    return rc;
}