ReactOS 0.4.15-dev-7788-g1ad9096
devenum.c File Reference
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winreg.h"
#include "wine/debug.h"
#include "wine/list.h"
#include "initguid.h"
#include "ole2.h"
#include "mmdeviceapi.h"
#include "dshow.h"
#include "dsound.h"
#include "audioclient.h"
#include "endpointvolume.h"
#include "audiopolicy.h"
#include "mmdevapi.h"
#include "devpkey.h"
Include dependency graph for devenum.c:

Go to the source code of this file.

Classes

struct  MMDevPropStoreImpl
 
struct  MMDevEnumImpl
 
struct  MMDevColImpl
 
struct  IPropertyBagImpl
 
struct  NotificationClientWrapper
 

Macros

#define NONAMELESSUNION
 
#define COBJMACROS
 

Typedefs

typedef struct MMDevPropStoreImpl MMDevPropStore
 
typedef struct MMDevEnumImpl MMDevEnumImpl
 
typedef struct MMDevColImpl MMDevColImpl
 
typedef struct IPropertyBagImpl IPropertyBagImpl
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (mmdevapi)
 
static HRESULT MMDevPropStore_Create (MMDevice *This, DWORD access, IPropertyStore **ppv)
 
static MMDevPropStoreimpl_from_IPropertyStore (IPropertyStore *iface)
 
static MMDevEnumImplimpl_from_IMMDeviceEnumerator (IMMDeviceEnumerator *iface)
 
static MMDevColImplimpl_from_IMMDeviceCollection (IMMDeviceCollection *iface)
 
static IPropertyBagImplimpl_from_IPropertyBag (IPropertyBag *iface)
 
static HRESULT MMDevPropStore_OpenPropKey (const GUID *guid, DWORD flow, HKEY *propkey)
 
static HRESULT MMDevice_GetPropValue (const GUID *devguid, DWORD flow, REFPROPERTYKEY key, PROPVARIANT *pv)
 
static HRESULT MMDevice_SetPropValue (const GUID *devguid, DWORD flow, REFPROPERTYKEY key, REFPROPVARIANT pv)
 
static HRESULT set_driver_prop_value (GUID *id, const EDataFlow flow, const PROPERTYKEY *prop)
 
static MMDeviceMMDevice_Create (WCHAR *name, GUID *id, EDataFlow flow, DWORD state, BOOL setdefault)
 
static HRESULT load_devices_from_reg (void)
 
static HRESULT set_format (MMDevice *dev)
 
static HRESULT load_driver_devices (EDataFlow flow)
 
static void MMDevice_Destroy (MMDevice *This)
 
static MMDeviceimpl_from_IMMDevice (IMMDevice *iface)
 
