149 lines
4.9 KiB
C++
149 lines
4.9 KiB
C++
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <Windows.h>
|
|
#include <mmdeviceapi.h>
|
|
#include <combaseapi.h>
|
|
#include <initguid.h>
|
|
#include <functiondiscoverykeys_devpkey.h>
|
|
#include <endpointvolume.h>
|
|
#include <audiopolicy.h>
|
|
#include <audioclient.h>
|
|
#include <Winerror.h>
|
|
|
|
#define EXIT_ON_ERROR(hres) \
|
|
if (FAILED(hres)) { printf("%s - %d\n", __FILE__, __LINE__); goto Exit; }
|
|
|
|
|
|
#define SAFE_RELEASE(punk) \
|
|
if ((punk) != NULL) \
|
|
{ (punk)->Release(); (punk) = NULL; }
|
|
|
|
IMMDeviceEnumerator *deviceEnumeratorPtr = NULL;
|
|
IMMDeviceCollection *deviceCollectionPtr = NULL;
|
|
IMMDevice *endpointPtr = NULL;
|
|
|
|
IAudioEndpointVolume *endpointVolumePtr = NULL;
|
|
IAudioSessionManager2 *sessionManagerPtr = NULL;
|
|
|
|
IAudioSessionEnumerator *sessionEnumeratorPtr = NULL;
|
|
IAudioSessionControl* sessionControlPtr = NULL;
|
|
IAudioSessionControl2 *sessionControl2Ptr = NULL;
|
|
ISimpleAudioVolume *sessionVolumePtr = NULL;
|
|
|
|
void PrintEndpointNames() {
|
|
|
|
HRESULT hr = S_OK;
|
|
IPropertyStore *deviceEndpointPropertiesPtr = NULL;
|
|
LPWSTR endpointID = NULL;
|
|
|
|
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
|
EXIT_ON_ERROR(hr)
|
|
|
|
//MMDeviceEnumerator es el CLSID de toda la vaina de MMDevicear
|
|
hr = CoCreateInstance(
|
|
__uuidof(MMDeviceEnumerator), NULL,
|
|
CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
|
|
(void**)&deviceEnumeratorPtr);
|
|
EXIT_ON_ERROR(hr)
|
|
|
|
//hr = deviceEnumeratorPtr->EnumAudioEndpoints(eRender, DEVICE_STATE_&deviceCollectionPtr); << Elegimos a mano para ahorrar código de iteración
|
|
//Llamar a dispositivo por defecto. 2o param no importa lmao
|
|
hr = deviceEnumeratorPtr->GetDefaultAudioEndpoint(eRender, eConsole, &endpointPtr);
|
|
EXIT_ON_ERROR(hr)
|
|
|
|
//RECUPERAR ENDPOINT ID
|
|
hr = endpointPtr->GetId(&endpointID);
|
|
EXIT_ON_ERROR(hr)
|
|
|
|
//RECUPERAR STRUCT DE PROPIEDADES
|
|
hr = endpointPtr->OpenPropertyStore(STGM_READ, &deviceEndpointPropertiesPtr);
|
|
EXIT_ON_ERROR(hr)
|
|
|
|
|
|
PROPVARIANT varName;
|
|
// Inicializar el struct para poder extraer la información.
|
|
PropVariantInit(&varName);
|
|
|
|
// Cogemos el nombre humano
|
|
hr = deviceEndpointPropertiesPtr->GetValue(PKEY_Device_FriendlyName , &varName);
|
|
EXIT_ON_ERROR(hr)
|
|
|
|
//PINTAR ID + PROPIEDAD RECUPERADA
|
|
printf("Endpoint %d: \"%S\" (%S)\n", 0, varName.pwszVal, endpointID);
|
|
|
|
|
|
//Activamos desde Device para tener control sobre el Endpoint
|
|
hr = endpointPtr->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&endpointVolumePtr);
|
|
EXIT_ON_ERROR(hr)
|
|
|
|
hr = endpointVolumePtr->SetMasterVolumeLevelScalar(0.4f, NULL);
|
|
EXIT_ON_ERROR(hr);
|
|
|
|
//Registramos el gestor de sesiones para conseguir el handle que da el handle de sesiones a nivel informativo
|
|
//Y justo despues, el que da control a nivel sonoro
|
|
hr = endpointPtr->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void**) &sessionManagerPtr);
|
|
EXIT_ON_ERROR(hr);
|
|
|
|
//Ahora si viene el handle de las sesiones
|
|
hr = sessionManagerPtr->GetSessionEnumerator(&sessionEnumeratorPtr);
|
|
EXIT_ON_ERROR(hr);
|
|
|
|
//Cogemos el numero de sesiones y recorreríamos para coger cada una. Aquí, se elige la 0 para, una vez más, no enmarañar el código.
|
|
INT sessionCount;
|
|
hr = sessionEnumeratorPtr->GetCount(&sessionCount);
|
|
EXIT_ON_ERROR(hr);
|
|
|
|
hr = sessionEnumeratorPtr->GetSession(0, (IAudioSessionControl**)&sessionControlPtr);
|
|
EXIT_ON_ERROR(hr);
|
|
|
|
hr = sessionControlPtr->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&sessionControl2Ptr);
|
|
EXIT_ON_ERROR(hr);
|
|
|
|
//Puede que el nombre no se rellene. Esto se debe a que no todos los programas registran su sesión con un nombre humano. SndVol.exe se toma la libertad de pesquisar el nombre a través de los metadatos del ejecutable que la ha creado si es una aplicación Win32, y otro campo si es una aplicación .appx.
|
|
LPWSTR sessionDisplayName;
|
|
hr = sessionControl2Ptr->IsSystemSoundsSession();
|
|
if(hr)
|
|
hr = sessionControl2Ptr->GetDisplayName(&sessionDisplayName);
|
|
else
|
|
sessionDisplayName = L"System Sounds";
|
|
|
|
printf("Sesion 0 de endpoint %S: \"%S\" \n Num sesiones: (%d)\n", varName.pwszVal, sessionDisplayName, sessionCount);
|
|
|
|
hr = sessionControl2Ptr->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&sessionVolumePtr);
|
|
EXIT_ON_ERROR(hr);
|
|
|
|
hr = sessionVolumePtr->SetMute(TRUE, 0);
|
|
EXIT_ON_ERROR(hr);
|
|
|
|
//Limpiamos memoria
|
|
CoTaskMemFree(endpointID);
|
|
endpointID = NULL;
|
|
PropVariantClear(&varName);
|
|
SAFE_RELEASE(deviceEndpointPropertiesPtr)
|
|
SAFE_RELEASE(endpointPtr)
|
|
SAFE_RELEASE(endpointVolumePtr);
|
|
SAFE_RELEASE(sessionManagerPtr);
|
|
SAFE_RELEASE(sessionEnumeratorPtr);
|
|
//SAFE_RELEASE(sessionControlPtr);
|
|
SAFE_RELEASE(sessionControl2Ptr);
|
|
SAFE_RELEASE(sessionVolumePtr);
|
|
|
|
SAFE_RELEASE(deviceEnumeratorPtr)
|
|
SAFE_RELEASE(deviceCollectionPtr)
|
|
return;
|
|
|
|
Exit:
|
|
printf("Error!\n");
|
|
CoTaskMemFree(endpointID);
|
|
SAFE_RELEASE(deviceEnumeratorPtr)
|
|
SAFE_RELEASE(deviceCollectionPtr)
|
|
SAFE_RELEASE(endpointPtr)
|
|
SAFE_RELEASE(deviceEndpointPropertiesPtr)
|
|
CoUninitialize();
|
|
}
|
|
|
|
int main (int argc, char* argv[]) {
|
|
PrintEndpointNames();
|
|
}
|