@@ -169,6 +169,12 @@ bool SarClient::start()
169169 return false ;
170170 }
171171
172+ if (!openMmNotificationClient ()) {
173+ OutputDebugString (_T (" Couldn't open MMDevice notification client" ));
174+ stop ();
175+ return false ;
176+ }
177+
172178 if (!setBufferLayout ()) {
173179 OutputDebugString (_T (" Couldn't set layout" ));
174180 stop ();
@@ -190,6 +196,21 @@ bool SarClient::start()
190196
191197void SarClient::stop ()
192198{
199+ if (_mmNotificationClientRegistered) {
200+ _mmEnumerator->UnregisterEndpointNotificationCallback (
201+ _mmNotificationClient);
202+ _mmNotificationClientRegistered = false ;
203+ }
204+
205+ if (_mmNotificationClient) {
206+ _mmNotificationClient->Release ();
207+ _mmNotificationClient = nullptr ;
208+ }
209+
210+ if (_mmEnumerator) {
211+ _mmEnumerator = nullptr ;
212+ }
213+
193214 if (_device != INVALID_HANDLE_VALUE) {
194215 CancelIoEx (_device, nullptr );
195216 CloseHandle (_device);
@@ -267,6 +288,33 @@ bool SarClient::openControlDevice()
267288 return true ;
268289}
269290
291+ bool SarClient::openMmNotificationClient ()
292+ {
293+ if (FAILED (CoCreateInstance (
294+ __uuidof (MMDeviceEnumerator), nullptr , CLSCTX_ALL,
295+ __uuidof (IMMDeviceEnumerator), (LPVOID *)&_mmEnumerator))) {
296+
297+ return false ;
298+ }
299+
300+ if (FAILED (CComObject<NotificationClient>::CreateInstance (
301+ &_mmNotificationClient))) {
302+
303+ return false ;
304+ }
305+
306+ _mmNotificationClient->AddRef ();
307+
308+ if (FAILED (_mmEnumerator->RegisterEndpointNotificationCallback (
309+ _mmNotificationClient))) {
310+
311+ return false ;
312+ }
313+
314+ _mmNotificationClientRegistered = true ;
315+ return true ;
316+ }
317+
270318bool SarClient::setBufferLayout ()
271319{
272320 SarSetBufferLayoutRequest request = {};
@@ -470,4 +518,43 @@ void SarClient::mux(
470518 }
471519}
472520
521+ HRESULT STDMETHODCALLTYPE SarClient::NotificationClient::OnDeviceStateChanged (
522+ _In_ LPCWSTR pwstrDeviceId,
523+ _In_ DWORD dwNewState)
524+ {
525+ OutputDebugString (_T (" OnDeviceStateChanged" ));
526+ return S_OK;
527+ }
528+
529+ HRESULT STDMETHODCALLTYPE SarClient::NotificationClient::OnDeviceAdded (
530+ _In_ LPCWSTR pwstrDeviceId)
531+ {
532+ OutputDebugString (_T (" OnDeviceAdded" ));
533+ return S_OK;
534+ }
535+
536+ HRESULT STDMETHODCALLTYPE SarClient::NotificationClient::OnDeviceRemoved (
537+ _In_ LPCWSTR pwstrDeviceId)
538+ {
539+ OutputDebugString (_T (" OnDeviceRemoved" ));
540+ return S_OK;
541+ }
542+
543+ HRESULT STDMETHODCALLTYPE SarClient::NotificationClient::OnDefaultDeviceChanged (
544+ _In_ EDataFlow flow,
545+ _In_ ERole role,
546+ _In_ LPCWSTR pwstrDefaultDeviceId)
547+ {
548+ OutputDebugString (_T (" OnDefaultDeviceChanged" ));
549+ return S_OK;
550+ }
551+
552+ HRESULT STDMETHODCALLTYPE SarClient::NotificationClient::OnPropertyValueChanged (
553+ _In_ LPCWSTR pwstrDeviceId,
554+ _In_ const PROPERTYKEY key)
555+ {
556+ OutputDebugString (_T (" OnPropertyValueChanged" ));
557+ return S_OK;
558+ }
559+
473560} // namespace Sar
0 commit comments