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

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2020-07-10 11:42:50 -05:00 committed by Alexandre Julliard
parent aa2406ecea
commit caa41d4917
1 changed files with 61 additions and 15 deletions

View File

@ -32,6 +32,35 @@
WINE_DEFAULT_DEBUG_CHANNEL(msdmo); 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 typedef struct
{ {
IEnumDMO IEnumDMO_iface; IEnumDMO IEnumDMO_iface;
@ -51,8 +80,6 @@ static inline IEnumDMOImpl *impl_from_IEnumDMO(IEnumDMO *iface)
return CONTAINING_RECORD(iface, IEnumDMOImpl, 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 IEnumDMOVtbl edmovt;
static const WCHAR *GUIDToString(WCHAR *string, const GUID *guid) static const WCHAR *GUIDToString(WCHAR *string, const GUID *guid)
@ -443,11 +470,12 @@ static HRESULT WINAPI IEnumDMO_fnNext(
WCHAR ** Names, WCHAR ** Names,
DWORD * pcItemsFetched) DWORD * pcItemsFetched)
{ {
DMO_PARTIAL_MEDIATYPE *types = NULL;
unsigned int types_size = 0;
HKEY hkey; HKEY hkey;
WCHAR szNextKey[MAX_PATH]; WCHAR szNextKey[MAX_PATH];
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
WCHAR szValue[MAX_PATH]; WCHAR szValue[MAX_PATH];
DMO_PARTIAL_MEDIATYPE types[100];
DWORD len; DWORD len;
UINT count = 0; UINT count = 0;
HRESULT hres = S_OK; HRESULT hres = S_OK;
@ -498,21 +526,29 @@ static HRESULT WINAPI IEnumDMO_fnNext(
if (This->pInTypes) if (This->pInTypes)
{ {
DWORD cInTypes, i; DWORD size = types_size, i;
hres = read_types(hkey, L"InputTypes", &cInTypes, ARRAY_SIZE(types), types); while ((ret = RegQueryValueExW(hkey, L"InputTypes", NULL, NULL,
if (FAILED(hres)) (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); RegCloseKey(hkey);
continue; 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), TRACE("intype %d: type %s, subtype %s\n", i, debugstr_guid(&types[i].type),
debugstr_guid(&types[i].subtype)); 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); RegCloseKey(hkey);
continue; continue;
@ -521,21 +557,29 @@ static HRESULT WINAPI IEnumDMO_fnNext(
if (This->pOutTypes) if (This->pOutTypes)
{ {
DWORD cOutTypes, i; DWORD size = types_size, i;
hres = read_types(hkey, L"OutputTypes", &cOutTypes, ARRAY_SIZE(types), types); while ((ret = RegQueryValueExW(hkey, L"OutputTypes", NULL, NULL,
if (FAILED(hres)) (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); RegCloseKey(hkey);
continue; 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), TRACE("outtype %d: type %s, subtype %s\n", i, debugstr_guid(&types[i].type),
debugstr_guid(&types[i].subtype)); 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); RegCloseKey(hkey);
continue; continue;
@ -561,6 +605,8 @@ static HRESULT WINAPI IEnumDMO_fnNext(
count++; count++;
} }
free(types);
if (pcItemsFetched) *pcItemsFetched = count; if (pcItemsFetched) *pcItemsFetched = count;
if (count < cItemsToFetch) if (count < cItemsToFetch)
hres = S_FALSE; hres = S_FALSE;