Skip to content

Commit 1e15746

Browse files
committed
Protect COM callbacks from unhandled exceptions during RDP session switch
1 parent 39958db commit 1e15746

File tree

3 files changed

+131
-51
lines changed

3 files changed

+131
-51
lines changed

EarTrumpet/DataModel/WindowsAudio/Internal/AudioDevice.cs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,20 +109,27 @@ public AudioDevice(IAudioDeviceManager deviceManager, IMMDevice device, Dispatch
109109

110110
public unsafe void OnNotify(AUDIO_VOLUME_NOTIFICATION_DATA* pNotify)
111111
{
112-
_volume = (*pNotify).fMasterVolume;
113-
if (App.Settings.UseLogarithmicVolume)
112+
try
114113
{
115-
_deviceVolume.GetMasterVolumeLevel(out _volume);
116-
}
117-
_isMuted = (*pNotify).bMuted != 0;
114+
_volume = (*pNotify).fMasterVolume;
115+
if (App.Settings.UseLogarithmicVolume)
116+
{
117+
_deviceVolume.GetMasterVolumeLevel(out _volume);
118+
}
119+
_isMuted = (*pNotify).bMuted != 0;
118120

119-
_channels.OnNotify((nint)pNotify, *pNotify);
121+
_channels.OnNotify((nint)pNotify, *pNotify);
120122

121-
_dispatcher.Invoke((Action)(() =>
123+
_dispatcher.Invoke((Action)(() =>
124+
{
125+
RaisePropertyChanged(nameof(Volume));
126+
RaisePropertyChanged(nameof(IsMuted));
127+
}));
128+
}
129+
catch (Exception ex)
122130
{
123-
RaisePropertyChanged(nameof(Volume));
124-
RaisePropertyChanged(nameof(IsMuted));
125-
}));
131+
Trace.WriteLine($"AudioDevice OnNotify: {ex}");
132+
}
126133
}
127134

128135
/// <summary>

EarTrumpet/DataModel/WindowsAudio/Internal/AudioDeviceSession.cs

Lines changed: 102 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -426,80 +426,146 @@ private void DisconnectSession()
426426
_isDisconnected = true;
427427
_dispatcher.BeginInvoke((Action)(() =>
428428
{
429-
RaisePropertyChanged(nameof(State));
429+
try
430+
{
431+
RaisePropertyChanged(nameof(State));
432+
}
433+
catch (Exception ex)
434+
{
435+
Trace.WriteLine($"AudioDeviceSession DisconnectSession dispatch: {ex}");
436+
}
430437
}));
431438
}
432439

433440
unsafe void IAudioSessionEvents.OnSimpleVolumeChanged(float NewVolume, BOOL NewMute, Guid* EventContext)
434441
{
435-
_volume = NewVolume;
436-
_isMuted = NewMute != 0;
442+
try
443+
{
444+
_volume = NewVolume;
445+
_isMuted = NewMute != 0;
437446

438-
_dispatcher.BeginInvoke((Action)(() =>
447+
_dispatcher.BeginInvoke((Action)(() =>
448+
{
449+
RaisePropertyChanged(nameof(Volume));
450+
RaisePropertyChanged(nameof(IsMuted));
451+
}));
452+
}
453+
catch (Exception ex)
439454
{
440-
RaisePropertyChanged(nameof(Volume));
441-
RaisePropertyChanged(nameof(IsMuted));
442-
}));
455+
Trace.WriteLine($"AudioDeviceSession OnSimpleVolumeChanged: {ex}");
456+
}
443457
}
444458

445459
unsafe void IAudioSessionEvents.OnGroupingParamChanged(Guid* NewGroupingParam, Guid* EventContext)
446460
{
447-
GroupingParam = *NewGroupingParam;
448-
Trace.WriteLine($"AudioDeviceSession OnGroupingParamChanged {ExeName} {Id}");
449-
_dispatcher.BeginInvoke((Action)(() =>
461+
try
450462
{
451-
RaisePropertyChanged(nameof(GroupingParam));
452-
}));
463+
GroupingParam = *NewGroupingParam;
464+
Trace.WriteLine($"AudioDeviceSession OnGroupingParamChanged {ExeName} {Id}");
465+
_dispatcher.BeginInvoke((Action)(() =>
466+
{
467+
RaisePropertyChanged(nameof(GroupingParam));
468+
}));
469+
}
470+
catch (Exception ex)
471+
{
472+
Trace.WriteLine($"AudioDeviceSession OnGroupingParamChanged: {ex}");
473+
}
453474
}
454475

