Initial re-upload of spice2x-24-08-24

This commit is contained in:
2024-08-28 11:10:34 -04:00
commit caa9e02285
1181 changed files with 380065 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
#include "audio_endpoint_volume.h"
#include "util/logging.h"
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::QueryInterface(REFIID riid, void **ppvObj) {
if (ppvObj == nullptr) {
return E_POINTER;
}
if (riid == __uuidof(IAudioEndpointVolume)) {
this->AddRef();
*ppvObj = this;
return S_OK;
}
return pReal->QueryInterface(riid, ppvObj);
}
ULONG STDMETHODCALLTYPE WrappedIAudioEndpointVolume::AddRef() {
return pReal->AddRef();
}
ULONG STDMETHODCALLTYPE WrappedIAudioEndpointVolume::Release() {
// get reference count of underlying interface
ULONG refs = pReal != nullptr ? pReal->Release() : 0;
if (refs == 0) {
delete this;
}
return refs;
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::SetMasterVolumeLevelScalar(float fLevel, LPCGUID pguidEventContext) {
log_misc("audio", "WrappedIAudioEndpointVolume::SetMasterVolumeLevelScalar called; ignoring volume change");
return S_OK;
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::RegisterControlChangeNotify(IAudioEndpointVolumeCallback *pNotify) {
return pReal->RegisterControlChangeNotify(pNotify);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::UnregisterControlChangeNotify(IAudioEndpointVolumeCallback *pNotify) {
return pReal->UnregisterControlChangeNotify(pNotify);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::GetChannelCount(uint32_t *pnChannelCount) {
return pReal->GetChannelCount(pnChannelCount);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::SetMasterVolumeLevel(float fLevelDB, LPCGUID pguidEventContext) {
log_misc("audio", "WrappedIAudioEndpointVolume::SetMasterVolumeLevel called; ignoring volume change");
return S_OK;
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::GetMasterVolumeLevel(float *fLevelDB) {
return pReal->GetMasterVolumeLevel(fLevelDB);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::GetMasterVolumeLevelScalar(float *fLevel) {
return pReal->GetMasterVolumeLevelScalar(fLevel);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::SetChannelVolumeLevel(uint32_t nChannel, float fLevelDB, LPCGUID pguidEventContext) {
log_misc("audio", "WrappedIAudioEndpointVolume::SetChannelVolumeLevel called; ignoring volume change");
return S_OK;
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::SetChannelVolumeLevelScalar(uint32_t nChannel, float fLevel, LPCGUID pguidEventContext) {
log_misc("audio", "WrappedIAudioEndpointVolume::SetChannelVolumeLevelScalar called; ignoring volume change");
return S_OK;
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::GetChannelVolumeLevel(uint32_t nChannel, float *fLevelDB) {
return pReal->GetChannelVolumeLevel(nChannel, fLevelDB);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::GetChannelVolumeLevelScalar(uint32_t nChannel, float *fLevel) {
return pReal->GetChannelVolumeLevelScalar(nChannel, fLevel);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::SetMute(WINBOOL bMute, LPCGUID pguidEventContext) {
log_misc("audio", "WrappedIAudioEndpointVolume::SetMute called; ignoring volume change");
return S_OK;
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::GetMute(WINBOOL *bMute) {
return pReal->GetMute(bMute);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::GetVolumeStepInfo(uint32_t *pnStep, uint32_t *pnStepCount) {
return pReal->GetVolumeStepInfo(pnStep, pnStepCount);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::VolumeStepUp(LPCGUID pguidEventContext) {
log_misc("audio", "WrappedIAudioEndpointVolume::VolumeStepUp called; ignoring volume change");
return S_OK;
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::VolumeStepDown(LPCGUID pguidEventContext) {
log_misc("audio", "WrappedIAudioEndpointVolume::VolumeStepDown called; ignoring volume change");
return S_OK;
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::QueryHardwareSupport(DWORD *pdwHardwareSupportMask) {
return pReal->QueryHardwareSupport(pdwHardwareSupportMask);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioEndpointVolume::GetVolumeRange(float *pflVolumeMindB, float *pflVolumeMaxdB, float *pflVolumeIncrementdB) {
return pReal->GetVolumeRange(pflVolumeMindB, pflVolumeMaxdB, pflVolumeIncrementdB);
}

View File

@@ -0,0 +1,43 @@
#pragma once
#include <stdint.h>
#include <endpointvolume.h>
struct WrappedIAudioEndpointVolume : IAudioEndpointVolume {
explicit WrappedIAudioEndpointVolume(IAudioEndpointVolume *orig) : pReal(orig) {}
WrappedIAudioEndpointVolume(const WrappedIAudioEndpointVolume &) = delete;
WrappedIAudioEndpointVolume &operator=(const WrappedIAudioEndpointVolume &) = delete;
virtual ~WrappedIAudioEndpointVolume() = default;
#pragma region IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
ULONG STDMETHODCALLTYPE AddRef() override;
ULONG STDMETHODCALLTYPE Release() override;
#pragma endregion
#pragma region IAudioEndpointVolume
HRESULT STDMETHODCALLTYPE RegisterControlChangeNotify(IAudioEndpointVolumeCallback *pNotify) override;
HRESULT STDMETHODCALLTYPE UnregisterControlChangeNotify(IAudioEndpointVolumeCallback *pNotify) override;
HRESULT STDMETHODCALLTYPE GetChannelCount(uint32_t *pnChannelCount) override;
HRESULT STDMETHODCALLTYPE SetMasterVolumeLevel(float fLevelDB, LPCGUID pguidEventContext) override;
HRESULT STDMETHODCALLTYPE SetMasterVolumeLevelScalar(float fLevel, LPCGUID pguidEventContext) override;
HRESULT STDMETHODCALLTYPE GetMasterVolumeLevel(float *fLevelDB) override;
HRESULT STDMETHODCALLTYPE GetMasterVolumeLevelScalar(float *fLevel) override;
HRESULT STDMETHODCALLTYPE SetChannelVolumeLevel(uint32_t nChannel, float fLevelDB, LPCGUID pguidEventContext) override;
HRESULT STDMETHODCALLTYPE SetChannelVolumeLevelScalar(uint32_t nChannel, float fLevel, LPCGUID pguidEventContext) override;
HRESULT STDMETHODCALLTYPE GetChannelVolumeLevel(uint32_t nChannel, float *fLevelDB) override;
HRESULT STDMETHODCALLTYPE GetChannelVolumeLevelScalar(uint32_t nChannel, float *fLevel) override;
HRESULT STDMETHODCALLTYPE SetMute(WINBOOL bMute, LPCGUID pguidEventContext) override;
HRESULT STDMETHODCALLTYPE GetMute(WINBOOL *bMute) override;
HRESULT STDMETHODCALLTYPE GetVolumeStepInfo(uint32_t *pnStep, uint32_t *pnStepCount) override;
HRESULT STDMETHODCALLTYPE VolumeStepUp(LPCGUID pguidEventContext) override;
HRESULT STDMETHODCALLTYPE VolumeStepDown(LPCGUID pguidEventContext) override;
HRESULT STDMETHODCALLTYPE QueryHardwareSupport(DWORD *pdwHardwareSupportMask) override;
HRESULT STDMETHODCALLTYPE GetVolumeRange(float *pflVolumeMindB, float *pflVolumeMaxdB, float *pflVolumeIncrementdB) override;
#pragma endregion
private:
IAudioEndpointVolume *const pReal;
};

View 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));
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include <initguid.h>
#include <mmdeviceapi.h>
#include "util/logging.h"
// {7CC2A363-D96F-4BE2-B6CF-2A44AADA424B}
static const GUID IID_WrappedIMMDevice = {
0x7cc2a363, 0xd96f, 0x4be2, { 0xb6, 0xcf, 0x2a, 0x44, 0xaa, 0xda, 0x42, 0x4b }
};
struct WrappedIMMDevice : IMMDevice {
explicit WrappedIMMDevice(IMMDevice *orig) : pReal(orig) {
}
WrappedIMMDevice(const WrappedIMMDevice &) = delete;
WrappedIMMDevice &operator=(const WrappedIMMDevice &) = delete;
virtual ~WrappedIMMDevice() = default;
#pragma region IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
ULONG STDMETHODCALLTYPE AddRef() override;
ULONG STDMETHODCALLTYPE Release() override;
#pragma endregion
#pragma region IMMDevice
HRESULT STDMETHODCALLTYPE Activate(REFIID iid, DWORD dwClsCtx, PROPVARIANT *pActivationParams, void **ppInterface) override;
HRESULT STDMETHODCALLTYPE OpenPropertyStore(DWORD stgmAccess, IPropertyStore **ppProperties) override;
HRESULT STDMETHODCALLTYPE GetId(LPWSTR *ppstrId) override;
HRESULT STDMETHODCALLTYPE GetState(DWORD *pdwState) override;
#pragma endregion
IMMDevice *const pReal;
};

View File

@@ -0,0 +1,82 @@
#include "device_enumerator.h"
#include "device.h"
#ifdef _MSC_VER
DEFINE_GUID(IID_IMMDeviceEnumerator,
0xa95664d2, 0x9614, 0x4f35,
0xa7, 0x46, 0xde, 0x8d, 0xb6, 0x36, 0x17, 0xe6);
#endif
HRESULT STDMETHODCALLTYPE WrappedIMMDeviceEnumerator::QueryInterface(REFIID riid, void **ppvObj) {
if (ppvObj == nullptr) {
return E_POINTER;
}
if (riid == IID_IMMDeviceEnumerator) {
this->AddRef();
*ppvObj = this;
return S_OK;
}
return pReal->QueryInterface(riid, ppvObj);
}
ULONG STDMETHODCALLTYPE WrappedIMMDeviceEnumerator::AddRef() {
return pReal->AddRef();
}
ULONG STDMETHODCALLTYPE WrappedIMMDeviceEnumerator::Release() {
// get reference count of underlying interface
ULONG refs = pReal != nullptr ? pReal->Release() : 0;
if (refs == 0) {
delete this;
}
return refs;
}
HRESULT STDMETHODCALLTYPE WrappedIMMDeviceEnumerator::EnumAudioEndpoints(
EDataFlow dataFlow,
DWORD dwStateMask,
IMMDeviceCollection **ppDevices)
{
return pReal->EnumAudioEndpoints(dataFlow, dwStateMask, ppDevices);
}
HRESULT STDMETHODCALLTYPE WrappedIMMDeviceEnumerator::GetDefaultAudioEndpoint(
EDataFlow dataFlow,
ERole role,
IMMDevice **ppEndpoint)
{
// call orignal
HRESULT ret = this->pReal->GetDefaultAudioEndpoint(dataFlow, role, ppEndpoint);
// check for failure
if (FAILED(ret)) {
log_warning("audio", "IMMDeviceEnumerator::GetDefaultAudioEndpoint failed, hr={}", FMT_HRESULT(ret));
return ret;
}
// wrap interface
*ppEndpoint = new WrappedIMMDevice(*ppEndpoint);
// return original result
return ret;
}
HRESULT STDMETHODCALLTYPE WrappedIMMDeviceEnumerator::GetDevice(
LPCWSTR pwstrId,
IMMDevice **ppDevice)
{
return pReal->GetDevice(pwstrId, ppDevice);
}
HRESULT STDMETHODCALLTYPE WrappedIMMDeviceEnumerator::RegisterEndpointNotificationCallback(
IMMNotificationClient *pClient)
{
return pReal->RegisterEndpointNotificationCallback(pClient);
}
HRESULT STDMETHODCALLTYPE WrappedIMMDeviceEnumerator::UnregisterEndpointNotificationCallback(
IMMNotificationClient *pClient)
{
return pReal->UnregisterEndpointNotificationCallback(pClient);
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include <initguid.h>
#include <mmdeviceapi.h>
#include "util/logging.h"
struct WrappedIMMDeviceEnumerator : IMMDeviceEnumerator {
explicit WrappedIMMDeviceEnumerator(IMMDeviceEnumerator *orig) : pReal(orig) {
}
WrappedIMMDeviceEnumerator(const WrappedIMMDeviceEnumerator &) = delete;
WrappedIMMDeviceEnumerator &operator=(const WrappedIMMDeviceEnumerator &) = delete;
virtual ~WrappedIMMDeviceEnumerator() = default;
#pragma region IUnknown
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
virtual ULONG STDMETHODCALLTYPE AddRef() override;
virtual ULONG STDMETHODCALLTYPE Release() override;
#pragma endregion
#pragma region IMMDeviceEnumerator
virtual HRESULT STDMETHODCALLTYPE EnumAudioEndpoints(EDataFlow dataFlow, DWORD dwStateMask, IMMDeviceCollection **ppDevices) override;
virtual HRESULT STDMETHODCALLTYPE GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, IMMDevice **ppEndpoint) override;
virtual HRESULT STDMETHODCALLTYPE GetDevice(LPCWSTR pwstrId, IMMDevice **ppDevice) override;
virtual HRESULT STDMETHODCALLTYPE RegisterEndpointNotificationCallback(IMMNotificationClient *pClient) override;
virtual HRESULT STDMETHODCALLTYPE UnregisterEndpointNotificationCallback(IMMNotificationClient *pClient) override;
#pragma endregion
private:
IMMDeviceEnumerator *const pReal;
};