/*++ 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; }
/*++ 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; }