Commit d86627a2 authored by Brendan Shanks's avatar Brendan Shanks Committed by Alexandre Julliard

mmdevapi: Make IMMDeviceCollection immutable after creation.

parent 7a529fc9
...@@ -76,8 +76,8 @@ typedef struct MMDevColImpl ...@@ -76,8 +76,8 @@ typedef struct MMDevColImpl
{ {
IMMDeviceCollection IMMDeviceCollection_iface; IMMDeviceCollection IMMDeviceCollection_iface;
LONG ref; LONG ref;
EDataFlow flow; IMMDevice **devices;
DWORD state; UINT devices_count;
} MMDevColImpl; } MMDevColImpl;
typedef struct IPropertyBagImpl { typedef struct IPropertyBagImpl {
...@@ -827,6 +827,8 @@ static const IMMEndpointVtbl MMEndpointVtbl = ...@@ -827,6 +827,8 @@ static const IMMEndpointVtbl MMEndpointVtbl =
static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, EDataFlow flow, DWORD state) static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, EDataFlow flow, DWORD state)
{ {
MMDevColImpl *This; MMDevColImpl *This;
MMDevice *cur;
UINT i = 0;
This = malloc(sizeof(*This)); This = malloc(sizeof(*This));
*ppv = NULL; *ppv = NULL;
...@@ -834,14 +836,43 @@ static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, EDataFlow flow, DWORD ...@@ -834,14 +836,43 @@ static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, EDataFlow flow, DWORD
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
This->IMMDeviceCollection_iface.lpVtbl = &MMDevColVtbl; This->IMMDeviceCollection_iface.lpVtbl = &MMDevColVtbl;
This->ref = 1; This->ref = 1;
This->flow = flow; This->devices = NULL;
This->state = state; This->devices_count = 0;
*ppv = &This->IMMDeviceCollection_iface; *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; return S_OK;
} }
static void MMDevCol_Destroy(MMDevColImpl *This) 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); free(This);
} }
...@@ -884,46 +915,33 @@ static ULONG WINAPI MMDevCol_Release(IMMDeviceCollection *iface) ...@@ -884,46 +915,33 @@ static ULONG WINAPI MMDevCol_Release(IMMDeviceCollection *iface)
static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdevs) static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdevs)
{ {
MMDevColImpl *This = impl_from_IMMDeviceCollection(iface); MMDevColImpl *This = impl_from_IMMDeviceCollection(iface);
MMDevice *cur;
TRACE("(%p)->(%p)\n", This, numdevs); TRACE("(%p)->(%p)\n", This, numdevs);
if (!numdevs) if (!numdevs)
return E_POINTER; return E_POINTER;
*numdevs = 0; *numdevs = This->devices_count;
LIST_FOR_EACH_ENTRY(cur, &device_list, MMDevice, entry)
{
if ((cur->flow == This->flow || This->flow == eAll)
&& (cur->state & This->state))
++(*numdevs);
}
return S_OK; return S_OK;
} }
static HRESULT WINAPI MMDevCol_Item(IMMDeviceCollection *iface, UINT n, IMMDevice **dev) static HRESULT WINAPI MMDevCol_Item(IMMDeviceCollection *iface, UINT n, IMMDevice **dev)
{ {
MMDevColImpl *This = impl_from_IMMDeviceCollection(iface); MMDevColImpl *This = impl_from_IMMDeviceCollection(iface);
MMDevice *cur;
DWORD i = 0;
TRACE("(%p)->(%u, %p)\n", This, n, dev); TRACE("(%p)->(%u, %p)\n", This, n, dev);
if (!dev) if (!dev)
return E_POINTER; 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) WARN("Could not obtain item %u\n", n);
&& (cur->state & This->state) *dev = NULL;
&& i++ == n) return E_INVALIDARG;
{
*dev = &cur->IMMDevice_iface;
IMMDevice_AddRef(*dev);
return S_OK;
}
} }
WARN("Could not obtain item %u\n", n);
*dev = NULL; *dev = This->devices[n];
return E_INVALIDARG; IMMDevice_AddRef(*dev);
return S_OK;
} }
static const IMMDeviceCollectionVtbl MMDevColVtbl = static const IMMDeviceCollectionVtbl MMDevColVtbl =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment