summaryrefslogtreecommitdiffstats
path: root/src/libirecovery.c
diff options
context:
space:
mode:
authorGravatar Sami Kortelainen2023-12-21 12:51:36 +0100
committerGravatar Nikias Bassen2023-12-21 12:51:36 +0100
commit0a0ad0c4f125d7366a56df0e548ee2ca21114c76 (patch)
tree09709d63179c642688d0605744d1b8a085de1097 /src/libirecovery.c
parent345ac620f2c13322328a51128f76383bf69c1e45 (diff)
downloadlibirecovery-0a0ad0c4f125d7366a56df0e548ee2ca21114c76.tar.gz
libirecovery-0a0ad0c4f125d7366a56df0e548ee2ca21114c76.tar.bz2
win32: Improve irecv_event_handler to make sure events get delivered properly
Diffstat (limited to 'src/libirecovery.c')
-rw-r--r--src/libirecovery.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/src/libirecovery.c b/src/libirecovery.c
index 16330d2..2491b66 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -2491,9 +2491,12 @@ static void *_irecv_event_handler(void* data)
2491{ 2491{
2492 struct _irecv_event_handler_info* info = (struct _irecv_event_handler_info*)data; 2492 struct _irecv_event_handler_info* info = (struct _irecv_event_handler_info*)data;
2493#ifdef WIN32 2493#ifdef WIN32
2494 struct collection newDevices;
2494 const GUID *guids[] = { &GUID_DEVINTERFACE_DFU, &GUID_DEVINTERFACE_IBOOT, NULL }; 2495 const GUID *guids[] = { &GUID_DEVINTERFACE_DFU, &GUID_DEVINTERFACE_IBOOT, NULL };
2495 int running = 1; 2496 int running = 1;
2496 2497
2498 collection_init(&newDevices);
2499
2497 mutex_lock(&(info->startup_mutex)); 2500 mutex_lock(&(info->startup_mutex));
2498 cond_signal(&(info->startup_cond)); 2501 cond_signal(&(info->startup_cond));
2499 mutex_unlock(&(info->startup_mutex)); 2502 mutex_unlock(&(info->startup_mutex));
@@ -2512,6 +2515,13 @@ static void *_irecv_event_handler(void* data)
2512 usbDevices = SetupDiGetClassDevs(guids[k], NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 2515 usbDevices = SetupDiGetClassDevs(guids[k], NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
2513 if (!usbDevices) { 2516 if (!usbDevices) {
2514 debug("%s: ERROR: SetupDiGetClassDevs failed\n", __func__); 2517 debug("%s: ERROR: SetupDiGetClassDevs failed\n", __func__);
2518 // cleanup/free newDevices
2519 FOREACH(struct irecv_win_dev_ctx *win_ctx, &newDevices) {
2520 free(win_ctx->details);
2521 collection_remove(&newDevices, win_ctx);
2522 free(win_ctx);
2523 } ENDFOREACH
2524 collection_free(&newDevices);
2515 return NULL; 2525 return NULL;
2516 } 2526 }
2517 2527
@@ -2564,11 +2574,27 @@ static void *_irecv_event_handler(void* data)
2564 } 2574 }
2565 } ENDFOREACH 2575 } ENDFOREACH
2566 2576
2567 if (!found) { 2577 unsigned int pid = 0;
2568 struct irecv_win_dev_ctx win_ctx; 2578 if (sscanf(details->DevicePath, "\\\\?\\usb#vid_05ac&pid_%04x", &pid)!= 1) {
2569 win_ctx.details = details; 2579 debug("%s: ERROR: failed to parse PID! path: %s\n", __func__, details->DevicePath);
2570 win_ctx.location = location; 2580 free(details);
2571 _irecv_handle_device_add(&win_ctx); 2581 continue;
2582 }
2583 // make sure the current device is actually in the right mode for the given driver interface
2584 int skip = 0;
2585 if ((guids[k] == &GUID_DEVINTERFACE_DFU && pid != IRECV_K_DFU_MODE && pid != IRECV_K_WTF_MODE)
2586 || (guids[k] == &GUID_DEVINTERFACE_IBOOT && (pid < IRECV_K_RECOVERY_MODE_1 || pid > IRECV_K_RECOVERY_MODE_4))
2587 ) {
2588 skip = 1;
2589 }
2590
2591 if (!found && !skip) {
2592 // Add device to newDevices list, and deliver the notification later, when removed devices are first handled.
2593 struct irecv_win_dev_ctx *win_ctx = (struct irecv_win_dev_ctx*)malloc(sizeof(struct irecv_win_dev_ctx));
2594 win_ctx->details = details;
2595 win_ctx->location = location;
2596 collection_add(&newDevices, win_ctx);
2597 details = NULL;
2572 } 2598 }
2573 free(details); 2599 free(details);
2574 } 2600 }
@@ -2577,19 +2603,29 @@ static void *_irecv_event_handler(void* data)
2577 2603
2578 FOREACH(struct irecv_usb_device_info *devinfo, &devices) { 2604 FOREACH(struct irecv_usb_device_info *devinfo, &devices) {
2579 if (!devinfo->alive) { 2605 if (!devinfo->alive) {
2606 debug("%s: removed ecid: %016" PRIx64 ", location: %d\n",__func__, (uint64_t)devinfo->device_info.ecid, devinfo->location);
2580 _irecv_handle_device_remove(devinfo); 2607 _irecv_handle_device_remove(devinfo);
2581 } 2608 }
2582 } ENDFOREACH 2609 } ENDFOREACH
2583 2610
2611 // handle newly added devices and remove from local list
2612 FOREACH(struct irecv_win_dev_ctx *win_ctx, &newDevices) {
2613 debug("%s: found new: %s, location: %d\n", __func__, win_ctx->details->DevicePath, win_ctx->location);
2614 _irecv_handle_device_add(win_ctx);
2615 free(win_ctx->details);
2616 collection_remove(&newDevices, win_ctx);
2617 free(win_ctx);
2618 } ENDFOREACH
2619
2620 Sleep(500);
2584 mutex_lock(&listener_mutex); 2621 mutex_lock(&listener_mutex);
2585 if (collection_count(&listeners) == 0) { 2622 if (collection_count(&listeners) == 0) {
2586 running = 0; 2623 running = 0;
2587 } 2624 }
2588 mutex_unlock(&listener_mutex); 2625 mutex_unlock(&listener_mutex);
2589
2590 Sleep(500);
2591 } while (running); 2626 } while (running);
2592 2627
2628 collection_free(&newDevices);
2593#else /* !WIN32 */ 2629#else /* !WIN32 */
2594#ifdef HAVE_IOKIT 2630#ifdef HAVE_IOKIT
2595 kern_return_t kr; 2631 kern_return_t kr;