@@ -2491,9 +2491,12 @@ static void *_irecv_event_handler(void* data)
24912491{
24922492 struct _irecv_event_handler_info * info = (struct _irecv_event_handler_info * )data ;
24932493#ifdef WIN32
2494+ struct collection newDevices ;
24942495 const GUID * guids [] = { & GUID_DEVINTERFACE_DFU , & GUID_DEVINTERFACE_IBOOT , NULL };
24952496 int running = 1 ;
24962497
2498+ collection_init (& newDevices );
2499+
24972500 mutex_lock (& (info -> startup_mutex ));
24982501 cond_signal (& (info -> startup_cond ));
24992502 mutex_unlock (& (info -> startup_mutex ));
@@ -2512,6 +2515,13 @@ static void *_irecv_event_handler(void* data)
25122515 usbDevices = SetupDiGetClassDevs (guids [k ], NULL , NULL , DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
25132516 if (!usbDevices ) {
25142517 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 );
25152525 return NULL ;
25162526 }
25172527
@@ -2564,11 +2574,27 @@ static void *_irecv_event_handler(void* data)
25642574 }
25652575 } ENDFOREACH
25662576
2567- if (!found ) {
2568- struct irecv_win_dev_ctx win_ctx ;
2569- win_ctx .details = details ;
2570- win_ctx .location = location ;
2571- _irecv_handle_device_add (& win_ctx );
2577+ unsigned int pid = 0 ;
2578+ if (sscanf (details -> DevicePath , "\\\\?\\usb#vid_05ac&pid_%04x" , & pid )!= 1 ) {
2579+ debug ("%s: ERROR: failed to parse PID! path: %s\n" , __func__ , details -> DevicePath );
2580+ free (details );
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 ;
25722598 }
25732599 free (details );
25742600 }
@@ -2577,19 +2603,29 @@ static void *_irecv_event_handler(void* data)
25772603
25782604 FOREACH (struct irecv_usb_device_info * devinfo , & devices ) {
25792605 if (!devinfo -> alive ) {
2606+ debug ("%s: removed ecid: %016" PRIx64 ", location: %d\n" ,__func__ , (uint64_t )devinfo -> device_info .ecid , devinfo -> location );
25802607 _irecv_handle_device_remove (devinfo );
25812608 }
25822609 } ENDFOREACH
25832610
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 );
25842621 mutex_lock (& listener_mutex );
25852622 if (collection_count (& listeners ) == 0 ) {
25862623 running = 0 ;
25872624 }
25882625 mutex_unlock (& listener_mutex );
2589-
2590- Sleep (500 );
25912626 } while (running );
25922627
2628+ collection_free (& newDevices );
25932629#else /* !WIN32 */
25942630#ifdef HAVE_IOKIT
25952631 kern_return_t kr ;
0 commit comments