Added CSIDL_MYVIDEO|MYPICTURES|MYMUSIC to _SHRegisterUserShellFolders.
[wine] / dlls / dsound / duplex.c
1 /*              DirectSoundFullDuplex
2  *
3  * Copyright 1998 Marcus Meissner
4  * Copyright 1998 Rob Riggs
5  * Copyright 2000-2001 TransGaming Technologies, Inc.
6  * Copyright 2005 Robert Reif
7  *
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.
12  *
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.
17  *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 /*
23  * TODO:
24  *      Implement DirectSoundFullDuplex support.
25  */
26
27 #include <stdarg.h>
28
29 #define NONAMELESSSTRUCT
30 #define NONAMELESSUNION
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "mmsystem.h"
35 #include "mmddk.h"
36 #include "winreg.h"
37 #include "winternl.h"
38 #include "winnls.h"
39 #include "wine/debug.h"
40 #include "dsound.h"
41 #include "dsdriver.h"
42 #include "dsound_private.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
45
46 static HRESULT WINAPI
47 IDirectSoundFullDuplexImpl_QueryInterface(
48     LPDIRECTSOUNDFULLDUPLEX iface,
49     REFIID riid,
50     LPVOID* ppobj )
51 {
52     IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
53     TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
54
55     if (ppobj == NULL) {
56         WARN("invalid parameter\n");
57         return E_INVALIDARG;
58     }
59
60     *ppobj = NULL;
61     return E_NOINTERFACE;
62 }
63
64 static ULONG WINAPI
65 IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
66 {
67     IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
68     ULONG ref = InterlockedIncrement(&(This->ref));
69     TRACE("(%p) ref was %ld\n", This, ref - 1);
70     return ref;
71 }
72
73 static ULONG WINAPI
74 IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface )
75 {
76     IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
77     ULONG ref = InterlockedDecrement(&(This->ref));
78     TRACE("(%p) ref was %ld\n", This, ref - 1);
79
80     if (!ref) {
81         HeapFree( GetProcessHeap(), 0, This );
82         TRACE("(%p) released\n", This);
83     }
84     return ref;
85 }
86
87 static HRESULT WINAPI
88 IDirectSoundFullDuplexImpl_Initialize(
89     LPDIRECTSOUNDFULLDUPLEX iface,
90     LPCGUID pCaptureGuid,
91     LPCGUID pRendererGuid,
92     LPCDSCBUFFERDESC lpDscBufferDesc,
93     LPCDSBUFFERDESC lpDsBufferDesc,
94     HWND hWnd,
95     DWORD dwLevel,
96     LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
97     LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
98 {
99     IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
100     IDirectSoundCaptureBufferImpl** ippdscb=(IDirectSoundCaptureBufferImpl**)lplpDirectSoundCaptureBuffer8;
101     IDirectSoundBufferImpl** ippdsc=(IDirectSoundBufferImpl**)lplpDirectSoundBuffer8;
102
103     FIXME( "(%p,%s,%s,%p,%p,%p,%lx,%p,%p) stub!\n", This, debugstr_guid(pCaptureGuid),
104         debugstr_guid(pRendererGuid), lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
105         ippdscb, ippdsc);
106
107     return E_FAIL;
108 }
109
110 static const IDirectSoundFullDuplexVtbl dsfdvt =
111 {
112     /* IUnknown methods */
113     IDirectSoundFullDuplexImpl_QueryInterface,
114     IDirectSoundFullDuplexImpl_AddRef,
115     IDirectSoundFullDuplexImpl_Release,
116
117     /* IDirectSoundFullDuplex methods */
118     IDirectSoundFullDuplexImpl_Initialize
119 };
120
121 /***************************************************************************
122  * DirectSoundFullDuplexCreate [DSOUND.10]
123  *
124  * Create and initialize a DirectSoundFullDuplex interface.
125  *
126  * PARAMS
127  *    pcGuidCaptureDevice [I] Address of sound capture device GUID.
128  *    pcGuidRenderDevice  [I] Address of sound render device GUID.
129  *    pcDSCBufferDesc     [I] Address of capture buffer description.
130  *    pcDSBufferDesc      [I] Address of  render buffer description.
131  *    hWnd                [I] Handle to application window.
132  *    dwLevel             [I] Cooperative level.
133  *    ppDSFD              [O] Address where full duplex interface returned.
134  *    ppDSCBuffer8        [0] Address where capture buffer interface returned.
135  *    ppDSBuffer8         [0] Address where render buffer interface returned.
136  *    pUnkOuter           [I] Must be NULL.
137  *
138  * RETURNS
139  *    Success: DS_OK
140  *    Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
141  *             DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
142  */
143 HRESULT WINAPI
144 DirectSoundFullDuplexCreate(
145     LPCGUID pcGuidCaptureDevice,
146     LPCGUID pcGuidRenderDevice,
147     LPCDSCBUFFERDESC pcDSCBufferDesc,
148     LPCDSBUFFERDESC pcDSBufferDesc,
149     HWND hWnd,
150     DWORD dwLevel,
151     LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
152     LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
153     LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
154     LPUNKNOWN pUnkOuter)
155 {
156     IDirectSoundFullDuplexImpl** ippDSFD=(IDirectSoundFullDuplexImpl**)ppDSFD;
157     TRACE("(%s,%s,%p,%p,%p,%lx,%p,%p,%p,%p)\n", debugstr_guid(pcGuidCaptureDevice),
158         debugstr_guid(pcGuidRenderDevice), pcDSCBufferDesc, pcDSBufferDesc,
159         hWnd, dwLevel, ppDSFD, ppDSCBuffer8, ppDSBuffer8, pUnkOuter);
160
161     if ( pUnkOuter ) {
162         WARN("pUnkOuter != 0\n");
163         return DSERR_NOAGGREGATION;
164     }
165
166     *ippDSFD = HeapAlloc(GetProcessHeap(),
167         HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
168
169     if (*ippDSFD == NULL) {
170         WARN("out of memory\n");
171         return DSERR_OUTOFMEMORY;
172     } else {
173         HRESULT hres;
174         IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)*ippDSFD;
175
176         This->ref = 1;
177         This->lpVtbl = &dsfdvt;
178
179         hres = IDirectSoundFullDuplexImpl_Initialize( (LPDIRECTSOUNDFULLDUPLEX)This,
180                                                       pcGuidCaptureDevice, pcGuidRenderDevice,
181                                                       pcDSCBufferDesc, pcDSBufferDesc,
182                                                       hWnd, dwLevel, ppDSCBuffer8, ppDSBuffer8);
183         if (hres != DS_OK)
184             WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
185         return hres;
186     }
187 }
188
189 /*******************************************************************************
190  * DirectSoundFullDuplex ClassFactory
191  */
192
193 static HRESULT WINAPI
194 DSFDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
195 {
196     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
197
198     FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
199     return E_NOINTERFACE;
200 }
201
202 static ULONG WINAPI
203 DSFDCF_AddRef(LPCLASSFACTORY iface)
204 {
205     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
206     TRACE("(%p) ref was %ld\n", This, This->ref);
207     return InterlockedIncrement(&(This->ref));
208 }
209
210 static ULONG WINAPI
211 DSFDCF_Release(LPCLASSFACTORY iface)
212 {
213     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
214     /* static class, won't be  freed */
215     TRACE("(%p) ref was %ld\n", This, This->ref);
216     return InterlockedDecrement(&(This->ref));
217 }
218
219 static HRESULT WINAPI
220 DSFDCF_CreateInstance(
221     LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj )
222 {
223     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
224
225     TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
226
227     if (pOuter) {
228         WARN("aggregation not supported\n");
229         return CLASS_E_NOAGGREGATION;
230     }
231
232     if (ppobj == NULL) {
233         WARN("invalid parameter\n");
234         return E_INVALIDARG;
235     }
236
237     *ppobj = NULL;
238
239     if ( IsEqualGUID( &IID_IDirectSoundFullDuplex, riid ) ) {
240         /* FIXME: how do we do this one ? */
241         FIXME("not implemented\n");
242         return E_NOINTERFACE;
243     }
244
245     WARN("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj); 
246     return E_NOINTERFACE;
247 }
248
249 static HRESULT WINAPI
250 DSFDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
251 {
252     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
253     FIXME("(%p)->(%d),stub!\n",This,dolock);
254     return S_OK;
255 }
256
257 static const IClassFactoryVtbl DSFDCF_Vtbl =
258 {
259     DSFDCF_QueryInterface,
260     DSFDCF_AddRef,
261     DSFDCF_Release,
262     DSFDCF_CreateInstance,
263     DSFDCF_LockServer
264 };
265
266 IClassFactoryImpl DSOUND_FULLDUPLEX_CF = { &DSFDCF_Vtbl, 1 };