winmm: Try to get full device names from the Windows Registry.

This commit is contained in:
Ryan C. Gordon 2016-08-07 01:48:38 -04:00
parent ff7df7e687
commit a0ff2554c1
1 changed files with 61 additions and 5 deletions

View File

@ -37,8 +37,7 @@
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 #define WAVE_FORMAT_IEEE_FLOAT 0x0003
#endif #endif
/* !!! FIXME: /*
WAVExxxCAPS gives you 31 bytes for the device name, and just truncates if it's 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 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 will give you a name GUID. The full name is in the Windows Registry under
@ -50,17 +49,74 @@ 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 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) \ #define DETECT_DEV_IMPL(iscap, typ, capstyp) \
static void DetectWave##typ##Devs(void) { \ static void DetectWave##typ##Devs(void) { \
const UINT iscapture = iscap ? 1 : 0; \ const UINT iscapture = iscap ? 1 : 0; \
const UINT devcount = wave##typ##GetNumDevs(); \ const UINT devcount = wave##typ##GetNumDevs(); \
capstyp caps; \ capstyp##2W caps; \
UINT i; \ UINT i; \
for (i = 0; i < devcount; i++) { \ for (i = 0; i < devcount; i++) { \
if (wave##typ##GetDevCaps(i,&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
char *name = WIN_StringToUTF8(caps.szPname); \ char *name = LookupDeviceName(caps.szPname,&caps.NameGuid); \
if (name != NULL) { \ if (name != NULL) { \
SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \ SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
SDL_free(name); \ SDL_free(name); \