Add Windows installer packaging (Setup.exe + portable exe)

PyInstaller onedir/onefile specs, Inno Setup script, and GitHub Actions
workflow to produce JUC500-Setup-win64.exe and portable builds.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
joyharam
2026-07-15 10:26:10 +09:00
commit 8774a4843e
31 changed files with 4677 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
# JUC500 분석 노트
분석일: 2026-07-15
환경: Apple Silicon (T6000 USB XHCI), 케이블 연결 상태
## 하드웨어 식별
| 항목 | 값 |
|------|-----|
| VID:PID | `0711:7500` |
| 제품명 | Smart Data Link |
| bcdUSB | 2.10 |
| Device Class | `EF:02:01` (Miscellaneous + IAD) |
| 시리얼 예 | `D264CCA25B431D2E` |
| 미디어 | `/dev/disk4` → `/Volumes/WORMHOLE` (FAT12, ~16.7MB, read-only) |
| Media Name | SD Card Reader |
| 링크 속도 | USB 2.0 High Speed (480 Mb/s) — 허브 경유 시 SuperSpeed 미적용 가능 |
## 구성 인터페이스
1. **IF0** CDC Communication (`02:02:ff`) EP `0x81` INT
2. **IF1** CDC Data (`0a:00:00`) EP `0x02` OUT / `0x83` IN BULK 512
3. **IF2** Mass Storage BOT — WORMHOLE 가상 CD
4. **IF3** HID (mouse proto) EP `0x87`
5. **IF4** HID keyboard EP `0x86`
6. **IF5** Vendor `ff:00:00`
- `0x08` OUT / `0x89` IN
- `0x0A` OUT / `0x8B` IN
Apple Silicon에서 **IF0/IF1/IF5** 는 libusb로 claim 가능. IF2–4는 커널 드라이버 점유(권한 없이 detach 불가).
## 번들 소프트웨어 (WORMHOLE 볼륨)
- `Wormhole.exe` — PE32
- `Wormhole.app` / shell: **i386 + ppc** (케이블에 들어 있는 2015 페이로드)
- `Deployment/GSDD.zz` — 커스텀 압축(OT…) Windows 로더 페이로드
제조사 OEM: **KaiJet Technology / OTi**, 제품명 Wormhole / GO Bridge.
## 공식 다운로드 (2024-09, v1.0.1463.47)
- Mac: `U3Wormhole.app` + `OTiTransfer.framework` → **x86_64 only**
- 여전히 `IOUSBDevice` / `IOUSBDeviceStruct320` / `Query kIOUSBDeviceInterfaceID500`
- Windows: `JUC500_1463.47 Update FW for Windows.exe`
→ **arm64 네이티브 미제공**. Rosetta로 떠도 USB user client 경로가 Silicon에서 불안정할 수 있음.
## 소프트웨어 아키텍처 (공식)
```
Wormhole UI
└── GoBridgeDemon (daemon)
├── OTiTransfer.framework — USB open, alive pipe, data pipe, bounding
├── KMKeyMouse.dylib — HID KM 공유
└── KMClipboard.dylib — 클립보드
```
주요 API: `OTi_Open`, `OTi_SendData`, `OTi_ReadData`, `OTi_CheckBounding`, `OTi_SendHIDPacket`
알림: `OTi_NotifyDevicePlugin`, `OTi_NotifyRemoteAppActive`, …
상위 메시지: XML 기반 **UPipe** (`<OTIMSG>`, `NP_Cmd_*`, 파일/클립보드/KM)
데이터 경로: USB bulk 위 alive/data 파이프 분리 + XML 패킷 (`isXMLPacket`, `Will send an XML packet`).
## Silicon 미동작 원인 (종합)
1. **바이너리 아키텍처** — arm64 없음 (최신도 x86_64)
2. **레거시 IOKit USB API** — IOUSBDevice 경로
3. **커널/유저 권한·드라이버 클레임** 차이
4. j5create M1 지원 목록에 **JUC500 없음** (디스플레이/이더넷 어댑터 위주)
## 본 프로젝트 전략
공식 OTi/UPipe를 재구현하지 않고, **IF5 bulk 브릿지** 위에 자체 `J5FX` 프레임 프로토콜을 올려 Mac↔Win 양쪽에서 동일 스택으로 통신한다. Windows는 WinUSB(Zadig)로 IF5/IF1을 유저랜드에 노출해야 한다.
+47
View File
@@ -0,0 +1,47 @@
# Windows 11 설정
## 설치파일 사용 (권장)
1. `JUC500-Setup-win64.exe` 실행해 설치
또는 `JUC500-portable.exe` / zip 포터블 사용
2. 아래 **Zadig WinUSB** 설정
3. `JUC500` 실행 → 브라우저 GUI → **연결**
Mac에서 빌드 산출물 받기:
```bash
./build-installer-windows.sh --ci
```
## 1. Zadig로 WinUSB 바인딩
1. [Zadig](https://zadig.akeo.ie/) 실행 (관리자)
2. Options → **List All Devices**
3. `Smart Data Link` 선택
4. 하단에서 **Interface 5** 선택 → Driver: **WinUSB** → Replace Driver
5. 마찬가지로 **Interface 1** (CDC Data) 권장
6. Interface 2(Mass Storage), 3·4(HID) 는 그대로 두세요.
공식 Wormhole가 설치돼 있으면 제거하거나 프로세스를 종료한 뒤 Zadig를 실행하세요.
## 2. libusb DLL
[libusb releases](https://github.com/libusb/libusb/releases) 에서 MS64/dll을 받아:
```
juc500/vendor/libusb-1.0.dll
```
에 두거나 PATH에 추가합니다.
## 3. 실행
```powershell
py -3 -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
python -m juc500_xfer info
python -m juc500_xfer recv --dest $env:USERPROFILE\Downloads -y
```
Mac 쪽에서 `send` 하면 전송이 시작됩니다.