Index: /trunk/include/VBox/vmm/pdmifs.h
===================================================================
--- /trunk/include/VBox/vmm/pdmifs.h	(revision 53406)
+++ /trunk/include/VBox/vmm/pdmifs.h	(revision 53407)
@@ -1338,4 +1338,24 @@
 #define PDMISECKEY_IID                           "a7336c4a-2ca0-489d-ad2d-f740f215a1e6"
 
+/** Pointer to a secret key helper interface. */
+typedef struct PDMISECKEYHLP *PPDMISECKEYHLP;
+
+/**
+ * Secret key helper interface for non critical functionality.
+ */
+typedef struct PDMISECKEYHLP
+{
+    /**
+     * Notifies the interface provider that a key couldn't be retrieved from the key store.
+     *
+     * @returns VBox status code.
+     * @param   pInterface      Pointer to this interface.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnKeyMissingNotify, (PPDMISECKEYHLP pInterface));
+
+} PDMISECKEYHLP;
+/** PDMISECKEY interface ID. */
+#define PDMISECKEYHLP_IID                        "7be96168-4156-40ac-86d2-3073bf8b318e"
+
 /**
  * Media geometry structure.
@@ -1457,7 +1477,9 @@
      *                          Use NULL to clear the currently set interface and clear all secret
      *                          keys from the user.
-     * @thread  Any thread.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnSetSecKeyIf,(PPDMIMEDIA pInterface, PPDMISECKEY pIfSecKey));
+     * @param   pIfSecKeyHlp    The secret key helper interface to use.
+     * @thread  Any thread.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnSetSecKeyIf,(PPDMIMEDIA pInterface, PPDMISECKEY pIfSecKey,
+                                              PPDMISECKEYHLP pIfSecKeyHlp));
 
     /**
@@ -1587,5 +1609,5 @@
 } PDMIMEDIA;
 /** PDMIMEDIA interface ID. */
-#define PDMIMEDIA_IID                           "b4acf420-c9e3-4333-9ed5-e86f6b2d5f1a"
+#define PDMIMEDIA_IID                           "d8997ad8-4dda-4352-aa99-99bf87d54102"
 
 
Index: /trunk/src/VBox/Devices/Storage/DrvVD.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 53406)
+++ /trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 53407)
@@ -199,4 +199,6 @@
     /** The secret key interface used to retrieve keys. */
     PPDMISECKEY              pIfSecKey;
+    /** The secret key helper interface used to notify about missing keys. */
+    PPDMISECKEYHLP           pIfSecKeyHlp;
     /** @} */
 } VBOXDISK, *PVBOXDISK;
@@ -1537,4 +1539,26 @@
 }
 
+/**
+ * Checks the prerequisites for encrypted I/O.
+ *
+ * @returns VBox status code.
+ * @param   pThis    The VD driver instance data.
+ */
+static int drvvdKeyCheckPrereqs(PVBOXDISK pThis)
+{
+    if (   pThis->pCfgCrypto
+        && !pThis->pIfSecKey)
+    {
+        AssertPtr(pThis->pIfSecKeyHlp);
+        pThis->pIfSecKeyHlp->pfnKeyMissingNotify(pThis->pIfSecKeyHlp);
+
+        int rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
+                                            N_("VD: The DEK for this disk is missing"));
+        AssertRC(rc);
+        return VERR_VD_DEK_MISSING;
+    }
+
+    return VINF_SUCCESS;
+}
 
 /*******************************************************************************
@@ -1551,12 +1575,7 @@
     PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
 
-    if (   pThis->pCfgCrypto
-        && !pThis->pIfSecKey)
-    {
-        rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
-                                        N_("VD: The DEK for this disk is missing"));
-        AssertRC(rc);
-        return VERR_VD_DEK_MISSING;
-    }
+    rc = drvvdKeyCheckPrereqs(pThis);
+    if (RT_FAILURE(rc))
+        return rc;
 
     if (!pThis->fBootAccelActive)
@@ -1666,12 +1685,7 @@
           off, pvBuf, cbWrite, cbWrite, pvBuf));
 
-    if (   pThis->pCfgCrypto
-        && !pThis->pIfSecKey)
-    {
-        int rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
-                                            N_("VD: The DEK for this disk is missing"));
-        AssertRC(rc);
-        return VERR_VD_DEK_MISSING;
-    }
+    int rc = drvvdKeyCheckPrereqs(pThis);
+    if (RT_FAILURE(rc))
+        return rc;
 
     /* Invalidate any buffer if boot acceleration is enabled. */
