Skip to content

Commit

Permalink
Merge pull request #69 from puhitaku/fix/ventura
Browse files Browse the repository at this point in the history
Fix for macOS Ventura
  • Loading branch information
puhitaku authored Feb 7, 2023
2 parents 95729ec + 5b37caa commit 7821b65
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 9 deletions.
2 changes: 2 additions & 0 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ mtplvcapとOBSを組み合わせることで、NikonのカメラをHDMIキャプ

### macOS

:bangbang: macOS Ventura をお使いの方へ: `mtplvcap` コマンドは `sudo` 付きで実行してください。背景や理由については [#68](https://github.com/puhitaku/mtplvcap/issues/68) をご覧ください。

#### 1. 依存パッケージをインストールする
1. [Homebrew](https://brew.sh/)をインストールします

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ To revert it back, follow the instruction:
### macOS
:bangbang: For macOS Ventura users: please run `mtplvcap` command with `sudo`. See issue [#68](https://github.com/puhitaku/mtplvcap/issues/68) for the background and further info.
#### 1. Install dependencies
1. [Install Homebrew](https://brew.sh/)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/google/gousb v2.1.0+incompatible
github.com/gorilla/websocket v1.4.2
github.com/hanwen/usb v0.0.0-20141217151552-69aee4530ac7
github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f
github.com/mattn/go-colorable v0.1.7 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/onsi/ginkgo v1.14.0 // indirect
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ github.com/hanwen/usb v0.0.0-20141217151552-69aee4530ac7/go.mod h1:yF/X+HyjXB5nF
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f h1:B0OD7nYl2FPQEVrw8g2uyc1lGEzNbvrKh7fspGZcbvY=
github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f/go.mod h1:aEt7p9Rvh67BYApmZwNDPpgircTO2kgdmDUoF/1QmwA=
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
Expand Down Expand Up @@ -76,7 +78,6 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
1 change: 0 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,5 @@ func main() {
err = eg.Wait()
if err != nil {
log.Error(err)
os.Exit(1)
}
}
61 changes: 54 additions & 7 deletions mtp/device_direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import (
"fmt"
"io"
"os"
"runtime"
"strconv"
"strings"
"time"

"github.com/hanwen/usb"
"github.com/matishsiao/goInfo"
)

// DeviceDirect implements mtp.Device.
Expand All @@ -18,7 +21,8 @@ type DeviceDirect struct {
h *usb.DeviceHandle
dev *usb.Device

claimed bool
claimed bool
detached bool

// split off descriptor?
devDescr usb.DeviceDescriptor
Expand Down Expand Up @@ -72,6 +76,15 @@ func (d *DeviceDirect) Close() error {
log.USB.Debugf("releaseInterface 0x%x, err: %v", d.ifaceDescr.InterfaceNumber, err)
}
}

if d.detached {
log.USB.Infof("Reattaching kernel driver")
err := d.h.AttachKernelDriver(d.ifaceDescr.InterfaceNumber)
if d.Debug.USB {
log.USB.Debugf("attachKernelDriver 0x%x, err: %v", d.ifaceDescr.InterfaceNumber, err)
}
}

err := d.h.Close()
d.h = nil

Expand All @@ -90,18 +103,19 @@ func (d *DeviceDirect) Done() {
// Claims the USB interface of the device.
func (d *DeviceDirect) claim() error {
if d.h == nil {
return fmt.Errorf("mtp: claim: device not open")
return fmt.Errorf("device not open")
}

err := d.h.ClaimInterface(d.ifaceDescr.InterfaceNumber)
if d.Debug.USB {
log.USB.Debugf("claimInterface 0x%x, err: %v", d.ifaceDescr.InterfaceNumber, err)
}
if err == nil {
d.claimed = true
if err != nil {
return fmt.Errorf("failed to claim: %w", err)
}

return err
d.claimed = true
return nil
}

// Open opens an MTP device.
Expand All @@ -120,10 +134,43 @@ func (d *DeviceDirect) Open() error {
log.USB.Debugf("open, err: %v", err)
}
if err != nil {
return err
return fmt.Errorf("failed to open: %w", err)
}

// Detect macOS Ventura and detach the kernel driver
// https://github.com/puhitaku/mtplvcap/issues/68
if runtime.GOOS == "darwin" {
gi, err := goInfo.GetInfo()
if err != nil {
return fmt.Errorf("failed to get the macOS version: %w", err)
}

tokens := strings.Split(gi.Core, ".")
if len(tokens) != 3 {
return fmt.Errorf("failed to parse the macOS version: version string has unexpected format")
}

version, err := strconv.ParseInt(tokens[0], 10, 64)
if err != nil {
return fmt.Errorf("failed to parse the macOS version: %w", err)
}

if version >= 22 {
log.USB.Infof("detected macOS Ventura or newer: trying to detach the kernel driver")
err = d.h.DetachKernelDriver(d.ifaceDescr.InterfaceNumber)
if err != nil {
return fmt.Errorf("failed to detach the kernel driver: %w", err)
}

d.detached = true
}
}

err = d.claim()
if err != nil {
return fmt.Errorf("failed to claim: %w", err)
}

d.claim()
if d.ifaceDescr.InterfaceStringIndex == 0 {
// Some of the win8phones have no interface field.
info := DeviceInfo{}
Expand Down

0 comments on commit 7821b65

Please sign in to comment.