Exemplo n.º 1
0
int DnDManager::nextMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
    if (!m_pCurMsg)
    {
        /* Check for pending messages in our queue. */
        if (m_dndMessageQueue.isEmpty())
            return VERR_NO_DATA;
        m_pCurMsg = m_dndMessageQueue.first();
        m_dndMessageQueue.removeFirst();
    }

    /* Fetch the current message info */
    int rc = m_pCurMsg->currentMessage(uMsg, cParms, paParms);
    /* If this message not provide any additional sub messages, clear it. */
    if (!m_pCurMsg->isMessageWaiting())
    {
        delete m_pCurMsg;
        m_pCurMsg = 0;
    }

    /* If the user has canceled the operation, we need to cleanup all pending
     * events and inform the progress callback about our successful cleanup. */
    if (   rc == VERR_CANCELLED
        && m_pfnProgressCallback)
    {
        /* Clear any pending messages */
        clear();
        /* Create a new cancel message to inform the guest. */
        m_pCurMsg = new DnDHGCancelMessage();
        m_pfnProgressCallback(100.0, DragAndDropSvc::DND_PROGRESS_CANCELLED, m_pvProgressUser);
    }

    DO(("next msg: %d %d %Rrc\n", uMsg, cParms, rc));
    return rc;
}
Exemplo n.º 2
0
int DnDManager::nextMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
    LogFlowFunc(("uMsg=%RU32, cParms=%RU32\n", uMsg, cParms));

    if (!m_pCurMsg)
    {
        /* Check for pending messages in our queue. */
        if (m_dndMessageQueue.isEmpty())
        {
            LogFlowFunc(("Message queue is empty, returning\n"));
            return VERR_NO_DATA;
        }

        m_pCurMsg = m_dndMessageQueue.first();
        m_dndMessageQueue.removeFirst();
    }

    /* Fetch the current message info */
    int rc = m_pCurMsg->currentMessage(uMsg, cParms, paParms);
    /* If this message doesn't provide any additional sub messages, clear it. */
    if (!m_pCurMsg->isMessageWaiting())
    {
        delete m_pCurMsg;
        m_pCurMsg = NULL;
    }

    /*
     * If there was an error handling the current message or the user has canceled
     * the operation, we need to cleanup all pending events and inform the progress
     * callback about our exit.
     */
    if (   RT_FAILURE(rc)
        && m_pfnProgressCallback)
    {
        /* Clear any pending messages. */
        clear();

        /* Create a new cancel message to inform the guest + call
         * the host whether the current transfer was canceled or aborted
         * due to an error. */
        try
        {
            Assert(!m_pCurMsg);
            m_pCurMsg = new DnDHGCancelMessage();
            m_pfnProgressCallback(100 /* Percent */,
                                    rc == VERR_CANCELLED
                                  ? DragAndDropSvc::DND_PROGRESS_CANCELLED
                                  : DragAndDropSvc::DND_PROGRESS_ERROR, rc, m_pvProgressUser);
        }
        catch(std::bad_alloc &)
        {
            rc = VERR_NO_MEMORY;
        }
    }

    LogFlowFunc(("Message processed with rc=%Rrc\n", rc));
    return rc;
}
Exemplo n.º 3
0
    int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    {
        int rc = DnDMessage::currentMessage(uMsg, cParms, paParms);
        /* Advance progress info */
        if (   RT_SUCCESS(rc)
            && m_pfnProgressCallback)
            rc = m_pfnProgressCallback(m_URIObject.GetSize(), m_pvProgressUser);

        return rc;
    }
