|
5 | 5 | from dataclasses import astuple |
6 | 6 | import struct |
7 | 7 | import logging |
| 8 | +import errno |
8 | 9 |
|
9 | 10 | logger = logging.getLogger("snagrecover") |
10 | 11 |
|
@@ -37,10 +38,12 @@ def is_usb_path(usb_addr) -> bool: |
37 | 38 | return isinstance(usb_addr, tuple) and isinstance(usb_addr[1], tuple) |
38 | 39 |
|
39 | 40 |
|
40 | | -def access_error(dev_type: str, dev_addr: str): |
41 | | - logger.error( |
42 | | - f"Device access error: failed to access {dev_type} device {dev_addr}, please check its presence and access rights" |
43 | | - ) |
| 41 | +def access_error(dev_type: str, dev_addr: str, log_err: bool = True): |
| 42 | + if log_err: |
| 43 | + logger.error( |
| 44 | + f"Device access error: failed to access {dev_type} device {dev_addr}, please check its presence and access rights" |
| 45 | + ) |
| 46 | + |
44 | 47 | sys.exit(-1) |
45 | 48 |
|
46 | 49 |
|
@@ -141,7 +144,10 @@ def active_cfg_check(dev: usb.core.Device): |
141 | 144 | dev.get_active_configuration() |
142 | 145 | except NotImplementedError: |
143 | 146 | return True |
144 | | - except usb.core.USBError: |
| 147 | + except usb.core.USBError as e: |
| 148 | + if e.errno == errno.EACCES: # permission error |
| 149 | + raise e |
| 150 | + |
145 | 151 | logger.warning( |
146 | 152 | f"Failed to get configuration descriptor for device at {prettify_usb_addr((dev.bus, dev.port_numbers))}!" |
147 | 153 | ) |
@@ -170,8 +176,35 @@ def get_usb( |
170 | 176 | if nb_devs == 1: |
171 | 177 | dev = dev_list[0] |
172 | 178 |
|
173 | | - if ready_check(dev): |
174 | | - return dev |
| 179 | + try: |
| 180 | + if ready_check(dev): |
| 181 | + return dev |
| 182 | + except usb.USBError as e: |
| 183 | + if e.errno == errno.EACCES: |
| 184 | + logger.error( |
| 185 | + f"USB Device has been found at address {pretty_addr} but can't be accessed because of permission issue." |
| 186 | + ) |
| 187 | + if sys.platform == "linux": |
| 188 | + logger.error( |
| 189 | + "Please check your udev config (refer to README.md#Installation on Linux)." |
| 190 | + ) |
| 191 | + logger.error( |
| 192 | + "The following udev rule allow access to the USB device:" |
| 193 | + ) |
| 194 | + logger.error( |
| 195 | + f'SUBSYSTEM=="usb", ATTRS{{idVendor}}=="{dev.idProduct:x}", ATTRS{{idProduct}}=="{dev.idVendor:x}", MODE="0660", TAG+="uaccess"' |
| 196 | + ) |
| 197 | + elif sys.platform == "win32": |
| 198 | + logger.error( |
| 199 | + "Please check your installation (refer to README.md#Installation on Windows 10 or 11)." |
| 200 | + ) |
| 201 | + |
| 202 | + if error_on_fail: |
| 203 | + # Don't retry if it is a permission issue |
| 204 | + access_error("USB", pretty_addr, log_err=False) |
| 205 | + else: |
| 206 | + # Don't silence other USBErrors |
| 207 | + raise e |
175 | 208 |
|
176 | 209 | elif nb_devs > 1: |
177 | 210 | logger.info( |
|
0 commit comments