Created
October 22, 2019 20:16
-
-
Save cibomahto/066496390821e947096bce85931f7c45 to your computer and use it in GitHub Desktop.
Disco / crash feature for DeathAdder 2000 mouse
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************* | |
Windows HID simplification | |
Alan Ott | |
Signal 11 Software | |
8/22/2009 | |
Copyright 2009 | |
This contents of this file may be used by anyone | |
for any reason without any conditions and may be | |
used as a starting point for your own applications | |
which use HIDAPI. | |
********************************************************/ | |
#include <stdio.h> | |
#include <stdbool.h> | |
#include <wchar.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include "hidapi.h" | |
// Headers needed for sleeping. | |
#ifdef _WIN32 | |
#include <windows.h> | |
#else | |
#include <unistd.h> | |
#endif | |
void parse_feature_report(char *buf, int length) { | |
printf("Feature ID: %x\n", (uint8_t)buf[0]); | |
printf("Length: %i\n", length); | |
} | |
void parse_input_report(char *buf, int length) { | |
static int X = 0; | |
static int Y = 0; | |
printf("Input Report (size:%i)\n ", length); | |
for (int i = 0; i < length; i++) | |
printf("%02hhx ", buf[i]); | |
printf("x:%3i Y:%3i scroll:%3i buttons:",(int8_t)buf[1], (int8_t)buf[2], (int8_t)buf[3]); | |
for(int i = 0; i < 5; i++) | |
printf("%c", buf[0] & (1 << i) ? ('0' + i) : ' '); | |
printf("\n"); | |
// 0: buttons (left=bit 0/right=bit 1/middle=bit 2/up=bit 4/down=bit 5) | |
// 1: mouse x | |
// 2: mouse y | |
// 3: scroll (up=01, down=FF) | |
// 4: mouse x | |
// 5: mouse x | |
// 6: mouse y | |
// 7: mouse y | |
} | |
int main(int argc, char* argv[]) | |
{ | |
int res; | |
unsigned char buf[4096]; | |
#define MAX_STR 255 | |
wchar_t wstr[MAX_STR]; | |
hid_device *handle; | |
int i; | |
#ifdef WIN32 | |
UNREFERENCED_PARAMETER(argc); | |
UNREFERENCED_PARAMETER(argv); | |
#endif | |
struct hid_device_info *devs, *cur_dev; | |
if (hid_init()) | |
return -1; | |
devs = hid_enumerate(0x0, 0x0); | |
cur_dev = devs; | |
while (cur_dev) { | |
printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); | |
printf("\n"); | |
printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string); | |
printf(" Product: %ls\n", cur_dev->product_string); | |
printf(" Release: %hx\n", cur_dev->release_number); | |
printf(" Interface: %d\n", cur_dev->interface_number); | |
printf("\n"); | |
cur_dev = cur_dev->next; | |
} | |
hid_free_enumeration(devs); | |
// Open the device using the VID, PID, | |
// and optionally the Serial number. | |
handle = hid_open(0x1532, 0x005f, NULL); // Razor Deathadder 2000 | |
if (!handle) { | |
printf("unable to open device\n"); | |
return 1; | |
} | |
// Read the Manufacturer String | |
wstr[0] = 0x0000; | |
res = hid_get_manufacturer_string(handle, wstr, MAX_STR); | |
if (res < 0) | |
printf("Unable to read manufacturer string\n"); | |
printf("Manufacturer String: %ls\n", wstr); | |
// Read the Product String | |
wstr[0] = 0x0000; | |
res = hid_get_product_string(handle, wstr, MAX_STR); | |
if (res < 0) | |
printf("Unable to read product string\n"); | |
printf("Product String: %ls\n", wstr); | |
// Set the hid_read() function to be blocking. | |
hid_set_nonblocking(handle, 0); | |
memset(buf,0,sizeof(buf)); | |
// Read a Feature Report from the device | |
buf[0] = 0x90; | |
res = hid_get_feature_report(handle, buf, sizeof(buf)); | |
if (res < 0) { | |
printf("Unable to get a feature report.\n"); | |
printf("%ls", hid_error(handle)); | |
} | |
else { | |
//parse_feature_report(buf, res); | |
// Print out the returned buffer. | |
printf("Feature Report (size:%i)\n ", res); | |
for (i = 0; i < res; i++) { | |
if(i%32 == 0) | |
printf("\n%04x(%08i): ", i,i); | |
printf("%02hhx ", buf[i]); | |
} | |
printf("\n"); | |
FILE *f = fopen("feature_report.bin", "w"); | |
fwrite(buf,1,res,f); | |
fclose(f); | |
} | |
// Writing to these locations makes noticable changes: | |
// buf[508]: body LED | |
// buf[514]: wheel LED | |
// | |
// Other known features to look for: DPI, acceleration | |
// Send a Feature Report to the device | |
//for(int p = 0; p < sizeof(buf); p++) { | |
memset(buf,0,sizeof(buf)/16); | |
//buf[0] = 0; | |
//printf("%i\n", p); | |
printf("\n\nWriting junk feature reports...\n"); | |
for(int j = 0; j < 1000; j++) { | |
//buf[p] =0xff; | |
buf[508] =0xff; | |
buf[514] =0x0; | |
res = hid_send_feature_report(handle, buf, sizeof(buf)); | |
if (res < 0) { | |
printf("Unable to send a feature report.\n"); | |
} | |
//buf[p] =0x0; | |
buf[508] =0x0; | |
buf[514] =0xff; | |
res = hid_send_feature_report(handle, buf, sizeof(buf)); | |
if (res < 0) { | |
printf("Unable to send a feature report.\n"); | |
} | |
} | |
//} | |
memset(buf,0,sizeof(buf)); | |
while(true) { | |
res = hid_read(handle, buf, sizeof(buf)); | |
if (res < 0) { | |
printf("unable to read from device\n"); | |
printf("%ls", hid_error(handle)); | |
} | |
else { | |
parse_input_report(buf, res); | |
} | |
} | |
hid_close(handle); | |
/* Free static HIDAPI objects. */ | |
hid_exit(); | |
#ifdef WIN32 | |
system("pause"); | |
#endif | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment