diff --git a/README.md b/README.md index 8291991..00986e7 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,8 @@ start driver on wheel: [-u] log effects [-v] + spoof product and vendor id, in hex, eg. 1234:abcd, defaults to 0000:0000 for no spoofing + [-S 0000:0000] ``` ### Usage Examples diff --git a/driver_loops.c b/driver_loops.c index 92821b4..3e9c74e 100644 --- a/driver_loops.c +++ b/driver_loops.c @@ -105,10 +105,10 @@ static void uinput_g29_setup(int uinput_fd, struct loop_context *context){ struct uinput_setup usetup = {0}; usetup.id.bustype = BUS_USB; - usetup.id.vendor = USB_VENDOR_ID_LOGITECH; - usetup.id.product = USB_DEVICE_ID_LOGITECH_G29_WHEEL; + usetup.id.vendor = context->vendor_id == 0? USB_VENDOR_ID_LOGITECH: context->vendor_id; + usetup.id.product = context->product_id == 0? USB_DEVICE_ID_LOGITECH_G29_WHEEL: context->product_id; usetup.ff_effects_max = LG4FF_MAX_EFFECTS; - strcpy(usetup.name, "userspace G29"); + sprintf(usetup.name, "userspace G29 %04x:%04x", usetup.id.vendor, usetup.id.product); ioctl(uinput_fd, UI_DEV_SETUP, &usetup); ioctl(uinput_fd, UI_DEV_CREATE); @@ -156,10 +156,10 @@ static void uinput_g27_setup(int uinput_fd, struct loop_context *context){ struct uinput_setup usetup = {0}; usetup.id.bustype = BUS_USB; - usetup.id.vendor = USB_VENDOR_ID_LOGITECH; - usetup.id.product = USB_DEVICE_ID_LOGITECH_G27_WHEEL; + usetup.id.vendor = context->vendor_id == 0? USB_VENDOR_ID_LOGITECH: context->vendor_id; + usetup.id.product = context->product_id == 0? USB_DEVICE_ID_LOGITECH_G27_WHEEL: context->product_id; usetup.ff_effects_max = LG4FF_MAX_EFFECTS; - strcpy(usetup.name, "userspace G27"); + sprintf(usetup.name, "userspace G27 %04x:%04x", usetup.id.vendor, usetup.id.product); ioctl(uinput_fd, UI_DEV_SETUP, &usetup); ioctl(uinput_fd, UI_DEV_CREATE); @@ -207,10 +207,10 @@ static void uinput_g25_setup(int uinput_fd, struct loop_context *context){ struct uinput_setup usetup = {0}; usetup.id.bustype = BUS_USB; - usetup.id.vendor = USB_VENDOR_ID_LOGITECH; - usetup.id.product = USB_DEVICE_ID_LOGITECH_G25_WHEEL; + usetup.id.vendor = context->vendor_id == 0? USB_VENDOR_ID_LOGITECH: context->vendor_id; + usetup.id.product = context->product_id == 0? USB_DEVICE_ID_LOGITECH_G25_WHEEL: context->product_id; usetup.ff_effects_max = LG4FF_MAX_EFFECTS; - strcpy(usetup.name, "userspace G25"); + sprintf(usetup.name, "userspace G25 %04x:%04x", usetup.id.vendor, usetup.id.product); ioctl(uinput_fd, UI_DEV_SETUP, &usetup); ioctl(uinput_fd, UI_DEV_CREATE); @@ -258,10 +258,10 @@ static void uinput_dfgt_setup(int uinput_fd, struct loop_context *context){ struct uinput_setup usetup = {0}; usetup.id.bustype = BUS_USB; - usetup.id.vendor = USB_VENDOR_ID_LOGITECH; - usetup.id.product = USB_DEVICE_ID_LOGITECH_DFGT_WHEEL; + usetup.id.vendor = context->vendor_id == 0? USB_VENDOR_ID_LOGITECH: context->vendor_id; + usetup.id.product = context->product_id == 0? USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: context->product_id; usetup.ff_effects_max = LG4FF_MAX_EFFECTS; - strcpy(usetup.name, "userspace Driving Force GT"); + sprintf(usetup.name, "userspace Driving Force GT %04x:%04x", usetup.id.vendor, usetup.id.product); ioctl(uinput_fd, UI_DEV_SETUP, &usetup); ioctl(uinput_fd, UI_DEV_CREATE); @@ -309,10 +309,10 @@ static void uinput_dfp_setup(int uinput_fd, struct loop_context *context){ struct uinput_setup usetup = {0}; usetup.id.bustype = BUS_USB; - usetup.id.vendor = USB_VENDOR_ID_LOGITECH; - usetup.id.product = USB_DEVICE_ID_LOGITECH_DFP_WHEEL; + usetup.id.vendor = context->vendor_id == 0? USB_VENDOR_ID_LOGITECH: context->vendor_id; + usetup.id.product = context->product_id == 0? USB_DEVICE_ID_LOGITECH_DFP_WHEEL: context->product_id; usetup.ff_effects_max = LG4FF_MAX_EFFECTS; - strcpy(usetup.name, "userspace Driving Force Pro"); + sprintf(usetup.name, "userspace Driving Force Pro %04x:%04x", usetup.id.vendor, usetup.id.product); ioctl(uinput_fd, UI_DEV_SETUP, &usetup); ioctl(uinput_fd, UI_DEV_CREATE); @@ -360,10 +360,10 @@ static void uinput_dfex_setup(int uinput_fd, struct loop_context *context){ struct uinput_setup usetup = {0}; usetup.id.bustype = BUS_USB; - usetup.id.vendor = USB_VENDOR_ID_LOGITECH; - usetup.id.product = USB_DEVICE_ID_LOGITECH_WHEEL; + usetup.id.vendor = context->vendor_id == 0? USB_VENDOR_ID_LOGITECH: context->vendor_id; + usetup.id.product = context->product_id == 0? USB_DEVICE_ID_LOGITECH_WHEEL: context->product_id; usetup.ff_effects_max = LG4FF_MAX_EFFECTS; - strcpy(usetup.name, "userspace Driving Force EX"); + sprintf(usetup.name, "userspace Driving Force EX %04x:%04x", usetup.id.vendor, usetup.id.product); ioctl(uinput_fd, UI_DEV_SETUP, &usetup); ioctl(uinput_fd, UI_DEV_CREATE); diff --git a/driver_loops.h b/driver_loops.h index b81f267..dc82ae4 100644 --- a/driver_loops.h +++ b/driver_loops.h @@ -17,6 +17,8 @@ struct loop_context{ int combine_pedals; bool play_on_upload; bool log_effects; + int vendor_id; + int product_id; }; void start_loops(struct loop_context context); diff --git a/main.c b/main.c index f0fde91..1cf0b2e 100644 --- a/main.c +++ b/main.c @@ -53,6 +53,8 @@ static void print_help(char *binary_name){ STDOUT(" [-u]\n"); STDOUT(" log effects\n"); STDOUT(" [-v]\n"); + STDOUT(" spoof product and vendor id, in hex, eg. 1234:abcd, defaults to 0000:0000 for no spoofing\n"); + STDOUT(" [-S 0000:0000]\n"); } enum operation_mode{ @@ -114,7 +116,9 @@ static int start_driver( bool hide_effects, int combine_pedals, bool play_on_upload, - bool log_effects + bool log_effects, + int vendor_id, + int product_id ){ list_devices(hidraw_devices, wheels); STDOUT("starting driver on wheel %d\n", wheel_num); @@ -128,6 +132,7 @@ static int start_driver( STDOUT("combine pedals: %d\n", combine_pedals); STDOUT("play effect on upload: %s\n", play_on_upload? "true" : "false"); STDOUT("log effects: %s\n", log_effects? "true" : "false"); + STDOUT("spoof id: %04x:%04x\n", vendor_id, product_id); struct loop_context lc = { .device = hidraw_devices[wheel_num - 1], @@ -140,7 +145,9 @@ static int start_driver( .hide_effects = hide_effects, .combine_pedals = combine_pedals, .play_on_upload = play_on_upload, - .log_effects = log_effects + .log_effects = log_effects, + .vendor_id = vendor_id, + .product_id = product_id }; start_loops(lc); @@ -170,8 +177,10 @@ int main(int argc, char** argv){ int combine_pedals = 0; bool play_on_upload = false; bool log_effects = false; + int vendor_id = 0; + int product_id = 0; - while ((opt = getopt(argc, argv, "lhm:n:wg:a:s:d:f:r:Hc:uv")) != -1){ + while ((opt = getopt(argc, argv, "lhm:n:wg:a:s:d:f:r:Hc:uvS:")) != -1){ #define CLAMP_ARG_VALUE(name, field, min, max){ \ if(field > max){ \ field = max; \ @@ -249,6 +258,9 @@ int main(int argc, char** argv){ case 'v': log_effects = true; break; + case 'S': + sscanf(optarg, "%llx:%llx", &vendor_id, &product_id); + break; default: print_help(argv[0]); return 0; @@ -274,7 +286,7 @@ int main(int argc, char** argv){ reboot_wheel(hidraw_devices, wheels_found, device_number, wmode); return 0; case OPERATION_MODE_DRIVER: - start_driver(hidraw_devices, wheels_found, device_number, gain, auto_center, spring_level, damper_level, friction_level, range, hide_effects, combine_pedals, play_on_upload, log_effects); + start_driver(hidraw_devices, wheels_found, device_number, gain, auto_center, spring_level, damper_level, friction_level, range, hide_effects, combine_pedals, play_on_upload, log_effects, vendor_id, product_id); return 0; default: print_help(argv[0]);