summaryrefslogtreecommitdiff
path: root/print/OEM Printer Customization Plug-in Samples/C++/PTPCPlPr/src/xmlhandler.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'print/OEM Printer Customization Plug-in Samples/C++/PTPCPlPr/src/xmlhandler.cxx')
-rw-r--r--print/OEM Printer Customization Plug-in Samples/C++/PTPCPlPr/src/xmlhandler.cxx1612
1 files changed, 0 insertions, 1612 deletions
diff --git a/print/OEM Printer Customization Plug-in Samples/C++/PTPCPlPr/src/xmlhandler.cxx b/print/OEM Printer Customization Plug-in Samples/C++/PTPCPlPr/src/xmlhandler.cxx
deleted file mode 100644
index 4bbee2e8..00000000
--- a/print/OEM Printer Customization Plug-in Samples/C++/PTPCPlPr/src/xmlhandler.cxx
+++ /dev/null
@@ -1,1612 +0,0 @@
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-// PARTICULAR PURPOSE.
-//
-// Copyright 1998 - 2005 Microsoft Corporation. All Rights Reserved.
-//
-// FILE: xmlhandler.cxx
-//
-//
-// PURPOSE: Helper Class that handles all functionality related to
-// processing of input PrintTicket/PrintCapabilities XML documents.
-//
-//
-// Functions: Public and Private functions of class OEMPTXMLHandler.
-//
-
-#include "precomp.hxx"
-
-#include "globals.hxx"
-#include "printschema.hxx"
-#include "xmlhandler.hxx"
-
-// This indicates to Prefast that this is a usermode driver file.
-_Analysis_mode_(_Analysis_code_type_user_driver_);
-
-
-//Disable the warnings generated by PFEFAST for conversion between wchar_t * and BSTR
-//because MSXML defines all its interfaces parameters as BSTR but officially declares itself
-//to be wchar_t safe.
-
-#pragma prefast(disable:__WARNING_WCHAR_TO_BSTR)
-
-//
-// MSXML makes the guarantee that we can call it's methods with LPTSTRs instead
-// of BSTRs, so we need to do a const cast whenever we pass our strings to MSXML.
-//
-#define MSXMLSTR(lptstr_value) (const_cast<BSTR>(lptstr_value))
-
-/*++
-Routine Name:
- OEMPTXMLHandler
-Routine Description:
- Print Ticket Handler Constructor
-
-
-Arguments:
- None
-
-Return Value:
- None
-
---*/
-
-OEMPTXMLHandler::OEMPTXMLHandler() :
- m_pRootDocument(NULL),
- m_pRootElement(NULL),
- m_pNSManager(NULL),
- m_dwNextIndex(0)
-{
-}
-
-/*++
-Routine Name:
- ~OEMPTXMLHandler(
-Routine Description:
- Print Ticket Handler Destructor
-
-Arguments:
- None
-
-Return Value:
- None
-
---*/
-
-OEMPTXMLHandler::~OEMPTXMLHandler()
-{
- if (m_pRootDocument)
- {
- m_pRootDocument->Release();
- m_pRootDocument = NULL;
- }
- if (m_pRootElement)
- {
- m_pRootElement->Release();
- m_pRootElement = NULL;
- }
- if (m_pNSManager)
- {
- m_pNSManager->Release();
- m_pNSManager = NULL;
- }
-}
-
-/*++
-Routine Name:
- SetRoot
-
-Routine Description:
-
- Initialization routine. Sets root of the DOM tree. Alos creates an instance of xml namespace manager
- using plug-in helper interface method.
-
- Note: This routine MUST BE called before any other xml handling routines are called.
- Note also that it is not necessary to call CoInitializeEx because Unidrv has already
- made that call while creating the DOM tree with appropriate arguments passed on to it
- and when Unidrv makes a call to one of plug-in interface routines, since plug-in is
- running in the same thread, it does not need to make that call again
- In fact the plug-in SHOULD NOT make that call to CoInitializeEx , because Unidrv must have made
- that call with some particular concurrency model settings which plug-in cannot find out,
- so the plug-in might end up changing the concurrency setting made by Unidrv.
-
-Arguments:
- pRoot - Root of the input DOM tree.
-
-
-Return Value:
- HRESULT Completion status code
-
---*/
-HRESULT
-OEMPTXMLHandler::SetRoot(
- _In_ IXMLDOMDocument2 *pRoot,
- _In_ IPrintCoreHelper *pHelper
- )
-{
- HRESULT hr = S_OK;
-
- //
- // check if input paramters are not NULL
- //
- if (!pRoot || !pHelper)
- {
- return E_INVALIDARG;
- }
-
- m_pRootDocument = pRoot;
-
- m_pRootDocument->AddRef();
-
-
- //
- // Make use of Plug-in Helper Interface method provided by Unidrv to create an Instance of MSXML Namespace Manager.
- // The plug-in must make use of Helper Interface provided by Unidrv while creating instance of namespacemanager
- // of MSXML DOM document, the plug-in should not load MSXML6.DLL by itself but should rely on Unidrv for
- // doing that
- //
- if (SUCCEEDED(hr))
- {
- //
- // Note: Current versions of Unidrv support MSXML6 hence plug-in should also support that and write its
- // code in compliance with MSXML6
- //
- hr = pHelper->CreateInstanceOfMSXMLObject(CLSID_MXNamespaceManager60, NULL, NULL, IID_IMXNamespaceManager, (void**)&m_pNSManager);
- }
-
- //
- // Get the Root Element of the document and store it in pRootElement.
- //
- if (SUCCEEDED(hr))
- {
- hr = m_pRootDocument->get_documentElement(&m_pRootElement);
- }
-
- if (FAILED(hr))
- {
- if (m_pRootDocument)
- {
- m_pRootDocument->Release();
- m_pRootDocument = NULL;
- }
-
- if (m_pRootElement)
- {
- m_pRootElement->Release();
- m_pRootElement = NULL;
- }
-
- if (m_pNSManager)
- {
- m_pNSManager->Release();
- m_pNSManager = NULL;
- }
- }
-
- return hr;
-}
-
-/*++
-Routine Name:
- CreateFeatureNode
-
-Routine Description:
-
- Creates a new Feature Node
-
-Arguments:
- pParent - parent node of the new feature node, if NULL, root is considered as parent
- pszNamespaceURI - namesapce URI to which new node belongs
- pszFeatureName - local name of the new feature node
- ppFeatureNode - out pointer to newly created node
-
-Return Value:
- HRESULT Completion status code
- S_OK on success
- E_* on failure
-
---*/
-
-HRESULT OEMPTXMLHandler::CreateFeatureNode(
- _In_opt_ IXMLDOMElement *pParent,
- _In_ PCWSTR pszNamespaceURI,
- _In_ PCWSTR pszFeatureName,
- _Out_opt_ IXMLDOMElement **ppFeatureNode
- )
-{
- HRESULT hr = S_OK;
- IXMLDOMElement *pNewElement = NULL;
- BSTR qName = NULL;
-
- if (!pszFeatureName)
- {
- return E_INVALIDARG;
- }
-
- if (!pParent)
- {
- pParent = m_pRootElement;
- }
-
-
- hr = CreateXMLElement(pParent, printschema::FEATURE_ELEMENT_NAME, printschema::FRAMEWORK_URI, &pNewElement);
-
- if (SUCCEEDED(hr))
- {
- hr = CreateQName(pNewElement, pszNamespaceURI, pszFeatureName, &qName);
- }
-
- if (SUCCEEDED(hr))
- {
-
- // The 'name' attibute node is not namespace qualified; it
- // belongs to the namespace of its parent (feature/option)
- // node.
-
- hr = CreateXMLAttribute(pNewElement, printschema::NAME_ATTRIBUTE_NAME, L"", qName);
- }
-
- if (qName)
- {
- SysFreeString(qName);
- qName = NULL;
- }
-
- if (SUCCEEDED(hr) && ppFeatureNode)
- {
- *ppFeatureNode = pNewElement;
- }
- else if (pNewElement)
- {
- pNewElement->Release();
- }
-
- return hr;
-
-}
-
-/*++
-Routine Name:
- CreateOptionNode
-
-Routine Description:
-
- Creates a new Option Node
-
-Arguments:
- pParent - parent node of the new Option node
- pszNamespaceURI - namesapce URI to which new node belongs
- pszFeatureName - local name of the new Option node
- ppOptionElement - out pointer to newly created node
-
-Return Value:
- HRESULT Completion status code
- S_OK on success
- E_* on failure
-
---*/
-
-HRESULT OEMPTXMLHandler::CreateOptionNode(
- _In_ IXMLDOMElement *pParent,
- _In_ PCWSTR pszNamespaceURI, //print schema URI that corresponds to prefix "prn:"
- _In_ PCWSTR pszOptionName, //"TopLeft" etc
- _Out_opt_ IXMLDOMElement **ppOptionElement
- )
-{
- HRESULT hr = S_OK;
- IXMLDOMElement *pNewElement = NULL;
- BSTR qName = NULL;
-
- if (!pParent)
- {
- return E_INVALIDARG;
- }
-
- hr = CreateXMLElement(pParent, printschema::OPTION_ELEMENT_NAME, printschema::FRAMEWORK_URI, &pNewElement);
-
- if (SUCCEEDED(hr))
- {
- hr = CreateQName(pNewElement, pszNamespaceURI, pszOptionName, &qName);
- }
-
- if (SUCCEEDED(hr))
- {
- // The 'name' attibute node is not namespace qualified; it
- // belongs to the namespace of its parent (feature/option)
- // node.
-
- hr = CreateXMLAttribute(pNewElement, printschema::NAME_ATTRIBUTE_NAME, L"", qName);
- }
-
- if (qName)
- {
- SysFreeString(qName);
- qName = NULL;
- }
-
- if (SUCCEEDED(hr) && ppOptionElement)
- {
- *ppOptionElement = pNewElement;
- }
- else if (pNewElement)
- {
- pNewElement->Release();
- }
-
- return hr;
-}
-
-/*++
-Routine Name:
- CreateXMLElement
-
-Routine Description:
- Generic method to create new XML element node
-
-Arguments:
-
- pParent - pointer to the parent node of the new nod eto be created, if NULL root of DOM tree is considered as parent
- pszElementName - local name of the newly created element
- pszNamespaceURI - namespace URI that the new element belongs to, the caller can only specify the namespace URI
- and not the prefix
- ppCreatedElement - double pointer to the newly created element returned by the procedure
-
-Return Value:
- HRESULT Completion status code
- S_OK - If the new element node is created successfully
- E_* - on failure
-
---*/
-
-HRESULT OEMPTXMLHandler::CreateXMLElement(
- _In_ IXMLDOMElement *pParent,
- _In_ PCWSTR pszElementName,
- _In_ PCWSTR pszNamespaceURI,
- _Out_ IXMLDOMElement **ppCreatedElement
- )
-{
- HRESULT hr = S_OK;
- IXMLDOMNode *pNewNode = NULL;
- BSTR bstrQName = NULL;
-
- if (!pParent || !pszElementName || !pszNamespaceURI || !ppCreatedElement)
- {
- return E_INVALIDARG;
- }
-
- //
- // create XML Qname
- //
- hr = CreateQName(pParent, pszNamespaceURI, pszElementName, &bstrQName);
-
- if (SUCCEEDED(hr))
- {
- VARIANT nodeType;
- VariantInit(&nodeType);
- V_VT(&nodeType) = VT_I4;
- V_I4(&nodeType) = NODE_ELEMENT;
- hr = m_pRootDocument->createNode(nodeType, bstrQName, MSXMLSTR(pszNamespaceURI), &pNewNode);
- if (SUCCEEDED(hr))
- VariantClear(&nodeType);
- }
-
- if (SUCCEEDED(hr))
- hr = pParent->appendChild(pNewNode, NULL);
-
-
- if (SUCCEEDED(hr))
- {
- //
- // we need to return Interface ptr to IXMLDOMElement.
- //
- hr = pNewNode->QueryInterface(IID_IXMLDOMElement, (void **)ppCreatedElement);
-
- //
- // if interface is not supported, E_* will be returned in hr,
- // we simply return that to the caller.
- //
- }
-
- if (pNewNode)
- {
- //
- // release reference to local node Created since it is no longer being used
- //
- pNewNode->Release();
- }
-
- if (bstrQName)
- {
- SysFreeString(bstrQName);
- bstrQName = NULL;
- }
-
- return hr;
-
-}
-
-/*++
-Routine Name:
- CreateQName
-
-Routine Description:
-
- Creates XML qname for given local name and namespace URI
- Note: It is assumed that a prefix for given URI is already defined in root of DOM document
- either by Unidrv or by plug-in itself.
- Routine fails if it doesnot find a predefined prefix for given URI.
-
-Arguments:
- pElement - context node
- pszUri - Uri
- pszLocalName - local name
- pQName - a pointer to resultant qname string defined by the routine
-
-Return Value:
- HRESULT Completion status code
-
- S_OK - On success
- E_FAIL - on failure to create Qname
-
---*/
-HRESULT OEMPTXMLHandler::CreateQName(
- _In_ IXMLDOMElement *pElement,
- _In_ PCWSTR pszUri,
- _In_ PCWSTR pszLocalName,
- _Out_ BSTR *pQName
- )
-{
- HRESULT hr = S_OK;
- BSTR bstrPrefixString = NULL;
- size_t prefixLen = 0;
- // Is it the default namespace? If so, don't stick a semicolon in the string
- size_t localNameLen = 0;
-
- if (!pszUri || !pszLocalName || !pQName)
- {
- return E_INVALIDARG;
- }
-
- *pQName = NULL;
-
- //
- // See if a prefix is already defined for the given URI
- //
-
- hr = getPrefix(pElement, pszUri, &bstrPrefixString);
-
- //
- // It is possible that during validation the prefix might not
- // already be defined if we're converting public features to GPD
- // features. In that case, we need to add a definition for the
- // feature namespace.
- //
-
- if (S_FALSE == hr)
- {
- hr = declarePrefix(pElement, pszUri, NULL, &bstrPrefixString);
- }
-
- if (SUCCEEDED(hr))
- {
- //
- // StrSafe function StringCchLength checks if the length of string is less than
- // maximum length specified, and returns S_OK if the input string is non NULL and
- // length is less that maximum length specified.
- // It returns length of string EXCLUDING null terminator
- //
- hr = StringCchLength(pszLocalName, STR_MAX_CCH, &localNameLen);
- }
-
- if (SUCCEEDED(hr))
- {
- if (bstrPrefixString)
- {
- hr = StringCchLength(bstrPrefixString, STR_MAX_CCH, &prefixLen);
- }
- }
-
- if (SUCCEEDED(hr))
- {
- if (prefixLen > 0)
- {
- // non-default namespace
-
- UINT cchLength = 0;
-
- if (SUCCEEDED(hr = SizeTAdd(prefixLen, localNameLen, &localNameLen)) &&
- SUCCEEDED(hr = SizeTAdd(localNameLen, 2, &localNameLen)) &&
- SUCCEEDED(hr = SizeTToUInt(localNameLen, &cchLength)))
- {
-
- *pQName = SysAllocStringLen(NULL, cchLength);
-
- if (*pQName)
- {
- // we got a terminator character as part of SysAllocString.
- hr = StringCchPrintf(*pQName, cchLength, L"%s:%s", bstrPrefixString, pszLocalName);
- }
- else
- {
- hr = E_OUTOFMEMORY;
- }
- }
- }
- else
- {
- // Default namespace ...
-
- UINT cchLength = 0;
-
- if (SUCCEEDED(hr = SizeTAdd(localNameLen, 1, &localNameLen)) &&
- SUCCEEDED(hr = SizeTToUInt(localNameLen, &cchLength)))
- {
- *pQName = SysAllocStringLen(NULL, cchLength);
-
- if (*pQName)
- {
- // we got a terminator character as part of SysAllocString.
- hr = StringCchPrintf(*pQName, cchLength, L"%s", pszLocalName);
- }
- else
- {
- hr = E_OUTOFMEMORY;
- }
- }
- }
- }
-
- if (bstrPrefixString)
- {
- SysFreeString(bstrPrefixString);
- bstrPrefixString = NULL;
- }
-
- if (FAILED(hr))
- {
- if (*pQName)
- {
- SysFreeString(*pQName);
- *pQName = NULL;
- }
- }
-
- return hr;
-}
-
-/*++
-Routine Name:
- CreateXMLAttribute
-
-Routine Description:
- Creates an attribute for the given XML element.
-
-Arguments:
-
- pElement - pointer to the element node to which an attribute is to be added
- pszAttributeName - local name of the attribute
- pszNamespaceURI - namespace URI to which the attribute belongs
- pszAttributeValue - value of the attribute
-
-Return Value:
- HRESULT Completion status code
- S_OK - on success
- E_* - on failure
-
---*/
-
-HRESULT OEMPTXMLHandler::CreateXMLAttribute(
- _In_ IXMLDOMElement *pElement,
- _In_ PCWSTR pszAttributeName, //"name="
- _In_ PCWSTR pszNamespaceURI, //"pt:"
- _In_ PCWSTR pszAttributeValue //"prn:"
- )
-{
- HRESULT hr = S_OK;
- IXMLDOMAttribute *pNewAttribute = NULL ;
- IXMLDOMNode *pNewNode = NULL ;
-
- if (!pElement || !pszAttributeName || ! pszNamespaceURI || !pszAttributeValue)
- {
- return E_INVALIDARG;
- }
-
- VARIANT nodeType;
- VariantInit(&nodeType);
- V_VT(&nodeType) = VT_I4;
- V_I4(&nodeType) = NODE_ATTRIBUTE;
- hr = m_pRootDocument->createNode(nodeType, MSXMLSTR(pszAttributeName), MSXMLSTR(pszNamespaceURI), &pNewNode);
- if (SUCCEEDED(hr))
- VariantClear(&nodeType);
-
- if (SUCCEEDED(hr))
- {
- hr = pNewNode->QueryInterface(IID_IXMLDOMAttribute, (void **)&pNewAttribute);
- }
-
- if (SUCCEEDED(hr))
- {
- VARIANT attrType;
- VariantInit(&attrType);
- V_VT(&attrType) = VT_BSTR;
- V_BSTR(&attrType) = SysAllocString(pszAttributeValue);
- hr = pNewAttribute->put_value(attrType);
- if (SUCCEEDED(hr))
- VariantClear(&attrType);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = pElement->setAttributeNode(pNewAttribute, NULL);
- }
-
- if (SUCCEEDED(hr))
- {
- if (pNewAttribute)
- {
- pNewAttribute->Release();
- }
-
- }
- else if (pNewAttribute)
- pNewAttribute->Release();
-
- if (pNewNode)
- pNewNode->Release();
-
- return hr;
-}
-
-/*++
-Routine Name:
- GetXMLElement
-Routine Description:
- Returns an XML element with given namespace URI and given attribute
-
-Arguments:
-
- pParent - Parent of node to be found
- pszElementNamespaceURI - Namespace URI to which the element belongs
- pszElementName - Local Name of the element
- pszAttrNamespaceURI - Namespace URI to which the attribute of the element belongs
- pszAttrName - local name of the element attribute
- ppElement - out pointer to xml element so retrieved
-
-Return Value:
- HRESULT Completion status code
- S_OK - On Successfully locating XML node specified
- S_FALSE - If the specified XML node is not found
- E_* - On Failure
-
- Note: Since the module returns S_FALSE if the specified node is not found, the caller must be
- careful to check hr status to be S_OK before proceeding, just checking for SUCCEEDED(hr) might
- give wrong results
-
---*/
-HRESULT OEMPTXMLHandler::GetXMLElement(
- _In_ IXMLDOMElement *pParent,
- _In_ PCWSTR pszElementNamespaceURI,
- _In_ PCWSTR pszElementName,
- _In_ PCWSTR pszAttrNamespaceURI,
- _In_ PCWSTR pszAttrName,
- _Outptr_result_maybenull_ IXMLDOMElement **ppElement
- ) const
-{
- HRESULT hr = S_OK;
- LONG cChildren = 0;
- IXMLDOMNodeList *pChildren = NULL;
-
-
- if (!pParent || !pszElementNamespaceURI || !pszElementName || !pszAttrNamespaceURI || !pszAttrName)
- {
- return E_INVALIDARG;
- }
-
- *ppElement = NULL;
-
- //
- // Get a list of child nodes for the current DOM node
- //
- hr = pParent->get_childNodes(&pChildren);
-
- //
- // Get number of child nodes
- //
- if (SUCCEEDED(hr))
- {
- hr = pChildren->get_length(&cChildren);
- }
-
- if (SUCCEEDED(hr))
- {
- LONG i = 0;
- BOOL bFound = FALSE;
-
- for(i = 0;i < cChildren && !bFound;i++)
- {
- IXMLDOMNode *pCurNode;
- IXMLDOMElement *pCurElement = NULL;
-
- hr = pChildren->get_item(i, &pCurNode);
-
- if (SUCCEEDED(hr))
- {
- hr = pCurNode->QueryInterface(IID_IXMLDOMElement, (void **)&pCurElement);
- }
- if (S_OK == hr)
- {
- BSTR bstrElementName = NULL;
- BSTR bstrElementNamespaceURI = NULL;
-
- //
- // retrieve element name and namespace URI
- //
- hr = pCurElement->get_baseName(&bstrElementName);
-
- if (SUCCEEDED(hr))
- {
- hr = pCurElement->get_namespaceURI(&bstrElementNamespaceURI);
- }
-
- if (SUCCEEDED(hr) && bstrElementNamespaceURI && bstrElementName)
- {
-
- if (0 == wcscmp(bstrElementName, pszElementName) && 0 == wcscmp(bstrElementNamespaceURI, pszElementNamespaceURI))
- {
- //
- //check if element name matches
- //
- BSTR bstrAttrName = NULL;
- BSTR bstrAttrNamespaceURI = NULL;
- hr = GetXMLAttribute(pCurElement,&bstrAttrNamespaceURI,&bstrAttrName);
- if (SUCCEEDED(hr) && bstrAttrName && bstrAttrNamespaceURI)
- {
- if (0 == wcscmp(bstrAttrName, pszAttrName) && 0 == wcscmp(pszAttrNamespaceURI, bstrAttrNamespaceURI))
- {
- bFound = TRUE;
- *ppElement = pCurElement;
- (*ppElement)->AddRef();
- }
- else
- {
- hr = S_FALSE;
- }
- }
-
- SysFreeString(bstrAttrName);
- bstrAttrName = NULL;
-
- SysFreeString(bstrAttrNamespaceURI);
- bstrAttrNamespaceURI = NULL;
- }
- }
-
- SysFreeString(bstrElementName);
- bstrElementName = NULL;
-
- SysFreeString(bstrElementNamespaceURI);
- bstrElementNamespaceURI = NULL;
-
- if (pCurElement)
- {
- pCurElement->Release();
- }
- }
-
- if (pCurNode)
- {
- pCurNode->Release();
- }
- }
- }
-
- if (pChildren)
- pChildren->Release();
-
- if (SUCCEEDED(hr) && (*ppElement))
- {
- hr = S_OK;
- }
- else
- {
- hr = S_FALSE;
- }
-
- return hr;
-
-}
-
-/*++
-Routine Name:
- GetXMLElementWithoutAttribute
-
-Routine Description:
- Returns an XML element with given namespace URI.
-
-Arguments:
-
- pParent - Parent of node to be found
- pszElementNamespaceURI - Namespace URI to which the element belongs
- pszElementName - Local Name of the element
- ppChildElement - out pointer to xml element so retrieved
-
-Return Value:
- HRESULT Completion status code
- S_OK - On Successfully locating XML node specified
- S_FALSE - If the specified XML node is not found
- E_* - On Failure
-
- Note: Since the module returns S_FALSE if the specified node is not found, the caller must be
- careful to check hr status before proceeding, just checking for SUCCEEDED(hr) might
- give wrong results
-
---*/
-HRESULT OEMPTXMLHandler::GetXMLElementWithoutAttribute(
- _In_ IXMLDOMElement *pContext,
- _In_ PCWSTR pszElementNamespace,
- _In_ PCWSTR pszElementName,
- _Outptr_result_maybenull_ IXMLDOMElement **ppChildElement
- ) const
-{
- if (!pContext || !pszElementName || !pszElementNamespace || !ppChildElement)
- {
- return E_INVALIDARG;
- }
-
- HRESULT hr = S_OK;
- LONG cChildren = 0;
- IXMLDOMNodeList *pContextChildren;
- *ppChildElement = NULL;
-
- //
- // Get the list of child nodes
- //
- hr = pContext->get_childNodes(&pContextChildren);
-
- if (SUCCEEDED(hr))
- hr = pContextChildren->get_length(&cChildren);
-
- if (SUCCEEDED(hr))
- {
- for(LONG i = 0;i < cChildren && !(*ppChildElement);i++)
- {
-
- IXMLDOMNode *pCurrentNode;
- IXMLDOMElement *pCurrentElement;
- hr = pContextChildren->get_item(i, &pCurrentNode);
-
- //
- // See if its a DOM Element. Don't set hr here because we
- // fully expect that not everything in the context is an element.
- //
- if (SUCCEEDED(hr) && S_OK == pCurrentNode->QueryInterface(IID_IXMLDOMElement, (void**)&pCurrentElement))
- {
- BSTR pbstrBaseName = NULL;
- BSTR pbstrNamespaceURI = NULL;
-
- hr = pCurrentElement->get_baseName(&pbstrBaseName);
-
- if (SUCCEEDED(hr))
- {
- hr = pCurrentElement->get_namespaceURI(&pbstrNamespaceURI);
- }
- if (SUCCEEDED(hr) &&
- pbstrNamespaceURI &&
- pbstrBaseName &&
- 0 == wcscmp(pbstrNamespaceURI, pszElementNamespace) &&
- 0 == wcscmp(pbstrBaseName, pszElementName))
- {
- *ppChildElement = pCurrentElement;
- (*ppChildElement)->AddRef();
- }
-
- pCurrentElement->Release();
-
- SysFreeString(pbstrBaseName);
- pbstrBaseName = NULL;
-
- SysFreeString(pbstrNamespaceURI);
- pbstrNamespaceURI = NULL;
- }
-
- if (pCurrentNode)
- {
- pCurrentNode->Release();
- }
- }
- }
-
- if (pContextChildren)
- {
- pContextChildren->Release();
- }
-
- if (SUCCEEDED(hr))
- {
- if (*ppChildElement)
- {
- hr = S_OK;
- }
- else
- {
- hr = S_FALSE;
- }
- }
-
- return hr;
-}
-
-/*++
-Routine Name:
- GetXMLAttribute
-
-Routine Description:
- Returns an XML Attribute node with given namespace URI.
-
-Arguments:
-
- pParent - Parent of node to be found
- pszAttrNamespaceURI - Namespace URI to which the attribute belongs
- pszAttrName - Local Name of the attribute
- ppChildElement - out pointer to xml node so retrieved
-
-Return Value:
- HRESULT Completion status code
- S_OK - On Success
- E_* - On Failure
-
---*/
-HRESULT OEMPTXMLHandler::GetXMLAttribute(
- _In_ IXMLDOMElement *pElement,
- _Outptr_result_maybenull_ BSTR *ppAttrNamespaceURI,
- _Outptr_result_maybenull_ BSTR *ppAttrName
- ) const
-{
- HRESULT hr = S_OK;
- IXMLDOMNamedNodeMap *pAttrMap = NULL;
- IXMLDOMNode *pAttrNode = NULL;
-
- if (!pElement || !ppAttrNamespaceURI || !ppAttrName)
- {
- return E_INVALIDARG;
- }
-
- *ppAttrNamespaceURI = NULL;
- *ppAttrName = NULL;
-
- hr = pElement->get_attributes(&pAttrMap);
-
- if (SUCCEEDED(hr))
- {
- hr = pAttrMap->getNamedItem(MSXMLSTR(printschema::NAME_ATTRIBUTE_NAME),&pAttrNode);
- }
-
- if (S_OK == hr)
- {
- BSTR bstrAttrQName = NULL;
- IXMLDOMAttribute *pAttribute = NULL;
-
- hr = pAttrNode->QueryInterface(IID_IXMLDOMAttribute, (void **)&pAttribute);
-
- if (SUCCEEDED(hr))
- hr = pAttribute->get_text(&bstrAttrQName);
-
- if (S_OK == hr && bstrAttrQName)
- hr = getUri(pElement, bstrAttrQName, ppAttrNamespaceURI);
-
- if (S_OK == hr && bstrAttrQName)
- hr = getLocalName(bstrAttrQName, ppAttrName);
-
- if (pAttribute)
- pAttribute->Release();
-
- if (bstrAttrQName)
- {
- SysFreeString(bstrAttrQName);
- bstrAttrQName = NULL;
- }
- }
-
- if (pAttrMap)
- pAttrMap->Release();
- if (pAttrNode)
- pAttrNode->Release();
-
- if (FAILED(hr))
- {
- if (*ppAttrNamespaceURI)
- {
- SysFreeString(*ppAttrNamespaceURI);
- *ppAttrNamespaceURI = NULL;
- }
- if (*ppAttrName)
- {
- SysFreeString(*ppAttrName);
- *ppAttrName = NULL;
- }
- }
- return hr;
-}
-
-/*++
-Routine Name:
- GetFeatureNode
-
-Routine Description:
-
- Returns the feature node with specified attribute under printschema namespace
-
-Arguments:
- pParent - parent node of the feature node to be located
- pszAttrNamespaceURI - namespace URI for the attribute node of given feature node
- pszAttrName - attribute name for given feature node
- ppElement - OUT pointer to feature node to be returned
-
-Return Value:
- HRESULT Completion status code
- S_OK - On Successfully locating Feature node
- S_FALSE - If Feature node is not found
- E_* - On Failure
-
-
---*/
-HRESULT OEMPTXMLHandler::GetFeatureNode(
- _In_opt_ IXMLDOMElement *pParent,
- _In_ PCWSTR pszAttrNamespaceURI,
- _In_ PCWSTR pszAttrName,
- _Out_ _When_(return == S_FALSE, _At_(*ppElement, _Post_maybenull_))
- _When_(return != S_FALSE, _At_(*ppElement, _Post_valid_))
- IXMLDOMElement **ppElement
- ) const
-{
- HRESULT hr = S_OK;
-
- //
- // If no parent is specified, set root of DOM tree as parent
- //
- if (!pParent)
- {
- pParent = m_pRootElement;
- }
-
- hr = GetXMLElement(pParent, printschema::FRAMEWORK_URI, printschema::FEATURE_ELEMENT_NAME, pszAttrNamespaceURI, pszAttrName, ppElement);
-
- return hr;
-}
-
-/*++
-Routine Name:
- GetOptionNode
-
-Routine Description:
-
- Returns the option node under printschema namespace
-
-Arguments:
- pParent - parent node of the option node to be located
- ppElement - OUT pointer to option node to be returned
-
-Return Value:
- HRESULT Completion status code
- S_OK - On Successfully locating Option node
- S_FALSE - If Option node is not found
- E_* - On Failure
-
---*/
-HRESULT
-OEMPTXMLHandler::GetOptionNode(
- _In_ IXMLDOMElement *pParent,
- _Outptr_result_maybenull_ IXMLDOMElement **ppElement
- ) const
-{
- return GetXMLElementWithoutAttribute(pParent, printschema::FRAMEWORK_URI, printschema::OPTION_ELEMENT_NAME, ppElement);
-}
-
-/*++
-
-Routine Name:
- getLocalName
-Routine Description:
- Returns Local name for input XML Qname.
-
-Arguments:
- pszQName - Qname for which local name is to be found out
- ppbstrLocalName - OUT pointer to local name
-
-Return Value:
- HRESULT Completion status code
- S_OK - On Success
- E_* - On Failure
-
---*/
-HRESULT
-OEMPTXMLHandler::getLocalName(
- _In_ PCWSTR pszQName,
- _Out_ BSTR *ppbstrLocalName
- ) const
-{
- HRESULT hr = S_OK;
-
- if (!pszQName || !ppbstrLocalName)
- {
- return E_INVALIDARG;
- }
-
- *ppbstrLocalName = NULL;
-
- PCWSTR pszStartPos = wcschr(pszQName,L':');
-
- if (pszStartPos)
- {
- pszStartPos++;
- }
- else
- {
- pszStartPos = pszQName;
- }
-
- *ppbstrLocalName = SysAllocString(pszStartPos);
-
- if (!(*ppbstrLocalName))
- {
- hr = E_OUTOFMEMORY;
- }
-
- return hr;
-}
-
-
-/*++
-Routine Name:
- getUri
-Routine Description:
- Returns namespace URI for given input Qname and in context of given XML DOM node.
-Arguments:
- pContext - Input XML DOM node for current context
- pszQName - input qname
- pbstrURI - OUT pointer to URI to be returned
-Return Value:
-
- S_OK if found
- S_FALSE if not found
- E_OUTOFMEMORY if the string could not be allocated
- E_INVALIDARG if a non-optional param is null.
-
-Notes:
-
- This routine assumes that the string has already been
- validated, which should have happened in the managed code base.
- The string should either be of the form "prefix:localname",
- or "localname"
-
---*/
-HRESULT
-OEMPTXMLHandler::getUri(
- IXMLDOMElement *pContext,
- _In_ PCWSTR pszQName,
- _Out_ BSTR *pbstrURI
- ) const
-
-{
- HRESULT hr = S_OK;
- BOOL bNodePushed = FALSE;
-
- if (!(pContext && pbstrURI && pszQName))
- {
- return E_INVALIDARG;
- }
-
- PWSTR pszSplitPos = (_TCHAR*) wcschr(pszQName, L':');
- INT cchUri = 0;
- *pbstrURI = NULL;
-
- //
- // if splitpos is null, then there is no namespace
- // prefix, which means return the default namespace.
- //
- wchar_t wchSwapChar = L'\0';
- if (pszSplitPos)
- {
- wchSwapChar = *pszSplitPos;
- *pszSplitPos = (wchar_t)0;
- }
- else
- {
- pszQName = L"";
- }
-
- hr = m_pNSManager->pushNodeContext(pContext, TRUE);
-
- if (SUCCEEDED(hr))
- {
- bNodePushed = TRUE;
- // get the length first, then alloc the string
-#pragma prefast(suppress:__WARNING_INVALID_PARAM_VALUE_1, "According to MSDN, it is acceptable to pass a NULL buffer to getURI.")
- hr = m_pNSManager->getURI(pszQName, NULL, NULL, &cchUri);
- }
-
- if (S_OK == hr)
- {
- if (SUCCEEDED(hr))
- {
- // account for null terminator
- cchUri += 1;
-
- *pbstrURI = SysAllocStringLen(NULL, cchUri);
- if (!(*pbstrURI))
- {
- hr = E_OUTOFMEMORY;
- }
- }
-
- if (SUCCEEDED(hr))
- {
- hr = m_pNSManager->getURI(pszQName, NULL, *pbstrURI, &cchUri);
- }
-
- if (pszSplitPos)
- {
- *pszSplitPos = wchSwapChar;
- }
-
- if (FAILED(hr) && (*pbstrURI))
- {
- SysFreeString(*pbstrURI);
- *pbstrURI = NULL;
- }
- }
-
- if (bNodePushed)
- {
- hr = m_pNSManager->popContext();
- }
-
- return hr;
-}
-
-/*++
-
-Routine Name:
- getPrefix
-Routine Description:
-
- Returns predefined Prefix for the input namespace URI if one already exists
-
-Arguments:
- pContext - Current context node
- pszUri - namespace URI for which prefix is to be obtained
- pbstrPrefix - prefix string to be returned, if NULL routine just checks for
- existence of prefix
-
-Return Value:
- HRESULT Completion status code
- S_OK - on success
- S_FALSE - on failure
-
---*/
-HRESULT
-OEMPTXMLHandler::getPrefix(
- _In_ IXMLDOMElement *pContext,
- _In_ PCWSTR pszUri,
- _Outptr_opt_result_maybenull_ BSTR *pbstrPrefix
- ) const
-{
- HRESULT hr = S_OK;
- BOOL bNodePushed = FALSE;
- INT cchPrefix = 0;
-
- if (!pContext || !pszUri)
- return E_INVALIDARG;
-
- if (pbstrPrefix)
- {
- *pbstrPrefix = NULL;
- }
-
- //Push context "Deep" to get info abt all URI prefix mappings defined so far in the current DOM document
- hr = m_pNSManager->pushNodeContext(pContext, TRUE);
-
- if (SUCCEEDED(hr))
- {
- bNodePushed = TRUE;
-
- // get the length first, then alloc the string
-
- hr = m_pNSManager->getPrefix(pszUri, 0, NULL, &cchPrefix);
- }
-
-
- if (S_OK == hr && pbstrPrefix)
- {
-
- *pbstrPrefix = NULL;
- cchPrefix++;
-
- if (SUCCEEDED(hr))
- {
- *pbstrPrefix = SysAllocStringLen(NULL, cchPrefix);
-
- if (!(*pbstrPrefix))
- hr = E_OUTOFMEMORY;
- }
-
- if (SUCCEEDED(hr))
- {
- hr = m_pNSManager->getPrefix(pszUri, 0, *pbstrPrefix, &cchPrefix);
-
- }
-
- if (FAILED(hr) && (*pbstrPrefix))
- {
- SysFreeString(*pbstrPrefix);
- *pbstrPrefix = NULL;
- }
- }
-
- // Note: MSXML NSManager returns S_FALSE for an undeclared URI, and E_FAIL for an undeclared
- // prefix, hence it is safe to check for both here.
-
- if (E_FAIL == hr || S_FALSE == hr)
- {
- // NS manager didn't find the prefix. Tweak the result to S_FALSE
- hr = S_FALSE;
- }
-
- if (bNodePushed)
- {
- m_pNSManager->popContext();
- }
-
- return hr;
-}
-
-/*++
-
-Routine Name:
- declarePrefix
-
-Routine Description:
-
- This declares a new prefix for a given URI. This routine will always generate a new
- prefix definition, regardless of whether the URI is already defined. Use getPrefix
- to prevent duplicate definitions of namespace URI prefixes. If the preferred prefix is
- already in use or no preferred prefix is supplied the namespace will be declared using
- a generated namespace name.
-
-Arguments:
- pContext - The context in which you want to ensure that the prefix is properly declared
- in. This is where we check to see if the prefix is already in use. However, if not
- in use, the prefix will always be declared in the root of the document. This gaurantees
- 2 things: The prefix is declared in the entire document (though it may be overridden
- locally in other places), and the prefix has the expected meaning at the passed in pContext.
- pszUri - The URI to associate with the prefix.
- pszPreferredPrefix - prefix to use if not already defined, can be a BSTR or PCWSTR, either
- is acceptable
- pbstrNewPrefix - The actual prefix that was declared, which may be different from the
- preferred prefix
-
-Return Value:
- HRESULT Completion status code
- S_OK - on success
- S_FALSE - on failure
-
---*/
-HRESULT
-OEMPTXMLHandler::declarePrefix(
- _In_ IXMLDOMElement *pContext,
- _In_ PCWSTR pszUri,
- _In_opt_ PCWSTR pszPreferredPrefix,
- _Out_ BSTR *pbstrNewPrefix
- )
-{
- HRESULT hr = S_OK;
-
- // These two strings are tied ... the second string is used to print the number over top of a
- // copy of the first string, so chances are, if you change one, you need to change the other.
- PCWSTR szPrefixChars = L"ns0000";
- PCWSTR szPrefixPrintfPattern = L"ns%.4X";
-
- if (!(pContext && pszUri && pbstrNewPrefix))
- {
- return E_INVALIDARG;
- }
-
- *pbstrNewPrefix = NULL;
-
- // Check if the preferred prefix exists...
- //
- // If we got S_OK, the prefix exists, if we got E_*, bail out
- // anyway. Only declare the prefix if we successfully decided
- // it doesn't exist.
-
- if (pszPreferredPrefix)
- {
- INT unused = 0;
-
- if (SUCCEEDED(hr))
- {
- hr = m_pNSManager->pushNodeContext(pContext, TRUE);
- }
-
- if (SUCCEEDED(hr))
- {
-#pragma prefast(suppress:__WARNING_INVALID_PARAM_VALUE_1, "According to MSDN, it is acceptable to pass a NULL buffer to getURI.")
- hr = m_pNSManager->getURI(pszPreferredPrefix, NULL, NULL, &unused);
-
- // If the prefix is already defined, MSXML will return S_FALSE. In that
- // case, we don't want to declare another namespace with the same prefix
- if (S_FALSE != hr)
- {
- pszPreferredPrefix = NULL;
- }
-
- hr = m_pNSManager->popContext();
- }
-
- if (SUCCEEDED(hr) && pszPreferredPrefix)
- {
- *pbstrNewPrefix = SysAllocStringLen(pszPreferredPrefix, (UINT) wcslen(pszPreferredPrefix));
- }
- }
-
- // If we don't have a workable prefix, try to generate a namespace
- // Namespaces are in the form of NSxxxx where the x's are hex digits,
- // and there are sizeof(m_nextPrefix)*2 of them
- if (SUCCEEDED(hr) && !(*pbstrNewPrefix))
- {
- BOOL bFound = TRUE;
- UINT cchLength = (UINT) wcslen(szPrefixChars);
- *pbstrNewPrefix = SysAllocStringLen(NULL, cchLength);
- if (!(*pbstrNewPrefix))
- {
- hr = E_OUTOFMEMORY;
- }
- if (SUCCEEDED(hr))
- {
- do
- {
- INT unused = 0;
-
- // We're really unlikely to hit this. If we do we probably
- // have bigger problems. but put a reasonable cap on the
- // generated namespaces anyway.
- if (((UINT)m_dwNextIndex) >= (UINT)0xFFFF)
- {
- // We could reset the counter here, but it's very unlikely to
- // help matters, and could end up costing tons of CPU time if
- // caller ignored the error or retried.
- hr = E_FAIL;
- }
-
- if (SUCCEEDED(hr))
- {
- // now fill in the real value.
- hr = StringCchPrintf(*pbstrNewPrefix, cchLength+1, szPrefixPrintfPattern, (INT)m_dwNextIndex);
- }
-
- if (SUCCEEDED(hr))
- {
- // look up the URI associated with the prefix.
-#pragma prefast(suppress:__WARNING_INVALID_PARAM_VALUE_1, "According to MSDN, it is acceptable to pass a NULL buffer to getURI.")
- bFound = (S_OK == m_pNSManager->getURI(*pbstrNewPrefix, pContext, NULL, &unused));
- }
-
- m_dwNextIndex++;
-
- } while(SUCCEEDED(hr) && bFound);
-
- if (bFound)
- {
- SysFreeString(*pbstrNewPrefix);
- *pbstrNewPrefix = NULL;
- }
- }
- }
-
- if (SUCCEEDED(hr) && *pbstrNewPrefix)
- {
- // We'll always put declarations at the root
- if (SUCCEEDED(hr))
- {
- // Create the namespace declaration string
- UINT cchDeclLength = (UINT)(wcslen(L"xmlns:") + wcslen(*pbstrNewPrefix));
-
- BSTR bstrDecl = SysAllocStringLen(NULL, cchDeclLength);
- if (!bstrDecl)
- {
- hr = E_OUTOFMEMORY;
- }
-
- // Add the new declaration to the root of the document. This is important because
- // we really don't want to re-declare the namespace at every element. Just starts
- // to look really messy, and adds a lot of bloat.
- if (SUCCEEDED(hr))
- {
- hr = StringCchPrintf(bstrDecl, cchDeclLength+1, L"xmlns:%s", *pbstrNewPrefix);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = CreateXMLAttribute(m_pRootElement, bstrDecl, L"", pszUri);
- }
-
- SysFreeString(bstrDecl);
- bstrDecl = NULL;
-
- // Explicitly let the namespace manager know about our prefix
-
- if (SUCCEEDED(hr))
- {
- hr = m_pNSManager->declarePrefix(*pbstrNewPrefix, pszUri);
- }
- }
- }
-
- if (FAILED(hr))
- {
- SysFreeString(*pbstrNewPrefix);
- *pbstrNewPrefix = NULL;
- }
-
- return hr;
-}
-
-/*++
-Routine Name:
- DeleteFeatureNode
-Routine Description:
-
- Deletes given input Feature node and all its children from DOM tree
-
-Arguments:
-
- pParent - Parent node of the XML DOM node to be deleted
- pElement - XML DOM node to be deleted
-
-Return Value:
- HRESULT Completion status code
- S_OK - On Success
- E_* - On failure
---*/
-HRESULT
-OEMPTXMLHandler::DeleteFeatureNode(
- _In_opt_ IXMLDOMNode *pParent,
- _In_ IXMLDOMNode *pElement
- )
-{
- HRESULT hr = S_OK;
-
- IXMLDOMNode *pRemovedElement = NULL;
-
- if (!pElement)
- {
- return E_INVALIDARG;
- }
-
- //
- // if no parent node specified assume root of DOM tree as parent
- //
-
- if (!pParent)
- {
- pParent = m_pRootElement;
- }
-
- //
- // MSXML function removeChild removes the given child of the XML
- // element and all its children, even the Attribute nodes defined
- // for given element node if any are removed. Hence we do not need
- // to worry about recursively removing all the children of the
- // given node before removing it
- //
-
- hr = pParent->removeChild(pElement, &pRemovedElement);
-
- if (pRemovedElement)
- {
- pRemovedElement->Release();
- }
-
- return hr ;
-}