mmdevapi: Attempt to determine default devices from the registry.

This uses a new, Wine-specific registry key
<HKCU\Software\Wine\Drivers\wine<driver>.drv> to determine the correct
device to use for the various defaults. The drivers still supply their
own defaults which will be chosen if no registry entry is defined. For
portability we use a driver-specific key in order to support default
devices for each of the driver backends.
This commit is contained in:
Andrew Eikum 2011-10-05 13:39:53 -05:00 committed by Alexandre Julliard
parent b07a82c01d
commit 66724f617e
3 changed files with 70 additions and 9 deletions

View File

@ -909,21 +909,79 @@ static HRESULT WINAPI MMDevEnum_EnumAudioEndpoints(IMMDeviceEnumerator *iface, E
static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint(IMMDeviceEnumerator *iface, EDataFlow flow, ERole role, IMMDevice **device) static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint(IMMDeviceEnumerator *iface, EDataFlow flow, ERole role, IMMDevice **device)
{ {
MMDevEnumImpl *This = impl_from_IMMDeviceEnumerator(iface); MMDevEnumImpl *This = impl_from_IMMDeviceEnumerator(iface);
WCHAR reg_key[256];
HKEY key;
HRESULT hr;
static const WCHAR slashW[] = {'\\',0};
static const WCHAR reg_out_nameW[] = {'D','e','f','a','u','l','t','O','u','t','p','u','t',0};
static const WCHAR reg_vout_nameW[] = {'D','e','f','a','u','l','t','V','o','i','c','e','O','u','t','p','u','t',0};
static const WCHAR reg_in_nameW[] = {'D','e','f','a','u','l','t','I','n','p','u','t',0};
static const WCHAR reg_vin_nameW[] = {'D','e','f','a','u','l','t','V','o','i','c','e','I','n','p','u','t',0};
TRACE("(%p)->(%u,%u,%p)\n", This, flow, role, device); TRACE("(%p)->(%u,%u,%p)\n", This, flow, role, device);
if (!device) if (!device)
return E_POINTER; return E_POINTER;
if((flow != eRender && flow != eCapture) ||
(role != eConsole && role != eMultimedia && role != eCommunications)){
WARN("Unknown flow (%u) or role (%u)\n", flow, role);
return E_INVALIDARG;
}
*device = NULL; *device = NULL;
if(!drvs.module_name[0])
return E_NOTFOUND;
lstrcpyW(reg_key, drv_keyW);
lstrcatW(reg_key, slashW);
lstrcatW(reg_key, drvs.module_name);
if(RegOpenKeyW(HKEY_CURRENT_USER, reg_key, &key) == ERROR_SUCCESS){
const WCHAR *reg_x_name, *reg_vx_name;
WCHAR def_id[256];
DWORD size = sizeof(def_id);
if(flow == eRender){
reg_x_name = reg_out_nameW;
reg_vx_name = reg_vout_nameW;
}else{
reg_x_name = reg_in_nameW;
reg_vx_name = reg_vin_nameW;
}
if(role == eCommunications &&
RegQueryValueExW(key, reg_vx_name, 0, NULL,
(BYTE*)def_id, &size) == ERROR_SUCCESS){
hr = IMMDeviceEnumerator_GetDevice(iface, def_id, device);
if(SUCCEEDED(hr)){
RegCloseKey(key);
return S_OK;
}
TRACE("Unable to find voice device %s\n", wine_dbgstr_w(def_id));
}
if(RegQueryValueExW(key, reg_x_name, 0, NULL,
(BYTE*)def_id, &size) == ERROR_SUCCESS){
hr = IMMDeviceEnumerator_GetDevice(iface, def_id, device);
if(SUCCEEDED(hr)){
RegCloseKey(key);
return S_OK;
}
TRACE("Unable to find device %s\n", wine_dbgstr_w(def_id));
}
RegCloseKey(key);
}
if (flow == eRender) if (flow == eRender)
*device = &MMDevice_def_play->IMMDevice_iface; *device = &MMDevice_def_play->IMMDevice_iface;
else if (flow == eCapture)
*device = &MMDevice_def_rec->IMMDevice_iface;
else else
{ *device = &MMDevice_def_rec->IMMDevice_iface;
WARN("Unknown flow %u\n", flow);
return E_INVALIDARG;
}
if (!*device) if (!*device)
return E_NOTFOUND; return E_NOTFOUND;

View File

@ -53,6 +53,9 @@ static HINSTANCE instance;
DriverFuncs drvs; DriverFuncs drvs;
const WCHAR drv_keyW[] = {'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','D','r','i','v','e','r','s',0};
static const char *get_priority_string(int prio) static const char *get_priority_string(int prio)
{ {
switch(prio){ switch(prio){
@ -106,8 +109,6 @@ static BOOL load_driver(const WCHAR *name, DriverFuncs *driver)
static BOOL init_driver(void) static BOOL init_driver(void)
{ {
static const WCHAR drv_key[] = {'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','D','r','i','v','e','r','s',0};
static const WCHAR drv_value[] = {'A','u','d','i','o',0}; static const WCHAR drv_value[] = {'A','u','d','i','o',0};
static WCHAR default_list[] = {'a','l','s','a',',','o','s','s',',', static WCHAR default_list[] = {'a','l','s','a',',','o','s','s',',',
@ -120,7 +121,7 @@ static BOOL init_driver(void)
if(drvs.module) if(drvs.module)
return TRUE; return TRUE;
if(RegOpenKeyW(HKEY_CURRENT_USER, drv_key, &key) == ERROR_SUCCESS){ if(RegOpenKeyW(HKEY_CURRENT_USER, drv_keyW, &key) == ERROR_SUCCESS){
DWORD size = sizeof(reg_list); DWORD size = sizeof(reg_list);
if(RegQueryValueExW(key, drv_value, 0, NULL, (BYTE*)reg_list, if(RegQueryValueExW(key, drv_value, 0, NULL, (BYTE*)reg_list,

View File

@ -75,3 +75,5 @@ typedef struct MMDevice {
extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv) DECLSPEC_HIDDEN; extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv) DECLSPEC_HIDDEN;
extern HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolume **ppv) DECLSPEC_HIDDEN; extern HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolume **ppv) DECLSPEC_HIDDEN;
extern const WCHAR drv_keyW[] DECLSPEC_HIDDEN;