455476
void IAudioSessionEvents.OnStateChanged(AudioSessionState NewState)
456477
{
457-
Trace.WriteLine($"AudioDeviceSession OnStateChanged {NewState} {ExeName} {Id}");
478+
try
479+
{
480+
Trace.WriteLine($"AudioDeviceSession OnStateChanged {NewState} {ExeName} {Id}");
458481

459-
_state = NewState;
482+
_state = NewState;
460483

461-
if (_isMoved && NewState == AudioSessionState.AudioSessionStateActive)
462-
{
463-
_isMoved = false;
484+
if (_isMoved && NewState == AudioSessionState.AudioSessionStateActive)
485+
{
486+
_isMoved = false;
487+
}
488+
else if (_moveOnInactive && NewState == AudioSessionState.AudioSessionStateInactive)
489+
{
490+
_isMoved = true;
491+
_moveOnInactive = false;
492+
}
493+
494+
_dispatcher.BeginInvoke((Action)(() =>
495+
{
496+
try
497+
{
498+
RaisePropertyChanged(nameof(State));
499+
}
500+
catch (Exception ex)
501+
{
502+
Trace.WriteLine($"AudioDeviceSession OnStateChanged dispatch: {ex}");
503+
}
504+
}));
464505
}
465-
else if (_moveOnInactive && NewState == AudioSessionState.AudioSessionStateInactive)
506+
catch (Exception ex)
466507
{
467-
_isMoved = true;
468-
_moveOnInactive = false;
508+
Trace.WriteLine($"AudioDeviceSession OnStateChanged: {ex}");
469509
}
470-
471-
_dispatcher.BeginInvoke((Action)(() =>
472-
{
473-
RaisePropertyChanged(nameof(State));
474-
}));
475510
}
476511

477512
unsafe void IAudioSessionEvents.OnDisplayNameChanged(PCWSTR NewDisplayName, Guid* EventContext)
478513
{
479-
ChooseDisplayName(NewDisplayName.ToString());
514+
try
515+
{
516+
ChooseDisplayName(NewDisplayName.ToString());
480517

481-
_dispatcher.BeginInvoke((Action)(() =>
518+
_dispatcher.BeginInvoke((Action)(() =>
519+
{
520+
RaisePropertyChanged(nameof(DisplayName));
521+
}));
522+
}
523+
catch (Exception ex)
482524
{
483-
RaisePropertyChanged(nameof(DisplayName));
484-
}));
525+
Trace.WriteLine($"AudioDeviceSession OnDisplayNameChanged: {ex}");
526+
}
485527
}
486528

487-
void IAudioSessionEvents.OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason) => DisconnectSession();
529+
void IAudioSessionEvents.OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason)
530+
{
531+
try
532+
{
533+
DisconnectSession();
534+
}
535+
catch (Exception ex)
536+
{
537+
Trace.WriteLine($"AudioDeviceSession OnSessionDisconnected: {ex}");
538+
}
539+
}
488540

489541
unsafe void IAudioSessionEvents.OnChannelVolumeChanged(uint ChannelCount, float[] afNewChannelVolume, uint ChangedChannel, Guid* EventContext)
490542
{
491-
var channelVolumesValues = new float[ChannelCount];
492-
Array.Copy(afNewChannelVolume, 0, channelVolumesValues, 0, (int)ChannelCount);
543+
try
544+
{
545+
var channelVolumesValues = new float[ChannelCount];
546+
Array.Copy(afNewChannelVolume, 0, channelVolumesValues, 0, (int)ChannelCount);
493547

494-
for (var i = 0; i < ChannelCount; i++)
548+
for (var i = 0; i < ChannelCount; i++)
549+
{
550+
_channels.Channels[i].SetLevel(channelVolumesValues[i]);
551+
}
552+
}
553+
catch (Exception ex)
495554
{
496-
_channels.Channels[i].SetLevel(channelVolumesValues[i]);
555+
Trace.WriteLine($"AudioDeviceSession OnChannelVolumeChanged: {ex}");
497556
}
498557
}
499558

500559
unsafe void IAudioSessionEvents.OnIconPathChanged(PCWSTR NewIconPath, Guid* EventContext)
501560
{
502-
IconPath = NewIconPath.ToString();
503-
RaisePropertyChanged(nameof(IconPath));
561+
try
562+
{
563+
IconPath = NewIconPath.ToString();
564+
RaisePropertyChanged(nameof(IconPath));
565+
}
566+
catch (Exception ex)
567+
{
568+
Trace.WriteLine($"AudioDeviceSession OnIconPathChanged: {ex}");
569+
}
504570
}
505571
}

EarTrumpet/DataModel/WindowsAudio/Internal/AudioDeviceSessionCollection.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,21 @@ private void CreateAndAddSession(IAudioSessionControl session)
7474
var newSession = new AudioDeviceSession(parent, session, _dispatcher);
7575
_dispatcher.BeginInvoke((Action)(() =>
7676
{
77-
if (newSession.State == SessionState.Moved)
77+
try
7878
{
79-
_movedSessions.Add(newSession);
80-
newSession.PropertyChanged += MovedSession_PropertyChanged;
79+
if (newSession.State == SessionState.Moved)
80+
{
81+
_movedSessions.Add(newSession);
82+
newSession.PropertyChanged += MovedSession_PropertyChanged;
83+
}
84+
else if (newSession.State != SessionState.Expired)
85+
{
86+
AddSession(newSession);
87+
}
8188
}
82-
else if (newSession.State != SessionState.Expired)
89+
catch (Exception ex)
8390
{
84-
AddSession(newSession);
91+
Trace.WriteLine($"AudioDeviceSessionCollection CreateAndAddSession dispatch: {ex}");
8592
}
8693
}));
8794
}

0 commit comments

Comments
 (0)