Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * rever_g_hack
- * slight modification of Andreas Schneider's g_hack by Bombenbach
- * in order to make it work with logitech G500
- * Big thanks to Andreas Schneider and Marian Kyral
- */
- /*
- * gcc -o g_hack g_hack.c
- * ./g_hack /dev/hidraw0
- *
- * g_hack - proof of conecpt code
- *
- *
- * Copyright (c) 2006-2009 Andreas Schneider <mail@cynapses.org>
- * Copyright (c) 2006-2007 Peter Feuerer <piie@piie.net>
- *
- * License: GPLv2 or later
- *
- * Additional Info:
- *
- * the G-series has two modes:
- *
- * 1. mode: no driver
- * in this mode there is a list of resolutions implemented in the mouse
- * and you can switch between them using the buttons
- *
- * 2. mode is: windows driver
- * in this mode the buttons talk to the driver
- * they have absolute no effect on the hardware in first place
- * the driver gets the button event looks in its table, which resolution to use
- * sends it to the mouse sets the leds and the resolution
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #include <string.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <asm/types.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <linux/hiddev.h>
- #define VERSION "0.0.7"
- #define VENDOR 0x046d
- #define MOUSE_G5 0xc041
- #define MOUSE_G7 0xc51a
- /* thanks to Michael "sanni" Dewein */
- #define MOUSE_G3 0xc042
- /* thanks to Niels "aboe" Abspoel */
- #define MOUSE_G9 0xc048
- /* G500's signature*/
- #define MOUSE_G500 0xc068
- /* function borrowed from http://www.lomoco.org/vx_hack.c */
- static int query_report(int fd, int id, unsigned int *buf, size_t size) {
- struct hiddev_usage_ref_multi uref;
- struct hiddev_report_info rinfo;
- int i = 0, rc = -1;
- rinfo.report_type = HID_REPORT_TYPE_INPUT;
- rinfo.report_id = id;
- rinfo.num_fields = 1;
- rc = ioctl(fd, HIDIOCGREPORT, &rinfo);
- if (rc < 0) {
- perror("HIDIOCGREPORT");
- return rc;
- }
- uref.uref.report_type = HID_REPORT_TYPE_INPUT;
- uref.uref.report_id = id;
- uref.uref.field_index = 0;
- uref.uref.usage_index = 0;
- uref.num_values = size;
- rc = ioctl(fd, HIDIOCGUSAGES, &uref);
- if (rc < 0) {
- perror("HIDIOCGUSAGES");
- return rc;
- }
- for (i = 0; i < size; i++) {
- buf[i] = uref.values[i];
- }
- return rc;
- }
- /*modified send_report since G500 also uses a 20 byte long buffer*/
- static int send_report20(int fd, const unsigned char *buf, size_t size) {
- struct hiddev_report_info rinfo;
- struct hiddev_usage_ref uref;
- int i, err;
- for (i = 0; i < size; i++) {
- memset(&uref, 0, sizeof(uref));
- uref.report_type = HID_REPORT_TYPE_OUTPUT;
- uref.report_id = 0x11;
- uref.field_index = 0;
- uref.usage_index = i;
- uref.usage_code = 0xff000001;
- uref.value = buf[i];
- err = ioctl(fd, HIDIOCSUSAGE, &uref);
- if (err < 0)
- return err;
- }
- memset(&rinfo, 0, sizeof(rinfo));
- rinfo.report_type = HID_REPORT_TYPE_OUTPUT;
- rinfo.report_id = 0x11;
- rinfo.num_fields = 1;
- err = ioctl(fd, HIDIOCSREPORT, &rinfo);
- return err;
- }
- static int send_report(int fd, const unsigned char *buf, size_t size) {
- struct hiddev_report_info rinfo;
- struct hiddev_usage_ref uref;
- int i, err;
- for (i = 0; i < size; i++) {
- memset(&uref, 0, sizeof(uref));
- uref.report_type = HID_REPORT_TYPE_OUTPUT;
- uref.report_id = 0x10;
- uref.field_index = 0;
- uref.usage_index = i;
- uref.usage_code = 0xff000001;
- uref.value = buf[i];
- err = ioctl(fd, HIDIOCSUSAGE, &uref);
- if (err < 0)
- return err;
- }
- memset(&rinfo, 0, sizeof(rinfo));
- rinfo.report_type = HID_REPORT_TYPE_OUTPUT;
- rinfo.report_id = 0x10;
- rinfo.num_fields = 1;
- err = ioctl(fd, HIDIOCSREPORT, &rinfo);
- return err;
- }
- void send_msg(int fd,char c0,char c1,char c2, char c3, char c4, char c5)
- {
- unsigned char b[6];
- b[0]=c0;
- b[1]=c1;
- b[2]=c2;
- b[3]=c3;
- b[4]=c4;
- b[5]=c5;
- if(send_report(fd,b,6)<0)
- {
- perror("error sending to device");
- close(fd);
- exit(1);
- }
- }
- /*modified send_msg since G500 also uses a 20 byte long buffer*/
- void send_msg20(int fd,char c0,char c1,char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, char c11, char c12, char c13, char c14 , char c15 , char c16 , char c17, char c18 )
- {
- unsigned char b[19];
- b[0]=c0;
- b[1]=c1;
- b[2]=c2;
- b[3]=c3;
- b[4]=c4;
- b[5]=c5;
- b[6]=c6;
- b[7]=c7;
- b[8]=c8;
- b[9]=c9;
- b[10]=c10;
- b[11]=c11;
- b[12]=c12;
- b[13]=c13;
- b[14]=c14;
- b[15]=c15;
- b[16]=c16;
- b[17]=c17;
- b[18]=c18;
- if(send_report20(fd,b,19)<0)
- {
- perror("error sending to device");
- close(fd);
- exit(1);
- }
- }
- int main (int argc, char **argv) {
- /*this snippet fo the nanosleep comes from http://timmurphy.org/2009/09/29/nanosleep-in-c-c/ */
- int milisec = 100; // length of time to sleep, in miliseconds
- struct timespec req = {0};
- req.tv_sec = 0;
- req.tv_nsec = milisec * 1000000L;
- /* new function hid_reply to check G500's replies. Contains code from vx_hack.c*/
- void hid_reply(int fd) {
- unsigned int buf[6] = {0};
- int i;
- nanosleep(&req, (struct timespec *)NULL);
- if (query_report(fd, 0x10, buf, 6) < 0) {
- perror("query failed");
- close(fd);
- exit(1);
- }
- printf("query result: ");
- for (i = 0; i < 6; i++) {
- printf(" %02x", buf[i]);
- }
- printf("\n");
- }
- int fd = -1;
- int version;
- struct hiddev_devinfo device_info;
- printf("g5hack version: %s\n\n", VERSION);
- /* ioctl() requires a file descriptor, so we check we got one, and
- then open it */
- if (argc != 2) {
- fprintf(stderr, "This works only with Logitech G500! Usage: %s hiddevice \n - hiddevice probably /dev/usb/hiddev0 or /dev/hidraw0\n", argv[0]);
- exit(1);
- }
- if ((fd = open(argv[1], O_RDONLY)) < 0) {
- perror("hiddev open");
- exit(1);
- }
- /* ioctl() accesses the underlying driver */
- ioctl(fd, HIDIOCGVERSION, &version);
- /* the HIDIOCGVERSION ioctl() returns an int
- * so we unpack it and display it
- * we create a patch
- */
- printf("hiddev driver version is %d.%d.%d\n", version >> 16, (version >> 8) & 0xff, version & 0xff);
- /* suck out some device information */
- ioctl(fd, HIDIOCGDEVINFO, &device_info);
- /* the HIDIOCGDEVINFO ioctl() returns hiddev_devinfo
- * structure - see <linux/hiddev.h>
- * So we work through the various elements, displaying
- * each of them
- */
- printf("vendor 0x%04hx product 0x%04hx version 0x%04hx ",
- device_info.vendor, device_info.product,
- device_info.version);
- printf("has %i application%s ", device_info.num_applications,
- (device_info.num_applications==1?"":"s"));
- printf("and is on bus: %d devnum: %d ifnum: %d\n",
- device_info.busnum, device_info.devnum,
- device_info.ifnum);
- /* We have a G500? */
- if((device_info.vendor == (short)VENDOR) && (device_info.product == (short)MOUSE_G500)) {
- if(device_info.product == (short)MOUSE_G500)
- printf(">> G500 Gaming Mouse detected!\n");
- if (ioctl(fd, HIDIOCINITREPORT, 0) < 0) {
- perror("hid report init failed");
- exit(1);
- }
- printf("Initializing the mouse\n");
- send_msg(fd,0x00,0x80,0xa1,0x01,0x00,0x02);
- hid_reply(fd);
- send_msg(fd,0x00,0x83,0xa2,0x01,0x80,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x83,0xa2,0x01,0x88,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x83,0xa2,0x01,0x80,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x83,0xa2,0x01,0x88,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x83,0xa2,0x01,0x80,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x81,0x0f,0x00,0x00,0x00);
- hid_reply(fd);
- send_msg20(fd,0x00,0x82,0xa0,0x04,0x00,0x01,0x02,0x00,0x00,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x83,0xa2,0x00,0xa1,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x83,0xa2,0x00,0xa1,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x83,0x63,0x00,0x00,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x81,0x0f,0x00,0x00,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x80,0x0f,0x00,0x00,0x00);
- hid_reply(fd);
- send_msg20(fd,0x00,0x90,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x4e,0x00,0x00,0xff,0x00,0x00,0x80,0x00,0x22,0x00);
- send_msg20(fd,0x00,0x91,0x01,0x22,0x22,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
- send_msg20(fd,0x00,0x91,0x02,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x10,0x02);
- send_msg20(fd,0x00,0x91,0x03,0x81,0x01,0x00,0x81,0x02,0x00,0x81,0x04,0x00,0x81,0x08,0x00,0x81,0x10,0x00,0x81);
- send_msg20(fd,0x00,0x91,0x04,0x20,0x00,0x81,0x40,0x00,0x81,0x80,0x00,0x81,0x00,0x01,0x81,0x00,0x02,0x8f,0x00);
- send_msg20(fd,0x00,0x93,0x05,0x00,0x8f,0x00,0x00,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x80,0x0f,0x01,0x00,0x00);
- hid_reply(fd);
- printf("Activating DPI Buttons with the standard values 400, 800 and 2000 DPI\n");
- send_msg20(fd,0x00,0x82,0xa0,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00);
- hid_reply(fd);
- // V
- send_msg20(fd,0x00,0x90,0x06,0x01,0x02,0x00,0x00,0x00,0x00,0x4e,0x00,0x00,0xff,0x00,0x00,0x80,0x00,0x11,0x00);
- // V
- send_msg20(fd,0x00,0x91,0x07,0x11,0x22,0x11,0x00,0x22,0x00,0x22,0x22,0x12,0x00,0x55,0x00,0x55,0x22,0x22,0x00);
- send_msg20(fd,0x00,0x91,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x10,0x10,0x02);
- send_msg20(fd,0x00,0x91,0x09,0x81,0x01,0x00,0x81,0x02,0x00,0x81,0x04,0x00,0x81,0x08,0x00,0x81,0x10,0x00,0x81);
- send_msg20(fd,0x00,0x91,0x0a,0x20,0x00,0x83,0x01,0x00,0x83,0x02,0x00,0x83,0x04,0x00,0x83,0x08,0x00,0x8f,0x00);
- send_msg20(fd,0x00,0x93,0x0b,0x00,0x8f,0x00,0x00,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
- hid_reply(fd);
- // V V
- send_msg20(fd,0x00,0x92,0x0c,0x01,0x02,0xff,0x00,0x00,0x00,0x02,0x00,0x00,0xdb,0x5e,0x00,0x00,0x00,0x00,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x83,0x63,0x00,0x00,0x00);
- hid_reply(fd);
- // V
- send_msg20(fd,0x00,0x90,0x0d,0x01,0x00,0xa1,0x00,0x00,0x00,0x4e,0x00,0x00,0xff,0x00,0x00,0x80,0x00,0x11,0x00);
- hid_reply(fd);
- //
- send_msg20(fd,0x00,0x91,0x0e,0x11,0x22,0x11,0x00,0x22,0x00,0x22,0x22,0x12,0x00,0x55,0x00,0x55,0x22,0x22,0x00);
- hid_reply(fd);
- send_msg20(fd,0x00,0x91,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x10,0x10,0x02);
- send_msg20(fd,0x00,0x91,0x10,0x81,0x01,0x00,0x81,0x02,0x00,0x81,0x04,0x00,0x81,0x08,0x00,0x81,0x10,0x00,0x81);
- send_msg20(fd,0x00,0x91,0x11,0x20,0x00,0x81,0x40,0x00,0x81,0x80,0x00,0x83,0x04,0x00,0x83,0x08,0x00,0x8f,0x00);
- send_msg20(fd,0x00,0x93,0x12,0x00,0x8f,0x00,0x00,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x80,0x0f,0x01,0x00,0xa1);
- hid_reply(fd);
- send_msg20(fd,0x00,0x90,0x13,0x01,0x00,0x00,0x00,0x00,0x00,0x4e,0x00,0x00,0xff,0x00,0x00,0x80,0x00,0x11,0x00);
- send_msg20(fd,0x00,0x91,0x14,0x11,0x22,0x11,0x00,0x22,0x00,0x22,0x22,0x12,0x00,0x55,0x00,0x55,0x22,0x22,0x00);
- send_msg20(fd,0x00,0x91,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x10,0x02);
- send_msg20(fd,0x00,0x91,0x16,0x81,0x01,0x00,0x81,0x02,0x00,0x81,0x04,0x00,0x81,0x08,0x00,0x81,0x10,0x00,0x81);
- send_msg20(fd,0x00,0x91,0x17,0x20,0x00,0x81,0x40,0x00,0x81,0x80,0x00,0x83,0x04,0x00,0x83,0x08,0x00,0x8f,0x00);
- send_msg20(fd,0x00,0x93,0x18,0x00,0x8f,0x00,0x00,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
- hid_reply(fd);
- send_msg(fd,0x00,0x80,0x0f,0x01,0x00,0x00);
- hid_reply(fd);
- printf ("Done\n");
- }
- close(fd);
- exit(0);
- }
Add Comment
Please, Sign In to add comment