ReactOS  0.4.14-dev-41-g31d7680
dsound_main.c
Go to the documentation of this file.
1 /* DirectSound
2  *
3  * Copyright 1998 Marcus Meissner
4  * Copyright 1998 Rob Riggs
5  * Copyright 2000-2002 TransGaming Technologies, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * 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  * Most thread locking is complete. There may be a few race
22  * conditions still lurking.
23  *
24  * TODO:
25  * Implement SetCooperativeLevel properly (need to address focus issues)
26  * Implement DirectSound3DBuffers (stubs in place)
27  * Use hardware 3D support if available
28  * Add critical section locking inside Release and AddRef methods
29  * Handle static buffers - put those in hardware, non-static not in hardware
30  * Hardware DuplicateSoundBuffer
31  * Proper volume calculation for 3d buffers
32  * Remove DS_HEL_FRAGS and use mixer fragment length for it
33  */
34 
35 #include "dsound_private.h"
36 
37 #include <winreg.h>
38 #include <rpcproxy.h>
39 
43 
45 {
46  switch(err) {
47  case MMSYSERR_NOERROR:
48  return DS_OK;
49  case MMSYSERR_ALLOCATED:
50  return DSERR_ALLOCATED;
51  case MMSYSERR_ERROR:
54  return DSERR_GENERIC; /* FIXME */
55  case MMSYSERR_NODRIVER:
56  return DSERR_NODRIVER;
57  case MMSYSERR_NOMEM:
58  return DSERR_OUTOFMEMORY;
60  case WAVERR_BADFORMAT:
61  case WAVERR_UNPREPARED:
62  return DSERR_INVALIDPARAM;
64  return DSERR_UNSUPPORTED;
65  default:
66  FIXME("Unknown MMSYS error %d\n",err);
67  return DSERR_GENERIC;
68  }
69 }
70 
71 /* All default settings, you most likely don't want to touch these, see wiki on UsefulRegistryKeys */
72 int ds_emuldriver = 0;
73 int ds_hel_buflen = 32768 * 2;
81 static int ds_default_capture;
83 
84 /*
85  * Get a config key from either the app-specific or the default config
86  */
87 
88 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
89  char *buffer, DWORD size )
90 {
91  if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
92  if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
93  return ERROR_FILE_NOT_FOUND;
94 }
95 
96 
97 /*
98  * Setup the dsound options.
99  */
100 
102 {
103  char buffer[MAX_PATH+16];
104  HKEY hkey, appkey = 0;
105  DWORD len;
106 
107  buffer[MAX_PATH]='\0';
108 
109  /* @@ Wine registry key: HKCU\Software\Wine\DirectSound */
110  if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\DirectSound", &hkey )) hkey = 0;
111 
113  if (len && len < MAX_PATH)
114  {
115  HKEY tmpkey;
116  /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DirectSound */
117  if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
118  {
119  char *p, *appname = buffer;
120  if ((p = strrchr( appname, '/' ))) appname = p + 1;
121  if ((p = strrchr( appname, '\\' ))) appname = p + 1;
122  strcat( appname, "\\DirectSound" );
123  TRACE("appname = [%s]\n", appname);
124  if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
125  RegCloseKey( tmpkey );
126  }
127  }
128 
129  /* get options */
130 
131  if (!get_config_key( hkey, appkey, "EmulDriver", buffer, MAX_PATH ))
132  ds_emuldriver = strcmp(buffer, "N");
133 
134  if (!get_config_key( hkey, appkey, "HelBuflen", buffer, MAX_PATH ))
136 
137  if (!get_config_key( hkey, appkey, "SndQueueMax", buffer, MAX_PATH ))
139 
140  if (!get_config_key( hkey, appkey, "SndQueueMin", buffer, MAX_PATH ))
142 
143  if (!get_config_key( hkey, appkey, "HardwareAcceleration", buffer, MAX_PATH )) {
144  if (strcmp(buffer, "Full") == 0)
146  else if (strcmp(buffer, "Standard") == 0)
148  else if (strcmp(buffer, "Basic") == 0)
150  else if (strcmp(buffer, "Emulation") == 0)
152  }
153 
154  if (!get_config_key( hkey, appkey, "DefaultPlayback", buffer, MAX_PATH ))
156 
157  if (!get_config_key( hkey, appkey, "MaxShadowSize", buffer, MAX_PATH ))
159 
160  if (!get_config_key( hkey, appkey, "DefaultCapture", buffer, MAX_PATH ))
162 
163  if (!get_config_key( hkey, appkey, "DefaultSampleRate", buffer, MAX_PATH ))
165 
166  if (!get_config_key( hkey, appkey, "DefaultBitsPerSample", buffer, MAX_PATH ))
168 
169  if (appkey) RegCloseKey( appkey );
170  if (hkey) RegCloseKey( hkey );
171 
172  TRACE("ds_emuldriver = %d\n", ds_emuldriver);
173  TRACE("ds_hel_buflen = %d\n", ds_hel_buflen);
174  TRACE("ds_snd_queue_max = %d\n", ds_snd_queue_max);
175  TRACE("ds_snd_queue_min = %d\n", ds_snd_queue_min);
176  TRACE("ds_hw_accel = %s\n",
177  ds_hw_accel==DS_HW_ACCEL_FULL ? "Full" :
178  ds_hw_accel==DS_HW_ACCEL_STANDARD ? "Standard" :
179  ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" :
180  ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" :
181  "Unknown");
182  TRACE("ds_default_playback = %d\n", ds_default_playback);
183  TRACE("ds_default_capture = %d\n", ds_default_playback);
184  TRACE("ds_default_sample_rate = %d\n", ds_default_sample_rate);
185  TRACE("ds_default_bits_per_sample = %d\n", ds_default_bits_per_sample);
186  TRACE("ds_snd_shadow_maxsize = %d\n", ds_snd_shadow_maxsize);
187 }
188 
189 static const char * get_device_id(LPCGUID pGuid)
190 {
191  if (IsEqualGUID(&DSDEVID_DefaultPlayback, pGuid))
192  return "DSDEVID_DefaultPlayback";
193  else if (IsEqualGUID(&DSDEVID_DefaultVoicePlayback, pGuid))
194  return "DSDEVID_DefaultVoicePlayback";
195  else if (IsEqualGUID(&DSDEVID_DefaultCapture, pGuid))
196  return "DSDEVID_DefaultCapture";
197  else if (IsEqualGUID(&DSDEVID_DefaultVoiceCapture, pGuid))
198  return "DSDEVID_DefaultVoiceCapture";
199  return debugstr_guid(pGuid);
200 }
201 
202 /***************************************************************************
203  * GetDeviceID [DSOUND.9]
204  *
205  * Retrieves unique identifier of default device specified
206  *
207  * PARAMS
208  * pGuidSrc [I] Address of device GUID.
209  * pGuidDest [O] Address to receive unique device GUID.
210  *
211  * RETURNS
212  * Success: DS_OK
213  * Failure: DSERR_INVALIDPARAM
214  *
215  * NOTES
216  * pGuidSrc is a valid device GUID or DSDEVID_DefaultPlayback,
217  * DSDEVID_DefaultCapture, DSDEVID_DefaultVoicePlayback, or
218  * DSDEVID_DefaultVoiceCapture.
219  * Returns pGuidSrc if pGuidSrc is a valid device or the device
220  * GUID for the specified constants.
221  */
223 {
224  TRACE("(%s,%p)\n", get_device_id(pGuidSrc),pGuidDest);
225 
226  if ( pGuidSrc == NULL) {
227  WARN("invalid parameter: pGuidSrc == NULL\n");
228  return DSERR_INVALIDPARAM;
229  }
230 
231  if ( pGuidDest == NULL ) {
232  WARN("invalid parameter: pGuidDest == NULL\n");
233  return DSERR_INVALIDPARAM;
234  }
235 
236  if ( IsEqualGUID( &DSDEVID_DefaultPlayback, pGuidSrc ) ||
237  IsEqualGUID( &DSDEVID_DefaultVoicePlayback, pGuidSrc ) ) {
239  TRACE("returns %s\n", get_device_id(pGuidDest));
240  return DS_OK;
241  }
242 
243  if ( IsEqualGUID( &DSDEVID_DefaultCapture, pGuidSrc ) ||
244  IsEqualGUID( &DSDEVID_DefaultVoiceCapture, pGuidSrc ) ) {
246  TRACE("returns %s\n", get_device_id(pGuidDest));
247  return DS_OK;
248  }
249 
250  *pGuidDest = *pGuidSrc;
251  TRACE("returns %s\n", get_device_id(pGuidDest));
252 
253  return DS_OK;
254 }
255 
257 {
260 };
261 
263 {
264  struct morecontext *context = data;
265  char descA[MAXPNAMELEN], modA[MAXPNAMELEN];
266 
267  WideCharToMultiByte(CP_ACP, 0, descW, -1, descA, sizeof(descA), NULL, NULL);
268  WideCharToMultiByte(CP_ACP, 0, modW, -1, modA, sizeof(modA), NULL, NULL);
269 
270  return context->callA(guid, descA, modA, context->data);
271 }
272 
273 /***************************************************************************
274  * DirectSoundEnumerateA [DSOUND.2]
275  *
276  * Enumerate all DirectSound drivers installed in the system
277  *
278  * PARAMS
279  * lpDSEnumCallback [I] Address of callback function.
280  * lpContext [I] Address of user defined context passed to callback function.
281  *
282  * RETURNS
283  * Success: DS_OK
284  * Failure: DSERR_INVALIDPARAM
285  */
287  LPDSENUMCALLBACKA lpDSEnumCallback,
288  LPVOID lpContext)
289 {
290  struct morecontext context;
291 
292  if (lpDSEnumCallback == NULL) {
293  WARN("invalid parameter: lpDSEnumCallback == NULL\n");
294  return DSERR_INVALIDPARAM;
295  }
296 
297  context.callA = lpDSEnumCallback;
298  context.data = lpContext;
299 
301 }
302 
303 /***************************************************************************
304  * DirectSoundEnumerateW [DSOUND.3]
305  *
306  * Enumerate all DirectSound drivers installed in the system
307  *
308  * PARAMS
309  * lpDSEnumCallback [I] Address of callback function.
310  * lpContext [I] Address of user defined context passed to callback function.
311  *
312  * RETURNS
313  * Success: DS_OK
314  * Failure: DSERR_INVALIDPARAM
315  */
317  LPDSENUMCALLBACKW lpDSEnumCallback,
318  LPVOID lpContext )
319 {
320  unsigned devs, wod;
322  GUID guid;
323  int err;
324  WCHAR wDesc[MAXPNAMELEN];
325  WCHAR wName[MAXPNAMELEN];
326 
327  TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
328  lpDSEnumCallback, lpContext);
329 
330  if (lpDSEnumCallback == NULL) {
331  WARN("invalid parameter: lpDSEnumCallback == NULL\n");
332  return DSERR_INVALIDPARAM;
333  }
334 
336 
337  devs = waveOutGetNumDevs();
338  if (devs > 0) {
339  if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
340  static const WCHAR empty[] = { 0 };
341  for (wod = 0; wod < devs; ++wod) {
342  if (IsEqualGUID( &guid, &DSOUND_renderer_guids[wod] ) ) {
343  err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
344  if (err == DS_OK) {
345  TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
346  "Primary Sound Driver",desc.szDrvname,lpContext);
347  MultiByteToWideChar( CP_ACP, 0, "Primary Sound Driver", -1,
348  wDesc, sizeof(wDesc)/sizeof(WCHAR) );
349  if (lpDSEnumCallback(NULL, wDesc, empty, lpContext) == FALSE)
350  return DS_OK;
351  }
352  }
353  }
354  }
355  }
356 
357  for (wod = 0; wod < devs; ++wod) {
358  err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
359  if (err == DS_OK) {
360  TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
361  debugstr_guid(&DSOUND_renderer_guids[wod]),desc.szDesc,desc.szDrvname,lpContext);
362  MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
363  wDesc, sizeof(wDesc)/sizeof(WCHAR) );
364  wDesc[(sizeof(wDesc)/sizeof(WCHAR)) - 1] = '\0';
365 
366  MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
367  wName, sizeof(wName)/sizeof(WCHAR) );
368  wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0';
369 
370  if (lpDSEnumCallback(&DSOUND_renderer_guids[wod], wDesc, wName, lpContext) == FALSE)
371  return DS_OK;
372  }
373  }
374  return DS_OK;
375 }
376 
377 /***************************************************************************
378  * DirectSoundCaptureEnumerateA [DSOUND.7]
379  *
380  * Enumerate all DirectSound drivers installed in the system.
381  *
382  * PARAMS
383  * lpDSEnumCallback [I] Address of callback function.
384  * lpContext [I] Address of user defined context passed to callback function.
385  *
386  * RETURNS
387  * Success: DS_OK
388  * Failure: DSERR_INVALIDPARAM
389  */
391  LPDSENUMCALLBACKA lpDSEnumCallback,
392  LPVOID lpContext)
393 {
394  struct morecontext context;
395 
396  if (lpDSEnumCallback == NULL) {
397  WARN("invalid parameter: lpDSEnumCallback == NULL\n");
398  return DSERR_INVALIDPARAM;
399  }
400 
401  context.callA = lpDSEnumCallback;
402  context.data = lpContext;
403 
405 }
406 
407 /***************************************************************************
408  * DirectSoundCaptureEnumerateW [DSOUND.8]
409  *
410  * Enumerate all DirectSound drivers installed in the system.
411  *
412  * PARAMS
413  * lpDSEnumCallback [I] Address of callback function.
414  * lpContext [I] Address of user defined context passed to callback function.
415  *
416  * RETURNS
417  * Success: DS_OK
418  * Failure: DSERR_INVALIDPARAM
419  */
422  LPDSENUMCALLBACKW lpDSEnumCallback,
423  LPVOID lpContext)
424 {
425  unsigned devs, wid;
427  GUID guid;
428  int err;
429  WCHAR wDesc[MAXPNAMELEN];
430  WCHAR wName[MAXPNAMELEN];
431 
432  TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
433 
434  if (lpDSEnumCallback == NULL) {
435  WARN("invalid parameter: lpDSEnumCallback == NULL\n");
436  return DSERR_INVALIDPARAM;
437  }
438 
440 
441  devs = waveInGetNumDevs();
442  if (devs > 0) {
443  if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
444  for (wid = 0; wid < devs; ++wid) {
445  if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) {
446  err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
447  if (err == DS_OK) {
448  TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
449  "Primary Sound Capture Driver",desc.szDrvname,lpContext);
450  MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1,
451  wDesc, sizeof(wDesc)/sizeof(WCHAR) );
452  MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
453  wName, sizeof(wName)/sizeof(WCHAR) );
454  wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0';
455 
456  if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE)
457  return DS_OK;
458  }
459  }
460  }
461  }
462  }
463 
464  for (wid = 0; wid < devs; ++wid) {
465  err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
466  if (err == DS_OK) {
467  TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
468  debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext);
469  MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
470  wDesc, sizeof(wDesc)/sizeof(WCHAR) );
471  wDesc[(sizeof(wDesc)/sizeof(WCHAR)) - 1] = '\0';
472 
473  MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
474  wName, sizeof(wName)/sizeof(WCHAR) );
475  wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0';
476 
477  if (lpDSEnumCallback(&DSOUND_capture_guids[wid], wDesc, wName, lpContext) == FALSE)
478  return DS_OK;
479  }
480  }
481 
482  return DS_OK;
483 }
484 
485 /*******************************************************************************
486  * DirectSound ClassFactory
487  */
488 
490 
491 typedef struct {
492  IClassFactory IClassFactory_iface;
496 
498 {
499  return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
500 }
501 
502 static HRESULT WINAPI
503 DSCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj)
504 {
506  TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
507  if (ppobj == NULL)
508  return E_POINTER;
509  if (IsEqualIID(riid, &IID_IUnknown) ||
511  {
512  *ppobj = iface;
513  IUnknown_AddRef(iface);
514  return S_OK;
515  }
516  *ppobj = NULL;
517  return E_NOINTERFACE;
518 }
519 
520 static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
521 {
522  return 2;
523 }
524 
525 static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
526 {
527  /* static class, won't be freed */
528  return 1;
529 }
530 
532  LPCLASSFACTORY iface,
533  LPUNKNOWN pOuter,
534  REFIID riid,
535  LPVOID *ppobj)
536 {
538  TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), ppobj);
539 
540  if (pOuter)
541  return CLASS_E_NOAGGREGATION;
542 
543  if (ppobj == NULL) {
544  WARN("invalid parameter\n");
545  return DSERR_INVALIDPARAM;
546  }
547  *ppobj = NULL;
548  return This->pfnCreateInstance(riid, ppobj);
549 }
550 
551 static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
552 {
554  FIXME("(%p, %d) stub!\n", This, dolock);
555  return S_OK;
556 }
557 
558 static const IClassFactoryVtbl DSCF_Vtbl = {
560  DSCF_AddRef,
561  DSCF_Release,
564 };
565 
567  { { &DSCF_Vtbl }, &CLSID_DirectSound, (FnCreateInstance)DSOUND_Create },
568  { { &DSCF_Vtbl }, &CLSID_DirectSound8, (FnCreateInstance)DSOUND_Create8 },
569  { { &DSCF_Vtbl }, &CLSID_DirectSoundCapture, (FnCreateInstance)DSOUND_CaptureCreate },
570  { { &DSCF_Vtbl }, &CLSID_DirectSoundCapture8, (FnCreateInstance)DSOUND_CaptureCreate8 },
571  { { &DSCF_Vtbl }, &CLSID_DirectSoundFullDuplex, (FnCreateInstance)DSOUND_FullDuplexCreate },
572  { { &DSCF_Vtbl }, &CLSID_DirectSoundPrivate, (FnCreateInstance)IKsPrivatePropertySetImpl_Create },
573  { { NULL }, NULL, NULL }
574 };
575 
576 /*******************************************************************************
577  * DllGetClassObject [DSOUND.@]
578  * Retrieves class object from a DLL object
579  *
580  * NOTES
581  * Docs say returns STDAPI
582  *
583  * PARAMS
584  * rclsid [I] CLSID for the class object
585  * riid [I] Reference to identifier of interface for class object
586  * ppv [O] Address of variable to receive interface pointer for riid
587  *
588  * RETURNS
589  * Success: S_OK
590  * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
591  * E_UNEXPECTED
592  */
594 {
595  int i = 0;
596  TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
597 
598  if (ppv == NULL) {
599  WARN("invalid parameter\n");
600  return E_INVALIDARG;
601  }
602 
603  *ppv = NULL;
604 
607  WARN("no interface for %s\n", debugstr_guid(riid));
608  return E_NOINTERFACE;
609  }
610 
611  while (NULL != DSOUND_CF[i].rclsid) {
612  if (IsEqualGUID(rclsid, DSOUND_CF[i].rclsid)) {
613  DSCF_AddRef(&DSOUND_CF[i].IClassFactory_iface);
614  *ppv = &DSOUND_CF[i];
615  return S_OK;
616  }
617  i++;
618  }
619 
620  WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid),
623 }
624 
625 
626 /*******************************************************************************
627  * DllCanUnloadNow [DSOUND.4]
628  * Determines whether the DLL is in use.
629  *
630  * RETURNS
631  * Can unload now: S_OK
632  * Cannot unload now (the DLL is still active): S_FALSE
633  */
635 {
636  return S_FALSE;
637 }
638 
639 #define INIT_GUID(guid, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
640  guid.Data1 = l; guid.Data2 = w1; guid.Data3 = w2; \
641  guid.Data4[0] = b1; guid.Data4[1] = b2; guid.Data4[2] = b3; \
642  guid.Data4[3] = b4; guid.Data4[4] = b5; guid.Data4[5] = b6; \
643  guid.Data4[6] = b7; guid.Data4[7] = b8;
644 
645 /***********************************************************************
646  * DllMain (DSOUND.init)
647  */
649 {
650  int i;
651  TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpvReserved);
652 
653  switch (fdwReason) {
654  case DLL_PROCESS_ATTACH:
655  TRACE("DLL_PROCESS_ATTACH\n");
656  for (i = 0; i < MAXWAVEDRIVERS; i++) {
658  DSOUND_capture[i] = NULL;
659  INIT_GUID(DSOUND_renderer_guids[i], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
660  INIT_GUID(DSOUND_capture_guids[i], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
661  }
662  instance = hInstDLL;
663  DisableThreadLibraryCalls(hInstDLL);
664  /* Increase refcount on dsound by 1 */
665  GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)hInstDLL, &hInstDLL);
666  break;
667  case DLL_PROCESS_DETACH:
668  TRACE("DLL_PROCESS_DETACH\n");
669  break;
670  default:
671  TRACE("UNKNOWN REASON\n");
672  break;
673  }
674  return TRUE;
675 }
676 
677 /***********************************************************************
678  * DllRegisterServer (DSOUND.@)
679  */
681 {
683 }
684 
685 /***********************************************************************
686  * DllUnregisterServer (DSOUND.@)
687  */
689 {
691 }
void setup_dsound_options(void)
Definition: dsound_main.c:101
static DWORD get_config_key(HKEY defkey, HKEY appkey, const char *name, char *buffer, DWORD size)
Definition: dsound_main.c:88
HRESULT(* FnCreateInstance)(REFIID riid, LPVOID *ppobj)
Definition: dsound_main.c:489
#define WAVERR_BADFORMAT
Definition: mmsystem.h:176
#define DSERR_GENERIC
Definition: dsound.h:123
int ds_snd_queue_min
Definition: dsound_main.c:75
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3257
#define HRESULT
Definition: msvc.h:9
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4023
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT WINAPI DllRegisterServer(void)
Definition: dsound_main.c:680
#define WideCharToMultiByte
Definition: compat.h:101
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
HRESULT __wine_register_resources(HMODULE module) DECLSPEC_HIDDEN
Definition: register.c:98
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2541
Definition: http.c:6587
HRESULT WINAPI DirectSoundEnumerateA(LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext)
Definition: dsound_main.c:286
REFIID riid
Definition: precomp.h:44
int ds_emuldriver
Definition: dsound_main.c:72
static const WCHAR empty[]
Definition: main.c:49
#define REFCLSID
Definition: guiddef.h:117
#define CP_ACP
Definition: compat.h:99
#define HKEY_CURRENT_USER
Definition: winreg.h:11
HRESULT WINAPI DirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext)
Definition: dsound_main.c:390
#define WARN(fmt,...)
Definition: debug.h:111
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
Definition: dsound_main.c:222
#define CALLBACK
Definition: compat.h:27
REFIID LPVOID * ppv
Definition: atlbase.h:39
HRESULT DSOUND_Create8(REFIID riid, LPDIRECTSOUND8 *ppDS)
Definition: dsound.c:1050
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
HRESULT WINAPI DllUnregisterServer(void)
Definition: dsound_main.c:688
GLuint buffer
Definition: glext.h:5915
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
static BOOL CALLBACK a_to_w_callback(LPGUID guid, LPCWSTR descW, LPCWSTR modW, LPVOID data)
Definition: dsound_main.c:262
#define CLASS_E_CLASSNOTAVAILABLE
Definition: winerror.h:2663
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:548
static IN DWORD IN LPVOID lpvReserved
UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2816
HRESULT DSOUND_CaptureCreate8(REFIID riid, LPDIRECTSOUNDCAPTURE8 *ppDSC8)
Definition: capture.c:1359
struct tagIClassFactoryImpl IClassFactoryImpl
HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, IKsPropertySet **piks) DECLSPEC_HIDDEN
Definition: propset.c:615
HRESULT DSOUND_Create(REFIID riid, LPDIRECTSOUND *ppDS)
Definition: dsound.c:963
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
static int ds_default_playback
Definition: dsound_main.c:80
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HINSTANCE instance
Definition: dsound_main.c:82
const GUID * guid
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
unsigned char * LPBYTE
Definition: typedefs.h:52
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
HRESULT WINAPI DirectSoundEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext)
Definition: dsound_main.c:316
#define INIT_GUID(guid, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: dsound_main.c:639
unsigned int BOOL
Definition: ntddk_ex.h:94
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
Definition: dsound_main.c:648
GUID DSOUND_capture_guids[MAXWAVEDRIVERS]
Definition: dsound_main.c:42
static LPUNKNOWN
Definition: ndr_ole.c:49
DirectSoundDevice * DSOUND_renderer[MAXWAVEDRIVERS]
Definition: dsound_main.c:40
#define FIXME(fmt,...)
Definition: debug.h:110
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
const struct builtin_class_descr * desc
Definition: regcontrol.c:48
smooth NULL
Definition: ftsmooth.c:416
#define DSERR_NODRIVER
Definition: dsound.h:128
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2140
#define DS_HW_ACCEL_EMULATION
#define debugstr_guid
Definition: kernel32.h:35
static HRESULT WINAPI DSCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj)
Definition: dsound_main.c:503
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
Definition: dsound_main.c:531
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
Definition: dsound_main.c:593
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
FnCreateInstance pfnCreateInstance
Definition: dsound_main.c:494
#define DLL_PROCESS_DETACH
Definition: compat.h:119
HRESULT mmErr(UINT err)
Definition: dsound_main.c:44
HRESULT DSOUND_CaptureCreate(REFIID riid, LPDIRECTSOUNDCAPTURE *ppDSC)
Definition: capture.c:1330
LPDSENUMCALLBACKA callA
Definition: dsound_main.c:258
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
Definition: dsound_main.c:551
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MMSYSERR_ALLOCATED
Definition: mmsystem.h:100
LONG HRESULT
Definition: typedefs.h:77
#define UlongToHandle(ul)
Definition: basetsd.h:97
const GUID IID_IUnknown
static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
Definition: dsound_main.c:520
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
Definition: dsound_main.c:525
#define DSERR_UNSUPPORTED
Definition: dsound.h:127
#define MAXWAVEDRIVERS
Definition: mmddk.h:33
HRESULT WINAPI DllCanUnloadNow(void)
Definition: dsound_main.c:634
HRESULT __wine_unregister_resources(HMODULE module) DECLSPEC_HIDDEN
Definition: register.c:110
static IClassFactoryImpl DSOUND_CF[]
Definition: dsound_main.c:566
GLenum GLsizei len
Definition: glext.h:6722
#define DS_HW_ACCEL_STANDARD
HRESULT WINAPI DirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext)
Definition: dsound_main.c:421
#define err(...)
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
uint32_t DWORD_PTR
Definition: typedefs.h:63
static const WCHAR modW[]
Definition: lex.c:64
int ds_hel_buflen
Definition: dsound_main.c:73
int ds_default_sample_rate
Definition: dsound_main.c:78
BOOL WINAPI GetModuleHandleExW(IN DWORD dwFlags, IN LPCWSTR lpwModuleName OPTIONAL, OUT HMODULE *phModule)
Definition: loader.c:875
#define S_OK
Definition: intsafe.h:59
LPVOID data
Definition: dsound_main.c:259
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define DS_HW_ACCEL_FULL
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
int ds_snd_queue_max
Definition: dsound_main.c:74
BOOL(CALLBACK * LPDSENUMCALLBACKA)(LPGUID, LPCSTR, LPCSTR, LPVOID)
Definition: dsound.h:405
#define MAXPNAMELEN
Definition: mmsystem.h:24
#define MultiByteToWideChar
Definition: compat.h:100
static IClassFactoryImpl * impl_from_IClassFactory(IClassFactory *iface)
Definition: dsound_main.c:497
static int ds_default_capture
Definition: dsound_main.c:81
#define WAVERR_UNPREPARED
Definition: mmsystem.h:178
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
Definition: name.c:36
#define DSERR_ALLOCATED
Definition: dsound.h:119
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2568
int ds_snd_shadow_maxsize
Definition: dsound_main.c:76
int ds_default_bits_per_sample
Definition: dsound_main.c:79
static const char * get_device_id(LPCGUID pGuid)
Definition: dsound_main.c:189
GUID DSOUND_renderer_guids[MAXWAVEDRIVERS]
Definition: dsound_main.c:41
GLfloat GLfloat p
Definition: glext.h:8902
#define E_POINTER
Definition: winerror.h:2365
#define DS_HW_ACCEL_BASIC
static const IClassFactoryVtbl DSCF_Vtbl
Definition: dsound_main.c:558
const GUID IID_IClassFactory
HRESULT DSOUND_FullDuplexCreate(REFIID riid, LPDIRECTSOUNDFULLDUPLEX *ppDSFD) DECLSPEC_HIDDEN
Definition: duplex.c:604
BOOL(CALLBACK * LPDSENUMCALLBACKW)(LPGUID, LPCWSTR, LPCWSTR, LPVOID)
Definition: dsound.h:404
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS]
Definition: capture.c:965
int ds_hw_accel
Definition: dsound_main.c:77