ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dsound_main.c
Go to the documentation of this file.
00001 /*              DirectSound
00002  *
00003  * Copyright 1998 Marcus Meissner
00004  * Copyright 1998 Rob Riggs
00005  * Copyright 2000-2002 TransGaming Technologies, Inc.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  *
00021  * Most thread locking is complete. There may be a few race
00022  * conditions still lurking.
00023  *
00024  * TODO:
00025  *  Implement SetCooperativeLevel properly (need to address focus issues)
00026  *  Implement DirectSound3DBuffers (stubs in place)
00027  *  Use hardware 3D support if available
00028  *      Add critical section locking inside Release and AddRef methods
00029  *      Handle static buffers - put those in hardware, non-static not in hardware
00030  *      Hardware DuplicateSoundBuffer
00031  *      Proper volume calculation for 3d buffers
00032  *      Remove DS_HEL_FRAGS and use mixer fragment length for it
00033  */
00034 
00035 #include <stdarg.h>
00036 
00037 #define COBJMACROS
00038 #define NONAMELESSSTRUCT
00039 #define NONAMELESSUNION
00040 #include "windef.h"
00041 #include "winbase.h"
00042 #include "winuser.h"
00043 #include "winnls.h"
00044 #include "winreg.h"
00045 #include "mmsystem.h"
00046 #include "winternl.h"
00047 #include "mmddk.h"
00048 #include "wine/debug.h"
00049 #include "dsound.h"
00050 #include "dsconf.h"
00051 #include "ks.h"
00052 #include "initguid.h"
00053 #include "ksmedia.h"
00054 #include "dsdriver.h"
00055 
00056 #include "dsound_private.h"
00057 
00058 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
00059 
00060 DirectSoundDevice*  DSOUND_renderer[MAXWAVEDRIVERS];
00061 GUID                    DSOUND_renderer_guids[MAXWAVEDRIVERS];
00062 GUID                    DSOUND_capture_guids[MAXWAVEDRIVERS];
00063 
00064 HRESULT mmErr(UINT err)
00065 {
00066     switch(err) {
00067     case MMSYSERR_NOERROR:
00068         return DS_OK;
00069     case MMSYSERR_ALLOCATED:
00070         return DSERR_ALLOCATED;
00071     case MMSYSERR_ERROR:
00072     case MMSYSERR_INVALHANDLE:
00073     case WAVERR_STILLPLAYING:
00074         return DSERR_GENERIC; /* FIXME */
00075     case MMSYSERR_NODRIVER:
00076         return DSERR_NODRIVER;
00077     case MMSYSERR_NOMEM:
00078         return DSERR_OUTOFMEMORY;
00079     case MMSYSERR_INVALPARAM:
00080     case WAVERR_BADFORMAT:
00081     case WAVERR_UNPREPARED:
00082         return DSERR_INVALIDPARAM;
00083     case MMSYSERR_NOTSUPPORTED:
00084         return DSERR_UNSUPPORTED;
00085     default:
00086         FIXME("Unknown MMSYS error %d\n",err);
00087         return DSERR_GENERIC;
00088     }
00089 }
00090 
00091 /* All default settings, you most likely don't want to touch these, see wiki on UsefulRegistryKeys */
00092 int ds_emuldriver = 0;
00093 int ds_hel_buflen = 32768 * 2;
00094 int ds_snd_queue_max = 10;
00095 int ds_snd_queue_min = 6;
00096 int ds_snd_shadow_maxsize = 2;
00097 int ds_hw_accel = DS_HW_ACCEL_FULL;
00098 int ds_default_sample_rate = 44100;
00099 int ds_default_bits_per_sample = 16;
00100 static int ds_default_playback;
00101 static int ds_default_capture;
00102 
00103 /*
00104  * Get a config key from either the app-specific or the default config
00105  */
00106 
00107 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
00108                                     char *buffer, DWORD size )
00109 {
00110     if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
00111     if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
00112     return ERROR_FILE_NOT_FOUND;
00113 }
00114 
00115 
00116 /*
00117  * Setup the dsound options.
00118  */
00119 
00120 void setup_dsound_options(void)
00121 {
00122     char buffer[MAX_PATH+16];
00123     HKEY hkey, appkey = 0;
00124     DWORD len;
00125 
00126     buffer[MAX_PATH]='\0';
00127 
00128     /* @@ Wine registry key: HKCU\Software\Wine\DirectSound */
00129     if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\DirectSound", &hkey )) hkey = 0;
00130 
00131     len = GetModuleFileNameA( 0, buffer, MAX_PATH );
00132     if (len && len < MAX_PATH)
00133     {
00134         HKEY tmpkey;
00135         /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DirectSound */
00136         if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
00137         {
00138             char *p, *appname = buffer;
00139             if ((p = strrchr( appname, '/' ))) appname = p + 1;
00140             if ((p = strrchr( appname, '\\' ))) appname = p + 1;
00141             strcat( appname, "\\DirectSound" );
00142             TRACE("appname = [%s]\n", appname);
00143             if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
00144             RegCloseKey( tmpkey );
00145         }
00146     }
00147 
00148     /* get options */
00149 
00150     if (!get_config_key( hkey, appkey, "EmulDriver", buffer, MAX_PATH ))
00151         ds_emuldriver = strcmp(buffer, "N");
00152 
00153     if (!get_config_key( hkey, appkey, "HelBuflen", buffer, MAX_PATH ))
00154         ds_hel_buflen = atoi(buffer);
00155 
00156     if (!get_config_key( hkey, appkey, "SndQueueMax", buffer, MAX_PATH ))
00157         ds_snd_queue_max = atoi(buffer);
00158 
00159     if (!get_config_key( hkey, appkey, "SndQueueMin", buffer, MAX_PATH ))
00160         ds_snd_queue_min = atoi(buffer);
00161 
00162     if (!get_config_key( hkey, appkey, "HardwareAcceleration", buffer, MAX_PATH )) {
00163     if (strcmp(buffer, "Full") == 0)
00164         ds_hw_accel = DS_HW_ACCEL_FULL;
00165     else if (strcmp(buffer, "Standard") == 0)
00166         ds_hw_accel = DS_HW_ACCEL_STANDARD;
00167     else if (strcmp(buffer, "Basic") == 0)
00168         ds_hw_accel = DS_HW_ACCEL_BASIC;
00169     else if (strcmp(buffer, "Emulation") == 0)
00170         ds_hw_accel = DS_HW_ACCEL_EMULATION;
00171     }
00172 
00173     if (!get_config_key( hkey, appkey, "DefaultPlayback", buffer, MAX_PATH ))
00174         ds_default_playback = atoi(buffer);
00175 
00176     if (!get_config_key( hkey, appkey, "MaxShadowSize", buffer, MAX_PATH ))
00177         ds_snd_shadow_maxsize = atoi(buffer);
00178 
00179     if (!get_config_key( hkey, appkey, "DefaultCapture", buffer, MAX_PATH ))
00180         ds_default_capture = atoi(buffer);
00181 
00182     if (!get_config_key( hkey, appkey, "DefaultSampleRate", buffer, MAX_PATH ))
00183         ds_default_sample_rate = atoi(buffer);
00184 
00185     if (!get_config_key( hkey, appkey, "DefaultBitsPerSample", buffer, MAX_PATH ))
00186         ds_default_bits_per_sample = atoi(buffer);
00187 
00188     if (appkey) RegCloseKey( appkey );
00189     if (hkey) RegCloseKey( hkey );
00190 
00191     TRACE("ds_emuldriver = %d\n", ds_emuldriver);
00192     TRACE("ds_hel_buflen = %d\n", ds_hel_buflen);
00193     TRACE("ds_snd_queue_max = %d\n", ds_snd_queue_max);
00194     TRACE("ds_snd_queue_min = %d\n", ds_snd_queue_min);
00195     TRACE("ds_hw_accel = %s\n",
00196         ds_hw_accel==DS_HW_ACCEL_FULL ? "Full" :
00197         ds_hw_accel==DS_HW_ACCEL_STANDARD ? "Standard" :
00198         ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" :
00199         ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" :
00200         "Unknown");
00201     TRACE("ds_default_playback = %d\n", ds_default_playback);
00202     TRACE("ds_default_capture = %d\n", ds_default_playback);
00203     TRACE("ds_default_sample_rate = %d\n", ds_default_sample_rate);
00204     TRACE("ds_default_bits_per_sample = %d\n", ds_default_bits_per_sample);
00205     TRACE("ds_snd_shadow_maxsize = %d\n", ds_snd_shadow_maxsize);
00206 }
00207 
00208 static const char * get_device_id(LPCGUID pGuid)
00209 {
00210     if (IsEqualGUID(&DSDEVID_DefaultPlayback, pGuid))
00211         return "DSDEVID_DefaultPlayback";
00212     else if (IsEqualGUID(&DSDEVID_DefaultVoicePlayback, pGuid))
00213         return "DSDEVID_DefaultVoicePlayback";
00214     else if (IsEqualGUID(&DSDEVID_DefaultCapture, pGuid))
00215         return "DSDEVID_DefaultCapture";
00216     else if (IsEqualGUID(&DSDEVID_DefaultVoiceCapture, pGuid))
00217         return "DSDEVID_DefaultVoiceCapture";
00218     return debugstr_guid(pGuid);
00219 }
00220 
00221 /***************************************************************************
00222  * GetDeviceID  [DSOUND.9]
00223  *
00224  * Retrieves unique identifier of default device specified
00225  *
00226  * PARAMS
00227  *    pGuidSrc  [I] Address of device GUID.
00228  *    pGuidDest [O] Address to receive unique device GUID.
00229  *
00230  * RETURNS
00231  *    Success: DS_OK
00232  *    Failure: DSERR_INVALIDPARAM
00233  *
00234  * NOTES
00235  *    pGuidSrc is a valid device GUID or DSDEVID_DefaultPlayback,
00236  *    DSDEVID_DefaultCapture, DSDEVID_DefaultVoicePlayback, or
00237  *    DSDEVID_DefaultVoiceCapture.
00238  *    Returns pGuidSrc if pGuidSrc is a valid device or the device
00239  *    GUID for the specified constants.
00240  */
00241 HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
00242 {
00243     TRACE("(%s,%p)\n", get_device_id(pGuidSrc),pGuidDest);
00244 
00245     if ( pGuidSrc == NULL) {
00246     WARN("invalid parameter: pGuidSrc == NULL\n");
00247     return DSERR_INVALIDPARAM;
00248     }
00249 
00250     if ( pGuidDest == NULL ) {
00251     WARN("invalid parameter: pGuidDest == NULL\n");
00252     return DSERR_INVALIDPARAM;
00253     }
00254 
00255     if ( IsEqualGUID( &DSDEVID_DefaultPlayback, pGuidSrc ) ||
00256          IsEqualGUID( &DSDEVID_DefaultVoicePlayback, pGuidSrc ) ) {
00257     *pGuidDest = DSOUND_renderer_guids[ds_default_playback];
00258         TRACE("returns %s\n", get_device_id(pGuidDest));
00259     return DS_OK;
00260     }
00261 
00262     if ( IsEqualGUID( &DSDEVID_DefaultCapture, pGuidSrc ) ||
00263          IsEqualGUID( &DSDEVID_DefaultVoiceCapture, pGuidSrc ) ) {
00264     *pGuidDest = DSOUND_capture_guids[ds_default_capture];
00265         TRACE("returns %s\n", get_device_id(pGuidDest));
00266     return DS_OK;
00267     }
00268 
00269     *pGuidDest = *pGuidSrc;
00270     TRACE("returns %s\n", get_device_id(pGuidDest));
00271 
00272     return DS_OK;
00273 }
00274 
00275 
00276 /***************************************************************************
00277  * DirectSoundEnumerateA [DSOUND.2]
00278  *
00279  * Enumerate all DirectSound drivers installed in the system
00280  *
00281  * PARAMS
00282  *    lpDSEnumCallback  [I] Address of callback function.
00283  *    lpContext         [I] Address of user defined context passed to callback function.
00284  *
00285  * RETURNS
00286  *    Success: DS_OK
00287  *    Failure: DSERR_INVALIDPARAM
00288  */
00289 HRESULT WINAPI DirectSoundEnumerateA(
00290     LPDSENUMCALLBACKA lpDSEnumCallback,
00291     LPVOID lpContext)
00292 {
00293     unsigned devs, wod;
00294     DSDRIVERDESC desc;
00295     GUID guid;
00296     int err;
00297 
00298     TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
00299     lpDSEnumCallback, lpContext);
00300 
00301     if (lpDSEnumCallback == NULL) {
00302     WARN("invalid parameter: lpDSEnumCallback == NULL\n");
00303     return DSERR_INVALIDPARAM;
00304     }
00305 
00306     devs = waveOutGetNumDevs();
00307     if (devs > 0) {
00308     if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
00309         for (wod = 0; wod < devs; ++wod) {
00310                 if (IsEqualGUID( &guid, &DSOUND_renderer_guids[wod]) ) {
00311                     err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
00312                     if (err == DS_OK) {
00313                         TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
00314                               "Primary Sound Driver","",lpContext);
00315                         if (lpDSEnumCallback(NULL, "Primary Sound Driver", "", lpContext) == FALSE)
00316                             return DS_OK;
00317             }
00318         }
00319         }
00320     }
00321     }
00322 
00323     for (wod = 0; wod < devs; ++wod) {
00324         err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
00325     if (err == DS_OK) {
00326             TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
00327                   debugstr_guid(&DSOUND_renderer_guids[wod]),desc.szDesc,desc.szDrvname,lpContext);
00328             if (lpDSEnumCallback(&DSOUND_renderer_guids[wod], desc.szDesc, desc.szDrvname, lpContext) == FALSE)
00329                 return DS_OK;
00330     }
00331     }
00332     return DS_OK;
00333 }
00334 
00335 /***************************************************************************
00336  * DirectSoundEnumerateW [DSOUND.3]
00337  *
00338  * Enumerate all DirectSound drivers installed in the system
00339  *
00340  * PARAMS
00341  *    lpDSEnumCallback  [I] Address of callback function.
00342  *    lpContext         [I] Address of user defined context passed to callback function.
00343  *
00344  * RETURNS
00345  *    Success: DS_OK
00346  *    Failure: DSERR_INVALIDPARAM
00347  */
00348 HRESULT WINAPI DirectSoundEnumerateW(
00349     LPDSENUMCALLBACKW lpDSEnumCallback,
00350     LPVOID lpContext )
00351 {
00352     unsigned devs, wod;
00353     DSDRIVERDESC desc;
00354     GUID guid;
00355     int err;
00356     WCHAR wDesc[MAXPNAMELEN];
00357     WCHAR wName[MAXPNAMELEN];
00358 
00359     TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
00360     lpDSEnumCallback, lpContext);
00361 
00362     if (lpDSEnumCallback == NULL) {
00363     WARN("invalid parameter: lpDSEnumCallback == NULL\n");
00364     return DSERR_INVALIDPARAM;
00365     }
00366 
00367     devs = waveOutGetNumDevs();
00368     if (devs > 0) {
00369     if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
00370             static const WCHAR empty[] = { 0 };
00371         for (wod = 0; wod < devs; ++wod) {
00372                 if (IsEqualGUID( &guid, &DSOUND_renderer_guids[wod] ) ) {
00373                     err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
00374                     if (err == DS_OK) {
00375                         TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
00376                               "Primary Sound Driver",desc.szDrvname,lpContext);
00377                         MultiByteToWideChar( CP_ACP, 0, "Primary Sound Driver", -1,
00378                                              wDesc, sizeof(wDesc)/sizeof(WCHAR) );
00379                         if (lpDSEnumCallback(NULL, wDesc, empty, lpContext) == FALSE)
00380                             return DS_OK;
00381             }
00382         }
00383         }
00384     }
00385     }
00386 
00387     for (wod = 0; wod < devs; ++wod) {
00388         err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
00389     if (err == DS_OK) {
00390             TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
00391                   debugstr_guid(&DSOUND_renderer_guids[wod]),desc.szDesc,desc.szDrvname,lpContext);
00392             MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
00393                                  wDesc, sizeof(wDesc)/sizeof(WCHAR) );
00394             MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
00395                                  wName, sizeof(wName)/sizeof(WCHAR) );
00396             if (lpDSEnumCallback(&DSOUND_renderer_guids[wod], wDesc, wName, lpContext) == FALSE)
00397                 return DS_OK;
00398     }
00399     }
00400     return DS_OK;
00401 }
00402 
00403 /*******************************************************************************
00404  * DirectSound ClassFactory
00405  */
00406 
00407 typedef  HRESULT (*FnCreateInstance)(REFIID riid, LPVOID *ppobj);
00408  
00409 typedef struct {
00410     const IClassFactoryVtbl *lpVtbl;
00411     LONG ref;
00412     REFCLSID rclsid;
00413     FnCreateInstance pfnCreateInstance;
00414 } IClassFactoryImpl;
00415 
00416 static HRESULT WINAPI
00417 DSCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj)
00418 {
00419     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
00420     TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
00421     if (ppobj == NULL)
00422         return E_POINTER;
00423     if (IsEqualIID(riid, &IID_IUnknown) ||
00424         IsEqualIID(riid, &IID_IClassFactory))
00425     {
00426         *ppobj = iface;
00427         IUnknown_AddRef(iface);
00428         return S_OK;
00429     }
00430     *ppobj = NULL;
00431     return E_NOINTERFACE;
00432 }
00433 
00434 static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
00435 {
00436     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
00437     ULONG ref = InterlockedIncrement(&(This->ref));
00438     TRACE("(%p) ref was %d\n", This, ref - 1);
00439     return ref;
00440 }
00441 
00442 static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
00443 {
00444     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
00445     ULONG ref = InterlockedDecrement(&(This->ref));
00446     TRACE("(%p) ref was %d\n", This, ref + 1);
00447     /* static class, won't be freed */
00448     return ref;
00449 }
00450 
00451 static HRESULT WINAPI DSCF_CreateInstance(
00452     LPCLASSFACTORY iface,
00453     LPUNKNOWN pOuter,
00454     REFIID riid,
00455     LPVOID *ppobj)
00456 {
00457     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
00458     TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), ppobj);
00459 
00460     if (pOuter)
00461         return CLASS_E_NOAGGREGATION;
00462 
00463     if (ppobj == NULL) {
00464         WARN("invalid parameter\n");
00465         return DSERR_INVALIDPARAM;
00466     }
00467     *ppobj = NULL;
00468     return This->pfnCreateInstance(riid, ppobj);
00469 }
00470  
00471 static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
00472 {
00473     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
00474     FIXME("(%p, %d) stub!\n", This, dolock);
00475     return S_OK;
00476 }
00477 
00478 static const IClassFactoryVtbl DSCF_Vtbl = {
00479     DSCF_QueryInterface,
00480     DSCF_AddRef,
00481     DSCF_Release,
00482     DSCF_CreateInstance,
00483     DSCF_LockServer
00484 };
00485 
00486 static IClassFactoryImpl DSOUND_CF[] = {
00487     { &DSCF_Vtbl, 1, &CLSID_DirectSound, (FnCreateInstance)DSOUND_Create },
00488     { &DSCF_Vtbl, 1, &CLSID_DirectSound8, (FnCreateInstance)DSOUND_Create8 },
00489     { &DSCF_Vtbl, 1, &CLSID_DirectSoundCapture, (FnCreateInstance)DSOUND_CaptureCreate },
00490     { &DSCF_Vtbl, 1, &CLSID_DirectSoundCapture8, (FnCreateInstance)DSOUND_CaptureCreate8 },
00491     { &DSCF_Vtbl, 1, &CLSID_DirectSoundFullDuplex, (FnCreateInstance)DSOUND_FullDuplexCreate },
00492     { &DSCF_Vtbl, 1, &CLSID_DirectSoundPrivate, (FnCreateInstance)IKsPrivatePropertySetImpl_Create },
00493     { NULL, 0, NULL, NULL }
00494 };
00495 
00496 /*******************************************************************************
00497  * DllGetClassObject [DSOUND.@]
00498  * Retrieves class object from a DLL object
00499  *
00500  * NOTES
00501  *    Docs say returns STDAPI
00502  *
00503  * PARAMS
00504  *    rclsid [I] CLSID for the class object
00505  *    riid   [I] Reference to identifier of interface for class object
00506  *    ppv    [O] Address of variable to receive interface pointer for riid
00507  *
00508  * RETURNS
00509  *    Success: S_OK
00510  *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
00511  *             E_UNEXPECTED
00512  */
00513 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
00514 {
00515     int i = 0;
00516     TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
00517 
00518     if (ppv == NULL) {
00519         WARN("invalid parameter\n");
00520         return E_INVALIDARG;
00521     }
00522 
00523     *ppv = NULL;
00524 
00525     if (!IsEqualIID(riid, &IID_IClassFactory) &&
00526         !IsEqualIID(riid, &IID_IUnknown)) {
00527         WARN("no interface for %s\n", debugstr_guid(riid));
00528         return E_NOINTERFACE;
00529     }
00530 
00531     while (NULL != DSOUND_CF[i].rclsid) {
00532         if (IsEqualGUID(rclsid, DSOUND_CF[i].rclsid)) {
00533             DSCF_AddRef((IClassFactory*) &DSOUND_CF[i]);
00534             *ppv = &DSOUND_CF[i];
00535             return S_OK;
00536         }
00537         i++;
00538     }
00539 
00540     WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid),
00541          debugstr_guid(riid), ppv);
00542     return CLASS_E_CLASSNOTAVAILABLE;
00543 }
00544 
00545 
00546 /*******************************************************************************
00547  * DllCanUnloadNow [DSOUND.4]
00548  * Determines whether the DLL is in use.
00549  *
00550  * RETURNS
00551  *    Success: S_OK
00552  *    Failure: S_FALSE
00553  */
00554 HRESULT WINAPI DllCanUnloadNow(void)
00555 {
00556     FIXME("(void): stub\n");
00557     return S_FALSE;
00558 }
00559 
00560 #define INIT_GUID(guid, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)      \
00561         guid.Data1 = l; guid.Data2 = w1; guid.Data3 = w2;               \
00562         guid.Data4[0] = b1; guid.Data4[1] = b2; guid.Data4[2] = b3;     \
00563         guid.Data4[3] = b4; guid.Data4[4] = b5; guid.Data4[5] = b6;     \
00564         guid.Data4[6] = b7; guid.Data4[7] = b8;
00565 
00566 /***********************************************************************
00567  *           DllMain (DSOUND.init)
00568  */
00569 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
00570 {
00571     int i;
00572     TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpvReserved);
00573 
00574     switch (fdwReason) {
00575     case DLL_PROCESS_ATTACH:
00576         TRACE("DLL_PROCESS_ATTACH\n");
00577         for (i = 0; i < MAXWAVEDRIVERS; i++) {
00578             DSOUND_renderer[i] = NULL;
00579             DSOUND_capture[i] = NULL;
00580             INIT_GUID(DSOUND_renderer_guids[i], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
00581             INIT_GUID(DSOUND_capture_guids[i],  0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
00582         }
00583         DisableThreadLibraryCalls(hInstDLL);
00584         /* Increase refcount on dsound by 1 */
00585         GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)hInstDLL, &hInstDLL);
00586         break;
00587     case DLL_PROCESS_DETACH:
00588         TRACE("DLL_PROCESS_DETACH\n");
00589         break;
00590     default:
00591         TRACE("UNKNOWN REASON\n");
00592         break;
00593     }
00594     return TRUE;
00595 }

Generated on Sat May 26 2012 04:20:12 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.