import com.jniwrapper.*; import com.jniwrapper.win32.Handle; import com.jniwrapper.win32.IntPtr; import com.jniwrapper.win32.LastErrorException; import com.jniwrapper.win32.ui.*;
import javax.swing.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;
/** * This example demonstrates how to implement key logging * using <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms645536%28v=vs.85%29.aspx">Raw Input</a> Windows API. */ public class RawKeyboardInputSample { /** * Wrapper for <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms645575%28v=vs.85%29.aspx">RAWKEYBOARD</a> structure. */ static class RAWKEYBOARD extends Structure { UShortInt MakeCode = new UShortInt(); UShortInt Flags = new UShortInt(); UShortInt Reserved = new UShortInt(); UShortInt VKey = new UShortInt(); UInt Message = new UInt(); ULongInt ExtraInformation = new ULongInt(); public RAWKEYBOARD() { init(new Parameter[] {MakeCode, Flags, Reserved, VKey, Message, ExtraInformation}, (short) 8); } }
/** * Wrapper for <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms645565%28v=vs.85%29.aspx">RAWINPUTDEVICE</a> structure. */ static class RAWINPUTDEVICE extends Structure { UShortInt usUsagePage = new UShortInt(); UShortInt usUsage = new UShortInt(); UInt32 dwFlags = new UInt32(); Wnd hwndTarget = new Wnd();
public RAWINPUTDEVICE() { init(new Parameter[] {usUsagePage, usUsage, dwFlags, hwndTarget}, (short) 8); } }
/** * Wrapper for <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms645571%28v=vs.85%29.aspx">RAWINPUTHEADER</a> structure. */ static class RAWINPUTHEADER extends Structure { UInt32 dwType = new UInt32(); UInt32 dwSize = new UInt32(); Handle hDevice = new Handle(); IntPtr wParam = new IntPtr();
public RAWINPUTHEADER() { init(new Parameter[] {dwType, dwSize, hDevice, wParam}, (short) 8); } }
/** * Wrapper for <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms645562%28v=vs.85%29.aspx">RAWINPUT</a> structure. */ static class RAWINPUT extends Structure { RAWINPUTHEADER rawinputheader = new RAWINPUTHEADER(); RAWKEYBOARD keyboard = new RAWKEYBOARD();
public RAWINPUT() { init(new Parameter[] {rawinputheader, keyboard}, (short) 8); } }
/** * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms645590%28v=vs.85%29.aspx">WM_INPUT</a> event. */ public static final int WM_INPUT = 0x00FF;
public static void main(String[] args) {
// a sample frame to redirect raw messages to JFrame mainFrame = new JFrame("Main Frame"); mainFrame.setSize(800, 600); mainFrame.setLocationRelativeTo(null); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainFrame.setVisible(true);
User32 user32 = User32.getInstance(); final Function getRawInputData = user32.getFunction("GetRawInputData"); final Function registerRawInputDevices = User32.getInstance().getFunction("RegisterRawInputDevices");
Wnd wnd = new Wnd(mainFrame);
// Substitute frame's window procedure to receive WM_INPUT events final WindowProc windowProc = new WindowProc(wnd); windowProc.addMessageListener(new WindowMessageListener() { public boolean canHandle(WindowMessage message, boolean beforeWindowProc) { return message.getMsg() == WM_INPUT; }
public int handle(WindowMessage message) { final int RID_INPUT = 0x10000003;
RAWINPUTHEADER rih = new RAWINPUTHEADER(); UInt32 size = new UInt32(); UInt result = new UInt(); getRawInputData.invoke(result, new Parameter[]{ new Pointer.Void(message.getLParam()), new UInt(RID_INPUT), new Pointer.Void(), new Pointer(size), new Int(rih.getLength()) }); if (result.getValue() == -1) { return 0; }
PrimitiveArray buffer = new PrimitiveArray(UInt8.class, (int) size.getValue()); Pointer bufferPtr = new Pointer(buffer); getRawInputData.invoke(result, new Parameter[]{ new Pointer.Void(message.getLParam()), new UInt(RID_INPUT), bufferPtr, new Pointer(size), new Int(rih.getLength()) });
if (result.getValue() != size.getValue()) { return 0; }
RAWINPUT rawinput = new RAWINPUT(); Pointer rawinputPtr = new Pointer(rawinput); bufferPtr.castTo(rawinputPtr);
RAWKEYBOARD keyboard = rawinput.keyboard; System.out.println("Keyboard: make = " + keyboard.MakeCode + "; flags = " + keyboard.Flags + "; Reserved = " + keyboard.Reserved + "; ExtraInformation = " + keyboard.ExtraInformation + "; Message = " + keyboard.Message + "; VKey = " + keyboard.VKey);
return 0; } }); windowProc.substitute();
mainFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { windowProc.restoreNative(); } });
RAWINPUTDEVICE rid = new RAWINPUTDEVICE(); rid.usUsagePage.setValue(1); // generic desktop controls rid.usUsage.setValue(6); // keyboard rid.dwFlags.setValue(0x00000030 | 0x00000100); rid.hwndTarget.setValue(wnd.getValue()); // use Frame's wnd (message queue) to receive events
Bool result = new Bool(); long lastErrorCode = registerRawInputDevices.invoke(result, new Pointer(rid), new UInt(1), new UInt(rid.getLength())); if (!result.getValue()) { throw new LastErrorException(lastErrorCode); } } }
|