From 15d06180833da1270de809b90df8a80521b2c60d Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 11 Jul 2022 01:06:57 -0400 Subject: [PATCH] SDL_IMMDevice: Fix a WASAPI-specific leak, clean up Add() --- src/core/windows/SDL_immdevice.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/core/windows/SDL_immdevice.c b/src/core/windows/SDL_immdevice.c index 415f983d8..3b5714c23 100644 --- a/src/core/windows/SDL_immdevice.c +++ b/src/core/windows/SDL_immdevice.c @@ -84,7 +84,7 @@ GetMMDeviceInfo(IMMDevice *device, char **utf8dev, WAVEFORMATEXTENSIBLE *fmt, GU /* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */ typedef struct DevIdList { - WCHAR *str; + LPWSTR str; LPGUID guid; struct DevIdList *next; } DevIdList; @@ -118,7 +118,9 @@ SDL_IMMDevice_Add(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTEN { DevIdList *devidlist; SDL_AudioSpec spec; + LPWSTR devidcopy; LPGUID cpyguid; + LPVOID driverdata; /* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever). In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for @@ -137,20 +139,28 @@ SDL_IMMDevice_Add(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTEN return; /* oh well. */ } - devid = SDL_wcsdup(devid); - if (!devid) { + devidcopy = SDL_wcsdup(devid); + if (!devidcopy) { SDL_free(devidlist); return; /* oh well. */ } - cpyguid = (LPGUID)SDL_malloc(sizeof(GUID)); - if (!cpyguid) { - SDL_free(devidlist); - return; /* oh well. */ + if (useguid) { + /* This is freed by DSOUND_FreeDeviceData! */ + cpyguid = (LPGUID)SDL_malloc(sizeof(GUID)); + if (!cpyguid) { + SDL_free(devidlist); + SDL_free(devidcopy); + return; /* oh well. */ + } + SDL_memcpy(cpyguid, dsoundguid, sizeof(GUID)); + driverdata = cpyguid; + } else { + cpyguid = NULL; + driverdata = devidcopy; } - SDL_memcpy(cpyguid, dsoundguid, sizeof(GUID)); - devidlist->str = (WCHAR *)devid; + devidlist->str = devidcopy; devidlist->guid = cpyguid; devidlist->next = deviceid_list; deviceid_list = devidlist; @@ -159,7 +169,7 @@ SDL_IMMDevice_Add(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTEN spec.channels = (Uint8)fmt->Format.nChannels; spec.freq = fmt->Format.nSamplesPerSec; spec.format = WaveFormatToSDLFormat((WAVEFORMATEX *)fmt); - SDL_AddAudioDevice(iscapture, devname, &spec, useguid ? ((void *) cpyguid) : ((void *) devid)); + SDL_AddAudioDevice(iscapture, devname, &spec, driverdata); } /* We need a COM subclass of IMMNotificationClient for hotplug support, which is