Index: /trunk/include/VBox/vd.h
===================================================================
--- /trunk/include/VBox/vd.h	(revision 51885)
+++ /trunk/include/VBox/vd.h	(revision 51886)
@@ -424,4 +424,17 @@
 } VDBACKENDINFO, *PVDBACKENDINFO;
 
+/**
+ * Data structure for returning a list of filter capabilities.
+ */
+typedef struct VDFILTERINFO
+{
+    /** Name of the filter. Must be unique even with case insensitive comparison. */
+    const char *pszFilter;
+    /** Pointer to an array of structs describing each supported config key.
+     * Terminated by a NULL config key. Note that some filters do not support
+     * the configuration interface, so this pointer may just contain NULL. */
+    PCVDCONFIGINFO paConfigInfo;
+} VDFILTERINFO, *PVDFILTERINFO;
+
 
 /**
@@ -508,4 +521,25 @@
  */
 VBOXDDU_DECL(int) VDBackendInfoOne(const char *pszBackend, PVDBACKENDINFO pEntry);
+
+/**
+ * Lists all filters and their capabilities in a caller-provided buffer.
+ *
+ * @return  VBox status code.
+ *          VERR_BUFFER_OVERFLOW if not enough space is passed.
+ * @param   cEntriesAlloc   Number of list entries available.
+ * @param   pEntries        Pointer to array for the entries.
+ * @param   pcEntriesUsed   Number of entries returned.
+ */
+VBOXDDU_DECL(int) VDFilterInfo(unsigned cEntriesAlloc, PVDFILTERINFO pEntries,
+                               unsigned *pcEntriesUsed);
+
+/**
+ * Lists the capabilities of a filter identified by its name.
+ *
+ * @return  VBox status code.
+ * @param   pszFilter       The filter name (case insensitive).
+ * @param   pEntries        Pointer to an entry.
+ */
+VBOXDDU_DECL(int) VDFilterInfoOne(const char *pszFilter, PVDFILTERINFO pEntry);
 
 /**
Index: /trunk/src/VBox/Storage/VD.cpp
===================================================================
--- /trunk/src/VBox/Storage/VD.cpp	(revision 51885)
+++ /trunk/src/VBox/Storage/VD.cpp	(revision 51886)
@@ -5538,4 +5538,84 @@
             pEntry->paFileExtensions = g_apBackends[i]->paFileExtensions;
             pEntry->paConfigInfo = g_apBackends[i]->paConfigInfo;
+            return VINF_SUCCESS;
+        }
+    }
+
+    return VERR_NOT_FOUND;
+}
+
+/**
+ * Lists all filters and their capabilities in a caller-provided buffer.
+ *
+ * @return  VBox status code.
+ *          VERR_BUFFER_OVERFLOW if not enough space is passed.
+ * @param   cEntriesAlloc   Number of list entries available.
+ * @param   pEntries        Pointer to array for the entries.
+ * @param   pcEntriesUsed   Number of entries returned.
+ */
+VBOXDDU_DECL(int) VDFilterInfo(unsigned cEntriesAlloc, PVDFILTERINFO pEntries,
+                               unsigned *pcEntriesUsed)
+{
+    int rc = VINF_SUCCESS;
+    unsigned cEntries = 0;
+
+    LogFlowFunc(("cEntriesAlloc=%u pEntries=%#p pcEntriesUsed=%#p\n", cEntriesAlloc, pEntries, pcEntriesUsed));
+    /* Check arguments. */
+    AssertMsgReturn(cEntriesAlloc,
+                    ("cEntriesAlloc=%u\n", cEntriesAlloc),
+                    VERR_INVALID_PARAMETER);
+    AssertMsgReturn(VALID_PTR(pEntries),
+                    ("pEntries=%#p\n", pEntries),
+                    VERR_INVALID_PARAMETER);
+    AssertMsgReturn(VALID_PTR(pcEntriesUsed),
+                    ("pcEntriesUsed=%#p\n", pcEntriesUsed),
+                    VERR_INVALID_PARAMETER);
+    if (!g_apBackends)
+        VDInit();
+
+    if (cEntriesAlloc < g_cFilterBackends)
+    {
+        *pcEntriesUsed = g_cFilterBackends;
+        return VERR_BUFFER_OVERFLOW;
+    }
+
+    for (unsigned i = 0; i < g_cFilterBackends; i++)
+    {
+        pEntries[i].pszFilter = g_apFilterBackends[i]->pszBackendName;
+        pEntries[i].paConfigInfo = g_apFilterBackends[i]->paConfigInfo;
+    }
+
+    LogFlowFunc(("returns %Rrc *pcEntriesUsed=%u\n", rc, cEntries));
+    *pcEntriesUsed = g_cFilterBackends;
+    return rc;
+}
+
+/**
+ * Lists the capabilities of a filter identified by its name.
+ *
+ * @return  VBox status code.
+ * @param   pszFilter       The filter name (case insensitive).
+ * @param   pEntries        Pointer to an entry.
+ */
+VBOXDDU_DECL(int) VDFilterInfoOne(const char *pszFilter, PVDFILTERINFO pEntry)
+{
+    LogFlowFunc(("pszFilter=%#p pEntry=%#p\n", pszFilter, pEntry));
+    /* Check arguments. */
+    AssertMsgReturn(VALID_PTR(pszFilter),
+                    ("pszFilter=%#p\n", pszFilter),
+                    VERR_INVALID_PARAMETER);
+    AssertMsgReturn(VALID_PTR(pEntry),
+                    ("pEntry=%#p\n", pEntry),
+                    VERR_INVALID_PARAMETER);
+    if (!g_apBackends)
+        VDInit();
+
+    /* Go through loaded backends. */
+    for (unsigned i = 0; i < g_cFilterBackends; i++)
+    {
+        if (!RTStrICmp(pszFilter, g_apFilterBackends[i]->pszBackendName))
+        {
+            pEntry->pszFilter = g_apFilterBackends[i]->pszBackendName;
+            pEntry->paConfigInfo = g_apFilterBackends[i]->paConfigInfo;
             return VINF_SUCCESS;
         }
