mmdevapi: Make IMMDeviceCollection immutable after creation.
This commit is contained in:
parent
7a529fc94f
commit
d86627a27a
1 changed files with 44 additions and 26 deletions
|
@ -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 =
|
||||
|
|
Loading…
Add table
Reference in a new issue