cfgldr.cpp revision 0010ccca43c2554000fdd0572c7b9cf5ad17ac91
/** @file
*
* CFGLDR - Configuration Loader
*/
/*
* Copyright (C) 2006-2007 innotek GmbH
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License as published by the Free Software Foundation,
* in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
* distribution. VirtualBox OSE is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY of any kind.
*
* If you received this file as part of a commercial VirtualBox
* distribution, then only the terms of your commercial VirtualBox
* license agreement apply instead of the previous paragraph.
*/
/* Define STANDALONE_TEST for making a executable that
* will load and parse a XML file
*/
// #define STANDALONE_TEST
/** @page pg_cfgldr CFGLDR - The Configuration Loader
*
* The configuration loader loads and keeps the configuration of VBox
* session. It will be used by VBox components to retrieve configuration
* values at startup and to change values if necessary.
*
* When VBox is started, it must call CFGLDRLoad to load global
* VBox configuration and then VM configuration.
*
* Handles then used by VBox components to retrieve configuration
* values. Components must query their values at startup.
* Configuration values can be changed only by respective
* component and the component must call CFGLDRSet*, to change the
* value in configuration file.
*
* Values are accessed only by name. It is important for components to
* use CFGLDRQuery* only at startup for performance reason.
*
* All CFGLDR* functions that take a CFGHANDLE or CFGNODE as their first
* argument return the VERR_INVALID_HANDLE status code if the argument is
* null handle (i.e. its value is zero).
*/
#define VBOX_XML_WRITER_FILTER
#define VBOX_XML_XSLT
#define _CRT_SECURE_NO_DEPRECATE
#define LOG_GROUP LOG_GROUP_MAIN
/// @todo (dmik) until RTTimeImplode and friends are done
#include <time.h>
#ifdef VBOX_XML_WRITER_FILTER
#endif
#ifdef VBOX_XML_XSLT
// generated file
#include "SettingsConverter_xsl.h"
#endif // VBOX_XML_XSLT
// Little hack so we don't have to include the COM stuff
// Note that those defines need to be made before we include
// cfgldr.h so that the prototypes can be compiled.
#ifndef BSTR
#define OLECHAR wchar_t
#define BSTR void*
#if defined(RT_OS_WINDOWS)
#else
#endif
#endif
#include "Logging.h"
#include "cfgldrhlp.h"
#include <string.h>
#include <stdio.h> // for sscanf
#ifdef STANDALONE_TEST
# include <stdlib.h>
#endif
class CfgNode
{
private:
friend class CfgLoader;
virtual ~CfgNode ();
DOMNode *findChildText (void);
public:
enum {
fSearch = 0,
fCreateIfNotExists = 1,
fAppend = 2
};
int QueryString (const char *pszName, void **pValue, unsigned cbValue, unsigned *pcbValue, bool returnUtf16);
int DeleteAttribute (const char *pszName);
};
class CfgLoader
{
private:
friend class CfgNode;
RTFILE hOriginalFileHandle; /** r=bird: this is supposed to mean 'handle to the orignal file handle'? The name is
* overloaded with too many 'handles'... That goes for those hFileHandle parameters too.
* hOriginalFile / FileOriginal and hFile / File should do by a long way. */
int getNode (DOMNode *prootnode, const char *pszName, unsigned uIndex, CfgNode **ppnode, unsigned flags);
public:
CfgLoader ();
virtual ~CfgLoader ();
const char *pszExternalSchemaLocation, bool bDoNamespaces,
char **ppszErrorMessage);
char **ppszErrorMessage);
int Create ();
#ifdef VBOX_XML_XSLT
int Transform (const char *pszTemlateLocation,
char **ppszErrorMessage);
#endif
};
#ifdef VBOX_XML_WRITER_FILTER
class VBoxWriterFilter : public DOMWriterFilter
{
public:
~VBoxWriterFilter () {};
virtual short acceptNode (const DOMNode*) const;
virtual unsigned long getWhatToShow () const { return fWhatToShow; };
private:
unsigned long fWhatToShow;
};
:
{
}
{
switch (node->getNodeType())
{
{
/* Reject empty nodes */
if (pxmlch)
{
{
)
{
pxmlch++;
continue;
}
break;
}
{
/* Accept the node because it contains non space characters */
return DOMNodeFilter::FILTER_ACCEPT;
}
}
return DOMNodeFilter::FILTER_REJECT;
}
}
return DOMNodeFilter::FILTER_ACCEPT;
}
#endif
// CfgLdrInputSource
////////////////////////////////////////////////////////////////////////////////
/**
* A wrapper around RTFILE or a char buffer that acts like a DOMInputSource
* and therefore can be with DOMBuilder instances.
*/
class CfgLdrInputSource : public DOMInputSource
{
public:
virtual ~CfgLdrInputSource() { release(); }
// Functions introduced in DOM Level 3
{ AssertMsgFailed (("Not implemented!\n")); }
{ AssertMsgFailed (("Not implemented!\n")); }
{ AssertMsgFailed (("Not implemented!\n")); }
{ AssertMsgFailed (("Not implemented!\n")); }
// Non-standard Extension
BinInputStream *makeStream() const;
void setIssueFatalErrorIfNotFound (const bool /* flag */) {}
bool getIssueFatalErrorIfNotFound() const { return true; }
void release();
private:
class FileHandleInputStream : public BinInputStream
{
public:
unsigned int curPos() const;
private:
};
void init (const char *pcszSystemId);
};
const char *pcszSystemId) :
{
// make a copy of the entity descriptor
char *pszBaseURI = NULL;
Assert (pszBaseURI);
}
void CfgLdrInputSource::release()
{
{
case CFGLDRENTITYTYPE_HANDLE:
break;
case CFGLDRENTITYTYPE_MEMORY:
break;
default:
break;
};
if (m_pwszBaseURI)
{
}
if (m_pwszSystemId)
{
}
}
{
{
case CFGLDRENTITYTYPE_HANDLE:
break;
case CFGLDRENTITYTYPE_MEMORY:
// puchBuf is neither copied nor destructed by BinMemInputStream
break;
default:
AssertMsgFailed (("Invalid resolver entity type!\n"));
break;
};
return stream;
}
m_cbPos (0)
{
}
{
return (unsigned int)m_cbPos;
}
)
{
/// @todo (dmik) trhow the appropriate exceptions if we fail to write
int rc;
// memorize the current position
// set the new position
// read from the file
unsigned cbRead = 0;
// adjust the private position
// restore the current position
return cbRead;
}
// CfgLdrFormatTarget
////////////////////////////////////////////////////////////////////////////////
class CfgLdrFormatTarget : public XMLFormatTarget
{
public:
// virtual XMLFormatTarget methods
XMLFormatter *const formatter);
void flush() {}
private:
};
{
// make a copy of the entity descriptor
{
case CFGLDRENTITYTYPE_HANDLE:
int rc;
// start writting from the beginning
break;
case CFGLDRENTITYTYPE_MEMORY:
AssertMsgFailed (("Unsupported entity type!\n"));
break;
default:
break;
};
}
{
{
case CFGLDRENTITYTYPE_HANDLE:
{
int rc;
// truncate the file upto the size actually written
// reset the position to he beginning
break;
}
case CFGLDRENTITYTYPE_MEMORY:
break;
default:
break;
};
}
const unsigned int count,
XMLFormatter *const /* formatter */)
{
/// @todo (dmik) trhow the appropriate exceptions if we fail to write
{
case CFGLDRENTITYTYPE_HANDLE:
int rc;
break;
case CFGLDRENTITYTYPE_MEMORY:
AssertMsgFailed (("Unsupported entity type!\n"));
break;
default:
AssertMsgFailed (("Invalid entity type!\n"));
break;
};
}
// CfgLdrEntityResolver
////////////////////////////////////////////////////////////////////////////////
/**
* A wrapper around FNCFGLDRENTITYRESOLVER callback that acts like a
* DOMEntityResolver and therefore can be used with DOMBuilder instances.
*/
class CfgLdrEntityResolver : public DOMEntityResolver
{
public:
// Functions introduced in DOM Level 2
private:
};
{
if (!m_pfnEntityResolver)
return NULL;
int rc = VINF_SUCCESS;
char *pszPublicId = NULL;
char *pszSystemId = NULL;
char *pszBaseURI = NULL;
if (publicId)
if (VBOX_SUCCESS (rc))
{
if (systemId)
if (VBOX_SUCCESS (rc))
{
if (baseURI)
if (VBOX_SUCCESS (rc))
{
&entity);
if (rc == VINF_SUCCESS)
}
}
}
if (pszBaseURI)
if (pszSystemId)
if (pszPublicId)
return source;
}
// CfgLdrErrorHandler
////////////////////////////////////////////////////////////////////////////////
/**
* An error handler that accumulates all error messages in a single UTF-8 string.
*/
class CfgLdrErrorHandler : public DOMErrorHandler
#ifdef VBOX_XML_XSLT
, public ProblemListener
#endif
{
public:
/** Transfers ownership of the string to the caller and resets the handler */
char *takeErrorMessage() {
return pszBuf;
}
// Functions introduced in DOM Level 3
#ifdef VBOX_XML_XSLT
// Xalan ProblemListener interface
int lineNo, int charOffset);
#endif
private:
char *m_pszBuf;
};
{
}
{
if (m_pszBuf)
}
{
const char *pszSeverity = NULL;
switch (domError.getSeverity())
{
}
char *pszLocation = NULL;
if (pLocation)
{
static const char Location[] = "\nLocation: '%s', line %d, column %d";
10 + 10 + 1 /* line & column & \0 */;
if (pszURI)
}
LogFlow (("CfgLdrErrorHandler::handleError():\n %s%ls%s\n",
if (domError.getMessage())
if (m_pszBuf)
{
}
if (pszSeverity)
if (pszMsg)
if (pszLocation)
if (m_pszBuf)
if (pszLocation)
if (pszMsg)
// fail on any error when possible
return false;
}
#ifdef VBOX_XML_XSLT
int lineNo, int charOffset)
{
switch (classification)
{
}
if (m_pszBuf)
{
}
if (pszClass)
if (pszMsg)
if (m_pszBuf)
if (pszNewBuf)
if (pszMsg)
}
#endif
//
////////////////////////////////////////////////////////////////////////////////
static int xmlInitialized = 0;
static int initXML (void)
{
try
{
}
catch(...)
{
return 0;
}
return (xmlInitialized = 1);
}
static void terminateXML (void)
{
if (xmlInitialized)
{
xmlInitialized = 0;
}
}
/* CfgLoader implementation */
:
pfirstnode (NULL),
{
}
{
if (pwszOriginalFilename)
{
}
if (builder)
{
/* Configuration was parsed from a file.
* Parser owns root and will delete root.
*/
}
else if (root)
{
/* This is new, just created configuration.
* root is new object created by DOMImplementation::createDocument
* We have to delete root.
*/
}
}
const char *pszExternalSchemaLocation, bool bDoNamespaces,
char **ppszErrorMessage)
{
if (!xmlInitialized)
return VERR_NOT_SUPPORTED;
if (root || pwszOriginalFilename)
return VERR_ALREADY_LOADED;
if (!impl)
return VERR_NOT_SUPPORTED;
// note:
// member variables allocated here (builder, pwszOriginalFilename) are not
// freed in case of error because CFGLDRLoad() that calls this method will
// delete this instance (and all members) if we return a failure from here
if (!builder)
return VERR_NOT_SUPPORTED;
int rc = VINF_SUCCESS;
if (ppszErrorMessage)
*ppszErrorMessage = NULL;
// set parser's features
else
return VERR_NOT_SUPPORTED;
if (bDoNamespaces)
{
else
return VERR_NOT_SUPPORTED;
}
{
// set validation related features & properties
else
return VERR_NOT_SUPPORTED;
else
return VERR_NOT_SUPPORTED;
else
return VERR_NOT_SUPPORTED;
if (VBOX_FAILURE (rc))
return rc;
if (bDoNamespaces)
{
// set schema that supports namespaces
}
else
{
// set schema that doesn't support namespaces
}
}
if (VBOX_FAILURE (rc))
return rc;
try
{
if (hFileHandle != NIL_RTFILE)
{
}
else
{
}
}
catch (...)
{
}
if (errorHandler.hasErrors())
{
// this will transfer ownership of the string
if (ppszErrorMessage)
}
return rc;
}
char **ppszErrorMessage)
{
if (!pszFilename && !pwszOriginalFilename &&
{
// was created from scratch
return VERR_INVALID_PARAMETER;
}
if (!impl)
return VERR_NOT_SUPPORTED;
if (!writer)
return VERR_NOT_SUPPORTED;
int rc = VINF_SUCCESS;
if (ppszErrorMessage)
*ppszErrorMessage = NULL;
#ifdef VBOX_XML_WRITER_FILTER
#endif
try
{
{
}
else
{
if (pszFilename)
if (VBOX_SUCCESS (rc))
{
if (pwszFilename)
}
}
}
catch(...)
{
}
if (errorHandler.hasErrors())
{
// this will transfer ownership of the string
if (ppszErrorMessage)
}
return rc;
}
#ifdef VBOX_XML_XSLT
char **ppszErrorMessage)
{
int rc = VINF_SUCCESS;
if (ppszErrorMessage)
*ppszErrorMessage = NULL;
// input stream to read from SettingsConverter_xsl
struct SettingsConverterStream : public XSLTInputSource
{
{
setSystemId (id);
setPublicId (id);
}
BinInputStream *makeStream () const
{
return new BinMemInputStream (g_abSettingsConverter_xsl,
}
};
try
{
// target is the DOM tree
// source is the DOM tree
// stylesheet
if (xrc)
{
}
else
{
// release the builder and the old document, if any
if (builder)
{
builder = 0;
root = 0;
}
else if (root)
{
root = 0;
}
// Xalan 1.9.0 (and 1.10.0) is stupid bacause disregards the
// XSLT specs and ignores the exclude-result-prefixes stylesheet
// attribute, flooding all the elements with stupid xmlns
// specifications. Here we remove them.
NULL, false);
{
continue;
continue;
if (xmlns[0] == 0 ||
{
}
}
}
}
catch (...)
{
}
if (VBOX_FAILURE (rc))
{
// this will transfer ownership of the string
if (ppszErrorMessage)
{
if (xalan.getLastError())
else
}
}
return rc;
}
#endif
{
if (!xmlInitialized)
{
return VERR_NOT_SUPPORTED;
}
int rc = VINF_SUCCESS;
if (impl)
{
// creating an empty doc is a non-standard extension to DOM specs.
// we're using it since we're bound to Xerces anyway.
}
if (!root)
{
}
return rc;
}
{
int rc = VINF_SUCCESS;
while (pcfg->pfirstnode)
{
}
delete pcfg;
return rc;
}
{
}
{
}
int CfgLoader::getNode (DOMNode *prootnode, const char *pszName, unsigned uIndex, CfgNode **ppnode, unsigned flags)
{
int rc = VINF_SUCCESS;
if (!pnode)
{
rc = VERR_NO_MEMORY;
}
else if (!prootnode)
{
}
else
{
}
if (VBOX_SUCCESS(rc))
{
if (pfirstnode)
{
}
pfirstnode = pnode;
}
else
{
if (pnode)
{
delete pnode;
}
}
return rc;
}
/* CfgNode implementation */
:
{
}
{
}
{
int rc = VINF_SUCCESS;
{
}
{
}
else
{
}
delete pnode;
return rc;
}
{
int rc = VINF_SUCCESS;
ReleaseNode (pnode);
return rc;
}
{
static const char *pcszEmptyName = "";
if (!root)
{
return VERR_PATH_NOT_FOUND;
}
if (!pszName)
{
// special case for resolving any child
}
{
return VERR_INVALID_PARAMETER;
}
int rc = VINF_SUCCESS;
if (VBOX_SUCCESS(rc))
{
bool lastComponent = false;
if (lastindex == -1)
{
lastComponent = true;
}
for (;;)
{
{
{
{
{
if (lastComponent)
{
if (uIndex == 0)
{
rc = VINF_SUCCESS;
break;
}
uIndex--;
continue;
}
else
{
if (!first)
{
}
else
{
break;
}
}
}
}
}
}
if (first)
{
if (child)
{
// some element in the path (except the last) has
// siblingswith the same name
break;
}
}
if (!child)
{
{
// Extract the component name to a temporary buffer
try
{
}
catch (...)
{
break;
}
if (lastComponent)
{
rc = VINF_SUCCESS;
break;
}
}
else
{
break;
}
}
if (*puszComponent)
{
}
if (!*puszComponent)
{
break;
}
if (lastindex == -1)
{
lastComponent = true;
}
}
}
return rc;
}
{
}
{
}
{
}
{
int rc = VINF_SUCCESS;
if (pszChildName)
{
}
if (VBOX_SUCCESS(rc))
{
unsigned count = 0;
{
{
if (pwszChildName == NULL)
{
count++;
}
{
count++;
}
}
}
if (pwszChildName)
{
}
}
return rc;
}
{
{
{
break;
}
}
return child;
}
{
int rc = VINF_SUCCESS;
if (!pszName)
{
if (ptext)
{
}
}
else
{
if (VBOX_SUCCESS(rc))
{
if (attr)
{
}
}
}
if (!pwszValue)
{
*ppwszValue = NULL;
}
else
{
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (!pszName)
{
try
{
}
catch (...)
{
}
{
try
{
if (poldtext)
{
}
else
{
}
}
catch (...)
{
}
}
}
else
{
if (VBOX_SUCCESS(rc))
{
try
{
}
catch (...)
{
}
}
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (VBOX_SUCCESS(rc))
{
if (VBOX_SUCCESS(rc))
{
}
}
return rc;
}
{
int rc = VINF_SUCCESS;
char szValue[64];
if (VBOX_SUCCESS (rc))
{
if (VBOX_SUCCESS (rc))
{
}
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (VBOX_SUCCESS(rc))
{
if (VBOX_SUCCESS(rc))
{
}
}
return rc;
}
{
int rc = VINF_SUCCESS;
char szValue[64];
if (VBOX_SUCCESS (rc))
{
if (VBOX_SUCCESS (rc))
{
}
}
return rc;
}
{
if (VBOX_SUCCESS(rc))
{
}
return rc;
}
{
if (VBOX_SUCCESS(rc))
{
}
return rc;
}
{
if (VBOX_SUCCESS(rc))
{
}
return rc;
}
{
if (VBOX_SUCCESS(rc))
{
}
return rc;
}
{
if (VBOX_SUCCESS(rc))
{
}
return rc;
}
{
if (VBOX_SUCCESS(rc))
{
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (VBOX_SUCCESS(rc))
{
{
}
else if (!pvValue)
{
}
else
{
}
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (VBOX_SUCCESS (rc))
{
if (VBOX_SUCCESS (rc))
{
}
}
return rc;
}
int CfgNode::QueryString (const char *pszName, void **pValue, unsigned cbValue, unsigned *pcbValue, bool returnUtf16)
{
int rc = VINF_SUCCESS;
// start with 0 bytes return value
if (pcbValue)
*pcbValue = 0;
if (VBOX_SUCCESS(rc))
{
if (returnUtf16)
{
// make a copy
} else
{
if (VBOX_SUCCESS(rc))
{
*pcbValue = l;
if (l > cbValue)
{
}
else if (!*pValue)
{
}
else
{
}
}
}
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (isUtf16)
else
if (VBOX_SUCCESS (rc))
{
if (!isUtf16)
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (VBOX_SUCCESS (rc))
{
if (VBOX_SUCCESS (rc))
{
*pfValue = true;
*pfValue = false;
else
}
}
return rc;
}
{
}
{
int rc = VINF_SUCCESS;
if (VBOX_SUCCESS (rc))
{
try
{
}
catch (...)
{
}
}
return rc;
}
/* Configuration loader public entry points.
*/
{
if (!phcfg)
{
return VERR_INVALID_POINTER;
}
if (!pcfgldr)
{
return VERR_NO_MEMORY;
}
if (VBOX_SUCCESS(rc))
{
}
else
{
delete pcfgldr;
}
return rc;
}
const char *pszExternalSchemaLocation, bool bDoNamespaces,
char **ppszErrorMessage)
{
if (!phcfg || !pszFileName)
return VERR_INVALID_POINTER;
if (!pcfgldr)
return VERR_NO_MEMORY;
if (VBOX_SUCCESS(rc))
else
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;
}
#else
return VERR_NOT_SUPPORTED;
#endif
}
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;
}
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
if (!pullValue)
{
return VERR_INVALID_POINTER;
}
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
if (!pu16Value)
{
return VERR_INVALID_POINTER;
}
}
{
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;
}
// we need it as UTF8
unsigned size;
int rc;
if (rc == VERR_BUFFER_OVERFLOW)
{
if (VBOX_SUCCESS(rc))
{
// remove the curly brackets
}
delete[] uuidUtf8;
}
return rc;
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
if (!pUuid)
{
return VERR_INVALID_HANDLE;
}
// UUID + curly brackets
strUuid[0] = '{';
}
{
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;
}
// query as UTF8 string
unsigned size = 0;
if (rc != VERR_BUFFER_OVERFLOW)
return rc;
if (VBOX_SUCCESS(rc)) do
{
// Parse xsd:dateTime. The format is:
// '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
// where zzzzzz is: (('+' | '-') hh ':' mm) | 'Z'
{
break;
}
// currently, we accept only the UTC timezone ('Z'),
// ignoring fractional seconds, if present
if (pszBuf[0] == 'Z' ||
{
// start with an error
#if 0
if (RTTimeNormalize(&time))
{
{
rc = VINF_SUCCESS;
}
}
#else
/// @todo (dmik) until RTTimeImplode and friends are done
int isdst = 0;
{
}
// mktime expects local time, but we supply it UTC,
// do a trick to get the right time value
*pi64Value *= 1000;
rc = VINF_SUCCESS;
#endif
}
else
}
while (0);
delete[] pszBuf;
delete[] pszValue;
return rc;
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
#if 0
#else
/// @todo (dmik) until RTTimeImplode and friends are done
if (!ptm)
return VERR_PARSE_ERROR;
#endif
// Store xsd:dateTime. The format is:
// '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
// where zzzzzz is: (('+' | '-') hh ':' mm) | 'Z'
char aszBuf [256];
"%04ld-%02hd-%02hdT%02hd:%02hd:%02hdZ",
#if 0
#else
/// @todo (dmik) until RTTimeImplode and friends are done
#endif
}
{
if (!hnode)
{
return VERR_INVALID_HANDLE;
}
if (!pszName)
{
return VERR_INVALID_POINTER;
}
}
CFGLDRR3DECL(int) CFGLDRInitialize (void)
{
int rc = VINF_SUCCESS;
if (!initXML ())
{
}
return rc;
}
CFGLDRR3DECL(void) CFGLDRShutdown (void)
{
/// @todo delete CfgLoaders
terminateXML ();
}
#ifdef STANDALONE_TEST
{
Log(("Configuration loader standalone test\n"));
unsigned count = 0;
unsigned i;
char *cfgFilename = "vboxcfg.xml";
char *cfgFilenameSaved = "testas.xml";
/*
* Initialize the VBox runtime without loading
* the kernel support driver
*/
if (VBOX_FAILURE(rc))
{
goto l_exit_0;
}
rc = CFGLDRInitialize();
if (VBOX_FAILURE(rc))
{
goto l_exit_0;
}
if (VBOX_FAILURE(rc))
{
goto l_exit_0;
}
if (VBOX_FAILURE(rc))
{
goto l_exit_1;
}
if (VBOX_FAILURE(rc))
{
goto l_exit_1;
}
if (VBOX_FAILURE(rc))
{
goto l_exit_2;
}
for (i = 0; i < count; i++)
{
unsigned cbValue;
char szValue[256];
if (VBOX_FAILURE(rc))
{
goto l_exit_2;
}
unsigned dummy;
if (VBOX_FAILURE(rc))
{
}
if (VBOX_FAILURE(rc))
{
}
// CFGLDRSetUInt64(hchild, "uint64", 0x1973);
if (VBOX_FAILURE(rc))
{
}
if (VBOX_FAILURE(rc))
{
}
}
if (VBOX_FAILURE(rc))
{
goto l_exit_2;
}
if (VBOX_FAILURE(rc))
{
}
if (VBOX_FAILURE(rc))
{
}
Log(("Test completed."));
return rc;
}
#endif