Module: wine Branch: master Commit: d86627a27af1e69f08b1d2a9e10dd93804d88b2c URL: https://gitlab.winehq.org/wine/wine/-/commit/d86627a27af1e69f08b1d2a9e10dd93...
Author: Brendan Shanks bshanks@codeweavers.com Date: Thu Mar 21 11:48:32 2024 -0700
mmdevapi: Make IMMDeviceCollection immutable after creation.
---
dlls/mmdevapi/devenum.c | 70 +++++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 26 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index 66f954fad44..52c88ad0a03 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -76,8 +76,8 @@ typedef struct MMDevColImpl { IMMDeviceCollection IMMDeviceCollection_iface; LONG ref; - EDataFlow flow; - DWORD state; + IMMDevice **devices; + UINT devices_count; } MMDevColImpl;
typedef struct IPropertyBagImpl { @@ -827,6 +827,8 @@ static const IMMEndpointVtbl MMEndpointVtbl = static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, EDataFlow flow, DWORD state) { MMDevColImpl *This; + MMDevice *cur; + UINT i = 0;
This = malloc(sizeof(*This)); *ppv = NULL; @@ -834,14 +836,43 @@ static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, EDataFlow flow, DWORD return E_OUTOFMEMORY; This->IMMDeviceCollection_iface.lpVtbl = &MMDevColVtbl; This->ref = 1; - This->flow = flow; - This->state = state; + This->devices = NULL; + This->devices_count = 0; *ppv = &This->IMMDeviceCollection_iface; + + LIST_FOR_EACH_ENTRY(cur, &device_list, MMDevice, entry) + { + if ((cur->flow == flow || flow == eAll) && (cur->state & state)) + This->devices_count++; + } + + if (This->devices_count) + { + This->devices = malloc(This->devices_count * sizeof(IMMDevice *)); + if (!This->devices_count) + return E_OUTOFMEMORY; + + LIST_FOR_EACH_ENTRY(cur, &device_list, MMDevice, entry) + { + if ((cur->flow == flow || flow == eAll) && (cur->state & state)) + { + This->devices[i] = &cur->IMMDevice_iface; + IMMDevice_AddRef(This->devices[i]); + i++; + } + } + } + return S_OK; }
static void MMDevCol_Destroy(MMDevColImpl *This) { + UINT i; + for (i = 0; i < This->devices_count; i++) + IMMDevice_Release(This->devices[i]); + + free(This->devices); free(This); }
@@ -884,46 +915,33 @@ static ULONG WINAPI MMDevCol_Release(IMMDeviceCollection *iface) static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdevs) { MMDevColImpl *This = impl_from_IMMDeviceCollection(iface); - MMDevice *cur;
TRACE("(%p)->(%p)\n", This, numdevs); if (!numdevs) return E_POINTER;
- *numdevs = 0; - LIST_FOR_EACH_ENTRY(cur, &device_list, MMDevice, entry) - { - if ((cur->flow == This->flow || This->flow == eAll) - && (cur->state & This->state)) - ++(*numdevs); - } + *numdevs = This->devices_count; return S_OK; }
static HRESULT WINAPI MMDevCol_Item(IMMDeviceCollection *iface, UINT n, IMMDevice **dev) { MMDevColImpl *This = impl_from_IMMDeviceCollection(iface); - MMDevice *cur; - DWORD i = 0;
TRACE("(%p)->(%u, %p)\n", This, n, dev); if (!dev) return E_POINTER;
- LIST_FOR_EACH_ENTRY(cur, &device_list, MMDevice, entry) + if (n >= This->devices_count) { - if ((cur->flow == This->flow || This->flow == eAll) - && (cur->state & This->state) - && i++ == n) - { - *dev = &cur->IMMDevice_iface; - IMMDevice_AddRef(*dev); - return S_OK; - } + WARN("Could not obtain item %u\n", n); + *dev = NULL; + return E_INVALIDARG; } - WARN("Could not obtain item %u\n", n); - *dev = NULL; - return E_INVALIDARG; + + *dev = This->devices[n]; + IMMDevice_AddRef(*dev); + return S_OK; }
static const IMMDeviceCollectionVtbl MMDevColVtbl =