某浏览器有个静音的效果。可以实现一键静音。花了点时间看了下,模拟了一个。具体模块请自行翻阅
audiomute.dll
#include "StdAfx.h"
#include "Mmsystem.h"
#include "disableAudio.h"
#include "mhook-lib/mhook.h"
#include "Mmdeviceapi.h"
#include "Audioclient.h"
#define DSERR_NODRIVER 0x88780078
static BOOL g_bAudioStatus = TRUE;
/////////////////////////////waveOutWrite/////////////////////////////////////////////
MMRESULT(WINAPI *TruewaveOutWrite)(HWAVEOUT ,
LPWAVEHDR ,
UINT) = (MMRESULT(WINAPI *)
(HWAVEOUT ,
LPWAVEHDR ,
UINT))GetProcAddress(LoadLibrary(L"Winmm.dll"), "waveOutWrite");
MMRESULT WINAPI HookwaveOutWrite(HWAVEOUT hwo,
LPWAVEHDR pwh,
UINT cbwh
)
{
if(g_bAudioStatus)
{
return TruewaveOutWrite(hwo, pwh, cbwh);
}
return MMSYSERR_NOERROR;
}
/////////////////////////////midiStreamOut/////////////////////////////////////////////
MMRESULT(WINAPI *TruemidiStreamOut)(HMIDISTRM hMidiStream,
LPMIDIHDR lpMidiHdr,
UINT cbMidiHdr) = (MMRESULT(WINAPI *)
(HMIDISTRM hMidiStream,
LPMIDIHDR lpMidiHdr,
UINT cbMidiHdr))GetProcAddress(LoadLibrary(L"Winmm.dll"), "midiStreamOut");
MMRESULT WINAPI HookmidiStreamOut(HMIDISTRM hMidiStream,
LPMIDIHDR lpMidiHdr,
UINT cbMidiHdr
)
{
if(g_bAudioStatus)
{
return TruemidiStreamOut(hMidiStream, lpMidiHdr, cbMidiHdr);
}
return MMSYSERR_NOERROR;
}
/////////////////////////////DirectSoundCreate8/////////////////////////////////////////////
HRESULT(WINAPI *TrueDirectSoundCreate8)(PVOID,
PVOID,
PVOID) = (HRESULT(WINAPI *)
(PVOID,
PVOID,
PVOID))GetProcAddress(LoadLibrary(L"dsound.dll"), "DirectSoundCreate8");
HRESULT WINAPI HookDirectSoundCreate8(PVOID pv1,
PVOID pv2,
PVOID pv3
)
{
if(g_bAudioStatus)
{
return TrueDirectSoundCreate8(pv1, pv2, pv3);
}
return DSERR_NODRIVER;
}
////////////////////////////DirectSoundCreate//////////////////////////////////////////////
HRESULT(WINAPI *TrueDirectSoundCreate)(PVOID,
PVOID,
PVOID) = (HRESULT(WINAPI *)
(PVOID,
PVOID,
PVOID))GetProcAddress(LoadLibrary(L"dsound.dll"), "DirectSoundCreate");
HRESULT WINAPI HookDirectSoundCreate(PVOID pv1,
PVOID pv2,
PVOID pv3
)
{
if(g_bAudioStatus)
{
return TrueDirectSoundCreate(pv1, pv2, pv3);
}
return DSERR_NODRIVER;
}
//////////////////////////////////////////////////////////////////////////
int CheckOsVer()
{
int result = 0;
OSVERSIONINFOW VersionInformation;
VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
GetVersionExW(&VersionInformation);
if(VersionInformation.dwPlatformId == 2)
{
if(VersionInformation.dwMajorVersion == 5)
{
return 1;
}
if(VersionInformation.dwMajorVersion >= 6)
{
return 2;
}
}
else
{
result = 1;
if(VersionInformation.dwPlatformId == 1)
{
return result;
}
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
//int (__cdecl *TrueAudiosesProc)(int a1, int a2, int a3);
//typedef char (__fastcall *pFunc)(void* pthis,int dummy,const char *str);
int (__fastcall *TrueAudiosesProc)(void* pthis, int a0, int a1, int a2, int a3);
int __fastcall HookAudiosesProc(void* pthis, int a0, int a1, int a2, int a3)
{
if(!g_bAudioStatus)
{
a3 |= 2u;
}
return TrueAudiosesProc(pthis, a0, a1, a2, a3);
}
DWORD GetAudiosesProc()
{
DWORD dwAddress = 0;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
IMMDeviceEnumerator *pEnumerator = NULL;
IMMDevice *pDevice = NULL;
IAudioClient *pAudioClient = NULL;
WAVEFORMATEX *pwfx = NULL;
REFERENCE_TIME hnsRequestedDuration = 10000000;
UINT32 bufferFrameCount;
IAudioRenderClient * _IAudioRenderClient = NULL;
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,
CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator),
(void**)&pEnumerator);
if(!SUCCEEDED(hr))
{
goto Exit0;
}
hr = pEnumerator->GetDefaultAudioEndpoint(
eRender, eMultimedia, &pDevice);
if(!SUCCEEDED(hr))
{
goto Exit0;
}
hr = pDevice->Activate(
__uuidof(IAudioClient), CLSCTX_ALL,
NULL, (void**)&pAudioClient);
if(!SUCCEEDED(hr))
{
goto Exit0;
}
hr = pAudioClient->GetMixFormat(&pwfx);
if(!SUCCEEDED(hr))
{
goto Exit0;
}
hr = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_SHARED,
0,
hnsRequestedDuration,
0,
pwfx,
NULL);
if(!SUCCEEDED(hr))
{
goto Exit0;
}
hr = pAudioClient->GetBufferSize(&bufferFrameCount);
if(!SUCCEEDED(hr))
{
goto Exit0;
}
hr = pAudioClient->GetService(__uuidof(IAudioRenderClient), (void**)&_IAudioRenderClient);
if(!SUCCEEDED(hr))
{
goto Exit0;
}
dwAddress = *((PDWORD)_IAudioRenderClient) + 4 * 4;
Exit0:
if(pEnumerator)
{
pEnumerator->Release();
pEnumerator = NULL;
}
if(pDevice)
{
pDevice->Release();
pDevice = NULL;
}
if(pwfx)
{
CoTaskMemFree(pwfx);
}
if(pAudioClient)
{
pAudioClient->Release();
}
if(_IAudioRenderClient)
{
_IAudioRenderClient->Release();
}
CoUninitialize();
return dwAddress;
}
void DisableAudionOnVistaLater()
{
DWORD dwRet = GetAudiosesProc();
if(dwRet == 0)
{
return;
}
TrueAudiosesProc = (int (__fastcall *)(void* pthis, int a0, int a1, int a2, int a3)) * ((PDWORD)dwRet);
if(TrueAudiosesProc == 0)
{
return;
}
Mhook_SetHook((PVOID*)&TrueAudiosesProc, HookAudiosesProc);
}
//////////////////////////////////////////////////////////////////////////
void InstallHook()
{
static BOOL bFirst = TRUE;
if(!bFirst)
{
return ;
}
bFirst = FALSE;
if(TruewaveOutWrite != NULL)
{
Mhook_SetHook((PVOID*)&TruewaveOutWrite, HookwaveOutWrite);
}
if(TruemidiStreamOut != NULL)
{
Mhook_SetHook((PVOID*)&TruemidiStreamOut, HookmidiStreamOut);
}
if(TrueDirectSoundCreate8 != NULL)
{
Mhook_SetHook((PVOID*)&TrueDirectSoundCreate8, HookDirectSoundCreate8);
}
if(TrueDirectSoundCreate != NULL)
{
Mhook_SetHook((PVOID*)&TrueDirectSoundCreate, HookDirectSoundCreate);
}
if(CheckOsVer() == 2)
{
//继续其他的HOOK
DisableAudionOnVistaLater();
}
}
void SetAudioStatus(BOOL bOpen)
{
if(bOpen == g_bAudioStatus)
{
return ;
}
//如果不是呢??
InstallHook();
g_bAudioStatus = bOpen;
return;
}
BOOL GetAudioStatus()
{
return g_bAudioStatus;
}
参考资料:
1、
Windows下Core Audio APIS 音频应用开发(一)
2、用detours对C++类成员函数加钩子
3、
Hook Com接口函数
4、mhooklib库及百度搜索。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!