windows: directsound should also map audio device GUIDs to proper names. Moved this code from winmm into core so both can use it. DirectSound (at least on Win10) also returns truncated device names, even though it's handed in as a string pointer and not a static-sized buffer. :/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
diff --git a/src/audio/directsound/SDL_directsound.c b/src/audio/directsound/SDL_directsound.c
index f48d300..ea8e17c 100644
--- a/src/audio/directsound/SDL_directsound.c
+++ b/src/audio/directsound/SDL_directsound.c
@@ -155,7 +155,7 @@ FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
{
const int iscapture = (int) ((size_t) data);
if (guid != NULL) { /* skip default device */
- char *str = WIN_StringToUTF8(desc);
+ char *str = WIN_LookupAudioDeviceName(desc, guid);
if (str != NULL) {
LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID));
SDL_memcpy(cpyguid, guid, sizeof (GUID));
diff --git a/src/audio/winmm/SDL_winmm.c b/src/audio/winmm/SDL_winmm.c
index dea1aac..1cf8020 100644
--- a/src/audio/winmm/SDL_winmm.c
+++ b/src/audio/winmm/SDL_winmm.c
@@ -37,77 +37,6 @@
#define WAVE_FORMAT_IEEE_FLOAT 0x0003
#endif
-/*
-WAVExxxCAPS gives you 31 bytes for the device name, and just truncates if it's
-longer. However, since WinXP, you can use the WAVExxxCAPS2 structure, which
-will give you a name GUID. The full name is in the Windows Registry under
-that GUID, located here: HKLM\System\CurrentControlSet\Control\MediaCategories
-
-Note that drivers can report GUID_NULL for the name GUID, in which case,
-Windows makes a best effort to fill in those 31 bytes in the usual place.
-This info summarized from MSDN:
-
-http://web.archive.org/web/20131027093034/http://msdn.microsoft.com/en-us/library/windows/hardware/ff536382(v=vs.85).aspx
-
-Always look this up in the registry if possible, because the strings are
-different! At least on Win10, I see "Yeti Stereo Microphone" in the
-Registry, and a unhelpful "Microphone(Yeti Stereo Microph" in winmm. Sigh.
-*/
-static char *
-LookupDeviceName(const WCHAR *name, const GUID *guid)
-{
- static const GUID nullguid = { 0 };
- const unsigned char *ptr;
- char keystr[128];
- WCHAR *strw = NULL;
- SDL_bool rc;
- HKEY hkey;
- DWORD len = 0;
- char *retval = NULL;
-
- if (SDL_memcmp(guid, &nullguid, sizeof (*guid)) == 0) {
- return WIN_StringToUTF8(name); /* No GUID, go with what we've got. */
- }
-
- ptr = (const char *) guid;
- SDL_snprintf(keystr, sizeof (keystr),
- "System\\CurrentControlSet\\Control\\MediaCategories\\{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
- ptr[3], ptr[2], ptr[1], ptr[0], ptr[5], ptr[4], ptr[7], ptr[6],
- ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
-
- strw = WIN_UTF8ToString(keystr);
- rc = (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strw, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS);
- SDL_free(strw);
- if (!rc) {
- return WIN_StringToUTF8(name); /* oh well. */
- }
-
- rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, NULL, &len) == ERROR_SUCCESS);
- if (!rc) {
- RegCloseKey(hkey);
- return WIN_StringToUTF8(name); /* oh well. */
- }
-
- strw = (WCHAR *) SDL_malloc(len + sizeof (WCHAR));
- if (!strw) {
- RegCloseKey(hkey);
- return WIN_StringToUTF8(name); /* oh well. */
- }
-
- rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, (LPBYTE) strw, &len) == ERROR_SUCCESS);
- RegCloseKey(hkey);
- if (!rc) {
- SDL_free(strw);
- return WIN_StringToUTF8(name); /* oh well. */
- }
-
- strw[len / 2] = 0; /* make sure it's null-terminated. */
-
- retval = WIN_StringToUTF8(strw);
- SDL_free(strw);
- return retval ? retval : WIN_StringToUTF8(name);
-}
-
#define DETECT_DEV_IMPL(iscap, typ, capstyp) \
static void DetectWave##typ##Devs(void) { \
const UINT iscapture = iscap ? 1 : 0; \
@@ -116,7 +45,7 @@ static void DetectWave##typ##Devs(void) { \
UINT i; \
for (i = 0; i < devcount; i++) { \
if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
- char *name = LookupDeviceName(caps.szPname,&caps.NameGuid); \
+ char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \
if (name != NULL) { \
SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
SDL_free(name); \
diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c
index bc4afe0..a1d366b 100644
--- a/src/core/windows/SDL_windows.c
+++ b/src/core/windows/SDL_windows.c
@@ -124,6 +124,80 @@ BOOL WIN_IsWindowsVistaOrGreater()
#endif
}
+/*
+WAVExxxCAPS gives you 31 bytes for the device name, and just truncates if it's
+longer. However, since WinXP, you can use the WAVExxxCAPS2 structure, which
+will give you a name GUID. The full name is in the Windows Registry under
+that GUID, located here: HKLM\System\CurrentControlSet\Control\MediaCategories
+
+Note that drivers can report GUID_NULL for the name GUID, in which case,
+Windows makes a best effort to fill in those 31 bytes in the usual place.
+This info summarized from MSDN:
+
+http://web.archive.org/web/20131027093034/http://msdn.microsoft.com/en-us/library/windows/hardware/ff536382(v=vs.85).aspx
+
+Always look this up in the registry if possible, because the strings are
+different! At least on Win10, I see "Yeti Stereo Microphone" in the
+Registry, and a unhelpful "Microphone(Yeti Stereo Microph" in winmm. Sigh.
+
+(Also, DirectSound shouldn't be limited to 32 chars, but its device enum
+has the same problem.)
+*/
+char *
+WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
+{
+ static const GUID nullguid = { 0 };
+ const unsigned char *ptr;
+ char keystr[128];
+ WCHAR *strw = NULL;
+ SDL_bool rc;
+ HKEY hkey;
+ DWORD len = 0;
+ char *retval = NULL;
+
+ if (SDL_memcmp(guid, &nullguid, sizeof (*guid)) == 0) {
+ return WIN_StringToUTF8(name); /* No GUID, go with what we've got. */
+ }
+
+ ptr = (const char *) guid;
+ SDL_snprintf(keystr, sizeof (keystr),
+ "System\\CurrentControlSet\\Control\\MediaCategories\\{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ ptr[3], ptr[2], ptr[1], ptr[0], ptr[5], ptr[4], ptr[7], ptr[6],
+ ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
+
+ strw = WIN_UTF8ToString(keystr);
+ rc = (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strw, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS);
+ SDL_free(strw);
+ if (!rc) {
+ return WIN_StringToUTF8(name); /* oh well. */
+ }
+
+ rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, NULL, &len) == ERROR_SUCCESS);
+ if (!rc) {
+ RegCloseKey(hkey);
+ return WIN_StringToUTF8(name); /* oh well. */
+ }
+
+ strw = (WCHAR *) SDL_malloc(len + sizeof (WCHAR));
+ if (!strw) {
+ RegCloseKey(hkey);
+ return WIN_StringToUTF8(name); /* oh well. */
+ }
+
+ rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, (LPBYTE) strw, &len) == ERROR_SUCCESS);
+ RegCloseKey(hkey);
+ if (!rc) {
+ SDL_free(strw);
+ return WIN_StringToUTF8(name); /* oh well. */
+ }
+
+ strw[len / 2] = 0; /* make sure it's null-terminated. */
+
+ retval = WIN_StringToUTF8(strw);
+ SDL_free(strw);
+ return retval ? retval : WIN_StringToUTF8(name);
+}
+
#endif /* __WIN32__ || __WINRT__ */
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h
index 0c99b03..0f67e4b 100644
--- a/src/core/windows/SDL_windows.h
+++ b/src/core/windows/SDL_windows.h
@@ -59,6 +59,9 @@ extern void WIN_CoUninitialize(void);
/* Returns SDL_TRUE if we're running on Windows Vista and newer */
extern BOOL WIN_IsWindowsVistaOrGreater();
+/* You need to SDL_free() the result of this call. */
+extern char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid);
+
#endif /* _INCLUDED_WINDOWS_H */
/* vi: set ts=4 sw=4 expandtab: */