Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v3: Keep enumerator refcounting, as there are tests checking it.
dlls/mmdevapi/devenum.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index fc33cac17ec..38ae5f8962d 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -59,7 +59,6 @@ typedef struct MMDevEnumImpl LONG ref; } MMDevEnumImpl;
-static MMDevEnumImpl *MMDevEnumerator; static MMDevice **MMDevice_head; static MMDevice *MMDevice_def_rec, *MMDevice_def_play; static DWORD MMDevice_count; @@ -69,6 +68,7 @@ static const IMMDeviceVtbl MMDeviceVtbl; static const IPropertyStoreVtbl MMDevPropVtbl; static const IMMEndpointVtbl MMEndpointVtbl;
+static MMDevEnumImpl enumerator; static IMMDevice info_device;
typedef struct MMDevColImpl @@ -860,23 +860,15 @@ static const IMMDeviceCollectionVtbl MMDevColVtbl =
HRESULT MMDevEnum_Create(REFIID riid, void **ppv) { - MMDevEnumImpl *This = MMDevEnumerator; - - if (!This) + if (enumerator.ref == 0) { - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); - *ppv = NULL; - if (!This) - return E_OUTOFMEMORY; - This->ref = 1; - This->IMMDeviceEnumerator_iface.lpVtbl = &MMDevEnumVtbl; - MMDevEnumerator = This; - + enumerator.ref = 1; load_devices_from_reg(); load_driver_devices(eRender); load_driver_devices(eCapture); } - return IMMDeviceEnumerator_QueryInterface(&This->IMMDeviceEnumerator_iface, riid, ppv); + + return IMMDeviceEnumerator_QueryInterface(&enumerator.IMMDeviceEnumerator_iface, riid, ppv); }
void MMDevEnum_Free(void) @@ -886,8 +878,6 @@ void MMDevEnum_Free(void) RegCloseKey(key_render); RegCloseKey(key_capture); key_render = key_capture = NULL; - HeapFree(GetProcessHeap(), 0, MMDevEnumerator); - MMDevEnumerator = NULL; }
static HRESULT WINAPI MMDevEnum_QueryInterface(IMMDeviceEnumerator *iface, REFIID riid, void **ppv) @@ -920,8 +910,6 @@ static ULONG WINAPI MMDevEnum_Release(IMMDeviceEnumerator *iface) { MMDevEnumImpl *This = impl_from_IMMDeviceEnumerator(iface); LONG ref = InterlockedDecrement(&This->ref); - if (!ref) - MMDevEnum_Free(); TRACE("Refcount now %i\n", ref); return ref; } @@ -1287,6 +1275,12 @@ static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl = MMDevEnum_UnregisterEndpointNotificationCallback };
+static MMDevEnumImpl enumerator = +{ + {&MMDevEnumVtbl}, + 0, +}; + static HRESULT MMDevPropStore_Create(MMDevice *parent, DWORD access, IPropertyStore **ppv) { MMDevPropStore *This;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mmdevapi/devenum.c | 14 +++----------- dlls/mmdevapi/main.c | 6 ++++++ dlls/mmdevapi/mmdevapi.h | 3 +++ 3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index 38ae5f8962d..a0b36671595 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -373,7 +373,7 @@ static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD st return cur; }
-static HRESULT load_devices_from_reg(void) +HRESULT load_devices_from_reg(void) { DWORD i = 0; HKEY root, cur; @@ -466,7 +466,7 @@ static HRESULT set_format(MMDevice *dev) return S_OK; }
-static HRESULT load_driver_devices(EDataFlow flow) +HRESULT load_driver_devices(EDataFlow flow) { WCHAR **ids; GUID *guids; @@ -860,14 +860,6 @@ static const IMMDeviceCollectionVtbl MMDevColVtbl =
HRESULT MMDevEnum_Create(REFIID riid, void **ppv) { - if (enumerator.ref == 0) - { - enumerator.ref = 1; - load_devices_from_reg(); - load_driver_devices(eRender); - load_driver_devices(eCapture); - } - return IMMDeviceEnumerator_QueryInterface(&enumerator.IMMDeviceEnumerator_iface, riid, ppv); }
@@ -1278,7 +1270,7 @@ static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl = static MMDevEnumImpl enumerator = { {&MMDevEnumVtbl}, - 0, + 1, };
static HRESULT MMDevPropStore_Create(MMDevice *parent, DWORD access, IPropertyStore **ppv) diff --git a/dlls/mmdevapi/main.c b/dlls/mmdevapi/main.c index 9cc0aad6105..358c1697a23 100644 --- a/dlls/mmdevapi/main.c +++ b/dlls/mmdevapi/main.c @@ -148,6 +148,12 @@ static BOOL WINAPI init_driver(INIT_ONCE *once, void *param, void **context) *next = ','; }
+ if (drvs.module != 0){ + load_devices_from_reg(); + load_driver_devices(eRender); + load_driver_devices(eCapture); + } + return drvs.module != 0; }
diff --git a/dlls/mmdevapi/mmdevapi.h b/dlls/mmdevapi/mmdevapi.h index 3bcf568cddf..73c9b0e9592 100644 --- a/dlls/mmdevapi/mmdevapi.h +++ b/dlls/mmdevapi/mmdevapi.h @@ -73,4 +73,7 @@ extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv) DECLSPEC extern HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv) DECLSPEC_HIDDEN; extern HRESULT SpatialAudioClient_Create(IMMDevice *device, ISpatialAudioClient **out) DECLSPEC_HIDDEN;
+extern HRESULT load_devices_from_reg(void) DECLSPEC_HIDDEN; +extern HRESULT load_driver_devices(EDataFlow flow) DECLSPEC_HIDDEN; + extern const WCHAR drv_keyW[] DECLSPEC_HIDDEN;
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Thu, Jun 03, 2021 at 06:15:30PM +0200, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/mmdevapi/devenum.c | 14 +++----------- dlls/mmdevapi/main.c | 6 ++++++ dlls/mmdevapi/mmdevapi.h | 3 +++ 3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index 38ae5f8962d..a0b36671595 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -373,7 +373,7 @@ static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD st return cur; }
-static HRESULT load_devices_from_reg(void) +HRESULT load_devices_from_reg(void) { DWORD i = 0; HKEY root, cur; @@ -466,7 +466,7 @@ static HRESULT set_format(MMDevice *dev) return S_OK; }
-static HRESULT load_driver_devices(EDataFlow flow) +HRESULT load_driver_devices(EDataFlow flow) { WCHAR **ids; GUID *guids; @@ -860,14 +860,6 @@ static const IMMDeviceCollectionVtbl MMDevColVtbl =
HRESULT MMDevEnum_Create(REFIID riid, void **ppv) {
- if (enumerator.ref == 0)
- {
enumerator.ref = 1;
load_devices_from_reg();
load_driver_devices(eRender);
load_driver_devices(eCapture);
- }
- return IMMDeviceEnumerator_QueryInterface(&enumerator.IMMDeviceEnumerator_iface, riid, ppv);
}
@@ -1278,7 +1270,7 @@ static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl = static MMDevEnumImpl enumerator = { {&MMDevEnumVtbl},
- 0,
- 1,
};
static HRESULT MMDevPropStore_Create(MMDevice *parent, DWORD access, IPropertyStore **ppv) diff --git a/dlls/mmdevapi/main.c b/dlls/mmdevapi/main.c index 9cc0aad6105..358c1697a23 100644 --- a/dlls/mmdevapi/main.c +++ b/dlls/mmdevapi/main.c @@ -148,6 +148,12 @@ static BOOL WINAPI init_driver(INIT_ONCE *once, void *param, void **context) *next = ','; }
- if (drvs.module != 0){
load_devices_from_reg();
load_driver_devices(eRender);
load_driver_devices(eCapture);
- }
- return drvs.module != 0;
}
diff --git a/dlls/mmdevapi/mmdevapi.h b/dlls/mmdevapi/mmdevapi.h index 3bcf568cddf..73c9b0e9592 100644 --- a/dlls/mmdevapi/mmdevapi.h +++ b/dlls/mmdevapi/mmdevapi.h @@ -73,4 +73,7 @@ extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv) DECLSPEC extern HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv) DECLSPEC_HIDDEN; extern HRESULT SpatialAudioClient_Create(IMMDevice *device, ISpatialAudioClient **out) DECLSPEC_HIDDEN;
+extern HRESULT load_devices_from_reg(void) DECLSPEC_HIDDEN; +extern HRESULT load_driver_devices(EDataFlow flow) DECLSPEC_HIDDEN;
extern const WCHAR drv_keyW[] DECLSPEC_HIDDEN;
2.31.0
It's not guarded but devices are only created on driver initialization and destroyed on DLL detach.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mmdevapi/devenum.c | 48 ++++++++++++++-------------------------- dlls/mmdevapi/mmdevapi.h | 4 ++++ 2 files changed, 20 insertions(+), 32 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index a0b36671595..b17572425f3 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -59,9 +59,7 @@ typedef struct MMDevEnumImpl LONG ref; } MMDevEnumImpl;
-static MMDevice **MMDevice_head; static MMDevice *MMDevice_def_rec, *MMDevice_def_play; -static DWORD MMDevice_count; static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl; static const IMMDeviceCollectionVtbl MMDevColVtbl; static const IMMDeviceVtbl MMDeviceVtbl; @@ -69,6 +67,7 @@ static const IPropertyStoreVtbl MMDevPropVtbl; static const IMMEndpointVtbl MMEndpointVtbl;
static MMDevEnumImpl enumerator; +static struct list device_list = LIST_INIT(device_list); static IMMDevice info_device;
typedef struct MMDevColImpl @@ -263,9 +262,8 @@ static HRESULT set_driver_prop_value(GUID *id, const EDataFlow flow, const PROPE static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD state, BOOL setdefault) { HKEY key, root; - MMDevice *cur = NULL; + MMDevice *device, *cur = NULL; WCHAR guidstr[39]; - DWORD i;
static const PROPERTYKEY deviceinterface_key = { {0x233164c8, 0x1b2c, 0x4c7d, {0xbc, 0x68, 0xb6, 0x71, 0x68, 0x7a, 0x25, 0x67}}, 1 @@ -275,9 +273,8 @@ static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD st {0xb3f8fa53, 0x0004, 0x438e, {0x90, 0x03, 0x51, 0xa4, 0x6e, 0x13, 0x9b, 0xfc}}, 2 };
- for (i = 0; i < MMDevice_count; ++i) + LIST_FOR_EACH_ENTRY(device, &device_list, MMDevice, entry) { - MMDevice *device = MMDevice_head[i]; if (device->flow == flow && IsEqualGUID(&device->devguid, id)){ cur = device; break; @@ -296,11 +293,7 @@ static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD st InitializeCriticalSection(&cur->crst); cur->crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MMDevice.crst");
- if (!MMDevice_head) - MMDevice_head = HeapAlloc(GetProcessHeap(), 0, sizeof(*MMDevice_head)); - else - MMDevice_head = HeapReAlloc(GetProcessHeap(), 0, MMDevice_head, sizeof(*MMDevice_head)*(1+MMDevice_count)); - MMDevice_head[MMDevice_count++] = cur; + list_add_tail(&device_list, &cur->entry); }else if(cur->ref > 0) WARN("Modifying an MMDevice with postitive reference count!\n");
@@ -495,17 +488,8 @@ HRESULT load_driver_devices(EDataFlow flow)
static void MMDevice_Destroy(MMDevice *This) { - DWORD i; TRACE("Freeing %s\n", debugstr_w(This->drv_id)); - /* Since this function is called at destruction time, reordering of the list is unimportant */ - for (i = 0; i < MMDevice_count; ++i) - { - if (MMDevice_head[i] == This) - { - MMDevice_head[i] = MMDevice_head[--MMDevice_count]; - break; - } - } + list_remove(&This->entry); This->crst.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->crst); HeapFree(GetProcessHeap(), 0, This->drv_id); @@ -806,16 +790,15 @@ static ULONG WINAPI MMDevCol_Release(IMMDeviceCollection *iface) static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdevs) { MMDevColImpl *This = impl_from_IMMDeviceCollection(iface); - DWORD i; + MMDevice *cur;
TRACE("(%p)->(%p)\n", This, numdevs); if (!numdevs) return E_POINTER;
*numdevs = 0; - for (i = 0; i < MMDevice_count; ++i) + LIST_FOR_EACH_ENTRY(cur, &device_list, MMDevice, entry) { - MMDevice *cur = MMDevice_head[i]; if ((cur->flow == This->flow || This->flow == eAll) && (cur->state & This->state)) ++(*numdevs); @@ -826,15 +809,15 @@ static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdev static HRESULT WINAPI MMDevCol_Item(IMMDeviceCollection *iface, UINT n, IMMDevice **dev) { MMDevColImpl *This = impl_from_IMMDeviceCollection(iface); - DWORD i = 0, j = 0; + MMDevice *cur; + DWORD i = 0;
TRACE("(%p)->(%u, %p)\n", This, n, dev); if (!dev) return E_POINTER;
- for (j = 0; j < MMDevice_count; ++j) + LIST_FOR_EACH_ENTRY(cur, &device_list, MMDevice, entry) { - MMDevice *cur = MMDevice_head[j]; if ((cur->flow == This->flow || This->flow == eAll) && (cur->state & This->state) && i++ == n) @@ -865,8 +848,9 @@ HRESULT MMDevEnum_Create(REFIID riid, void **ppv)
void MMDevEnum_Free(void) { - while (MMDevice_count) - MMDevice_Destroy(MMDevice_head[0]); + MMDevice *device, *next; + LIST_FOR_EACH_ENTRY_SAFE(device, next, &device_list, MMDevice, entry) + MMDevice_Destroy(device); RegCloseKey(key_render); RegCloseKey(key_capture); key_render = key_capture = NULL; @@ -1006,7 +990,7 @@ static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint(IMMDeviceEnumerator *ifa static HRESULT WINAPI MMDevEnum_GetDevice(IMMDeviceEnumerator *iface, const WCHAR *name, IMMDevice **device) { MMDevEnumImpl *This = impl_from_IMMDeviceEnumerator(iface); - DWORD i=0; + MMDevice *impl; IMMDevice *dev = NULL;
TRACE("(%p)->(%s,%p)\n", This, debugstr_w(name), device); @@ -1019,11 +1003,11 @@ static HRESULT WINAPI MMDevEnum_GetDevice(IMMDeviceEnumerator *iface, const WCHA return S_OK; }
- for (i = 0; i < MMDevice_count; ++i) + LIST_FOR_EACH_ENTRY(impl, &device_list, MMDevice, entry) { HRESULT hr; WCHAR *str; - dev = &MMDevice_head[i]->IMMDevice_iface; + dev = &impl->IMMDevice_iface; hr = IMMDevice_GetId(dev, &str); if (FAILED(hr)) { diff --git a/dlls/mmdevapi/mmdevapi.h b/dlls/mmdevapi/mmdevapi.h index 73c9b0e9592..db91e333cc8 100644 --- a/dlls/mmdevapi/mmdevapi.h +++ b/dlls/mmdevapi/mmdevapi.h @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <wine/list.h> + extern HRESULT MMDevEnum_Create(REFIID riid, void **ppv) DECLSPEC_HIDDEN; extern void MMDevEnum_Free(void) DECLSPEC_HIDDEN;
@@ -67,6 +69,8 @@ typedef struct MMDevice { DWORD state; GUID devguid; WCHAR *drv_id; + + struct list entry; } MMDevice;
extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv) DECLSPEC_HIDDEN;
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Thu, Jun 03, 2021 at 06:15:31PM +0200, Rémi Bernon wrote:
It's not guarded but devices are only created on driver initialization and destroyed on DLL detach.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/mmdevapi/devenum.c | 48 ++++++++++++++-------------------------- dlls/mmdevapi/mmdevapi.h | 4 ++++ 2 files changed, 20 insertions(+), 32 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index a0b36671595..b17572425f3 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -59,9 +59,7 @@ typedef struct MMDevEnumImpl LONG ref; } MMDevEnumImpl;
-static MMDevice **MMDevice_head; static MMDevice *MMDevice_def_rec, *MMDevice_def_play; -static DWORD MMDevice_count; static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl; static const IMMDeviceCollectionVtbl MMDevColVtbl; static const IMMDeviceVtbl MMDeviceVtbl; @@ -69,6 +67,7 @@ static const IPropertyStoreVtbl MMDevPropVtbl; static const IMMEndpointVtbl MMEndpointVtbl;
static MMDevEnumImpl enumerator; +static struct list device_list = LIST_INIT(device_list); static IMMDevice info_device;
typedef struct MMDevColImpl @@ -263,9 +262,8 @@ static HRESULT set_driver_prop_value(GUID *id, const EDataFlow flow, const PROPE static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD state, BOOL setdefault) { HKEY key, root;
- MMDevice *cur = NULL;
- MMDevice *device, *cur = NULL; WCHAR guidstr[39];
DWORD i;
static const PROPERTYKEY deviceinterface_key = { {0x233164c8, 0x1b2c, 0x4c7d, {0xbc, 0x68, 0xb6, 0x71, 0x68, 0x7a, 0x25, 0x67}}, 1
@@ -275,9 +273,8 @@ static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD st {0xb3f8fa53, 0x0004, 0x438e, {0x90, 0x03, 0x51, 0xa4, 0x6e, 0x13, 0x9b, 0xfc}}, 2 };
- for (i = 0; i < MMDevice_count; ++i)
- LIST_FOR_EACH_ENTRY(device, &device_list, MMDevice, entry) {
MMDevice *device = MMDevice_head[i]; if (device->flow == flow && IsEqualGUID(&device->devguid, id)){ cur = device; break;
@@ -296,11 +293,7 @@ static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD st InitializeCriticalSection(&cur->crst); cur->crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MMDevice.crst");
if (!MMDevice_head)
MMDevice_head = HeapAlloc(GetProcessHeap(), 0, sizeof(*MMDevice_head));
else
MMDevice_head = HeapReAlloc(GetProcessHeap(), 0, MMDevice_head, sizeof(*MMDevice_head)*(1+MMDevice_count));
MMDevice_head[MMDevice_count++] = cur;
}else if(cur->ref > 0) WARN("Modifying an MMDevice with postitive reference count!\n");list_add_tail(&device_list, &cur->entry);
@@ -495,17 +488,8 @@ HRESULT load_driver_devices(EDataFlow flow)
static void MMDevice_Destroy(MMDevice *This) {
- DWORD i; TRACE("Freeing %s\n", debugstr_w(This->drv_id));
- /* Since this function is called at destruction time, reordering of the list is unimportant */
- for (i = 0; i < MMDevice_count; ++i)
- {
if (MMDevice_head[i] == This)
{
MMDevice_head[i] = MMDevice_head[--MMDevice_count];
break;
}
- }
- list_remove(&This->entry); This->crst.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->crst); HeapFree(GetProcessHeap(), 0, This->drv_id);
@@ -806,16 +790,15 @@ static ULONG WINAPI MMDevCol_Release(IMMDeviceCollection *iface) static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdevs) { MMDevColImpl *This = impl_from_IMMDeviceCollection(iface);
- DWORD i;
MMDevice *cur;
TRACE("(%p)->(%p)\n", This, numdevs); if (!numdevs) return E_POINTER;
*numdevs = 0;
- for (i = 0; i < MMDevice_count; ++i)
- LIST_FOR_EACH_ENTRY(cur, &device_list, MMDevice, entry) {
MMDevice *cur = MMDevice_head[i]; if ((cur->flow == This->flow || This->flow == eAll) && (cur->state & This->state)) ++(*numdevs);
@@ -826,15 +809,15 @@ static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdev static HRESULT WINAPI MMDevCol_Item(IMMDeviceCollection *iface, UINT n, IMMDevice **dev) { MMDevColImpl *This = impl_from_IMMDeviceCollection(iface);
- DWORD i = 0, j = 0;
MMDevice *cur;
DWORD i = 0;
TRACE("(%p)->(%u, %p)\n", This, n, dev); if (!dev) return E_POINTER;
- for (j = 0; j < MMDevice_count; ++j)
- LIST_FOR_EACH_ENTRY(cur, &device_list, MMDevice, entry) {
MMDevice *cur = MMDevice_head[j]; if ((cur->flow == This->flow || This->flow == eAll) && (cur->state & This->state) && i++ == n)
@@ -865,8 +848,9 @@ HRESULT MMDevEnum_Create(REFIID riid, void **ppv)
void MMDevEnum_Free(void) {
- while (MMDevice_count)
MMDevice_Destroy(MMDevice_head[0]);
- MMDevice *device, *next;
- LIST_FOR_EACH_ENTRY_SAFE(device, next, &device_list, MMDevice, entry)
RegCloseKey(key_render); RegCloseKey(key_capture); key_render = key_capture = NULL;MMDevice_Destroy(device);
@@ -1006,7 +990,7 @@ static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint(IMMDeviceEnumerator *ifa static HRESULT WINAPI MMDevEnum_GetDevice(IMMDeviceEnumerator *iface, const WCHAR *name, IMMDevice **device) { MMDevEnumImpl *This = impl_from_IMMDeviceEnumerator(iface);
- DWORD i=0;
MMDevice *impl; IMMDevice *dev = NULL;
TRACE("(%p)->(%s,%p)\n", This, debugstr_w(name), device);
@@ -1019,11 +1003,11 @@ static HRESULT WINAPI MMDevEnum_GetDevice(IMMDeviceEnumerator *iface, const WCHA return S_OK; }
- for (i = 0; i < MMDevice_count; ++i)
- LIST_FOR_EACH_ENTRY(impl, &device_list, MMDevice, entry) { HRESULT hr; WCHAR *str;
dev = &MMDevice_head[i]->IMMDevice_iface;
dev = &impl->IMMDevice_iface; hr = IMMDevice_GetId(dev, &str); if (FAILED(hr)) {
diff --git a/dlls/mmdevapi/mmdevapi.h b/dlls/mmdevapi/mmdevapi.h index 73c9b0e9592..db91e333cc8 100644 --- a/dlls/mmdevapi/mmdevapi.h +++ b/dlls/mmdevapi/mmdevapi.h @@ -16,6 +16,8 @@
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <wine/list.h>
extern HRESULT MMDevEnum_Create(REFIID riid, void **ppv) DECLSPEC_HIDDEN; extern void MMDevEnum_Free(void) DECLSPEC_HIDDEN;
@@ -67,6 +69,8 @@ typedef struct MMDevice { DWORD state; GUID devguid; WCHAR *drv_id;
- struct list entry;
} MMDevice;
extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv) DECLSPEC_HIDDEN;
2.31.0
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Thu, Jun 03, 2021 at 06:15:29PM +0200, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
v3: Keep enumerator refcounting, as there are tests checking it.
dlls/mmdevapi/devenum.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index fc33cac17ec..38ae5f8962d 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -59,7 +59,6 @@ typedef struct MMDevEnumImpl LONG ref; } MMDevEnumImpl;
-static MMDevEnumImpl *MMDevEnumerator; static MMDevice **MMDevice_head; static MMDevice *MMDevice_def_rec, *MMDevice_def_play; static DWORD MMDevice_count; @@ -69,6 +68,7 @@ static const IMMDeviceVtbl MMDeviceVtbl; static const IPropertyStoreVtbl MMDevPropVtbl; static const IMMEndpointVtbl MMEndpointVtbl;
+static MMDevEnumImpl enumerator; static IMMDevice info_device;
typedef struct MMDevColImpl @@ -860,23 +860,15 @@ static const IMMDeviceCollectionVtbl MMDevColVtbl =
HRESULT MMDevEnum_Create(REFIID riid, void **ppv) {
- MMDevEnumImpl *This = MMDevEnumerator;
- if (!This)
- if (enumerator.ref == 0) {
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
*ppv = NULL;
if (!This)
return E_OUTOFMEMORY;
This->ref = 1;
This->IMMDeviceEnumerator_iface.lpVtbl = &MMDevEnumVtbl;
MMDevEnumerator = This;
}enumerator.ref = 1; load_devices_from_reg(); load_driver_devices(eRender); load_driver_devices(eCapture);
- return IMMDeviceEnumerator_QueryInterface(&This->IMMDeviceEnumerator_iface, riid, ppv);
- return IMMDeviceEnumerator_QueryInterface(&enumerator.IMMDeviceEnumerator_iface, riid, ppv);
}
void MMDevEnum_Free(void) @@ -886,8 +878,6 @@ void MMDevEnum_Free(void) RegCloseKey(key_render); RegCloseKey(key_capture); key_render = key_capture = NULL;
- HeapFree(GetProcessHeap(), 0, MMDevEnumerator);
- MMDevEnumerator = NULL;
}
static HRESULT WINAPI MMDevEnum_QueryInterface(IMMDeviceEnumerator *iface, REFIID riid, void **ppv) @@ -920,8 +910,6 @@ static ULONG WINAPI MMDevEnum_Release(IMMDeviceEnumerator *iface) { MMDevEnumImpl *This = impl_from_IMMDeviceEnumerator(iface); LONG ref = InterlockedDecrement(&This->ref);
- if (!ref)
TRACE("Refcount now %i\n", ref); return ref;MMDevEnum_Free();
} @@ -1287,6 +1275,12 @@ static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl = MMDevEnum_UnregisterEndpointNotificationCallback };
+static MMDevEnumImpl enumerator = +{
- {&MMDevEnumVtbl},
- 0,
+};
static HRESULT MMDevPropStore_Create(MMDevice *parent, DWORD access, IPropertyStore **ppv) { MMDevPropStore *This; -- 2.31.0