2 * Copyright 2011 Andrew Eikum for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/debug.h"
29 #include "wine/list.h"
30 #include "wine/unixlib.h"
33 #include "mmdeviceapi.h"
39 #include "endpointvolume.h"
40 #include "audioclient.h"
41 #include "audiopolicy.h"
44 #include "../mmdevapi/mmdevdrv.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(coreaudio
);
48 static WCHAR drv_key_devicesW
[256];
50 BOOL WINAPI
DllMain(HINSTANCE dll
, DWORD reason
, void *reserved
)
54 case DLL_PROCESS_ATTACH
:
59 DisableThreadLibraryCalls(dll
);
60 if (__wine_init_unix_call())
63 GetModuleFileNameW(dll
, buf
, ARRAY_SIZE(buf
));
65 filename
= wcsrchr(buf
, '\\');
66 filename
= filename
? filename
+ 1 : buf
;
68 swprintf(drv_key_devicesW
, ARRAY_SIZE(drv_key_devicesW
),
69 L
"Software\\Wine\\Drivers\\%s\\devices", filename
);
73 case DLL_PROCESS_DETACH
:
80 static void set_device_guid(EDataFlow flow
, HKEY drv_key
, const WCHAR
*key_name
,
88 lr
= RegCreateKeyExW(HKEY_CURRENT_USER
, drv_key_devicesW
, 0, NULL
, 0, KEY_WRITE
,
89 NULL
, &drv_key
, NULL
);
90 if(lr
!= ERROR_SUCCESS
){
91 ERR("RegCreateKeyEx(drv_key) failed: %lu\n", lr
);
97 lr
= RegCreateKeyExW(drv_key
, key_name
, 0, NULL
, 0, KEY_WRITE
,
99 if(lr
!= ERROR_SUCCESS
){
100 ERR("RegCreateKeyEx(%s) failed: %lu\n", wine_dbgstr_w(key_name
), lr
);
104 lr
= RegSetValueExW(key
, L
"guid", 0, REG_BINARY
, (BYTE
*)guid
,
106 if(lr
!= ERROR_SUCCESS
)
107 ERR("RegSetValueEx(%s\\guid) failed: %lu\n", wine_dbgstr_w(key_name
), lr
);
112 RegCloseKey(drv_key
);
115 void WINAPI
get_device_guid(EDataFlow flow
, const char *dev
, GUID
*guid
)
117 HKEY key
= NULL
, dev_key
;
118 DWORD type
, size
= sizeof(*guid
);
127 MultiByteToWideChar(CP_UTF8
, 0, dev
, -1, key_name
+ 2, ARRAY_SIZE(key_name
) - 2);
129 if(RegOpenKeyExW(HKEY_CURRENT_USER
, drv_key_devicesW
, 0, KEY_WRITE
|KEY_READ
, &key
) == ERROR_SUCCESS
){
130 if(RegOpenKeyExW(key
, key_name
, 0, KEY_READ
, &dev_key
) == ERROR_SUCCESS
){
131 if(RegQueryValueExW(dev_key
, L
"guid", 0, &type
,
132 (BYTE
*)guid
, &size
) == ERROR_SUCCESS
){
133 if(type
== REG_BINARY
){
134 RegCloseKey(dev_key
);
138 ERR("Invalid type for device %s GUID: %lu; ignoring and overwriting\n",
139 wine_dbgstr_w(key_name
), type
);
141 RegCloseKey(dev_key
);
147 set_device_guid(flow
, key
, key_name
, guid
);
153 BOOL WINAPI
get_device_name_from_guid(const GUID
*guid
, char **name
, EDataFlow
*flow
)
160 if(RegOpenKeyExW(HKEY_CURRENT_USER
, drv_key_devicesW
, 0, KEY_READ
, &devices_key
) != ERROR_SUCCESS
){
161 ERR("No devices in registry?\n");
170 key_name_size
= ARRAY_SIZE(key_name
);
171 if(RegEnumKeyExW(devices_key
, i
++, key_name
, &key_name_size
, NULL
,
172 NULL
, NULL
, NULL
) != ERROR_SUCCESS
)
175 if(RegOpenKeyExW(devices_key
, key_name
, 0, KEY_READ
, &key
) != ERROR_SUCCESS
){
176 WARN("Couldn't open key: %s\n", wine_dbgstr_w(key_name
));
180 size
= sizeof(reg_guid
);
181 if(RegQueryValueExW(key
, L
"guid", 0, &type
,
182 (BYTE
*)®_guid
, &size
) == ERROR_SUCCESS
){
183 if(IsEqualGUID(®_guid
, guid
)){
185 RegCloseKey(devices_key
);
187 TRACE("Found matching device key: %s\n", wine_dbgstr_w(key_name
));
189 if(key_name
[0] == '0')
191 else if(key_name
[0] == '1')
194 ERR("Unknown device type: %c\n", key_name
[0]);
198 if(!(size
= WideCharToMultiByte(CP_UTF8
, 0, key_name
+ 2, -1, NULL
, 0, NULL
, NULL
)))
201 if(!(*name
= malloc(size
)))
204 if(!WideCharToMultiByte(CP_UTF8
, 0, key_name
+ 2, -1, *name
, size
, NULL
, NULL
)){
216 RegCloseKey(devices_key
);
218 WARN("No matching device in registry for GUID %s\n", debugstr_guid(guid
));