⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpsproc.cpp

📁 wdk自带xpsdrv filter之 cont
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        {
            CStringXDA cstrRelsPartName;
            CComPtr<ISequentialStream> pFileReader(NULL);

            //
            // Construct the rels part from the parent part name and parse for
            // relationships
            //
            if (SUCCEEDED(hr = MakeRelsPartName(szPartName, &cstrRelsPartName)) &&
                SUCCEEDED(hr = m_contentTypes.ValidateContentType(cstrRelsPartName, ContentRelationships)) &&
                SUCCEEDED(hr = m_xpsArchive.GetFileStream(cstrRelsPartName, &pFileReader)) &&
                SUCCEEDED(hr = m_pSaxRdr->putContentHandler(&m_rels)) &&
                SUCCEEDED(hr = m_rels.SetCurrentFileName(szPartName)) &&
                SUCCEEDED(hr = m_pSaxRdr->parse(CComVariant(pFileReader))))
            {
                //
                // We are done with the .rels part - send it on
                //
                hr = m_xpsArchive.SendCurrentFile();
            }

            //
            // Close the curent file ready for the next
            //
            m_xpsArchive.CloseCurrent();
        }
        catch (CXDException& e)
        {
            hr = e;
        }
    }

    ERR_ON_HR_EXC(hr, E_ELEMENT_NOT_FOUND);
    return hr;
}

