Index: /trunk/src/VBox/VMM/VMMR3/CFGM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CFGM.cpp	(revision 46780)
+++ /trunk/src/VBox/VMM/VMMR3/CFGM.cpp	(revision 46781)
@@ -66,4 +66,5 @@
 #include <VBox/log.h>
 #include <iprt/assert.h>
+#include <iprt/mem.h>
 #include <iprt/param.h>
 #include <iprt/string.h>
@@ -81,5 +82,91 @@
 static int  cfgmR3InsertLeaf(PCFGMNODE pNode, const char *pszName, PCFGMLEAF *ppLeaf);
 static void cfgmR3RemoveLeaf(PCFGMNODE pNode, PCFGMLEAF pLeaf);
-static void cfgmR3FreeValue(PCFGMLEAF pLeaf);
+static void cfgmR3FreeValue(PVM pVM, PCFGMLEAF pLeaf);
+
+
+/**
+ * Allocator wrapper.
+ *
+ * @returns Pointer to the allocated memory, NULL on failure.
+ * @param   pVM                 The VM handle, if tree associated with one.
+ * @param   enmTag              The allocation tag.
+ * @param   cb                  The size of the allocation.
+ */
+static void *cfgmR3MemAlloc(PVM pVM, MMTAG enmTag, size_t cb)
+{
+    if (pVM)
+        return MMR3HeapAlloc(pVM, enmTag, cb);
+    return RTMemAlloc(cb);
+}
+
+
+/**
+ * Free wrapper.
+ *
+ * @returns Pointer to the allocated memory, NULL on failure.
+ * @param   pVM                 The VM handle, if tree associated with one.
+ * @param   pv                  The memory block to free.
+ */
+static void cfgmR3MemFree(PVM pVM, void *pv)
+{
+    if (pVM)
+        MMR3HeapFree(pv);
+    else
+        RTMemFree(pv);
+}
+
+
+/**
+ * String allocator wrapper.
+ *
+ * @returns Pointer to the allocated memory, NULL on failure.
+ * @param   pVM                 The VM handle, if tree associated with one.
+ * @param   enmTag              The allocation tag.
+ * @param   cbString            The size of the allocation, terminator included.
+ */
+static char *cfgmR3StrAlloc(PVM pVM, MMTAG enmTag,  size_t cbString)
+{
+    if (pVM)
+        return (char *)MMR3HeapAlloc(pVM, enmTag, cbString);
+    return (char *)RTStrAlloc(cbString);
+}
+
+
+/**
+ * String free wrapper.
+ *
+ * @returns Pointer to the allocated memory, NULL on failure.
+ * @param   pVM                 The VM handle, if tree associated with one.
+ * @param   pszString           The memory block to free.
+ */
+static void cfgmR3StrFree(PVM pVM, char *pszString)
+{
+    if (pVM)
+        MMR3HeapFree(pszString);
+    else
+        RTStrFree(pszString);
+}
+
+
+/**
+ * Frees one node, leaving any children or leaves to the caller.
+ *
+ * @param   pNode               The node structure to free.
+ */
+static void cfgmR3FreeNodeOnly(PCFGMNODE pNode)
+{
+    pNode->pFirstLeaf    = NULL;
+    pNode->pFirstChild   = NULL;
+    pNode->pNext         = NULL;
+    pNode->pPrev         = NULL;
+    if (!pNode->pVM)
+        RTMemFree(pNode);
+    else
+    {
+        pNode->pVM       = NULL;
+        MMR3HeapFree(pNode);
+    }
+}
+
 
 
@@ -1203,12 +1290,23 @@
  * @returns Pointer to the root node, NULL on error (out of memory or invalid
  *          VM handle).
