Initial re-upload of spice2x-24-08-24
This commit is contained in:
128
hooks/audio/backends/mmdevice/device.cpp
Normal file
128
hooks/audio/backends/mmdevice/device.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include "device.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <audioclient.h>
|
||||
#include <endpointvolume.h>
|
||||
|
||||
#include "hooks/audio/audio_private.h"
|
||||
#include "hooks/audio/backends/mmdevice/audio_endpoint_volume.h"
|
||||
#include "hooks/audio/backends/wasapi/audio_client.h"
|
||||
|
||||
#define PRINT_FAILED_RESULT(name, ret) \
|
||||
do { \
|
||||
if (AUDIO_LOG_HRESULT) { \
|
||||
log_warning("audio::mmdevice", "{} failed, hr={}", name, FMT_HRESULT(ret)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_RESULT(x) \
|
||||
do { \
|
||||
HRESULT __ret = (x); \
|
||||
if (FAILED(__ret)) { \
|
||||
PRINT_FAILED_RESULT(__FUNCTION__, __ret); \
|
||||
} \
|
||||
return __ret; \
|
||||
} while (0)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
DEFINE_GUID(IID_IMMDevice,
|
||||
0xd666063f, 0x1587, 0x4e43,
|
||||
0x81, 0xf1, 0xb9, 0x48, 0xe8, 0x07, 0x36, 0x3f);
|
||||
#endif
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIMMDevice::QueryInterface(REFIID riid, void **ppvObj) {
|
||||
if (ppvObj == nullptr) {
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (riid == IID_WrappedIMMDevice ||
|
||||
riid == IID_IMMDevice)
|
||||
{
|
||||
this->AddRef();
|
||||
*ppvObj = this;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return pReal->QueryInterface(riid, ppvObj);
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE WrappedIMMDevice::AddRef() {
|
||||
return pReal->AddRef();
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE WrappedIMMDevice::Release() {
|
||||
|
||||
// get reference count of underlying interface
|
||||
ULONG refs = pReal != nullptr ? pReal->Release() : 0;
|
||||
|
||||
if (refs == 0) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
||||
// IMMDevice
|
||||
HRESULT STDMETHODCALLTYPE WrappedIMMDevice::Activate(
|
||||
REFIID iid,
|
||||
DWORD dwClsCtx,
|
||||
PROPVARIANT *pActivationParams,
|
||||
void **ppInterface)
|
||||
{
|
||||
log_misc("audio::mmdevice", "WrappedIMMDevice::Activate");
|
||||
|
||||
// call original
|
||||
HRESULT ret = pReal->Activate(iid, dwClsCtx, pActivationParams, ppInterface);
|
||||
|
||||
// check for failure
|
||||
if (FAILED(ret)) {
|
||||
PRINT_FAILED_RESULT("IMMDevice::Activate", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (iid == IID_IAudioClient) {
|
||||
|
||||
// prevent initialization recursion when using some ASIO backends that proxy to DirectSound, WASAPI, or WDM
|
||||
// like ASIO4All or FlexASIO
|
||||
if (!hooks::audio::INITIALIZE_LOCK.try_lock()) {
|
||||
log_warning("audio::mmdevice", "ignoring wrap request while backend is initializing, possible recursion");
|
||||
return ret;
|
||||
}
|
||||
std::lock_guard initialize_guard(hooks::audio::INITIALIZE_LOCK, std::adopt_lock);
|
||||
|
||||
auto client = reinterpret_cast<IAudioClient *>(*ppInterface);
|
||||
|
||||
// release old audio client if initialized
|
||||
if (hooks::audio::CLIENT) {
|
||||
hooks::audio::CLIENT->Release();
|
||||
}
|
||||
|
||||
/*
|
||||
ret = wrap_audio_client(pReal, dwClsCtx, pActivationParams, &client);
|
||||
if (FAILED(ret)) {
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
client = wrap_audio_client(client);
|
||||
|
||||
*ppInterface = client;
|
||||
|
||||
// persist the audio client
|
||||
hooks::audio::CLIENT = client;
|
||||
hooks::audio::CLIENT->AddRef();
|
||||
|
||||
} else if (iid == __uuidof(IAudioEndpointVolume) && hooks::audio::VOLUME_HOOK_ENABLED) {
|
||||
*ppInterface = new WrappedIAudioEndpointVolume(reinterpret_cast<IAudioEndpointVolume *>(*ppInterface));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE WrappedIMMDevice::OpenPropertyStore(DWORD stgmAccess, IPropertyStore **ppProperties) {
|
||||
CHECK_RESULT(pReal->OpenPropertyStore(stgmAccess, ppProperties));
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE WrappedIMMDevice::GetId(LPWSTR *ppstrId) {
|
||||
CHECK_RESULT(pReal->GetId(ppstrId));
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE WrappedIMMDevice::GetState(DWORD *pdwState) {
|
||||
CHECK_RESULT(pReal->GetState(pdwState));
|
||||
}
|
||||
Reference in New Issue
Block a user