private DecisionRecord GetRecord(ushort virtualKeyCode, KeyState state) { lock (DecisionBuffer) { int currentTime = Environment.TickCount; for (int i = 0; i < DecisionBuffer.Count; i++) { DecisionRecord record = DecisionBuffer.ElementAt(i); //if (SkipTimedOutRecords) //{ #warning temporarily(?) disabled, breaks with macros sending keys //if (record.DeviceHandle != IntPtr.Zero && GetTickCountDifference(record.TimeCreated, currentTime) > MaxWaitingTime) continue; //} if (record.KeyCode == virtualKeyCode && record.State == state) { while (i >= 0) { DecisionBuffer.Dequeue(); i--; } return(record); } } DecisionRecord timedoutrecord; while (DecisionBuffer.Count > 0 && (timedoutrecord = DecisionBuffer.ElementAt(0)).DeviceHandle != IntPtr.Zero && GetTickCountDifference(timedoutrecord.TimeCreated, currentTime) > MaxWaitingTime) { DecisionBuffer.Dequeue(); } } return(null); }
public bool ProcessHookMessage(ref Message m) { try { ushort virtualKeyCode = (ushort)m.WParam; Keys key = (Keys)virtualKeyCode; if (key == Keys.Packet) { return(false); } KeyState state = (KeyState)(((long)m.LParam & 0x80000000) > 0 ? 0 : 1); DecisionRecord record = GetRecord(virtualKeyCode, state); if (record == null && Timeouts < MaxTimeouts) { bool reported = false; int currentTime = Environment.TickCount, startTime = Environment.TickCount; while (record == null) { bool peeked = false; NativeMessage rawMessage; while (!(peeked = Win32.PeekMessage(out rawMessage, Handle, Win32.WM_INPUT, Win32.WM_INPUT, PM_REMOVE))) { currentTime = Environment.TickCount; if (!reported && GetTickCountDifference(startTime, currentTime) > 0) { Console.WriteLine($"UNRECORDED INPUT {key} {state}"); reported = true; } if (GetTickCountDifference(startTime, currentTime) > MaxWaitingTime) { Console.WriteLine($"IDLE FOR RAW INPUT TIMED OUT {key} {state}"); Timeouts++; break; } } if (!peeked) { break; } if (!reported && GetTickCountDifference(startTime, currentTime) > 0) { Console.WriteLine($"UNRECORDED INPUT {key} {state}"); reported = true; } if (rawMessage.msg == Win32.WM_INPUT) { ProcessRawInput(rawMessage.lParam); record = GetRecord(virtualKeyCode, state); } else { return(false); } } if (reported && record != null) { Console.WriteLine($"IDLE FOR RAW INPUT SUCCESSFUL, WAITED FOR {(currentTime < startTime ? uint.MaxValue - startTime + currentTime : currentTime - startTime)}ms - {key} {state}"); } } if (record != null) { Timeouts = 0; } Console.WriteLine($"Hook: {key} {state}"); bool block = (record?.Decision).GetValueOrDefault(); m.Result = (IntPtr)(block ? 1 : 0); if (block) { Console.WriteLine($"Key press: {key} {state} is being blocked!"); } return(true); } catch (Exception e) { Console.WriteLine(e); } return(false); }