@@ -1682,5 +1696,5 @@
     }
 
-    int rc = VDWrite(pThis->pDisk, off, pvBuf, cbWrite);
+    rc = VDWrite(pThis->pDisk, off, pvBuf, cbWrite);
     LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
@@ -1733,5 +1747,5 @@
 
 /** @copydoc PDMIMEDIA::pfnSetKey */
-static DECLCALLBACK(int) drvvdSetSecKeyIf(PPDMIMEDIA pInterface, PPDMISECKEY pIfSecKey)
+static DECLCALLBACK(int) drvvdSetSecKeyIf(PPDMIMEDIA pInterface, PPDMISECKEY pIfSecKey, PPDMISECKEYHLP pIfSecKeyHlp)
 {
     LogFlowFunc(("\n"));
@@ -1742,4 +1756,6 @@
     {
         PVDINTERFACE pVDIfFilter = NULL;
+
+        pThis->pIfSecKeyHlp = pIfSecKeyHlp;
 
         if (   pThis->pIfSecKey
@@ -1987,12 +2003,7 @@
     PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
 
-    if (   pThis->pCfgCrypto
-        && !pThis->pIfSecKey)
-    {
-        rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
-                                        N_("VD: The DEK for this disk is missing"));
-        AssertRC(rc);
-        return VERR_VD_DEK_MISSING;
-    }
+    rc = drvvdKeyCheckPrereqs(pThis);
+    if (RT_FAILURE(rc))
+        return rc;
 
     pThis->fBootAccelActive = false;
@@ -2025,12 +2036,7 @@
     PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
 
-    if (   pThis->pCfgCrypto
-        && !pThis->pIfSecKey)
-    {
-        rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
-                                        N_("VD: The DEK for this disk is missing"));
-        AssertRC(rc);
-        return VERR_VD_DEK_MISSING;
-    }
+    rc = drvvdKeyCheckPrereqs(pThis);
+    if (RT_FAILURE(rc))
+        return rc;
 
     pThis->fBootAccelActive = false;
Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 53406)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 53407)
@@ -806,4 +806,6 @@
     static DECLCALLBACK(int)    i_pdmIfSecKey_KeyRelease(PPDMISECKEY pInterface, const char *pszId);
 
+    static DECLCALLBACK(int)    i_pdmIfSecKeyHlp_KeyMissingNotify(PPDMISECKEYHLP pInterface);
+
     int mcAudioRefs;
     volatile uint32_t mcVRDPClients;
@@ -981,4 +983,10 @@
     } *mpIfSecKey;
 
+    /** Pointer to the key helpers -> provider (that's us) callbacks. */
+    struct MYPDMISECKEYHLP : public PDMISECKEYHLP
+    {
+        Console *pConsole;
+    } *mpIfSecKeyHlp;
+
 /* Note: FreeBSD needs this whether netflt is used or not. */
 #if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || defined(RT_OS_FREEBSD))
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 53406)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 53407)
@@ -423,4 +423,5 @@
     , mBusMgr(NULL)
     , mpIfSecKey(NULL)
+    , mpIfSecKeyHlp(NULL)
     , mVMStateChangeCallbackDisabled(false)
     , mfUseHostClipboard(true)
@@ -467,4 +468,11 @@
     pIfSecKey->pConsole                 = this;
     mpIfSecKey = pIfSecKey;
+
+    MYPDMISECKEYHLP *pIfSecKeyHlp = (MYPDMISECKEYHLP *)RTMemAllocZ(sizeof(*mpIfSecKeyHlp) + sizeof(Console *));
+    if (!pIfSecKeyHlp)
+        return E_OUTOFMEMORY;
+    pIfSecKeyHlp->pfnKeyMissingNotify   = Console::i_pdmIfSecKeyHlp_KeyMissingNotify;
+    pIfSecKeyHlp->pConsole              = this;
+    mpIfSecKeyHlp = pIfSecKeyHlp;
 
     return BaseFinalConstruct();