- * @param   pUVM            The user mode VM handle.
+ * @param   pUVM            The user mode VM handle.  For testcase (and other
+ *                          purposes, NULL can be used.  However, the resulting
+ *                          tree cannot be inserted into a tree that has a
+ *                          non-NULL value.  Using NULL can be usedful for
+ *                          testcases and similar, non VMM uses.
  */
 VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PUVM pUVM)
 {
-    UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
-    VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, NULL);
-
-    PCFGMNODE pNew = (PCFGMNODE)MMR3HeapAllocU(pUVM, MM_TAG_CFGM, sizeof(*pNew));
+    if (pUVM)
+    {
+        UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
+        VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, NULL);
+    }
+
+    PCFGMNODE pNew;
+    if (pUVM)
+        pNew = (PCFGMNODE)MMR3HeapAllocU(pUVM, MM_TAG_CFGM, sizeof(*pNew));
+    else
+        pNew = (PCFGMNODE)RTMemAlloc(sizeof(*pNew));
     if (pNew)
     {
@@ -1218,5 +1316,5 @@
         pNew->pFirstChild   = NULL;
         pNew->pFirstLeaf    = NULL;
-        pNew->pVM           = pUVM->pVM;
+        pNew->pVM           = pUVM ? pUVM->pVM : NULL;
         pNew->fRestrictedRoot = false;
         pNew->cchName       = 0;
@@ -1242,5 +1340,5 @@
      * Create a new tree.
      */
-    PCFGMNODE pNewRoot = CFGMR3CreateTree(pRoot->pVM->pUVM);
+    PCFGMNODE pNewRoot = CFGMR3CreateTree(pRoot->pVM ? pRoot->pVM->pUVM : NULL);
     if (!pNewRoot)
         return VERR_NO_MEMORY;
@@ -1352,5 +1450,5 @@
     AssertReturn(pNode != pSubTree, VERR_INVALID_PARAMETER);
     AssertReturn(!pSubTree->pParent, VERR_INVALID_PARAMETER);
-    AssertReturn(pSubTree->pVM, VERR_INVALID_PARAMETER);
+    AssertReturn(pNode->pVM == pSubTree->pVM, VERR_INVALID_PARAMETER);
     Assert(!pSubTree->pNext);
     Assert(!pSubTree->pPrev);
@@ -1376,8 +1474,5 @@
 
         /* free the old subtree root */
-        pSubTree->pVM = NULL;
-        pSubTree->pFirstLeaf = NULL;
-        pSubTree->pFirstChild = NULL;
-        MMR3HeapFree(pSubTree);
+        cfgmR3FreeNodeOnly(pSubTree);
     }
     return rc;
@@ -1407,5 +1502,4 @@
     AssertReturn(pRoot != pNewRoot, VERR_INVALID_PARAMETER);
     AssertReturn(!pNewRoot->pParent, VERR_INVALID_PARAMETER);
-    AssertReturn(pNewRoot->pVM, VERR_INVALID_PARAMETER);
     AssertReturn(pNewRoot->pVM == pRoot->pVM, VERR_INVALID_PARAMETER);
     AssertReturn(!pNewRoot->pNext, VERR_INVALID_PARAMETER);
@@ -1429,8 +1523,5 @@
         pChild->pParent     = pRoot;
 
-    pNewRoot->pFirstLeaf    = NULL;
-    pNewRoot->pFirstChild   = NULL;
-    pNewRoot->pVM           = NULL;
-    MMR3HeapFree(pNewRoot);
+    cfgmR3FreeNodeOnly(pNewRoot);
 
     return VINF_SUCCESS;
@@ -1644,5 +1735,5 @@
              * Allocate and init node.
              */