static HRESULT WINAPI MMDevice_QueryInterface (IMMDevice *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI MMDevice_AddRef (IMMDevice *iface)
 
static ULONG WINAPI MMDevice_Release (IMMDevice *iface)
 
static HRESULT WINAPI MMDevice_Activate (IMMDevice *iface, REFIID riid, DWORD clsctx, PROPVARIANT *params, void **ppv)
 
static HRESULT WINAPI MMDevice_OpenPropertyStore (IMMDevice *iface, DWORD access, IPropertyStore **ppv)
 
static HRESULT WINAPI MMDevice_GetId (IMMDevice *iface, WCHAR **itemid)
 
static HRESULT WINAPI MMDevice_GetState (IMMDevice *iface, DWORD *state)
 
static MMDeviceimpl_from_IMMEndpoint (IMMEndpoint *iface)
 
static HRESULT WINAPI MMEndpoint_QueryInterface (IMMEndpoint *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI MMEndpoint_AddRef (IMMEndpoint *iface)
 
static ULONG WINAPI MMEndpoint_Release (IMMEndpoint *iface)
 
static HRESULT WINAPI MMEndpoint_GetDataFlow (IMMEndpoint *iface, EDataFlow *flow)
 
static HRESULT MMDevCol_Create (IMMDeviceCollection **ppv, EDataFlow flow, DWORD state)
 
static void MMDevCol_Destroy (MMDevColImpl *This)
 
static HRESULT WINAPI MMDevCol_QueryInterface (IMMDeviceCollection *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI MMDevCol_AddRef (IMMDeviceCollection *iface)
 
static ULONG WINAPI MMDevCol_Release (IMMDeviceCollection *iface)
 
static HRESULT WINAPI MMDevCol_GetCount (IMMDeviceCollection *iface, UINT *numdevs)
 
static HRESULT WINAPI MMDevCol_Item (IMMDeviceCollection *iface, UINT n, IMMDevice **dev)
 
HRESULT MMDevEnum_Create (REFIID riid, void **ppv)
 
void MMDevEnum_Free (void)
 
static HRESULT WINAPI MMDevEnum_QueryInterface (IMMDeviceEnumerator *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI MMDevEnum_AddRef (IMMDeviceEnumerator *iface)
 
static ULONG WINAPI MMDevEnum_Release (IMMDeviceEnumerator *iface)
 
static HRESULT WINAPI MMDevEnum_EnumAudioEndpoints (IMMDeviceEnumerator *iface, EDataFlow flow, DWORD mask, IMMDeviceCollection **devices)
 
static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint (IMMDeviceEnumerator *iface, EDataFlow flow, ERole role, IMMDevice **device)
 
static HRESULT WINAPI MMDevEnum_GetDevice (IMMDeviceEnumerator *iface, const WCHAR *name, IMMDevice **device)
 
static void notify_clients (EDataFlow flow, ERole role, const WCHAR *id)
 
static BOOL notify_if_changed (EDataFlow flow, ERole role, HKEY key, const WCHAR *val_name, WCHAR *old_val, IMMDevice *def_dev)
 
static DWORD WINAPI notif_thread_proc (void *user)
 
static HRESULT WINAPI MMDevEnum_RegisterEndpointNotificationCallback (IMMDeviceEnumerator *iface, IMMNotificationClient *client)
 
static HRESULT WINAPI MMDevEnum_UnregisterEndpointNotificationCallback (IMMDeviceEnumerator *iface, IMMNotificationClient *client)
 
static void MMDevPropStore_Destroy (MMDevPropStore *This)
 
static HRESULT WINAPI MMDevPropStore_QueryInterface (IPropertyStore *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI MMDevPropStore_AddRef (IPropertyStore *iface)
 
static ULONG WINAPI MMDevPropStore_Release (IPropertyStore *iface)
 
static HRESULT WINAPI MMDevPropStore_GetCount (IPropertyStore *iface, DWORD *nprops)
 
static HRESULT WINAPI MMDevPropStore_GetAt (IPropertyStore *iface, DWORD prop, PROPERTYKEY *key)
 
static HRESULT WINAPI MMDevPropStore_GetValue (IPropertyStore *iface, REFPROPERTYKEY key, PROPVARIANT *pv)
 
static HRESULT WINAPI MMDevPropStore_SetValue (IPropertyStore *iface, REFPROPERTYKEY key, REFPROPVARIANT pv)
 
static HRESULT WINAPI MMDevPropStore_Commit (IPropertyStore *iface)
 
static HRESULT WINAPI PB_QueryInterface (IPropertyBag *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI PB_AddRef (IPropertyBag *iface)
 
static ULONG WINAPI PB_Release (IPropertyBag *iface)
 
static HRESULT WINAPI PB_Read (IPropertyBag *iface, LPCOLESTR name, VARIANT *var, IErrorLog *log)
 
static HRESULT WINAPI PB_Write (IPropertyBag *iface, LPCOLESTR name, VARIANT *var)
 
static ULONG WINAPI info_device_ps_AddRef (IPropertyStore *iface)
 
static ULONG WINAPI info_device_ps_Release (IPropertyStore *iface)
 
static HRESULT WINAPI info_device_ps_GetValue (IPropertyStore *iface, REFPROPERTYKEY key, PROPVARIANT *pv)
 
static ULONG WINAPI info_device_AddRef (IMMDevice *iface)
 
static ULONG WINAPI info_device_Release (IMMDevice *iface)
 
static HRESULT WINAPI info_device_OpenPropertyStore (IMMDevice *iface, DWORD access, IPropertyStore **ppv)
 

Variables

static const WCHAR software_mmdevapi []
 
static const WCHAR reg_render []
 
static const WCHAR reg_capture []
 
static const WCHAR reg_devicestate []
 
static const WCHAR reg_properties []
 
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}
 
static HKEY key_render
 
static HKEY key_capture
 
static MMDevEnumImplMMDevEnumerator
 
static MMDevice ** MMDevice_head
 
static MMDeviceMMDevice_def_rec
 
static MMDeviceMMDevice_def_play
 
static DWORD MMDevice_count
 
static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl
 
static const IMMDeviceCollectionVtbl MMDevColVtbl
 
static const IMMDeviceVtbl MMDeviceVtbl
 
static const IPropertyStoreVtbl MMDevPropVtbl
 
static const IMMEndpointVtbl MMEndpointVtbl
 
static IMMDevice info_device
 
static const IPropertyBagVtbl PB_Vtbl
 
static const WCHAR propkey_formatW []
 
static struct list g_notif_clients = LIST_INIT(g_notif_clients)
 
static HANDLE g_notif_thread
 
static CRITICAL_SECTION g_notif_lock = { &g_notif_lock_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG g_notif_lock_debug
 
static const IPropertyStoreVtbl info_device_ps_Vtbl
 
static IPropertyStore info_device_ps
 
static const IMMDeviceVtbl info_device_Vtbl
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 22 of file devenum.c.

◆ NONAMELESSUNION

#define NONAMELESSUNION

Definition at line 21 of file devenum.c.

Typedef Documentation

◆ IPropertyBagImpl

◆ MMDevColImpl

◆ MMDevEnumImpl

◆ MMDevPropStore

Function Documentation

◆ impl_from_IMMDevice()

static MMDevice * impl_from_IMMDevice ( IMMDevice iface)
inlinestatic

Definition at line 537 of file devenum.c.

538{
539 return CONTAINING_RECORD(iface, MMDevice, IMMDevice_iface);
540}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by MMDevice_Activate(), MMDevice_AddRef(), MMDevice_GetId(), MMDevice_GetState(), MMDevice_OpenPropertyStore(), MMDevice_QueryInterface(), and MMDevice_Release().

◆ impl_from_IMMDeviceCollection()

static MMDevColImpl * impl_from_IMMDeviceCollection ( IMMDeviceCollection iface)
inlinestatic

Definition at line 121 of file devenum.c.

122{
123 return CONTAINING_RECORD(iface, MMDevColImpl, IMMDeviceCollection_iface);
124}

Referenced by MMDevCol_AddRef(), MMDevCol_GetCount(), MMDevCol_Item(), MMDevCol_QueryInterface(), and MMDevCol_Release().

◆ impl_from_IMMDeviceEnumerator()

◆ impl_from_IMMEndpoint()

static MMDevice * impl_from_IMMEndpoint ( IMMEndpoint iface)
inlinestatic

Definition at line 725 of file devenum.c.

726{
727 return CONTAINING_RECORD(iface, MMDevice, IMMEndpoint_iface);
728}

Referenced by MMEndpoint_AddRef(), MMEndpoint_GetDataFlow(), MMEndpoint_QueryInterface(), and MMEndpoint_Release().

◆ impl_from_IPropertyBag()

static IPropertyBagImpl * impl_from_IPropertyBag ( IPropertyBag iface)
inlinestatic

Definition at line 126 of file devenum.c.

127{
128 return CONTAINING_RECORD(iface, IPropertyBagImpl, IPropertyBag_iface);
129}

Referenced by PB_Read().

◆ impl_from_IPropertyStore()

◆ info_device_AddRef()

static ULONG WINAPI info_device_AddRef ( IMMDevice iface)
static

Definition at line 1602 of file devenum.c.

1603{
1604 return 2;
1605}

◆ info_device_OpenPropertyStore()

static HRESULT WINAPI info_device_OpenPropertyStore ( IMMDevice iface,
DWORD  access,
IPropertyStore **  ppv 
)
static

Definition at line 1612 of file devenum.c.

1614{
1615 TRACE("(static)->(%x, %p)\n", access, ppv);
1616 *ppv = &info_device_ps;
1617 return S_OK;
1618}
static IPropertyStore info_device_ps
Definition: devenum.c:1598
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define TRACE(s)
Definition: solgame.cpp:4

◆ info_device_ps_AddRef()

static ULONG WINAPI info_device_ps_AddRef ( IPropertyStore iface)
static

Definition at line 1554 of file devenum.c.

1555{
1556 return 2;
1557}

◆ info_device_ps_GetValue()

static HRESULT WINAPI info_device_ps_GetValue ( IPropertyStore iface,
REFPROPERTYKEY  key,
PROPVARIANT *  pv 
)
static

Definition at line 1564 of file devenum.c.

1566{
1567 TRACE("(static)->(\"%s,%u\", %p)\n", debugstr_guid(&key->fmtid), key ? key->pid : 0, pv);
1568
1569 if (!key || !pv)
1570 return E_POINTER;
1571
1572 if (IsEqualPropertyKey(*key, DEVPKEY_Device_Driver))
1573 {
1574 INT size = (lstrlenW(drvs.module_name) + 1) * sizeof(WCHAR);
1575 pv->vt = VT_LPWSTR;
1576 pv->u.pwszVal = CoTaskMemAlloc(size);
1577 if (!pv->u.pwszVal)
1578 return E_OUTOFMEMORY;
1579 memcpy(pv->u.pwszVal, drvs.module_name, size);
1580 return S_OK;
1581 }
1582
1583 return E_INVALIDARG;
1584}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
@ VT_LPWSTR
Definition: compat.h:2325
#define lstrlenW
Definition: compat.h:750
DriverFuncs drvs
Definition: main.c:48
GLsizeiptr size
Definition: glext.h:5919
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
#define debugstr_guid
Definition: kernel32.h:35
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define IsEqualPropertyKey(a, b)
Definition: propkeydef.h:52
WCHAR module_name[64]
Definition: mmdevapi.h:35
Definition: copy.c:22
int32_t INT
Definition: typedefs.h:58
#define E_POINTER
Definition: winerror.h:2365
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ info_device_ps_Release()

static ULONG WINAPI info_device_ps_Release ( IPropertyStore iface)
static

Definition at line 1559 of file devenum.c.

1560{
1561 return 1;
1562}

◆ info_device_Release()

static ULONG WINAPI info_device_Release ( IMMDevice iface)
static

Definition at line 1607 of file devenum.c.

1608{
1609 return 1;
1610}

◆ load_devices_from_reg()

static HRESULT load_devices_from_reg ( void  )
static

Definition at line 400 of file devenum.c.

401{
402 DWORD i = 0;
403 HKEY root, cur;
404 LONG ret;
405 DWORD curflow;
406
408 if (ret == ERROR_SUCCESS)
410 if (ret == ERROR_SUCCESS)
414 curflow = eCapture;
415 if (ret != ERROR_SUCCESS)
416 {
419 WARN("Couldn't create key: %u\n", ret);
420 return E_FAIL;
421 }
422
423 do {
424 WCHAR guidvalue[39];
425 GUID guid;
426 DWORD len;
427 PROPVARIANT pv = { VT_EMPTY };
428
429 len = ARRAY_SIZE(guidvalue);
430 ret = RegEnumKeyExW(cur, i++, guidvalue, &len, NULL, NULL, NULL, NULL);
432 {
433 if (cur == key_capture)
434 {
435 cur = key_render;
436 curflow = eRender;
437 i = 0;
438 continue;
439 }
440 break;
441 }
442 if (ret != ERROR_SUCCESS)
443 continue;
444 if (SUCCEEDED(CLSIDFromString(guidvalue, &guid))
445 && SUCCEEDED(MMDevice_GetPropValue(&guid, curflow, (const PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &pv))
446 && pv.vt == VT_LPWSTR)
447 {
448 DWORD size_bytes = (lstrlenW(pv.u.pwszVal) + 1) * sizeof(WCHAR);
449 WCHAR *name = HeapAlloc(GetProcessHeap(), 0, size_bytes);
450 memcpy(name, pv.u.pwszVal, size_bytes);
451 MMDevice_Create(name, &guid, curflow,
452 DEVICE_STATE_NOTPRESENT, FALSE);
453 CoTaskMemFree(pv.u.pwszVal);
454 }
455 } while (1);
456
457 return S_OK;
458}
#define ARRAY_SIZE(A)
Definition: main.h:33
#define WARN(fmt,...)
Definition: debug.h:112
#define RegCloseKey(hKey)
Definition: registry.h:49
struct _root root
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2533
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
@ VT_EMPTY
Definition: compat.h:2295
static HKEY key_render
Definition: devenum.c:65
static const WCHAR software_mmdevapi[]
Definition: devenum.c:44
static HRESULT MMDevice_GetPropValue(const GUID *devguid, DWORD flow, REFPROPERTYKEY key, PROPVARIANT *pv)
Definition: devenum.c:158
static HKEY key_capture
Definition: devenum.c:66
static const WCHAR reg_capture[]
Definition: devenum.c:53
static const WCHAR reg_render[]
Definition: devenum.c:51
static MMDevice * MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD state, BOOL setdefault)
Definition: devenum.c:287
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
unsigned long DWORD
Definition: ntddk_ex.h:95
FxCollectionEntry * cur
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
#define SUCCEEDED(hr)
Definition: intsafe.h:50
const GUID * guid
@ eCapture
Definition: mmdeviceapi.idl:64
@ eRender
Definition: mmdeviceapi.idl:63
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_WRITE
Definition: nt_native.h:1031
long LONG
Definition: pedump.c:60
Definition: name.c:39
int ret
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46

Referenced by MMDevEnum_Create().

◆ load_driver_devices()

static HRESULT load_driver_devices ( EDataFlow  flow)
static

Definition at line 491 of file devenum.c.

492{
493 WCHAR **ids;
494 GUID *guids;
495 UINT num, def, i;
496 HRESULT hr;
497
498 if(!drvs.pGetEndpointIDs)
499 return S_OK;
500
501 hr = drvs.pGetEndpointIDs(flow, &ids, &guids, &num, &def);
502 if(FAILED(hr))
503 return hr;
504
505 for(i = 0; i < num; ++i){
506 MMDevice *dev;
507 dev = MMDevice_Create(ids[i], &guids[i], flow, DEVICE_STATE_ACTIVE,
508 def == i);
510 }
511
512 HeapFree(GetProcessHeap(), 0, guids);
514
515 return S_OK;
516}
#define HeapFree(x, y, z)
Definition: compat.h:735
static HRESULT set_format(MMDevice *dev)
Definition: devenum.c:460
GLuint * ids
Definition: glext.h:5907
GLuint GLuint num
Definition: glext.h:9618
#define FAILED(hr)
Definition: intsafe.h:51
unsigned int UINT
Definition: ndis.h:50
HRESULT hr
Definition: shlfolder.c:183

Referenced by MMDevEnum_Create().

◆ MMDevCol_AddRef()

static ULONG WINAPI MMDevCol_AddRef ( IMMDeviceCollection iface)
static

Definition at line 808 of file devenum.c.

809{
812 TRACE("Refcount now %i\n", ref);
813 return ref;
814}
#define InterlockedIncrement
Definition: armddk.h:53
static MMDevColImpl * impl_from_IMMDeviceCollection(IMMDeviceCollection *iface)
Definition: devenum.c:121
Definition: send.c:48

◆ MMDevCol_Create()

static HRESULT MMDevCol_Create ( IMMDeviceCollection **  ppv,
EDataFlow  flow,
DWORD  state 
)
static

Definition at line 769 of file devenum.c.

770{
772
773 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
774 *ppv = NULL;
775 if (!This)
776 return E_OUTOFMEMORY;
777 This->IMMDeviceCollection_iface.lpVtbl = &MMDevColVtbl;
778 This->ref = 1;
779 This->flow = flow;
780 This->state = state;
781 *ppv = &This->IMMDeviceCollection_iface;
782 return S_OK;
783}
static int state
Definition: maze.c:121
static const IMMDeviceCollectionVtbl MMDevColVtbl
Definition: devenum.c:87

Referenced by MMDevEnum_EnumAudioEndpoints().

◆ MMDevCol_Destroy()

static void MMDevCol_Destroy ( MMDevColImpl This)
static

Definition at line 785 of file devenum.c.

786{
788}

Referenced by MMDevCol_Release().

◆ MMDevCol_GetCount()

static HRESULT WINAPI MMDevCol_GetCount ( IMMDeviceCollection iface,
UINT numdevs 
)
static

Definition at line 826 of file devenum.c.

827{
829 DWORD i;
830
831 TRACE("(%p)->(%p)\n", This, numdevs);
832 if (!numdevs)
833 return E_POINTER;
834
835 *numdevs = 0;
836 for (i = 0; i < MMDevice_count; ++i)
837 {
839 if ((cur->flow == This->flow || This->flow == eAll)
840 && (cur->state & This->state))
841 ++(*numdevs);
842 }
843 return S_OK;
844}
static DWORD MMDevice_count
Definition: devenum.c:85
static MMDevice ** MMDevice_head
Definition: devenum.c:83
@ eAll
Definition: mmdeviceapi.idl:65

◆ MMDevCol_Item()

static HRESULT WINAPI MMDevCol_Item ( IMMDeviceCollection iface,
UINT  n,
IMMDevice **  dev 
)
static

Definition at line 846 of file devenum.c.

847{
849 DWORD i = 0, j = 0;
850
851 TRACE("(%p)->(%u, %p)\n", This, n, dev);
852 if (!dev)
853 return E_POINTER;
854
855 for (j = 0; j < MMDevice_count; ++j)
856 {
858 if ((cur->flow == This->flow || This->flow == eAll)
859 && (cur->state & This->state)
860 && i++ == n)
861 {
862 *dev = &cur->IMMDevice_iface;
863 IMMDevice_AddRef(*dev);
864 return S_OK;
865 }
866 }
867 WARN("Could not obtain item %u\n", n);
868 *dev = NULL;
869 return E_INVALIDARG;
870}
GLdouble n
Definition: glext.h:7729
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250

◆ MMDevCol_QueryInterface()

static HRESULT WINAPI MMDevCol_QueryInterface ( IMMDeviceCollection iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 790 of file devenum.c.

791{
793 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
794
795 if (!ppv)
796 return E_POINTER;
798 || IsEqualIID(riid, &IID_IMMDeviceCollection))
799 *ppv = &This->IMMDeviceCollection_iface;
800 else
801 *ppv = NULL;
802 if (!*ppv)
803 return E_NOINTERFACE;
804 IUnknown_AddRef((IUnknown*)*ppv);
805 return S_OK;
806}
const GUID IID_IUnknown
REFIID riid
Definition: atlbase.h:39
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define E_NOINTERFACE
Definition: winerror.h:2364

◆ MMDevCol_Release()

static ULONG WINAPI MMDevCol_Release ( IMMDeviceCollection iface)
static

Definition at line 816 of file devenum.c.

817{
820 TRACE("Refcount now %i\n", ref);
821 if (!ref)
823 return ref;
824}
#define InterlockedDecrement
Definition: armddk.h:52
static void MMDevCol_Destroy(MMDevColImpl *This)
Definition: devenum.c:785

◆ MMDevEnum_AddRef()

static ULONG WINAPI MMDevEnum_AddRef ( IMMDeviceEnumerator iface)
static

Definition at line 931 of file devenum.c.

932{
935 TRACE("Refcount now %i\n", ref);
936 return ref;
937}
static MMDevEnumImpl * impl_from_IMMDeviceEnumerator(IMMDeviceEnumerator *iface)
Definition: devenum.c:116

◆ MMDevEnum_Create()

HRESULT MMDevEnum_Create ( REFIID  riid,
void **  ppv 
)

Definition at line 881 of file devenum.c.

882{
884
885 if (!This)
886 {
887 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
888 *ppv = NULL;
889 if (!This)
890 return E_OUTOFMEMORY;
891 This->ref = 1;
892 This->IMMDeviceEnumerator_iface.lpVtbl = &MMDevEnumVtbl;
894
898 }
899 return IMMDeviceEnumerator_QueryInterface(&This->IMMDeviceEnumerator_iface, riid, ppv);
900}
static HRESULT load_devices_from_reg(void)
Definition: devenum.c:400
static MMDevEnumImpl * MMDevEnumerator
Definition: devenum.c:82
static HRESULT load_driver_devices(EDataFlow flow)
Definition: devenum.c:491
static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl
Definition: devenum.c:86

◆ MMDevEnum_EnumAudioEndpoints()

static HRESULT WINAPI MMDevEnum_EnumAudioEndpoints ( IMMDeviceEnumerator iface,
EDataFlow  flow,
DWORD  mask,
IMMDeviceCollection **  devices 
)
static

Definition at line 949 of file devenum.c.

950{
952 TRACE("(%p)->(%u,%u,%p)\n", This, flow, mask, devices);
953 if (!devices)
954 return E_POINTER;
955 *devices = NULL;
956 if (flow >= EDataFlow_enum_count)
957 return E_INVALIDARG;
958 if (mask & ~DEVICE_STATEMASK_ALL)
959 return E_INVALIDARG;
960 return MMDevCol_Create(devices, flow, mask);
961}
static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, EDataFlow flow, DWORD state)
Definition: devenum.c:769
static struct all_devices * devices
Definition: dsm_ctrl.c:48
GLenum GLint GLuint mask
Definition: glext.h:6028
@ EDataFlow_enum_count
Definition: mmdeviceapi.idl:66

◆ MMDevEnum_Free()

void MMDevEnum_Free ( void  )

Definition at line 902 of file devenum.c.

903{
904 while (MMDevice_count)
911}
static void MMDevice_Destroy(MMDevice *This)
Definition: devenum.c:518

Referenced by DllMain(), and MMDevEnum_Release().

◆ MMDevEnum_GetDefaultAudioEndpoint()

static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint ( IMMDeviceEnumerator iface,
EDataFlow  flow,
ERole  role,
IMMDevice **  device 
)
static

Definition at line 963 of file devenum.c.

964{
966 WCHAR reg_key[256];
967 HKEY key;
968 HRESULT hr;
969
970 TRACE("(%p)->(%u,%u,%p)\n", This, flow, role, device);
971
972 if (!device)
973 return E_POINTER;
974
975 if((flow != eRender && flow != eCapture) ||
976 (role != eConsole && role != eMultimedia && role != eCommunications)){
977 WARN("Unknown flow (%u) or role (%u)\n", flow, role);
978 return E_INVALIDARG;
979 }
980
981 *device = NULL;
982
983 if(!drvs.module_name[0])
984 return E_NOTFOUND;
985
986 lstrcpyW(reg_key, drv_keyW);
987 lstrcatW(reg_key, slashW);
988 lstrcatW(reg_key, drvs.module_name);
989
991 const WCHAR *reg_x_name, *reg_vx_name;
992 WCHAR def_id[256];
993 DWORD size = sizeof(def_id), state;
994
995 if(flow == eRender){
996 reg_x_name = reg_out_nameW;
997 reg_vx_name = reg_vout_nameW;
998 }else{
999 reg_x_name = reg_in_nameW;
1000 reg_vx_name = reg_vin_nameW;
1001 }
1002
1003 if(role == eCommunications &&
1004 RegQueryValueExW(key, reg_vx_name, 0, NULL,
1005 (BYTE*)def_id, &size) == ERROR_SUCCESS){
1006 hr = IMMDeviceEnumerator_GetDevice(iface, def_id, device);
1007 if(SUCCEEDED(hr)){
1008 if(SUCCEEDED(IMMDevice_GetState(*device, &state)) &&
1009 state == DEVICE_STATE_ACTIVE){
1011 return S_OK;
1012 }
1013 }
1014
1015 TRACE("Unable to find voice device %s\n", wine_dbgstr_w(def_id));
1016 }
1017
1018 if(RegQueryValueExW(key, reg_x_name, 0, NULL,
1019 (BYTE*)def_id, &size) == ERROR_SUCCESS){
1020 hr = IMMDeviceEnumerator_GetDevice(iface, def_id, device);
1021 if(SUCCEEDED(hr)){
1022 if(SUCCEEDED(IMMDevice_GetState(*device, &state)) &&
1023 state == DEVICE_STATE_ACTIVE){
1025 return S_OK;
1026 }
1027 }
1028
1029 TRACE("Unable to find device %s\n", wine_dbgstr_w(def_id));
1030 }
1031
1033 }
1034
1035 if (flow == eRender)
1037 else
1039
1040 if (!*device)
1041 return E_NOTFOUND;
1042 IMMDevice_AddRef(*device);
1043 return S_OK;
1044}
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3297
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4132
#define lstrcpyW
Definition: compat.h:749
static MMDevice * MMDevice_def_play
Definition: devenum.c:84
static const WCHAR reg_vout_nameW[]
Definition: devenum.c:61
static const WCHAR reg_vin_nameW[]
Definition: devenum.c:63
static const WCHAR reg_out_nameW[]
Definition: devenum.c:60
static MMDevice * MMDevice_def_rec
Definition: devenum.c:84
static const WCHAR slashW[]
Definition: devenum.c:59
static const WCHAR reg_in_nameW[]
Definition: devenum.c:62
const WCHAR drv_keyW[]
Definition: main.c:50
#define wine_dbgstr_w
Definition: kernel32.h:34
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
@ eMultimedia
Definition: mmdeviceapi.idl:72
@ eConsole
Definition: mmdeviceapi.idl:71
@ eCommunications
Definition: mmdeviceapi.idl:73
IMMDevice IMMDevice_iface
Definition: mmdevapi.h:62
Definition: devices.h:37
#define HKEY_CURRENT_USER
Definition: winreg.h:11
unsigned char BYTE
Definition: xxhash.c:193

◆ MMDevEnum_GetDevice()

static HRESULT WINAPI MMDevEnum_GetDevice ( IMMDeviceEnumerator iface,
const WCHAR name,
IMMDevice **  device 
)
static

Definition at line 1046 of file devenum.c.

1047{
1049 DWORD i=0;
1050 IMMDevice *dev = NULL;
1051
1052 static const WCHAR wine_info_deviceW[] = {'W','i','n','e',' ',
1053 'i','n','f','o',' ','d','e','v','i','c','e',0};
1054
1055 TRACE("(%p)->(%s,%p)\n", This, debugstr_w(name), device);
1056
1057 if(!name || !device)
1058 return E_POINTER;
1059
1060 if(!lstrcmpW(name, wine_info_deviceW)){
1061 *device = &info_device;
1062 return S_OK;
1063 }
1064
1065 for (i = 0; i < MMDevice_count; ++i)
1066 {
1067 HRESULT hr;
1068 WCHAR *str;
1070 hr = IMMDevice_GetId(dev, &str);
1071 if (FAILED(hr))
1072 {
1073 WARN("GetId failed: %08x\n", hr);
1074 continue;
1075 }
1076
1077 if (str && !lstrcmpW(str, name))
1078 {
1080 IMMDevice_AddRef(dev);
1081 *device = dev;
1082 return S_OK;
1083 }
1085 }
1086 TRACE("Could not find device %s\n", debugstr_w(name));
1087 return E_INVALIDARG;
1088}
static IMMDevice info_device
Definition: devenum.c:92
#define debugstr_w
Definition: kernel32.h:32
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
const WCHAR * str

◆ MMDevEnum_QueryInterface()

static HRESULT WINAPI MMDevEnum_QueryInterface ( IMMDeviceEnumerator iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 913 of file devenum.c.

914{
916 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
917
918 if (!ppv)
919 return E_POINTER;
921 || IsEqualIID(riid, &IID_IMMDeviceEnumerator))
922 *ppv = &This->IMMDeviceEnumerator_iface;
923 else
924 *ppv = NULL;
925 if (!*ppv)
926 return E_NOINTERFACE;
927 IUnknown_AddRef((IUnknown*)*ppv);
928 return S_OK;
929}

◆ MMDevEnum_RegisterEndpointNotificationCallback()

static HRESULT WINAPI MMDevEnum_RegisterEndpointNotificationCallback ( IMMDeviceEnumerator iface,
IMMNotificationClient client 
)
static

Definition at line 1248 of file devenum.c.

1249{
1251 struct NotificationClientWrapper *wrapper;
1252
1253 TRACE("(%p)->(%p)\n", This, client);
1254
1255 if(!client)
1256 return E_POINTER;
1257
1258 wrapper = HeapAlloc(GetProcessHeap(), 0, sizeof(*wrapper));
1259 if(!wrapper)
1260 return E_OUTOFMEMORY;
1261
1262 wrapper->client = client;
1263
1265
1266 list_add_tail(&g_notif_clients, &wrapper->entry);
1267
1268 if(!g_notif_thread){
1270 if(!g_notif_thread)
1271 ERR("CreateThread failed: %u\n", GetLastError());
1272 }
1273
1275
1276 return S_OK;
1277}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define ERR(fmt,...)
Definition: debug.h:110
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
static DWORD WINAPI notif_thread_proc(void *user)
Definition: devenum.c:1181
static HANDLE g_notif_thread
Definition: devenum.c:1096
static CRITICAL_SECTION g_notif_lock
Definition: devenum.c:1098
static struct list g_notif_clients
Definition: devenum.c:1095
static FILE * client
Definition: client.c:41
IMMNotificationClient * client
Definition: devenum.c:1091
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

◆ MMDevEnum_Release()

static ULONG WINAPI MMDevEnum_Release ( IMMDeviceEnumerator iface)
static

Definition at line 939 of file devenum.c.

940{
943 if (!ref)
945 TRACE("Refcount now %i\n", ref);
946 return ref;
947}
void MMDevEnum_Free(void)
Definition: devenum.c:902

◆ MMDevEnum_UnregisterEndpointNotificationCallback()

static HRESULT WINAPI MMDevEnum_UnregisterEndpointNotificationCallback ( IMMDeviceEnumerator iface,
IMMNotificationClient client 
)
static

Definition at line 1279 of file devenum.c.

1280{
1282 struct NotificationClientWrapper *wrapper;
1283
1284 TRACE("(%p)->(%p)\n", This, client);
1285
1286 if(!client)
1287 return E_POINTER;
1288
1290
1292 if(wrapper->client == client){
1293 list_remove(&wrapper->entry);
1294 HeapFree(GetProcessHeap(), 0, wrapper);
1296 return S_OK;
1297 }
1298 }
1299
1301
1302 return E_NOTFOUND;
1303}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
uint32_t entry
Definition: isohybrid.c:63
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198

◆ MMDevice_Activate()

static HRESULT WINAPI MMDevice_Activate ( IMMDevice iface,
REFIID  riid,
DWORD  clsctx,
PROPVARIANT *  params,
void **  ppv 
)
static

Definition at line 584 of file devenum.c.

585{
588
589 TRACE("(%p)->(%s, %x, %p, %p)\n", iface, debugstr_guid(riid), clsctx, params, ppv);
590
591 if (!ppv)
592 return E_POINTER;
593
594 if (IsEqualIID(riid, &IID_IAudioClient)){
595 hr = drvs.pGetAudioEndpoint(&This->devguid, iface, (IAudioClient**)ppv);
596 }else if (IsEqualIID(riid, &IID_IAudioEndpointVolume) ||
597 IsEqualIID(riid, &IID_IAudioEndpointVolumeEx))
599 else if (IsEqualIID(riid, &IID_IAudioSessionManager)
600 || IsEqualIID(riid, &IID_IAudioSessionManager2))
601 {
602 hr = drvs.pGetAudioSessionManager(iface, (IAudioSessionManager2**)ppv);
603 }
604 else if (IsEqualIID(riid, &IID_IBaseFilter))
605 {
606 if (This->flow == eRender)
607 hr = CoCreateInstance(&CLSID_DSoundRender, NULL, clsctx, riid, ppv);
608 else
609 ERR("Not supported for recording?\n");
610 if (SUCCEEDED(hr))
611 {
613 hr = IUnknown_QueryInterface((IUnknown*)*ppv, &IID_IPersistPropertyBag, (void **)&ppb);
614 if (SUCCEEDED(hr))
615 {
616 /* ::Load cannot assume the interface stays alive after the function returns,
617 * so just create the interface on the stack, saves a lot of complicated code */
618 IPropertyBagImpl bag = { { &PB_Vtbl } };
619 bag.devguid = This->devguid;
620 hr = IPersistPropertyBag_Load(ppb, &bag.IPropertyBag_iface, NULL);
621 IPersistPropertyBag_Release(ppb);
622 if (FAILED(hr))
623 IBaseFilter_Release((IBaseFilter*)*ppv);
624 }
625 else
626 {
627 FIXME("Wine doesn't support IPersistPropertyBag on DSoundRender yet, ignoring..\n");
628 hr = S_OK;
629 }
630 }
631 }
632 else if (IsEqualIID(riid, &IID_IDeviceTopology))
633 {
634 FIXME("IID_IDeviceTopology unsupported\n");
635 }
636 else if (IsEqualIID(riid, &IID_IDirectSound)
637 || IsEqualIID(riid, &IID_IDirectSound8))
638 {
639 if (This->flow == eRender)
640 hr = CoCreateInstance(&CLSID_DirectSound8, NULL, clsctx, riid, ppv);
641 if (SUCCEEDED(hr))
642 {
643 hr = IDirectSound_Initialize((IDirectSound*)*ppv, &This->devguid);
644 if (FAILED(hr))
645 IDirectSound_Release((IDirectSound*)*ppv);
646 }
647 }
648 else if (IsEqualIID(riid, &IID_IDirectSoundCapture))
649 {
650 if (This->flow == eCapture)
651 hr = CoCreateInstance(&CLSID_DirectSoundCapture8, NULL, clsctx, riid, ppv);
652 if (SUCCEEDED(hr))
653 {
654 hr = IDirectSoundCapture_Initialize((IDirectSoundCapture*)*ppv, &This->devguid);
655 if (FAILED(hr))
656 IDirectSoundCapture_Release((IDirectSoundCapture*)*ppv);
657 }
658 }
659 else
660 ERR("Invalid/unknown iid %s\n", debugstr_guid(riid));
661
662 if (FAILED(hr))
663 *ppv = NULL;
664
665 TRACE("Returning %08x\n", hr);
666 return hr;
667}
HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv)
Definition: audiovolume.c:305
#define FIXME(fmt,...)
Definition: debug.h:111
const GUID IID_IBaseFilter
static MMDevice * impl_from_IMMDevice(IMMDevice *iface)
Definition: devenum.c:537
static const IPropertyBagVtbl PB_Vtbl
Definition: devenum.c:107
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
#define IDirectSoundCapture_Release(p)
Definition: dsound.h:736
#define IDirectSoundCapture_Initialize(p, a)
Definition: dsound.h:740
#define IDirectSound_Initialize(p, a)
Definition: dsound.h:462
#define IDirectSound_Release(p)
Definition: dsound.h:453
GLenum const GLfloat * params
Definition: glext.h:5645
const GUID IID_IPersistPropertyBag
Definition: proxy.cpp:11
IPropertyBag IPropertyBag_iface
Definition: devenum.c:103

◆ MMDevice_AddRef()

static ULONG WINAPI MMDevice_AddRef ( IMMDevice iface)
static

Definition at line 564 of file devenum.c.

565{
567 LONG ref;
568
570 TRACE("Refcount now %i\n", ref);
571 return ref;
572}

◆ MMDevice_Create()

static MMDevice * MMDevice_Create ( WCHAR name,
GUID id,
EDataFlow  flow,
DWORD  state,
BOOL  setdefault 
)
static

Definition at line 287 of file devenum.c.

288{
289 HKEY key, root;
290 MMDevice *cur = NULL;
291 WCHAR guidstr[39];
292 DWORD i;
293
294 static const PROPERTYKEY deviceinterface_key = {
295 {0x233164c8, 0x1b2c, 0x4c7d, {0xbc, 0x68, 0xb6, 0x71, 0x68, 0x7a, 0x25, 0x67}}, 1
296 };
297
298 static const PROPERTYKEY devicepath_key = {
299 {0xb3f8fa53, 0x0004, 0x438e, {0x90, 0x03, 0x51, 0xa4, 0x6e, 0x13, 0x9b, 0xfc}}, 2
300 };
301
302 for (i = 0; i < MMDevice_count; ++i)
303 {
305 if (device->flow == flow && IsEqualGUID(&device->devguid, id)){
306 cur = device;
307 break;
308 }
309 }
310
311 if(!cur){
312 /* No device found, allocate new one */
314 if (!cur)
315 return NULL;
316
317 cur->IMMDevice_iface.lpVtbl = &MMDeviceVtbl;
318 cur->IMMEndpoint_iface.lpVtbl = &MMEndpointVtbl;
319
321 cur->crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MMDevice.crst");
322
323 if (!MMDevice_head)
325 else
328 }else if(cur->ref > 0)
329 WARN("Modifying an MMDevice with postitive reference count!\n");
330
331 HeapFree(GetProcessHeap(), 0, cur->drv_id);
332 cur->drv_id = name;
333
334 cur->flow = flow;
335 cur->state = state;
336 cur->devguid = *id;
337
338 StringFromGUID2(&cur->devguid, guidstr, ARRAY_SIZE(guidstr));
339
340 if (flow == eRender)
342 else
344
346 {
347 HKEY keyprop;
348 RegSetValueExW(key, reg_devicestate, 0, REG_DWORD, (const BYTE*)&state, sizeof(DWORD));
350 {
351 PROPVARIANT pv;
352
353 pv.vt = VT_LPWSTR;
354 pv.u.pwszVal = name;
355 MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &pv);
356 MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_DeviceInterface_FriendlyName, &pv);
357 MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_DeviceDesc, &pv);
358
359 pv.u.pwszVal = guidstr;
360 MMDevice_SetPropValue(id, flow, &deviceinterface_key, &pv);
361
362 set_driver_prop_value(id, flow, &devicepath_key);
363
364 if (FAILED(set_driver_prop_value(id, flow, &PKEY_AudioEndpoint_FormFactor)))
365 {
366 pv.vt = VT_UI4;
367 pv.u.ulVal = (flow == eCapture) ? Microphone : Speakers;
368
369 MMDevice_SetPropValue(id, flow, &PKEY_AudioEndpoint_FormFactor, &pv);
370 }
371
372 if (flow != eCapture)
373 {
374 PROPVARIANT pv2;
375
376 PropVariantInit(&pv2);
377
378 /* make read-write by not overwriting if already set */
379 if (FAILED(MMDevice_GetPropValue(id, flow, &PKEY_AudioEndpoint_PhysicalSpeakers, &pv2)) || pv2.vt != VT_UI4)
380 set_driver_prop_value(id, flow, &PKEY_AudioEndpoint_PhysicalSpeakers);
381
383 }
384
385 RegCloseKey(keyprop);
386 }
388 }
389
390 if (setdefault)
391 {
392 if (flow == eRender)
394 else
396 }
397 return cur;
398}
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4911
#define HeapReAlloc
Definition: compat.h:734
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
@ VT_UI4
Definition: compat.h:2313
static const IMMEndpointVtbl MMEndpointVtbl
Definition: devenum.c:90
static const WCHAR reg_devicestate[]
Definition: devenum.c:55
static const IMMDeviceVtbl MMDeviceVtbl
Definition: devenum.c:88
static HRESULT MMDevice_SetPropValue(const GUID *devguid, DWORD flow, REFPROPERTYKEY key, REFPROPVARIANT pv)
Definition: devenum.c:220
static const WCHAR reg_properties[]
Definition: devenum.c:57
static HRESULT set_driver_prop_value(GUID *id, const EDataFlow flow, const PROPERTYKEY *prop)
Definition: devenum.c:264
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2968
GLuint id
Definition: glext.h:5910
@ Microphone
Definition: mmdeviceapi.idl:83
@ Speakers
Definition: mmdeviceapi.idl:80
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REG_DWORD
Definition: sdbapi.c:596
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define DWORD_PTR
Definition: treelist.c:76
const void * pv2
Definition: winddi.h:2453

