From d84d8708178a71a93ebe30ce5459913a359752ce Mon Sep 17 00:00:00 2001 From: Adam Hovorka Date: Sun, 19 Jul 2020 19:12:46 -0600 Subject: Initial commit --- .gitignore | 2 + .npmignore | 3 + README.md | 83 +++++++++++ binding.gyp | 11 ++ index.js | 13 ++ lib/Events/EV_ABS.js | 44 ++++++ lib/Events/EV_KEY.js | 393 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/Events/EV_SYN.js | 6 + lib/Events/index.js | 14 ++ lib/index.js | 90 ++++++++++++ lib/ioctl.cpp | 42 ++++++ package-lock.json | 26 ++++ package.json | 16 +++ 13 files changed, 743 insertions(+) create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 README.md create mode 100644 binding.gyp create mode 100755 index.js create mode 100644 lib/Events/EV_ABS.js create mode 100644 lib/Events/EV_KEY.js create mode 100644 lib/Events/EV_SYN.js create mode 100644 lib/Events/index.js create mode 100644 lib/index.js create mode 100644 lib/ioctl.cpp create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd87e2d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +build diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..91514a2 --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +.idea +build +example.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..dba118d --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# node-exclusive-keyboard +Keylogger for NodeJS and Linux that grabs the input device exclusively. + +Useful for capturing USB input devices that act like keyboards, so that their inputs do no pollute other processes like terminals. + +Based on [node-keylogger](https://github.com/taosx/node-keylogger/) and [node-ioctl](https://github.com/santigimeno/node-ioctl). + +## Installation +```bash +npm install --save exclusive-keyboard +``` + +## Usage + +Set access control right to device for user `username`: +```bash +sudo setfacl -m u:username:r /dev/input/by-id/usb-Logitech_Logitech_USB_Keyboard-event-kbd +``` + +```js +const ExclusiveKeyboard = require('exclusive-keyboard'); + +const keyboard = new ExclusiveKeyboard('by-id/usb-Logitech_Logitech_USB_Keyboard-event-kbd', true); +keyboard.on('keyup', console.log); +keyboard.on('keydown', console.log); +keyboard.on('keypress', console.log); +keyboard.on('close', console.log); +keyboard.on('error', console.error); +``` + +## API + +### `new ExclusiveKeyboard(dev, exclusive)` +* `dev` (string): Device name (part after '/dev/input/'). Example: 'event0' would use '/dev/input/event0' +* `exclusive` (boolean): If true, grab device exclusively using ioctl EVIOCGRAB (default: true) + +### `close()` +Releases the grabbed device and closes the file descriptor. Emits 'close' event when done. + +### ExclusiveKeyboard.Keys +Mapping of key codes to key ids, see `keycodes.js`. + +### Event `keyup(event)` +Example event: +```js +{ + timeS: 39234, + timeMS: 3812, + keyCode: 71, + keyId: 'KEY_KP7', + type: 'keyup', + dev: 'by-id/usb-SEM_Trust_Numpad-event-kbd' +} +``` + +### Event `keypress(event)` +Example event: +```js +{ + timeS: 39234, + timeMS: 3812, + keyCode: 71, + keyId: 'KEY_KP7', + type: 'keypress', + dev: 'by-id/usb-SEM_Trust_Numpad-event-kbd' +} +``` + +### Event `keydown(event)` +```js +{ + timeS: 39234, + timeMS: 3812, + keyCode: 71, + keyId: 'KEY_KP7', + type: 'keydown', + dev: 'by-id/usb-SEM_Trust_Numpad-event-kbd' +} +``` + +### Event `error(error)` + +### Event `close()` diff --git a/binding.gyp b/binding.gyp new file mode 100644 index 0000000..7add6fc --- /dev/null +++ b/binding.gyp @@ -0,0 +1,11 @@ +{ + 'targets': [ + { + 'target_name': 'ioctl', + 'sources': [ 'lib/ioctl.cpp' ], + 'include_dirs': [ + ' console.error("Reader error:", e)) + .on("open", () => { console.log(device.id); device.grab(); }) + .on("EV_KEY", e => console.log(/*e.time,*/ "KEY", e.code, e.value)) + .on("EV_ABS", e => console.log(/*e.time,*/ "ABS", e.code, e.value)) + .on("EV_REL", e => console.log(/*e.time,*/ "REN", e.code, e.value)) + .on("EV_SYN", e => console.log(/*e.time,*/ "SYN", e.code, e.value)) diff --git a/lib/Events/EV_ABS.js b/lib/Events/EV_ABS.js new file mode 100644 index 0000000..08a19fa --- /dev/null +++ b/lib/Events/EV_ABS.js @@ -0,0 +1,44 @@ +module.exports = { + 0x00:"ABS_X", + 0x01:"ABS_Y", + 0x02:"ABS_Z", + 0x03:"ABS_RX", + 0x04:"ABS_RY", + 0x05:"ABS_RZ", + 0x06:"ABS_THROTTLE", + 0x07:"ABS_RUDDER", + 0x08:"ABS_WHEEL", + 0x09:"ABS_GAS", + 0x0a:"ABS_BRAKE", + 0x10:"ABS_HAT0X", + 0x11:"ABS_HAT0Y", + 0x12:"ABS_HAT1X", + 0x13:"ABS_HAT1Y", + 0x14:"ABS_HAT2X", + 0x15:"ABS_HAT2Y", + 0x16:"ABS_HAT3X", + 0x17:"ABS_HAT3Y", + 0x18:"ABS_PRESSURE", + 0x19:"ABS_DISTANCE", + 0x1a:"ABS_TILT_X", + 0x1b:"ABS_TILT_Y", + 0x1c:"ABS_TOOL_WIDTH", + 0x20:"ABS_VOLUME", + 0x28:"ABS_MISC", + 0x2f:"ABS_MT_SLOT", + 0x30:"ABS_MT_TOUCH_MAJOR", + 0x31:"ABS_MT_TOUCH_MINOR", + 0x32:"ABS_MT_WIDTH_MAJOR", + 0x33:"ABS_MT_WIDTH_MINOR", + 0x34:"ABS_MT_ORIENTATION", + 0x35:"ABS_MT_POSITION_X", + 0x36:"ABS_MT_POSITION_Y", + 0x37:"ABS_MT_TOOL_TYPE", + 0x38:"ABS_MT_BLOB_ID", + 0x39:"ABS_MT_TRACKING_ID", + 0x3a:"ABS_MT_PRESSURE", + 0x3b:"ABS_MT_DISTANCE", + 0x3c:"ABS_MT_TOOL_X", + 0x3d:"ABS_MT_TOOL_Y", + 0x3f:"ABS_MAX" +}; diff --git a/lib/Events/EV_KEY.js b/lib/Events/EV_KEY.js new file mode 100644 index 0000000..51409cf --- /dev/null +++ b/lib/Events/EV_KEY.js @@ -0,0 +1,393 @@ +module.exports = { + 0:"KEY_RESERVED", + 1:"KEY_ESC", + 2:"KEY_1", + 3:"KEY_2", + 4:"KEY_3", + 5:"KEY_4", + 6:"KEY_5", + 7:"KEY_6", + 8:"KEY_7", + 9:"KEY_8", + 10:"KEY_9", + 11:"KEY_0", + 12:"KEY_MINUS", + 13:"KEY_EQUAL", + 14:"KEY_BACKSPACE", + 15:"KEY_TAB", + 16:"KEY_Q", + 17:"KEY_W", + 18:"KEY_E", + 19:"KEY_R", + 20:"KEY_T", + 21:"KEY_Y", + 22:"KEY_U", + 23:"KEY_I", + 24:"KEY_O", + 25:"KEY_P", + 26:"KEY_LEFTBRACE", + 27:"KEY_RIGHTBRACE", + 28:"KEY_ENTER", + 29:"KEY_LEFTCTRL", + 30:"KEY_A", + 31:"KEY_S", + 32:"KEY_D", + 33:"KEY_F", + 34:"KEY_G", + 35:"KEY_H", + 36:"KEY_J", + 37:"KEY_K", + 38:"KEY_L", + 39:"KEY_SEMICOLON", + 40:"KEY_APOSTROPHE", + 41:"KEY_GRAVE", + 42:"KEY_LEFTSHIFT", + 43:"KEY_BACKSLASH", + 44:"KEY_Z", + 45:"KEY_X", + 46:"KEY_C", + 47:"KEY_V", + 48:"KEY_B", + 49:"KEY_N", + 50:"KEY_M", + 51:"KEY_COMMA", + 52:"KEY_DOT", + 53:"KEY_SLASH", + 54:"KEY_RIGHTSHIFT", + 55:"KEY_KPASTERISK", + 56:"KEY_LEFTALT", + 57:"KEY_SPACE", + 58:"KEY_CAPSLOCK", + 59:"KEY_F1", + 60:"KEY_F2", + 61:"KEY_F3", + 62:"KEY_F4", + 63:"KEY_F5", + 64:"KEY_F6", + 65:"KEY_F7", + 66:"KEY_F8", + 67:"KEY_F9", + 68:"KEY_F10", + 69:"KEY_NUMLOCK", + 70:"KEY_SCROLLLOCK", + 71:"KEY_KP7", + 72:"KEY_KP8", + 73:"KEY_KP9", + 74:"KEY_KPMINUS", + 75:"KEY_KP4", + 76:"KEY_KP5", + 77:"KEY_KP6", + 78:"KEY_KPPLUS", + 79:"KEY_KP1", + 80:"KEY_KP2", + 81:"KEY_KP3", + 82:"KEY_KP0", + 83:"KEY_KPDOT", + + 85:"KEY_ZENKAKUHANKAKU", + 86:"KEY_102ND", + 87:"KEY_F11", + 88:"KEY_F12", + 89:"KEY_RO", + 90:"KEY_KATAKANA", + 91:"KEY_HIRAGANA", + 92:"KEY_HENKAN", + 93:"KEY_KATAKANAHIRAGANA", + 94:"KEY_MUHENKAN", + 95:"KEY_KPJPCOMMA", + 96:"KEY_KPENTER", + 97:"KEY_RIGHTCTRL", + 98:"KEY_KPSLASH", + 99:"KEY_SYSRQ", + 100:"KEY_RIGHTALT", + 101:"KEY_LINEFEED", + 102:"KEY_HOME", + 103:"KEY_UP", + 104:"KEY_PAGEUP", + 105:"KEY_LEFT", + 106:"KEY_RIGHT", + 107:"KEY_END", + 108:"KEY_DOWN", + 109:"KEY_PAGEDOWN", + 110:"KEY_INSERT", + 111:"KEY_DELETE", + 112:"KEY_MACRO", + 113:"KEY_MUTE", + 114:"KEY_VOLUMEDOWN", + 115:"KEY_VOLUMEUP", + 116:"KEY_POWER", + 117:"KEY_KPEQUAL", + 118:"KEY_KPPLUSMINUS", + 119:"KEY_PAUSE", + + 121:"KEY_KPCOMMA", + 122:"KEY_HANGUEL", + 123:"KEY_HANJA", + 124:"KEY_YEN", + 125:"KEY_LEFTMETA", + 126:"KEY_RIGHTMETA", + 127:"KEY_COMPOSE", + + 128:"KEY_STOP", + 129:"KEY_AGAIN", + 130:"KEY_PROPS", + 131:"KEY_UNDO", + 132:"KEY_FRONT", + 133:"KEY_COPY", + 134:"KEY_OPEN", + 135:"KEY_PASTE", + 136:"KEY_FIND", + 137:"KEY_CUT", + 138:"KEY_HELP", + 139:"KEY_MENU", + 140:"KEY_CALC", + 141:"KEY_SETUP", + 142:"KEY_SLEEP", + 143:"KEY_WAKEUP", + 144:"KEY_FILE", + 145:"KEY_SENDFILE", + 146:"KEY_DELETEFILE", + 147:"KEY_XFER", + 148:"KEY_PROG1", + 149:"KEY_PROG2", + 150:"KEY_WWW", + 151:"KEY_MSDOS", + 152:"KEY_COFFEE", + 153:"KEY_DIRECTION", + 154:"KEY_CYCLEWINDOWS", + 155:"KEY_MAIL", + 156:"KEY_BOOKMARKS", + 157:"KEY_COMPUTER", + 158:"KEY_BACK", + 159:"KEY_FORWARD", + 160:"KEY_CLOSECD", + 161:"KEY_EJECTCD", + 162:"KEY_EJECTCLOSECD", + 163:"KEY_NEXTSONG", + 164:"KEY_PLAYPAUSE", + 165:"KEY_PREVIOUSSONG", + 166:"KEY_STOPCD", + 167:"KEY_RECORD", + 168:"KEY_REWIND", + 169:"KEY_PHONE", + 170:"KEY_ISO", + 171:"KEY_CONFIG", + 172:"KEY_HOMEPAGE", + 173:"KEY_REFRESH", + 174:"KEY_EXIT", + 175:"KEY_MOVE", + 176:"KEY_EDIT", + 177:"KEY_SCROLLUP", + 178:"KEY_SCROLLDOWN", + 179:"KEY_KPLEFTPAREN", + 180:"KEY_KPRIGHTPAREN", + + 183:"KEY_F13", + 184:"KEY_F14", + 185:"KEY_F15", + 186:"KEY_F16", + 187:"KEY_F17", + 188:"KEY_F18", + 189:"KEY_F19", + 190:"KEY_F20", + 191:"KEY_F21", + 192:"KEY_F22", + 193:"KEY_F23", + 194:"KEY_F24", + + 200:"KEY_PLAYCD", + 201:"KEY_PAUSECD", + 202:"KEY_PROG3", + 203:"KEY_PROG4", + 205:"KEY_SUSPEND", + 206:"KEY_CLOSE", + 207:"KEY_PLAY", + 208:"KEY_FASTFORWARD", + 209:"KEY_BASSBOOST", + 210:"KEY_PRINT", + 211:"KEY_HP", + 212:"KEY_CAMERA", + 213:"KEY_SOUND", + 214:"KEY_QUESTION", + 215:"KEY_EMAIL", + 216:"KEY_CHAT", + 217:"KEY_SEARCH", + 218:"KEY_CONNECT", + 219:"KEY_FINANCE", + 220:"KEY_SPORT", + 221:"KEY_SHOP", + 222:"KEY_ALTERASE", + 223:"KEY_CANCEL", + 224:"KEY_BRIGHTNESSDOWN", + 225:"KEY_BRIGHTNESSUP", + 226:"KEY_MEDIA", + + 240:"KEY_UNKNOWN", + + //0x100:"BTN_MISC", + 0x100:"BTN_0", + 0x101:"BTN_1", + 0x102:"BTN_2", + 0x103:"BTN_3", + 0x104:"BTN_4", + 0x105:"BTN_5", + 0x106:"BTN_6", + 0x107:"BTN_7", + 0x108:"BTN_8", + 0x109:"BTN_9", + + //0x110:"BTN_MOUSE", + 0x110:"BTN_LEFT", + 0x111:"BTN_RIGHT", + 0x112:"BTN_MIDDLE", + 0x113:"BTN_SIDE", + 0x114:"BTN_EXTRA", + 0x115:"BTN_FORWARD", + 0x116:"BTN_BACK", + 0x117:"BTN_TASK", + + //0x120:"BTN_JOYSTICK", + 0x120:"BTN_TRIGGER", + 0x121:"BTN_THUMB", + 0x122:"BTN_THUMB2", + 0x123:"BTN_TOP", + 0x124:"BTN_TOP2", + 0x125:"BTN_PINKIE", + 0x126:"BTN_BASE", + 0x127:"BTN_BASE2", + 0x128:"BTN_BASE3", + 0x129:"BTN_BASE4", + 0x12a:"BTN_BASE5", + 0x12b:"BTN_BASE6", + 0x12f:"BTN_DEAD", + + //0x130:"BTN_GAMEPAD", + 0x130:"BTN_A", + 0x131:"BTN_B", + 0x132:"BTN_C", + 0x133:"BTN_X", + 0x134:"BTN_Y", + 0x135:"BTN_Z", + 0x136:"BTN_TL", + 0x137:"BTN_TR", + 0x138:"BTN_TL2", + 0x139:"BTN_TR2", + 0x13a:"BTN_SELECT", + 0x13b:"BTN_START", + 0x13c:"BTN_MODE", + 0x13d:"BTN_THUMBL", + 0x13e:"BTN_THUMBR", + + //0x140:"BTN_DIGI", + 0x140:"BTN_TOOL_PEN", + 0x141:"BTN_TOOL_RUBBER", + 0x142:"BTN_TOOL_BRUSH", + 0x143:"BTN_TOOL_PENCIL", + 0x144:"BTN_TOOL_AIRBRUSH", + 0x145:"BTN_TOOL_FINGER", + 0x146:"BTN_TOOL_MOUSE", + 0x147:"BTN_TOOL_LENS", + 0x14a:"BTN_TOUCH", + 0x14b:"BTN_STYLUS", + 0x14c:"BTN_STYLUS2", + 0x14d:"BTN_TOOL_DOUBLETAP", + 0x14e:"BTN_TOOL_TRIPLETAP", + + //0x150:"BTN_WHEEL", + 0x150:"BTN_GEAR_DOWN", + 0x151:"BTN_GEAR_UP", + + 0x160:"KEY_OK", + 0x161:"KEY_SELECT", + 0x162:"KEY_GOTO", + 0x163:"KEY_CLEAR", + 0x164:"KEY_POWER2", + 0x165:"KEY_OPTION", + 0x166:"KEY_INFO", + 0x167:"KEY_TIME", + 0x168:"KEY_VENDOR", + 0x169:"KEY_ARCHIVE", + 0x16a:"KEY_PROGRAM", + 0x16b:"KEY_CHANNEL", + 0x16c:"KEY_FAVORITES", + 0x16d:"KEY_EPG", + 0x16e:"KEY_PVR", + 0x16f:"KEY_MHP", + 0x170:"KEY_LANGUAGE", + 0x171:"KEY_TITLE", + 0x172:"KEY_SUBTITLE", + 0x173:"KEY_ANGLE", + 0x174:"KEY_ZOOM", + 0x175:"KEY_MODE", + 0x176:"KEY_KEYBOARD", + 0x177:"KEY_SCREEN", + 0x178:"KEY_PC", + 0x179:"KEY_TV", + 0x17a:"KEY_TV2", + 0x17b:"KEY_VCR", + 0x17c:"KEY_VCR2", + 0x17d:"KEY_SAT", + 0x17e:"KEY_SAT2", + 0x17f:"KEY_CD", + 0x180:"KEY_TAPE", + 0x181:"KEY_RADIO", + 0x182:"KEY_TUNER", + 0x183:"KEY_PLAYER", + 0x184:"KEY_TEXT", + 0x185:"KEY_DVD", + 0x186:"KEY_AUX", + 0x187:"KEY_MP3", + 0x188:"KEY_AUDIO", + 0x189:"KEY_VIDEO", + 0x18a:"KEY_DIRECTORY", + 0x18b:"KEY_LIST", + 0x18c:"KEY_MEMO", + 0x18d:"KEY_CALENDAR", + 0x18e:"KEY_RED", + 0x18f:"KEY_GREEN", + 0x190:"KEY_YELLOW", + 0x191:"KEY_BLUE", + 0x192:"KEY_CHANNELUP", + 0x193:"KEY_CHANNELDOWN", + 0x194:"KEY_FIRST", + 0x195:"KEY_LAST", + 0x196:"KEY_AB", + 0x197:"KEY_NEXT", + 0x198:"KEY_RESTART", + 0x199:"KEY_SLOW", + 0x19a:"KEY_SHUFFLE", + 0x19b:"KEY_BREAK", + 0x19c:"KEY_PREVIOUS", + 0x19d:"KEY_DIGITS", + 0x19e:"KEY_TEEN", + 0x19f:"KEY_TWEN", + + 0x1c0:"KEY_DEL_EOL", + 0x1c1:"KEY_DEL_EOS", + 0x1c2:"KEY_INS_LINE", + 0x1c3:"KEY_DEL_LINE", + + 0x1d0:"KEY_FN", + 0x1d1:"KEY_FN_ESC", + 0x1d2:"KEY_FN_F1", + 0x1d3:"KEY_FN_F2", + 0x1d4:"KEY_FN_F3", + 0x1d5:"KEY_FN_F4", + 0x1d6:"KEY_FN_F5", + 0x1d7:"KEY_FN_F6", + 0x1d8:"KEY_FN_F7", + 0x1d9:"KEY_FN_F8", + 0x1da:"KEY_FN_F9", + 0x1db:"KEY_FN_F10", + 0x1dc:"KEY_FN_F11", + 0x1dd:"KEY_FN_F12", + 0x1de:"KEY_FN_1", + 0x1df:"KEY_FN_2", + 0x1e0:"KEY_FN_D", + 0x1e1:"KEY_FN_E", + 0x1e2:"KEY_FN_F", + 0x1e3:"KEY_FN_S", + 0x1e4:"KEY_FN_B", + + 0x1ff:"KEY_MAX" +}; diff --git a/lib/Events/EV_SYN.js b/lib/Events/EV_SYN.js new file mode 100644 index 0000000..47d2cde --- /dev/null +++ b/lib/Events/EV_SYN.js @@ -0,0 +1,6 @@ +module.exports = { + 0:"SYN_REPORT", + 1:"SYN_CONFIG", + 2:"SYN_MT_REPORT", + 3:"SYN_DROPPED" +}; diff --git a/lib/Events/index.js b/lib/Events/index.js new file mode 100644 index 0000000..fcb9d3c --- /dev/null +++ b/lib/Events/index.js @@ -0,0 +1,14 @@ +module.exports = { + 0x00:"EV_SYN", + 0x01:"EV_KEY", + 0x02:"EV_REL", + 0x03:"EV_ABS", + 0x04:"EV_MSC", + 0x11:"EV_LED", + 0x12:"EV_SND", + 0x14:"EV_REP", + 0x15:"EV_FF", + 0x16:"EV_PWR", + 0x17:"EV_FF_STATUS", + 0x1f:"EV_MAX" +}; diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..d0129ab --- /dev/null +++ b/lib/index.js @@ -0,0 +1,90 @@ +const fs = require("fs") + , util = require("util") + , EventEmitter = require("events").EventEmitter + , {eviocgrab, eviocgid} = require("bindings")("ioctl.node") + , events = require("./Events") + , codes = { + EV_KEY : require("./Events/EV_KEY"), + EV_ABS : require("./Events/EV_ABS"), + EV_SYN : require("./Events/EV_SYN") + }; + +const arch = (process.arch.indexOf("64")>=0)?64:32; + +function Device(path) { + this.grabbed = false; + if (path) this.open(path); +} + +util.inherits(Device, EventEmitter); + +Device.prototype.open = function(path) { + this.stream = fs + .createReadStream(path, {flags: "r", autoClose: true}) + .on("error", e => this.emit("error", e)) + .on("open", fd => { this.fd = fd; + try { this.id = eviocgid(fd); } + catch(e) { this.emit("error", + new Error("Reader eviocgid error:"+e)); } + if (this.grabbed) eviocgrab(this.fd, 1); + this.emit("open", fd); }) + .on("data", buf => { + var i, j, chunk = (arch===64)?24:16; + for (i=0, j=buf.length; i +#include +#include +#include "nan.h" + +NAN_METHOD(eviocgrab) { + assert(info.Length() == 2); + if (!info[0]->IsUint32()) Nan::ThrowTypeError("Argument 0 Must be an Integer"); + if (!info[1]->IsUint32()) Nan::ThrowTypeError("Argument 1 Must be an Integer"); + int fd = Nan::To(info[0]).ToChecked(); + int grab = Nan::To(info[1]).ToChecked(); + + int res = ioctl(fd, EVIOCGRAB, grab); + if (res < 0) return Nan::ThrowError( + Nan::ErrnoException(errno, "ioctl", nullptr, nullptr)); + + info.GetReturnValue().Set(res); +} + +NAN_METHOD(eviocgid) { + assert(info.Length() == 1); + if (!info[0]->IsUint32()) Nan::ThrowTypeError("Argument 0 Must be an Integer"); + int fd = Nan::To(info[0]).ToChecked(); + + struct input_id id; + if (ioctl(fd, EVIOCGID, &id) == -1) return Nan::ThrowError( + Nan::ErrnoException(errno, "ioctl", nullptr, nullptr)); + + v8::Local size = Nan::New(); + Nan::Set(size, Nan::New("bustype").ToLocalChecked(), Nan::New((double)id.bustype)); + Nan::Set(size, Nan::New("vendor" ).ToLocalChecked(), Nan::New((double)id.vendor )); + Nan::Set(size, Nan::New("product").ToLocalChecked(), Nan::New((double)id.product)); + Nan::Set(size, Nan::New("version").ToLocalChecked(), Nan::New((double)id.version)); + info.GetReturnValue().Set(size); +} + +NAN_MODULE_INIT(InitAll) { + NAN_EXPORT(target, eviocgrab); + NAN_EXPORT(target, eviocgid); +} + +NODE_MODULE(ioctl, InitAll) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4021b41 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,26 @@ +{ + "name": "test", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "nan": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..b970ec5 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "test", + "version": "0.1.0", + "description": "meh", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Alexis Hovorka", + "license": "MIT", + "private": true, + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.14.0" + } +} -- cgit v1.2.3-54-g00ecf