-            PCFGMNODE pNew = (PCFGMNODE)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM, sizeof(*pNew) + cchName);
+            PCFGMNODE pNew = (PCFGMNODE)cfgmR3MemAlloc(pNode->pVM, MM_TAG_CFGM, sizeof(*pNew) + cchName);
             if (pNew)
             {
@@ -1786,5 +1877,5 @@
              * Allocate and init node.
              */
-            PCFGMLEAF pNew = (PCFGMLEAF)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM, sizeof(*pNew) + cchName);
+            PCFGMLEAF pNew = (PCFGMLEAF)cfgmR3MemAlloc(pNode->pVM, MM_TAG_CFGM, sizeof(*pNew) + cchName);
             if (pNew)
             {
@@ -1856,11 +1947,7 @@
 
         /*
-         * Free ourselves. (bit of paranoia first)
+         * Free ourselves.
          */
-        pNode->pVM = NULL;
-        pNode->pNext = NULL;
-        pNode->pPrev = NULL;
-        pNode->pParent = NULL;
-        MMR3HeapFree(pNode);
+        cfgmR3FreeNodeOnly(pNode);
     }
 }
@@ -1890,8 +1977,8 @@
          * Free value and node.
          */
-        cfgmR3FreeValue(pLeaf);
+        cfgmR3FreeValue(pNode->pVM, pLeaf);
         pLeaf->pNext = NULL;
         pLeaf->pPrev = NULL;
-        MMR3HeapFree(pLeaf);
+        cfgmR3MemFree(pNode->pVM, pLeaf);
     }
 }
@@ -1904,7 +1991,8 @@
  * The caller must either free the leaf or assign a new value to it.
  *
+ * @param   pVM         Used to select the heap.
  * @param   pLeaf       Pointer to the leaf which value should be free.
  */
-static void cfgmR3FreeValue(PCFGMLEAF pLeaf)
+static void cfgmR3FreeValue(PVM pVM, PCFGMLEAF pLeaf)
 {
     if (pLeaf)
@@ -1913,5 +2001,5 @@
         {
             case CFGMVALUETYPE_BYTES:
-                MMR3HeapFree(pLeaf->Value.Bytes.pau8);
+                cfgmR3MemFree(pVM, pLeaf->Value.Bytes.pau8);
                 pLeaf->Value.Bytes.pau8 = NULL;
                 pLeaf->Value.Bytes.cb = 0;
@@ -1919,5 +2007,5 @@
 
             case CFGMVALUETYPE_STRING:
-                MMR3HeapFree(pLeaf->Value.String.psz);
+                cfgmR3StrFree(pVM, pLeaf->Value.String.psz);
                 pLeaf->Value.String.psz = NULL;
                 pLeaf->Value.String.cb = 0;
@@ -1974,5 +2062,5 @@
          * Allocate string object first.
          */
-        char *pszStringCopy = (char *)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cchString + 1);
+        char *pszStringCopy = (char *)cfgmR3StrAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cchString + 1);
         if (pszStringCopy)
         {
@@ -1992,5 +2080,5 @@
             }
             else
-                MMR3HeapFree(pszStringCopy);
+                cfgmR3StrFree(pNode->pVM, pszStringCopy);
         }
         else
@@ -2037,5 +2125,9 @@
          * Allocate string object first.
          */
-        char *pszString = MMR3HeapAPrintfVU(pNode->pVM->pUVM, MM_TAG_CFGM_STRING, pszFormat, va);
+        char *pszString;
+        if (!pNode->pVM)
+            pszString = RTStrAPrintf2(pszFormat, va);
+        else
+            pszString = MMR3HeapAPrintfVU(pNode->pVM->pUVM, MM_TAG_CFGM_STRING, pszFormat, va);
         if (pszString)
         {
@@ -2052,5 +2144,5 @@
             }
             else
-                MMR3HeapFree(pszString);
+                cfgmR3StrFree(pNode->pVM, pszString);
         }
         else
@@ -2124,5 +2216,5 @@
              * Allocate string object first.
              */
-            void *pvCopy = MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cbBytes);
+            void *pvCopy = cfgmR3MemAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cbBytes);
             if (pvCopy || !cbBytes)
             {
@@ -2140,4 +2232,6 @@
                     pLeaf->Value.Bytes.pau8 = (uint8_t *)pvCopy;
                 }
