Esempio n. 1
0
/*++

Routine Name:

    CXDXpsFilter::StartOperation

Routine Description:

    This is the XPS Doxument interface implementation of IPrintPipelineFilter::StartOperation
    shared by all XPS Document filters

Arguments:

    None

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CXDXpsFilter::StartOperation(
    VOID
    )
{
    VERBOSE("Starting filter operation.\n");

    HRESULT hr = S_OK;

    if (SUCCEEDED(hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)) &&
        SUCCEEDED(hr = InitialiseXDIO()) &&
        SUCCEEDED(hr = InitializePrintTicketManager()))
    {
        CComPtr<IUnknown> pUnk(NULL);

        while (SUCCEEDED(hr) &&
               SUCCEEDED(hr = m_pXDReader->GetXpsPart(&pUnk)) &&
               pUnk != NULL &&
               !m_bFilterFinished)
        {
            CComPtr<IXpsDocument> pXD(NULL);
            CComPtr<IFixedDocumentSequence> pFDS(NULL);
            CComPtr<IFixedDocument> pFD(NULL);
            CComPtr<IFixedPage> pFP(NULL);

            //
            // Query interface to find the part type and pass to the
            // appropriate part handler
            //
            if (SUCCEEDED(pUnk.QueryInterface(&pXD)))
            {
                hr = ProcessPart(pXD);
            }
            else if (SUCCEEDED(pUnk.QueryInterface(&pFDS)))
            {
                hr = ProcessPart(pFDS);
            }
            else if (SUCCEEDED(pUnk.QueryInterface(&pFD)))
            {
                hr = ProcessPart(pFD);
            }
            else if (SUCCEEDED(pUnk.QueryInterface(&pFP)))
            {
                hr = ProcessPart(pFP);
            }
            else
            {
                //
                // Unrecognised part - send as unknown.
                //
                hr = m_pXDWriter->SendXpsUnknown(pUnk);
            }

            //
            // Must call release since pUnk is declared outside of the while loop
            //
            pUnk.Release();
        }

        if (SUCCEEDED(hr))
        {
            //
            // Call finalize letting derived classes know we have
            // processed all parts
            //
            hr = Finalize();
        }

        //
        // Close the xps package consumer
        //
        m_pXDWriter->CloseSender();
    }

    //
    // If the filter failed make sure we shutdown the pipeline
    //
    if (FAILED(hr))
    {
        if (m_bFilterFinished)
        {
            //
            // Filter is already closing down so report S_OK
            //
            hr = S_OK;
        }
        else
        {
            //
            // Request the pipeline manager shutdown the filter
            //
            ERR("Requesting filter shutdown\n");
            RequestShutdown(hr);
        }
    }

    //
    // Let the filter pipe manager know the filter is finished
    //
    CoUninitialize();
    FilterFinished();

    ERR_ON_HR(hr);
    return hr;
}
Esempio n. 2
0
/*++

Routine Name:

    CXDStreamFilter::StartOperation

Routine Description:

    This is the stream interface implementation of IPrintPipelineFilter::StartOperation
    shared by all stream interface filters

Arguments:

    None

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT STDMETHODCALLTYPE
CXDStreamFilter::StartOperation(
    VOID
    )
{
    VERBOSE("Starting stream filter operation.\n");

    HRESULT hr = S_OK;
    BOOL bDoCoUninitialize = FALSE;

    if (SUCCEEDED(hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
    {
        bDoCoUninitialize = TRUE;
    }

    if (SUCCEEDED(hr) &&
        SUCCEEDED(hr = InitialiseStreamIO()) &&
        SUCCEEDED(hr = InitializePrintTicketManager()))
    {
        try
        {
            CXPSProcessor* pXpsProcessor = new CXPSProcessor(m_pStreamReader, m_pStreamWriter, this, m_pPrintPropertyBag, &m_ptManager);

            if (SUCCEEDED(hr = CHECK_POINTER(pXpsProcessor, E_OUTOFMEMORY)))
            {
                hr = pXpsProcessor->Start();
            }

            if (pXpsProcessor != NULL)
            {
                delete pXpsProcessor;
                pXpsProcessor = NULL;
            }
        }
        catch (CXDException& e)
        {
            hr = e;
        }

        if (hr == E_NOINTERFACE)
        {
            //
            // The PK archive handler is missing - just pass the data on
            //

            if (SUCCEEDED(hr = CHECK_POINTER(m_pStreamReader, E_POINTER)) &&
                SUCCEEDED(hr = CHECK_POINTER(m_pStreamWriter, E_POINTER)))
            {
                ULONG cbRead = 0;
                BOOL bEOF = FALSE;

                PBYTE pBuff = new BYTE[CB_COPY_BUFFER];

                if (SUCCEEDED(hr = CHECK_POINTER(pBuff, E_OUTOFMEMORY)))
                {
                    do
                    {
                        if (SUCCEEDED(hr = m_pStreamReader->ReadBytes(pBuff, CB_COPY_BUFFER, &cbRead, &bEOF)))
                        {
                            ULONG cbWritten = 0;
                            hr = m_pStreamWriter->WriteBytes(pBuff, cbRead, &cbWritten);
                        }
                    }
                    while (SUCCEEDED(hr) &&
                           !bEOF &&
                           cbRead > 0);

                    delete[] pBuff;
                    pBuff = NULL;
                }
            }
        }
    }

    if (m_pStreamWriter)
    {
        m_pStreamWriter->Close();
    }

    //
    // If the filter failed make sure we shutdown the pipeline
    //
    if (FAILED(hr))
    {
        if (m_bFilterFinished)
        {
            //
            // Filter is already closing down so report S_OK
            //
            hr = S_OK;
        }
        else
        {
            //
            // Request the pipeline manager shutdown the filter
            //
            ERR("Requesting filter shutdown\n");
            RequestShutdown(hr);
        }
    }

    //
    // Let the filter pipe manager know the filter is finished
    //
    if (bDoCoUninitialize)
    {
        CoUninitialize();
    }

    FilterFinished();

    ERR_ON_HR(hr);
    return hr;
}