Wrap the wide-char enumerating functions instead of the ASCII
[dsound-openal.git] / propset.c
blob3e5aee40b7d1a9812c128894bfd7d3bb56d68c63
1 /* DirectSound
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2002 TransGaming Technologies, Inc.
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.
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.
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
22 #include <stdarg.h>
24 #ifdef __WINESRC__
26 #define COBJMACROS
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "mmsystem.h"
32 #include "winternl.h"
33 #include "winnls.h"
34 #include "vfwmsgs.h"
35 #include "mmddk.h"
36 #include "wine/debug.h"
37 #include "dsound.h"
38 #include "dsdriver.h"
40 #include "dsound_private.h"
41 #include "dsconf.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
45 #else
47 #define WINVER 0x0600
48 #include <windows.h>
49 #include <dsound.h>
51 #include "dsound_private.h"
53 typedef enum {
54 DIRECTSOUNDDEVICE_DATAFLOW_RENDER,
55 DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE
56 } DIRECTSOUNDDEVICE_DATAFLOW;
58 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA {
59 LPSTR DeviceName;
60 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
61 GUID DeviceId;
62 } DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA;
64 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA {
65 LPWSTR DeviceName;
66 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
67 GUID DeviceId;
68 } DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA;
70 typedef enum {
71 DIRECTSOUNDDEVICE_TYPE_EMULATED,
72 DIRECTSOUNDDEVICE_TYPE_VXD,
73 DIRECTSOUNDDEVICE_TYPE_WDM
74 } DIRECTSOUNDDEVICE_TYPE;
76 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA {
77 GUID DeviceId;
78 CHAR DescriptionA[0x100];
79 WCHAR DescriptionW[0x100];
80 CHAR ModuleA[MAX_PATH];
81 WCHAR ModuleW[MAX_PATH];
82 DIRECTSOUNDDEVICE_TYPE Type;
83 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
84 ULONG WaveDeviceId;
85 ULONG Devnode;
86 } DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA;
88 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA {
89 DIRECTSOUNDDEVICE_TYPE Type;
90 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
91 GUID DeviceId;
92 LPSTR Description;
93 LPSTR Module;
94 LPSTR Interface;
95 ULONG WaveDeviceId;
96 } DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA;
98 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA {
99 DIRECTSOUNDDEVICE_TYPE Type;
100 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
101 GUID DeviceId;
102 LPWSTR Description;
103 LPWSTR Module;
104 LPWSTR Interface;
105 ULONG WaveDeviceId;
106 } DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA;
108 typedef struct _DSDRIVERDESC {
109 DWORD dwFlags;
110 CHAR szDesc[256];
111 CHAR szDrvname[256];
112 DWORD dnDevNode;
113 WORD wVxdId;
114 WORD wReserved;
115 ULONG ulDeviceNum;
116 DWORD dwHeapType;
117 LPVOID pvDirectDrawHeap;
118 DWORD dwMemStartAddress;
119 DWORD dwMemEndAddress;
120 DWORD dwMemAllocExtra;
121 LPVOID pvReserved1;
122 LPVOID pvReserved2;
123 } DSDRIVERDESC,*PDSDRIVERDESC;
125 #ifndef E_PROP_ID_UNSUPPORTED
126 #define E_PROP_ID_UNSUPPORTED ((HRESULT)0x80070490)
127 #endif
129 #ifndef DRV_QUERYDSOUNDDESC
130 #define DRV_QUERYDSOUNDDESC (DRV_RESERVED + 21)
131 #endif
133 typedef BOOL (CALLBACK *LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK1)(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA, LPVOID);
134 typedef BOOL (CALLBACK *LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKA)(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA, LPVOID);
135 typedef BOOL (CALLBACK *LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKW)(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA, LPVOID);
137 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA {
138 LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK1 Callback;
139 LPVOID Context;
140 } DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA;
142 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA {
143 LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKA Callback;
144 LPVOID Context;
145 } DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA;
147 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA {
148 LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKW Callback;
149 LPVOID Context;
150 } DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA;
152 DEFINE_GUID(DSPROPSETID_DirectSoundDevice,0x84624f82,0x25ec,0x11d1,0xa4,0xd8,0x00,0xc0,0x4f,0xc2,0x8a,0xca);
154 typedef enum {
155 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A = 1,
156 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1 = 2,
157 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1 = 3,
158 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W = 4,
159 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A = 5,
160 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W = 6,
161 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A = 7,
162 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W = 8,
163 } DSPROPERTY_DIRECTSOUNDDEVICE;
165 #ifndef ULongToHandle
166 #define ULongToHandle(ul) ((HANDLE)(ULONG_PTR)(ul))
167 #endif
168 #ifndef UlongToHandle
169 #define UlongToHandle(ul) ULongToHandle(ul)
170 #endif
172 #endif
174 typedef struct IKsPrivatePropertySetImpl {
175 IKsPropertySet IKsPropertySet_iface;
176 LONG ref;
177 } IKsPrivatePropertySetImpl;
179 /*******************************************************************************
180 * IKsPrivatePropertySet
183 static inline IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *iface)
185 return CONTAINING_RECORD(iface, IKsPrivatePropertySetImpl, IKsPropertySet_iface);
188 /* IUnknown methods */
189 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
190 IKsPropertySet *iface,
191 REFIID riid,
192 LPVOID *ppobj )
194 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
195 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
197 if (IsEqualIID(riid, &IID_IUnknown) ||
198 IsEqualIID(riid, &IID_IKsPropertySet)) {
199 *ppobj = iface;
200 IUnknown_AddRef(iface);
201 return S_OK;
203 *ppobj = NULL;
204 return E_NOINTERFACE;
207 static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(IKsPropertySet *iface)
209 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
210 ULONG ref = InterlockedIncrement(&(This->ref));
211 TRACE("(%p) ref was %u\n", This, ref - 1);
212 return ref;
215 static ULONG WINAPI IKsPrivatePropertySetImpl_Release(IKsPropertySet *iface)
217 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
218 ULONG ref = InterlockedDecrement(&(This->ref));
219 TRACE("(%p) ref was %u\n", This, ref + 1);
221 if (!ref) {
222 HeapFree(GetProcessHeap(), 0, This);
223 TRACE("(%p) released\n", This);
225 return ref;
228 static HRESULT DSPROPERTY_WaveDeviceMappingW(
229 LPVOID pPropData,
230 ULONG cbPropData,
231 PULONG pcbReturned )
233 HRESULT hr = DSERR_INVALIDPARAM;
234 PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
235 TRACE("(pPropData=%p,cbPropData=%u,pcbReturned=%p)\n",
236 pPropData,cbPropData,pcbReturned);
238 ppd = pPropData;
239 if (!ppd) {
240 WARN("invalid parameter: pPropData\n");
241 return DSERR_INVALIDPARAM;
244 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
245 ULONG wod;
246 unsigned int wodn;
247 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
248 wodn = waveOutGetNumDevs();
249 for (wod = 0; wod < wodn; wod++) {
250 WAVEOUTCAPSW capsW;
251 MMRESULT res;
252 res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
253 if (res == MMSYSERR_NOERROR) {
254 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
255 ppd->DeviceId = DSOUND_renderer_guid;
256 ppd->DeviceId.Data4[7] = wod;
257 hr = DS_OK;
258 TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
259 debugstr_w(ppd->DeviceName));
260 break;
264 } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
265 ULONG wid;
266 unsigned int widn;
267 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
268 widn = waveInGetNumDevs();
269 for (wid = 0; wid < widn; wid++) {
270 WAVEINCAPSW capsW;
271 MMRESULT res;
272 res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
273 if (res == MMSYSERR_NOERROR) {
274 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
275 ppd->DeviceId = DSOUND_capture_guid;
276 ppd->DeviceId.Data4[7] = wid;
277 hr = DS_OK;
278 TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
279 debugstr_w(ppd->DeviceName));
280 break;
286 if (pcbReturned)
287 *pcbReturned = cbPropData;
289 return hr;
292 static HRESULT DSPROPERTY_WaveDeviceMappingA(
293 LPVOID pPropData,
294 ULONG cbPropData,
295 PULONG pcbReturned )
297 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data;
298 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData;
299 DWORD len;
300 HRESULT hr;
302 TRACE("(pPropData=%p,cbPropData=%u,pcbReturned=%p)\n",
303 pPropData,cbPropData,pcbReturned);
305 if (!ppd || !ppd->DeviceName) {
306 WARN("invalid parameter: ppd=%p\n", ppd);
307 return DSERR_INVALIDPARAM;
310 data.DataFlow = ppd->DataFlow;
311 len = strlen(ppd->DeviceName)+1;
312 data.DeviceName = HeapAlloc(GetProcessHeap(), 0, len);
313 if (!data.DeviceName)
314 return E_OUTOFMEMORY;
315 MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, data.DeviceName, len );
317 hr = DSPROPERTY_WaveDeviceMappingW(&data, cbPropData, pcbReturned);
318 HeapFree(GetProcessHeap(), 0, data.DeviceName);
319 ppd->DeviceId = data.DeviceId;
321 if (pcbReturned)
322 *pcbReturned = cbPropData;
324 return hr;
327 static HRESULT DSPROPERTY_DescriptionW(
328 LPVOID pPropData,
329 ULONG cbPropData,
330 PULONG pcbReturned )
332 PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
333 HRESULT err;
334 GUID dev_guid;
335 ULONG wod, wid, wodn, widn;
336 DSDRIVERDESC desc;
338 TRACE("pPropData=%p,cbPropData=%u,pcbReturned=%p)\n",
339 pPropData,cbPropData,pcbReturned);
341 TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
342 if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
343 /* default device of type specified by ppd->DataFlow */
344 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
345 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
346 ppd->DeviceId = DSDEVID_DefaultCapture;
347 } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
348 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
349 ppd->DeviceId = DSDEVID_DefaultPlayback;
350 } else {
351 WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow);
352 return E_PROP_ID_UNSUPPORTED;
356 GetDeviceID(&ppd->DeviceId, &dev_guid);
358 wodn = waveOutGetNumDevs();
359 widn = waveInGetNumDevs();
360 wid = wod = dev_guid.Data4[7];
361 if (!memcmp(&dev_guid, &DSOUND_renderer_guid, sizeof(GUID)-1)
362 && wod < wodn)
364 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
365 ppd->WaveDeviceId = wod;
367 else if (!memcmp(&dev_guid, &DSOUND_capture_guid, sizeof(GUID)-1)
368 && wid < widn)
370 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
371 ppd->WaveDeviceId = wid;
373 else
375 WARN("Device not found\n");
376 return E_PROP_ID_UNSUPPORTED;
379 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
380 err = waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0);
381 else
382 err = waveInMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0);
384 if (err != MMSYSERR_NOERROR)
386 WARN("waveMessage(DRV_QUERYDSOUNDDESC) failed!\n");
387 return E_PROP_ID_UNSUPPORTED;
389 else
391 /* FIXME: Still a memory leak.. */
392 int desclen, modlen;
393 static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
395 modlen = strlen(desc.szDrvname)+1;
396 desclen = strlen(desc.szDesc)+1;
397 ppd->Module = HeapAlloc(GetProcessHeap(),0,modlen*sizeof(WCHAR));
398 ppd->Description = HeapAlloc(GetProcessHeap(),0,desclen*sizeof(WCHAR));
399 ppd->Interface = wInterface;
400 if (!ppd->Description || !ppd->Module)
402 WARN("Out of memory\n");
403 HeapFree(GetProcessHeap(), 0, ppd->Description);
404 HeapFree(GetProcessHeap(), 0, ppd->Module);
405 ppd->Description = ppd->Module = NULL;
406 return E_OUTOFMEMORY;
409 MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->Module, modlen );
410 MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->Description, desclen );
413 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
415 if (pcbReturned) {
416 *pcbReturned = sizeof(*ppd);
417 TRACE("*pcbReturned=%u\n", *pcbReturned);
420 return S_OK;
423 static HRESULT DSPROPERTY_EnumerateW(
424 LPVOID pPropData,
425 ULONG cbPropData,
426 PULONG pcbReturned )
428 PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
429 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
430 BOOL ret;
431 int widn, wodn, i;
432 TRACE("(pPropData=%p,cbPropData=%u,pcbReturned=%p)\n",
433 pPropData,cbPropData,pcbReturned);
435 if (pcbReturned)
436 *pcbReturned = 0;
438 if (!ppd || !ppd->Callback)
440 WARN("Invalid ppd %p\n", ppd);
441 return E_PROP_ID_UNSUPPORTED;
444 wodn = waveOutGetNumDevs();
445 widn = waveInGetNumDevs();
447 data.DeviceId = DSOUND_renderer_guid;
448 for (i = 0; i < wodn; ++i)
450 HRESULT hr;
451 data.DeviceId.Data4[7] = i;
452 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
453 if (FAILED(hr))
455 ERR("DescriptionW failed!\n");
456 return S_OK;
458 ret = ppd->Callback(&data, ppd->Context);
459 HeapFree(GetProcessHeap(), 0, data.Module);
460 HeapFree(GetProcessHeap(), 0, data.Description);
461 if (!ret)
462 return S_OK;
465 data.DeviceId = DSOUND_capture_guid;
466 for (i = 0; i < widn; ++i)
468 HRESULT hr;
469 data.DeviceId.Data4[7] = i;
470 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
471 if (FAILED(hr))
473 ERR("DescriptionW failed!\n");
474 return S_OK;
476 ret = ppd->Callback(&data, ppd->Context);
477 HeapFree(GetProcessHeap(), 0, data.Module);
478 HeapFree(GetProcessHeap(), 0, data.Description);
479 if (!ret)
480 return S_OK;
482 return S_OK;
485 static void DSPROPERTY_descWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
486 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *dataA)
488 DWORD modlen, desclen;
489 static char Interface[] = "Interface";
491 modlen = lstrlenW(dataW->Module)+1;
492 desclen = lstrlenW(dataW->Description)+1;
493 dataA->Type = dataW->Type;
494 dataA->DataFlow = dataW->DataFlow;
495 dataA->DeviceId = dataW->DeviceId;
496 dataA->WaveDeviceId = dataW->WaveDeviceId;
497 dataA->Interface = Interface;
498 dataA->Module = HeapAlloc(GetProcessHeap(), 0, modlen);
499 dataA->Description = HeapAlloc(GetProcessHeap(), 0, desclen);
500 if (dataA->Module)
501 WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, dataA->Module, modlen, NULL, NULL);
502 if (dataA->Description)
503 WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, dataA->Description, desclen, NULL, NULL);
506 static void DSPROPERTY_descWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
507 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *data1)
509 data1->DeviceId = dataW->DeviceId;
510 lstrcpynW(data1->ModuleW, dataW->Module, sizeof(data1->ModuleW)/sizeof(*data1->ModuleW));
511 lstrcpynW(data1->DescriptionW, dataW->Description, sizeof(data1->DescriptionW)/sizeof(*data1->DescriptionW));
512 WideCharToMultiByte(CP_ACP, 0, data1->DescriptionW, -1, data1->DescriptionA, sizeof(data1->DescriptionA), NULL, NULL);
513 WideCharToMultiByte(CP_ACP, 0, data1->ModuleW, -1, data1->ModuleA, sizeof(data1->ModuleA), NULL, NULL);
514 data1->Type = dataW->Type;
515 data1->DataFlow = dataW->DataFlow;
516 data1->WaveDeviceId = data1->Devnode = dataW->WaveDeviceId;
519 static BOOL CALLBACK DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
521 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA;
522 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = data;
523 BOOL ret;
525 DSPROPERTY_descWtoA(descW, &descA);
526 ret = ppd->Callback(&descA, ppd->Context);
527 HeapFree(GetProcessHeap(), 0, descA.Module);
528 HeapFree(GetProcessHeap(), 0, descA.Description);
529 return ret;
532 static HRESULT DSPROPERTY_EnumerateA(
533 LPVOID pPropData,
534 ULONG cbPropData,
535 PULONG pcbReturned)
537 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
538 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData;
540 if(cbPropData < sizeof(*ppd))
541 return DSERR_INVALIDPARAM;
543 if (!ppd || !ppd->Callback)
545 WARN("Invalid ppd %p\n", ppd);
546 return E_PROP_ID_UNSUPPORTED;
549 data.Callback = DSPROPERTY_enumWtoA;
550 data.Context = ppd;
552 return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
555 static BOOL CALLBACK DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
557 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1;
558 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = data;
559 BOOL ret;
561 DSPROPERTY_descWto1(descW, &desc1);
562 ret = ppd->Callback(&desc1, ppd->Context);
563 return ret;
566 static HRESULT DSPROPERTY_Enumerate1(
567 LPVOID pPropData,
568 ULONG cbPropData,
569 PULONG pcbReturned)
571 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
572 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData;
574 if(cbPropData < sizeof(*ppd))
575 return DSERR_INVALIDPARAM;
577 if (!ppd || !ppd->Callback)
579 WARN("Invalid ppd %p\n", ppd);
580 return E_PROP_ID_UNSUPPORTED;
583 data.Callback = DSPROPERTY_enumWto1;
584 data.Context = ppd;
586 return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
589 static HRESULT DSPROPERTY_DescriptionA(
590 LPVOID pPropData,
591 ULONG cbPropData,
592 PULONG pcbReturned)
594 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
595 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *ppd = pPropData;
596 HRESULT hr;
598 if(cbPropData < sizeof(*ppd))
599 return DSERR_INVALIDPARAM;
601 if (pcbReturned)
602 *pcbReturned = sizeof(*ppd);
603 if (!pPropData)
604 return S_OK;
606 data.DeviceId = ppd->DeviceId;
607 data.DataFlow = ppd->DataFlow;
608 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
609 if (FAILED(hr))
610 return hr;
611 DSPROPERTY_descWtoA(&data, ppd);
612 HeapFree(GetProcessHeap(), 0, data.Module);
613 HeapFree(GetProcessHeap(), 0, data.Interface);
614 return hr;
617 static HRESULT DSPROPERTY_Description1(
618 LPVOID pPropData,
619 ULONG cbPropData,
620 PULONG pcbReturned)
622 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
623 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *ppd = pPropData;
624 HRESULT hr;
626 if(cbPropData < sizeof(*ppd))
627 return DSERR_INVALIDPARAM;
629 if (pcbReturned)
630 *pcbReturned = sizeof(*ppd);
631 if (!pPropData)
632 return S_OK;
634 data.DeviceId = ppd->DeviceId;
635 data.DataFlow = ppd->DataFlow;
636 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
637 if (FAILED(hr))
638 return hr;
639 DSPROPERTY_descWto1(&data, ppd);
640 HeapFree(GetProcessHeap(), 0, data.Module);
641 HeapFree(GetProcessHeap(), 0, data.Interface);
642 return hr;
645 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
646 IKsPropertySet *iface,
647 REFGUID guidPropSet,
648 ULONG dwPropID,
649 LPVOID pInstanceData,
650 ULONG cbInstanceData,
651 LPVOID pPropData,
652 ULONG cbPropData,
653 PULONG pcbReturned )
655 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
656 TRACE("(iface=%p,guidPropSet=%s,dwPropID=%u,pInstanceData=%p,cbInstanceData=%u,pPropData=%p,cbPropData=%u,pcbReturned=%p)\n",
657 This,debugstr_guid(guidPropSet),dwPropID,
658 pInstanceData,cbInstanceData,
659 pPropData,cbPropData,pcbReturned);
661 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
662 switch (dwPropID) {
663 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
664 return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned);
665 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
666 return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned);
667 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
668 return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned);
669 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
670 return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned);
671 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
672 return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned);
673 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
674 return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned);
675 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
676 return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned);
677 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
678 return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned);
679 default:
680 FIXME("unsupported ID: %u\n",dwPropID);
681 break;
683 } else {
684 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
687 if (pcbReturned) {
688 *pcbReturned = 0;
689 FIXME("*pcbReturned=%u\n", *pcbReturned);
692 return E_PROP_ID_UNSUPPORTED;
695 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
696 IKsPropertySet *iface,
697 REFGUID guidPropSet,
698 ULONG dwPropID,
699 LPVOID pInstanceData,
700 ULONG cbInstanceData,
701 LPVOID pPropData,
702 ULONG cbPropData )
704 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
706 FIXME("(%p)->(%s,%u,%p,%u,%p,%u), stub!\n",This,
707 debugstr_guid(guidPropSet),dwPropID,
708 pInstanceData,cbInstanceData,pPropData,cbPropData);
709 return E_PROP_ID_UNSUPPORTED;
712 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
713 IKsPropertySet *iface,
714 REFGUID guidPropSet,
715 ULONG dwPropID,
716 PULONG pTypeSupport )
718 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
719 TRACE("(%p,%s,%u,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
721 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
722 switch (dwPropID) {
723 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
724 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
725 return S_OK;
726 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
727 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
728 return S_OK;
729 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
730 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
731 return S_OK;
732 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
733 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
734 return S_OK;
735 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
736 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
737 return S_OK;
738 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
739 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
740 return S_OK;
741 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
742 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
743 return S_OK;
744 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
745 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
746 return S_OK;
747 default:
748 FIXME("unsupported ID: %u\n",dwPropID);
749 break;
751 } else {
752 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
755 return E_PROP_ID_UNSUPPORTED;
758 static const IKsPropertySetVtbl ikspvt = {
759 IKsPrivatePropertySetImpl_QueryInterface,
760 IKsPrivatePropertySetImpl_AddRef,
761 IKsPrivatePropertySetImpl_Release,
762 IKsPrivatePropertySetImpl_Get,
763 IKsPrivatePropertySetImpl_Set,
764 IKsPrivatePropertySetImpl_QuerySupport
767 HRESULT IKsPrivatePropertySetImpl_Create(
768 REFIID riid,
769 void **piks)
771 IKsPrivatePropertySetImpl *iks;
772 TRACE("(%s, %p)\n", debugstr_guid(riid), piks);
774 if (!IsEqualIID(riid, &IID_IUnknown) &&
775 !IsEqualIID(riid, &IID_IKsPropertySet)) {
776 *piks = 0;
777 return E_NOINTERFACE;
780 iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
781 iks->ref = 1;
782 iks->IKsPropertySet_iface.lpVtbl = (IKsPropertySetVtbl*)&ikspvt;
784 *piks = iks;
785 return S_OK;