Ejemplo n.º 1
0
        /// <summary>
        /// Starts blocking.
        /// </summary>
        /// <exception cref="ArgumentException"><i>what</i> is 0.</exception>
        /// <exception cref="InvalidOperationException">Already started.</exception>
        public void Start(BIEvents what)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(AInputBlocker));
            }
            if (_block != 0)
            {
                throw new InvalidOperationException();
            }
            if (!what.HasAny(BIEvents.All))
            {
                throw new ArgumentException();
            }

            _block     = what;
            _startTime = ATime.WinMilliseconds;

            _syncEvent    = Api.CreateEvent(false);
            _stopEvent    = Api.CreateEvent(false);
            _threadHandle = Api.OpenThread(Api.SYNCHRONIZE, false, _threadId = Api.GetCurrentThreadId());

            ThreadPool.QueueUserWorkItem(_this => (_this as AInputBlocker)._ThreadProc(), this);
            //SHOULDDO: what if thread pool is very busy? Eg if scripts use it incorrectly. Maybe better have own internal pool.

            Api.WaitForSingleObject(_syncEvent, Timeout.Infinite);
            GC.KeepAlive(this);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Stops blocking.
 /// Plays back blocked keys if need. See <see cref="ResendBlockedKeys"/>.
 /// Does nothing if currently is not blocking.
 /// </summary>
 /// <param name="discardBlockedKeys">Do not play back blocked key-down events recorded because of <see cref="ResendBlockedKeys"/>.</param>
 public void Stop(bool discardBlockedKeys = false)
 {
     if (_block == 0)
     {
         return;
     }
     _block = 0;
     _discardBlockedKeys = discardBlockedKeys;
     Api.SetEvent(_stopEvent);
     Api.WaitForSingleObject(_syncEvent, Timeout.Infinite);
     _CloseHandles();
 }
Ejemplo n.º 3
0
        void _ThreadProc()
        {
            AHookWin hk = null, hm = null; AHookAcc hwe = null;

            try {
                try {
                    if (_block.Has(BIEvents.Keys))
                    {
                        hk = AHookWin.Keyboard(_keyHookProc ??= _KeyHookProc);
                    }
                    if (_block.HasAny(BIEvents.MouseClicks | BIEvents.MouseMoving))
                    {
                        hm = AHookWin.Mouse(_mouseHookProc ??= _MouseHookProc);
                    }
                }
                catch (AuException e1) { ADebug.Print(e1); _block = 0; return; }                //failed to hook

                //This prevents occassional inserting a foreign key after the first our-script-pressed key.
                //To reproduce, let our script send small series of chars in loop, and simultaneously a foreign script send other chars.
                ATime.DoEvents();

                //AOutput.Write("started");
                Api.SetEvent(_syncEvent);

                //the acc hook detects Ctrl+Alt+Del, Win+L, UAC consent, etc. SystemEvents.SessionSwitch only Win+L.
                try { hwe = new AHookAcc(AccEVENT.SYSTEM_DESKTOPSWITCH, 0, _winEventProc ??= _WinEventProc); }
                catch (AuException e1) { ADebug.Print(e1); }                //failed to hook

                AWaitFor.Wait_(-1, WHFlags.DoEvents, _stopEvent, _threadHandle);

                if (_blockedKeys != null)
                {
                    bool onlyUp = _discardBlockedKeys || ATime.WinMilliseconds - _startTime > c_maxResendTime;
                    _blockedKeys.SendBlocked_(onlyUp);
                }
                //AOutput.Write("ended");
            }
            finally {
                _blockedKeys = null;
                hk?.Dispose();
                hm?.Dispose();
                hwe?.Dispose();
                Api.SetEvent(_syncEvent);
            }
            GC.KeepAlive(this);
        }
Ejemplo n.º 4
0
        void _ThreadProc()
        {
            WindowsHook hk = null, hm = null; WinEventHook hwe = null;

            try {
                try {
                    if (_block.Has(BIEvents.Keys))
                    {
                        hk = WindowsHook.Keyboard(_keyHookProc ??= _KeyHookProc);
                    }
                    if (_block.HasAny(BIEvents.MouseClicks | BIEvents.MouseMoving))
                    {
                        hm = WindowsHook.Mouse(_mouseHookProc ??= _MouseHookProc);
                    }
                }
                catch (AuException e1) { Debug_.Print(e1); _block = 0; return; }                 //failed to hook

                //This prevents occassional inserting a foreign key after the first our-script-pressed key.
                //To reproduce, let our script send small series of chars in loop, and simultaneously a foreign script send other chars.
                wait.doEvents();

                //print.it("started");
                Api.SetEvent(_syncEvent);

                //the hook detects Ctrl+Alt+Del, Win+L, UAC consent, etc. SystemEvents.SessionSwitch only Win+L.
                try { hwe = new WinEventHook(EEvent.SYSTEM_DESKTOPSWITCH, 0, _winEventProc ??= _WinEventProc); }
                catch (AuException e1) { Debug_.Print(e1); }                 //failed to hook

                wait.Wait_(-1, WHFlags.DoEvents, _stopEvent, _threadHandle);

                if (_blockedKeys != null)
                {
                    bool onlyUp = _discardBlockedKeys || Environment.TickCount64 - _startTime > c_maxResendTime;
                    _blockedKeys.SendBlocked_(onlyUp);
                }
                //print.it("ended");
            }
            finally {
                _blockedKeys = null;
                hk?.Dispose();
                hm?.Dispose();
                hwe?.Dispose();
                Api.SetEvent(_syncEvent);
            }
            GC.KeepAlive(this);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// This constructor calls <see cref="Start"/>.
 /// </summary>
 /// <exception cref="ArgumentException"><i>what</i> is 0.</exception>
 public AInputBlocker(BIEvents what)
 {
     Start(what);
 }