Fix an errant WINELESS check
[dsound-openal.git] / duplex.c
bloba1cec78b32a507ca8dea1f5a71fb3d81e7258c0d
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;
65 LONG unkref;
66 LONG ds8ref;
67 LONG dscref;
69 /* IDirectSoundFullDuplexImpl fields */
70 IDirectSound8 *renderer_device;
71 IDirectSoundCapture *capture_device;
72 } IDirectSoundFullDuplexImpl;
75 static void DSOUND_FullDuplexDestroy(IDirectSoundFullDuplexImpl *This)
77 if (This->capture_device)
78 IDirectSoundCapture_Release(This->capture_device);
79 if (This->renderer_device)
80 IDirectSound_Release(This->renderer_device);
81 HeapFree(GetProcessHeap(), 0, This);
82 TRACE("(%p) released\n", This);
85 /*******************************************************************************
86 * IUnknown
88 static inline IDirectSoundFullDuplexImpl *impl_from_IUnknown(IUnknown *iface)
90 return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IUnknown_iface);
93 static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
94 IUnknown *iface,
95 REFIID riid,
96 LPVOID *ppobj)
98 IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
99 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
100 return IDirectSoundFullDuplex_QueryInterface(&This->IDirectSoundFullDuplex_iface, riid, ppobj);
103 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_AddRef(IUnknown *iface)
105 IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
106 ULONG ref = InterlockedIncrement(&(This->unkref));
107 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 (!This->ref && !This->unkref && !This->ds8ref && !This->dscref)
117 DSOUND_FullDuplexDestroy(This);
118 return ref;
121 static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl =
123 IDirectSoundFullDuplex_IUnknown_QueryInterface,
124 IDirectSoundFullDuplex_IUnknown_AddRef,
125 IDirectSoundFullDuplex_IUnknown_Release
128 /*******************************************************************************
129 * IDirectSoundFullDuplex_IDirectSound8
131 static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSound8(IDirectSound8 *iface)
133 return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSound8_iface);
136 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
137 IDirectSound8 *iface,
138 REFIID riid,
139 LPVOID *ppobj)
141 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
142 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
143 return IDirectSoundFullDuplex_QueryInterface(&This->IDirectSoundFullDuplex_iface, riid, ppobj);
146 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_AddRef(IDirectSound8 *iface)
148 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
149 ULONG ref = InterlockedIncrement(&(This->ds8ref));
150 TRACE("(%p) ref was %d\n", This, ref - 1);
151 return ref;
154 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_Release(IDirectSound8 *iface)
156 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
157 ULONG ref = InterlockedDecrement(&(This->ds8ref));
158 TRACE("(%p) ref was %d\n", This, ref + 1);
159 if (!This->ref && !This->unkref && !This->ds8ref && !This->dscref)
160 DSOUND_FullDuplexDestroy(This);
161 return ref;
164 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
165 IDirectSound8 *iface,
166 LPCDSBUFFERDESC dsbd,
167 IDirectSoundBuffer **ppdsb,
168 IUnknown *lpunk)
170 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
171 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
172 return IDirectSound8_CreateSoundBuffer(This->renderer_device,dsbd,ppdsb,lpunk);
175 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetCaps(
176 IDirectSound8 *iface,
177 DSCAPS *lpDSCaps)
179 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
180 TRACE("(%p,%p)\n",This,lpDSCaps);
181 return IDirectSound8_GetCaps(This->renderer_device, lpDSCaps);
184 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
185 IDirectSound8 *iface,
186 IDirectSoundBuffer *psb,
187 IDirectSoundBuffer **ppdsb)
189 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
190 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
191 return IDirectSound8_DuplicateSoundBuffer(This->renderer_device,psb,ppdsb);
194 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
195 IDirectSound8 *iface,
196 HWND hwnd,
197 DWORD level)
199 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
200 TRACE("(%p,%p,%u)\n",This,hwnd,level);
201 return IDirectSound8_SetCooperativeLevel(This->renderer_device,hwnd,level);
204 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Compact(IDirectSound8 *iface)
206 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
207 TRACE("(%p)\n", This);
208 return IDirectSound8_Compact(This->renderer_device);
211 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
212 IDirectSound8 *iface,
213 DWORD *lpdwSpeakerConfig)
215 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
216 TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
217 return IDirectSound8_GetSpeakerConfig(This->renderer_device,lpdwSpeakerConfig);
220 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
221 IDirectSound8 *iface,
222 DWORD config)
224 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
225 TRACE("(%p,0x%08x)\n",This,config);
226 return IDirectSound8_SetSpeakerConfig(This->renderer_device,config);
229 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Initialize(
230 IDirectSound8 *iface,
231 LPCGUID lpcGuid)
233 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
234 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
235 return IDirectSound8_Initialize(This->renderer_device,lpcGuid);
238 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_VerifyCertification(
239 IDirectSound8 *iface,
240 DWORD *cert)
242 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSound8(iface);
243 TRACE("(%p, %p)\n", This, cert);
244 return IDirectSound8_VerifyCertification(This->renderer_device,cert);
247 static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl =
249 IDirectSoundFullDuplex_IDirectSound8_QueryInterface,
250 IDirectSoundFullDuplex_IDirectSound8_AddRef,
251 IDirectSoundFullDuplex_IDirectSound8_Release,
252 IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer,
253 IDirectSoundFullDuplex_IDirectSound8_GetCaps,
254 IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer,
255 IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel,
256 IDirectSoundFullDuplex_IDirectSound8_Compact,
257 IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig,
258 IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig,
259 IDirectSoundFullDuplex_IDirectSound8_Initialize,
260 IDirectSoundFullDuplex_IDirectSound8_VerifyCertification
263 /*******************************************************************************
264 * IDirectSoundFullDuplex_IDirectSoundCapture
266 static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSoundCapture(IDirectSoundCapture *iface)
268 return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSoundCapture_iface);
271 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
272 IDirectSoundCapture *iface,
273 REFIID riid,
274 LPVOID *ppobj)
276 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
277 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
278 return IDirectSoundFullDuplex_QueryInterface(&This->IDirectSoundFullDuplex_iface, riid, ppobj);
281 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(IDirectSoundCapture *iface)
283 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
284 ULONG ref = InterlockedIncrement(&(This->dscref));
285 TRACE("(%p) ref was %d\n", This, ref - 1);
286 return ref;
289 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release(IDirectSoundCapture *iface)
291 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
292 ULONG ref = InterlockedDecrement(&(This->dscref));
293 TRACE("(%p) ref was %d\n", This, ref + 1);
294 if (!This->ref && !This->unkref && !This->ds8ref && !This->dscref)
295 DSOUND_FullDuplexDestroy(This);
296 return ref;
299 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
300 IDirectSoundCapture *iface,
301 LPCDSCBUFFERDESC lpcDSCBufferDesc,
302 IDirectSoundCaptureBuffer **lplpDSCaptureBuffer,
303 IUnknown *pUnk)
305 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
306 TRACE("(%p, %p, %p, %p)\n", This, lpcDSCBufferDesc, lplpDSCaptureBuffer, pUnk);
307 return IDirectSoundCapture_CreateCaptureBuffer(This->capture_device,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
310 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
311 IDirectSoundCapture *iface,
312 LPDSCCAPS lpDSCCaps)
314 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
315 TRACE("(%p, %p)\n", This, lpDSCCaps);
316 return IDirectSoundCapture_GetCaps(This->capture_device, lpDSCCaps);
319 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
320 IDirectSoundCapture *iface,
321 LPCGUID lpcGUID)
323 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundCapture(iface);
324 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGUID));
325 return IDirectSoundCapture_Initialize(This->capture_device,lpcGUID);
328 static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl =
330 IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface,
331 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef,
332 IDirectSoundFullDuplex_IDirectSoundCapture_Release,
333 IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer,
334 IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps,
335 IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
338 /***************************************************************************
339 * IDirectSoundFullDuplexImpl
341 static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSoundFullDuplex(IDirectSoundFullDuplex *iface)
343 return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSoundFullDuplex_iface);
346 static HRESULT WINAPI IDirectSoundFullDuplexImpl_QueryInterface(
347 IDirectSoundFullDuplex *iface, REFIID riid, LPVOID *ppobj)
349 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
350 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
352 if (ppobj == NULL) {
353 WARN("invalid parameter\n");
354 return E_INVALIDARG;
357 *ppobj = NULL;
359 if (IsEqualIID(riid, &IID_IUnknown)) {
360 *ppobj = &This->IUnknown_iface;
361 IUnknown_AddRef((IUnknown*)*ppobj);
362 return S_OK;
363 } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
364 *ppobj = &This->IDirectSoundFullDuplex_iface;
365 IUnknown_AddRef((IUnknown*)*ppobj);
366 return S_OK;
367 } else if (IsEqualIID(riid, &IID_IDirectSound) ||
368 IsEqualIID(riid, &IID_IDirectSound8)) {
369 *ppobj = &This->IDirectSound8_iface;
370 IUnknown_AddRef((IUnknown*)*ppobj);
371 return S_OK;
372 } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
373 *ppobj = &This->IDirectSoundCapture_iface;
374 IUnknown_AddRef((IUnknown*)*ppobj);
375 return S_OK;
378 return E_NOINTERFACE;
381 static ULONG WINAPI IDirectSoundFullDuplexImpl_AddRef(IDirectSoundFullDuplex *iface)
383 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
384 ULONG ref = InterlockedIncrement(&(This->ref));
385 TRACE("(%p) ref was %d\n", This, ref - 1);
386 return ref;
389 static ULONG WINAPI IDirectSoundFullDuplexImpl_Release(IDirectSoundFullDuplex *iface)
391 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
392 ULONG ref = InterlockedDecrement(&(This->ref));
393 TRACE("(%p) ref was %d\n", This, ref - 1);
394 if (!This->ref && !This->unkref && !This->ds8ref && !This->dscref)
395 DSOUND_FullDuplexDestroy(This);
396 return ref;
399 static HRESULT WINAPI IDirectSoundFullDuplexImpl_Initialize(
400 IDirectSoundFullDuplex *iface,
401 LPCGUID pCaptureGuid,
402 LPCGUID pRendererGuid,
403 LPCDSCBUFFERDESC lpDscBufferDesc,
404 LPCDSBUFFERDESC lpDsBufferDesc,
405 HWND hWnd,
406 DWORD dwLevel,
407 IDirectSoundCaptureBuffer8 **lplpDirectSoundCaptureBuffer8,
408 IDirectSoundBuffer8 **lplpDirectSoundBuffer8)
410 HRESULT hr;
411 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
413 TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This,
414 debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
415 lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
416 lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);
418 if (This->renderer_device != NULL || This->capture_device != NULL) {
419 WARN("already initialized\n");
420 *lplpDirectSoundCaptureBuffer8 = NULL;
421 *lplpDirectSoundBuffer8 = NULL;
422 return DSERR_ALREADYINITIALIZED;
425 hr = DSOUND_Create8(&IID_IDirectSound8, (void**)&This->renderer_device);
426 if (SUCCEEDED(hr))
427 hr = IDirectSound_Initialize(This->renderer_device, pRendererGuid);
428 if (hr != DS_OK) {
429 WARN("DirectSoundDevice_Initialize() failed\n");
430 *lplpDirectSoundCaptureBuffer8 = NULL;
431 *lplpDirectSoundBuffer8 = NULL;
432 return hr;
435 IDirectSound8_SetCooperativeLevel(This->renderer_device, hWnd, dwLevel);
437 hr = IDirectSound8_CreateSoundBuffer(This->renderer_device, lpDsBufferDesc,
438 (IDirectSoundBuffer**)lplpDirectSoundBuffer8, NULL);
439 if (hr != DS_OK) {
440 WARN("IDirectSoundBufferImpl_Create() failed\n");
441 *lplpDirectSoundCaptureBuffer8 = NULL;
442 *lplpDirectSoundBuffer8 = NULL;
443 return hr;
446 hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &This->capture_device);
447 if (SUCCEEDED(hr))
448 hr = IDirectSoundCapture_Initialize(This->capture_device, pCaptureGuid);
449 if (hr != DS_OK) {
450 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
451 *lplpDirectSoundCaptureBuffer8 = NULL;
452 *lplpDirectSoundBuffer8 = NULL;
453 return hr;
456 hr = IDirectSoundCapture_CreateCaptureBuffer(This->capture_device,
457 lpDscBufferDesc,
458 (IDirectSoundCaptureBuffer**)lplpDirectSoundCaptureBuffer8,
459 NULL);
460 if (hr != DS_OK) {
461 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
462 *lplpDirectSoundCaptureBuffer8 = NULL;
463 *lplpDirectSoundBuffer8 = NULL;
464 return hr;
467 return hr;
470 static const IDirectSoundFullDuplexVtbl dsfdvt =
472 /* IUnknown methods */
473 IDirectSoundFullDuplexImpl_QueryInterface,
474 IDirectSoundFullDuplexImpl_AddRef,
475 IDirectSoundFullDuplexImpl_Release,
477 /* IDirectSoundFullDuplex methods */
478 IDirectSoundFullDuplexImpl_Initialize
481 HRESULT DSOUND_FullDuplexCreate(
482 REFIID riid,
483 LPDIRECTSOUNDFULLDUPLEX* ppDSFD)
485 IDirectSoundFullDuplexImpl *This = NULL;
486 TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSFD);
488 if (ppDSFD == NULL) {
489 WARN("invalid parameter: ppDSFD == NULL\n");
490 return DSERR_INVALIDPARAM;
493 if (!IsEqualIID(riid, &IID_IUnknown) &&
494 !IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
495 *ppDSFD = 0;
496 return E_NOINTERFACE;
499 This = HeapAlloc(GetProcessHeap(),
500 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
502 if (This == NULL) {
503 WARN("out of memory\n");
504 *ppDSFD = NULL;
505 return DSERR_OUTOFMEMORY;
508 This->IDirectSoundFullDuplex_iface.lpVtbl = &dsfdvt;
509 This->IUnknown_iface.lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
510 This->IDirectSound8_iface.lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
511 This->IDirectSoundCapture_iface.lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
512 This->ref = 1;
513 This->unkref = 0;
514 This->ds8ref = 0;
515 This->dscref = 0;
517 This->capture_device = NULL;
518 This->renderer_device = NULL;
520 *ppDSFD = &This->IDirectSoundFullDuplex_iface;
522 return DS_OK;
525 /***************************************************************************
526 * DirectSoundFullDuplexCreate [DSOUND.10]
528 * Create and initialize a DirectSoundFullDuplex interface.
530 * PARAMS
531 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
532 * pcGuidRenderDevice [I] Address of sound render device GUID.
533 * pcDSCBufferDesc [I] Address of capture buffer description.
534 * pcDSBufferDesc [I] Address of render buffer description.
535 * hWnd [I] Handle to application window.
536 * dwLevel [I] Cooperative level.
537 * ppDSFD [O] Address where full duplex interface returned.
538 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
539 * ppDSBuffer8 [0] Address where render buffer interface returned.
540 * pUnkOuter [I] Must be NULL.
542 * RETURNS
543 * Success: DS_OK
544 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
545 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
547 HRESULT WINAPI
548 DirectSoundFullDuplexCreate(
549 LPCGUID pcGuidCaptureDevice,
550 LPCGUID pcGuidRenderDevice,
551 LPCDSCBUFFERDESC pcDSCBufferDesc,
552 LPCDSBUFFERDESC pcDSBufferDesc,
553 HWND hWnd,
554 DWORD dwLevel,
555 IDirectSoundFullDuplex **ppDSFD,
556 IDirectSoundCaptureBuffer8 **ppDSCBuffer8,
557 IDirectSoundBuffer8 **ppDSBuffer8,
558 IUnknown *pUnkOuter)
560 HRESULT hres;
561 IDirectSoundFullDuplex *iface = NULL;
563 TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n",
564 debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
565 pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
566 ppDSBuffer8, pUnkOuter);
568 if (pUnkOuter) {
569 WARN("pUnkOuter != 0\n");
570 *ppDSFD = NULL;
571 return DSERR_NOAGGREGATION;
574 if (pcDSCBufferDesc == NULL) {
575 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
576 *ppDSFD = NULL;
577 return DSERR_INVALIDPARAM;
580 if (pcDSBufferDesc == NULL) {
581 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
582 *ppDSFD = NULL;
583 return DSERR_INVALIDPARAM;
586 if (ppDSFD == NULL) {
587 WARN("invalid parameter: ppDSFD == NULL\n");
588 return DSERR_INVALIDPARAM;
591 if (ppDSCBuffer8 == NULL) {
592 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
593 *ppDSFD = NULL;
594 return DSERR_INVALIDPARAM;
597 if (ppDSBuffer8 == NULL) {
598 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
599 *ppDSFD = NULL;
600 return DSERR_INVALIDPARAM;
603 hres = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, &iface);
604 if (FAILED(hres)) return hres;
606 hres = IDirectSoundFullDuplexImpl_Initialize(iface,
607 pcGuidCaptureDevice,
608 pcGuidRenderDevice,
609 pcDSCBufferDesc,
610 pcDSBufferDesc,
611 hWnd, dwLevel, ppDSCBuffer8,
612 ppDSBuffer8);
613 if (hres != DS_OK) {
614 IDirectSoundFullDuplex_Release(iface);
615 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
616 *ppDSFD = NULL;
617 } else
618 *ppDSFD = iface;
620 return hres;