Index: trunk/src/VBox/ValidationKit/utils/audio/Makefile.kmk
===================================================================
--- trunk/src/VBox/ValidationKit/utils/audio/Makefile.kmk	(revision 89054)
+++ trunk/src/VBox/ValidationKit/utils/audio/Makefile.kmk	(revision 89055)
@@ -42,9 +42,11 @@
 # The Validation Kit Audio Test (VKAT) utility.
 #
-VKAT_PATH_AUDIO=$(PATH_ROOT)/src/VBox/Devices/Audio
+VKAT_PATH_AUDIO = $(PATH_ROOT)/src/VBox/Devices/Audio
 
 PROGRAMS += AudioTest
 AudioTest_TEMPLATE = VBoxValidationKitR3
-AudioTest_DEFS    += VBOX_AUDIO_VKAT
+AudioTest_DEFS     = VBOX_AUDIO_VKAT
+AudioTest_INCS     = \
+	$(PATH_ROOT)/src/VBox/Devices/build
 AudioTest_SOURCES  = \
 	vkat.cpp \
Index: trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp	(revision 89054)
+++ trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp	(revision 89055)
@@ -51,5 +51,5 @@
 #include "../../../Devices/Audio/AudioHlp.h"
 #include "../../../Devices/Audio/AudioTest.h"
-#include "../../../Devices/Audio/VBoxDDVKAT.h"
+#include "VBoxDD.h"
 
 
@@ -231,6 +231,4 @@
 /** The current verbosity level. */
 static unsigned     g_uVerbosity = 0;
-/** The driver instance data. */
-static PDMDRVINS    g_DrvIns;
 
 
@@ -402,31 +400,123 @@
 }
 
+/** @name Driver Helper Fakes / Stubs
+ * @{  */
+
+VMMR3DECL(int) CFGMR3QueryString(PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString)
+{
+    if (pNode != NULL)
+    {
+        PCPDMDRVREG pDrvReg = (PCPDMDRVREG)pNode;
+        if (g_uVerbosity > 2)
+            RTPrintf("debug: CFGMR3QueryString([%s], %s, %p, %#x)\n", pDrvReg->szName, pszName, pszString, cchString);
+
+        if (   (   strcmp(pDrvReg->szName, "PulseAudio") == 0
+                || strcmp(pDrvReg->szName, "HostAudioWas") == 0)
+            && strcmp(pszName, "VmName") == 0)
+            return RTStrCopy(pszString, cchString, "vkat");
+
+        if (   strcmp(pDrvReg->szName, "HostAudioWas") == 0
+            && strcmp(pszName, "VmUuid") == 0)
+            return RTStrCopy(pszString, cchString, "794c9192-d045-4f28-91ed-46253ac9998e");
+    }
+    else if (g_uVerbosity > 2)
+        RTPrintf("debug: CFGMR3QueryString(%p, %s, %p, %#x)\n", pNode, pszName, pszString, cchString);
+
+    return VERR_CFGM_VALUE_NOT_FOUND;
+}
+
+/* Fake stub. Will be removed when this moves into the driver helpers. */
+VMMR3DECL(int) CFGMR3QueryStringDef(PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString, const char *pszDef)
+{
+    if (g_uVerbosity > 2)
+        RTPrintf("debug: CFGMR3QueryStringDef(%p, %s, %p, %#x, %s)\n", pNode, pszName, pszString, cchString, pszDef);
+    return RTStrCopy(pszString, cchString, pszDef);
+}
+
+/* Fake stub. Will be removed when this moves into the driver helpers. */
+VMMR3DECL(int) CFGMR3ValidateConfig(PCFGMNODE pNode, const char *pszNode,
+                                    const char *pszValidValues, const char *pszValidNodes,
+                                    const char *pszWho, uint32_t uInstance)
+{
+    RT_NOREF(pNode, pszNode, pszValidValues, pszValidNodes, pszWho, uInstance);
+    return VINF_SUCCESS;
+}
+
+/** @} */
+
+
 /**
  * Constructs a PDM audio driver instance.
  *
  * @returns VBox status code.
- * @param   pDrvReg             PDM driver registration record to use for construction.
- * @param   pDrvIns             Driver instance to use for construction.
- * @param   ppDrvAudio          Where to return the audio driver interface of type IHOSTAUDIO.
- */
-static int audioTestDrvConstruct(const PDMDRVREG *pDrvReg, PPDMDRVINS pDrvIns, PPDMIHOSTAUDIO *ppDrvAudio)
-{
-    AssertReturn(pDrvReg->cbInstance, VERR_INVALID_PARAMETER); /** @todo Very crude; improve. */
-
+ * @param   pDrvReg     PDM driver registration record to use for construction.
+ * @param   ppDrvIns    Where to return the driver instance structure.
+ * @param   ppDrvAudio  Where to return the audio driver interface of type IHOSTAUDIO.
+ */
+static int audioTestDrvConstruct(PCPDMDRVREG pDrvReg, PPPDMDRVINS ppDrvIns, PPDMIHOSTAUDIO *ppDrvAudio)
+{
+    /* The destruct function must have valid data to work with. */
+    *ppDrvIns   = NULL;
+    *ppDrvAudio = NULL;
+
+    /*
+     * Check registration structure validation (doesn't need to be too
+     * thorough, PDM check it in detail on every VM startup).
+     */
+    AssertPtrReturn(pDrvReg, VERR_INVALID_POINTER);
     RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Initializing backend '%s' ...\n", pDrvReg->szName);
-
-    pDrvIns->pvInstanceData = RTMemAllocZ(pDrvReg->cbInstance);
-    AssertPtrReturn(pDrvIns->pvInstanceData, VERR_NO_MEMORY);
-
-    int rc = pDrvReg->pfnConstruct(pDrvIns, NULL /* PCFGMNODE */, 0 /* fFlags */);
+    AssertPtrReturn(pDrvReg->pfnConstruct, VERR_INVALID_PARAMETER);
+
+    /*
+     * Initialize the driver helper the first time thru.
+     */
+    static PDMDRVHLPR3 s_DrvHlp;
+    if (s_DrvHlp.u32Version == 0)
+    {
+        s_DrvHlp.u32Version = PDM_DRVHLPR3_VERSION;
+        s_DrvHlp.u32TheEnd  = PDM_DRVHLPR3_VERSION;
+    }
+
+    /*
+     * Create the instance data structure.
+     */
+    PPDMDRVINS pDrvIns = (PPDMDRVINS)RTMemAllocZVar(RT_UOFFSETOF_DYN(PDMDRVINS, achInstanceData[pDrvReg->cbInstance]));
+    RTTEST_CHECK_RET(g_hTest, pDrvIns, VERR_NO_MEMORY);
+
+    pDrvIns->u32Version       = PDM_DRVINS_VERSION;
+    pDrvIns->iInstance        = 0;
+    pDrvIns->pHlpR3           = &s_DrvHlp;
+    pDrvIns->pvInstanceDataR3 = &pDrvIns->achInstanceData[0];
+    pDrvIns->pReg             = pDrvReg;
+    pDrvIns->pCfg             = (PCFGMNODE)pDrvReg;
+    //pDrvIns->pUpBase          = NULL;
+    //pDrvIns->pDownBase        = NULL;
+
+    /*
+     * Invoke the constructor.
+     */
+    int rc = pDrvReg->pfnConstruct(pDrvIns, pDrvIns->pCfg, 0 /*fFlags*/);
     if (RT_SUCCESS(rc))
     {
         PPDMIHOSTAUDIO pDrvAudio = (PPDMIHOSTAUDIO)pDrvIns->IBase.pfnQueryInterface(&pDrvIns->IBase, PDMIHOSTAUDIO_IID);
-
-        pDrvAudio->pfnGetStatus(pDrvAudio, PDMAUDIODIR_OUT);
-
-        *ppDrvAudio = pDrvAudio;
-    }
-
+        if (pDrvAudio)
+        {
+            PDMAUDIOBACKENDSTS enmStatus = pDrvAudio->pfnGetStatus(pDrvAudio, PDMAUDIODIR_OUT);
+            if (enmStatus == PDMAUDIOBACKENDSTS_RUNNING)
+            {
+                *ppDrvAudio = pDrvAudio;
+                *ppDrvIns   = pDrvIns;
+                return VINF_SUCCESS;
+            }
+            RTTestFailed(g_hTest, "Expected backend status RUNNING, got %d instead", enmStatus);
+        }
+        else
+            RTTestFailed(g_hTest, "Failed to query PDMIHOSTAUDIO for '%s'", pDrvReg->szName);
+    }
+    else
+        RTTestFailed(g_hTest, "Failed to construct audio driver '%s': %Rrc", pDrvReg->szName, rc);
+    if (pDrvReg->pfnDestruct)
+        pDrvReg->pfnDestruct(pDrvIns);
+    RTMemFree(pDrvIns);
     return rc;
 }