+                else
+                    cfgmR3MemFree(pNode->pVM, pvCopy);
             }
             else
@@ -2918,5 +3012,6 @@
  * @param   pszName         Value name. This value must be of zero terminated character string type.
  * @param   ppszString      Where to store the string pointer.
- *                          Free this using MMR3HeapFree().
+ *                          Free this using MMR3HeapFree() (or RTStrFree if not
+ *                          associated with a pUVM - see CFGMR3CreateTree).
  */
 VMMR3DECL(int) CFGMR3QueryStringAlloc(PCFGMNODE pNode, const char *pszName, char **ppszString)
@@ -2926,5 +3021,5 @@
     if (RT_SUCCESS(rc))
     {
-        char *pszString = (char *)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbString);
+        char *pszString = cfgmR3StrAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbString);
         if (pszString)
         {
@@ -2933,5 +3028,5 @@
                 *ppszString = pszString;
             else
-                MMR3HeapFree(pszString);
+                cfgmR3StrFree(pNode->pVM, pszString);
         }
         else
@@ -2953,5 +3048,6 @@
  * @param   pszName         Value name. This value must be of zero terminated character string type.
  * @param   ppszString      Where to store the string pointer. Not set on failure.
- *                          Free this using MMR3HeapFree().
+ *                          Free this using MMR3HeapFree() (or RTStrFree if not
+ *                          associated with a pUVM - see CFGMR3CreateTree).
  * @param   pszDef          The default return value.  This can be NULL.
  */
@@ -2971,5 +3067,5 @@
         {
             size_t const cbSrc = pLeaf->Value.String.cb;
-            char *pszString = (char *)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbSrc);
+            char *pszString = cfgmR3StrAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbSrc);
             if (pszString)
             {
@@ -2988,5 +3084,9 @@
             *ppszString = NULL;
         else
-            *ppszString = MMR3HeapStrDup(pNode->pVM, MM_TAG_CFGM_USER, pszDef);
+        {
+            size_t const cbDef = strlen(pszDef) + 1;
+            *ppszString = cfgmR3StrAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbDef);
+            memcpy(*ppszString, pszDef, cbDef);
+        }
         if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
             rc = VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/testcase/tstCFGM.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstCFGM.cpp	(revision 46780)
+++ /trunk/src/VBox/VMM/testcase/tstCFGM.cpp	(revision 46781)
@@ -31,6 +31,107 @@
 #include <iprt/initterm.h>
 #include <iprt/stream.h>
+#include <iprt/mem.h>
 #include <iprt/string.h>
 