Referenced by load_devices_from_reg(), and load_driver_devices().

◆ MMDevice_Destroy()

static void MMDevice_Destroy ( MMDevice This)
static

Definition at line 518 of file devenum.c.

519{
520 DWORD i;
521 TRACE("Freeing %s\n", debugstr_w(This->drv_id));
522 /* Since this function is called at destruction time, reordering of the list is unimportant */
523 for (i = 0; i < MMDevice_count; ++i)
524 {
525 if (MMDevice_head[i] == This)
526 {
528 break;
529 }
530 }
531 This->crst.DebugInfo->Spare[0] = 0;
533 HeapFree(GetProcessHeap(), 0, This->drv_id);
535}
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

Referenced by MMDevEnum_Free().

◆ MMDevice_GetId()

static HRESULT WINAPI MMDevice_GetId ( IMMDevice iface,
WCHAR **  itemid 
)
static

Definition at line 679 of file devenum.c.

680{
682 WCHAR *str;
683 GUID *id = &This->devguid;
684 static const WCHAR formatW[] = { '{','0','.','0','.','%','u','.','0','0','0','0','0','0','0','0','}','.',
685 '{','%','0','8','X','-','%','0','4','X','-',
686 '%','0','4','X','-','%','0','2','X','%','0','2','X','-',
687 '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',
688 '%','0','2','X','%','0','2','X','}',0 };
689
690 TRACE("(%p)->(%p)\n", This, itemid);
691 if (!itemid)
692 return E_POINTER;
693 *itemid = str = CoTaskMemAlloc(56 * sizeof(WCHAR));
694 if (!str)
695 return E_OUTOFMEMORY;
696 wsprintfW( str, formatW, This->flow, id->Data1, id->Data2, id->Data3,
697 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
698 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
699 TRACE("returning %s\n", wine_dbgstr_w(str));
700 return S_OK;
701}
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)

