propset.c 18.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*  			DirectSound
 *
 * Copyright 1998 Marcus Meissner
 * Copyright 1998 Rob Riggs
 * Copyright 2000-2002 TransGaming Technologies, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * 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 23
#include <stdarg.h>

24
#define COBJMACROS
25 26
#include "windef.h"
#include "winbase.h"
27
#include "winuser.h"
28
#include "mmsystem.h"
29
#include "winnls.h"
30
#include "vfwmsgs.h"
31 32 33 34
#include "mmddk.h"
#include "wine/debug.h"
#include "dsound.h"
#include "dsound_private.h"
35
#include "dsconf.h"
36

37 38 39 40
#include "ksmedia.h"
#include "propkey.h"
#include "devpkey.h"

41 42
WINE_DEFAULT_DEBUG_CHANNEL(dsound);

43
static WCHAR wInterface[] = L"Interface";
44

45 46 47 48 49 50 51 52 53 54 55
typedef struct IKsPrivatePropertySetImpl
{
    IKsPropertySet IKsPropertySet_iface;
    LONG ref;
} IKsPrivatePropertySetImpl;

static IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *iface)
{
    return CONTAINING_RECORD(iface, IKsPrivatePropertySetImpl, IKsPropertySet_iface);
}

56 57 58 59 60 61
/*******************************************************************************
 *              IKsPrivatePropertySet
 */

/* IUnknown methods */
static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
62
        IKsPropertySet *iface, REFIID riid, void **ppobj)
63
{
64
    IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
65 66
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

67 68 69
    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IKsPropertySet)) {
        *ppobj = iface;
70
        IKsPropertySet_AddRef(iface);
71 72
        return S_OK;
    }
73
    *ppobj = NULL;
74
    return E_NOINTERFACE;
75 76 77 78
}

static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface)
{
79
    IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
80
    ULONG ref = InterlockedIncrement(&(This->ref));
81
    TRACE("(%p) ref %ld\n", This, ref);
82
    return ref;
83 84
}

85 86
static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
{
87
    IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
88
    ULONG ref = InterlockedDecrement(&(This->ref));
89
    TRACE("(%p) ref %ld\n", This, ref);
90

91
    if (!ref) {
92
        TRACE("(%p) released\n", This);
93
        free(This);
94
    }
95
    return ref;
96 97
}

98 99 100 101 102
struct search_data {
    const WCHAR *tgt_name;
    GUID *found_guid;
};

103
static BOOL CALLBACK search_callback(GUID *guid, const WCHAR *desc,
104 105 106 107 108 109 110 111 112 113 114 115
        const WCHAR *module, void *user)
{
    struct search_data *search = user;

    if(!lstrcmpW(desc, search->tgt_name)){
        *search->found_guid = *guid;
        return FALSE;
    }

    return TRUE;
}

116
static HRESULT DSPROPERTY_WaveDeviceMappingW(
117
    LPVOID pPropData,
118 119 120
    ULONG cbPropData,
    PULONG pcbReturned )
{
121 122 123
    HRESULT hr;
    PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd = pPropData;
    struct search_data search;
124

125
    TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
126
          pPropData,cbPropData,pcbReturned);
127 128

    if (!ppd) {
129 130
        WARN("invalid parameter: pPropData\n");
        return DSERR_INVALIDPARAM;
131 132
    }

133 134 135 136
    search.tgt_name = ppd->DeviceName;
    search.found_guid = &ppd->DeviceId;

    if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
137 138
        hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
                search_callback, &search);
139
    else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE)
140 141
        hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
                search_callback, &search);
142 143 144 145 146 147
    else
        return DSERR_INVALIDPARAM;

    if(hr != S_FALSE)
        /* device was not found */
        return DSERR_INVALIDPARAM;
148

149
    if (pcbReturned)
150
        *pcbReturned = cbPropData;
151

152
    return DS_OK;
153 154
}

155
static HRESULT DSPROPERTY_WaveDeviceMappingA(
156
    LPVOID pPropData,
157 158 159
    ULONG cbPropData,
    PULONG pcbReturned )
{
160 161 162 163
    DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData;
    DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data;
    DWORD len;
    HRESULT hr;
164

165
    TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
166
      pPropData,cbPropData,pcbReturned);
167

168 169 170
    if (!ppd || !ppd->DeviceName) {
        WARN("invalid parameter: ppd=%p\n", ppd);
        return DSERR_INVALIDPARAM;
171 172
    }

