|
刚刚那个是测试版,这个是最终版,之前那个代码没有等待音效播放完成后就停止了,音效可能会不完整,我又改了一下,顺便去除了日志记录功能(之前那个版本会在X:\ChromeFix_Logs里记录日志)。
pan.huang1111.cn/s/P6BjyFm?password=wavv63
最终版代码:
- // dllmain.cpp : Defines the entry point for the DLL application.
- // References: blog.csdn.net/king110_1/article/details/121170336
- #include "pch.h"
- #include "Detours/include/detours.h"
- #include <stdio.h>
- #include <mmsystem.h>
- #include <mmdeviceapi.h>
- #include <Audioclient.h>
- #pragma comment(lib, "winmm.lib")
- #if !defined(_WIN64)
- # if defined(_DEBUG)
- # pragma comment(lib, "Detours/lib.X86Debug/detours.lib")
- # else
- # pragma comment(lib, "Detours/lib.X86/detours.lib")
- # endif
- #else
- # if defined(_DEBUG)
- # pragma comment(lib, "Detours/lib.X64Debug/detours.lib")
- # else
- # pragma comment(lib, "Detours/lib.X64/detours.lib")
- # endif
- #endif
- #ifdef DEBUG
- static FILE* filelog = NULL;
- #define OutputLog(...) (filelog ? (fprintf(filelog, __VA_ARGS__), fflush(filelog)) : (printf(__VA_ARGS__), fflush(stdout)))
- #else
- #define OutputLog(...)
- #endif
- typedef BOOL(WINAPI* FuncPlaySoundW)(
- LPCWSTR pszSound,
- HMODULE hmod,
- DWORD fdwSound
- );
- FARPROC pfOrigPlaySoundW = NULL;
- #define EXIT_ON_ERROR(hres, step) if (FAILED(hres)) { goto Exit; }
- #define REFTIMES_PER_SEC 5000000
- int SetFormat(WAVEFORMATEX* wfex)
- {
- wfex->wFormatTag = 1;
- wfex->nChannels = 2;
- wfex->cbSize = 0;
- wfex->nSamplesPerSec = 44100;
- wfex->nAvgBytesPerSec = 44100 * 2 * 2;
- wfex->wBitsPerSample = 16;
- wfex->nBlockAlign = 4;
- return 0;
- }
- const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
- const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
- const IID IID_IAudioClient = __uuidof(IAudioClient);
- const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
- HRESULT AudioClientPlayAudio(INT16* wav_buf, LONG64 dataSize)
- {
- int sk = 0;
- HRESULT hr;
- IMMDevice* pDevice;
- IMMDeviceEnumerator* pEnumerator = NULL;
- IAudioClient* pAudioClient = NULL;
- IAudioRenderClient* pRenderClient = NULL;
- REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
- UINT32 bufferSizeInFrames;
- DWORD initStreamFlags = (AUDCLNT_STREAMFLAGS_RATEADJUST | AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY);
- WAVEFORMATEX pwfx;
- INT16* pData = NULL;
- IAudioClock* audioClock;
- UINT64 audioPlaybackFreq;
- UINT64 audioPlaybackPos;
- UINT64 audioPlaybackPosInSeconds;
- UINT64 audioPlaybackPosInSamples;
- UINT32 wavPlaybackSample = 0;
- UINT32 bufferPadding;
- UINT32 soundBufferLatency;
- UINT32 numFramesToWrite;
- int read = 0, n = 0;
- UINT32 numWavSamples = (UINT32)(dataSize / (2 * sizeof(UINT16)));
- DWORD num = 0;
- hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
- EXIT_ON_ERROR(hr, "CoInitializeEx()");
- hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator);
- EXIT_ON_ERROR(hr, "CoCreateInstance()");
- hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
- EXIT_ON_ERROR(hr, "pEnumerator->GetDefaultAudioEndpoint()");
- hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pAudioClient);
- EXIT_ON_ERROR(hr, "pDevice->Activate()");
- hr = SetFormat(&pwfx);
- EXIT_ON_ERROR(hr, "SetFormat()");
- hr = pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, initStreamFlags, hnsRequestedDuration * 40, 0, &pwfx, NULL);
- EXIT_ON_ERROR(hr, "pAudioClient->Initialize()");
- hr = pAudioClient->GetService(__uuidof(IAudioRenderClient), (LPVOID*)(&pRenderClient));
- EXIT_ON_ERROR(hr, "pAudioClient->GetService()");
- hr = pAudioClient->GetBufferSize(&bufferSizeInFrames);
- EXIT_ON_ERROR(hr, "pAudioClient->GetBufferSize()");
- hr = pAudioClient->Start();
- EXIT_ON_ERROR(hr, "pAudioClient->Start()");
- while (read < dataSize / 2)
- {
- hr = pAudioClient->GetCurrentPadding(&bufferPadding);
- EXIT_ON_ERROR(hr, "pAudioClient->GetCurrentPadding()");
- soundBufferLatency = bufferSizeInFrames / 50;
- numFramesToWrite = soundBufferLatency - bufferPadding;
- hr = pRenderClient->GetBuffer(numFramesToWrite, (BYTE**)(&pData));
- EXIT_ON_ERROR(hr, "pRenderClient->GetBuffer()");
- for (UINT32 i = 0; i < numFramesToWrite; i++)
- {
- pData[2 * i] = wav_buf[sk++];
- pData[2 * i + 1] = wav_buf[sk++];
- read = read + 2;
- }
- hr = pRenderClient->ReleaseBuffer(numFramesToWrite, 0);
- EXIT_ON_ERROR(hr, "pRenderClient->ReleaseBuffer()");
- hr = pAudioClient->GetService(__uuidof(IAudioClock), (LPVOID*)(&audioClock));
- EXIT_ON_ERROR(hr, "pAudioClient->GetService()");
- audioClock->GetFrequency(&audioPlaybackFreq);
- audioClock->GetPosition(&audioPlaybackPos, 0);
- audioClock->Release();
- audioPlaybackPosInSeconds = audioPlaybackPos / audioPlaybackFreq;
- audioPlaybackPosInSamples = audioPlaybackPosInSeconds * 44100;
- }
- UINT32 padding;
- while (1)
- {
- pAudioClient->GetCurrentPadding(&padding);
- if (padding == 0) break;
- Sleep(100);
- }
- Exit:
- pAudioClient->Stop();
- pAudioClient->Release();
- pRenderClient->Release();
- CoUninitialize();
- return hr;
- }
- // Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, s16, 1411 kb/s
- unsigned char AudioData[349532] = {
- ... // 这里面是完成音效的数据,需要按照要求的格式从wav音频里提取出数据
- };
- HANDLE g_hPlayEvent;
- DWORD WINAPI AudioThread(LPVOID lpParameter)
- {
- while (1)
- {
- WaitForSingleObject(g_hPlayEvent, INFINITE);
- AudioClientPlayAudio((INT16*)AudioData, sizeof(AudioData));
- ResetEvent(g_hPlayEvent);
- }
- }
- BOOL
- WINAPI
- MyPlaySoundW(
- LPCWSTR pszSound,
- HMODULE hmod,
- DWORD fdwSound
- )
- {
- OutputLog("PlaySoundW(%ls, %d)\n", pszSound, fdwSound);
- if (pszSound && !wcscmp(pszSound, L"complete.wav") && !hmod && fdwSound == 131075)
- {
- OutputLog("Intercepted, calling AudioClient to play the audio.\n");
- SetEvent(g_hPlayEvent);
- return TRUE;
- }
- return ((FuncPlaySoundW)pfOrigPlaySoundW)(pszSound, hmod, fdwSound);
- }
- void StartHook()
- {
- DetourRestoreAfterWith();
- DetourTransactionBegin();
- DetourUpdateThread(GetCurrentThread());
- HMODULE hWinmm = LoadLibraryW(L"winmm.dll");
- if (hWinmm)
- pfOrigPlaySoundW = GetProcAddress(hWinmm, "PlaySoundW");
- if (pfOrigPlaySoundW)
- DetourAttach(&(PVOID&)pfOrigPlaySoundW, MyPlaySoundW);
- else
- OutputLog("Could not find PlaySoundW in winmm.dll\n");
- LONG error = DetourTransactionCommit();
- if (error == NO_ERROR)
- {
- OutputLog("Hooked functions\n");
- }
- else
- {
- OutputLog("Error hooking functions: %ld\n", error);
- }
- }
- BOOL APIENTRY DllMain( HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
- {
- if (DetourIsHelperProcess())
- {
- return TRUE;
- }
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- {
- WCHAR lpExeFilePath[MAX_PATH];
- GetModuleFileNameW(GetModuleHandle(NULL), lpExeFilePath, MAX_PATH);
- WCHAR* lpExeFileName = wcsrchr(lpExeFilePath, L'\\');
- if (lpExeFileName == NULL)
- lpExeFileName = lpExeFilePath;
- else
- lpExeFileName++;
- if (!_wcsicmp(lpExeFileName, L"chrome.exe"))
- {
- #ifdef DEBUG
- char logfile[MAX_PATH];
- sprintf_s(logfile, MAX_PATH, "X:\\ChromeFix_Logs\\Chromefix-%d.log", GetCurrentProcessId());
- if (fopen_s(&filelog, logfile, "a+"))
- filelog = NULL;
- OutputLog("Attached to process %d, command line: %ls\n", GetCurrentProcessId(), GetCommandLineW());
- #endif
- g_hPlayEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- CreateThread(NULL, 0, AudioThread, NULL, 0, NULL);
- StartHook();
- }
- break;
- }
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
- }
复制代码 |
评分
-
查看全部评分
|