Restore SEBPatch
This commit is contained in:
66
SafeExamBrowser.WindowsApi/Hooks/SystemHook.cs
Normal file
66
SafeExamBrowser.WindowsApi/Hooks/SystemHook.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using SafeExamBrowser.WindowsApi.Constants;
|
||||
using SafeExamBrowser.WindowsApi.Contracts.Events;
|
||||
using SafeExamBrowser.WindowsApi.Delegates;
|
||||
|
||||
namespace SafeExamBrowser.WindowsApi.Hooks
|
||||
{
|
||||
internal class SystemHook
|
||||
{
|
||||
private SystemEventCallback callback;
|
||||
private AutoResetEvent detachEvent, detachResultAvailableEvent;
|
||||
private bool detachSuccess;
|
||||
private EventDelegate eventDelegate;
|
||||
private uint eventId;
|
||||
private IntPtr handle;
|
||||
|
||||
internal Guid Id { get; private set; }
|
||||
|
||||
public SystemHook(SystemEventCallback callback, uint eventId)
|
||||
{
|
||||
this.callback = callback;
|
||||
this.detachEvent = new AutoResetEvent(false);
|
||||
this.detachResultAvailableEvent = new AutoResetEvent(false);
|
||||
this.eventId = eventId;
|
||||
this.Id = Guid.NewGuid();
|
||||
}
|
||||
|
||||
internal void Attach()
|
||||
{
|
||||
// IMPORTANT:
|
||||
// Ensures that the hook delegate does not get garbage collected prematurely, as it will be passed to unmanaged code.
|
||||
// Not doing so will result in a <c>CallbackOnCollectedDelegate</c> error and subsequent application crash!
|
||||
eventDelegate = new EventDelegate(LowLevelSystemProc);
|
||||
handle = User32.SetWinEventHook(eventId, eventId, IntPtr.Zero, eventDelegate, 0, 0, Constant.WINEVENT_OUTOFCONTEXT);
|
||||
}
|
||||
|
||||
internal void AwaitDetach()
|
||||
{
|
||||
detachEvent.WaitOne();
|
||||
detachSuccess = User32.UnhookWinEvent(handle);
|
||||
detachResultAvailableEvent.Set();
|
||||
}
|
||||
|
||||
internal bool Detach()
|
||||
{
|
||||
detachEvent.Set();
|
||||
detachResultAvailableEvent.WaitOne();
|
||||
|
||||
return detachSuccess;
|
||||
}
|
||||
|
||||
private void LowLevelSystemProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
|
||||
{
|
||||
callback(hwnd);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user