c19ff9f7d0d874c45e8da4b9f26af8c9e2cc199c
[reactos.git] / reactos / dll / directx / wine / dsound / propset.c
1 /* DirectSound
2 *
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2002 TransGaming Technologies, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #define COBJMACROS
23 #define NONAMELESSSTRUCT
24 #define NONAMELESSUNION
25
26 #define WIN32_NO_STATUS
27 #define _INC_WINDOWS
28 #define COM_NO_WINDOWS_H
29
30 #include <stdarg.h>
31
32 #include <windef.h>
33 #include <winbase.h>
34 //#include "winuser.h"
35 #include <mmsystem.h>
36 #include <winternl.h>
37 #include <winnls.h>
38 #include <vfwmsgs.h>
39 #include <initguid.h>
40 //#include <mmddk.h>
41 #include <wine/debug.h>
42 #include <dsound.h>
43 #include "dsound_private.h"
44 #include <dsconf.h>
45
46 //#include "ksmedia.h"
47 //#include "propkey.h"
48 #include <devpkey.h>
49
50 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
51
52 static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
53
54 typedef struct IKsPrivatePropertySetImpl
55 {
56 IKsPropertySet IKsPropertySet_iface;
57 LONG ref;
58 } IKsPrivatePropertySetImpl;
59
60 static IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *iface)
61 {
62 return CONTAINING_RECORD(iface, IKsPrivatePropertySetImpl, IKsPropertySet_iface);
63 }
64
65 /*******************************************************************************
66 * IKsPrivatePropertySet
67 */
68
69 /* IUnknown methods */
70 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
71 IKsPropertySet *iface, REFIID riid, void **ppobj)
72 {
73 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
74 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
75
76 if (IsEqualIID(riid, &IID_IUnknown) ||
77 IsEqualIID(riid, &IID_IKsPropertySet)) {
78 *ppobj = iface;
79 IKsPropertySet_AddRef(iface);
80 return S_OK;
81 }
82 *ppobj = NULL;
83 return E_NOINTERFACE;
84 }
85
86 static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface)
87 {
88 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
89 ULONG ref = InterlockedIncrement(&(This->ref));
90 TRACE("(%p) ref was %d\n", This, ref - 1);
91 return ref;
92 }
93
94 static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
95 {
96 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
97 ULONG ref = InterlockedDecrement(&(This->ref));
98 TRACE("(%p) ref was %d\n", This, ref + 1);
99
100 if (!ref) {
101 HeapFree(GetProcessHeap(), 0, This);
102 TRACE("(%p) released\n", This);
103 }
104 return ref;
105 }
106
107 struct search_data {
108 const WCHAR *tgt_name;
109 GUID *found_guid;
110 };
111
112 static BOOL CALLBACK search_callback(GUID *guid, const WCHAR *desc,
113 const WCHAR *module, void *user)
114 {
115 struct search_data *search = user;
116
117 if(!lstrcmpW(desc, search->tgt_name)){
118 *search->found_guid = *guid;
119 return FALSE;
120 }
121
122 return TRUE;
123 }
124
125 static HRESULT DSPROPERTY_WaveDeviceMappingW(
126 LPVOID pPropData,
127 ULONG cbPropData,
128 PULONG pcbReturned )
129 {
130 HRESULT hr;
131 PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd = pPropData;
132 struct search_data search;
133
134 TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
135 pPropData,cbPropData,pcbReturned);
136
137 if (!ppd) {
138 WARN("invalid parameter: pPropData\n");
139 return DSERR_INVALIDPARAM;
140 }
141
142 search.tgt_name = ppd->DeviceName;
143 search.found_guid = &ppd->DeviceId;
144
145 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
146 hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
147 search_callback, &search);
148 else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE)
149 hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
150 search_callback, &search);
151 else
152 return DSERR_INVALIDPARAM;
153
154 if(hr != S_FALSE)
155 /* device was not found */
156 return DSERR_INVALIDPARAM;
157
158 if (pcbReturned)
159 *pcbReturned = cbPropData;
160
161 return DS_OK;
162 }
163
164 static HRESULT DSPROPERTY_WaveDeviceMappingA(
165 LPVOID pPropData,
166 ULONG cbPropData,
167 PULONG pcbReturned )
168 {
169 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData;
170 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data;
171 DWORD len;
172 HRESULT hr;
173
174 TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
175 pPropData,cbPropData,pcbReturned);
176
177 if (!ppd || !ppd->DeviceName) {
178 WARN("invalid parameter: ppd=%p\n", ppd);
179 return DSERR_INVALIDPARAM;
180 }
181
182 data.DataFlow = ppd->DataFlow;
183 len = MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, NULL, 0);
184 data.DeviceName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
185 if (!data.DeviceName)
186 return E_OUTOFMEMORY;
187 MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, data.DeviceName, len);
188
189 hr = DSPROPERTY_WaveDeviceMappingW(&data, cbPropData, pcbReturned);
190 HeapFree(GetProcessHeap(), 0, data.DeviceName);
191 ppd->DeviceId = data.DeviceId;
192
193 if (pcbReturned)
194 *pcbReturned = cbPropData;
195
196 return hr;
197 }
198
199 static HRESULT DSPROPERTY_DescriptionW(
200 LPVOID pPropData,
201 ULONG cbPropData,
202 PULONG pcbReturned )
203 {
204 PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
205 GUID dev_guid;
206 IMMDevice *mmdevice;
207 IPropertyStore *ps;
208 PROPVARIANT pv;
209 DWORD desclen;
210 HRESULT hr;
211
212 TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
213 pPropData,cbPropData,pcbReturned);
214
215 TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
216 if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
217 /* default device of type specified by ppd->DataFlow */
218 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
219 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
220 ppd->DeviceId = DSDEVID_DefaultCapture;
221 } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
222 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
223 ppd->DeviceId = DSDEVID_DefaultPlayback;
224 } else {
225 WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow);
226 return E_PROP_ID_UNSUPPORTED;
227 }
228 }
229
230 setup_dsound_options();
231
232 GetDeviceID(&ppd->DeviceId, &dev_guid);
233
234 hr = get_mmdevice(eRender, &dev_guid, &mmdevice);
235 if(FAILED(hr)){
236 hr = get_mmdevice(eCapture, &dev_guid, &mmdevice);
237 if(FAILED(hr))
238 return hr;
239 }
240
241 hr = IMMDevice_OpenPropertyStore(mmdevice, STGM_READ, &ps);
242 if(FAILED(hr)){
243 IMMDevice_Release(mmdevice);
244 WARN("OpenPropertyStore failed: %08x\n", hr);
245 return hr;
246 }
247
248 hr = IPropertyStore_GetValue(ps,
249 (const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
250 if(FAILED(hr)){
251 IPropertyStore_Release(ps);
252 IMMDevice_Release(mmdevice);
253 WARN("GetValue(FriendlyName) failed: %08x\n", hr);
254 return hr;
255 }
256
257 desclen = lstrlenW(pv.u.pwszVal) + 1;
258 /* FIXME: Still a memory leak.. */
259 ppd->Description = HeapAlloc(GetProcessHeap(), 0, desclen * sizeof(WCHAR));
260 memcpy(ppd->Description, pv.u.pwszVal, desclen * sizeof(WCHAR));
261 ppd->Module = wine_vxd_drv;
262 ppd->Interface = wInterface;
263 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
264
265 PropVariantClear(&pv);
266 IPropertyStore_Release(ps);
267 IMMDevice_Release(mmdevice);
268
269 if (pcbReturned) {
270 *pcbReturned = sizeof(*ppd);
271 TRACE("*pcbReturned=%d\n", *pcbReturned);
272 }
273
274 return S_OK;
275 }
276
277 static
278 BOOL CALLBACK enum_callback(GUID *guid, const WCHAR *desc, const WCHAR *module,
279 void *user)
280 {
281 PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = user;
282 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
283 DWORD len;
284 BOOL ret;
285
286 TRACE("%s %s %s %p\n", wine_dbgstr_guid(guid), wine_dbgstr_w(desc),
287 wine_dbgstr_w(module), user);
288
289 if(!guid)
290 return TRUE;
291
292 data.DeviceId = *guid;
293
294 len = lstrlenW(module) + 1;
295 data.Module = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
296 memcpy(data.Module, module, len * sizeof(WCHAR));
297
298 len = lstrlenW(desc) + 1;
299 data.Description = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
300 memcpy(data.Description, desc, len * sizeof(WCHAR));
301
302 data.Interface = wInterface;
303
304 ret = ppd->Callback(&data, ppd->Context);
305
306 HeapFree(GetProcessHeap(), 0, data.Module);
307 HeapFree(GetProcessHeap(), 0, data.Description);
308
309 return ret;
310 }
311
312 static HRESULT DSPROPERTY_EnumerateW(
313 LPVOID pPropData,
314 ULONG cbPropData,
315 PULONG pcbReturned )
316 {
317 PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
318 HRESULT hr;
319
320 TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
321 pPropData,cbPropData,pcbReturned);
322
323 if (pcbReturned)
324 *pcbReturned = 0;
325
326 if (!ppd || !ppd->Callback)
327 {
328 WARN("Invalid ppd %p\n", ppd);
329 return E_PROP_ID_UNSUPPORTED;
330 }
331
332 hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
333 enum_callback, ppd);
334
335 if(hr == S_OK)
336 hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
337 enum_callback, ppd);
338
339 return SUCCEEDED(hr) ? DS_OK : hr;
340 }
341
342 static BOOL DSPROPERTY_descWtoA(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
343 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *dataA)
344 {
345 DWORD modlen, desclen;
346 static char Interface[] = "Interface";
347
348 modlen = WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, NULL, 0, NULL, NULL);
349 desclen = WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, NULL, 0, NULL, NULL);
350 dataA->Type = dataW->Type;
351 dataA->DataFlow = dataW->DataFlow;
352 dataA->DeviceId = dataW->DeviceId;
353 dataA->WaveDeviceId = dataW->WaveDeviceId;
354 dataA->Interface = Interface;
355 dataA->Module = HeapAlloc(GetProcessHeap(), 0, modlen);
356 dataA->Description = HeapAlloc(GetProcessHeap(), 0, desclen);
357 if (!dataA->Module || !dataA->Description)
358 {
359 HeapFree(GetProcessHeap(), 0, dataA->Module);
360 HeapFree(GetProcessHeap(), 0, dataA->Description);
361 dataA->Module = dataA->Description = NULL;
362 return FALSE;
363 }
364
365 WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, dataA->Module, modlen, NULL, NULL);
366 WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, dataA->Description, desclen, NULL, NULL);
367 return TRUE;
368 }
369
370 static void DSPROPERTY_descWto1(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
371 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *data1)
372 {
373 data1->DeviceId = dataW->DeviceId;
374 lstrcpynW(data1->ModuleW, dataW->Module, sizeof(data1->ModuleW)/sizeof(*data1->ModuleW));
375 lstrcpynW(data1->DescriptionW, dataW->Description, sizeof(data1->DescriptionW)/sizeof(*data1->DescriptionW));
376 WideCharToMultiByte(CP_ACP, 0, data1->DescriptionW, -1, data1->DescriptionA, sizeof(data1->DescriptionA)-1, NULL, NULL);
377 WideCharToMultiByte(CP_ACP, 0, data1->ModuleW, -1, data1->ModuleA, sizeof(data1->ModuleA)-1, NULL, NULL);
378 data1->DescriptionA[sizeof(data1->DescriptionA)-1] = 0;
379 data1->ModuleA[sizeof(data1->ModuleA)-1] = 0;
380 data1->Type = dataW->Type;
381 data1->DataFlow = dataW->DataFlow;
382 data1->WaveDeviceId = data1->Devnode = dataW->WaveDeviceId;
383 }
384
385 static BOOL CALLBACK DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
386 {
387 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA;
388 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = data;
389 BOOL ret;
390
391 ret = DSPROPERTY_descWtoA(descW, &descA);
392 if (!ret)
393 return FALSE;
394 ret = ppd->Callback(&descA, ppd->Context);
395 HeapFree(GetProcessHeap(), 0, descA.Module);
396 HeapFree(GetProcessHeap(), 0, descA.Description);
397 return ret;
398 }
399
400 static HRESULT DSPROPERTY_EnumerateA(
401 LPVOID pPropData,
402 ULONG cbPropData,
403 PULONG pcbReturned)
404 {
405 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData;
406 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
407
408 if (!ppd || !ppd->Callback)
409 {
410 WARN("Invalid ppd %p\n", ppd);
411 return E_PROP_ID_UNSUPPORTED;
412 }
413
414 data.Callback = DSPROPERTY_enumWtoA;
415 data.Context = ppd;
416
417 return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
418 }
419
420 static BOOL CALLBACK DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
421 {
422 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1;
423 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = data;
424 BOOL ret;
425
426 DSPROPERTY_descWto1(descW, &desc1);
427 ret = ppd->Callback(&desc1, ppd->Context);
428 return ret;
429 }
430
431 static HRESULT DSPROPERTY_Enumerate1(
432 LPVOID pPropData,
433 ULONG cbPropData,
434 PULONG pcbReturned)
435 {
436 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData;
437 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
438
439 if (!ppd || !ppd->Callback)
440 {
441 WARN("Invalid ppd %p\n", ppd);
442 return E_PROP_ID_UNSUPPORTED;
443 }
444
445 data.Callback = DSPROPERTY_enumWto1;
446 data.Context = ppd;
447
448 return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
449 }
450
451 static HRESULT DSPROPERTY_DescriptionA(
452 LPVOID pPropData,
453 ULONG cbPropData,
454 PULONG pcbReturned)
455 {
456 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
457 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *ppd = pPropData;
458 HRESULT hr;
459
460 if (pcbReturned)
461 *pcbReturned = sizeof(*ppd);
462 if (!pPropData)
463 return S_OK;
464
465 data.DeviceId = ppd->DeviceId;
466 data.DataFlow = ppd->DataFlow;
467 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
468 if (FAILED(hr))
469 return hr;
470 if (!DSPROPERTY_descWtoA(&data, ppd))
471 hr = E_OUTOFMEMORY;
472 HeapFree(GetProcessHeap(), 0, data.Module);
473 HeapFree(GetProcessHeap(), 0, data.Interface);
474 return hr;
475 }
476
477 static HRESULT DSPROPERTY_Description1(
478 LPVOID pPropData,
479 ULONG cbPropData,
480 PULONG pcbReturned)
481 {
482 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
483 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *ppd = pPropData;
484 HRESULT hr;
485
486 if (pcbReturned)
487 *pcbReturned = sizeof(*ppd);
488 if (!pPropData)
489 return S_OK;
490
491 data.DeviceId = ppd->DeviceId;
492 data.DataFlow = ppd->DataFlow;
493 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
494 if (FAILED(hr))
495 return hr;
496 DSPROPERTY_descWto1(&data, ppd);
497 HeapFree(GetProcessHeap(), 0, data.Module);
498 HeapFree(GetProcessHeap(), 0, data.Interface);
499 return hr;
500 }
501
502 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
503 LPKSPROPERTYSET iface,
504 REFGUID guidPropSet,
505 ULONG dwPropID,
506 LPVOID pInstanceData,
507 ULONG cbInstanceData,
508 LPVOID pPropData,
509 ULONG cbPropData,
510 PULONG pcbReturned )
511 {
512 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
513 TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
514 This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
515
516 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
517 switch (dwPropID) {
518 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
519 return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned);
520 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
521 return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned);
522 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
523 return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned);
524 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
525 return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned);
526 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
527 return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned);
528 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
529 return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned);
530 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
531 return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned);
532 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
533 return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned);
534 default:
535 FIXME("unsupported ID: %d\n",dwPropID);
536 break;
537 }
538 } else {
539 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
540 }
541
542 if (pcbReturned) {
543 *pcbReturned = 0;
544 FIXME("*pcbReturned=%d\n", *pcbReturned);
545 }
546
547 return E_PROP_ID_UNSUPPORTED;
548 }
549
550 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
551 LPKSPROPERTYSET iface,
552 REFGUID guidPropSet,
553 ULONG dwPropID,
554 LPVOID pInstanceData,
555 ULONG cbInstanceData,
556 LPVOID pPropData,
557 ULONG cbPropData )
558 {
559 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
560
561 FIXME("(%p,%s,%d,%p,%d,%p,%d), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
562 return E_PROP_ID_UNSUPPORTED;
563 }
564
565 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
566 LPKSPROPERTYSET iface,
567 REFGUID guidPropSet,
568 ULONG dwPropID,
569 PULONG pTypeSupport )
570 {
571 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
572 TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
573
574 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
575 switch (dwPropID) {
576 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
577 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
578 return S_OK;
579 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
580 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
581 return S_OK;
582 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
583 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
584 return S_OK;
585 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
586 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
587 return S_OK;
588 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
589 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
590 return S_OK;
591 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
592 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
593 return S_OK;
594 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
595 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
596 return S_OK;
597 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
598 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
599 return S_OK;
600 default:
601 FIXME("unsupported ID: %d\n",dwPropID);
602 break;
603 }
604 } else {
605 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
606 }
607
608 return E_PROP_ID_UNSUPPORTED;
609 }
610
611 static const IKsPropertySetVtbl ikspvt = {
612 IKsPrivatePropertySetImpl_QueryInterface,
613 IKsPrivatePropertySetImpl_AddRef,
614 IKsPrivatePropertySetImpl_Release,
615 IKsPrivatePropertySetImpl_Get,
616 IKsPrivatePropertySetImpl_Set,
617 IKsPrivatePropertySetImpl_QuerySupport
618 };
619
620 HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **ppv)
621 {
622 IKsPrivatePropertySetImpl *iks;
623 HRESULT hr;
624
625 TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
626
627 iks = HeapAlloc(GetProcessHeap(), 0, sizeof(*iks));
628 if (!iks) {
629 WARN("out of memory\n");
630 return DSERR_OUTOFMEMORY;
631 }
632
633 iks->ref = 1;
634 iks->IKsPropertySet_iface.lpVtbl = &ikspvt;
635
636 hr = IKsPropertySet_QueryInterface(&iks->IKsPropertySet_iface, riid, ppv);
637 IKsPropertySet_Release(&iks->IKsPropertySet_iface);
638
639 return hr;
640 }