Skip to content

Instantly share code, notes, and snippets.

@cibomahto
Created October 22, 2019 20:16
Show Gist options
  • Save cibomahto/066496390821e947096bce85931f7c45 to your computer and use it in GitHub Desktop.
Save cibomahto/066496390821e947096bce85931f7c45 to your computer and use it in GitHub Desktop.
Disco / crash feature for DeathAdder 2000 mouse
/*******************************************************
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