mmdevapi: Make IMMDeviceCollection immutable after creation.

This commit is contained in:
Brendan Shanks 2024-03-21 11:48:32 -07:00 committed by Alexandre Julliard
parent 7a529fc94f
commit d86627a27a

View file

@ -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 =