◆ MMDevice_GetPropValue()

static HRESULT MMDevice_GetPropValue ( const GUID devguid,
DWORD  flow,
REFPROPERTYKEY  key,
PROPVARIANT *  pv 
)
static

Definition at line 158 of file devenum.c.

159{
160 WCHAR buffer[80];
161 const GUID *id = &key->fmtid;
162 DWORD type, size;
163 HRESULT hr = S_OK;
164 HKEY regkey;
165 LONG ret;
166
167 hr = MMDevPropStore_OpenPropKey(devguid, flow, &regkey);
168 if (FAILED(hr))
169 return hr;
170 wsprintfW( buffer, propkey_formatW, id->Data1, id->Data2, id->Data3,
171 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
172 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7], key->pid );
174 if (ret != ERROR_SUCCESS)
175 {
176 WARN("Reading %s returned %d\n", debugstr_w(buffer), ret);
177 RegCloseKey(regkey);
179 return S_OK;
180 }
181
182 switch (type)
183 {
184 case REG_SZ:
185 {
186 pv->vt = VT_LPWSTR;
187 pv->u.pwszVal = CoTaskMemAlloc(size);
188 if (!pv->u.pwszVal)
190 else
191 RegGetValueW(regkey, NULL, buffer, RRF_RT_REG_SZ, NULL, (BYTE*)pv->u.pwszVal, &size);
192 break;
193 }
194 case REG_DWORD:
195 {
196 pv->vt = VT_UI4;
197 RegGetValueW(regkey, NULL, buffer, RRF_RT_REG_DWORD, NULL, (BYTE*)&pv->u.ulVal, &size);
198 break;
199 }
200 case REG_BINARY:
201 {
202 pv->vt = VT_BLOB;
203 pv->u.blob.cbSize = size;
204 pv->u.blob.pBlobData = CoTaskMemAlloc(size);
205 if (!pv->u.blob.pBlobData)
207 else
208 RegGetValueW(regkey, NULL, buffer, RRF_RT_REG_BINARY, NULL, (BYTE*)pv->u.blob.pBlobData, &size);
209 break;
210 }
211 default:
212 ERR("Unknown/unhandled type: %u\n", type);
214 break;
215 }
216 RegCloseKey(regkey);
217 return hr;
218}
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1969
@ VT_BLOB
Definition: compat.h:2330
static const WCHAR propkey_formatW[]
Definition: devenum.c:131
static HRESULT MMDevPropStore_OpenPropKey(const GUID *guid, DWORD flow, HKEY *propkey)
Definition: devenum.c:137
#define RRF_RT_REG_BINARY
Definition: driver.c:577
#define RRF_RT_REG_DWORD
Definition: driver.c:578
#define RRF_RT_REG_SZ
Definition: driver.c:575
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
#define REG_SZ
Definition: layer.c:22
#define REG_BINARY
Definition: nt_native.h:1496
#define RRF_RT_ANY
Definition: winreg.h:64

