diff options
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.cxx | 1612 |
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 ; -} |