/*++

Routine Name:

    CXPSProcessor::MakeRelsPartName

Routine Description:

    This routine converts a part name into the appropriate .rels name.
    The rules for naming are:
        rels parts are stored in a directory named _rels relative to the current part
        rels parts always end in .rels
    e.g. \Documents\FixedDoc.fdseq has rels part \Documents\_rels\FixedDoc.fdseq.rels

Arguments:

    szPartName        - The name of the part to be converted
    pcstrRelsPartName - Pointer to a CStringXDA that recieves the new name

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CXPSProcessor::MakeRelsPartName(
    __in  PCSTR     szPartName,
    __out CStringXDA* pcstrRelsPartName
    )
{
    HRESULT hr = S_OK;

    if (SUCCEEDED(hr = CHECK_POINTER(szPartName, E_POINTER)) &&
        SUCCEEDED(hr = CHECK_POINTER(pcstrRelsPartName, E_POINTER)))
    {
        try
        {
            *pcstrRelsPartName = szPartName;

            //
            // Find the slash that splits the directory and part name
            //
            INT cLastSlash = -1;
            for (;;)
            {
                INT cSlash = pcstrRelsPartName->Find("/", cLastSlash + 1);

                if (cSlash != -1)
                {
                    cLastSlash = cSlash;
                }
                else
                {
                    break;
                }
            }
            cLastSlash++;

            //
            // Insert "_rels/" after the slash and append ".rels"
            //
            pcstrRelsPartName->Insert(cLastSlash, szRelsPre);
            pcstrRelsPartName->Append(szRelsPost);
        }
        catch (CXDException& e)
        {
            hr = e;
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CXPSProcessor::ProcessRelsParts

Routine Description:

    This routine processes the related parts for a given part

Arguments:

    szPartName   - The name of the part
    eContentType - The type of the part to be processed. This must be either an FDS, FD or FP.

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CXPSProcessor::ProcessRelsParts(
    __in PCSTR              szPartName,
    __in CONST EContentType eContentType
    )
{
    HRESULT hr = S_OK;

    BOOL bPrintTicketSent = FALSE;

    if (SUCCEEDED(hr = CHECK_POINTER(szPartName, E_POINTER)))
    {
        if (eContentType != ContentFixedDocumentSequence &&
            eContentType != ContentFixedDocument &&
            eContentType != ContentFixedPage)
        {
            hr = E_INVALIDARG;
        }
    }

    if (SUCCEEDED(hr))
    {
        try
        {
            //
            // Validate the part content type
            // Get the rels and handle any print tickets
            //
            CONST RelsTypeList* pRelsTypeList;
            if (SUCCEEDED(hr = m_contentTypes.ValidateContentType(szPartName, eContentType)) &&
                SUCCEEDED(hr = GetRelsForPart(szPartName)) &&
                SUCCEEDED(hr = m_rels.GetRelsTypeList(szPartName, &pRelsTypeList)))
            {

                RelsTypeList::const_iterator iterRels = pRelsTypeList->begin();

                for (;iterRels != pRelsTypeList->end() && SUCCEEDED(hr); iterRels++)
                {
                    //
                    // Strip any leading "/"
                    //
                    CStringXDA cstrName(iterRels->first);
                    if (cstrName.GetAt(0) == '/')
                    {
                        cstrName.Delete(0);
                    }

                    //
                    // The second of the pair in the RelsTypeList iterator is the rels type
                    //
                    switch (iterRels->second)
                    {
                        case RelsPrintTicket:
                        {
                            hr = AddPrintTicket(cstrName, eContentType);
                            bPrintTicketSent = TRUE;
                        }
                        break;

                        case RelsAnnotations:
                        case RelsDigitalSignatureDefinitions:
                        case RelsDiscardControl:
                        case RelsDocumentStructure:
                        case RelsRequiredResource:
                        case RelsRestrictedFont:
                        case RelsStoryFragments:
                        case RelsCoreProperties:
                        case RelsDigitalSignature:
                        case RelsDigitalSignatureCertificate:
                        case RelsDigitalSignatureOrigin:
                        case RelsThumbnail:
                        {
                            //
                            // We are not interested in the content so intialise the current
                            // file in the XPS archive and send it on
                            //
                            if (SUCCEEDED(hr = m_xpsArchive.InitialiseFile(cstrName)))
                            {
                                hr = m_xpsArchive.SendCurrentFile();
                            }
                        }
                        break;

                        default:
                        {
                            ERR("Unrecognised rels part\n");

                            hr = E_FAIL;
                        }
                        break;
                    }

                    //
                    // Close the current file ready for the next
                    //
                    m_xpsArchive.CloseCurrent();
                }
            }
            else if (hr == E_ELEMENT_NOT_FOUND)
            {
                //
                // There is no PrintTicket
                //
                hr = S_OK;
            }

            //
            // No print ticket has been sent so just inform the print ticket
            // manager that a suitable ticket needs to be set for this level
            //
            if (bPrintTicketSent == FALSE)
            {
                switch (eContentType)
                {
                    case ContentFixedPage:
                    {
                        hr = m_pPtManager->SetTicket(kPTPageScope, NULL);
                    }
                    break;
                    case ContentFixedDocument:
                    {
                        hr = m_pPtManager->SetTicket(kPTDocumentScope, NULL);
                    }
                    break;
                    case ContentFixedDocumentSequence:
                    {
                        hr = m_pPtManager->SetTicket(kPTJobScope, NULL);
                    }
                    break;
                    default:
                    {
                        hr = ERROR_NOT_SUPPORTED;
                    }
                    break;
                }
            }
        }
        catch (CXDException& e)
        {
            hr = e;
        }
        catch (exception& DBG_ONLY(e))
        {
            ERR(e.what());
            hr = E_FAIL;
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CXPSProcessor::AddPrintTicket

Routine Description:

    This routine retrieves the PrintTicket information and updates the PrintTicket
    manager at the appropriate scope

Arguments:

    szPTPartName - The part name for the PrintTicket
    eContentType - The type of the containing part. This must be either an FDS, FD or FP.

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CXPSProcessor::AddPrintTicket(
    __in PCSTR              szPTPartName,
    __in CONST EContentType eContentType
    )
{
    HRESULT hr = S_OK;

    //
    // Validate the parameters
    //
    if (SUCCEEDED(hr = CHECK_POINTER(szPTPartName, E_POINTER)))
    {
        if (eContentType != ContentFixedDocumentSequence &&
            eContentType != ContentFixedDocument &&
            eContentType != ContentFixedPage)
        {
            hr = E_INVALIDARG;
        }
    }

    //
    // Extract the PrintTicket from the current file in the XPS archive
    // and pass to the PrinTicket manager at the appropriate scope
    //
    CComPtr<ISequentialStream> pFileReader(NULL);
    CComPtr<IXMLDOMDocument2>  pPT(NULL);

    VARIANT_BOOL fLoaded = VARIANT_FALSE;

    if (SUCCEEDED(hr) &&
        SUCCEEDED(hr = m_xpsArchive.GetFileStream(szPTPartName, &pFileReader)) &&
        SUCCEEDED(hr = pPT.CoCreateInstance(CLSID_DOMDocument60)) &&
        SUCCEEDED(hr = pPT->load(CComVariant(pFileReader), &fLoaded)))
    {
        if (fLoaded == VARIANT_TRUE)
        {
            //
            // Determine the scope from the parent parts content type
            //
            EPrintTicketScope ePTScope = kPTPageScope;

            if (eContentType == ContentFixedDocumentSequence)
            {
                ePTScope = kPTJobScope;
            }
            else if (eContentType == ContentFixedDocument)
            {
                ePTScope = kPTDocumentScope;
            }

            if (SUCCEEDED(hr = m_pPtManager->SetTicket(ePTScope, pPT)))
            {
                //
                // Make sure the PrintTicket is passed on
                //
                hr = m_xpsArchive.SendCurrentFile();
            }
        }
        else
        {
            ERR("Failed to load PT\n");

            hr = E_FAIL;
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CXPSProcessor::AddPrintTicket

Routine Description:

    This routine intialises the appropriate read and write streams for a fixed
    page processor and calls the processor to do the work

Arguments:

    szFPPartName - The name of the FixedPage part

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CXPSProcessor::ProcessFixedPage(
    __in PCSTR szFPPartName
    )
{
    HRESULT hr = S_OK;
    //
    // Retrieve the file stream and pass to the page scaling handler
    //
    CComPtr<ISequentialStream> pFileReader(NULL);
    CXPSWriteFile* pXpsWriteFile = new CXPSWriteFile(szFPPartName);

    IXMLDOMDocument2* pPT = NULL;

    if (SUCCEEDED(hr = CHECK_POINTER(pXpsWriteFile, E_OUTOFMEMORY)) &&
        SUCCEEDED(hr = CHECK_POINTER(m_pPageProcessor, E_PENDING)) &&
        SUCCEEDED(hr = CHECK_POINTER(szFPPartName, E_PENDING)) &&
        SUCCEEDED(hr = m_xpsArchive.GetFileStream(szFPPartName, &pFileReader)) &&
        SUCCEEDED(hr = m_pPtManager->GetTicket(kPTPageScope, &pPT)) &&
        SUCCEEDED(hr = CHECK_POINTER(pPT, E_FAIL)) &&
        SUCCEEDED(hr = m_pPageProcessor->ProcessFixedPage(pPT, pFileReader, pXpsWriteFile)))
    {
        //
        // Send the new fixed page
        //
        ULONG cb = 0;
        PVOID pv = NULL;

        if (SUCCEEDED(hr = pXpsWriteFile->GetBuffer(&pv, &cb)))
        {
            hr = m_xpsArchive.SendFile(szFPPartName, pv, cb, CompDeflated);
        }
    }
    else if (hr == HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED))
    {
        //
        // The page processor does not want to do any work - just send the page
        //
        hr = m_xpsArchive.SendCurrentFile();
    }

    //
    // Close the curent file ready for the next
    //
    m_xpsArchive.CloseCurrent();

    if (pXpsWriteFile != NULL)
    {
        delete pXpsWriteFile;
        pXpsWriteFile = NULL;
    }

    ERR_ON_HR(hr);
    return hr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -