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
25 #define NONAMELESSUNION
34 #include "wine/debug.h"
36 #include "dsound_private.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(dsound
);
45 static WCHAR wInterface
[] = L
"Interface";
47 typedef struct IKsPrivatePropertySetImpl
49 IKsPropertySet IKsPropertySet_iface
;
51 } IKsPrivatePropertySetImpl
;
53 static IKsPrivatePropertySetImpl
*impl_from_IKsPropertySet(IKsPropertySet
*iface
)
55 return CONTAINING_RECORD(iface
, IKsPrivatePropertySetImpl
, IKsPropertySet_iface
);
58 /*******************************************************************************
59 * IKsPrivatePropertySet
62 /* IUnknown methods */
63 static HRESULT WINAPI
IKsPrivatePropertySetImpl_QueryInterface(
64 IKsPropertySet
*iface
, REFIID riid
, void **ppobj
)
66 IKsPrivatePropertySetImpl
*This
= impl_from_IKsPropertySet(iface
);
67 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
69 if (IsEqualIID(riid
, &IID_IUnknown
) ||
70 IsEqualIID(riid
, &IID_IKsPropertySet
)) {
72 IKsPropertySet_AddRef(iface
);
79 static ULONG WINAPI
IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface
)
81 IKsPrivatePropertySetImpl
*This
= impl_from_IKsPropertySet(iface
);
82 ULONG ref
= InterlockedIncrement(&(This
->ref
));
83 TRACE("(%p) ref %d\n", This
, ref
);
87 static ULONG WINAPI
IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface
)
89 IKsPrivatePropertySetImpl
*This
= impl_from_IKsPropertySet(iface
);
90 ULONG ref
= InterlockedDecrement(&(This
->ref
));
91 TRACE("(%p) ref %d\n", This
, ref
);
94 HeapFree(GetProcessHeap(), 0, This
);
95 TRACE("(%p) released\n", This
);
101 const WCHAR
*tgt_name
;
105 static BOOL CALLBACK
search_callback(GUID
*guid
, const WCHAR
*desc
,
106 const WCHAR
*module
, void *user
)
108 struct search_data
*search
= user
;
110 if(!lstrcmpW(desc
, search
->tgt_name
)){
111 *search
->found_guid
= *guid
;
118 static HRESULT
DSPROPERTY_WaveDeviceMappingW(
124 PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd
= pPropData
;
125 struct search_data search
;
127 TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
128 pPropData
,cbPropData
,pcbReturned
);
131 WARN("invalid parameter: pPropData\n");
132 return DSERR_INVALIDPARAM
;
135 search
.tgt_name
= ppd
->DeviceName
;
136 search
.found_guid
= &ppd
->DeviceId
;
138 if (ppd
->DataFlow
== DIRECTSOUNDDEVICE_DATAFLOW_RENDER
)
139 hr
= enumerate_mmdevices(eRender
, DSOUND_renderer_guids
,
140 search_callback
, &search
);
141 else if (ppd
->DataFlow
== DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE
)
142 hr
= enumerate_mmdevices(eCapture
, DSOUND_capture_guids
,
143 search_callback
, &search
);
145 return DSERR_INVALIDPARAM
;
148 /* device was not found */
149 return DSERR_INVALIDPARAM
;
152 *pcbReturned
= cbPropData
;
157 static HRESULT
DSPROPERTY_WaveDeviceMappingA(
162 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA
*ppd
= pPropData
;
163 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data
;
167 TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
168 pPropData
,cbPropData
,pcbReturned
);
170 if (!ppd
|| !ppd
->DeviceName
) {
171 WARN("invalid parameter: ppd=%p\n", ppd
);
172 return DSERR_INVALIDPARAM
;
175 data
.DataFlow
= ppd
->DataFlow
;
176 len
= MultiByteToWideChar(CP_ACP
, 0, ppd
->DeviceName
, -1, NULL
, 0);
177 data
.DeviceName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
178 if (!data
.DeviceName
)
179 return E_OUTOFMEMORY
;
180 MultiByteToWideChar(CP_ACP
, 0, ppd
->DeviceName
, -1, data
.DeviceName
, len
);
182 hr
= DSPROPERTY_WaveDeviceMappingW(&data
, cbPropData
, pcbReturned
);
183 HeapFree(GetProcessHeap(), 0, data
.DeviceName
);
184 ppd
->DeviceId
= data
.DeviceId
;
187 *pcbReturned
= cbPropData
;
192 static HRESULT
DSPROPERTY_DescriptionW(
197 PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd
= pPropData
;
204 TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
205 pPropData
,cbPropData
,pcbReturned
);
207 TRACE("DeviceId=%s\n",debugstr_guid(&ppd
->DeviceId
));
208 if ( IsEqualGUID( &ppd
->DeviceId
, &GUID_NULL
) ) {
209 /* default device of type specified by ppd->DataFlow */
210 if (ppd
->DataFlow
== DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE
) {
211 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
212 ppd
->DeviceId
= DSDEVID_DefaultCapture
;
213 } else if (ppd
->DataFlow
== DIRECTSOUNDDEVICE_DATAFLOW_RENDER
) {
214 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
215 ppd
->DeviceId
= DSDEVID_DefaultPlayback
;
217 WARN("DataFlow=Unknown(%d)\n", ppd
->DataFlow
);
218 return E_PROP_ID_UNSUPPORTED
;
222 setup_dsound_options();
224 GetDeviceID(&ppd
->DeviceId
, &dev_guid
);
226 hr
= get_mmdevice(eRender
, &dev_guid
, &mmdevice
);
228 hr
= get_mmdevice(eCapture
, &dev_guid
, &mmdevice
);
233 hr
= IMMDevice_OpenPropertyStore(mmdevice
, STGM_READ
, &ps
);
235 IMMDevice_Release(mmdevice
);
236 WARN("OpenPropertyStore failed: %08x\n", hr
);
240 hr
= IPropertyStore_GetValue(ps
,
241 (const PROPERTYKEY
*)&DEVPKEY_Device_FriendlyName
, &pv
);
243 IPropertyStore_Release(ps
);
244 IMMDevice_Release(mmdevice
);
245 WARN("GetValue(FriendlyName) failed: %08x\n", hr
);
249 ppd
->Description
= strdupW(pv
.u
.pwszVal
);
250 ppd
->Module
= strdupW(wine_vxd_drv
);
251 ppd
->Interface
= strdupW(wInterface
);
252 ppd
->Type
= DIRECTSOUNDDEVICE_TYPE_VXD
;
254 PropVariantClear(&pv
);
255 IPropertyStore_Release(ps
);
256 IMMDevice_Release(mmdevice
);
259 *pcbReturned
= sizeof(*ppd
);
260 TRACE("*pcbReturned=%d\n", *pcbReturned
);
267 BOOL CALLBACK
enum_callback(GUID
*guid
, const WCHAR
*desc
, const WCHAR
*module
,
270 PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd
= user
;
271 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data
;
275 TRACE("%s %s %s %p\n", wine_dbgstr_guid(guid
), wine_dbgstr_w(desc
),
276 wine_dbgstr_w(module
), user
);
281 data
.DeviceId
= *guid
;
283 len
= lstrlenW(module
) + 1;
284 data
.Module
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
285 memcpy(data
.Module
, module
, len
* sizeof(WCHAR
));
287 len
= lstrlenW(desc
) + 1;
288 data
.Description
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
289 memcpy(data
.Description
, desc
, len
* sizeof(WCHAR
));
291 data
.Interface
= wInterface
;
293 ret
= ppd
->Callback(&data
, ppd
->Context
);
295 HeapFree(GetProcessHeap(), 0, data
.Module
);
296 HeapFree(GetProcessHeap(), 0, data
.Description
);
301 static HRESULT
DSPROPERTY_EnumerateW(
306 PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd
= pPropData
;
309 TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
310 pPropData
,cbPropData
,pcbReturned
);
315 if (!ppd
|| !ppd
->Callback
)
317 WARN("Invalid ppd %p\n", ppd
);
318 return E_PROP_ID_UNSUPPORTED
;
321 hr
= enumerate_mmdevices(eRender
, DSOUND_renderer_guids
,
325 hr
= enumerate_mmdevices(eCapture
, DSOUND_capture_guids
,
328 return SUCCEEDED(hr
) ? DS_OK
: hr
;
331 static BOOL
DSPROPERTY_descWtoA(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA
*dataW
,
332 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA
*dataA
)
334 DWORD modlen
, desclen
;
335 static char Interface
[] = "Interface";
337 modlen
= WideCharToMultiByte(CP_ACP
, 0, dataW
->Module
, -1, NULL
, 0, NULL
, NULL
);
338 desclen
= WideCharToMultiByte(CP_ACP
, 0, dataW
->Description
, -1, NULL
, 0, NULL
, NULL
);
339 dataA
->Type
= dataW
->Type
;
340 dataA
->DataFlow
= dataW
->DataFlow
;
341 dataA
->DeviceId
= dataW
->DeviceId
;
342 dataA
->WaveDeviceId
= dataW
->WaveDeviceId
;
343 dataA
->Interface
= Interface
;
344 dataA
->Module
= HeapAlloc(GetProcessHeap(), 0, modlen
);
345 dataA
->Description
= HeapAlloc(GetProcessHeap(), 0, desclen
);
346 if (!dataA
->Module
|| !dataA
->Description
)
348 HeapFree(GetProcessHeap(), 0, dataA
->Module
);
349 HeapFree(GetProcessHeap(), 0, dataA
->Description
);
350 dataA
->Module
= dataA
->Description
= NULL
;
354 WideCharToMultiByte(CP_ACP
, 0, dataW
->Module
, -1, dataA
->Module
, modlen
, NULL
, NULL
);
355 WideCharToMultiByte(CP_ACP
, 0, dataW
->Description
, -1, dataA
->Description
, desclen
, NULL
, NULL
);
359 static void DSPROPERTY_descWto1(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA
*dataW
,
360 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA
*data1
)
362 data1
->DeviceId
= dataW
->DeviceId
;
363 lstrcpynW(data1
->ModuleW
, dataW
->Module
, ARRAY_SIZE(data1
->ModuleW
));
364 lstrcpynW(data1
->DescriptionW
, dataW
->Description
, ARRAY_SIZE(data1
->DescriptionW
));
365 WideCharToMultiByte(CP_ACP
, 0, data1
->DescriptionW
, -1, data1
->DescriptionA
, sizeof(data1
->DescriptionA
)-1, NULL
, NULL
);
366 WideCharToMultiByte(CP_ACP
, 0, data1
->ModuleW
, -1, data1
->ModuleA
, sizeof(data1
->ModuleA
)-1, NULL
, NULL
);
367 data1
->DescriptionA
[sizeof(data1
->DescriptionA
)-1] = 0;
368 data1
->ModuleA
[sizeof(data1
->ModuleA
)-1] = 0;
369 data1
->Type
= dataW
->Type
;
370 data1
->DataFlow
= dataW
->DataFlow
;
371 data1
->WaveDeviceId
= data1
->Devnode
= dataW
->WaveDeviceId
;
374 static BOOL CALLBACK
DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA
*descW
, void *data
)
376 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA
;
377 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA
*ppd
= data
;
380 ret
= DSPROPERTY_descWtoA(descW
, &descA
);
383 ret
= ppd
->Callback(&descA
, ppd
->Context
);
384 HeapFree(GetProcessHeap(), 0, descA
.Module
);
385 HeapFree(GetProcessHeap(), 0, descA
.Description
);
389 static HRESULT
DSPROPERTY_EnumerateA(
394 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA
*ppd
= pPropData
;
395 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data
;
397 if (!ppd
|| !ppd
->Callback
)
399 WARN("Invalid ppd %p\n", ppd
);
400 return E_PROP_ID_UNSUPPORTED
;
403 data
.Callback
= DSPROPERTY_enumWtoA
;
406 return DSPROPERTY_EnumerateW(&data
, cbPropData
, pcbReturned
);
409 static BOOL CALLBACK
DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA
*descW
, void *data
)
411 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1
;
412 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA
*ppd
= data
;
415 DSPROPERTY_descWto1(descW
, &desc1
);
416 ret
= ppd
->Callback(&desc1
, ppd
->Context
);
420 static HRESULT
DSPROPERTY_Enumerate1(
425 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA
*ppd
= pPropData
;
426 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data
;
428 if (!ppd
|| !ppd
->Callback
)
430 WARN("Invalid ppd %p\n", ppd
);
431 return E_PROP_ID_UNSUPPORTED
;
434 data
.Callback
= DSPROPERTY_enumWto1
;
437 return DSPROPERTY_EnumerateW(&data
, cbPropData
, pcbReturned
);
440 static HRESULT
DSPROPERTY_DescriptionA(
445 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data
;
446 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA
*ppd
= pPropData
;
450 *pcbReturned
= sizeof(*ppd
);
454 data
.DeviceId
= ppd
->DeviceId
;
455 data
.DataFlow
= ppd
->DataFlow
;
456 hr
= DSPROPERTY_DescriptionW(&data
, sizeof(data
), NULL
);
459 if (!DSPROPERTY_descWtoA(&data
, ppd
))
461 HeapFree(GetProcessHeap(), 0, data
.Description
);
462 HeapFree(GetProcessHeap(), 0, data
.Module
);
463 HeapFree(GetProcessHeap(), 0, data
.Interface
);
467 static HRESULT
DSPROPERTY_Description1(
472 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data
;
473 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA
*ppd
= pPropData
;
477 *pcbReturned
= sizeof(*ppd
);
481 data
.DeviceId
= ppd
->DeviceId
;
482 data
.DataFlow
= ppd
->DataFlow
;
483 hr
= DSPROPERTY_DescriptionW(&data
, sizeof(data
), NULL
);
486 DSPROPERTY_descWto1(&data
, ppd
);
487 HeapFree(GetProcessHeap(), 0, data
.Description
);
488 HeapFree(GetProcessHeap(), 0, data
.Module
);
489 HeapFree(GetProcessHeap(), 0, data
.Interface
);
493 static HRESULT WINAPI
IKsPrivatePropertySetImpl_Get(
494 LPKSPROPERTYSET iface
,
497 LPVOID pInstanceData
,
498 ULONG cbInstanceData
,
503 IKsPrivatePropertySetImpl
*This
= impl_from_IKsPropertySet(iface
);
504 TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
505 This
,debugstr_guid(guidPropSet
),dwPropID
,pInstanceData
,cbInstanceData
,pPropData
,cbPropData
,pcbReturned
);
507 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice
, guidPropSet
) ) {
509 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A
:
510 return DSPROPERTY_WaveDeviceMappingA(pPropData
,cbPropData
,pcbReturned
);
511 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1
:
512 return DSPROPERTY_Description1(pPropData
,cbPropData
,pcbReturned
);
513 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1
:
514 return DSPROPERTY_Enumerate1(pPropData
,cbPropData
,pcbReturned
);
515 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W
:
516 return DSPROPERTY_WaveDeviceMappingW(pPropData
,cbPropData
,pcbReturned
);
517 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A
:
518 return DSPROPERTY_DescriptionA(pPropData
,cbPropData
,pcbReturned
);
519 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W
:
520 return DSPROPERTY_DescriptionW(pPropData
,cbPropData
,pcbReturned
);
521 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A
:
522 return DSPROPERTY_EnumerateA(pPropData
,cbPropData
,pcbReturned
);
523 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W
:
524 return DSPROPERTY_EnumerateW(pPropData
,cbPropData
,pcbReturned
);
526 FIXME("unsupported ID: %d\n",dwPropID
);
530 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet
));
535 FIXME("*pcbReturned=%d\n", *pcbReturned
);
538 return E_PROP_ID_UNSUPPORTED
;
541 static HRESULT WINAPI
IKsPrivatePropertySetImpl_Set(
542 LPKSPROPERTYSET iface
,
545 LPVOID pInstanceData
,
546 ULONG cbInstanceData
,
550 IKsPrivatePropertySetImpl
*This
= impl_from_IKsPropertySet(iface
);
552 FIXME("(%p,%s,%d,%p,%d,%p,%d), stub!\n",This
,debugstr_guid(guidPropSet
),dwPropID
,pInstanceData
,cbInstanceData
,pPropData
,cbPropData
);
553 return E_PROP_ID_UNSUPPORTED
;
556 static HRESULT WINAPI
IKsPrivatePropertySetImpl_QuerySupport(
557 LPKSPROPERTYSET iface
,
560 PULONG pTypeSupport
)
562 IKsPrivatePropertySetImpl
*This
= impl_from_IKsPropertySet(iface
);
563 TRACE("(%p,%s,%d,%p)\n",This
,debugstr_guid(guidPropSet
),dwPropID
,pTypeSupport
);
565 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice
, guidPropSet
) ) {
567 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A
:
568 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
;
570 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1
:
571 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
;
573 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1
:
574 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
;
576 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W
:
577 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
;
579 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A
:
580 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
;
582 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W
:
583 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
;
585 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A
:
586 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
;
588 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W
:
589 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
;
592 FIXME("unsupported ID: %d\n",dwPropID
);
596 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet
));
599 return E_PROP_ID_UNSUPPORTED
;
602 static const IKsPropertySetVtbl ikspvt
= {
603 IKsPrivatePropertySetImpl_QueryInterface
,
604 IKsPrivatePropertySetImpl_AddRef
,
605 IKsPrivatePropertySetImpl_Release
,
606 IKsPrivatePropertySetImpl_Get
,
607 IKsPrivatePropertySetImpl_Set
,
608 IKsPrivatePropertySetImpl_QuerySupport
611 HRESULT
IKsPrivatePropertySetImpl_Create(REFIID riid
, void **ppv
)
613 IKsPrivatePropertySetImpl
*iks
;
616 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
618 iks
= HeapAlloc(GetProcessHeap(), 0, sizeof(*iks
));
620 WARN("out of memory\n");
621 return DSERR_OUTOFMEMORY
;
625 iks
->IKsPropertySet_iface
.lpVtbl
= &ikspvt
;
627 hr
= IKsPropertySet_QueryInterface(&iks
->IKsPropertySet_iface
, riid
, ppv
);
628 IKsPropertySet_Release(&iks
->IKsPropertySet_iface
);