Clarify Windows Access denied on USB interface 5

Point users to Zadig WinUSB binding for MI_05 and stopping official
Wormhole drivers that hold exclusive claim on interface 5.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
joyharam
2026-07-15 10:52:01 +09:00
parent 64284f1afc
commit 2035c0b4fe
3 changed files with 95 additions and 10 deletions
+33 -10
View File
@@ -182,9 +182,39 @@ def _usb_err_text(exc: BaseException) -> str:
return " ".join(parts).lower()
def _is_not_supported(exc: BaseException) -> bool:
def _is_access_denied(exc: BaseException) -> bool:
text = _usb_err_text(exc)
return "not supported" in text or "unimplemented" in text or "enosys" in text
errno = getattr(exc, "errno", None)
return (
errno in (13, 5)
or "access denied" in text
or "permission" in text
or "busy" in text
or "resource busy" in text
)
def _claim_failure_message(ifnum: int, exc: BaseException) -> str:
base = f"USB interface {ifnum} 점유 실패: {exc}"
if not _IS_WIN:
return base
if _is_access_denied(exc):
return (
f"{base}\n\n"
"Windows가 Interface 5를 다른 드라이버(공식 Wormhole 등)로 붙잡고 있습니다.\n"
"아래를 순서대로 하세요:\n"
"1) 작업 관리자에서 Wormhole / SmartDataLink / j5create 관련 프로그램 모두 종료\n"
"2) Zadig(https://zadig.akeo.ie/) 실행 (관리자)\n"
"3) Options → List All Devices\n"
"4) 목록에서 'Smart Data Link (Interface 5)' 또는 InstanceId에 MI_05 가 있는 항목 선택\n"
"5) Driver 를 WinUSB 로 바꾼 뒤 Replace Driver\n"
"6) 케이블 뽑았다가 다시 꽂고 JUC500 재실행 → 연결\n"
"장치 관리자에서 Interface 5가 'WinUSB' / 'libusb-winusb' 인지도 확인하세요."
)
return (
f"{base}\n"
f"Zadig에서 Smart Data Link → Interface {ifnum} (MI_0{ifnum}) 에 WinUSB를 설치하세요."
)
@dataclass
@@ -435,14 +465,7 @@ class Juc500Link:
usb.util.claim_interface(self._dev, ifnum)
except usb.core.USBError as exc:
if required:
hint = ""
if _IS_WIN:
hint = (
f"\nZadig에서 Smart Data Link → Interface {ifnum} (MI_0{ifnum}) 에 "
"WinUSB 를 설치하세요. 데이터 전송은 Interface 5가 필수입니다.\n"
"공식 j5create Wormhole 드라이버가 있으면 제거하고 다시 시도하세요."
)
raise RuntimeError(f"USB interface {ifnum} 점유 실패: {exc}{hint}") from exc
raise RuntimeError(_claim_failure_message(ifnum, exc)) from exc
return
self._claimed.append(ifnum)