ReactOS 0.4.15-dev-8096-ga0eec98
devenum.c
Go to the documentation of this file.
1/*
2 * Copyright 2009 Maarten Lankhorst
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include <stdarg.h>
20
21#define NONAMELESSUNION
22#define COBJMACROS
23#include "windef.h"
24#include "winbase.h"
25#include "winnls.h"
26#include "winreg.h"
27#include "wine/debug.h"
28#include "wine/list.h"
29
30#include "initguid.h"
31#include "ole2.h"
32#include "mmdeviceapi.h"
33#include "dshow.h"
34#include "dsound.h"
35#include "audioclient.h"
36#include "endpointvolume.h"
37#include "audiopolicy.h"
38
39#include "mmdevapi.h"
40#include "devpkey.h"
41
43
44static const WCHAR software_mmdevapi[] =
45 { 'S','o','f','t','w','a','r','e','\\',
46 'M','i','c','r','o','s','o','f','t','\\',
47 'W','i','n','d','o','w','s','\\',
48 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
49 'M','M','D','e','v','i','c','e','s','\\',
50 'A','u','d','i','o',0};
51static const WCHAR reg_render[] =
52 { 'R','e','n','d','e','r',0 };
53static const WCHAR reg_capture[] =
54 { 'C','a','p','t','u','r','e',0 };
55static const WCHAR reg_devicestate[] =
56 { 'D','e','v','i','c','e','S','t','a','t','e',0 };
57static const WCHAR reg_properties[] =
58 { 'P','r','o','p','e','r','t','i','e','s',0 };
59static const WCHAR slashW[] = {'\\',0};
60static const WCHAR reg_out_nameW[] = {'D','e','f','a','u','l','t','O','u','t','p','u','t',0};
61static const WCHAR reg_vout_nameW[] = {'D','e','f','a','u','l','t','V','o','i','c','e','O','u','t','p','u','t',0};
62static const WCHAR reg_in_nameW[] = {'D','e','f','a','u','l','t','I','n','p','u','t',0};
63static const WCHAR reg_vin_nameW[] = {'D','e','f','a','u','l','t','V','o','i','c','e','I','n','p','u','t',0};
64
67
68typedef struct MMDevPropStoreImpl
69{
75
76typedef struct MMDevEnumImpl
77{
81
86static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl;
87static const IMMDeviceCollectionVtbl MMDevColVtbl;
88static const IMMDeviceVtbl MMDeviceVtbl;
89static const IPropertyStoreVtbl MMDevPropVtbl;
90static const IMMEndpointVtbl MMEndpointVtbl;
91
93
94typedef struct MMDevColImpl
95{
101
102typedef struct IPropertyBagImpl {
106
107static const IPropertyBagVtbl PB_Vtbl;
108
110
112{
113 return CONTAINING_RECORD(iface, MMDevPropStore, IPropertyStore_iface);
114}
115
117{
118 return CONTAINING_RECORD(iface, MMDevEnumImpl, IMMDeviceEnumerator_iface);
119}
120
122{
123 return CONTAINING_RECORD(iface, MMDevColImpl, IMMDeviceCollection_iface);
124}
125
127{
128 return CONTAINING_RECORD(iface, IPropertyBagImpl, IPropertyBag_iface);
129}
130
131static const WCHAR propkey_formatW[] = {
132 '{','%','0','8','X','-','%','0','4','X','-',
133 '%','0','4','X','-','%','0','2','X','%','0','2','X','-',
134 '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',
135 '%','0','2','X','%','0','2','X','}',',','%','d',0 };
136
137static HRESULT MMDevPropStore_OpenPropKey(const GUID *guid, DWORD flow, HKEY *propkey)
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}
157
158static HRESULT MMDevice_GetPropValue(const GUID *devguid, DWORD flow, REFPROPERTYKEY key, PROPVARIANT *pv)
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}
219
220static HRESULT MMDevice_SetPropValue(const GUID *devguid, DWORD flow, REFPROPERTYKEY key, REFPROPVARIANT pv)
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}
263
264static HRESULT set_driver_prop_value(GUID *id, const EDataFlow flow, const PROPERTYKEY *prop)
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}
282
283/* Creates or updates the state of a device
284 * If GUID is null, a random guid will be assigned
285 * and the device will be created
286 */
287static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD state, BOOL setdefault)
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}
399
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}
459
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}
490
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}
517
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}
536
538{
539 return CONTAINING_RECORD(iface, MMDevice, IMMDevice_iface);
540}
541
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}
563
565{
567 LONG ref;
568
570 TRACE("Refcount now %i\n", ref);
571 return ref;
572}
573
575{
577 LONG ref;
578
580 TRACE("Refcount now %i\n", ref);
581 return ref;
582}
583
584static HRESULT WINAPI MMDevice_Activate(IMMDevice *iface, REFIID riid, DWORD clsctx, PROPVARIANT *params, void **ppv)
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}
668
670{
672 TRACE("(%p)->(%x,%p)\n", This, access, ppv);
673
674 if (!ppv)
675 return E_POINTER;
677}
678
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}
702
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}
713
714static const IMMDeviceVtbl MMDeviceVtbl =
715{
723};
724
726{
727 return CONTAINING_RECORD(iface, MMDevice, IMMEndpoint_iface);
728}
729
731{
733 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
734 return IMMDevice_QueryInterface(&This->IMMDevice_iface, riid, ppv);
735}
736
738{
740 TRACE("(%p)\n", This);
741 return IMMDevice_AddRef(&This->IMMDevice_iface);
742}
743
745{
747 TRACE("(%p)\n", This);
748 return IMMDevice_Release(&This->IMMDevice_iface);
749}
750
752{
754 TRACE("(%p)->(%p)\n", This, flow);
755 if (!flow)
756 return E_POINTER;
757 *flow = This->flow;
758 return S_OK;
759}
760
761static const IMMEndpointVtbl MMEndpointVtbl =
762{
767};
768
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}
784
786{
788}
789
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}
807
809{
812 TRACE("Refcount now %i\n", ref);
813 return ref;
814}
815
817{
820 TRACE("Refcount now %i\n", ref);
821 if (!ref)
823 return ref;
824}
825
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}
845
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}
871
872static const IMMDeviceCollectionVtbl MMDevColVtbl =
873{
879};
880
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}
901
903{
904 while (MMDevice_count)
911}
912
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}
930
932{
935 TRACE("Refcount now %i\n", ref);
936 return ref;
937}
938
940{
943 if (!ref)
945 TRACE("Refcount now %i\n", ref);
946 return ref;
947}
948
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}
962
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}
1045
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}
1089
1092 struct list entry;
1093};
1094
1097
1100{
1101 0, 0, &g_notif_lock,
1103 0, 0, { (DWORD_PTR)(__FILE__ ": g_notif_lock") }
1104};
1105static CRITICAL_SECTION g_notif_lock = { &g_notif_lock_debug, -1, 0, 0, 0, 0 };
1106
1107static void notify_clients(EDataFlow flow, ERole role, const WCHAR *id)
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}
1119
1121 const WCHAR *val_name, WCHAR *old_val, IMMDevice *def_dev)
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}
1180
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}
1247
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}
1278
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}
1304
1305static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl =
1306{
1315};
1316
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}
1337
1339{
1341}
1342
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}
1360
1362{
1365 TRACE("Refcount now %i\n", ref);
1366 return ref;
1367}
1368
1370{
1373 TRACE("Refcount now %i\n", ref);
1374 if (!ref)
1376 return ref;
1377}
1378
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}
1405
1406static HRESULT WINAPI MMDevPropStore_GetAt(IPropertyStore *iface, DWORD prop, PROPERTYKEY *key)
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}
1434
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}
1459
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}
1473
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}
1488
1489static const IPropertyStoreVtbl MMDevPropVtbl =
1490{
1499};
1500
1501
1502/* Property bag for IBaseFilter activation */
1504{
1505 ERR("Should not be called\n");
1506 *ppv = NULL;
1507 return E_NOINTERFACE;
1508}
1509
1511{
1512 ERR("Should not be called\n");
1513 return 2;
1514}
1515
1517{
1518 ERR("Should not be called\n");
1519 return 1;
1520}
1521
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}
1538
1540{
1541 ERR("Should not be called\n");
1542 return E_FAIL;
1543}
1544
1545static const IPropertyBagVtbl PB_Vtbl =
1546{
1548 PB_AddRef,
1549 PB_Release,
1550 PB_Read,
1551 PB_Write
1552};
1553
1555{
1556 return 2;
1557}
1558
1560{
1561 return 1;
1562}
1563
1565 REFPROPERTYKEY key, PROPVARIANT *pv)
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}
1585
1586static const IPropertyStoreVtbl info_device_ps_Vtbl =
1587{
1588 NULL,
1591 NULL,
1592 NULL,
1594 NULL,
1595 NULL
1596};
1597
1600};
1601
1603{
1604 return 2;
1605}
1606
1608{
1609 return 1;
1610}
1611
1614{
1615 TRACE("(static)->(%x, %p)\n", access, ppv);
1616 *ppv = &info_device_ps;
1617 return S_OK;
1618}
1619
1620static const IMMDeviceVtbl info_device_Vtbl =
1621{
1622 NULL,
1625 NULL,
1627 NULL,
1628 NULL
1629};
1630
1631static IMMDevice info_device = {
1633};
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv)
Definition: audiovolume.c:305
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ARRAY_SIZE(A)
Definition: main.h:33
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:114
#define WARN(fmt,...)
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:113
#define RegCloseKey(hKey)
Definition: registry.h:49
struct _root root
Definition: list.h:37
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
const GUID IID_IBaseFilter
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#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 RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
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:2504
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
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:4882
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:2830
LONG WINAPI RegNotifyChangeKeyValue(HKEY hKey, BOOL bWatchSubtree, DWORD dwNotifyFilter, HANDLE hEvent, BOOL fAsynchronous)
Definition: reg.c:3152
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
@ VT_BLOB
Definition: compat.h:2330
@ VT_BSTR
Definition: compat.h:2303
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_UI4
Definition: compat.h:2313
@ VT_EMPTY
Definition: compat.h:2295
#define lstrlenW
Definition: compat.h:750
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
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4242
static MMDevice * MMDevice_def_play
Definition: devenum.c:84
static HRESULT WINAPI PB_Write(IPropertyBag *iface, LPCOLESTR name, VARIANT *var)
Definition: devenum.c:1539
static HRESULT load_devices_from_reg(void)
Definition: devenum.c:400
static HRESULT MMDevCol_Create(IMMDeviceCollection **ppv, EDataFlow flow, DWORD state)
Definition: devenum.c:769
static void MMDevice_Destroy(MMDevice *This)
Definition: devenum.c:518
static const IMMEndpointVtbl MMEndpointVtbl
Definition: devenum.c:90
static const IPropertyStoreVtbl info_device_ps_Vtbl
Definition: devenum.c:1586
static HRESULT WINAPI MMEndpoint_GetDataFlow(IMMEndpoint *iface, EDataFlow *flow)
Definition: devenum.c:751
static const IMMDeviceVtbl info_device_Vtbl
Definition: devenum.c:1620
static ULONG WINAPI MMDevEnum_AddRef(IMMDeviceEnumerator *iface)
Definition: devenum.c:931
static const WCHAR reg_vout_nameW[]
Definition: devenum.c:61
static MMDevice * impl_from_IMMDevice(IMMDevice *iface)
Definition: devenum.c:537
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 const IPropertyBagVtbl PB_Vtbl
Definition: devenum.c:107
static ULONG WINAPI MMEndpoint_Release(IMMEndpoint *iface)
Definition: devenum.c:744
static HRESULT WINAPI MMDevCol_QueryInterface(IMMDeviceCollection *iface, REFIID riid, void **ppv)
Definition: devenum.c:790
static HRESULT WINAPI MMDevPropStore_SetValue(IPropertyStore *iface, REFPROPERTYKEY key, REFPROPVARIANT pv)
Definition: devenum.c:1460
static HRESULT WINAPI info_device_OpenPropertyStore(IMMDevice *iface, DWORD access, IPropertyStore **ppv)
Definition: devenum.c:1612
static HKEY key_render
Definition: devenum.c:65
static const WCHAR propkey_formatW[]
Definition: devenum.c:131
static MMDevColImpl * impl_from_IMMDeviceCollection(IMMDeviceCollection *iface)
Definition: devenum.c:121
static ULONG WINAPI MMEndpoint_AddRef(IMMEndpoint *iface)
Definition: devenum.c:737
static const WCHAR reg_vin_nameW[]
Definition: devenum.c:63
static const WCHAR software_mmdevapi[]
Definition: devenum.c:44
static IPropertyStore info_device_ps
Definition: devenum.c:1598
static CRITICAL_SECTION_DEBUG g_notif_lock_debug
Definition: devenum.c:1099
static MMDevice * impl_from_IMMEndpoint(IMMEndpoint *iface)
Definition: devenum.c:725
static IPropertyBagImpl * impl_from_IPropertyBag(IPropertyBag *iface)
Definition: devenum.c:126
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 MMDevPropStore * impl_from_IPropertyStore(IPropertyStore *iface)
Definition: devenum.c:111
static HRESULT WINAPI MMDevEnum_QueryInterface(IMMDeviceEnumerator *iface, REFIID riid, void **ppv)
Definition: devenum.c:913
static DWORD WINAPI notif_thread_proc(void *user)
Definition: devenum.c:1181
static const WCHAR reg_out_nameW[]
Definition: devenum.c:60
void MMDevEnum_Free(void)
Definition: devenum.c:902
static HRESULT WINAPI MMDevCol_GetCount(IMMDeviceCollection *iface, UINT *numdevs)
Definition: devenum.c:826
static ULONG WINAPI info_device_ps_Release(IPropertyStore *iface)
Definition: devenum.c:1559
static ULONG WINAPI PB_AddRef(IPropertyBag *iface)
Definition: devenum.c:1510
static DWORD MMDevice_count
Definition: devenum.c:85
static void MMDevCol_Destroy(MMDevColImpl *This)
Definition: devenum.c:785
static MMDevice * MMDevice_def_rec
Definition: devenum.c:84
static HRESULT MMDevPropStore_Create(MMDevice *This, DWORD access, IPropertyStore **ppv)
Definition: devenum.c:1317
static HRESULT WINAPI MMDevice_GetState(IMMDevice *iface, DWORD *state)
Definition: devenum.c:703
static ULONG WINAPI MMDevCol_Release(IMMDeviceCollection *iface)
Definition: devenum.c:816
static HRESULT WINAPI MMDevice_OpenPropertyStore(IMMDevice *iface, DWORD access, IPropertyStore **ppv)
Definition: devenum.c:669
static const IMMDeviceCollectionVtbl MMDevColVtbl
Definition: devenum.c:87
static HRESULT WINAPI MMDevEnum_UnregisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
Definition: devenum.c:1279
static ULONG WINAPI MMDevPropStore_Release(IPropertyStore *iface)
Definition: devenum.c:1369
static HRESULT WINAPI MMEndpoint_QueryInterface(IMMEndpoint *iface, REFIID riid, void **ppv)
Definition: devenum.c:730
static HRESULT WINAPI MMDevPropStore_GetValue(IPropertyStore *iface, REFPROPERTYKEY key, PROPVARIANT *pv)
Definition: devenum.c:1435
static const WCHAR slashW[]
Definition: devenum.c:59
static HRESULT WINAPI MMDevEnum_EnumAudioEndpoints(IMMDeviceEnumerator *iface, EDataFlow flow, DWORD mask, IMMDeviceCollection **devices)
Definition: devenum.c:949
static HRESULT WINAPI MMDevice_Activate(IMMDevice *iface, REFIID riid, DWORD clsctx, PROPVARIANT *params, void **ppv)
Definition: devenum.c:584
static ULONG WINAPI info_device_AddRef(IMMDevice *iface)
Definition: devenum.c:1602
static const WCHAR reg_capture[]
Definition: devenum.c:53
static HRESULT WINAPI PB_Read(IPropertyBag *iface, LPCOLESTR name, VARIANT *var, IErrorLog *log)
Definition: devenum.c:1522
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
static HRESULT MMDevPropStore_OpenPropKey(const GUID *guid, DWORD flow, HKEY *propkey)
Definition: devenum.c:137
static ULONG WINAPI MMDevCol_AddRef(IMMDeviceCollection *iface)
Definition: devenum.c:808
static void notify_clients(EDataFlow flow, ERole role, const WCHAR *id)
Definition: devenum.c:1107
static HANDLE g_notif_thread
Definition: devenum.c:1096
static const WCHAR reg_devicestate[]
Definition: devenum.c:55
static HRESULT WINAPI MMDevice_GetId(IMMDevice *iface, WCHAR **itemid)
Definition: devenum.c:679
static HRESULT WINAPI MMDevPropStore_Commit(IPropertyStore *iface)
Definition: devenum.c:1474
static HRESULT WINAPI info_device_ps_GetValue(IPropertyStore *iface, REFPROPERTYKEY key, PROPVARIANT *pv)
Definition: devenum.c:1564
static const IPropertyStoreVtbl MMDevPropVtbl
Definition: devenum.c:89
static ULONG WINAPI info_device_Release(IMMDevice *iface)
Definition: devenum.c:1607
static MMDevEnumImpl * MMDevEnumerator
Definition: devenum.c:82
static MMDevice ** MMDevice_head
Definition: devenum.c:83
static HRESULT set_format(MMDevice *dev)
Definition: devenum.c:460
static HRESULT WINAPI MMDevEnum_GetDevice(IMMDeviceEnumerator *iface, const WCHAR *name, IMMDevice **device)
Definition: devenum.c:1046
static HRESULT load_driver_devices(EDataFlow flow)
Definition: devenum.c:491
static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl
Definition: devenum.c:86
static const IMMDeviceVtbl MMDeviceVtbl
Definition: devenum.c:88
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 ULONG WINAPI MMDevice_Release(IMMDevice *iface)
Definition: devenum.c:574
static HRESULT WINAPI MMDevCol_Item(IMMDeviceCollection *iface, UINT n, IMMDevice **dev)
Definition: devenum.c:846
static void MMDevPropStore_Destroy(MMDevPropStore *This)
Definition: devenum.c:1338
static HRESULT WINAPI PB_QueryInterface(IPropertyBag *iface, REFIID riid, void **ppv)
Definition: devenum.c:1503
static HRESULT MMDevice_SetPropValue(const GUID *devguid, DWORD flow, REFPROPERTYKEY key, REFPROPVARIANT pv)
Definition: devenum.c:220
static CRITICAL_SECTION g_notif_lock
Definition: devenum.c:1098
static const WCHAR reg_in_nameW[]
Definition: devenum.c:62
static IMMDevice info_device
Definition: devenum.c:92
static ULONG WINAPI PB_Release(IPropertyBag *iface)
Definition: devenum.c:1516
static HRESULT WINAPI MMDevEnum_RegisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
Definition: devenum.c:1248
static const WCHAR reg_properties[]
Definition: devenum.c:57
static HRESULT WINAPI MMDevice_QueryInterface(IMMDevice *iface, REFIID riid, void **ppv)
Definition: devenum.c:542
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
static const WCHAR reg_render[]
Definition: devenum.c:51
static ULONG WINAPI MMDevice_AddRef(IMMDevice *iface)
Definition: devenum.c:564
HRESULT MMDevEnum_Create(REFIID riid, void **ppv)
Definition: devenum.c:881
static MMDevice * MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD state, BOOL setdefault)
Definition: devenum.c:287
static ULONG WINAPI info_device_ps_AddRef(IPropertyStore *iface)
Definition: devenum.c:1554
static struct list g_notif_clients
Definition: devenum.c:1095
static MMDevEnumImpl * impl_from_IMMDeviceEnumerator(IMMDeviceEnumerator *iface)
Definition: devenum.c:116
struct MMDevPropStoreImpl MMDevPropStore
static HRESULT set_driver_prop_value(GUID *id, const EDataFlow flow, const PROPERTYKEY *prop)
Definition: devenum.c:264
const WCHAR drv_keyW[]
Definition: main.c:50
DriverFuncs drvs
Definition: main.c:48
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2968
#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
r parent
Definition: btrfs.c:3010
static struct all_devices * devices
Definition: dsm_ctrl.c:48
#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
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxCollectionEntry * cur
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint * ids
Definition: glext.h:5907
GLuint buffer
Definition: glext.h:5915
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum const GLfloat * params
Definition: glext.h:5645
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
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
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
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define REG_SZ
Definition: layer.c:22
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
enum _ERole ERole
@ eAll
Definition: mmdeviceapi.idl:65
@ eCapture
Definition: mmdeviceapi.idl:64
@ EDataFlow_enum_count
Definition: mmdeviceapi.idl:66
@ eRender
Definition: mmdeviceapi.idl:63
@ eMultimedia
Definition: mmdeviceapi.idl:72
@ eConsole
Definition: mmdeviceapi.idl:71
@ eCommunications
Definition: mmdeviceapi.idl:73
enum _EDataFlow EDataFlow
@ Microphone
Definition: mmdeviceapi.idl:83
@ Speakers
Definition: mmdeviceapi.idl:80
const char * var
Definition: shader.c:5666
unsigned int UINT
Definition: ndis.h:50
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_WRITE
Definition: nt_native.h:1031
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_WRITE
Definition: objbase.h:918
#define STGM_READ
Definition: objbase.h:917
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
long LONG
Definition: pedump.c:60
#define IsEqualPropertyKey(a, b)
Definition: propkeydef.h:52
PROPERTYKEY * REFPROPERTYKEY
Definition: propsys.idl:34
const GUID IID_IPersistPropertyBag
Definition: proxy.cpp:11
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define log(outFile, fmt,...)
Definition: util.h:15
static FILE * client
Definition: client.c:41
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
IPropertyBag IPropertyBag_iface
Definition: devenum.c:103
LONG ref
Definition: devenum.c:97
IMMDeviceCollection IMMDeviceCollection_iface
Definition: devenum.c:96
DWORD state
Definition: devenum.c:99
EDataFlow flow
Definition: devenum.c:98
IMMDeviceEnumerator IMMDeviceEnumerator_iface
Definition: devenum.c:78
LONG ref
Definition: devenum.c:79
IPropertyStore IPropertyStore_iface
Definition: devenum.c:70
MMDevice * parent
Definition: devenum.c:72
IMMDevice IMMDevice_iface
Definition: mmdevapi.h:62
IMMNotificationClient * client
Definition: devenum.c:1091
LIST_ENTRY ProcessLocksList
Definition: winbase.h:883
WCHAR module_name[64]
Definition: mmdevapi.h:35
Definition: devices.h:37
Definition: dsound.c:943
Definition: copy.c:22
Definition: name.c:39
Definition: send.c:48
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define LIST_INIT(head)
Definition: queue.h:197
#define DWORD_PTR
Definition: treelist.c:76
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
const void * pv2
Definition: winddi.h:2453
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define STG_E_ACCESSDENIED
Definition: winerror.h:2568
#define E_POINTER
Definition: winerror.h:2365
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RRF_RT_ANY
Definition: winreg.h:64
#define REG_NOTIFY_CHANGE_LAST_SET
Definition: winreg.h:40
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193