ReactOS  0.4.14-dev-114-gc8cbd56
directsound.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Configuration of network devices
4  * FILE: dll/directx/dsound_new/directsound.c
5  * PURPOSE: Handles IDirectSound interface
6  *
7  * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
8  */
9 
10 #include "precomp.h"
11 
12 typedef struct
13 {
14  IDirectSound8Vtbl *lpVtbl;
22 
23 
25 
26 HRESULT
27 WINAPI
29  LPDIRECTSOUND8 iface,
30  REFIID riid,
31  LPVOID * ppobj)
32 {
33  LPOLESTR pStr;
35 
36  if ((IsEqualIID(riid, &IID_IDirectSound) && This->bDirectSound8 == FALSE) ||
37  (IsEqualIID(riid, &IID_IDirectSound8) && This->bDirectSound8 != FALSE) ||
39  {
40  *ppobj = (LPVOID)&This->lpVtbl;
42  return S_OK;
43  }
44 
45  if (SUCCEEDED(StringFromIID(riid, &pStr)))
46  {
47  DPRINT("No Interface for class %s\n", pStr);
48  CoTaskMemFree(pStr);
49  }
50  return E_NOINTERFACE;
51 }
52 
53 ULONG
54 WINAPI
56  LPDIRECTSOUND8 iface)
57 {
58  ULONG ref;
60 
61  ref = InterlockedIncrement(&This->ref);
62 
63  return ref;
64 }
65 
66 ULONG
67 WINAPI
69  LPDIRECTSOUND8 iface)
70 {
71  ULONG ref;
73 
74  ref = InterlockedDecrement(&(This->ref));
75 
76  if (!ref)
77  {
79  }
80 
81  return ref;
82 }
83 
84 HRESULT
85 WINAPI
87  LPDIRECTSOUND8 iface,
88  LPCDSBUFFERDESC lpcDSBufferDesc,
89  LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer,
90  IUnknown FAR* pUnkOuter)
91 {
92  HRESULT hResult;
94 
95  if (!This->bInitialized)
96  {
97  /* object not yet initialized */
98  return DSERR_UNINITIALIZED;
99  }
100 
101  if (!lpcDSBufferDesc || !lplpDirectSoundBuffer || pUnkOuter != NULL)
102  {
103  DPRINT("Invalid parameter %p %p %p\n", lpcDSBufferDesc, lplpDirectSoundBuffer, pUnkOuter);
104  return DSERR_INVALIDPARAM;
105  }
106 
107  /* check buffer description */
108  if ((lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC) && lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC1)) || lpcDSBufferDesc->dwReserved != 0)
109  {
110  DPRINT("Invalid buffer description size %u expected %u dwReserved %u\n", lpcDSBufferDesc->dwSize, sizeof(DSBUFFERDESC1), lpcDSBufferDesc->dwReserved);
111  return DSERR_INVALIDPARAM;
112  }
113 
114  DPRINT("This %p dwFlags %x dwBufferBytes %u lpwfxFormat %p dwSize %u\n", This, lpcDSBufferDesc->dwFlags, lpcDSBufferDesc->dwBufferBytes, lpcDSBufferDesc->lpwfxFormat, lpcDSBufferDesc->dwSize);
115 
116  if (lpcDSBufferDesc->dwFlags & DSBCAPS_PRIMARYBUFFER)
117  {
118  if (lpcDSBufferDesc->lpwfxFormat != NULL)
119  {
120  /* format must be null for primary sound buffer */
121  return DSERR_INVALIDPARAM;
122  }
123 
124  if (lpcDSBufferDesc->dwBufferBytes != 0)
125  {
126  /* buffer size must be zero for primary sound buffer */
127  return DSERR_INVALIDPARAM;
128  }
129 
130  if (This->PrimaryBuffer)
131  {
132  /* primary buffer already exists */
133  IDirectSoundBuffer8_AddRef(This->PrimaryBuffer);
134  *lplpDirectSoundBuffer = (LPDIRECTSOUNDBUFFER)This->PrimaryBuffer;
135  return S_OK;
136  }
137 
138  hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc->dwFlags);
139  if (SUCCEEDED(hResult))
140  {
141  /* store primary buffer */
142  This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer;
143  }
144  return hResult;
145  }
146  else
147  {
148  if (lpcDSBufferDesc->lpwfxFormat == NULL)
149  {
150  /* format must not be null */
151  return DSERR_INVALIDPARAM;
152  }
153 
154  if (lpcDSBufferDesc->dwBufferBytes < DSBSIZE_MIN || lpcDSBufferDesc->dwBufferBytes > DSBSIZE_MAX)
155  {
156  /* buffer size must be within bounds for secondary sound buffer*/
157  return DSERR_INVALIDPARAM;
158  }
159 
160  if (!This->PrimaryBuffer)
161  {
162  hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc->dwFlags);
163  if (SUCCEEDED(hResult))
164  {
165  /* store primary buffer */
166  This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer;
167  }
168  else
169  {
170  DPRINT("Failed to create primary buffer with %x\n", hResult);
171  return hResult;
172  }
173 
174  }
175 
176  ASSERT(This->PrimaryBuffer);
177 
178  DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n",
179  This, lpcDSBufferDesc->lpwfxFormat->wFormatTag, lpcDSBufferDesc->lpwfxFormat->nChannels, lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec, lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec, lpcDSBufferDesc->lpwfxFormat->nBlockAlign, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample, lpcDSBufferDesc->lpwfxFormat->cbSize);
180 
181  hResult = NewSecondarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc, This->PrimaryBuffer);
182  return hResult;
183  }
184 }
185 
186 HRESULT
187 WINAPI
189  LPDIRECTSOUND8 iface,
190  LPDSCAPS lpDSCaps)
191 {
193 
194  if (!This->bInitialized)
195  {
196  /* object not yet initialized */
197  return DSERR_UNINITIALIZED;
198  }
199 
200  if (!lpDSCaps)
201  {
202  /* object not yet initialized */
203  return DSERR_INVALIDPARAM;
204  }
205 
206  if (lpDSCaps->dwSize != sizeof(DSCAPS))
207  {
208  /* object not yet initialized */
209  return DSERR_INVALIDPARAM;
210  }
211 
213  return DSERR_GENERIC;
214 }
215 
216 HRESULT
217 WINAPI
219  LPDIRECTSOUND8 iface,
220  LPDIRECTSOUNDBUFFER lpDsbOriginal,
221  LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate)
222 {
224  return DSERR_OUTOFMEMORY;
225 }
226 
227 HRESULT
228 WINAPI
230  LPDIRECTSOUND8 iface,
231  HWND hwnd,
232  DWORD dwLevel)
233 {
235 
236  if (!This->bInitialized)
237  {
238  /* object not yet initialized */
239  return DSERR_UNINITIALIZED;
240  }
241 
242  /* store cooperation level */
243  This->dwLevel = dwLevel;
244  return DS_OK;
245 }
246 
247 HRESULT
248 WINAPI
250  LPDIRECTSOUND8 iface)
251 {
253 
254  if (!This->bInitialized)
255  {
256  /* object not yet initialized */
257  return DSERR_UNINITIALIZED;
258  }
259 
260  if (This->dwLevel != DSSCL_PRIORITY)
261  {
262  /* needs priority level */
263  return DSERR_PRIOLEVELNEEDED;
264  }
265 
266  /* done */
267  return DS_OK;
268 }
269 
270 HRESULT
271 WINAPI
273  LPDIRECTSOUND8 iface,
274  LPDWORD pdwSpeakerConfig)
275 {
277 
278  if (!This->bInitialized)
279  {
280  /* object not yet initialized */
281  return DSERR_UNINITIALIZED;
282  }
283 
284 
286  return DSERR_INVALIDPARAM;
287 }
288 
289 HRESULT
290 WINAPI
292  LPDIRECTSOUND8 iface,
293  DWORD dwSpeakerConfig)
294 {
296  return DSERR_INVALIDPARAM;
297 }
298 
299 
300 HRESULT
301 WINAPI
303  LPDIRECTSOUND8 iface,
304  LPCGUID pcGuidDevice)
305 {
306  GUID DeviceGuid;
307  LPOLESTR pGuidStr;
308  HRESULT hr;
310 
311  if (!RootInfo)
312  {
314  }
315 
316  /* sanity check */
317  ASSERT(RootInfo);
318 
319  if (This->bInitialized)
320  {
321  /* object has already been initialized */
323  }
324 
325  /* fixme mutual exclusion */
326 
327  if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL))
328  {
329  /* use default playback device id */
330  pcGuidDevice = &DSDEVID_DefaultPlayback;
331  }
332 
333  if (IsEqualIID(pcGuidDevice, &DSDEVID_DefaultCapture) || IsEqualIID(pcGuidDevice, &DSDEVID_DefaultVoiceCapture))
334  {
335  /* this has to be a winetest */
336  return DSERR_NODRIVER;
337  }
338 
339  /* now verify the guid */
340  if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK)
341  {
342  if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr)))
343  {
344  DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr);
345  CoTaskMemFree(pGuidStr);
346  }
347  return DSERR_INVALIDPARAM;
348  }
349 
350  hr = FindDeviceByGuid(&DeviceGuid, &This->Filter);
351 
352  if (SUCCEEDED(hr))
353  {
354  This->bInitialized = TRUE;
355  return DS_OK;
356  }
357 
358  DPRINT("Failed to find device\n");
359  return DSERR_INVALIDPARAM;
360 }
361 
362 HRESULT
363 WINAPI
365  LPDIRECTSOUND8 iface,
366  LPDWORD pdwCertified)
367 {
369 
370  if (!This->bInitialized)
371  {
372  /* object not yet initialized */
373  return DSERR_UNINITIALIZED;
374  }
375 
377  return DS_CERTIFIED;
378 }
379 
380 static IDirectSound8Vtbl vt_DirectSound8 =
381 {
382  /* IUnknown methods */
386  /* IDirectSound methods */
395  /* IDirectSound8 methods */
397 };
398 
399 HRESULT
401  LPCGUID lpcGUID,
402  LPDIRECTSOUND8 *ppDS,
403  IUnknown *pUnkOuter,
404  BOOL bDirectSound8)
405 {
407  HRESULT hr;
408 
409  if (!ppDS || pUnkOuter != NULL)
410  {
411  /* invalid parameter passed */
412  return DSERR_INVALIDPARAM;
413  }
414 
415  /* allocate CDirectSoundImpl struct */
417  if (!This)
418  {
419  /* not enough memory */
420  return DSERR_OUTOFMEMORY;
421  }
422 
423  /* initialize IDirectSound object */
424  This->ref = 1;
425  This->bDirectSound8 = bDirectSound8;
426  This->lpVtbl = &vt_DirectSound8;
427 
428 
429  /* initialize direct sound interface */
430  hr = IDirectSound8_Initialize((LPDIRECTSOUND8)&This->lpVtbl, lpcGUID);
431 
432  /* check for success */
433  if (!SUCCEEDED(hr))
434  {
435  /* failed */
436  DPRINT("Failed to initialize DirectSound object with %x\n", hr);
438  return hr;
439  }
440 
441  /* store result */
442  *ppDS = (LPDIRECTSOUND8)&This->lpVtbl;
443  DPRINT("DirectSound object %p\n", *ppDS);
444  return DS_OK;
445 }
446 
447 HRESULT
448 CALLBACK
450  IUnknown* pUnkOuter,
451  REFIID riid,
452  LPVOID* ppvObject)
453 {
454  LPOLESTR pStr;
456 
457  /* check param */
458  if (!ppvObject)
459  {
460  /* invalid param */
461  return E_INVALIDARG;
462  }
463 
464  /* check requested interface */
465  if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IDirectSound) && !IsEqualIID(riid, &IID_IDirectSound8))
466  {
467  *ppvObject = 0;
468  StringFromIID(riid, &pStr);
469  DPRINT("KsPropertySet does not support Interface %ws\n", pStr);
470  CoTaskMemFree(pStr);
471  return E_NOINTERFACE;
472  }
473 
474  /* allocate CDirectSoundCaptureImpl struct */
476  if (!This)
477  {
478  /* not enough memory */
479  return DSERR_OUTOFMEMORY;
480  }
481 
482  /* initialize object */
483  This->ref = 1;
484  This->lpVtbl = &vt_DirectSound8;
485  This->bInitialized = FALSE;
486  *ppvObject = (LPVOID)&This->lpVtbl;
487 
488  return S_OK;
489 }
490 
491 
492 HRESULT
493 WINAPI
495  LPCGUID lpcGUID,
496  LPDIRECTSOUND *ppDS,
497  IUnknown *pUnkOuter)
498 {
499  return InternalDirectSoundCreate(lpcGUID, (LPDIRECTSOUND8*)ppDS, pUnkOuter, FALSE);
500 }
501 
502 HRESULT
503 WINAPI
505  LPCGUID lpcGUID,
506  LPDIRECTSOUND8 *ppDS,
507  IUnknown *pUnkOuter)
508 {
509  return InternalDirectSoundCreate(lpcGUID, ppDS, pUnkOuter, TRUE);
510 }
HRESULT EnumAudioDeviceInterfaces(LPFILTERINFO *OutRootInfo)
Definition: devicelist.c:384
struct IDirectSoundBuffer8 * LPDIRECTSOUNDBUFFER8
Definition: dsound.h:79
#define DSERR_GENERIC
Definition: dsound.h:123
HRESULT WINAPI IDirectSound8_fnSetCooperativeLevel(LPDIRECTSOUND8 iface, HWND hwnd, DWORD dwLevel)
Definition: directsound.c:229
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
ULONG WINAPI IDirectSound8_fnAddRef(LPDIRECTSOUND8 iface)
Definition: directsound.c:55
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID, LPDIRECTSOUND8 *ppDS, IUnknown *pUnkOuter)
Definition: directsound.c:504
DWORD dwSize
Definition: dsound.h:162
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
Definition: dsound.c:53
#define E_NOINTERFACE
Definition: winerror.h:2364
struct CDirectSoundImpl * LPCDirectSoundImpl
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
BOOL FindDeviceByGuid(LPCGUID pGuidSrc, LPFILTERINFO *Filter)
Definition: devicelist.c:470
HRESULT hr
Definition: shlfolder.c:183
REFIID riid
Definition: precomp.h:44
static IDirectSound8Vtbl vt_DirectSound8
Definition: directsound.c:380
HRESULT WINAPI DirectSoundCreate(LPCGUID lpcGUID, LPDIRECTSOUND *ppDS, IUnknown *pUnkOuter)
Definition: directsound.c:494
#define DSERR_UNINITIALIZED
Definition: dsound.h:133
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
WORD nChannels
Definition: mmreg.h:79
#define DSERR_ALREADYINITIALIZED
Definition: dsound.h:129
#define CALLBACK
Definition: compat.h:27
#define IDirectSoundBuffer8_AddRef(p)
Definition: dsound.h:659
HRESULT WINAPI IDirectSound8_fnGetSpeakerConfig(LPDIRECTSOUND8 iface, LPDWORD pdwSpeakerConfig)
Definition: directsound.c:272
HRESULT NewSecondarySoundBuffer(LPDIRECTSOUNDBUFFER8 *OutBuffer, LPFILTERINFO Filter, DWORD dwLevel, LPCDSBUFFERDESC lpcDSBufferDesc, LPDIRECTSOUNDBUFFER8 PrimaryBuffer)
Definition: secondary.c:611
HRESULT WINAPI IDirectSound8_fnCreateSoundBuffer(LPDIRECTSOUND8 iface, LPCDSBUFFERDESC lpcDSBufferDesc, LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer, IUnknown FAR *pUnkOuter)
Definition: directsound.c:86
HRESULT WINAPI IDirectSound8_fnGetCaps(LPDIRECTSOUND8 iface, LPDSCAPS lpDSCaps)
Definition: directsound.c:188
#define IDirectSound8_Release(p)
Definition: dsound.h:507
HRESULT InternalDirectSoundCreate(LPCGUID lpcGUID, LPDIRECTSOUND8 *ppDS, IUnknown *pUnkOuter, BOOL bDirectSound8)
Definition: directsound.c:400
static LPOLESTR
Definition: stg_prop.c:27
HRESULT WINAPI IDirectSound8_fnDuplicateSoundBuffer(LPDIRECTSOUND8 iface, LPDIRECTSOUNDBUFFER lpDsbOriginal, LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate)
Definition: directsound.c:218
Definition: send.c:47
HRESULT NewPrimarySoundBuffer(LPDIRECTSOUNDBUFFER8 *OutBuffer, LPFILTERINFO Filter, DWORD dwLevel, DWORD dwFlags)
Definition: primary.c:768
LPDIRECTSOUNDBUFFER8 PrimaryBuffer
Definition: directsound.c:21
#define DSERR_PRIOLEVELNEEDED
Definition: dsound.h:124
#define DS_CERTIFIED
Definition: dsound.h:326
struct IDirectSoundBuffer8 ** LPLPDIRECTSOUNDBUFFER8
Definition: dsound.h:79
HRESULT WINAPI IDirectSound8_fnSetSpeakerConfig(LPDIRECTSOUND8 iface, DWORD dwSpeakerConfig)
Definition: directsound.c:291
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define DSBSIZE_MAX
Definition: dsound.h:225
#define FAR
Definition: guiddef.h:36
GLenum GLint ref
Definition: glext.h:6028
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
#define DSERR_NODRIVER
Definition: dsound.h:128
struct IDirectSoundBuffer ** LPLPDIRECTSOUNDBUFFER
Definition: dsound.h:76
void DPRINT(...)
Definition: polytest.cpp:61
#define DSBSIZE_MIN
Definition: dsound.h:224
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Check_return_ HRESULT WINAPI StringFromIID(_In_ REFIID rclsid, _Outptr_ LPOLESTR *lplpsz)
#define DS_OK
Definition: dsound.h:116
#define DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:206
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD dwSize
Definition: dsound.h:288
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
LPWAVEFORMATEX lpwfxFormat
Definition: dsound.h:292
HRESULT WINAPI IDirectSound8_fnInitialize(LPDIRECTSOUND8 iface, LPCGUID pcGuidDevice)
Definition: directsound.c:302
#define LPVOID
Definition: nt_native.h:45
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
WORD wFormatTag
Definition: mmreg.h:78
#define InterlockedDecrement
Definition: armddk.h:52
struct IDirectSound8 * LPDIRECTSOUND8
Definition: dsound.h:73
LPFILTERINFO Filter
Definition: directsound.c:20
#define GUID_NULL
Definition: ks.h:106
REFIID LPVOID * ppvObject
Definition: precomp.h:44
HRESULT CALLBACK NewDirectSound(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppvObject)
Definition: directsound.c:449
struct IDirectSoundBuffer * LPDIRECTSOUNDBUFFER
Definition: dsound.h:76
LPFILTERINFO RootInfo
Definition: dsound.c:13
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
HRESULT WINAPI IDirectSound8_fnVerifyCertification(LPDIRECTSOUND8 iface, LPDWORD pdwCertified)
Definition: directsound.c:364
WORD cbSize
Definition: mmreg.h:84
HRESULT WINAPI IDirectSound8_fnCompact(LPDIRECTSOUND8 iface)
Definition: directsound.c:249
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
DWORD dwReserved
Definition: dsound.h:291
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
HRESULT WINAPI IDirectSound8_fnQueryInterface(LPDIRECTSOUND8 iface, REFIID riid, LPVOID *ppobj)
Definition: directsound.c:28
DWORD nSamplesPerSec
Definition: mmreg.h:80
struct IDirectSound * LPDIRECTSOUND
Definition: dsound.h:70
WORD nBlockAlign
Definition: mmreg.h:82
uint32_t * LPDWORD
Definition: typedefs.h:57
WORD wBitsPerSample
Definition: mmreg.h:83
DWORD dwBufferBytes
Definition: dsound.h:290
unsigned int ULONG
Definition: retypes.h:1
ULONG WINAPI IDirectSound8_fnRelease(LPDIRECTSOUND8 iface)
Definition: directsound.c:68
#define UNIMPLEMENTED
Definition: debug.h:114
IDirectSound8Vtbl * lpVtbl
Definition: directsound.c:14
DWORD dwFlags
Definition: dsound.h:289
#define DSSCL_PRIORITY
Definition: dsound.h:248
#define HeapFree(x, y, z)
Definition: compat.h:394
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define SUCCEEDED(hr)
Definition: intsafe.h:57
#define IDirectSound8_Initialize(p, a)
Definition: dsound.h:516