Zebediah Figura : devenum: Return filter data for DMO monikers.

Alexandre Julliard julliard at winehq.org
Fri May 15 16:55:07 CDT 2020


Module: wine
Branch: master
Commit: 2f2ac792427348b9172a8d269780002a484ab16e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2f2ac792427348b9172a8d269780002a484ab16e

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Fri May 15 16:09:19 2020 -0500

devenum: Return filter data for DMO monikers.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/devenum/createdevenum.c   | 48 ++++++++++++----------
 dlls/devenum/devenum_private.h |  1 +
 dlls/devenum/mediacatenum.c    | 93 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 120 insertions(+), 22 deletions(-)

diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index a3b9447144..c72bb683f9 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -351,40 +351,44 @@ static void free_regfilter2(REGFILTER2 *rgf)
     }
 }
 
-static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
+HRESULT create_filter_data(VARIANT *var, REGFILTER2 *rgf)
 {
-    BYTE *data = NULL, *array;
     IAMFilterData *fildata;
-    SAFEARRAYBOUND sabound;
-    VARIANT var = {};
+    BYTE *data = NULL;
     ULONG size;
     HRESULT hr;
 
     hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IAMFilterData, (void **)&fildata);
-    if (FAILED(hr)) goto cleanup;
+    if (FAILED(hr))
+        return hr;
 
     hr = IAMFilterData_CreateFilterData(fildata, rgf, &data, &size);
-    if (FAILED(hr)) goto cleanup;
+    IAMFilterData_Release(fildata);
+    if (FAILED(hr))
+        return hr;
 
-    V_VT(&var) = VT_ARRAY | VT_UI1;
-    sabound.lLbound = 0;
-    sabound.cElements = size;
-    if (!(V_ARRAY(&var) = SafeArrayCreate(VT_UI1, 1, &sabound)))
-        goto cleanup;
-    hr = SafeArrayAccessData(V_ARRAY(&var), (void *)&array);
-    if (FAILED(hr)) goto cleanup;
+    V_VT(var) = VT_ARRAY | VT_UI1;
+    if (!(V_ARRAY(var) = SafeArrayCreateVector(VT_UI1, 1, size)))
+    {
+        VariantClear(var);
+        CoTaskMemFree(data);
+        return E_OUTOFMEMORY;
+    }
 
-    memcpy(array, data, size);
-    hr = SafeArrayUnaccessData(V_ARRAY(&var));
-    if (FAILED(hr)) goto cleanup;
+    memcpy(V_ARRAY(var)->pvData, data, size);
+    CoTaskMemFree(data);
+    return S_OK;
+}
 
-    hr = IPropertyBag_Write(prop_bag, L"FilterData", &var);
-    if (FAILED(hr)) goto cleanup;
+static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
+{
+    VARIANT var;
 
-cleanup:
-    VariantClear(&var);
-    CoTaskMemFree(data);
-    IAMFilterData_Release(fildata);
+    if (SUCCEEDED(create_filter_data(&var, rgf)))
+    {
+        IPropertyBag_Write(prop_bag, L"FilterData", &var);
+        VariantClear(&var);
+    }
 }
 
 static void register_legacy_filters(void)
diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h
index bd018a42a0..15c41afd57 100644
--- a/dlls/devenum/devenum_private.h
+++ b/dlls/devenum/devenum_private.h
@@ -54,6 +54,7 @@ struct moniker
     IPropertyBag IPropertyBag_iface;
 };
 
+HRESULT create_filter_data(VARIANT *var, REGFILTER2 *rgf) DECLSPEC_HIDDEN;
 struct moniker *dmo_moniker_create(const GUID class, const GUID clsid) DECLSPEC_HIDDEN;
 struct moniker *codec_moniker_create(const GUID *class, const WCHAR *name) DECLSPEC_HIDDEN;
 struct moniker *filter_moniker_create(const GUID *class, const WCHAR *name) DECLSPEC_HIDDEN;
diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c
index 85634ead1a..16b729ab1f 100644
--- a/dlls/devenum/mediacatenum.c
+++ b/dlls/devenum/mediacatenum.c
@@ -28,6 +28,35 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(devenum);
 
+BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
+{
+    unsigned int max_capacity, new_capacity;
+    void *new_elements;
+
+    if (count <= *capacity)
+        return TRUE;
+
+    max_capacity = ~0u / size;
+    if (count > max_capacity)
+        return FALSE;
+
+    new_capacity = max(8, *capacity);
+    while (new_capacity < count && new_capacity <= max_capacity / 2)
+        new_capacity *= 2;
+    if (new_capacity < count)
+        new_capacity = count;
+
+    if (!(new_elements = realloc(*elements, new_capacity * size)))
+    {
+        ERR("Failed to allocate memory.\n");
+        return FALSE;
+    }
+
+    *elements = new_elements;
+    *capacity = new_capacity;
+    return TRUE;
+}
+
 typedef struct
 {
     IEnumMoniker IEnumMoniker_iface;
@@ -106,6 +135,70 @@ static HRESULT WINAPI property_bag_Read(IPropertyBag *iface,
             }
             return hr;
         }
+        else if (!wcscmp(name, L"FilterData"))
+        {
+            REGFILTERPINS2 reg_pins[2] = {{0}};
+            REGFILTER2 reg_filter =
+            {
+                .dwVersion = 2,
+                .dwMerit = MERIT_NORMAL + 0x800,
+                .cPins2 = 2,
+                .rgPins2 = reg_pins,
+            };
+
+            unsigned int count = 1, input_count, output_count, i;
+            DMO_PARTIAL_MEDIATYPE *types = NULL;
+            REGPINTYPES *reg_types;
+            HRESULT hr;
+
+            if (!(types = malloc(2 * count * sizeof(*types))))
+                return E_OUTOFMEMORY;
+
+            while ((hr = DMOGetTypes(&moniker->clsid, count, &input_count, types,
+                    count, &output_count, types + count)) == S_FALSE)
+            {
+                count *= 2;
+                if (!(types = realloc(types, count * sizeof(*types))))
+                {
+                    free(types);
+                    return E_OUTOFMEMORY;
+                }
+            }
+            if (hr != S_OK)
+            {
+                free(types);
+                return hr;
+            }
+
+            if (!(reg_types = malloc(2 * count * sizeof(*reg_types))))
+            {
+                free(types);
+                return hr;
+            }
+
+            for (i = 0; i < input_count; ++i)
+            {
+                reg_types[i].clsMajorType = &types[i].type;
+                reg_types[i].clsMinorType = &types[i].subtype;
+            }
+            for (i = 0; i < output_count; ++i)
+            {
+                reg_types[count + i].clsMajorType = &types[count + i].type;
+                reg_types[count + i].clsMinorType = &types[count + i].subtype;
+            }
+            reg_pins[0].cInstances = 1;
+            reg_pins[0].nMediaTypes = input_count;
+            reg_pins[0].lpMediaType = reg_types;
+            reg_pins[1].dwFlags = REG_PINFLAG_B_OUTPUT;
+            reg_pins[1].cInstances = 1;
+            reg_pins[1].nMediaTypes = output_count;
+            reg_pins[1].lpMediaType = reg_types + count;
+
+            hr = create_filter_data(var, &reg_filter);
+            free(reg_types);
+            free(types);
+            return hr;
+        }
         return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
     }
 




More information about the wine-cvs mailing list