#define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #include #include #include #include #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(); }