@@ -701,4 +709,10 @@
         RTMemFree((void *)mpIfSecKey);
         mpIfSecKey = NULL;
+    }
+
+    if (mpIfSecKeyHlp)
+    {
+        RTMemFree((void *)mpIfSecKeyHlp);
+        mpIfSecKeyHlp = NULL;
     }
 
@@ -4457,5 +4471,5 @@
                 if (pIMedium)
                 {
-                    rc = pIMedium->pfnSetSecKeyIf(pIMedium, NULL);
+                    rc = pIMedium->pfnSetSecKeyIf(pIMedium, NULL, mpIfSecKeyHlp);
                     Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
                 }
@@ -4574,5 +4588,5 @@
                     else
                     {
-                        rc = pIMedium->pfnSetSecKeyIf(pIMedium, mpIfSecKey);
+                        rc = pIMedium->pfnSetSecKeyIf(pIMedium, mpIfSecKey, mpIfSecKeyHlp);
                         if (RT_FAILURE(rc))
                             return setError(E_FAIL, tr("Failed to set the encryption key (%Rrc)"), rc);
@@ -8224,4 +8238,14 @@
         }
 
+        case VMSTATE_POWERING_ON:
+        {
+            /*
+             * We have to set the secret key helper interface for the VD drivers to
+             * get notified about missing keys.
+             */
+            that->i_clearDiskEncryptionKeysOnAllAttachments();
+            break;
+        }
+
         default: /* shut up gcc */
             break;
@@ -8893,14 +8917,4 @@
     LogRel(("Console: VM runtime error: fatal=%RTbool, errorID=%s message=\"%s\"\n",
             fFatal, pszErrorId, message.c_str()));
-
-    /* Set guest property if the reason of the error is a missing DEK for a disk. */
-    if (!RTStrCmp(pszErrorId, "DrvVD_DEKMISSING"))
-    {
-        that->mMachine->DeleteGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw());
-        that->mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw(),
-                                         Bstr("1").raw(), Bstr("RDONLYGUEST").raw());
-        that->mMachine->SaveSettings();
-    }
-
 
     that->i_onRuntimeError(BOOL(fFatal), Bstr(pszErrorId).raw(), Bstr(message).raw());
@@ -10258,4 +10272,20 @@
 }
 
+/**
+ * @interface_method_impl{PDMISECKEYHLP,pfnKeyMissingNotify}
+ */
+/*static*/ DECLCALLBACK(int)
+Console::i_pdmIfSecKeyHlp_KeyMissingNotify(PPDMISECKEYHLP pInterface)
+{
+    Console *pConsole = ((MYPDMISECKEYHLP *)pInterface)->pConsole;
+
+    /* Set guest property only, the VM is paused in the media driver calling us. */
+    pConsole->mMachine->DeleteGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw());
+    pConsole->mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw(),
+                                         Bstr("1").raw(), Bstr("RDONLYGUEST").raw());
+    pConsole->mMachine->SaveSettings();
+
+    return VINF_SUCCESS;
+}
 
 
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 53406)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 53407)
@@ -3968,4 +3968,20 @@
             AssertRCReturn(rc, rc);
 
+            /*
+             * Make the secret key helper interface known to the VD driver if it is attached,
+             * so we can get notified about missing keys.
+             */
+            PPDMIBASE pIBase = NULL;
+            rc = PDMR3QueryDriverOnLun(pUVM, pcszDevice, uInstance, uLUN, "VD", &pIBase);
+            if (RT_SUCCESS(rc) && pIBase)
+            {
+                PPDMIMEDIA pIMedium = (PPDMIMEDIA)pIBase->pfnQueryInterface(pIBase, PDMIMEDIA_IID);
+                if (pIMedium)
+                {
+                    rc = pIMedium->pfnSetSecKeyIf(pIMedium, NULL, mpIfSecKeyHlp);
+                    Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
+                }
+            }
+
             /* There is no need to handle removable medium mounting, as we
              * unconditionally replace everthing including the block driver level.