+#include <iprt/test.h>
+
+
+static void doGeneralTests(PCFGMNODE pRoot)
+{
+    /* test multilevel node creation */
+    PCFGMNODE pChild = NULL;
+    RTTESTI_CHECK_RC_RETV(CFGMR3InsertNode(pRoot, "First/Second/Third//Final", &pChild), VINF_SUCCESS);
+    RTTESTI_CHECK_RETV(RT_VALID_PTR(pChild));
+    RTTESTI_CHECK(CFGMR3GetChild(pRoot, "First/Second/Third/Final") == pChild);
+
+    /*
+     * Boolean queries.
+     */
+    RTTESTI_CHECK_RC(CFGMR3InsertInteger(pChild, "BoolValue", 1), VINF_SUCCESS);
+    bool f = false;
+    RTTESTI_CHECK_RC(CFGMR3QueryBool(pChild, "BoolValue", &f), VINF_SUCCESS);
+    RTTESTI_CHECK(f == true);
+
+    RTTESTI_CHECK_RC(CFGMR3QueryBool(pRoot, "BoolValue", &f), VERR_CFGM_VALUE_NOT_FOUND);
+    RTTESTI_CHECK_RC(CFGMR3QueryBool(NULL, "BoolValue", &f), VERR_CFGM_NO_PARENT);
+
+    RTTESTI_CHECK_RC(CFGMR3QueryBoolDef(pChild, "ValueNotFound", &f, true), VINF_SUCCESS);
+    RTTESTI_CHECK(f == true);
+    RTTESTI_CHECK_RC(CFGMR3QueryBoolDef(pChild, "ValueNotFound", &f, false), VINF_SUCCESS);
+    RTTESTI_CHECK(f == false);
+
+    RTTESTI_CHECK_RC(CFGMR3QueryBoolDef(NULL, "BoolValue", &f, true), VINF_SUCCESS);
+    RTTESTI_CHECK(f == true);
+    RTTESTI_CHECK_RC(CFGMR3QueryBoolDef(NULL, "BoolValue", &f, false), VINF_SUCCESS);
+    RTTESTI_CHECK(f == false);
+
+}
+
+
+
+static void doTestsOnDefaultValues(PCFGMNODE pRoot)
+{
+    /* integer */
+    uint64_t u64;
+    RTTESTI_CHECK_RC(CFGMR3QueryU64(pRoot, "RamSize", &u64), VINF_SUCCESS);
+
+    size_t cb = 0;
+    RTTESTI_CHECK_RC(CFGMR3QuerySize(pRoot, "RamSize", &cb), VINF_SUCCESS);
+    RTTESTI_CHECK(cb == sizeof(uint64_t));
+
+    /* string */
+    char *pszName = NULL;
+    RTTESTI_CHECK_RC(CFGMR3QueryStringAlloc(pRoot, "Name", &pszName), VINF_SUCCESS);
+    RTTESTI_CHECK_RC(CFGMR3QuerySize(pRoot, "Name", &cb), VINF_SUCCESS);
+    RTTESTI_CHECK(cb == strlen(pszName) + 1);
+    MMR3HeapFree(pszName);
+}
+
+
+static void doInVmmTests(RTTEST hTest)
+{
+    /*
+     * Create empty VM structure and init SSM.
+     */
+    int rc = SUPR3Init(NULL);
+    if (RT_FAILURE(rc))
+    {
+        RTTestSkipped(hTest, "SUPR3Init failed with rc=%Rrc",  rc);
+        return;
+    }
+
+    PVM pVM;
+    RTTESTI_CHECK_RC_RETV(SUPR3PageAlloc(RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT, (void **)&pVM), VINF_SUCCESS);
+
+
+    PUVM pUVM = (PUVM)RTMemPageAlloc(sizeof(*pUVM));
+    pUVM->u32Magic = UVM_MAGIC;
+    pUVM->pVM = pVM;
+    pVM->pUVM = pUVM;
+
+    /*
+     * Do the testing.
+     */
+    RTTESTI_CHECK_RC_RETV(STAMR3InitUVM(pUVM), VINF_SUCCESS);
+    RTTESTI_CHECK_RC_RETV(MMR3InitUVM(pUVM), VINF_SUCCESS);
+    RTTESTI_CHECK_RC_RETV(CFGMR3Init(pVM, NULL, NULL), VINF_SUCCESS);
+    RTTESTI_CHECK_RETV(CFGMR3GetRoot(pVM) != NULL);
+
+    doTestsOnDefaultValues(CFGMR3GetRoot(pVM));
+    doGeneralTests(CFGMR3GetRoot(pVM));
+
+
+    /* done */
+    RTTESTI_CHECK_RC_RETV(CFGMR3Term(pVM), VINF_SUCCESS);
+}
+
+
+static void doStandaloneTests(void)
+{
+    RTTestISub("Standalone");
+    PCFGMNODE pRoot;;
+    RTTESTI_CHECK_RETV((pRoot = CFGMR3CreateTree(NULL)) != NULL);
+    doGeneralTests(pRoot);
+}
 
 int main()
@@ -39,134 +140,14 @@
      * Init runtime.
      */
+    RTTEST hTest;
     RTR3InitExeNoArguments(RTR3INIT_FLAGS_SUPLIB);
