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