173 174
    data.DataFlow = ppd->DataFlow;
    len = MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, NULL, 0);
175
    data.DeviceName = malloc(len * sizeof(WCHAR));
176 177 178 179 180
    if (!data.DeviceName)
        return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, data.DeviceName, len);

    hr = DSPROPERTY_WaveDeviceMappingW(&data, cbPropData, pcbReturned);
181
    free(data.DeviceName);
182
    ppd->DeviceId = data.DeviceId;
183

184 185 186 187
    if (pcbReturned)
        *pcbReturned = cbPropData;

    return hr;
188 189
}

190
static HRESULT DSPROPERTY_DescriptionW(
191 192 193 194
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
195
    PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
196
    GUID dev_guid;
197 198 199 200
    IMMDevice *mmdevice;
    IPropertyStore *ps;
    PROPVARIANT pv;
    HRESULT hr;
201

202
    TRACE("pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
203
          pPropData,cbPropData,pcbReturned);
204 205 206

    TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
    if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
207 208 209 210 211 212 213 214 215 216 217
        /* default device of type specified by ppd->DataFlow */
        if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
            TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
            ppd->DeviceId = DSDEVID_DefaultCapture;
        } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
            TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
            ppd->DeviceId = DSDEVID_DefaultPlayback;
        } else {
            WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow);
            return E_PROP_ID_UNSUPPORTED;
        }
218
    }
219

220 221
    setup_dsound_options();

222 223
    GetDeviceID(&ppd->DeviceId, &dev_guid);

224 225 226 227 228
    hr = get_mmdevice(eRender, &dev_guid, &mmdevice);
    if(FAILED(hr)){
        hr = get_mmdevice(eCapture, &dev_guid, &mmdevice);
        if(FAILED(hr))
            return hr;
229
    }
Robert Reif's avatar
Robert Reif committed
230

231 232 233
    hr = IMMDevice_OpenPropertyStore(mmdevice, STGM_READ, &ps);
    if(FAILED(hr)){
        IMMDevice_Release(mmdevice);
234
        WARN("OpenPropertyStore failed: %08lx\n", hr);
235
        return hr;
236
    }
237

238 239 240 241 242
    hr = IPropertyStore_GetValue(ps,
            (const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
    if(FAILED(hr)){
        IPropertyStore_Release(ps);
        IMMDevice_Release(mmdevice);
243
        WARN("GetValue(FriendlyName) failed: %08lx\n", hr);
244
        return hr;
245 246
    }

247 248 249
    ppd->Description = wcsdup(pv.pwszVal);
    ppd->Module = wcsdup(wine_vxd_drv);
    ppd->Interface = wcsdup(wInterface);
250 251
    ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;

252 253 254 255
    PropVariantClear(&pv);
    IPropertyStore_Release(ps);
    IMMDevice_Release(mmdevice);

256
    if (pcbReturned) {
257
        *pcbReturned = sizeof(*ppd);
258
        TRACE("*pcbReturned=%ld\n", *pcbReturned);
259
    }
260

261 262 263
    return S_OK;
}

264
static
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
BOOL CALLBACK enum_callback(GUID *guid, const WCHAR *desc, const WCHAR *module,
        void *user)
{
    PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = user;
    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
    DWORD len;
    BOOL ret;

    TRACE("%s %s %s %p\n", wine_dbgstr_guid(guid), wine_dbgstr_w(desc),
            wine_dbgstr_w(module), user);

    if(!guid)
        return TRUE;

    data.DeviceId = *guid;

    len = lstrlenW(module) + 1;
282
    data.Module = malloc(len * sizeof(WCHAR));
283 284 285
    memcpy(data.Module, module, len * sizeof(WCHAR));

    len = lstrlenW(desc) + 1;
286
    data.Description = malloc(len * sizeof(WCHAR));
287 288 289 290 291 292
    memcpy(data.Description, desc, len * sizeof(WCHAR));

    data.Interface = wInterface;

    ret = ppd->Callback(&data, ppd->Context);

293 294
    free(data.Module);
    free(data.Description);
295 296 297 298

    return ret;
}

299
static HRESULT DSPROPERTY_EnumerateW(
300 301 302 303
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
304
    PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
305 306
    HRESULT hr;

307
    TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
308 309
          pPropData,cbPropData,pcbReturned);

310 311
    if (pcbReturned)
        *pcbReturned = 0;
312

313 314 315 316 317
    if (!ppd || !ppd->Callback)
    {
        WARN("Invalid ppd %p\n", ppd);
        return E_PROP_ID_UNSUPPORTED;
    }
318

319 320
    hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
            enum_callback, ppd);
