cfgldr.cpp revision 3e04f45aeb634f1256d0510780bf77d4fdefd926
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * CFGLDR - Configuration Loader
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync * Copyright (C) 2006-2007 innotek GmbH
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License as published by the Free Software Foundation,
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* Define STANDALONE_TEST for making a executable that
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * will load and parse a XML file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// #define STANDALONE_TEST
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @page pg_cfgldr CFGLDR - The Configuration Loader
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * The configuration loader loads and keeps the configuration of VBox
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * session. It will be used by VBox components to retrieve configuration
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * values at startup and to change values if necessary.
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * When VBox is started, it must call CFGLDRLoad to load global
f091ce66ee934d599f16056078a9a76d7286b959vboxsync * VBox configuration and then VM configuration.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Handles then used by VBox components to retrieve configuration
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * values. Components must query their values at startup.
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * Configuration values can be changed only by respective
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * component and the component must call CFGLDRSet*, to change the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * value in configuration file.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Values are accessed only by name. It is important for components to
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * use CFGLDRQuery* only at startup for performance reason.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * All CFGLDR* functions that take a CFGHANDLE or CFGNODE as their first
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * argument return the VERR_INVALID_HANDLE status code if the argument is
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * null handle (i.e. its value is zero).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/// @todo (dmik) until RTTimeImplode and friends are done
953292a637f7ecfbb7340914e718919c84464f54vboxsync#include <xercesc/framework/LocalFileFormatTarget.hpp>
b14c09e8af60e4d1ba4da27da03cbd175617f298vboxsync#include <xalanc/XalanTransformer/XalanTransformer.hpp>
953292a637f7ecfbb7340914e718919c84464f54vboxsync#include <xalanc/XalanTransformer/XercesDOMWrapperParsedSource.hpp>
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync#include <xalanc/XercesParserLiaison/XercesParserLiaison.hpp>
953292a637f7ecfbb7340914e718919c84464f54vboxsync#include <xalanc/XercesParserLiaison/XercesDOMSupport.hpp>
953292a637f7ecfbb7340914e718919c84464f54vboxsync#include <xalanc/XercesParserLiaison/FormatterToXercesDOM.hpp>
953292a637f7ecfbb7340914e718919c84464f54vboxsync// generated file
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync#endif // VBOX_XML_XSLT
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync// Little hack so we don't have to include the COM stuff
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync// Note that those defines need to be made before we include
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsync// cfgldr.h so that the prototypes can be compiled.
953292a637f7ecfbb7340914e718919c84464f54vboxsync#define OLECHAR wchar_t
953292a637f7ecfbb7340914e718919c84464f54vboxsync#define BSTR void*
c628ff667b222f0e2f3b0b2883cebe34fce370f0vboxsyncextern "C" BSTR __stdcall SysAllocString(const OLECHAR* sz);
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync////////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Converts a string of hex digits to memory bytes.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param puszValue String of hex digits to convert.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * @param pvValue Where to store converted bytes.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * @param cbValue Size of the @a pvValue array.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pcbValue Where to store the actual number of stored bytes.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * @return IPRT status code.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsyncint wstr_to_bin (PCRTUTF16 puszValue, void *pvValue, unsigned cbValue, unsigned *pcbValue)
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync unsigned count = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (b == 0xFF)
ce666b71b4eb6477625b0057689a08aaa7c11b64vboxsync /* it was not a valid hex digit */
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync if (b == 0xFF)
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync /* it was not a valid hex digit */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Converts memory bytes to a null-terminated string of hex values.
ce666b71b4eb6477625b0057689a08aaa7c11b64vboxsync * @param pvValue Memory array to convert.
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync * @param cbValue Number of bytes in the @a pvValue array.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param puszValue Where to store the pointer to the resulting string.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * On success, this string should be freed using RTUtf16Free().
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return IPRT status code.
fa92c704624def98d3c4aca86d65182effb98e04vboxsyncstatic int bin_to_wstr (const void *pvValue, unsigned cbValue, PRTUTF16 *puszValue)
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync /* each byte will produce two hex digits and there will be nul
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * terminator */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *puszValue = (PRTUTF16) RTMemTmpAlloc (sizeof (RTUTF16) * (cbValue * 2 + 1));
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync unsigned i = 0;
8b43c87d70eb66ea6a484c18d7c23f2bc733e134vboxsync////////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync friend class CfgLoader;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync virtual ~CfgNode ();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int resolve (DOMNode *root, const char *pszName, unsigned uIndex, unsigned flags);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int getValueString (const char *pszName, PRTUTF16 *ppwszValue);
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync int setValueString (const char *pszName, PRTUTF16 pwszValue);
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync int CreateChildNode (const char *pszName, CfgNode **ppnode);
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync int AppendChildNode (const char *pszName, CfgNode **ppnode);
940dbfa4936f2e3966e9e874c4886709f0c75b44vboxsync int GetChild (const char *pszName, unsigned uIndex, CfgNode **ppnode);
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync int CountChildren (const char *pszChildName, unsigned *pCount);
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync int QueryUInt32 (const char *pszName, uint32_t *pulValue);
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync int SetUInt32 (const char *pszName, uint32_t ulValue, unsigned int uiBase = 0);
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync int QueryUInt64 (const char *pszName, uint64_t *pullValue);
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync int SetUInt64 (const char *pszName, uint64_t ullValue, unsigned int uiBase = 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int QueryInt32 (const char *pszName, int32_t *plValue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int SetInt32 (const char *pszName, int32_t lValue, unsigned int uiBase = 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int QueryInt64 (const char *pszName, int64_t *pllValue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int SetInt64 (const char *pszName, int64_t llValue, unsigned int uiBase = 0);
ada08ea58e7613c10d4c40669fd4fb955324bfdfvboxsync int QueryUInt16 (const char *pszName, uint16_t *puhValue);
2afbe132eb7931e0125141eabe3a48e08f1ffab5vboxsync int SetUInt16 (const char *pszName, uint16_t uhValue, unsigned int uiBase = 0);
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync int QueryBin (const char *pszName, void *pvValue, unsigned cbValue, unsigned *pcbValue);
ada08ea58e7613c10d4c40669fd4fb955324bfdfvboxsync int SetBin (const char *pszName, const void *pvValue, unsigned cbValue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int QueryString (const char *pszName, void **pValue, unsigned cbValue, unsigned *pcbValue, bool returnUtf16);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int SetString (const char *pszName, const char *pszValue, unsigned cbValue, bool isUtf16);
ce666b71b4eb6477625b0057689a08aaa7c11b64vboxsync int QueryBool (const char *pszName, bool *pfValue);
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync// CfgLoader
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync////////////////////////////////////////////////////////////////////////////////
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync friend class CfgNode;
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync RTFILE hOriginalFileHandle; /** r=bird: this is supposed to mean 'handle to the orignal file handle'? The name is
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * overloaded with too many 'handles'... That goes for those hFileHandle parameters too.
c3ad1c4d80999dbb6c9c3e6ff44a35f70566c306vboxsync * hOriginalFile / FileOriginal and hFile / File should do by a long way. */
c3ad1c4d80999dbb6c9c3e6ff44a35f70566c306vboxsync int getNode (DOMNode *prootnode, const char *pszName, unsigned uIndex, CfgNode **ppnode, unsigned flags);
c3ad1c4d80999dbb6c9c3e6ff44a35f70566c306vboxsync DOMDocument *Document(void) { return static_cast<DOMDocument *>(root); };
c3ad1c4d80999dbb6c9c3e6ff44a35f70566c306vboxsync int Load (const char *pszFileName, RTFILE hFileHandle,
c3ad1c4d80999dbb6c9c3e6ff44a35f70566c306vboxsync const char *pszExternalSchemaLocation, bool bDoNamespaces,
c3ad1c4d80999dbb6c9c3e6ff44a35f70566c306vboxsync int Save (const char *pszFilename, RTFILE hFileHandle,
a1d83f29ade4c8f9fe95fc75d3fb2642f36081c1vboxsync int CreateNode (const char *pszName, CfgNode **ppnode);
a1d83f29ade4c8f9fe95fc75d3fb2642f36081c1vboxsync int GetNode (const char *pszName, unsigned uIndex, CfgNode **ppnode);
a1d83f29ade4c8f9fe95fc75d3fb2642f36081c1vboxsync// VBoxWriterFilter
a1d83f29ade4c8f9fe95fc75d3fb2642f36081c1vboxsync////////////////////////////////////////////////////////////////////////////////
f091ce66ee934d599f16056078a9a76d7286b959vboxsync VBoxWriterFilter (unsigned long whatToShow = DOMNodeFilter::SHOW_ALL);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync virtual unsigned long getWhatToShow () const { return fWhatToShow; };
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync virtual void setWhatToShow (unsigned long toShow) { fWhatToShow = toShow; };
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync unsigned long fWhatToShow;
953292a637f7ecfbb7340914e718919c84464f54vboxsyncVBoxWriterFilter::VBoxWriterFilter(unsigned long whatToShow)
8b43c87d70eb66ea6a484c18d7c23f2bc733e134vboxsyncshort VBoxWriterFilter::acceptNode(const DOMNode* node) const
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* Reject empty nodes */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Accept the node because it contains non space characters */
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync// CfgLdrInputSource
46ae097c942b4a2d5038d9593e312856238da75fvboxsync////////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * A wrapper around RTFILE or a char buffer that acts like a DOMInputSource
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * and therefore can be with DOMBuilder instances.
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync CfgLdrInputSource (PCFGLDRENTITY pcEntity, const char *pcszSystemId);
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync // Functions introduced in DOM Level 3
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync const XMLCh *getSystemId () const { return (const XMLCh *)m_pwszSystemId; }
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync const XMLCh *getBaseURI () const { return (const XMLCh *)m_pwszBaseURI; }
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync void setEncoding (const XMLCh *const /* encodingStr */)
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync void setPublicId (const XMLCh *const /* publicId */)
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync void setSystemId (const XMLCh *const /* systemId */)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // Non-standard Extension
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void setIssueFatalErrorIfNotFound (const bool /* flag */) {}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool getIssueFatalErrorIfNotFound() const { return true; }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync class FileHandleInputStream : public BinInputStream
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unsigned int curPos() const;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unsigned int readBytes (XMLByte *const toFill, const unsigned int maxToRead);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncCfgLdrInputSource::CfgLdrInputSource (PCFGLDRENTITY pcEntity,
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync const char *pcszSystemId) :
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Assert (pcEntity && pcEntity->enmType != CFGLDRENTITYTYPE_INVALID);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync // make a copy of the entity descriptor
1f67f03c498fb10dfaa104a3698a1e149b7e9eb5vboxsync int rc = RTStrToUtf16 (pcszSystemId, &m_pwszSystemId);
395ac8a20a012656020c61a3975493a65fee0e77vboxsyncBinInputStream *CfgLdrInputSource::makeStream() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync stream = new FileHandleInputStream (m_entity.u.handle.hFile);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // puchBuf is neither copied nor destructed by BinMemInputStream
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync stream = new BinMemInputStream (m_entity.u.memory.puchBuf,
10eaaac806009b8336cc5d746fe5072f6c9f58c0vboxsync AssertMsgFailed (("Invalid resolver entity type!\n"));
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsyncCfgLdrInputSource::FileHandleInputStream::FileHandleInputStream (RTFILE hFileHandle) :
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsyncunsigned int CfgLdrInputSource::FileHandleInputStream::curPos() const
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync AssertMsg (!(m_cbPos >> 32), ("m_cbPos exceeds 32 bits (%16Xll)\n", m_cbPos));
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync return (unsigned int)m_cbPos;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncunsigned int CfgLdrInputSource::FileHandleInputStream::readBytes (
0c5d6027e582baa247e987e184f93d44623e7443vboxsync XMLByte *const toFill, const unsigned int maxToRead
0c5d6027e582baa247e987e184f93d44623e7443vboxsync /// @todo (dmik) trhow the appropriate exceptions if we fail to write
0c5d6027e582baa247e987e184f93d44623e7443vboxsync // memorize the current position
0c5d6027e582baa247e987e184f93d44623e7443vboxsync uint64_t cbOriginalPos = RTFileTell (m_hFileHandle);
0c5d6027e582baa247e987e184f93d44623e7443vboxsync // set the new position
0c5d6027e582baa247e987e184f93d44623e7443vboxsync rc = RTFileSeek (m_hFileHandle, m_cbPos, RTFILE_SEEK_BEGIN, NULL);
0c5d6027e582baa247e987e184f93d44623e7443vboxsync // read from the file
0c5d6027e582baa247e987e184f93d44623e7443vboxsync rc = RTFileRead (m_hFileHandle, toFill, maxToRead, &cbRead);
0c5d6027e582baa247e987e184f93d44623e7443vboxsync // adjust the private position
ae44e939c3ecbfce87a6666b3e44972ae4467acavboxsync // restore the current position
ae44e939c3ecbfce87a6666b3e44972ae4467acavboxsync rc = RTFileSeek (m_hFileHandle, cbOriginalPos, RTFILE_SEEK_BEGIN, NULL);
ae44e939c3ecbfce87a6666b3e44972ae4467acavboxsync return (unsigned int)cbRead;
ae44e939c3ecbfce87a6666b3e44972ae4467acavboxsync// CfgLdrFormatTarget
ae44e939c3ecbfce87a6666b3e44972ae4467acavboxsync////////////////////////////////////////////////////////////////////////////////
ae44e939c3ecbfce87a6666b3e44972ae4467acavboxsync // virtual XMLFormatTarget methods
ae44e939c3ecbfce87a6666b3e44972ae4467acavboxsync void writeChars (const XMLByte *const toWrite, const unsigned int count,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncCfgLdrFormatTarget::CfgLdrFormatTarget (PCFGLDRENTITY pcEntity)
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync Assert (pcEntity && pcEntity->enmType != CFGLDRENTITYTYPE_INVALID);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // make a copy of the entity descriptor
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync // start writting from the beginning
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTFileSeek (m_entity.u.handle.hFile, 0, RTFILE_SEEK_BEGIN, NULL);
0c5d6027e582baa247e987e184f93d44623e7443vboxsync // truncate the file upto the size actually written
ae44e939c3ecbfce87a6666b3e44972ae4467acavboxsync uint64_t cbPos = RTFileTell (m_entity.u.handle.hFile);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync rc = RTFileSetSize (m_entity.u.handle.hFile, cbPos);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync // reset the position to he beginning
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync rc = RTFileSeek (m_entity.u.handle.hFile, 0, RTFILE_SEEK_BEGIN, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid CfgLdrFormatTarget::writeChars (const XMLByte *const toWrite,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const unsigned int count,
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync /// @todo (dmik) trhow the appropriate exceptions if we fail to write
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTFileWrite (m_entity.u.handle.hFile, toWrite, count, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// CfgLdrEntityResolver
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync////////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * A wrapper around FNCFGLDRENTITYRESOLVER callback that acts like a
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * DOMEntityResolver and therefore can be used with DOMBuilder instances.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncclass CfgLdrEntityResolver : public DOMEntityResolver
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync CfgLdrEntityResolver (PFNCFGLDRENTITYRESOLVER pfnEntityResolver) :
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync // Functions introduced in DOM Level 2
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync DOMInputSource *resolveEntity (const XMLCh *const publicId,
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncDOMInputSource *CfgLdrEntityResolver::resolveEntity (const XMLCh *const publicId,
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync rc = m_pfnEntityResolver (pszPublicId, pszSystemId, pszBaseURI,
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync source = new CfgLdrInputSource (&entity, pszSystemId);
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync// CfgLdrErrorHandler
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync////////////////////////////////////////////////////////////////////////////////
f1f55b6ac890efaabca0ff940f58aa8df1dc84c8vboxsync * An error handler that accumulates all error messages in a single UTF-8 string.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync /** Transfers ownership of the string to the caller and resets the handler */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // Functions introduced in DOM Level 3
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // Xalan ProblemListener interface
ce666b71b4eb6477625b0057689a08aaa7c11b64vboxsync void problem (eProblemSource where, eClassification classification,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const XalanNode *sourceNode, const ElemTemplateElement *styleNode,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const XalanDOMString &msg, const XalanDOMChar *uri,
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncbool CfgLdrErrorHandler::handleError (const DOMError &domError)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync case DOMError::DOM_SEVERITY_WARNING: pszSeverity = "WARNING: ";
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync case DOMError::DOM_SEVERITY_ERROR: pszSeverity = "ERROR: ";
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync case DOMError::DOM_SEVERITY_FATAL_ERROR: pszSeverity = "FATAL ERROR: ";
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync const DOMLocator *pLocation = domError.getLocation();
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync static const char Location[] = "\nLocation: '%s', line %d, column %d";
11923fc977be1686f5428c3e790c04d0701a074cvboxsync pszLocation = (char *) RTMemTmpAllocZ (cbLocation);
cce0c6096dee0c5353bb74431dc47b05f87a1c6dvboxsync pLocation->getLineNumber(), pLocation->getColumnNumber());
11923fc977be1686f5428c3e790c04d0701a074cvboxsync LogFlow (("CfgLdrErrorHandler::handleError():\n %s%ls%s\n",
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync size_t cbNewBuf = (m_pszBuf ? strlen (m_pszBuf) : 0) +
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync char *pszNewBuf = (char *) RTMemTmpAllocZ (cbNewBuf + 2 /* \n + \0 */);
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync // fail on any error when possible
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync return false;
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsyncvoid CfgLdrErrorHandler::problem (eProblemSource where, eClassification classification,
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync const XalanNode *sourceNode, const ElemTemplateElement *styleNode,
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync const XalanDOMString &msg, const XalanDOMChar *uri,
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync LogFlow (("CfgLdrErrorHandler::problem():\n %s%ls\n", pszClass, msg.c_str()));
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync size_t cbNewBuf = (m_pszBuf ? strlen (m_pszBuf) : 0) +
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsync char *pszNewBuf = (char *) RTMemTmpAllocZ (cbNewBuf + 2 /* \n + \0 */);
5bc12adcd2551b1a206b40f9ad976fed75bea9a0vboxsync////////////////////////////////////////////////////////////////////////////////
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsyncstatic int xmlInitialized = 0;
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsyncstatic int initXML (void)
06dc6eb95cf33b2b83f0d07c602d1ca20a575663vboxsyncstatic void terminateXML (void)
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync/* CfgLoader implementation */
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync /* Configuration was parsed from a file.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * Parser owns root and will delete root.
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync /* This is new, just created configuration.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * root is new object created by DOMImplementation::createDocument
377f1df8d6ec248927bcdf0efabf87ab55c4a615vboxsync * We have to delete root.
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsyncint CfgLoader::Load (const char *pszFileName, RTFILE hFileHandle,
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsync const char *pszExternalSchemaLocation, bool bDoNamespaces,
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsync static const XMLCh LS[] = { chLatin_L, chLatin_S, chNull };
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsync DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation (LS);
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsync // member variables allocated here (builder, pwszOriginalFilename) are not
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsync // freed in case of error because CFGLDRLoad() that calls this method will
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsync // delete this instance (and all members) if we return a failure from here
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsync builder = static_cast <DOMImplementationLS *> (impl)->
766956791b9a42fc91ba6f8bd8be7f6a6f7ba092vboxsync createDOMBuilder (DOMImplementationLS::MODE_SYNCHRONOUS, 0);
return VERR_NOT_SUPPORTED;
if (ppszErrorMessage)
return VERR_NOT_SUPPORTED;
if (bDoNamespaces)
return VERR_NOT_SUPPORTED;
return VERR_NOT_SUPPORTED;
return VERR_NOT_SUPPORTED;
return VERR_NOT_SUPPORTED;
return rc;
if (bDoNamespaces)
return rc;
if (ppszErrorMessage)
return rc;
char **ppszErrorMessage)
return VERR_INVALID_PARAMETER;
if (!impl)
return VERR_NOT_SUPPORTED;
if (!writer)
return VERR_NOT_SUPPORTED;
if (ppszErrorMessage)
#ifdef VBOX_XML_WRITER_FILTER
if (pszFilename)
if (pwszFilename)
if (ppszErrorMessage)
return rc;
#ifdef VBOX_XML_XSLT
char **ppszErrorMessage)
if (ppszErrorMessage)
if (xrc)
if (builder)
builder = 0;
root = 0;
else if (root)
root = 0;
NULL, false);
if (xmlns[0] == 0 ||
if (ppszErrorMessage)
return rc;
if (!xmlInitialized)
return VERR_NOT_SUPPORTED;
if (impl)
if (!root)
return rc;
delete pcfg;
return rc;
int CfgLoader::getNode (DOMNode *prootnode, const char *pszName, unsigned uIndex, CfgNode **ppnode, unsigned flags)
if (!pnode)
else if (!prootnode)
if (pfirstnode)
if (pnode)
delete pnode;
return rc;
delete pnode;
return rc;
return rc;
if (!root)
return VERR_PATH_NOT_FOUND;
if (!pszName)
return VERR_INVALID_PARAMETER;
bool lastComponent = false;
lastComponent = true;
if (lastComponent)
if (uIndex == 0)
uIndex--;
if (!first)
if (first)
if (child)
if (!child)
if (lastComponent)
if (*puszComponent)
if (!*puszComponent)
lastComponent = true;
return rc;
if (pszChildName)
unsigned count = 0;
count++;
count++;
if (pwszChildName)
return rc;
return child;
if (!pszName)
if (ptext)
if (attr)
if (!pwszValue)
return rc;
if (!pszName)
if (poldtext)
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
else if (!pvValue)
return rc;
return rc;
int CfgNode::QueryString (const char *pszName, void **pValue, unsigned cbValue, unsigned *pcbValue, bool returnUtf16)
if (pcbValue)
*pcbValue = 0;
if (returnUtf16)
*pcbValue = l;
if (l > cbValue)
else if (!*pValue)
return rc;
if (isUtf16)
if (!isUtf16)
return rc;
*pfValue = true;
*pfValue = false;
return rc;
return rc;
if (!phcfg)
return VERR_INVALID_POINTER;
if (!pcfgldr)
return VERR_NO_MEMORY;
delete pcfgldr;
return rc;
char **ppszErrorMessage)
return VERR_INVALID_POINTER;
if (!pcfgldr)
return VERR_NO_MEMORY;
delete pcfgldr;
return rc;
if (!hcfg)
return VERR_INVALID_HANDLE;
return VINF_SUCCESS;
char **ppszErrorMessage)
if (!hcfg)
return VERR_INVALID_HANDLE;
char **ppszErrorMessage)
if (!hcfg)
return VERR_INVALID_HANDLE;
if (!pszFilename)
return VERR_INVALID_POINTER;
const char *pszTemlateLocation,
char **ppszErrorMessage)
#ifdef VBOX_XML_XSLT
if (!hcfg)
return VERR_INVALID_HANDLE;
if (!pszTemlateLocation)
return VERR_INVALID_POINTER;
return VERR_NOT_SUPPORTED;
CFGLDRR3DECL(int) CFGLDRGetNode(CFGHANDLE hcfg, const char *pszName, unsigned uIndex, CFGNODE *phnode)
if (!hcfg)
return VERR_INVALID_HANDLE;
if (!phnode)
return VERR_INVALID_POINTER;
CFGLDRR3DECL(int) CFGLDRGetChildNode(CFGNODE hparent, const char *pszName, unsigned uIndex, CFGNODE *phnode)
if (!hparent)
return VERR_INVALID_HANDLE;
if (!phnode)
return VERR_INVALID_POINTER;
if (!hcfg)
return VERR_INVALID_HANDLE;
return VERR_INVALID_POINTER;
if (!hparent)
return VERR_INVALID_HANDLE;
return VERR_INVALID_POINTER;
if (!hparent)
return VERR_INVALID_HANDLE;
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pCount)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pulValue)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
CFGLDRR3DECL(int) CFGLDRSetUInt32Ex(CFGNODE hnode, const char *pszName, uint32_t ulValue, unsigned int uiBase)
if (!hnode)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pullValue)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
CFGLDRR3DECL(int) CFGLDRSetUInt64Ex(CFGNODE hnode, const char *pszName, uint64_t ullValue, unsigned int uiBase)
if (!hnode)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
CFGLDRR3DECL(int) CFGLDRSetInt32Ex(CFGNODE hnode, const char *pszName, int32_t lValue, unsigned int uiBase)
if (!hnode)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
CFGLDRR3DECL(int) CFGLDRSetInt64Ex(CFGNODE hnode, const char *pszName, int64_t llValue, unsigned int uiBase)
if (!hnode)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!puhValue)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
CFGLDRR3DECL(int) CFGLDRSetUInt16Ex(CFGNODE hnode, const char *pszName, uint16_t uhValue, unsigned int uiBase)
if (!hnode)
return VERR_INVALID_HANDLE;
CFGLDRR3DECL(int) CFGLDRQueryBin(CFGNODE hnode, const char *pszName, void *pvValue, unsigned cbValue, unsigned *pcbValue)
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pcbValue)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pvValue)
return VERR_INVALID_POINTER;
CFGLDRR3DECL(int) CFGLDRQueryString(CFGNODE hnode, const char *pszName, char *pszValue, unsigned cbValue, unsigned *pcbValue)
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pcbValue)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!ppwszValue)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pUUID)
return VERR_INVALID_POINTER;
unsigned size;
int rc;
delete[] uuidUtf8;
return rc;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pUuid)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pszValue)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!bstrValue)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pfValue)
return VERR_INVALID_POINTER;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pi64Value)
return VERR_INVALID_POINTER;
unsigned size = 0;
return rc;
int isdst = 0;
delete[] pszBuf;
delete[] pszValue;
return rc;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!ptm)
return VERR_PARSE_ERROR;
if (!hnode)
return VERR_INVALID_HANDLE;
if (!pszName)
return VERR_INVALID_POINTER;
if (!initXML ())
return rc;
terminateXML ();
#ifdef STANDALONE_TEST
unsigned count = 0;
goto l_exit_0;
goto l_exit_0;
goto l_exit_0;
goto l_exit_1;
goto l_exit_1;
goto l_exit_2;
for (i = 0; i < count; i++)
unsigned cbValue;
goto l_exit_2;
unsigned dummy;
goto l_exit_2;
return rc;