Use a queue timer for capturing
[dsound-openal.git] / propset.c
bloba59b33b7a83225b2c1b813f0a64a4eb02927b387
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 #define CONST_VTABLE
23 #include <stdarg.h>
24 #include <string.h>
26 #include <windows.h>
27 #include <dsound.h>
28 #include <mmsystem.h>
30 #include "dsound_private.h"
32 typedef enum {
33 DIRECTSOUNDDEVICE_DATAFLOW_RENDER,
34 DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE
35 } DIRECTSOUNDDEVICE_DATAFLOW;
37 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA {
38 LPSTR DeviceName;
39 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
40 GUID DeviceId;
41 } DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA;
43 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA {
44 LPWSTR DeviceName;
45 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
46 GUID DeviceId;
47 } DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA;
49 typedef enum {
50 DIRECTSOUNDDEVICE_TYPE_EMULATED,
51 DIRECTSOUNDDEVICE_TYPE_VXD,
52 DIRECTSOUNDDEVICE_TYPE_WDM
53 } DIRECTSOUNDDEVICE_TYPE;
55 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA {
56 GUID DeviceId;
57 CHAR DescriptionA[0x100];
58 WCHAR DescriptionW[0x100];
59 CHAR ModuleA[MAX_PATH];
60 WCHAR ModuleW[MAX_PATH];
61 DIRECTSOUNDDEVICE_TYPE Type;
62 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
63 ULONG WaveDeviceId;
64 ULONG Devnode;
65 } DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA;
67 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA {
68 DIRECTSOUNDDEVICE_TYPE Type;
69 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
70 GUID DeviceId;
71 LPSTR Description;
72 LPSTR Module;
73 LPSTR Interface;
74 ULONG WaveDeviceId;
75 } DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA;
77 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA {
78 DIRECTSOUNDDEVICE_TYPE Type;
79 DIRECTSOUNDDEVICE_DATAFLOW DataFlow;
80 GUID DeviceId;
81 LPWSTR Description;
82 LPWSTR Module;
83 LPWSTR Interface;
84 ULONG WaveDeviceId;
85 } DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA;
87 typedef struct _DSDRIVERDESC {
88 DWORD dwFlags;
89 CHAR szDesc[256];
90 CHAR szDrvname[256];
91 DWORD dnDevNode;
92 WORD wVxdId;
93 WORD wReserved;
94 ULONG ulDeviceNum;
95 DWORD dwHeapType;
96 LPVOID pvDirectDrawHeap;
97 DWORD dwMemStartAddress;
98 DWORD dwMemEndAddress;
99 DWORD dwMemAllocExtra;
100 LPVOID pvReserved1;
101 LPVOID pvReserved2;
102 } DSDRIVERDESC,*PDSDRIVERDESC;
104 #ifndef E_PROP_ID_UNSUPPORTED
105 #define E_PROP_ID_UNSUPPORTED ((HRESULT)0x80070490)
106 #endif
108 #ifndef DRV_QUERYDSOUNDDESC
109 #define DRV_QUERYDSOUNDDESC (DRV_RESERVED + 21)
110 #endif
112 typedef BOOL (CALLBACK *LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK1)(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA, LPVOID);
113 typedef BOOL (CALLBACK *LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKA)(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA, LPVOID);
114 typedef BOOL (CALLBACK *LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKW)(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA, LPVOID);
116 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA {
117 LPFNDIRECTSOUNDDEVICEENUMERATECALLBACK1 Callback;
118 LPVOID Context;
119 } DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA;
121 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA {
122 LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKA Callback;
123 LPVOID Context;
124 } DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA;
126 typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA {
127 LPFNDIRECTSOUNDDEVICEENUMERATECALLBACKW Callback;
128 LPVOID Context;
129 } DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA;
131 DEFINE_GUID(DSPROPSETID_DirectSoundDevice,0x84624f82,0x25ec,0x11d1,0xa4,0xd8,0x00,0xc0,0x4f,0xc2,0x8a,0xca);
133 typedef enum {
134 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A = 1,
135 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1 = 2,
136 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1 = 3,
137 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W = 4,
138 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A = 5,
139 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W = 6,
140 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A = 7,
141 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W = 8,
142 } DSPROPERTY_DIRECTSOUNDDEVICE;
144 #ifndef ULongToHandle
145 #define ULongToHandle(ul) ((HANDLE)(ULONG_PTR)(ul))
146 #endif
147 #ifndef UlongToHandle
148 #define UlongToHandle(ul) ULongToHandle(ul)
149 #endif
152 typedef struct IKsPrivatePropertySetImpl {
153 IKsPropertySet IKsPropertySet_iface;
154 LONG ref;
155 } IKsPrivatePropertySetImpl;
157 /*******************************************************************************
158 * IKsPrivatePropertySet
161 static inline IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *iface)
163 return CONTAINING_RECORD(iface, IKsPrivatePropertySetImpl, IKsPropertySet_iface);
166 /* IUnknown methods */
167 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
168 IKsPropertySet *iface,
169 REFIID riid,
170 LPVOID *ppobj )
172 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
173 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
175 if (IsEqualIID(riid, &IID_IUnknown) ||
176 IsEqualIID(riid, &IID_IKsPropertySet)) {
177 *ppobj = iface;
178 IUnknown_AddRef(iface);
179 return S_OK;
181 *ppobj = NULL;
182 return E_NOINTERFACE;
185 static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(IKsPropertySet *iface)
187 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
188 ULONG ref = InterlockedIncrement(&(This->ref));
189 TRACE("(%p) ref was %lu\n", This, ref - 1);
190 return ref;
193 static ULONG WINAPI IKsPrivatePropertySetImpl_Release(IKsPropertySet *iface)
195 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
196 ULONG ref = InterlockedDecrement(&(This->ref));
197 TRACE("(%p) ref was %lu\n", This, ref + 1);
199 if (!ref) {
200 HeapFree(GetProcessHeap(), 0, This);
201 TRACE("(%p) released\n", This);
203 return ref;
206 static HRESULT DSPROPERTY_WaveDeviceMappingW(
207 LPVOID pPropData,
208 ULONG cbPropData,
209 PULONG pcbReturned )
211 HRESULT hr = DSERR_INVALIDPARAM;
212 PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
213 TRACE("(pPropData=%p,cbPropData=%lu,pcbReturned=%p)\n",
214 pPropData,cbPropData,pcbReturned);
216 ppd = pPropData;
217 if (!ppd) {
218 WARN("invalid parameter: pPropData\n");
219 return DSERR_INVALIDPARAM;
222 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
223 ULONG wod;
224 unsigned int wodn;
225 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
226 wodn = waveOutGetNumDevs();
227 for (wod = 0; wod < wodn; wod++) {
228 WAVEOUTCAPSW capsW;
229 MMRESULT res;
230 res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
231 if (res == MMSYSERR_NOERROR) {
232 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
233 ppd->DeviceId = DSOUND_renderer_guid;
234 ppd->DeviceId.Data4[7] = (unsigned char)wod;
235 hr = DS_OK;
236 TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
237 debugstr_w(ppd->DeviceName));
238 break;
242 } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
243 ULONG wid;
244 unsigned int widn;
245 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
246 widn = waveInGetNumDevs();
247 for (wid = 0; wid < widn; wid++) {
248 WAVEINCAPSW capsW;
249 MMRESULT res;
250 res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
251 if (res == MMSYSERR_NOERROR) {
252 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
253 ppd->DeviceId = DSOUND_capture_guid;
254 ppd->DeviceId.Data4[7] = (unsigned char)wid;
255 hr = DS_OK;
256 TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
257 debugstr_w(ppd->DeviceName));
258 break;
264 if (pcbReturned)
265 *pcbReturned = cbPropData;
267 return hr;
270 static HRESULT DSPROPERTY_WaveDeviceMappingA(
271 LPVOID pPropData,
272 ULONG cbPropData,
273 PULONG pcbReturned )
275 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data;
276 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData;
277 DWORD len;
278 HRESULT hr;
280 TRACE("(pPropData=%p,cbPropData=%lu,pcbReturned=%p)\n",
281 pPropData,cbPropData,pcbReturned);
283 if (!ppd || !ppd->DeviceName) {
284 WARN("invalid parameter: ppd=%p\n", ppd);
285 return DSERR_INVALIDPARAM;
288 data.DataFlow = ppd->DataFlow;
289 len = strlen(ppd->DeviceName)+1;
290 data.DeviceName = HeapAlloc(GetProcessHeap(), 0, len);
291 if (!data.DeviceName)
292 return E_OUTOFMEMORY;
293 MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, data.DeviceName, len );
295 hr = DSPROPERTY_WaveDeviceMappingW(&data, cbPropData, pcbReturned);
296 HeapFree(GetProcessHeap(), 0, data.DeviceName);
297 ppd->DeviceId = data.DeviceId;
299 if (pcbReturned)
300 *pcbReturned = cbPropData;
302 return hr;
305 static HRESULT DSPROPERTY_DescriptionW(
306 LPVOID pPropData,
307 ULONG cbPropData,
308 PULONG pcbReturned )
310 PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
311 HRESULT err;
312 GUID dev_guid;
313 ULONG wod, wid, wodn, widn;
314 DSDRIVERDESC desc;
316 TRACE("pPropData=%p,cbPropData=%lu,pcbReturned=%p)\n",
317 pPropData,cbPropData,pcbReturned);
319 TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
320 if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
321 /* default device of type specified by ppd->DataFlow */
322 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
323 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
324 ppd->DeviceId = DSDEVID_DefaultCapture;
325 } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
326 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
327 ppd->DeviceId = DSDEVID_DefaultPlayback;
328 } else {
329 WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow);
330 return E_PROP_ID_UNSUPPORTED;
334 GetDeviceID(&ppd->DeviceId, &dev_guid);
336 wodn = waveOutGetNumDevs();
337 widn = waveInGetNumDevs();
338 wid = wod = dev_guid.Data4[7];
339 if (!memcmp(&dev_guid, &DSOUND_renderer_guid, sizeof(GUID)-1)
340 && wod < wodn)
342 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
343 ppd->WaveDeviceId = wod;
345 else if (!memcmp(&dev_guid, &DSOUND_capture_guid, sizeof(GUID)-1)
346 && wid < widn)
348 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
349 ppd->WaveDeviceId = wid;
351 else
353 WARN("Device not found\n");
354 return E_PROP_ID_UNSUPPORTED;
357 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
358 err = waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0);
359 else
360 err = waveInMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0);
362 if (err != MMSYSERR_NOERROR)
364 WARN("waveMessage(DRV_QUERYDSOUNDDESC) failed!\n");
365 return E_PROP_ID_UNSUPPORTED;
367 else
369 /* FIXME: Still a memory leak.. */
370 int desclen, modlen;
371 static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
373 modlen = strlen(desc.szDrvname)+1;
374 desclen = strlen(desc.szDesc)+1;
375 ppd->Module = HeapAlloc(GetProcessHeap(),0,modlen*sizeof(WCHAR));
376 ppd->Description = HeapAlloc(GetProcessHeap(),0,desclen*sizeof(WCHAR));
377 ppd->Interface = wInterface;
378 if (!ppd->Description || !ppd->Module)
380 WARN("Out of memory\n");
381 HeapFree(GetProcessHeap(), 0, ppd->Description);
382 HeapFree(GetProcessHeap(), 0, ppd->Module);
383 ppd->Description = ppd->Module = NULL;
384 return E_OUTOFMEMORY;
387 MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->Module, modlen );
388 MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->Description, desclen );
391 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
393 if (pcbReturned) {
394 *pcbReturned = sizeof(*ppd);
395 TRACE("*pcbReturned=%lu\n", *pcbReturned);
398 return S_OK;
401 static HRESULT DSPROPERTY_EnumerateW(
402 LPVOID pPropData,
403 ULONG cbPropData,
404 PULONG pcbReturned )
406 PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
407 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
408 BOOL ret;
409 int widn, wodn, i;
410 TRACE("(pPropData=%p,cbPropData=%lu,pcbReturned=%p)\n",
411 pPropData,cbPropData,pcbReturned);
413 if (pcbReturned)
414 *pcbReturned = 0;
416 if (!ppd || !ppd->Callback)
418 WARN("Invalid ppd %p\n", ppd);
419 return E_PROP_ID_UNSUPPORTED;
422 wodn = waveOutGetNumDevs();
423 widn = waveInGetNumDevs();
425 data.DeviceId = DSOUND_renderer_guid;
426 for (i = 0; i < wodn; ++i)
428 HRESULT hr;
429 data.DeviceId.Data4[7] = i;
430 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
431 if (FAILED(hr))
433 ERR("DescriptionW failed!\n");
434 return S_OK;
436 ret = ppd->Callback(&data, ppd->Context);
437 HeapFree(GetProcessHeap(), 0, data.Module);
438 HeapFree(GetProcessHeap(), 0, data.Description);
439 if (!ret)
440 return S_OK;
443 data.DeviceId = DSOUND_capture_guid;
444 for (i = 0; i < widn; ++i)
446 HRESULT hr;
447 data.DeviceId.Data4[7] = i;
448 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
449 if (FAILED(hr))
451 ERR("DescriptionW failed!\n");
452 return S_OK;
454 ret = ppd->Callback(&data, ppd->Context);
455 HeapFree(GetProcessHeap(), 0, data.Module);
456 HeapFree(GetProcessHeap(), 0, data.Description);
457 if (!ret)
458 return S_OK;
460 return S_OK;
463 static void DSPROPERTY_descWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
464 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *dataA)
466 DWORD modlen, desclen;
467 static char Interface[] = "Interface";
469 modlen = lstrlenW(dataW->Module)+1;
470 desclen = lstrlenW(dataW->Description)+1;
471 dataA->Type = dataW->Type;
472 dataA->DataFlow = dataW->DataFlow;
473 dataA->DeviceId = dataW->DeviceId;
474 dataA->WaveDeviceId = dataW->WaveDeviceId;
475 dataA->Interface = Interface;
476 dataA->Module = HeapAlloc(GetProcessHeap(), 0, modlen);
477 dataA->Description = HeapAlloc(GetProcessHeap(), 0, desclen);
478 if (dataA->Module)
479 WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, dataA->Module, modlen, NULL, NULL);
480 if (dataA->Description)
481 WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, dataA->Description, desclen, NULL, NULL);
484 static void DSPROPERTY_descWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
485 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *data1)
487 data1->DeviceId = dataW->DeviceId;
488 lstrcpynW(data1->ModuleW, dataW->Module, sizeof(data1->ModuleW)/sizeof(*data1->ModuleW));
489 lstrcpynW(data1->DescriptionW, dataW->Description, sizeof(data1->DescriptionW)/sizeof(*data1->DescriptionW));
490 WideCharToMultiByte(CP_ACP, 0, data1->DescriptionW, -1, data1->DescriptionA, sizeof(data1->DescriptionA), NULL, NULL);
491 WideCharToMultiByte(CP_ACP, 0, data1->ModuleW, -1, data1->ModuleA, sizeof(data1->ModuleA), NULL, NULL);
492 data1->Type = dataW->Type;
493 data1->DataFlow = dataW->DataFlow;
494 data1->WaveDeviceId = data1->Devnode = dataW->WaveDeviceId;
497 static BOOL CALLBACK DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
499 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA;
500 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = data;
501 BOOL ret;
503 DSPROPERTY_descWtoA(descW, &descA);
504 ret = ppd->Callback(&descA, ppd->Context);
505 HeapFree(GetProcessHeap(), 0, descA.Module);
506 HeapFree(GetProcessHeap(), 0, descA.Description);
507 return ret;
510 static HRESULT DSPROPERTY_EnumerateA(
511 LPVOID pPropData,
512 ULONG cbPropData,
513 PULONG pcbReturned)
515 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
516 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData;
518 if(cbPropData < sizeof(*ppd))
519 return DSERR_INVALIDPARAM;
521 if (!ppd || !ppd->Callback)
523 WARN("Invalid ppd %p\n", ppd);
524 return E_PROP_ID_UNSUPPORTED;
527 data.Callback = DSPROPERTY_enumWtoA;
528 data.Context = ppd;
530 return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
533 static BOOL CALLBACK DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
535 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1;
536 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = data;
537 BOOL ret;
539 DSPROPERTY_descWto1(descW, &desc1);
540 ret = ppd->Callback(&desc1, ppd->Context);
541 return ret;
544 static HRESULT DSPROPERTY_Enumerate1(
545 LPVOID pPropData,
546 ULONG cbPropData,
547 PULONG pcbReturned)
549 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
550 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData;
552 if(cbPropData < sizeof(*ppd))
553 return DSERR_INVALIDPARAM;
555 if (!ppd || !ppd->Callback)
557 WARN("Invalid ppd %p\n", ppd);
558 return E_PROP_ID_UNSUPPORTED;
561 data.Callback = DSPROPERTY_enumWto1;
562 data.Context = ppd;
564 return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
567 static HRESULT DSPROPERTY_DescriptionA(
568 LPVOID pPropData,
569 ULONG cbPropData,
570 PULONG pcbReturned)
572 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
573 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *ppd = pPropData;
574 HRESULT hr;
576 if(cbPropData < sizeof(*ppd))
577 return DSERR_INVALIDPARAM;
579 if (pcbReturned)
580 *pcbReturned = sizeof(*ppd);
581 if (!pPropData)
582 return S_OK;
584 data.DeviceId = ppd->DeviceId;
585 data.DataFlow = ppd->DataFlow;
586 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
587 if (FAILED(hr))
588 return hr;
589 DSPROPERTY_descWtoA(&data, ppd);
590 HeapFree(GetProcessHeap(), 0, data.Module);
591 HeapFree(GetProcessHeap(), 0, data.Interface);
592 return hr;
595 static HRESULT DSPROPERTY_Description1(
596 LPVOID pPropData,
597 ULONG cbPropData,
598 PULONG pcbReturned)
600 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
601 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *ppd = pPropData;
602 HRESULT hr;
604 if(cbPropData < sizeof(*ppd))
605 return DSERR_INVALIDPARAM;
607 if (pcbReturned)
608 *pcbReturned = sizeof(*ppd);
609 if (!pPropData)
610 return S_OK;
612 data.DeviceId = ppd->DeviceId;
613 data.DataFlow = ppd->DataFlow;
614 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
615 if (FAILED(hr))
616 return hr;
617 DSPROPERTY_descWto1(&data, ppd);
618 HeapFree(GetProcessHeap(), 0, data.Module);
619 HeapFree(GetProcessHeap(), 0, data.Interface);
620 return hr;
623 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
624 IKsPropertySet *iface,
625 REFGUID guidPropSet,
626 ULONG dwPropID,
627 LPVOID pInstanceData,
628 ULONG cbInstanceData,
629 LPVOID pPropData,
630 ULONG cbPropData,
631 PULONG pcbReturned )
633 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
634 TRACE("(iface=%p,guidPropSet=%s,dwPropID=%lu,pInstanceData=%p,cbInstanceData=%lu,pPropData=%p,cbPropData=%lu,pcbReturned=%p)\n",
635 This,debugstr_guid(guidPropSet),dwPropID,
636 pInstanceData,cbInstanceData,
637 pPropData,cbPropData,pcbReturned);
639 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
640 switch (dwPropID) {
641 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
642 return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned);
643 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
644 return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned);
645 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
646 return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned);
647 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
648 return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned);
649 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
650 return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned);
651 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
652 return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned);
653 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
654 return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned);
655 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
656 return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned);
657 default:
658 FIXME("unsupported ID: %lu\n",dwPropID);
659 break;
661 } else {
662 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
665 if (pcbReturned) {
666 *pcbReturned = 0;
667 FIXME("*pcbReturned=%lu\n", *pcbReturned);
670 return E_PROP_ID_UNSUPPORTED;
673 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
674 IKsPropertySet *iface,
675 REFGUID guidPropSet,
676 ULONG dwPropID,
677 LPVOID pInstanceData,
678 ULONG cbInstanceData,
679 LPVOID pPropData,
680 ULONG cbPropData )
682 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
684 FIXME("(%p)->(%s,%lu,%p,%lu,%p,%lu), stub!\n",This,
685 debugstr_guid(guidPropSet),dwPropID,
686 pInstanceData,cbInstanceData,pPropData,cbPropData);
687 return E_PROP_ID_UNSUPPORTED;
690 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
691 IKsPropertySet *iface,
692 REFGUID guidPropSet,
693 ULONG dwPropID,
694 PULONG pTypeSupport )
696 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
697 TRACE("(%p,%s,%lu,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
699 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
700 switch (dwPropID) {
701 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
702 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
703 return S_OK;
704 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
705 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
706 return S_OK;
707 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
708 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
709 return S_OK;
710 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
711 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
712 return S_OK;
713 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
714 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
715 return S_OK;
716 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
717 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
718 return S_OK;
719 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
720 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
721 return S_OK;
722 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
723 *pTypeSupport = KSPROPERTY_SUPPORT_GET;
724 return S_OK;
725 default:
726 FIXME("unsupported ID: %lu\n",dwPropID);
727 break;
729 } else {
730 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
733 return E_PROP_ID_UNSUPPORTED;
736 static const IKsPropertySetVtbl ikspvt = {
737 IKsPrivatePropertySetImpl_QueryInterface,
738 IKsPrivatePropertySetImpl_AddRef,
739 IKsPrivatePropertySetImpl_Release,
740 IKsPrivatePropertySetImpl_Get,
741 IKsPrivatePropertySetImpl_Set,
742 IKsPrivatePropertySetImpl_QuerySupport
745 HRESULT IKsPrivatePropertySetImpl_Create(
746 REFIID riid,
747 void **piks)
749 IKsPrivatePropertySetImpl *iks;
750 TRACE("(%s, %p)\n", debugstr_guid(riid), piks);
752 if (!IsEqualIID(riid, &IID_IUnknown) &&
753 !IsEqualIID(riid, &IID_IKsPropertySet)) {
754 *piks = 0;
755 return E_NOINTERFACE;
758 iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
759 iks->ref = 1;
760 iks->IKsPropertySet_iface.lpVtbl = &ikspvt;
762 *piks = iks;
763 return S_OK;