321

322
    if(hr == S_OK)
323 324
        hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
                enum_callback, ppd);
325

326
    return SUCCEEDED(hr) ? DS_OK : hr;
327 328
}

329
static BOOL DSPROPERTY_descWtoA(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
330 331 332 333 334 335 336 337 338 339 340 341
                                DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *dataA)
{
    DWORD modlen, desclen;
    static char Interface[] = "Interface";

    modlen = WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, NULL, 0, NULL, NULL);
    desclen = WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, NULL, 0, NULL, NULL);
    dataA->Type = dataW->Type;
    dataA->DataFlow = dataW->DataFlow;
    dataA->DeviceId = dataW->DeviceId;
    dataA->WaveDeviceId = dataW->WaveDeviceId;
    dataA->Interface = Interface;
342 343
    dataA->Module = malloc(modlen);
    dataA->Description = malloc(desclen);
344 345
    if (!dataA->Module || !dataA->Description)
    {
346 347
        free(dataA->Module);
        free(dataA->Description);
348 349 350 351 352 353 354 355 356
        dataA->Module = dataA->Description = NULL;
        return FALSE;
    }

    WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, dataA->Module, modlen, NULL, NULL);
    WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, dataA->Description, desclen, NULL, NULL);
    return TRUE;
}

357
static void DSPROPERTY_descWto1(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
358 359 360
                                DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *data1)
{
    data1->DeviceId = dataW->DeviceId;
361 362
    lstrcpynW(data1->ModuleW, dataW->Module, ARRAY_SIZE(data1->ModuleW));
    lstrcpynW(data1->DescriptionW, dataW->Description, ARRAY_SIZE(data1->DescriptionW));
363 364 365 366 367 368 369 370 371
    WideCharToMultiByte(CP_ACP, 0, data1->DescriptionW, -1, data1->DescriptionA, sizeof(data1->DescriptionA)-1, NULL, NULL);
    WideCharToMultiByte(CP_ACP, 0, data1->ModuleW, -1, data1->ModuleA, sizeof(data1->ModuleA)-1, NULL, NULL);
    data1->DescriptionA[sizeof(data1->DescriptionA)-1] = 0;
    data1->ModuleA[sizeof(data1->ModuleA)-1] = 0;
    data1->Type = dataW->Type;
    data1->DataFlow = dataW->DataFlow;
    data1->WaveDeviceId = data1->Devnode = dataW->WaveDeviceId;
}

372 373 374 375 376 377 378 379 380 381
static BOOL CALLBACK DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
{
    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA;
    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = data;
    BOOL ret;

    ret = DSPROPERTY_descWtoA(descW, &descA);
    if (!ret)
        return FALSE;
    ret = ppd->Callback(&descA, ppd->Context);
382 383
    free(descA.Module);
    free(descA.Description);
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
    return ret;
}

static HRESULT DSPROPERTY_EnumerateA(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned)
{
    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData;
    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;

    if (!ppd || !ppd->Callback)
    {
        WARN("Invalid ppd %p\n", ppd);
        return E_PROP_ID_UNSUPPORTED;
    }

    data.Callback = DSPROPERTY_enumWtoA;
    data.Context = ppd;

    return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
}

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
static BOOL CALLBACK DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
{
    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1;
    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = data;
    BOOL ret;

    DSPROPERTY_descWto1(descW, &desc1);
    ret = ppd->Callback(&desc1, ppd->Context);
    return ret;
}

static HRESULT DSPROPERTY_Enumerate1(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned)
{
    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData;
    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;

    if (!ppd || !ppd->Callback)
    {
        WARN("Invalid ppd %p\n", ppd);
        return E_PROP_ID_UNSUPPORTED;
    }

    data.Callback = DSPROPERTY_enumWto1;
    data.Context = ppd;

    return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
}

