Zebediah Figura : msdmo: Use a dynamically allocated buffer in IEnumDMO::Next().

Alexandre Julliard julliard at winehq.org
Fri Jul 10 16:30:31 CDT 2020


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

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Fri Jul 10 11:42:50 2020 -0500

msdmo: Use a dynamically allocated buffer in IEnumDMO::Next().

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

---

 dlls/msdmo/dmoreg.c | 76 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 61 insertions(+), 15 deletions(-)

diff --git a/dlls/msdmo/dmoreg.c b/dlls/msdmo/dmoreg.c
index ab3fda743c..a23bd95512 100644
--- a/dlls/msdmo/dmoreg.c
+++ b/dlls/msdmo/dmoreg.c
@@ -32,6 +32,35 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(msdmo);
 
+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
 {
     IEnumDMO                    IEnumDMO_iface;
@@ -51,8 +80,6 @@ static inline IEnumDMOImpl *impl_from_IEnumDMO(IEnumDMO *iface)
     return CONTAINING_RECORD(iface, IEnumDMOImpl, IEnumDMO_iface);
 }
 
-static HRESULT read_types(HKEY root, LPCWSTR key, ULONG *supplied, ULONG requested, DMO_PARTIAL_MEDIATYPE* types);
-
 static const IEnumDMOVtbl edmovt;
 
 static const WCHAR *GUIDToString(WCHAR *string, const GUID *guid)
@@ -443,11 +470,12 @@ static HRESULT WINAPI IEnumDMO_fnNext(
     WCHAR ** Names,
     DWORD * pcItemsFetched)
 {
+    DMO_PARTIAL_MEDIATYPE *types = NULL;
+    unsigned int types_size = 0;
     HKEY hkey;
     WCHAR szNextKey[MAX_PATH];
     WCHAR path[MAX_PATH];
     WCHAR szValue[MAX_PATH];
-    DMO_PARTIAL_MEDIATYPE types[100];
     DWORD len;
     UINT count = 0;
     HRESULT hres = S_OK;
@@ -498,21 +526,29 @@ static HRESULT WINAPI IEnumDMO_fnNext(
 
         if (This->pInTypes)
         {
-            DWORD cInTypes, i;
+            DWORD size = types_size, i;
 
-            hres = read_types(hkey, L"InputTypes", &cInTypes, ARRAY_SIZE(types), types);
-            if (FAILED(hres))
+            while ((ret = RegQueryValueExW(hkey, L"InputTypes", NULL, NULL,
+                    (BYTE *)types, &size)) == ERROR_MORE_DATA)
+            {
+                if (!array_reserve((void **)&types, &types_size, size, 1))
+                {
+                    RegCloseKey(hkey);
+                    free(types);
+                    return E_OUTOFMEMORY;
+                }
+            }
+            if (ret)
             {
                 RegCloseKey(hkey);
                 continue;
             }
 
-            for (i = 0; i < cInTypes; i++) {
+            for (i = 0; i < size / sizeof(DMO_PARTIAL_MEDIATYPE); ++i)
                 TRACE("intype %d: type %s, subtype %s\n", i, debugstr_guid(&types[i].type),
                     debugstr_guid(&types[i].subtype));
-            }
 
-            if (!any_types_match(types, cInTypes, This->pInTypes, This->cInTypes))
+            if (!any_types_match(types, size / sizeof(DMO_PARTIAL_MEDIATYPE), This->pInTypes, This->cInTypes))
             {
                 RegCloseKey(hkey);
                 continue;
@@ -521,21 +557,29 @@ static HRESULT WINAPI IEnumDMO_fnNext(
 
         if (This->pOutTypes)
         {
-            DWORD cOutTypes, i;
+            DWORD size = types_size, i;
 
-            hres = read_types(hkey, L"OutputTypes", &cOutTypes, ARRAY_SIZE(types), types);
-            if (FAILED(hres))
+            while ((ret = RegQueryValueExW(hkey, L"OutputTypes", NULL, NULL,
+                    (BYTE *)types, &size)) == ERROR_MORE_DATA)
+            {
+                if (!array_reserve((void **)&types, &types_size, size, 1))
+                {
+                    RegCloseKey(hkey);
+                    free(types);
+                    return E_OUTOFMEMORY;
+                }
+            }
+            if (ret)
             {
                 RegCloseKey(hkey);
                 continue;
             }
 
-            for (i = 0; i < cOutTypes; i++) {
+            for (i = 0; i < size / sizeof(DMO_PARTIAL_MEDIATYPE); ++i)
                 TRACE("outtype %d: type %s, subtype %s\n", i, debugstr_guid(&types[i].type),
                     debugstr_guid(&types[i].subtype));
-            }
 
-            if (!any_types_match(types, cOutTypes, This->pOutTypes, This->cOutTypes))
+            if (!any_types_match(types, size / sizeof(DMO_PARTIAL_MEDIATYPE), This->pOutTypes, This->cOutTypes))
             {
                 RegCloseKey(hkey);
                 continue;
@@ -561,6 +605,8 @@ static HRESULT WINAPI IEnumDMO_fnNext(
         count++;
     }
 
+    free(types);
+
     if (pcItemsFetched) *pcItemsFetched = count;
     if (count < cItemsToFetch)
         hres = S_FALSE;




More information about the wine-cvs mailing list