Exemplo n.º 4
0
STDMETHODIMP CDataCallback::BandedDataCallback(
    LONG   lReason,
    LONG   lStatus,
    LONG   lPercentComplete,
    LONG   lOffset,
    LONG   lLength,
    LONG, LONG,
    PBYTE  pbBuffer
)
{
    HRESULT hr;

    // Parse the message

    switch (lReason)
    {
        case IT_MSG_DATA_HEADER:
        {
            PWIA_DATA_CALLBACK_HEADER pHeader = (PWIA_DATA_CALLBACK_HEADER) pbBuffer;

            // Determine if this is a BMP transfer

            m_bBMP = pHeader->guidFormatID == WiaImgFmt_MEMORYBMP || pHeader->guidFormatID == WiaImgFmt_BMP;

            // For WiaImgFmt_MEMORYBMP transfers, WIA does not send a BITMAPFILEHEADER before the data.
            // In this program, we desire all BMP files to contain a BITMAPFILEHEADER, so add it manually

            m_nHeaderSize = pHeader->guidFormatID == WiaImgFmt_MEMORYBMP ? sizeof(BITMAPFILEHEADER) : 0;

            // Allocate memory for the image if the size is given in the header

            if (pHeader != NULL && pHeader->lBufferSize != 0)
            {
                hr = ReAllocBuffer(m_nHeaderSize + pHeader->lBufferSize);

                if (FAILED(hr))
                {
                    return hr;
                }
            }
        
            break;
        }

        case IT_MSG_DATA:
        {
            // Invoke the callback function

            hr = m_pfnProgressCallback(lStatus, lPercentComplete, m_pProgressCallbackParam);

            if (FAILED(hr) || hr == S_FALSE)
            {
                return hr;
            }

            // If the buffer is not allocated yet and this is the first block, 
            // and the transferred image is in BMP format, allocate the buffer
            // according to the size information in the bitmap header

            if (m_pStream == NULL && lOffset == 0 && m_bBMP)
            {
                LONG nBufferSize = BitmapUtil::GetBitmapSize(pbBuffer);

                if (nBufferSize != 0)
                {
                    hr = ReAllocBuffer(m_nHeaderSize + nBufferSize);

                    if (FAILED(hr))
                    {
                        return hr;
                    }
                }
            }

            if (m_nHeaderSize + lOffset + lLength < 0)
            {
                return E_OUTOFMEMORY;
            }

            // If the transfer goes past the buffer, try to expand it
            if (m_nHeaderSize + lOffset + lLength > m_nDataSize)
            {
                hr = ReAllocBuffer(m_nHeaderSize + lOffset + lLength);

                if (FAILED(hr))
                {
                    return hr;
                }
            }

            // copy the transfer buffer

            hr = CopyToBuffer(m_nHeaderSize + lOffset, pbBuffer, lLength);

            if (FAILED(hr))
            {
                return hr;
            }

            break;
        }

        case IT_MSG_STATUS:
        {
            // Invoke the callback function

            hr = m_pfnProgressCallback(lStatus, lPercentComplete, m_pProgressCallbackParam);

            if (FAILED(hr) || hr == S_FALSE)
            {
                return hr;
            }

            break;
        }

        case IT_MSG_TERMINATION:
        case IT_MSG_NEW_PAGE:
        {
            if (m_pStream != NULL)
            {
                // For BMP files, we should validate the the image header
                // So, obtain the memory buffer from the stream

                if (m_bBMP)
                {
                    // Since the stream is created using CreateStreamOnHGlobal,
                    // we can get the memory buffer with GetHGlobalFromStream.

                    HGLOBAL hBuffer;

                    hr = GetHGlobalFromStream(m_pStream, &hBuffer);

                    if (FAILED(hr))
                    {
                        return hr;
                    }

                    PBITMAPFILEHEADER pBuffer = (PBITMAPFILEHEADER) GlobalLock(hBuffer);

                    if (pBuffer == NULL)
                    {
                        return HRESULT_FROM_WIN32(GetLastError());
                    }

                    // Some scroll-fed scanners may return 0 as the bitmap height
                    // In this case, calculate the image height and modify the header

                    BitmapUtil::FixBitmapHeight(pBuffer + 1, m_nDataSize, TRUE);

                    // For WiaImgFmt_MEMORYBMP transfers, the WIA service does not 
                    // include a BITMAPFILEHEADER preceeding the bitmap data. 
                    // In this case, fill in the BITMAPFILEHEADER structure.
        
                    if (m_nHeaderSize != 0)
                    {
                        BitmapUtil::FillBitmapFileHeader(pBuffer + 1, pBuffer);
                    }

                    GlobalUnlock(hBuffer);
                }

                // Store this buffer in the successfully transferred images array

                hr = StoreBuffer();

                if (FAILED(hr))
                {
                    return hr;
                }
            }

            break;
        }
    }

    return S_OK;
}