Initial re-upload of spice2x-24-08-24
This commit is contained in:
112
hooks/audio/backends/mmdevice/audio_endpoint_volume.cpp
Normal file
112
hooks/audio/backends/mmdevice/audio_endpoint_volume.cpp
Normal 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);
|
||||
}
|
||||
43
hooks/audio/backends/mmdevice/audio_endpoint_volume.h
Normal file
43
hooks/audio/backends/mmdevice/audio_endpoint_volume.h
Normal 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;
|
||||
};
|
||||
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));
|
||||
}
|
||||
36
hooks/audio/backends/mmdevice/device.h
Normal file
36
hooks/audio/backends/mmdevice/device.h
Normal 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;
|
||||
};
|
||||
82
hooks/audio/backends/mmdevice/device_enumerator.cpp
Normal file
82
hooks/audio/backends/mmdevice/device_enumerator.cpp
Normal 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);
|
||||
}
|
||||
33
hooks/audio/backends/mmdevice/device_enumerator.h
Normal file
33
hooks/audio/backends/mmdevice/device_enumerator.h
Normal 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;
|
||||
};
|
||||
Reference in New Issue
Block a user