438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
static HRESULT DSPROPERTY_DescriptionA(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned)
{
    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *ppd = pPropData;
    HRESULT hr;

    if (pcbReturned)
        *pcbReturned = sizeof(*ppd);
    if (!pPropData)
        return S_OK;

    data.DeviceId = ppd->DeviceId;
    data.DataFlow = ppd->DataFlow;
    hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
    if (FAILED(hr))
        return hr;
    if (!DSPROPERTY_descWtoA(&data, ppd))
        hr = E_OUTOFMEMORY;
459 460 461
    free(data.Description);
    free(data.Module);
    free(data.Interface);
462 463 464
    return hr;
}

465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
static HRESULT DSPROPERTY_Description1(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned)
{
    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *ppd = pPropData;
    HRESULT hr;

    if (pcbReturned)
        *pcbReturned = sizeof(*ppd);
    if (!pPropData)
        return S_OK;

    data.DeviceId = ppd->DeviceId;
    data.DataFlow = ppd->DataFlow;
    hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
    if (FAILED(hr))
        return hr;
    DSPROPERTY_descWto1(&data, ppd);
485 486 487
    free(data.Description);
    free(data.Module);
    free(data.Interface);
488 489 490
    return hr;
}

491 492 493 494 495 496 497 498
static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
    LPKSPROPERTYSET iface,
    REFGUID guidPropSet,
    ULONG dwPropID,
    LPVOID pInstanceData,
    ULONG cbInstanceData,
    LPVOID pPropData,
    ULONG cbPropData,
Robert Reif's avatar
Robert Reif committed
499 500
    PULONG pcbReturned )
{
501
    IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
502
    TRACE("(iface=%p,guidPropSet=%s,dwPropID=%lu,pInstanceData=%p,cbInstanceData=%lu,pPropData=%p,cbPropData=%lu,pcbReturned=%p)\n",
503
          This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
504 505

    if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
        switch (dwPropID) {
        case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
            return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
            return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
            return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
            return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
            return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
            return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
            return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
            return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned);
        default:
524
            FIXME("unsupported ID: %ld\n",dwPropID);
525 526
            break;
        }
527
    } else {
528
        FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
529
    }
530

531
    if (pcbReturned) {
532
        *pcbReturned = 0;
533
        FIXME("*pcbReturned=%ld\n", *pcbReturned);
534
    }
535

536
    return E_PROP_ID_UNSUPPORTED;
537 538
}

539 540 541 542 543 544 545 546 547
static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
    LPKSPROPERTYSET iface,
    REFGUID guidPropSet,
    ULONG dwPropID,
    LPVOID pInstanceData,
    ULONG cbInstanceData,
    LPVOID pPropData,
    ULONG cbPropData )
{
548
    IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
549

550
    FIXME("(%p,%s,%ld,%p,%ld,%p,%ld), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
551
    return E_PROP_ID_UNSUPPORTED;
552 553
}

554 555 556 557 558 559
static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
    LPKSPROPERTYSET iface,
    REFGUID guidPropSet,
    ULONG dwPropID,
    PULONG pTypeSupport )
{
560
    IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
561
    TRACE("(%p,%s,%ld,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589

    if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
	switch (dwPropID) {
	case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	default:
590
            FIXME("unsupported ID: %ld\n",dwPropID);
591 592 593 594 595
	    break;
	}
    } else {
	FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
    }
596

597
    return E_PROP_ID_UNSUPPORTED;
598 599
}

600
static const IKsPropertySetVtbl ikspvt = {
601 602 603 604 605 606
    IKsPrivatePropertySetImpl_QueryInterface,
    IKsPrivatePropertySetImpl_AddRef,
    IKsPrivatePropertySetImpl_Release,
    IKsPrivatePropertySetImpl_Get,
    IKsPrivatePropertySetImpl_Set,
    IKsPrivatePropertySetImpl_QuerySupport
607 608
};

609
HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **ppv)
610
{
611
    IKsPrivatePropertySetImpl *iks;
612 613 614
    HRESULT hr;

    TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
615

616
    iks = malloc(sizeof(*iks));
617 618 619
    if (!iks) {
        WARN("out of memory\n");
        return DSERR_OUTOFMEMORY;
620
    }
621

622
    iks->ref = 1;
623
    iks->IKsPropertySet_iface.lpVtbl = &ikspvt;
624

625 626 627 628
    hr = IKsPropertySet_QueryInterface(&iks->IKsPropertySet_iface, riid, ppv);
    IKsPropertySet_Release(&iks->IKsPropertySet_iface);

    return hr;
629
}