00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "CATDirectSoundIntercept.h"
00014 #ifdef CAT_CONFIG_WIN32
00015
00016 #define DIRECTSOUND_VERSION 0x0900
00017 #define INITGUID
00018 #include <dsound.h>
00019 #undef INITGUID
00020 #include <dmusicc.h>
00021 #include <dmusici.h>
00022 #include <cguid.h>
00023
00024
00025
00026 CATINTERCEPT_COM_TABLE_ENTRY kBufferInterceptTable[] =
00027 {
00028
00029 { 12, CATDirectSoundIntercept::OnPlayBuffer, 5},
00030
00031
00032
00033
00034 {(CATUInt32)-1,0,-1}
00035 };
00036
00037
00038
00039 CATINTERCEPT_COM_TABLE_ENTRY kEAXBufferInterceptTable[] =
00040 {
00041
00042 { 12, CATDirectSoundIntercept::OnPlayBufferEAX, 5},
00043
00044
00045
00046
00047 {(CATUInt32)-1,0,-1}
00048 };
00049
00050 CATINTERCEPT_COM_TABLE_ENTRY kPerformanceInterceptTable[] =
00051 {
00052
00053 { 4, CATDirectSoundIntercept::OnPlaySegment, 5},
00054 { 46, CATDirectSoundIntercept::OnPlaySegmentEx, 5},
00055
00056 {(CATUInt32)-1,0,-1}
00057 };
00058
00059 CATDirectSoundIntercept::CATDirectSoundIntercept()
00060 {
00061 CoInitializeEx(0,0);
00062 fDSoundDLL = ::LoadLibrary(L"dsound.dll");
00063 fDSound3DDLL = ::LoadLibrary(L"dsound3d.dll");
00064 fDSound3DEaxDLL = ::LoadLibrary(L"eax.dll");
00065 }
00066
00067 CATDirectSoundIntercept::~CATDirectSoundIntercept()
00068 {
00069
00070 RestoreAll();
00071
00072
00073 if (fDSound3DDLL)
00074 FreeLibrary(fDSound3DDLL);
00075
00076 if (fDSoundDLL)
00077 FreeLibrary(fDSoundDLL);
00078
00079 if (fDSound3DEaxDLL)
00080 FreeLibrary(fDSound3DEaxDLL);
00081
00082 CoUninitialize();
00083 }
00084
00085 CATResult CATDirectSoundIntercept::HookFunctions()
00086 {
00087
00088
00089
00090 DSoundCreate8Func tmpDSoundCreate8 = 0;
00091 IDirectSound8* tmpDS8 = 0;
00092
00093 if (!fDSoundDLL)
00094 return CATRESULT(CAT_ERR_INTERCEPT_NO_DSOUND);
00095
00096 tmpDSoundCreate8 = (DSoundCreate8Func)::GetProcAddress(fDSoundDLL,"DirectSoundCreate8");
00097 if (!tmpDSoundCreate8)
00098 return CATRESULT(CAT_ERR_INTERCEPT_NO_DSOUND);
00099
00100 tmpDSoundCreate8(0,(void**)&tmpDS8, 0);
00101 if (tmpDS8 == 0)
00102 return CATRESULT(CAT_ERR_INTERCEPT_NO_DSOUND);
00103
00104 tmpDS8->SetCooperativeLevel(::GetDesktopWindow(),DSSCL_PRIORITY);
00105
00106 ::OutputDebugString(L"Hooking DirectSound8...\n");
00107 CATResult result = HookDSound(tmpDS8,&kBufferInterceptTable[0]);
00108 if (CATFAILED(result))
00109 ::OutputDebugString(L"Failed hooking DirectSound8.\n");
00110
00111 if (tmpDS8)
00112 tmpDS8->Release();
00113
00114 if (fDSound3DEaxDLL)
00115 {
00116
00117 tmpDSoundCreate8 = (DSoundCreate8Func)::GetProcAddress(fDSound3DEaxDLL,"EAXDirectSoundCreate8");
00118 if (tmpDSoundCreate8)
00119 {
00120 tmpDSoundCreate8(0,(void**)&tmpDS8, 0);
00121 if (tmpDS8)
00122 {
00123 tmpDS8->SetCooperativeLevel(::GetDesktopWindow(),DSSCL_PRIORITY);
00124 ::OutputDebugString(L"Hooking EAX DirectSound...\n");
00125 result = HookDSound(tmpDS8,&kEAXBufferInterceptTable[0]);
00126 if (CATFAILED(result))
00127 ::OutputDebugString(L"Failed hooking EAX DirectSound.\n");
00128 tmpDS8->Release();
00129 }
00130 }
00131 }
00132
00133
00134
00135
00136
00137 IDirectMusicPerformance8* tmpPerformance = 0;
00138
00139 CoCreateInstance(CLSID_DirectMusicPerformance,
00140 NULL,
00141 CLSCTX_INPROC,
00142 IID_IDirectMusicPerformance8,
00143 (void**)&tmpPerformance );
00144
00145 if (tmpPerformance)
00146 {
00147 result = InterceptCOMObject(tmpPerformance,&kPerformanceInterceptTable[0],0);
00148
00149 tmpPerformance->Release();
00150 }
00151
00152 return result;
00153 }
00154
00155 CATResult CATDirectSoundIntercept::HookDSound(IDirectSound8* tmpDS8,CATINTERCEPT_COM_TABLE_ENTRY* interceptTable)
00156 {
00157 IDirectSoundBuffer* tmpDSPrimaryBuffer = 0;
00158 IDirectSoundBuffer* tmpDSBuffer = 0;
00159 IDirectSoundBuffer8* tmpDSBuffer8 = 0;
00160 IDirectSound3DBuffer* tmpDSBuffer3D = 0;
00161 IDirectSound3DListener* tmpDSListener3D = 0;
00162
00163 DSBUFFERDESC bufferDesc;
00164 memset(&bufferDesc, 0, sizeof(DSBUFFERDESC));
00165 bufferDesc.dwSize = sizeof(DSBUFFERDESC);
00166 bufferDesc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
00167
00168 HRESULT hr = S_OK;
00169
00170 if (SUCCEEDED(hr = tmpDS8->CreateSoundBuffer(&bufferDesc, &tmpDSPrimaryBuffer, NULL)))
00171 {
00172
00173 WAVEFORMATEX waveFormat;
00174 memset(&waveFormat, 0, sizeof(WAVEFORMATEX));
00175 waveFormat.wFormatTag = WAVE_FORMAT_PCM;
00176 waveFormat.nChannels = 2;
00177 waveFormat.nSamplesPerSec = 22050;
00178 waveFormat.nBlockAlign = 4;
00179 waveFormat.wBitsPerSample = 16;
00180 waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
00181 hr = tmpDSPrimaryBuffer->SetFormat(&waveFormat);
00182
00183
00184 hr = tmpDSPrimaryBuffer->QueryInterface(IID_IDirectSound3DListener, (LPVOID*)&tmpDSListener3D);
00185
00186
00187 waveFormat.nChannels = 1;
00188 waveFormat.nBlockAlign = 2;
00189 waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
00190
00191 bufferDesc.dwFlags = DSBCAPS_CTRL3D;
00192 bufferDesc.lpwfxFormat = &waveFormat;
00193 bufferDesc.guid3DAlgorithm = DS3DALG_NO_VIRTUALIZATION;
00194 bufferDesc.dwBufferBytes = waveFormat.nAvgBytesPerSec;
00195 hr = tmpDS8->CreateSoundBuffer(&bufferDesc,&tmpDSBuffer,0);
00196 if (tmpDSBuffer)
00197 {
00198
00199 hr = tmpDSBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&tmpDSBuffer8);
00200
00201
00202 hr = tmpDSBuffer->QueryInterface(IID_IDirectSound3DBuffer, (LPVOID*)&tmpDSBuffer3D);
00203 }
00204 }
00205
00206
00207 CATResult result;
00208 result = InterceptCOMObject(tmpDSBuffer,interceptTable,0);
00209
00210
00211
00212 if (tmpDSBuffer)
00213 tmpDSBuffer->Release();
00214
00215 if (tmpDSBuffer3D)
00216 tmpDSBuffer3D->Release();
00217
00218 if (tmpDSListener3D)
00219 tmpDSListener3D->Release();
00220
00221 if (tmpDSBuffer8)
00222 tmpDSBuffer8->Release();
00223
00224 if (tmpDSPrimaryBuffer)
00225 tmpDSPrimaryBuffer->Release();
00226
00227 return result;
00228 }
00229
00230
00231 CATHOOKFUNC HRESULT CATDirectSoundIntercept::OnPlayBuffer(CATHOOK* hookInst,
00232 IDirectSound* dsound,
00233 DWORD dwReserved1,
00234 DWORD dwPriority,
00235 DWORD dwFlags)
00236 {
00237 CATHOOK_PROLOGUE(4);
00238 ::OutputDebugString(L"ds:Play\n");
00239 CATHOOK_CALLORIGINAL_WINAPI(hookInst, 4);
00240 CATHOOK_EPILOGUE_WINAPI(4);
00241 }
00242
00243 CATHOOKFUNC HRESULT CATDirectSoundIntercept::OnPlayBufferEAX(CATHOOK* hookInst,
00244 IDirectSound* dsound,
00245 DWORD dwReserved1,
00246 DWORD dwPriority,
00247 DWORD dwFlags)
00248 {
00249 CATHOOK_PROLOGUE(4);
00250 ::OutputDebugString(L"eax:Play\n");
00251 CATHOOK_CALLORIGINAL_WINAPI(hookInst, 4);
00252 CATHOOK_EPILOGUE_WINAPI(4);
00253 }
00254
00255 CATHOOKFUNC HRESULT CATDirectSoundIntercept::OnLockBuffer(CATHOOK* hookInst,
00256 IDirectSound* dsound,
00257 DWORD dwOffset,
00258 DWORD dwBytes,
00259 LPVOID* ppvAudioPtr1,
00260 LPDWORD pdwAudioBytes1,
00261 LPVOID* ppvAudioPtr2,
00262 LPDWORD pdwAudioBytes2,
00263 DWORD dwFlags)
00264 {
00265 CATHOOK_PROLOGUE(8);
00266
00267 CATHOOK_CALLORIGINAL_WINAPI(hookInst, 8);
00268
00269
00270 CATHOOK_EPILOGUE_WINAPI(8);
00271 }
00272
00273 CATHOOKFUNC HRESULT CATDirectSoundIntercept::OnUnlockBuffer( CATHOOK* hookInst,
00274 IDirectSound* dsound,
00275 LPVOID pvAudioPtr1,
00276 DWORD dwAudioBytes1,
00277 LPVOID pvAudioPtr2,
00278 DWORD dwAudioBytes2)
00279 {
00280 CATHOOK_PROLOGUE(5);
00281
00282 CATHOOK_CALLORIGINAL_WINAPI(hookInst, 5);
00283
00284
00285 CATHOOK_EPILOGUE_WINAPI(5);
00286 }
00287
00288 CATHOOKFUNC HRESULT CATDirectSoundIntercept::OnPlaySegment( CATHOOK* hookInst,
00289 IDirectMusicPerformance* performance,
00290 IDirectMusicSegment* pSegment,
00291 DWORD dwFlags,
00292 DWORD startTimeLow,
00293 DWORD startTimeHigh,
00294 IDirectMusicSegmentState** ppSegmentState)
00295 {
00296 CATHOOK_PROLOGUE(6);
00297 ::OutputDebugString(L"ds:PlaySegment\n");
00298 CATHOOK_CALLORIGINAL_WINAPI(hookInst, 6);
00299
00300
00301 CATHOOK_EPILOGUE_WINAPI(6);
00302 }
00303
00304 CATHOOKFUNC HRESULT CATDirectSoundIntercept::OnPlaySegmentEx( CATHOOK* hookInst,
00305 IDirectMusicPerformance* performance,
00306 IUnknown* pSource,
00307 WCHAR* pwzSegmentName,
00308 IUnknown* pTransition,
00309 DWORD dwFlags,
00310 DWORD startTimeLow,
00311 DWORD startTimeHigh,
00312 IDirectMusicSegmentState** ppSegmentState,
00313 IUnknown* pFrom,
00314 IUnknown* pAudioPath)
00315 {
00316 CATHOOK_PROLOGUE(10);
00317 ::OutputDebugString(L"ds:PlaySegmentEx\n");
00318 CATHOOK_CALLORIGINAL_WINAPI(hookInst, 10);
00319
00320
00321 CATHOOK_EPILOGUE_WINAPI(10);
00322 }
00323
00324 #endif // CAT_CONFIG_WIN32