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;
|
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 =
|
||||||
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
|
||||||
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)
|
||||||
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 =
|
||||||
|
|
Loading…
Add table
Reference in a new issue