1 /* 2 * Interface for dynamically loading directsound and providing a dummy 3 * implementation if it isn't present. 4 * 5 * Author: Ross Bencina (some portions Phil Burk & Robert Marsanyi) 6 * 7 * For PortAudio Portable Real-Time Audio Library 8 * For more information see: http://www.portaudio.com 9 * Copyright (c) 1999-2006 Phil Burk, Robert Marsanyi and Ross Bencina 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining 12 * a copy of this software and associated documentation files 13 * (the "Software"), to deal in the Software without restriction, 14 * including without limitation the rights to use, copy, modify, merge, 15 * publish, distribute, sublicense, and/or sell copies of the Software, 16 * and to permit persons to whom the Software is furnished to do so, 17 * subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be 20 * included in all copies or substantial portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 26 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 27 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 */ 30 31 /* 32 * The text above constitutes the entire PortAudio license; however, 33 * the PortAudio community also makes the following non-binding requests: 34 * 35 * Any person wishing to distribute modifications to the Software is 36 * requested to send the modifications to the original developer so that 37 * they can be incorporated into the canonical version. It is also 38 * requested that these non-binding requests be included along with the 39 * license above. 40 */ 41 42 /** 43 @file 44 @ingroup hostapi_src 45 */ 46 47 #include "pa_win_ds_dynlink.h" 48 #include "pa_debugprint.h" 49 50 PaWinDsDSoundEntryPoints paWinDsDSoundEntryPoints = { 0, 0, 0, 0, 0, 0, 0 }; 51 52 53 static HRESULT WINAPI DummyDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 54 { 55 (void)rclsid; /* unused parameter */ 56 (void)riid; /* unused parameter */ 57 (void)ppv; /* unused parameter */ 58 return CLASS_E_CLASSNOTAVAILABLE; 59 } 60 61 static HRESULT WINAPI DummyDirectSoundCreate(LPGUID lpcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter) 62 { 63 (void)lpcGuidDevice; /* unused parameter */ 64 (void)ppDS; /* unused parameter */ 65 (void)pUnkOuter; /* unused parameter */ 66 return E_NOTIMPL; 67 } 68 69 static HRESULT WINAPI DummyDirectSoundEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext) 70 { 71 (void)lpDSEnumCallback; /* unused parameter */ 72 (void)lpContext; /* unused parameter */ 73 return E_NOTIMPL; 74 } 75 76 static HRESULT WINAPI DummyDirectSoundEnumerateA(LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext) 77 { 78 (void)lpDSEnumCallback; /* unused parameter */ 79 (void)lpContext; /* unused parameter */ 80 return E_NOTIMPL; 81 } 82 83 static HRESULT WINAPI DummyDirectSoundCaptureCreate(LPGUID lpcGUID, LPDIRECTSOUNDCAPTURE *lplpDSC, LPUNKNOWN pUnkOuter) 84 { 85 (void)lpcGUID; /* unused parameter */ 86 (void)lplpDSC; /* unused parameter */ 87 (void)pUnkOuter; /* unused parameter */ 88 return E_NOTIMPL; 89 } 90 91 static HRESULT WINAPI DummyDirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW lpDSCEnumCallback, LPVOID lpContext) 92 { 93 (void)lpDSCEnumCallback; /* unused parameter */ 94 (void)lpContext; /* unused parameter */ 95 return E_NOTIMPL; 96 } 97 98 static HRESULT WINAPI DummyDirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA lpDSCEnumCallback, LPVOID lpContext) 99 { 100 (void)lpDSCEnumCallback; /* unused parameter */ 101 (void)lpContext; /* unused parameter */ 102 return E_NOTIMPL; 103 } 104 105 #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE 106 static HRESULT WINAPI DummyDirectSoundFullDuplexCreate8( 107 LPCGUID pcGuidCaptureDevice, 108 LPCGUID pcGuidRenderDevice, 109 LPCDSCBUFFERDESC pcDSCBufferDesc, 110 LPCDSBUFFERDESC pcDSBufferDesc, 111 HWND hWnd, 112 DWORD dwLevel, 113 LPDIRECTSOUNDFULLDUPLEX * ppDSFD, 114 LPDIRECTSOUNDCAPTUREBUFFER8 * ppDSCBuffer8, 115 LPDIRECTSOUNDBUFFER8 * ppDSBuffer8, 116 LPUNKNOWN pUnkOuter) 117 { 118 (void)pcGuidCaptureDevice; /* unused parameter */ 119 (void)pcGuidRenderDevice; /* unused parameter */ 120 (void)pcDSCBufferDesc; /* unused parameter */ 121 (void)pcDSBufferDesc; /* unused parameter */ 122 (void)hWnd; /* unused parameter */ 123 (void)dwLevel; /* unused parameter */ 124 (void)ppDSFD; /* unused parameter */ 125 (void)ppDSCBuffer8; /* unused parameter */ 126 (void)ppDSBuffer8; /* unused parameter */ 127 (void)pUnkOuter; /* unused parameter */ 128 129 return E_NOTIMPL; 130 } 131 #endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */ 132 133 void PaWinDs_InitializeDSoundEntryPoints(void) 134 { 135 paWinDsDSoundEntryPoints.hInstance_ = LoadLibraryA("dsound.dll"); 136 if( paWinDsDSoundEntryPoints.hInstance_ != NULL ) 137 { 138 paWinDsDSoundEntryPoints.DllGetClassObject = 139 (HRESULT (WINAPI *)(REFCLSID, REFIID , LPVOID *)) 140 GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DllGetClassObject" ); 141 if( paWinDsDSoundEntryPoints.DllGetClassObject == NULL ) 142 paWinDsDSoundEntryPoints.DllGetClassObject = DummyDllGetClassObject; 143 144 paWinDsDSoundEntryPoints.DirectSoundCreate = 145 (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN)) 146 GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCreate" ); 147 if( paWinDsDSoundEntryPoints.DirectSoundCreate == NULL ) 148 paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate; 149 150 paWinDsDSoundEntryPoints.DirectSoundEnumerateW = 151 (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID)) 152 GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateW" ); 153 if( paWinDsDSoundEntryPoints.DirectSoundEnumerateW == NULL ) 154 paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW; 155 156 paWinDsDSoundEntryPoints.DirectSoundEnumerateA = 157 (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID)) 158 GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateA" ); 159 if( paWinDsDSoundEntryPoints.DirectSoundEnumerateA == NULL ) 160 paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA; 161 162 paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = 163 (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN)) 164 GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureCreate" ); 165 if( paWinDsDSoundEntryPoints.DirectSoundCaptureCreate == NULL ) 166 paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate; 167 168 paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = 169 (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID)) 170 GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateW" ); 171 if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW == NULL ) 172 paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW; 173 174 paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = 175 (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID)) 176 GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateA" ); 177 if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA == NULL ) 178 paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA; 179 180 #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE 181 paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 = 182 (HRESULT (WINAPI *)(LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC, 183 HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *, 184 LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN)) 185 GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundFullDuplexCreate" ); 186 if( paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 == NULL ) 187 paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 = DummyDirectSoundFullDuplexCreate8; 188 #endif 189 } 190 else 191 { 192 DWORD errorCode = GetLastError(); // 126 (0x7E) == ERROR_MOD_NOT_FOUND 193 PA_DEBUG(("Couldn't load dsound.dll error code: %d \n",errorCode)); 194 195 /* initialize with dummy entry points to make live easy when ds isn't present */ 196 paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate; 197 paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW; 198 paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA; 199 paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate; 200 paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW; 201 paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA; 202 #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE 203 paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 = DummyDirectSoundFullDuplexCreate8; 204 #endif 205 } 206 } 207 208 209 void PaWinDs_TerminateDSoundEntryPoints(void) 210 { 211 if( paWinDsDSoundEntryPoints.hInstance_ != NULL ) 212 { 213 /* ensure that we crash reliably if the entry points arent initialised */ 214 paWinDsDSoundEntryPoints.DirectSoundCreate = 0; 215 paWinDsDSoundEntryPoints.DirectSoundEnumerateW = 0; 216 paWinDsDSoundEntryPoints.DirectSoundEnumerateA = 0; 217 paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = 0; 218 paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = 0; 219 paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = 0; 220 221 FreeLibrary( paWinDsDSoundEntryPoints.hInstance_ ); 222 paWinDsDSoundEntryPoints.hInstance_ = NULL; 223 } 224 }