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 #include "dsound_private.h" 23 24 typedef struct IKsPrivatePropertySetImpl 25 { 26 IKsPropertySet IKsPropertySet_iface; 27 LONG ref; 28 } IKsPrivatePropertySetImpl; 29 30 static IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *iface) 31 { 32 return CONTAINING_RECORD(iface, IKsPrivatePropertySetImpl, IKsPropertySet_iface); 33 } 34 35 /******************************************************************************* 36 * IKsPrivatePropertySet 37 */ 38 39 /* IUnknown methods */ 40 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface( 41 LPKSPROPERTYSET iface, 42 REFIID riid, 43 LPVOID *ppobj ) 44 { 45 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface); 46 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); 47 48 if (IsEqualIID(riid, &IID_IUnknown) || 49 IsEqualIID(riid, &IID_IKsPropertySet)) { 50 *ppobj = iface; 51 IUnknown_AddRef(iface); 52 return S_OK; 53 } 54 *ppobj = NULL; 55 return E_NOINTERFACE; 56 } 57 58 static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface) 59 { 60 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface); 61 ULONG ref = InterlockedIncrement(&(This->ref)); 62 TRACE("(%p) ref was %d\n", This, ref - 1); 63 return ref; 64 } 65 66 static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface) 67 { 68 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface); 69 ULONG ref = InterlockedDecrement(&(This->ref)); 70 TRACE("(%p) ref was %d\n", This, ref + 1); 71 72 if (!ref) { 73 HeapFree(GetProcessHeap(), 0, This); 74 TRACE("(%p) released\n", This); 75 } 76 return ref; 77 } 78 79 static HRESULT DSPROPERTY_WaveDeviceMappingW( 80 LPVOID pPropData, 81 ULONG cbPropData, 82 PULONG pcbReturned ) 83 { 84 HRESULT hr = DSERR_INVALIDPARAM; 85 PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd; 86 TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", 87 pPropData,cbPropData,pcbReturned); 88 89 ppd = pPropData; 90 91 if (!ppd) { 92 WARN("invalid parameter: pPropData\n"); 93 return DSERR_INVALIDPARAM; 94 } 95 96 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { 97 ULONG wod; 98 unsigned int wodn; 99 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); 100 wodn = waveOutGetNumDevs(); 101 for (wod = 0; wod < wodn; wod++) { 102 WAVEOUTCAPSW capsW; 103 MMRESULT res; 104 res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW)); 105 if (res == MMSYSERR_NOERROR) { 106 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) { 107 ppd->DeviceId = DSOUND_renderer_guids[wod]; 108 hr = DS_OK; 109 TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId), 110 debugstr_w(ppd->DeviceName)); 111 break; 112 } 113 } 114 } 115 } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { 116 ULONG wid; 117 unsigned int widn; 118 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); 119 widn = waveInGetNumDevs(); 120 for (wid = 0; wid < widn; wid++) { 121 WAVEINCAPSW capsW; 122 MMRESULT res; 123 res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW)); 124 if (res == MMSYSERR_NOERROR) { 125 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) { 126 ppd->DeviceId = DSOUND_capture_guids[wid]; 127 hr = DS_OK; 128 TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId), 129 debugstr_w(ppd->DeviceName)); 130 break; 131 } 132 } 133 } 134 } 135 136 if (pcbReturned) 137 *pcbReturned = cbPropData; 138 139 return hr; 140 } 141 142 static HRESULT DSPROPERTY_WaveDeviceMappingA( 143 LPVOID pPropData, 144 ULONG cbPropData, 145 PULONG pcbReturned ) 146 { 147 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData; 148 DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data; 149 DWORD len; 150 HRESULT hr; 151 152 TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", 153 pPropData,cbPropData,pcbReturned); 154 155 if (!ppd || !ppd->DeviceName) { 156 WARN("invalid parameter: ppd=%p\n", ppd); 157 return DSERR_INVALIDPARAM; 158 } 159 160 data.DataFlow = ppd->DataFlow; 161 len = MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, NULL, 0); 162 data.DeviceName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 163 if (!data.DeviceName) 164 return E_OUTOFMEMORY; 165 MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, data.DeviceName, len); 166 167 hr = DSPROPERTY_WaveDeviceMappingW(&data, cbPropData, pcbReturned); 168 HeapFree(GetProcessHeap(), 0, data.DeviceName); 169 ppd->DeviceId = data.DeviceId; 170 171 if (pcbReturned) 172 *pcbReturned = cbPropData; 173 174 return hr; 175 } 176 177 static HRESULT DSPROPERTY_DescriptionW( 178 LPVOID pPropData, 179 ULONG cbPropData, 180 PULONG pcbReturned ) 181 { 182 PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData; 183 HRESULT err; 184 GUID dev_guid; 185 ULONG wod, wid, wodn, widn; 186 DSDRIVERDESC desc; 187 188 TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", 189 pPropData,cbPropData,pcbReturned); 190 191 TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId)); 192 if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) { 193 /* default device of type specified by ppd->DataFlow */ 194 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { 195 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); 196 ppd->DeviceId = DSDEVID_DefaultCapture; 197 } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { 198 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); 199 ppd->DeviceId = DSDEVID_DefaultPlayback; 200 } else { 201 WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow); 202 return E_PROP_ID_UNSUPPORTED; 203 } 204 } 205 206 setup_dsound_options(); 207 208 GetDeviceID(&ppd->DeviceId, &dev_guid); 209 210 wodn = waveOutGetNumDevs(); 211 widn = waveInGetNumDevs(); 212 wid = wod = dev_guid.Data4[7]; 213 if (!memcmp(&dev_guid, &DSOUND_renderer_guids[0], sizeof(GUID)-1) 214 && wod < wodn) 215 { 216 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; 217 ppd->WaveDeviceId = wod; 218 } 219 else if (!memcmp(&dev_guid, &DSOUND_capture_guids[0], sizeof(GUID)-1) 220 && wid < widn) 221 { 222 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; 223 ppd->WaveDeviceId = wid; 224 } 225 else 226 { 227 WARN("Device not found\n"); 228 return E_PROP_ID_UNSUPPORTED; 229 } 230 231 if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) 232 err = waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel); 233 else 234 err = waveInMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel); 235 236 if (err != MMSYSERR_NOERROR) 237 { 238 WARN("waveMessage(DRV_QUERYDSOUNDDESC) failed!\n"); 239 return E_PROP_ID_UNSUPPORTED; 240 } 241 else 242 { 243 /* FIXME: Still a memory leak.. */ 244 int desclen, modlen; 245 static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 }; 246 247 modlen = MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, NULL, 0 ); 248 desclen = MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, NULL, 0 ); 249 ppd->Module = HeapAlloc(GetProcessHeap(),0,modlen*sizeof(WCHAR)); 250 ppd->Description = HeapAlloc(GetProcessHeap(),0,desclen*sizeof(WCHAR)); 251 ppd->Interface = wInterface; 252 if (!ppd->Description || !ppd->Module) 253 { 254 WARN("Out of memory\n"); 255 HeapFree(GetProcessHeap(), 0, ppd->Description); 256 HeapFree(GetProcessHeap(), 0, ppd->Module); 257 ppd->Description = ppd->Module = NULL; 258 return E_OUTOFMEMORY; 259 } 260 261 MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->Module, modlen ); 262 MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->Description, desclen ); 263 } 264 265 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; 266 267 if (pcbReturned) { 268 *pcbReturned = sizeof(*ppd); 269 TRACE("*pcbReturned=%d\n", *pcbReturned); 270 } 271 272 return S_OK; 273 } 274 275 static HRESULT DSPROPERTY_EnumerateW( 276 LPVOID pPropData, 277 ULONG cbPropData, 278 PULONG pcbReturned ) 279 { 280 PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData; 281 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data; 282 BOOL ret; 283 int widn, wodn, i; 284 TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", 285 pPropData,cbPropData,pcbReturned); 286 287 if (pcbReturned) 288 *pcbReturned = 0; 289 290 if (!ppd || !ppd->Callback) 291 { 292 WARN("Invalid ppd %p\n", ppd); 293 return E_PROP_ID_UNSUPPORTED; 294 } 295 296 wodn = waveOutGetNumDevs(); 297 widn = waveInGetNumDevs(); 298 299 data.DeviceId = DSOUND_renderer_guids[0]; 300 for (i = 0; i < wodn; ++i) 301 { 302 HRESULT hr; 303 data.DeviceId.Data4[7] = i; 304 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL); 305 if (FAILED(hr)) 306 { 307 ERR("DescriptionW failed!\n"); 308 return S_OK; 309 } 310 ret = ppd->Callback(&data, ppd->Context); 311 HeapFree(GetProcessHeap(), 0, data.Module); 312 HeapFree(GetProcessHeap(), 0, data.Description); 313 if (!ret) 314 return S_OK; 315 } 316 317 data.DeviceId = DSOUND_capture_guids[0]; 318 for (i = 0; i < widn; ++i) 319 { 320 HRESULT hr; 321 data.DeviceId.Data4[7] = i; 322 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL); 323 if (FAILED(hr)) 324 { 325 ERR("DescriptionW failed!\n"); 326 return S_OK; 327 } 328 ret = ppd->Callback(&data, ppd->Context); 329 HeapFree(GetProcessHeap(), 0, data.Module); 330 HeapFree(GetProcessHeap(), 0, data.Description); 331 if (!ret) 332 return S_OK; 333 } 334 return S_OK; 335 } 336 337 static BOOL DSPROPERTY_descWtoA(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW, 338 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *dataA) 339 { 340 DWORD modlen, desclen; 341 static char Interface[] = "Interface"; 342 343 modlen = WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, NULL, 0, NULL, NULL); 344 desclen = WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, NULL, 0, NULL, NULL); 345 dataA->Type = dataW->Type; 346 dataA->DataFlow = dataW->DataFlow; 347 dataA->DeviceId = dataW->DeviceId; 348 dataA->WaveDeviceId = dataW->WaveDeviceId; 349 dataA->Interface = Interface; 350 dataA->Module = HeapAlloc(GetProcessHeap(), 0, modlen); 351 dataA->Description = HeapAlloc(GetProcessHeap(), 0, desclen); 352 if (!dataA->Module || !dataA->Description) 353 { 354 HeapFree(GetProcessHeap(), 0, dataA->Module); 355 HeapFree(GetProcessHeap(), 0, dataA->Description); 356 dataA->Module = dataA->Description = NULL; 357 return FALSE; 358 } 359 360 WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, dataA->Module, modlen, NULL, NULL); 361 WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, dataA->Description, desclen, NULL, NULL); 362 return TRUE; 363 } 364 365 static void DSPROPERTY_descWto1(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW, 366 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *data1) 367 { 368 data1->DeviceId = dataW->DeviceId; 369 lstrcpynW(data1->ModuleW, dataW->Module, sizeof(data1->ModuleW)/sizeof(*data1->ModuleW)); 370 lstrcpynW(data1->DescriptionW, dataW->Description, sizeof(data1->DescriptionW)/sizeof(*data1->DescriptionW)); 371 WideCharToMultiByte(CP_ACP, 0, data1->DescriptionW, -1, data1->DescriptionA, sizeof(data1->DescriptionA)-1, NULL, NULL); 372 WideCharToMultiByte(CP_ACP, 0, data1->ModuleW, -1, data1->ModuleA, sizeof(data1->ModuleA)-1, NULL, NULL); 373 data1->DescriptionA[sizeof(data1->DescriptionA)-1] = 0; 374 data1->ModuleA[sizeof(data1->ModuleA)-1] = 0; 375 data1->Type = dataW->Type; 376 data1->DataFlow = dataW->DataFlow; 377 data1->WaveDeviceId = data1->Devnode = dataW->WaveDeviceId; 378 } 379 380 static BOOL CALLBACK DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data) 381 { 382 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA; 383 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = data; 384 BOOL ret; 385 386 ret = DSPROPERTY_descWtoA(descW, &descA); 387 if (!ret) 388 return FALSE; 389 ret = ppd->Callback(&descA, ppd->Context); 390 HeapFree(GetProcessHeap(), 0, descA.Module); 391 HeapFree(GetProcessHeap(), 0, descA.Description); 392 return ret; 393 } 394 395 static HRESULT DSPROPERTY_EnumerateA( 396 LPVOID pPropData, 397 ULONG cbPropData, 398 PULONG pcbReturned) 399 { 400 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData; 401 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data; 402 403 if (!ppd || !ppd->Callback) 404 { 405 WARN("Invalid ppd %p\n", ppd); 406 return E_PROP_ID_UNSUPPORTED; 407 } 408 409 data.Callback = DSPROPERTY_enumWtoA; 410 data.Context = ppd; 411 412 return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned); 413 } 414 415 static BOOL CALLBACK DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data) 416 { 417 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1; 418 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = data; 419 BOOL ret; 420 421 DSPROPERTY_descWto1(descW, &desc1); 422 ret = ppd->Callback(&desc1, ppd->Context); 423 return ret; 424 } 425 426 static HRESULT DSPROPERTY_Enumerate1( 427 LPVOID pPropData, 428 ULONG cbPropData, 429 PULONG pcbReturned) 430 { 431 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData; 432 DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data; 433 434 if (!ppd || !ppd->Callback) 435 { 436 WARN("Invalid ppd %p\n", ppd); 437 return E_PROP_ID_UNSUPPORTED; 438 } 439 440 data.Callback = DSPROPERTY_enumWto1; 441 data.Context = ppd; 442 443 return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned); 444 } 445 446 static HRESULT DSPROPERTY_DescriptionA( 447 LPVOID pPropData, 448 ULONG cbPropData, 449 PULONG pcbReturned) 450 { 451 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data; 452 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *ppd = pPropData; 453 HRESULT hr; 454 455 if (pcbReturned) 456 *pcbReturned = sizeof(*ppd); 457 if (!pPropData) 458 return S_OK; 459 460 data.DeviceId = ppd->DeviceId; 461 data.DataFlow = ppd->DataFlow; 462 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL); 463 if (FAILED(hr)) 464 return hr; 465 if (!DSPROPERTY_descWtoA(&data, ppd)) 466 hr = E_OUTOFMEMORY; 467 HeapFree(GetProcessHeap(), 0, data.Module); 468 HeapFree(GetProcessHeap(), 0, data.Interface); 469 return hr; 470 } 471 472 static HRESULT DSPROPERTY_Description1( 473 LPVOID pPropData, 474 ULONG cbPropData, 475 PULONG pcbReturned) 476 { 477 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data; 478 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *ppd = pPropData; 479 HRESULT hr; 480 481 if (pcbReturned) 482 *pcbReturned = sizeof(*ppd); 483 if (!pPropData) 484 return S_OK; 485 486 data.DeviceId = ppd->DeviceId; 487 data.DataFlow = ppd->DataFlow; 488 hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL); 489 if (FAILED(hr)) 490 return hr; 491 DSPROPERTY_descWto1(&data, ppd); 492 HeapFree(GetProcessHeap(), 0, data.Module); 493 HeapFree(GetProcessHeap(), 0, data.Interface); 494 return hr; 495 } 496 497 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get( 498 LPKSPROPERTYSET iface, 499 REFGUID guidPropSet, 500 ULONG dwPropID, 501 LPVOID pInstanceData, 502 ULONG cbInstanceData, 503 LPVOID pPropData, 504 ULONG cbPropData, 505 PULONG pcbReturned ) 506 { 507 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface); 508 TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", 509 This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned); 510 511 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) { 512 switch (dwPropID) { 513 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: 514 return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned); 515 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: 516 return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned); 517 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: 518 return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned); 519 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: 520 return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned); 521 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: 522 return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned); 523 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: 524 return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned); 525 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: 526 return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned); 527 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: 528 return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned); 529 default: 530 FIXME("unsupported ID: %d\n",dwPropID); 531 break; 532 } 533 } else { 534 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet)); 535 } 536 537 if (pcbReturned) { 538 *pcbReturned = 0; 539 FIXME("*pcbReturned=%d\n", *pcbReturned); 540 } 541 542 return E_PROP_ID_UNSUPPORTED; 543 } 544 545 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set( 546 LPKSPROPERTYSET iface, 547 REFGUID guidPropSet, 548 ULONG dwPropID, 549 LPVOID pInstanceData, 550 ULONG cbInstanceData, 551 LPVOID pPropData, 552 ULONG cbPropData ) 553 { 554 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface); 555 556 FIXME("(%p,%s,%d,%p,%d,%p,%d), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData); 557 return E_PROP_ID_UNSUPPORTED; 558 } 559 560 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport( 561 LPKSPROPERTYSET iface, 562 REFGUID guidPropSet, 563 ULONG dwPropID, 564 PULONG pTypeSupport ) 565 { 566 IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface); 567 TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport); 568 569 if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) { 570 switch (dwPropID) { 571 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: 572 *pTypeSupport = KSPROPERTY_SUPPORT_GET; 573 return S_OK; 574 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: 575 *pTypeSupport = KSPROPERTY_SUPPORT_GET; 576 return S_OK; 577 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: 578 *pTypeSupport = KSPROPERTY_SUPPORT_GET; 579 return S_OK; 580 case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: 581 *pTypeSupport = KSPROPERTY_SUPPORT_GET; 582 return S_OK; 583 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: 584 *pTypeSupport = KSPROPERTY_SUPPORT_GET; 585 return S_OK; 586 case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: 587 *pTypeSupport = KSPROPERTY_SUPPORT_GET; 588 return S_OK; 589 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: 590 *pTypeSupport = KSPROPERTY_SUPPORT_GET; 591 return S_OK; 592 case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: 593 *pTypeSupport = KSPROPERTY_SUPPORT_GET; 594 return S_OK; 595 default: 596 FIXME("unsupported ID: %d\n",dwPropID); 597 break; 598 } 599 } else { 600 FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet)); 601 } 602 603 return E_PROP_ID_UNSUPPORTED; 604 } 605 606 static const IKsPropertySetVtbl ikspvt = { 607 IKsPrivatePropertySetImpl_QueryInterface, 608 IKsPrivatePropertySetImpl_AddRef, 609 IKsPrivatePropertySetImpl_Release, 610 IKsPrivatePropertySetImpl_Get, 611 IKsPrivatePropertySetImpl_Set, 612 IKsPrivatePropertySetImpl_QuerySupport 613 }; 614 615 HRESULT IKsPrivatePropertySetImpl_Create( 616 REFIID riid, 617 IKsPropertySet **piks) 618 { 619 IKsPrivatePropertySetImpl *iks; 620 TRACE("(%s, %p)\n", debugstr_guid(riid), piks); 621 622 if (!IsEqualIID(riid, &IID_IUnknown) && 623 !IsEqualIID(riid, &IID_IKsPropertySet)) { 624 *piks = 0; 625 return E_NOINTERFACE; 626 } 627 628 iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks)); 629 iks->ref = 1; 630 iks->IKsPropertySet_iface.lpVtbl = &ikspvt; 631 632 *piks = &iks->IKsPropertySet_iface; 633 return S_OK; 634 } 635