Avoid an upcast
[wine/multimedia.git] / duplex.c
blob865244dd89400054cf1b6ba5eaf7e117f0d05507
1 /* DirectSoundFullDuplex
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2001 TransGaming Technologies, Inc.
6 * Copyright 2005 Robert Reif
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <stdarg.h>
25 #ifdef __WINESRC__
27 #define NONAMELESSSTRUCT
28 #define NONAMELESSUNION
29 #define CINTERFACE
30 #define COBJMACROS
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "mmsystem.h"
35 #include "mmddk.h"
36 #include "winternl.h"
37 #include "wine/debug.h"
38 #include "dsound.h"
39 #include "dsdriver.h"
41 #include "dsound_private.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 #endif
55 /*****************************************************************************
56 * IDirectSoundFullDuplex implementation structure
58 typedef struct IDirectSoundFullDuplexImpl
60 IDirectSoundFullDuplex IDirectSoundFullDuplex_iface;
61 IUnknown IUnknown_iface;
62 IDirectSound8 IDirectSound8_iface;
63 IDirectSoundCapture IDirectSoundCapture_iface;
64 LONG ref, unkref, ds8ref, dscref;
65 LONG all_ref;
67 /* IDirectSoundFullDuplexImpl fields */
68 IDirectSound8 *renderer_device;
69 IDirectSoundCapture *capture_device;
70 } IDirectSoundFullDuplexImpl;
73 static void DSOUND_FullDuplexDestroy(IDirectSoundFullDuplexImpl *This)
75 if (This->capture_device)
76 IDirectSoundCapture_Release(This->capture_device);
77 if (This->renderer_device)
78 IDirectSound_Release(This->renderer_device);
79 HeapFree(GetProcessHeap(), 0, This);
80 TRACE("(%p) released\n", This);
83 /*******************************************************************************
84 * IUnknown
86 static inline IDirectSoundFullDuplexImpl *impl_from_IUnknown(IUnknown *iface)
88 return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IUnknown_iface);
91 static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
92 IUnknown *iface, REFIID riid, void **ppobj)
94 IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
95 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
96 return IDirectSoundFullDuplex_QueryInterface(&This->IDirectSoundFullDuplex_iface, riid, ppobj);
99 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_AddRef(IUnknown *iface)
101 IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
102 ULONG ref;
104 InterlockedIncrement(&(This->all_ref));
105 ref = InterlockedIncrement(&(This->unkref));
106 TRACE("(%p) ref was %d\n", This, ref - 1);
108 return ref;
111 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(IUnknown *iface)
113 IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
114 ULONG ref = InterlockedDecrement(&(This->unkref));
115 TRACE("(%p) ref was %d\n", This, ref + 1);
116 if(InterlockedDecrement(&(This->all_ref)) == 0)
117 DSOUND_FullDuplexDestroy(This);
118 return ref;
121 static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl = {
122 IDirectSoundFullDuplex_IUnknown_QueryInterface,
123 IDirectSoundFullDuplex_IUnknown_AddRef,
124 IDirectSoundFullDuplex_IUnknown_Release
127 /*******************************************************************************
128 * IDirectSoundFullDuplex_IDirectSound8
130 static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSound8(IDirectSound8 *iface)
132 return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSound8_iface);
135 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
136 IDirectSound8 *iface, REFIID riid, void **ppobj)
138 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
139 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
140 return IDirectSoundFullDuplex_QueryInterface(&This->IDirectSoundFullDuplex_iface, riid, ppobj);
143 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_AddRef(IDirectSound8 *iface)
145 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
146 ULONG ref;
148 InterlockedIncrement(&(This->all_ref));
149 ref = InterlockedIncrement(&(This->ds8ref));
150 TRACE("(%p) ref was %d\n", This, ref - 1);
152 return ref;
155 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_Release(IDirectSound8 *iface)
157 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
158 ULONG ref = InterlockedDecrement(&(This->ds8ref));
159 TRACE("(%p) ref was %d\n", This, ref + 1);
160 if(InterlockedDecrement(&(This->all_ref)) == 0)
161 DSOUND_FullDuplexDestroy(This);
162 return ref;
165 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
166 IDirectSound8 *iface, LPCDSBUFFERDESC dsbd, IDirectSoundBuffer **ppdsb,
167 IUnknown *lpunk)
169 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
170 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
171 return IDirectSound8_CreateSoundBuffer(This->renderer_device,dsbd,ppdsb,lpunk);
174 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetCaps(
175 IDirectSound8 *iface, DSCAPS *lpDSCaps)
177 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
178 TRACE("(%p,%p)\n",This,lpDSCaps);
179 return IDirectSound8_GetCaps(This->renderer_device, lpDSCaps);
182 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
183 IDirectSound8 *iface, IDirectSoundBuffer *psb, IDirectSoundBuffer **ppdsb)
185 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
186 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
187 return IDirectSound8_DuplicateSoundBuffer(This->renderer_device,psb,ppdsb);
190 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
191 IDirectSound8 *iface, HWND hwnd, DWORD level)
193 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
194 TRACE("(%p,%p,%u)\n",This,hwnd,level);
195 return IDirectSound8_SetCooperativeLevel(This->renderer_device,hwnd,level);
198 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Compact(IDirectSound8 *iface)
200 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
201 TRACE("(%p)\n", This);
202 return IDirectSound8_Compact(This->renderer_device);
205 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
206 IDirectSound8 *iface, DWORD *lpdwSpeakerConfig)
208 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
209 TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
210 return IDirectSound8_GetSpeakerConfig(This->renderer_device,lpdwSpeakerConfig);
213 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
214 IDirectSound8 *iface, DWORD config)
216 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
217 TRACE("(%p,0x%08x)\n",This,config);
218 return IDirectSound8_SetSpeakerConfig(This->renderer_device,config);
221 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Initialize(
222 IDirectSound8 *iface, LPCGUID lpcGuid)
224 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
225 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
226 return IDirectSound8_Initialize(This->renderer_device,lpcGuid);
229 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_VerifyCertification(
230 IDirectSound8 *iface, DWORD *cert)
232 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
233 TRACE("(%p, %p)\n", This, cert);
234 return IDirectSound8_VerifyCertification(This->renderer_device,cert);
237 static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl = {
238 IDirectSoundFullDuplex_IDirectSound8_QueryInterface,
239 IDirectSoundFullDuplex_IDirectSound8_AddRef,
240 IDirectSoundFullDuplex_IDirectSound8_Release,
241 IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer,
242 IDirectSoundFullDuplex_IDirectSound8_GetCaps,
243 IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer,
244 IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel,
245 IDirectSoundFullDuplex_IDirectSound8_Compact,
246 IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig,
247 IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig,
248 IDirectSoundFullDuplex_IDirectSound8_Initialize,
249 IDirectSoundFullDuplex_IDirectSound8_VerifyCertification
252 /*******************************************************************************
253 * IDirectSoundFullDuplex_IDirectSoundCapture
255 static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSoundCapture(IDirectSoundCapture *iface)
257 return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSoundCapture_iface);
260 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
261 IDirectSoundCapture *iface, REFIID riid, void **ppobj)
263 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
264 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
265 return IDirectSoundFullDuplex_QueryInterface(&This->IDirectSoundFullDuplex_iface, riid, ppobj);
268 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(IDirectSoundCapture *iface)
270 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
271 ULONG ref;
273 InterlockedIncrement(&(This->all_ref));
274 ref = InterlockedIncrement(&(This->dscref));
275 TRACE("(%p) ref was %d\n", This, ref - 1);
277 return ref;
280 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release(IDirectSoundCapture *iface)
282 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
283 ULONG ref = InterlockedDecrement(&(This->dscref));
284 TRACE("(%p) ref was %d\n", This, ref + 1);
285 if(InterlockedDecrement(&(This->all_ref)) == 0)
286 DSOUND_FullDuplexDestroy(This);
287 return ref;
290 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
291 IDirectSoundCapture *iface, LPCDSCBUFFERDESC lpcDSCBufferDesc,
292 IDirectSoundCaptureBuffer **lplpDSCaptureBuffer, IUnknown *pUnk)
294 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
295 TRACE("(%p, %p, %p, %p)\n", This, lpcDSCBufferDesc, lplpDSCaptureBuffer, pUnk);
296 return IDirectSoundCapture_CreateCaptureBuffer(This->capture_device,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
299 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
300 IDirectSoundCapture *iface, LPDSCCAPS lpDSCCaps)
302 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
303 TRACE("(%p, %p)\n", This, lpDSCCaps);
304 return IDirectSoundCapture_GetCaps(This->capture_device, lpDSCCaps);
307 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
308 IDirectSoundCapture *iface, LPCGUID lpcGUID)
310 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
311 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGUID));
312 return IDirectSoundCapture_Initialize(This->capture_device,lpcGUID);
315 static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl = {
316 IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface,
317 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef,
318 IDirectSoundFullDuplex_IDirectSoundCapture_Release,
319 IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer,
320 IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps,
321 IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
324 /***************************************************************************
325 * IDirectSoundFullDuplexImpl
327 static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSoundFullDuplex(IDirectSoundFullDuplex *iface)
329 return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSoundFullDuplex_iface);
332 static HRESULT WINAPI IDirectSoundFullDuplexImpl_QueryInterface(
333 IDirectSoundFullDuplex *iface, REFIID riid, void **ppobj)
335 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
336 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
338 if (ppobj == NULL) {
339 WARN("invalid parameter\n");
340 return E_INVALIDARG;
343 *ppobj = NULL;
345 if (IsEqualIID(riid, &IID_IUnknown)) {
346 *ppobj = &This->IUnknown_iface;
347 IUnknown_AddRef((IUnknown*)*ppobj);
348 return S_OK;
349 } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
350 *ppobj = &This->IDirectSoundFullDuplex_iface;
351 IUnknown_AddRef((IUnknown*)*ppobj);
352 return S_OK;
353 } else if (IsEqualIID(riid, &IID_IDirectSound) ||
354 IsEqualIID(riid, &IID_IDirectSound8)) {
355 *ppobj = &This->IDirectSound8_iface;
356 IUnknown_AddRef((IUnknown*)*ppobj);
357 return S_OK;
358 } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
359 *ppobj = &This->IDirectSoundCapture_iface;
360 IUnknown_AddRef((IUnknown*)*ppobj);
361 return S_OK;
364 return E_NOINTERFACE;
367 static ULONG WINAPI IDirectSoundFullDuplexImpl_AddRef(IDirectSoundFullDuplex *iface)
369 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
370 ULONG ref;
372 InterlockedIncrement(&(This->all_ref));
373 ref = InterlockedIncrement(&(This->ref));
374 TRACE("(%p) ref was %d\n", This, ref - 1);
376 return ref;
379 static ULONG WINAPI IDirectSoundFullDuplexImpl_Release(IDirectSoundFullDuplex *iface)
381 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
382 ULONG ref = InterlockedDecrement(&(This->ref));
383 TRACE("(%p) ref was %d\n", This, ref - 1);
384 if(InterlockedDecrement(&(This->all_ref)) == 0)
385 DSOUND_FullDuplexDestroy(This);
386 return ref;
389 static HRESULT WINAPI IDirectSoundFullDuplexImpl_Initialize(
390 IDirectSoundFullDuplex *iface,
391 LPCGUID pCaptureGuid, LPCGUID pRendererGuid,
392 LPCDSCBUFFERDESC lpDscBufferDesc, LPCDSBUFFERDESC lpDsBufferDesc,
393 HWND hWnd, DWORD dwLevel,
394 IDirectSoundCaptureBuffer8 **lplpDirectSoundCaptureBuffer8,
395 IDirectSoundBuffer8 **lplpDirectSoundBuffer8)
397 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
398 void *device;
399 HRESULT hr;
401 TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This,
402 debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
403 lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
404 lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);
406 *lplpDirectSoundCaptureBuffer8 = NULL;
407 *lplpDirectSoundBuffer8 = NULL;
409 if(This->renderer_device != NULL || This->capture_device != NULL)
411 WARN("already initialized\n");
412 return DSERR_ALREADYINITIALIZED;
415 hr = DSOUND_Create8(&IID_IDirectSound8, &device);
416 if(SUCCEEDED(hr))
418 This->renderer_device = device;
419 hr = IDirectSound_Initialize(This->renderer_device, pRendererGuid);
421 if(hr != DS_OK)
423 WARN("DirectSoundDevice_Initialize() failed\n");
424 return hr;
427 IDirectSound8_SetCooperativeLevel(This->renderer_device, hWnd, dwLevel);
429 hr = IDirectSound8_CreateSoundBuffer(This->renderer_device, lpDsBufferDesc,
430 (IDirectSoundBuffer**)lplpDirectSoundBuffer8, NULL);
431 if(hr != DS_OK)
433 WARN("IDirectSoundBufferImpl_Create() failed\n");
434 return hr;
437 hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &device);
438 if(SUCCEEDED(hr))
440 This->capture_device = device;
441 hr = IDirectSoundCapture_Initialize(This->capture_device, pCaptureGuid);
443 if(hr != DS_OK)
445 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
446 return hr;
449 hr = IDirectSoundCapture_CreateCaptureBuffer(This->capture_device, lpDscBufferDesc,
450 (IDirectSoundCaptureBuffer**)lplpDirectSoundCaptureBuffer8, NULL);
451 if(hr != DS_OK)
453 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
454 return hr;
457 return hr;
460 static const IDirectSoundFullDuplexVtbl dsfdvt = {
461 /* IUnknown methods */
462 IDirectSoundFullDuplexImpl_QueryInterface,
463 IDirectSoundFullDuplexImpl_AddRef,
464 IDirectSoundFullDuplexImpl_Release,
466 /* IDirectSoundFullDuplex methods */
467 IDirectSoundFullDuplexImpl_Initialize
470 HRESULT DSOUND_FullDuplexCreate(
471 REFIID riid, void **ppDSFD)
473 IDirectSoundFullDuplexImpl *This = NULL;
474 TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSFD);
476 if(ppDSFD == NULL)
478 WARN("invalid parameter: ppDSFD == NULL\n");
479 return DSERR_INVALIDPARAM;
481 *ppDSFD = NULL;
483 if(!IsEqualIID(riid, &IID_IUnknown) &&
484 !IsEqualIID(riid, &IID_IDirectSoundFullDuplex))
485 return E_NOINTERFACE;
487 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
488 if(This == NULL)
490 WARN("out of memory\n");
491 return DSERR_OUTOFMEMORY;
494 This->IDirectSoundFullDuplex_iface.lpVtbl = (IDirectSoundFullDuplexVtbl*)&dsfdvt;
495 This->IUnknown_iface.lpVtbl = (IUnknownVtbl*)&DirectSoundFullDuplex_Unknown_Vtbl;
496 This->IDirectSound8_iface.lpVtbl = (IDirectSound8Vtbl*)&DirectSoundFullDuplex_DirectSound8_Vtbl;
497 This->IDirectSoundCapture_iface.lpVtbl = (IDirectSoundCaptureVtbl*)&DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
499 This->all_ref = This->ref = 1;
500 This->unkref = 0;
501 This->ds8ref = 0;
502 This->dscref = 0;
504 This->capture_device = NULL;
505 This->renderer_device = NULL;
507 *ppDSFD = &This->IDirectSoundFullDuplex_iface;
508 return DS_OK;
511 /***************************************************************************
512 * DirectSoundFullDuplexCreate [DSOUND.10]
514 * Create and initialize a DirectSoundFullDuplex interface.
516 * PARAMS
517 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
518 * pcGuidRenderDevice [I] Address of sound render device GUID.
519 * pcDSCBufferDesc [I] Address of capture buffer description.
520 * pcDSBufferDesc [I] Address of render buffer description.
521 * hWnd [I] Handle to application window.
522 * dwLevel [I] Cooperative level.
523 * ppDSFD [O] Address where full duplex interface returned.
524 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
525 * ppDSBuffer8 [0] Address where render buffer interface returned.
526 * pUnkOuter [I] Must be NULL.
528 * RETURNS
529 * Success: DS_OK
530 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
531 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
533 HRESULT WINAPI
534 DirectSoundFullDuplexCreate(
535 LPCGUID pcGuidCaptureDevice, LPCGUID pcGuidRenderDevice,
536 LPCDSCBUFFERDESC pcDSCBufferDesc, LPCDSBUFFERDESC pcDSBufferDesc,
537 HWND hWnd, DWORD dwLevel,
538 IDirectSoundFullDuplex **ppDSFD,
539 IDirectSoundCaptureBuffer8 **ppDSCBuffer8,
540 IDirectSoundBuffer8 **ppDSBuffer8,
541 IUnknown *pUnkOuter)
543 void *iface = NULL;
544 HRESULT hres;
546 TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n",
547 debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
548 pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
549 ppDSBuffer8, pUnkOuter);
551 if(ppDSFD == NULL)
553 WARN("invalid parameter: ppDSFD == NULL\n");
554 return DSERR_INVALIDPARAM;
556 *ppDSFD = NULL;
558 if(pUnkOuter)
560 WARN("pUnkOuter != 0\n");
561 return DSERR_NOAGGREGATION;
564 if(pcDSCBufferDesc == NULL)
566 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
567 return DSERR_INVALIDPARAM;
570 if(pcDSBufferDesc == NULL)
572 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
573 return DSERR_INVALIDPARAM;
577 if(ppDSCBuffer8 == NULL)
579 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
580 return DSERR_INVALIDPARAM;
583 if(ppDSBuffer8 == NULL)
585 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
586 return DSERR_INVALIDPARAM;
589 hres = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, &iface);
590 if(FAILED(hres)) return hres;
592 *ppDSFD = iface;
593 hres = IDirectSoundFullDuplexImpl_Initialize(*ppDSFD,
594 pcGuidCaptureDevice,
595 pcGuidRenderDevice,
596 pcDSCBufferDesc,
597 pcDSBufferDesc,
598 hWnd, dwLevel,
599 ppDSCBuffer8,
600 ppDSBuffer8);
601 if(hres != DS_OK)
603 IDirectSoundFullDuplex_Release(*ppDSFD);
604 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
605 *ppDSFD = NULL;
608 return hres;