@@ -439,5 +529,5 @@
  * @param   pDrvIns             Driver instance to destruct.
  */
-static int audioTestDrvDestruct(const PDMDRVREG *pDrvReg, PPDMDRVINS pDrvIns)
+static int audioTestDrvDestruct(PCPDMDRVREG pDrvReg, PPDMDRVINS pDrvIns)
 {
     if (!pDrvIns)
@@ -447,9 +537,6 @@
         pDrvReg->pfnDestruct(pDrvIns);
 
-    if (pDrvIns->pvInstanceData)
-    {
-        RTMemFree(pDrvIns->pvInstanceData);
-        pDrvIns->pvInstanceData = NULL;
-    }
+    pDrvIns->u32Version = 0;
+    RTMemFree(pDrvIns);
 
     return VINF_SUCCESS;
@@ -896,5 +983,5 @@
 
     /* The backend: */
-    PDMDRVREG const *pDrvReg;
+    PCPDMDRVREG pDrvReg;
 #if defined(RT_OS_WINDOWS)
     pDrvReg = &g_DrvHostAudioWas;
@@ -1031,7 +1118,7 @@
     RTTestBanner(g_hTest);
 
-    PPDMIHOSTAUDIO pDrvAudio;
-    RT_ZERO(g_DrvIns);
-    rc = audioTestDrvConstruct(pDrvReg, &g_DrvIns, &pDrvAudio);
+    PPDMIHOSTAUDIO pDrvAudio = NULL;
+    PPDMDRVINS     pDrvIns   = NULL;
+    rc = audioTestDrvConstruct(pDrvReg, &pDrvIns, &pDrvAudio);
     if (RT_SUCCESS(rc))
     {
@@ -1057,6 +1144,6 @@
             audioTestEnvDestroy(&TstEnv);
         }
-        audioTestDrvDestruct(pDrvReg, &g_DrvIns);
-    }
+    }
+    audioTestDrvDestruct(pDrvReg, pDrvIns);
 
     audioTestParmsDestroy(&TstCust);