+    RTEXITCODE rcExit = RTTestInitAndCreate("tstCFGM", &hTest);
+    if (rcExit != RTEXITCODE_SUCCESS)
+        return rcExit;
 
-    /*
-     * Create empty VM structure and init SSM.
-     */
-    PVM         pVM;
-    int rc = SUPR3Init(NULL);
-    if (RT_SUCCESS(rc))
-        rc = SUPR3PageAlloc(RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT, (void **)&pVM);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc);
-        return 1;
-    }
+    doInVmmTests(hTest);
+    doStandaloneTests();
 
-    static UVM s_UVM;
-    PUVM pUVM = &s_UVM;
-    pUVM->pVM = pVM;
-    pVM->pUVM = pUVM;
+    return RTTestSummaryAndDestroy(hTest);
+}
 
-    rc = STAMR3InitUVM(pUVM);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-
-    rc = MMR3InitUVM(pUVM);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-
-    rc = CFGMR3Init(pVM, NULL, NULL);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: CFGMR3Init failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-
-    if (!CFGMR3GetRoot(pVM))
-    {
-        RTPrintf("FAILURE: CFGMR3GetRoot failed\n");
-        return 1;
-    }
-
-    /* integer */
-    uint64_t u64;
-    rc = CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &u64);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: CFGMR3QueryU64(,\"RamSize\",) failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-
-    size_t cb;
-    rc = CFGMR3QuerySize(CFGMR3GetRoot(pVM), "RamSize", &cb);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: CFGMR3QuerySize(,\"RamSize\",) failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-    if (cb != sizeof(uint64_t))
-    {
-        RTPrintf("FAILURE: Incorrect valuesize %d for \"RamSize\" value.\n", cb);
-        return 1;
-    }
-
-    /* string */
-    char *pszName = NULL;
-    rc = CFGMR3QueryStringAlloc(CFGMR3GetRoot(pVM), "Name", &pszName);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: CFGMR3QueryStringAlloc(,\"Name\" failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-
-    rc = CFGMR3QuerySize(CFGMR3GetRoot(pVM), "Name", &cb);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: CFGMR3QuerySize(,\"RamSize\",) failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-    if (cb != strlen(pszName) + 1)
-    {
-        RTPrintf("FAILURE: Incorrect valuesize %d for \"Name\" value '%s'.\n", cb, pszName);
-        return 1;
-    }
-    MMR3HeapFree(pszName);
-
-
-    /* test multilevel node creation */
-    PCFGMNODE pChild = NULL;
-    rc = CFGMR3InsertNode(CFGMR3GetRoot(pVM), "First/Second/Third//Final", &pChild);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: CFGMR3InsertNode(,\"First/Second/Third//Final\" failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-    rc = CFGMR3InsertInteger(pChild, "BoolValue", 1);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: CFGMR3InsertInteger(,\"BoolValue\", 1) failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-    PCFGMNODE pNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "First/Second/Third/Final");
-    if (pNode != pChild)
-    {
-        RTPrintf("FAILURE: CFGMR3GetChild(,\"First/Second/Third/Final/BoolValue\") failed. pNode=%p expected %p\n", pNode, pChild);
-        return 1;
-    }
-    bool f = false;
-    rc = CFGMR3QueryBool(pNode, "BoolValue", &f);
-    if (RT_FAILURE(rc) || !f)
-    {
-        RTPrintf("FAILURE: CFGMR3QueryBool(,\"BoolValue\",) failed. rc=%Rrc f=%d\n", rc, f);
-        return 1;
-    }
-
-
-    /* done */
-    rc = CFGMR3Term(pVM);
-    if (RT_FAILURE(rc))
-    {
-        RTPrintf("FAILURE: CFGMR3QueryU64(,\"RamSize\" failed. rc=%Rrc\n", rc);
-        return 1;
-    }
-
-    RTPrintf("tstCFGM: SUCCESS\n");
-    return rc;
-}