Referenced by load_devices_from_reg(), MMDevice_Create(), and MMDevPropStore_GetValue().

◆ MMDevice_GetState()

static HRESULT WINAPI MMDevice_GetState ( IMMDevice iface,
DWORD state 
)
static

Definition at line 703 of file devenum.c.

704{
706 TRACE("(%p)->(%p)\n", iface, state);
707
708 if (!state)
709 return E_POINTER;
710 *state = This->state;
711 return S_OK;
712}

◆ MMDevice_OpenPropertyStore()

static HRESULT WINAPI MMDevice_OpenPropertyStore ( IMMDevice iface,
DWORD  access,
IPropertyStore **  ppv 
)
static

Definition at line 669 of file devenum.c.

670{
672 TRACE("(%p)->(%x,%p)\n", This, access, ppv);
673
674 if (!ppv)
675 return E_POINTER;
677}
static HRESULT MMDevPropStore_Create(MMDevice *This, DWORD access, IPropertyStore **ppv)
Definition: devenum.c:1317

◆ MMDevice_QueryInterface()

static HRESULT WINAPI MMDevice_QueryInterface ( IMMDevice iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 542 of file devenum.c.

543{
545 TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppv);
546
547 if (!ppv)
548 return E_POINTER;
549 *ppv = NULL;
551 || IsEqualIID(riid, &IID_IMMDevice))
552 *ppv = &This->IMMDevice_iface;
553 else if (IsEqualIID(riid, &IID_IMMEndpoint))
554 *ppv = &This->IMMEndpoint_iface;
555 if (*ppv)
556 {
557 IUnknown_AddRef((IUnknown*)*ppv);
558 return S_OK;
559 }
560 WARN("Unknown interface %s\n", debugstr_guid(riid));
561 return E_NOINTERFACE;
562}

◆ MMDevice_Release()

static ULONG WINAPI MMDevice_Release ( IMMDevice iface)
static

Definition at line 574 of file devenum.c.

575{
577 LONG ref;
578
580 TRACE("Refcount now %i\n", ref);
581 return ref;
582}

◆ MMDevice_SetPropValue()

static HRESULT MMDevice_SetPropValue ( const GUID devguid,
DWORD  flow,
REFPROPERTYKEY  key,
REFPROPVARIANT  pv 
)
static

Definition at line 220 of file devenum.c.

221{
222 WCHAR buffer[80];
223 const GUID *id = &key->fmtid;
224 HRESULT hr;
225 HKEY regkey;
226 LONG ret;
227
228 hr = MMDevPropStore_OpenPropKey(devguid, flow, &regkey);
229 if (FAILED(hr))
230 return hr;
231 wsprintfW( buffer, propkey_formatW, id->Data1, id->Data2, id->Data3,
232 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
233 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7], key->pid );
234 switch (pv->vt)
235 {
236 case VT_UI4:
237 {
238 ret = RegSetValueExW(regkey, buffer, 0, REG_DWORD, (const BYTE*)&pv->u.ulVal, sizeof(DWORD));
239 break;
240 }
241 case VT_BLOB:
242 {
243 ret = RegSetValueExW(regkey, buffer, 0, REG_BINARY, pv->u.blob.pBlobData, pv->u.blob.cbSize);
244 TRACE("Blob %p %u\n", pv->u.blob.pBlobData, pv->u.blob.cbSize);
245
246 break;
247 }
248 case VT_LPWSTR:
249 {
250 ret = RegSetValueExW(regkey, buffer, 0, REG_SZ, (const BYTE*)pv->u.pwszVal, sizeof(WCHAR)*(1+lstrlenW(pv->u.pwszVal)));
251 break;
252 }
253 default:
254 ret = 0;
255 FIXME("Unhandled type %u\n", pv->vt);
257 break;
258 }
259 RegCloseKey(regkey);
260 TRACE("Writing %s returned %u\n", debugstr_w(buffer), ret);
261 return hr;
262}

