Skip to content

Commit b202489

Browse files
committed
Stub implementation of IMMNotificationClient.
1 parent 25d7f3f commit b202489

3 files changed

Lines changed: 118 additions & 1 deletion

File tree

SarAsio/mmwrapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct ATL_NO_VTABLE SarMMDeviceEnumerator:
2828
{
2929
BEGIN_COM_MAP(SarMMDeviceEnumerator)
3030
COM_INTERFACE_ENTRY(IMMDeviceEnumerator)
31-
END_COM_MAP();
31+
END_COM_MAP()
3232

3333
DECLARE_REGISTRY_RESOURCEID(IDR_SARMMDEVICE)
3434

SarAsio/sarclient.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

191197
void 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+
270318
bool 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

SarAsio/sarclient.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,34 @@ struct SarClient
5959
SarHandleQueueResponse responses[32];
6060
};
6161

62+
struct ATL_NO_VTABLE NotificationClient:
63+
public CComObjectRootEx<CComMultiThreadModel>,
64+
public IMMNotificationClient
65+
{
66+
BEGIN_COM_MAP(NotificationClient)
67+
COM_INTERFACE_ENTRY(IMMNotificationClient)
68+
END_COM_MAP()
69+
70+
DECLARE_NO_REGISTRY()
71+
72+
virtual HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(
73+
_In_ LPCWSTR pwstrDeviceId,
74+
_In_ DWORD dwNewState) override;
75+
virtual HRESULT STDMETHODCALLTYPE OnDeviceAdded(
76+
_In_ LPCWSTR pwstrDeviceId) override;
77+
virtual HRESULT STDMETHODCALLTYPE OnDeviceRemoved(
78+
_In_ LPCWSTR pwstrDeviceId) override;
79+
virtual HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(
80+
_In_ EDataFlow flow,
81+
_In_ ERole role,
82+
_In_ LPCWSTR pwstrDefaultDeviceId) override;
83+
virtual HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(
84+
_In_ LPCWSTR pwstrDeviceId,
85+
_In_ const PROPERTYKEY key) override;
86+
};
87+
6288
bool openControlDevice();
89+
bool openMmNotificationClient();
6390
bool setBufferLayout();
6491
bool createEndpoints();
6592
bool enableRegistryFilter();
@@ -87,6 +114,9 @@ struct SarClient
87114
volatile SarEndpointRegisters *_registers;
88115
HandleQueueCompletion _handleQueueCompletion;
89116
bool _handleQueueStarted;
117+
CComPtr<IMMDeviceEnumerator> _mmEnumerator;
118+
CComObject<NotificationClient> *_mmNotificationClient = nullptr;
119+
bool _mmNotificationClientRegistered = false;
90120
};
91121

92122
} // namespace Sar

0 commit comments

Comments
 (0)