From 2da8f0a699a6aff9c65798ebc31974c5a8badaef Mon Sep 17 00:00:00 2001 From: beerpsi Date: Sat, 30 Dec 2023 23:50:42 +0700 Subject: [PATCH] Works (except it crashes when Brokenithm is out of focus) --- CMakeLists.txt | 12 ++++++++- src/chuniio.c | 69 ++++++++++++++++++++++++++++++++------------------ src/chuniio.h | 20 +++++++-------- 3 files changed, 65 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5568c55..586743e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,16 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_C_COMPILER "gcc") set(CMAKE_CXX_COMPILER "g++") +include(CheckIPOSupported) +check_ipo_supported(RESULT supported OUTPUT error) + +if (supported) + message(STATUS "IPO / LTO enabled") + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) +else() + message(STATUS "IPO / LTO not supported: <${error}>") +endif() + link_directories(src) add_library(chuniio_brokenithm SHARED src/chuniio.c src/chuniio.h @@ -20,4 +30,4 @@ add_library(chuniio_brokenithm SHARED src/chuniio.c set_target_properties(chuniio_brokenithm PROPERTIES PREFIX "") set_target_properties(chuniio_brokenithm PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32 -Wl,--allow-multiple-definition") -target_link_libraries(chuniio_brokenithm "-static-libgcc -Wl,-Bstatic -limobiledevice-1.0 -lssl -lcrypto -lplist-2.0 -lusbmuxd-2.0 -lwinpthread -Wl,-Bdynamic -lws2_32 -lcrypt32 -liphlpapi") +target_link_libraries(chuniio_brokenithm "-static-libgcc -Wl,-Bstatic -limobiledevice-1.0 -lssl -lcrypto -lplist-2.0 -lusbmuxd-2.0 -lpthread -Wl,-Bdynamic -lws2_32 -lcrypt32 -liphlpapi") diff --git a/src/chuniio.c b/src/chuniio.c index ad5e375..766c8b1 100644 --- a/src/chuniio.c +++ b/src/chuniio.c @@ -291,11 +291,13 @@ unsigned int __stdcall android_input_recv_thread_proc(void *v) { const int read = recv(sHost, buffer + recv_len, 4 - recv_len, 0); if (read == -1) { - if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) { + int error = WSAGetLastError(); + + if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN || error == WSAETIMEDOUT) { continue; } - print_err("[INFO] Device disconnected!\n"); + print_err("[INFO] Device disconnected (could not read data, errno %d, os error %ld)\n", errno, error); ctx->connected = false; ctx->exit_flag = true; break; @@ -311,11 +313,13 @@ unsigned int __stdcall android_input_recv_thread_proc(void *v) { const int read = recv(sHost, buffer + recv_len, packet_len - recv_len, 0); if (read == -1) { - if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) { + int error = WSAGetLastError(); + + if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN || error == WSAETIMEDOUT) { continue; } - print_err("[INFO] Device disconnected!\n"); + print_err("[INFO] Device disconnected (could not read data, errno %d, os error %ld)\n", errno, error); ctx->connected = false; ctx->exit_flag = true; break; @@ -410,6 +414,8 @@ unsigned int __stdcall android_input_recv_thread_proc(void *v) { } } + free(ctx); + return 0; } @@ -428,7 +434,7 @@ unsigned int __stdcall server_thread_proc(void* ctx) { android_thread_ctx args = { .sock = sock, .exit_flag = false, - .connected = true, + .connected = false, .last_input_packet_id = 0, .memory = memory, }; @@ -466,16 +472,15 @@ unsigned int __stdcall server_thread_proc(void* ctx) { print_err("[INFO] Device %s:%d connected.\n", user_address, user_socket.sin_port); } - android_thread_ctx args = { - .sock = acc_socket, - .exit_flag = false, - .connected = true, - .last_input_packet_id = 0, - .memory = memory, - }; + android_thread_ctx* args = malloc(sizeof(android_thread_ctx)); + args->sock = acc_socket; + args->exit_flag = false; + args->connected = true; + args->last_input_packet_id = 0, + args->memory = memory; - _beginthreadex(NULL, 0, android_led_broadcast_thread_proc, &args, 0, NULL); - _beginthreadex(NULL, 0, android_input_recv_thread_proc, &args, 0, NULL); + _beginthreadex(NULL, 0, android_led_broadcast_thread_proc, args, 0, NULL); + _beginthreadex(NULL, 0, android_input_recv_thread_proc, args, 0, NULL); } #pragma clang diagnostic pop } @@ -597,9 +602,14 @@ unsigned int __stdcall ios_input_recv_thread_proc(void *v) { } print_err("[INFO] Device disconnected."); + idevice_disconnect(ctx->connection); - free(ctx->connection); + ctx->connection = NULL; + idevice_free(ctx->device); + free(ctx); + + return 0; } unsigned int __stdcall connect_device(void* v) { @@ -614,7 +624,8 @@ unsigned int __stdcall connect_device(void* v) { if ((status = idevice_connect(ctx->device, 24864, &ctx->connection))) { print_err("[ERROR] Connection failed: %d, retrying in 5 seconds\n", status); - free(ctx->connection); + + ctx->connection = NULL; idevice_free(ctx->device); Sleep(5000); @@ -629,21 +640,28 @@ unsigned int __stdcall connect_device(void* v) { if ((status = idevice_connection_receive(ctx->connection, buf, 4, &read))) { print_err("[ERROR] Receiving data failed: %d\n", status); + idevice_disconnect(ctx->connection); - free(ctx->connection); + ctx->connection = NULL; + idevice_free(ctx->device); + return 1; } if (memcmp(buf, "\x03WEL", 4) != 0) { print_err("[ERROR] Client sent invalid data\n"); + idevice_disconnect(ctx->connection); - free(ctx->connection); + ctx->connection = NULL; + idevice_free(ctx->device); + return 1; } print_err("[INFO] Connected to device\n"); + ctx->exit_flag = false; _beginthreadex(NULL, 0, ios_input_recv_thread_proc, ctx, 0, NULL); _beginthreadex(NULL, 0, ios_led_broadcast_thread_proc, ctx, 0, NULL); @@ -657,13 +675,14 @@ void device_event_callback(const idevice_event_t* event, void* user_data) { case IDEVICE_DEVICE_ADD: print_err("[INFO] iDevice added, udid: %s\n", event->udid); - ios_thread_ctx args = { - .exit_flag = false, - .memory = memory, - }; + ios_thread_ctx* args = malloc(sizeof(ios_thread_ctx)); + args->exit_flag = false; + args->memory = memory; + args->device = NULL; + args->connection = NULL; + memcpy(args->remote_udid, event->udid, strlen(event->udid)); - memcpy(args.remote_udid, event->udid, strlen(event->udid)); - _beginthreadex(NULL, 0, connect_device, &args, 0, NULL); + _beginthreadex(NULL, 0, connect_device, args, 0, NULL); break; case IDEVICE_DEVICE_REMOVE: print_err("[INFO] iDevice removed, udid: %s\n", event->udid); @@ -710,7 +729,7 @@ HRESULT server_start() { print_err("[ERROR] Subscribing for iDevice events failed: %d\n", status); return E_FAIL; } else { - print_err("[INFO] Waiting for iDevices..."); + print_err("[INFO] Waiting for iDevices...\n"); } return S_OK; diff --git a/src/chuniio.h b/src/chuniio.h index bd8963b..f15ae96 100644 --- a/src/chuniio.h +++ b/src/chuniio.h @@ -24,7 +24,7 @@ enum { The latest API version as of this writing is 0x0101. */ -uint16_t chuni_io_get_api_version(); +uint16_t __declspec(dllexport) chuni_io_get_api_version(); /* Initialize JVS-based input. This function will be called before any other chuni_io_jvs_*() function calls. Errors returned from this function will @@ -36,7 +36,7 @@ uint16_t chuni_io_get_api_version(); Minimum API version: 0x0100 */ -HRESULT chuni_io_jvs_init(); +HRESULT __declspec(dllexport) chuni_io_jvs_init(); /* Poll JVS input. @@ -60,7 +60,7 @@ HRESULT chuni_io_jvs_init(); Minimum API version: 0x0100 Latest API version: 0x0101 */ -void chuni_io_jvs_poll(uint8_t *opbtn, uint8_t *beams); +void __declspec(dllexport) chuni_io_jvs_poll(uint8_t *opbtn, uint8_t *beams); /* Read the current state of the coin counter. This value should be incremented for every coin detected by the coin acceptor mechanism. This count does not @@ -68,7 +68,7 @@ void chuni_io_jvs_poll(uint8_t *opbtn, uint8_t *beams); Minimum API version: 0x0100 */ -void chuni_io_jvs_read_coin_counter(uint16_t *total); +void __declspec(dllexport) chuni_io_jvs_read_coin_counter(uint16_t *total); /* Initialize touch slider emulation. This function will be called before any @@ -80,7 +80,7 @@ void chuni_io_jvs_read_coin_counter(uint16_t *total); Minimum API version: 0x0100 */ -HRESULT chuni_io_slider_init(void); +HRESULT __declspec(dllexport) chuni_io_slider_init(void); /* Chunithm touch slider layout: @@ -116,7 +116,7 @@ typedef void (*chuni_io_slider_callback_t)(const uint8_t *state); Minimum API version: 0x0100 */ -void chuni_io_slider_start(void *callback); +void __declspec(dllexport) chuni_io_slider_start(void *callback); /* Stop polling the slider. You must cease to invoke the input callback before returning from this function. @@ -131,7 +131,7 @@ void chuni_io_slider_start(void *callback); Minimum API version: 0x0100 */ -void chuni_io_slider_stop(void); +void __declspec(dllexport) chuni_io_slider_stop(void); /* Update the RGB lighting on the slider. A pointer to an array of 32 * 3 = 96 bytes is supplied. The illuminated areas on the touch slider are some @@ -140,7 +140,7 @@ void chuni_io_slider_stop(void); Minimum API version: 0x0100 */ -void chuni_io_slider_set_leds(const uint8_t *rgb); +void __declspec(dllexport) chuni_io_slider_set_leds(const uint8_t *rgb); /* Initialize LED emulation. This function will be called before any other chuni_io_led_*() function calls. @@ -151,7 +151,7 @@ void chuni_io_slider_set_leds(const uint8_t *rgb); Minimum API version: 0x0102 */ -HRESULT chuni_io_led_init(void); +HRESULT __declspec(dllexport) chuni_io_led_init(void); /* Update the RGB LEDs. rgb is a pointer to an array of up to 63 * 3 = 189 bytes. @@ -167,6 +167,6 @@ HRESULT chuni_io_led_init(void); Minimum API version: 0x0102 */ -void chuni_io_led_set_colors(uint8_t board, uint8_t *rgb); +void __declspec(dllexport) chuni_io_led_set_colors(uint8_t board, uint8_t *rgb); #endif //CHUNIIO_BROKENITHM_CHUNIIO_H