Referenced by MMDevice_Create(), MMDevPropStore_SetValue(), set_driver_prop_value(), and set_format().

◆ MMDevPropStore_AddRef()

static ULONG WINAPI MMDevPropStore_AddRef ( IPropertyStore iface)
static

Definition at line 1361 of file devenum.c.

1362{
1365 TRACE("Refcount now %i\n", ref);
1366 return ref;
1367}
static MMDevPropStore * impl_from_IPropertyStore(IPropertyStore *iface)
Definition: devenum.c:111

◆ MMDevPropStore_Commit()

static HRESULT WINAPI MMDevPropStore_Commit ( IPropertyStore iface)
static

Definition at line 1474 of file devenum.c.

1475{
1477 TRACE("(%p)\n", iface);
1478
1479 if (This->access != STGM_WRITE
1480 && This->access != STGM_READWRITE)
1481 return STG_E_ACCESSDENIED;
1482
1483 /* Does nothing - for mmdevapi, the propstore values are written on SetValue,
1484 * not on Commit. */
1485
1486 return S_OK;
1487}
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_WRITE
Definition: objbase.h:918
#define STG_E_ACCESSDENIED
Definition: winerror.h:2568

◆ MMDevPropStore_Create()

static HRESULT MMDevPropStore_Create ( MMDevice This,
DWORD  access,
IPropertyStore **  ppv 
)
static

Definition at line 1317 of file devenum.c.

1318{
1320 if (access != STGM_READ
1321 && access != STGM_WRITE
1322 && access != STGM_READWRITE)
1323 {
1324 WARN("Invalid access %08x\n", access);
1325 return E_INVALIDARG;
1326 }
1327 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1328 *ppv = &This->IPropertyStore_iface;
1329 if (!This)
1330 return E_OUTOFMEMORY;
1331 This->IPropertyStore_iface.lpVtbl = &MMDevPropVtbl;
1332 This->ref = 1;
1333 This->parent = parent;
1334 This->access = access;
1335 return S_OK;
1336}
static const IPropertyStoreVtbl MMDevPropVtbl
Definition: devenum.c:89
r parent
Definition: btrfs.c:3010
#define STGM_READ
Definition: objbase.h:917

Referenced by MMDevice_OpenPropertyStore().

◆ MMDevPropStore_Destroy()

static void MMDevPropStore_Destroy ( MMDevPropStore This)
static

Definition at line 1338 of file devenum.c.

1339{
1341}

Referenced by MMDevPropStore_Release().

◆ MMDevPropStore_GetAt()

static HRESULT WINAPI MMDevPropStore_GetAt ( IPropertyStore iface,
DWORD  prop,
PROPERTYKEY *  key 
)
static

Definition at line 1406 of file devenum.c.

1407{
1409 WCHAR buffer[50];
1411 HRESULT hr;
1412 HKEY propkey;
1413
1414 TRACE("(%p)->(%u,%p)\n", iface, prop, key);
1415 if (!key)
1416 return E_POINTER;
1417
1418 hr = MMDevPropStore_OpenPropKey(&This->parent->devguid, This->parent->flow, &propkey);
1419 if (FAILED(hr))
1420 return hr;
1421
1422 if (RegEnumValueW(propkey, prop, buffer, &len, NULL, NULL, NULL, NULL) != ERROR_SUCCESS
1423 || len <= 39)
1424 {
1425 WARN("GetAt %u failed\n", prop);
1426 return E_INVALIDARG;
1427 }
1428 RegCloseKey(propkey);
1429 buffer[38] = 0;
1430 CLSIDFromString(buffer, &key->fmtid);
1431 key->pid = wcstol(&buffer[39], NULL, 10);
1432 return S_OK;
1433}
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2859
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)

◆ MMDevPropStore_GetCount()

static HRESULT WINAPI MMDevPropStore_GetCount ( IPropertyStore iface,
DWORD nprops 
)
static

Definition at line 1379 of file devenum.c.

1380{
1382 WCHAR buffer[50];
1383 DWORD i = 0;
1384 HKEY propkey;
1385 HRESULT hr;
1386
1387 TRACE("(%p)->(%p)\n", iface, nprops);
1388 if (!nprops)
1389 return E_POINTER;
1390 hr = MMDevPropStore_OpenPropKey(&This->parent->devguid, This->parent->flow, &propkey);
1391 if (FAILED(hr))
1392 return hr;
1393 *nprops = 0;
1394 do {
1396 if (RegEnumValueW(propkey, i, buffer, &len, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
1397 break;
1398 i++;
1399 } while (1);
1400 RegCloseKey(propkey);
1401 TRACE("Returning %i\n", i);
1402 *nprops = i;
1403 return S_OK;
1404}

◆ MMDevPropStore_GetValue()

static HRESULT WINAPI MMDevPropStore_GetValue ( IPropertyStore iface,
REFPROPERTYKEY  key,
PROPVARIANT *  pv 
)
static

Definition at line 1435 of file devenum.c.

1436{
1438 TRACE("(%p)->(\"%s,%u\", %p)\n", This, key ? debugstr_guid(&key->fmtid) : NULL, key ? key->pid : 0, pv);
1439
1440 if (!key || !pv)
1441 return E_POINTER;
1442 if (This->access != STGM_READ
1443 && This->access != STGM_READWRITE)
1444 return STG_E_ACCESSDENIED;
1445
1446 /* Special case */
1447 if (IsEqualPropertyKey(*key, PKEY_AudioEndpoint_GUID))
1448 {
1449 pv->vt = VT_LPWSTR;
1450 pv->u.pwszVal = CoTaskMemAlloc(39 * sizeof(WCHAR));
1451 if (!pv->u.pwszVal)
1452 return E_OUTOFMEMORY;
1453 StringFromGUID2(&This->parent->devguid, pv->u.pwszVal, 39);
1454 return S_OK;
1455 }
1456
1457 return MMDevice_GetPropValue(&This->parent->devguid, This->parent->flow, key, pv);
1458}

◆ MMDevPropStore_OpenPropKey()

static HRESULT MMDevPropStore_OpenPropKey ( const GUID guid,
DWORD  flow,
HKEY propkey 
)
static

Definition at line 137 of file devenum.c.

138{
139 WCHAR buffer[39];
140 LONG ret;
141 HKEY key;
144 {
145 WARN("Opening key %s failed with %u\n", debugstr_w(buffer), ret);
146 return E_FAIL;
147 }
150 if (ret != ERROR_SUCCESS)
151 {
152 WARN("Opening key %s failed with %u\n", debugstr_w(reg_properties), ret);
153 return E_FAIL;
154 }
155 return S_OK;
156}
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3362

Referenced by MMDevice_GetPropValue(), MMDevice_SetPropValue(), MMDevPropStore_GetAt(), and MMDevPropStore_GetCount().

◆ MMDevPropStore_QueryInterface()

static HRESULT WINAPI MMDevPropStore_QueryInterface ( IPropertyStore iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 1343 of file devenum.c.

1344{
1346 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
1347
1348 if (!ppv)
1349 return E_POINTER;
1351 || IsEqualIID(riid, &IID_IPropertyStore))
1352 *ppv = &This->IPropertyStore_iface;
1353 else
1354 *ppv = NULL;
1355 if (!*ppv)
1356 return E_NOINTERFACE;
1357 IUnknown_AddRef((IUnknown*)*ppv);
1358 return S_OK;
1359}

◆ MMDevPropStore_Release()

static ULONG WINAPI MMDevPropStore_Release ( IPropertyStore iface)
static

Definition at line 1369 of file devenum.c.

1370{
1373 TRACE("Refcount now %i\n", ref);
1374 if (!ref)
1376 return ref;
1377}
static void MMDevPropStore_Destroy(MMDevPropStore *This)
Definition: devenum.c:1338

◆ MMDevPropStore_SetValue()

static HRESULT WINAPI MMDevPropStore_SetValue ( IPropertyStore iface,
REFPROPERTYKEY  key,
REFPROPVARIANT  pv 
)
static

Definition at line 1460 of file devenum.c.

1461{
1463 TRACE("(%p)->(\"%s,%u\", %p)\n", This, key ? debugstr_guid(&key->fmtid) : NULL, key ? key->pid : 0, pv);
1464
1465 if (!key || !pv)
1466 return E_POINTER;
1467
1468 if (This->access != STGM_WRITE
1469 && This->access != STGM_READWRITE)
1470 return STG_E_ACCESSDENIED;
1471 return MMDevice_SetPropValue(&This->parent->devguid, This->parent->flow, key, pv);
1472}

◆ MMEndpoint_AddRef()

static ULONG WINAPI MMEndpoint_AddRef ( IMMEndpoint iface)
static

Definition at line 737 of file devenum.c.

738{
740 TRACE("(%p)\n", This);
741 return IMMDevice_AddRef(&This->IMMDevice_iface);
742}
static MMDevice * impl_from_IMMEndpoint(IMMEndpoint *iface)
Definition: devenum.c:725

◆ MMEndpoint_GetDataFlow()

static HRESULT WINAPI MMEndpoint_GetDataFlow ( IMMEndpoint iface,
EDataFlow flow 
)
static

Definition at line 751 of file devenum.c.

752{
754 TRACE("(%p)->(%p)\n", This, flow);
755 if (!flow)
756 return E_POINTER;
757 *flow = This->flow;
758 return S_OK;
759}

◆ MMEndpoint_QueryInterface()

static HRESULT WINAPI MMEndpoint_QueryInterface ( IMMEndpoint iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 730 of file devenum.c.

731{
733 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
734 return IMMDevice_QueryInterface(&This->IMMDevice_iface, riid, ppv);
735}

◆ MMEndpoint_Release()

static ULONG WINAPI MMEndpoint_Release ( IMMEndpoint iface)
static

Definition at line 744 of file devenum.c.

745{
747 TRACE("(%p)\n", This);
748 return IMMDevice_Release(&This->IMMDevice_iface);
749}

◆ notif_thread_proc()

static DWORD WINAPI notif_thread_proc ( void user)
static

Definition at line 1181 of file devenum.c.

1182{
1183 HKEY key;
1184 WCHAR reg_key[256];
1185 WCHAR out_name[64], vout_name[64], in_name[64], vin_name[64];
1186 DWORD size;
1187
1188 lstrcpyW(reg_key, drv_keyW);
1189 lstrcatW(reg_key, slashW);
1190 lstrcatW(reg_key, drvs.module_name);
1191
1192 if(RegCreateKeyExW(HKEY_CURRENT_USER, reg_key, 0, NULL, 0,
1194 ERR("RegCreateKeyEx failed: %u\n", GetLastError());
1195 return 1;
1196 }
1197
1198 size = sizeof(out_name);
1200 (BYTE*)out_name, &size) != ERROR_SUCCESS)
1201 out_name[0] = 0;
1202
1203 size = sizeof(vout_name);
1205 (BYTE*)vout_name, &size) != ERROR_SUCCESS)
1206 vout_name[0] = 0;
1207
1208 size = sizeof(in_name);
1210 (BYTE*)in_name, &size) != ERROR_SUCCESS)
1211 in_name[0] = 0;
1212
1213 size = sizeof(vin_name);
1215 (BYTE*)vin_name, &size) != ERROR_SUCCESS)
1216 vin_name[0] = 0;
1217
1218 while(1){
1220 NULL, FALSE) != ERROR_SUCCESS){
1221 ERR("RegNotifyChangeKeyValue failed: %u\n", GetLastError());
1224 return 1;
1225 }
1226
1228
1232 vout_name, &MMDevice_def_play->IMMDevice_iface);
1236 vin_name, &MMDevice_def_rec->IMMDevice_iface);
1237
1239 }
1240
1242
1244
1245 return 0;
1246}
LONG WINAPI RegNotifyChangeKeyValue(HKEY hKey, BOOL bWatchSubtree, DWORD dwNotifyFilter, HANDLE hEvent, BOOL fAsynchronous)
Definition: reg.c:3181
static BOOL notify_if_changed(EDataFlow flow, ERole role, HKEY key, const WCHAR *val_name, WCHAR *old_val, IMMDevice *def_dev)
Definition: devenum.c:1120
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define REG_NOTIFY_CHANGE_LAST_SET
Definition: winreg.h:40

Referenced by MMDevEnum_RegisterEndpointNotificationCallback().

◆ notify_clients()

static void notify_clients ( EDataFlow  flow,
ERole  role,
const WCHAR id 
)
static

Definition at line 1107 of file devenum.c.

1108{
1109 struct NotificationClientWrapper *wrapper;
1112 IMMNotificationClient_OnDefaultDeviceChanged(wrapper->client, flow,
1113 role, id);
1114
1115 /* Windows 7 treats changes to eConsole as changes to eMultimedia */
1116 if(role == eConsole)
1117 notify_clients(flow, eMultimedia, id);
1118}
static void notify_clients(EDataFlow flow, ERole role, const WCHAR *id)
Definition: devenum.c:1107

Referenced by notify_clients(), and notify_if_changed().

◆ notify_if_changed()

static BOOL notify_if_changed ( EDataFlow  flow,
ERole  role,
HKEY  key,
const WCHAR val_name,
WCHAR old_val,
IMMDevice def_dev 
)
static

Definition at line 1120 of file devenum.c.

1122{
1123 WCHAR new_val[64], *id;
1124 DWORD size;
1125 HRESULT hr;
1126
1127 size = sizeof(new_val);
1128 if(RegQueryValueExW(key, val_name, 0, NULL,
1129 (BYTE*)new_val, &size) != ERROR_SUCCESS){
1130 if(old_val[0] != 0){
1131 /* set by user -> system default */
1132 if(def_dev){
1133 hr = IMMDevice_GetId(def_dev, &id);
1134 if(FAILED(hr)){
1135 ERR("GetId failed: %08x\n", hr);
1136 return FALSE;
1137 }
1138 }else
1139 id = NULL;
1140
1141 notify_clients(flow, role, id);
1142 old_val[0] = 0;
1143 CoTaskMemFree(id);
1144
1145 return TRUE;
1146 }
1147
1148 /* system default -> system default, noop */
1149 return FALSE;
1150 }
1151
1152 if(!lstrcmpW(old_val, new_val)){
1153 /* set by user -> same value */
1154 return FALSE;
1155 }
1156
1157 if(new_val[0] != 0){
1158 /* set by user -> different value */
1159 notify_clients(flow, role, new_val);
1160 memcpy(old_val, new_val, sizeof(new_val));
1161 return TRUE;
1162 }
1163
1164 /* set by user -> system default */
1165 if(def_dev){
1166 hr = IMMDevice_GetId(def_dev, &id);
1167 if(FAILED(hr)){
1168 ERR("GetId failed: %08x\n", hr);
1169 return FALSE;
1170 }
1171 }else
1172 id = NULL;
1173
1174 notify_clients(flow, role, id);
1175 old_val[0] = 0;
1176 CoTaskMemFree(id);
1177
1178 return TRUE;
1179}
#define TRUE
Definition: types.h:120

Referenced by notif_thread_proc().

◆ PB_AddRef()

static ULONG WINAPI PB_AddRef ( IPropertyBag iface)
static

Definition at line 1510 of file devenum.c.

1511{
1512 ERR("Should not be called\n");
1513 return 2;
1514}

◆ PB_QueryInterface()

static HRESULT WINAPI PB_QueryInterface ( IPropertyBag iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 1503 of file devenum.c.

1504{
1505 ERR("Should not be called\n");
1506 *ppv = NULL;
1507 return E_NOINTERFACE;
1508}

◆ PB_Read()

static HRESULT WINAPI PB_Read ( IPropertyBag iface,
LPCOLESTR  name,
VARIANT var,
IErrorLog log 
)
static

Definition at line 1522 of file devenum.c.

1523{
1524 static const WCHAR dsguid[] = { 'D','S','G','u','i','d', 0 };
1526 TRACE("Trying to read %s, type %u\n", debugstr_w(name), var->n1.n2.vt);
1527 if (!lstrcmpW(name, dsguid))
1528 {
1529 WCHAR guidstr[39];
1530 StringFromGUID2(&This->devguid, guidstr,ARRAY_SIZE(guidstr));
1531 var->n1.n2.vt = VT_BSTR;
1532 var->n1.n2.n3.bstrVal = SysAllocString(guidstr);
1533 return S_OK;
1534 }
1535 ERR("Unknown property '%s' queried\n", debugstr_w(name));
1536 return E_FAIL;
1537}
@ VT_BSTR
Definition: compat.h:2303
static IPropertyBagImpl * impl_from_IPropertyBag(IPropertyBag *iface)
Definition: devenum.c:126
const char * var
Definition: shader.c:5666
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238

◆ PB_Release()

static ULONG WINAPI PB_Release ( IPropertyBag iface)
static

Definition at line 1516 of file devenum.c.

1517{
1518 ERR("Should not be called\n");
1519 return 1;
1520}

◆ PB_Write()

static HRESULT WINAPI PB_Write ( IPropertyBag iface,
LPCOLESTR  name,
VARIANT var 
)
static

Definition at line 1539 of file devenum.c.

1540{
1541 ERR("Should not be called\n");
1542 return E_FAIL;
1543}

◆ set_driver_prop_value()

static HRESULT set_driver_prop_value ( GUID id,
const EDataFlow  flow,
const PROPERTYKEY *  prop 
)
static

Definition at line 264 of file devenum.c.

265{
266 HRESULT hr;
267 PROPVARIANT pv;
268
269 if (!drvs.pGetPropValue)
270 return E_NOTIMPL;
271
272 hr = drvs.pGetPropValue(id, prop, &pv);
273
274 if (SUCCEEDED(hr))
275 {
276 MMDevice_SetPropValue(id, flow, prop, &pv);
277 PropVariantClear(&pv);
278 }
279
280 return hr;
281}
#define E_NOTIMPL
Definition: ddrawi.h:99

Referenced by MMDevice_Create().

◆ set_format()

static HRESULT set_format ( MMDevice dev)
static

Definition at line 460 of file devenum.c.

461{
462 HRESULT hr;
465 PROPVARIANT pv = { VT_EMPTY };
466
467 hr = drvs.pGetAudioEndpoint(&dev->devguid, &dev->IMMDevice_iface, &client);
468 if(FAILED(hr))
469 return hr;
470
471 hr = IAudioClient_GetMixFormat(client, &fmt);
472 if(FAILED(hr)){
473 IAudioClient_Release(client);
474 return hr;
475 }
476
477 IAudioClient_Release(client);
478
479 pv.vt = VT_BLOB;
480 pv.u.blob.cbSize = sizeof(WAVEFORMATEX) + fmt->cbSize;
481 pv.u.blob.pBlobData = (BYTE*)fmt;
482 MMDevice_SetPropValue(&dev->devguid, dev->flow,
483 &PKEY_AudioEngine_DeviceFormat, &pv);
484 MMDevice_SetPropValue(&dev->devguid, dev->flow,
485 &PKEY_AudioEngine_OEMFormat, &pv);
487
488 return S_OK;
489}
Definition: dsound.c:943

Referenced by load_driver_devices().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( mmdevapi  )

Variable Documentation

◆ g_notif_clients

struct list g_notif_clients = LIST_INIT(g_notif_clients)
static

◆ g_notif_lock

◆ g_notif_lock_debug

CRITICAL_SECTION_DEBUG g_notif_lock_debug
static
Initial value:
=
{
0, 0, &g_notif_lock,
0, 0, { (DWORD_PTR)(__FILE__ ": g_notif_lock") }
}
static CRITICAL_SECTION_DEBUG g_notif_lock_debug
Definition: devenum.c:1099
LIST_ENTRY ProcessLocksList
Definition: winbase.h:883

Definition at line 1099 of file devenum.c.

◆ g_notif_thread

HANDLE g_notif_thread
static

◆ info_device

static IMMDevice info_device
static
Initial value:
= {
}
static const IMMDeviceVtbl info_device_Vtbl
Definition: devenum.c:1620

Definition at line 92 of file devenum.c.

Referenced by MMDevEnum_GetDevice().

◆ info_device_ps

IPropertyStore info_device_ps
static
Initial value:
= {
}
static const IPropertyStoreVtbl info_device_ps_Vtbl
Definition: devenum.c:1586

Definition at line 1598 of file devenum.c.

Referenced by info_device_OpenPropertyStore().

◆ info_device_ps_Vtbl

const IPropertyStoreVtbl info_device_ps_Vtbl
static
Initial value:
=
{
}
static ULONG WINAPI info_device_ps_Release(IPropertyStore *iface)
Definition: devenum.c:1559
static HRESULT WINAPI info_device_ps_GetValue(IPropertyStore *iface, REFPROPERTYKEY key, PROPVARIANT *pv)
Definition: devenum.c:1564
static ULONG WINAPI info_device_ps_AddRef(IPropertyStore *iface)
Definition: devenum.c:1554

Definition at line 1586 of file devenum.c.

◆ info_device_Vtbl

const IMMDeviceVtbl info_device_Vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI info_device_OpenPropertyStore(IMMDevice *iface, DWORD access, IPropertyStore **ppv)
Definition: devenum.c:1612
static ULONG WINAPI info_device_AddRef(IMMDevice *iface)
Definition: devenum.c:1602
static ULONG WINAPI info_device_Release(IMMDevice *iface)
Definition: devenum.c:1607

Definition at line 1620 of file devenum.c.

◆ key_capture

HKEY key_capture
static

◆ key_render

HKEY key_render
static

◆ MMDevColVtbl

static const IMMDeviceCollectionVtbl MMDevColVtbl
static
Initial value:
=
{
}
static HRESULT WINAPI MMDevCol_QueryInterface(IMMDeviceCollection *iface, REFIID riid, void **ppv)
Definition: devenum.c:790
static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdevs)
Definition: devenum.c:826
static ULONG WINAPI MMDevCol_Release(IMMDeviceCollection *iface)
Definition: devenum.c:816
static ULONG WINAPI MMDevCol_AddRef(IMMDeviceCollection *iface)
Definition: devenum.c:808
static HRESULT WINAPI MMDevCol_Item(IMMDeviceCollection *iface, UINT n, IMMDevice **dev)
Definition: devenum.c:846

Definition at line 87 of file devenum.c.

Referenced by MMDevCol_Create().

◆ MMDevEnumerator

MMDevEnumImpl* MMDevEnumerator
static

Definition at line 82 of file devenum.c.

Referenced by MMDevEnum_Create(), and MMDevEnum_Free().

◆ MMDevEnumVtbl

static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl
static
Initial value:
=
{
}
static ULONG WINAPI MMDevEnum_AddRef(IMMDeviceEnumerator *iface)
Definition: devenum.c:931
static HRESULT WINAPI MMDevEnum_QueryInterface(IMMDeviceEnumerator *iface, REFIID riid, void **ppv)
Definition: devenum.c:913
static HRESULT WINAPI MMDevEnum_UnregisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
Definition: devenum.c:1279
static HRESULT WINAPI MMDevEnum_EnumAudioEndpoints(IMMDeviceEnumerator *iface, EDataFlow flow, DWORD mask, IMMDeviceCollection **devices)
Definition: devenum.c:949
static HRESULT WINAPI MMDevEnum_GetDevice(IMMDeviceEnumerator *iface, const WCHAR *name, IMMDevice **device)
Definition: devenum.c:1046
static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint(IMMDeviceEnumerator *iface, EDataFlow flow, ERole role, IMMDevice **device)
Definition: devenum.c:963
static ULONG WINAPI MMDevEnum_Release(IMMDeviceEnumerator *iface)
Definition: devenum.c:939
static HRESULT WINAPI MMDevEnum_RegisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
Definition: devenum.c:1248

Definition at line 86 of file devenum.c.

Referenced by MMDevEnum_Create().

◆ MMDevice_count

DWORD MMDevice_count
static

◆ MMDevice_def_play

MMDevice * MMDevice_def_play
static

Definition at line 84 of file devenum.c.

Referenced by MMDevEnum_GetDefaultAudioEndpoint(), MMDevice_Create(), and notif_thread_proc().

◆ MMDevice_def_rec

MMDevice* MMDevice_def_rec
static

Definition at line 84 of file devenum.c.

Referenced by MMDevEnum_GetDefaultAudioEndpoint(), MMDevice_Create(), and notif_thread_proc().

◆ MMDevice_head

MMDevice** MMDevice_head
static

◆ MMDeviceVtbl

static const IMMDeviceVtbl MMDeviceVtbl
static
Initial value:
=
{
}
static HRESULT WINAPI MMDevice_GetState(IMMDevice *iface, DWORD *state)
Definition: devenum.c:703
static HRESULT WINAPI MMDevice_OpenPropertyStore(IMMDevice *iface, DWORD access, IPropertyStore **ppv)
Definition: devenum.c:669
static HRESULT WINAPI MMDevice_Activate(IMMDevice *iface, REFIID riid, DWORD clsctx, PROPVARIANT *params, void **ppv)
Definition: devenum.c:584
static HRESULT WINAPI MMDevice_GetId(IMMDevice *iface, WCHAR **itemid)
Definition: devenum.c:679
static ULONG WINAPI MMDevice_Release(IMMDevice *iface)
Definition: devenum.c:574
static HRESULT WINAPI MMDevice_QueryInterface(IMMDevice *iface, REFIID riid, void **ppv)
Definition: devenum.c:542
static ULONG WINAPI MMDevice_AddRef(IMMDevice *iface)
Definition: devenum.c:564

Definition at line 88 of file devenum.c.

Referenced by MMDevice_Create().

◆ MMDevPropVtbl

static const IPropertyStoreVtbl MMDevPropVtbl
static
Initial value:
=
{
}
static HRESULT WINAPI MMDevPropStore_GetCount(IPropertyStore *iface, DWORD *nprops)
Definition: devenum.c:1379
static HRESULT WINAPI MMDevPropStore_GetAt(IPropertyStore *iface, DWORD prop, PROPERTYKEY *key)
Definition: devenum.c:1406
static HRESULT WINAPI MMDevPropStore_SetValue(IPropertyStore *iface, REFPROPERTYKEY key, REFPROPVARIANT pv)
Definition: devenum.c:1460
static ULONG WINAPI MMDevPropStore_Release(IPropertyStore *iface)
Definition: devenum.c:1369
static HRESULT WINAPI MMDevPropStore_GetValue(IPropertyStore *iface, REFPROPERTYKEY key, PROPVARIANT *pv)
Definition: devenum.c:1435
static HRESULT WINAPI MMDevPropStore_Commit(IPropertyStore *iface)
Definition: devenum.c:1474
static HRESULT WINAPI MMDevPropStore_QueryInterface(IPropertyStore *iface, REFIID riid, void **ppv)
Definition: devenum.c:1343
static ULONG WINAPI MMDevPropStore_AddRef(IPropertyStore *iface)
Definition: devenum.c:1361

Definition at line 89 of file devenum.c.

Referenced by MMDevPropStore_Create().

◆ MMEndpointVtbl

static const IMMEndpointVtbl MMEndpointVtbl
static
Initial value:
=
{
}
static HRESULT WINAPI MMEndpoint_GetDataFlow(IMMEndpoint *iface, EDataFlow *flow)
Definition: devenum.c:751
static ULONG WINAPI MMEndpoint_Release(IMMEndpoint *iface)
Definition: devenum.c:744
static ULONG WINAPI MMEndpoint_AddRef(IMMEndpoint *iface)
Definition: devenum.c:737
static HRESULT WINAPI MMEndpoint_QueryInterface(IMMEndpoint *iface, REFIID riid, void **ppv)
Definition: devenum.c:730

Definition at line 90 of file devenum.c.

Referenced by MMDevice_Create().

◆ PB_Vtbl

static const IPropertyBagVtbl PB_Vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI PB_Write(IPropertyBag *iface, LPCOLESTR name, VARIANT *var)
Definition: devenum.c:1539
static ULONG WINAPI PB_AddRef(IPropertyBag *iface)
Definition: devenum.c:1510
static HRESULT WINAPI PB_Read(IPropertyBag *iface, LPCOLESTR name, VARIANT *var, IErrorLog *log)
Definition: devenum.c:1522
static HRESULT WINAPI PB_QueryInterface(IPropertyBag *iface, REFIID riid, void **ppv)
Definition: devenum.c:1503
static ULONG WINAPI PB_Release(IPropertyBag *iface)
Definition: devenum.c:1516

Definition at line 107 of file devenum.c.

Referenced by MMDevice_Activate().

◆ propkey_formatW

const WCHAR propkey_formatW[]
static
Initial value:
= {
'{','%','0','8','X','-','%','0','4','X','-',
'%','0','4','X','-','%','0','2','X','%','0','2','X','-',
'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',
'%','0','2','X','%','0','2','X','}',',','%','d',0 }

Definition at line 131 of file devenum.c.

Referenced by MMDevice_GetPropValue(), and MMDevice_SetPropValue().

◆ reg_capture

const WCHAR reg_capture[]
static
Initial value:
=
{ 'C','a','p','t','u','r','e',0 }

Definition at line 53 of file devenum.c.

Referenced by load_devices_from_reg().

◆ reg_devicestate

const WCHAR reg_devicestate[]
static
Initial value:
=
{ 'D','e','v','i','c','e','S','t','a','t','e',0 }

Definition at line 55 of file devenum.c.

Referenced by MMDevice_Create().

◆ reg_in_nameW

const WCHAR reg_in_nameW[] = {'D','e','f','a','u','l','t','I','n','p','u','t',0}
static

Definition at line 62 of file devenum.c.

Referenced by MMDevEnum_GetDefaultAudioEndpoint(), and notif_thread_proc().

◆ reg_out_nameW

const WCHAR reg_out_nameW[] = {'D','e','f','a','u','l','t','O','u','t','p','u','t',0}
static

Definition at line 60 of file devenum.c.

Referenced by MMDevEnum_GetDefaultAudioEndpoint(), and notif_thread_proc().

◆ reg_properties

const WCHAR reg_properties[]
static
Initial value:
=
{ 'P','r','o','p','e','r','t','i','e','s',0 }

Definition at line 57 of file devenum.c.

Referenced by MMDevice_Create(), and MMDevPropStore_OpenPropKey().

◆ reg_render

const WCHAR reg_render[]
static
Initial value:
=
{ 'R','e','n','d','e','r',0 }

Definition at line 51 of file devenum.c.

Referenced by load_devices_from_reg().

◆ reg_vin_nameW

const WCHAR reg_vin_nameW[] = {'D','e','f','a','u','l','t','V','o','i','c','e','I','n','p','u','t',0}
static

Definition at line 63 of file devenum.c.

Referenced by MMDevEnum_GetDefaultAudioEndpoint(), and notif_thread_proc().

◆ reg_vout_nameW

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

Definition at line 61 of file devenum.c.

Referenced by MMDevEnum_GetDefaultAudioEndpoint(), and notif_thread_proc().

◆ slashW

◆ software_mmdevapi

const WCHAR software_mmdevapi[]
static
Initial value:
=
{ 'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'M','M','D','e','v','i','c','e','s','\\',
'A','u','d','i','o',0}

Definition at line 44 of file devenum.c.

Referenced by load_devices_from_reg().