├── LICENSE ├── README.md ├── go.mod ├── go.sum ├── main.go ├── ssh_fido_client.go ├── usbip ├── bin │ ├── attacher.exe │ ├── usb.ids │ ├── usbip.exe │ ├── usbip_root.inf │ ├── usbip_stub.inx │ ├── usbip_stub.sys │ ├── usbip_test.pfx │ ├── usbip_vhci.cat │ ├── usbip_vhci.inf │ ├── usbip_vhci.sys │ ├── usbip_vhci_ude.cat │ ├── usbip_vhci_ude.inf │ ├── usbip_vhci_ude.pdb │ ├── usbip_vhci_ude.sys │ └── usbipd.exe └── usbip-win │ ├── .gitignore │ ├── AUTHORS │ ├── LICENSE │ ├── README.md │ ├── driver │ ├── lib │ │ ├── dbgcode.c │ │ ├── dbgcode.h │ │ ├── dbgcommon.c │ │ ├── dbgcommon.h │ │ ├── devconf.c │ │ ├── devconf.h │ │ ├── libdrv.vcxproj │ │ ├── pdu.c │ │ ├── pdu.h │ │ ├── strutil.c │ │ ├── strutil.h │ │ ├── usb_util.c │ │ ├── usb_util.h │ │ ├── usbd_helper.c │ │ └── usbd_helper.h │ ├── stub │ │ ├── stub_cspkt.c │ │ ├── stub_cspkt.h │ │ ├── stub_dbg.c │ │ ├── stub_dbg.h │ │ ├── stub_dev.c │ │ ├── stub_dev.h │ │ ├── stub_devconf.c │ │ ├── stub_devconf.h │ │ ├── stub_dispatch.c │ │ ├── stub_driver.c │ │ ├── stub_driver.h │ │ ├── stub_ioctl.c │ │ ├── stub_irp.c │ │ ├── stub_irp.h │ │ ├── stub_pnp.c │ │ ├── stub_power.c │ │ ├── stub_read.c │ │ ├── stub_reg.c │ │ ├── stub_reg.h │ │ ├── stub_res.c │ │ ├── stub_res.h │ │ ├── stub_usbd.c │ │ ├── stub_usbd.h │ │ ├── stub_write.c │ │ ├── usbip_stub.inx │ │ └── usbip_stub.vcxproj │ ├── usbip_test.pfx │ ├── vhci │ │ ├── basetype.h │ │ ├── gencat.bat │ │ ├── globals.h │ │ ├── trace.h │ │ ├── usbip_root.inf │ │ ├── usbip_vhci.inf │ │ ├── usbip_vhci.vcxproj │ │ ├── usbreq.c │ │ ├── usbreq.h │ │ ├── vhci.c │ │ ├── vhci.h │ │ ├── vhci_dbg.c │ │ ├── vhci_dbg.h │ │ ├── vhci_dev.c │ │ ├── vhci_dev.h │ │ ├── vhci_devconf.c │ │ ├── vhci_devconf.h │ │ ├── vhci_internal_ioctl.c │ │ ├── vhci_ioctl.c │ │ ├── vhci_ioctl_usrreq.c │ │ ├── vhci_ioctl_vhci.c │ │ ├── vhci_ioctl_vhub.c │ │ ├── vhci_irp.c │ │ ├── vhci_irp.h │ │ ├── vhci_plugin.c │ │ ├── vhci_pnp.c │ │ ├── vhci_pnp.h │ │ ├── vhci_pnp_add.c │ │ ├── vhci_pnp_cap.c │ │ ├── vhci_pnp_devtext.c │ │ ├── vhci_pnp_id.c │ │ ├── vhci_pnp_intf.c │ │ ├── vhci_pnp_relations.c │ │ ├── vhci_pnp_remove.c │ │ ├── vhci_pnp_resources.c │ │ ├── vhci_pnp_start.c │ │ ├── vhci_pnp_vpdo.c │ │ ├── vhci_power.c │ │ ├── vhci_proto.c │ │ ├── vhci_read.c │ │ ├── vhci_vhub.c │ │ ├── vhci_vpdo.c │ │ ├── vhci_vpdo_dsc.c │ │ ├── vhci_wmi.c │ │ └── vhci_write.c │ └── vhci_ude │ │ ├── custom_wpp.ini │ │ ├── gencat.bat │ │ ├── usbip_vhci_ude.inf │ │ ├── usbip_vhci_ude.vcxproj │ │ ├── usbip_vhci_ude.vcxproj.filters │ │ ├── vhci_dbg.c │ │ ├── vhci_dbg.h │ │ ├── vhci_dev.h │ │ ├── vhci_driver.c │ │ ├── vhci_driver.h │ │ ├── vhci_ep.c │ │ ├── vhci_hc.c │ │ ├── vhci_ioctl.c │ │ ├── vhci_plugin.c │ │ ├── vhci_plugout.c │ │ ├── vhci_proto.c │ │ ├── vhci_queue_ep.c │ │ ├── vhci_queue_hc.c │ │ ├── vhci_read.c │ │ ├── vhci_trace.h │ │ ├── vhci_urbr.c │ │ ├── vhci_urbr.h │ │ ├── vhci_urbr_fetch.c │ │ ├── vhci_urbr_fetch_bulk.c │ │ ├── vhci_urbr_fetch_control.c │ │ ├── vhci_urbr_fetch_dscr.c │ │ ├── vhci_urbr_fetch_iso.c │ │ ├── vhci_urbr_fetch_status.c │ │ ├── vhci_urbr_fetch_vendor.c │ │ ├── vhci_urbr_store.c │ │ ├── vhci_urbr_store_bulk.c │ │ ├── vhci_urbr_store_control.c │ │ ├── vhci_urbr_store_dscr.c │ │ ├── vhci_urbr_store_iso.c │ │ ├── vhci_urbr_store_reset.c │ │ ├── vhci_urbr_store_select.c │ │ ├── vhci_urbr_store_status.c │ │ ├── vhci_urbr_store_vendor.c │ │ ├── vhci_vusb.c │ │ └── vhci_write.c │ ├── include │ ├── namecode.h │ ├── usbip_proto.h │ ├── usbip_stub_api.h │ └── usbip_vhci_api.h │ ├── usbip_win.sln │ └── userspace │ ├── COPYING │ ├── INSTALL │ ├── config.h │ ├── doc │ ├── usbip.8 │ ├── usbip_bind_driver.8 │ └── usbipd.8 │ ├── lib │ ├── cscope.out │ ├── dbgcode.c │ ├── dbgcode.h │ ├── getopt.c │ ├── getopt.h │ ├── getopt_long.c │ ├── list.h │ ├── mssign32.h │ ├── names.c │ ├── names.h │ ├── usbip_common.c │ ├── usbip_common.h │ ├── usbip_common.vcxproj │ ├── usbip_forward.c │ ├── usbip_forward.h │ ├── usbip_network.c │ ├── usbip_network.h │ ├── usbip_pki_cat.c │ ├── usbip_pki_sign.c │ ├── usbip_setupdi.c │ ├── usbip_setupdi.h │ ├── usbip_stub.c │ ├── usbip_stub.h │ ├── usbip_util.c │ ├── usbip_util.h │ ├── usbip_windows.c │ └── usbip_windows.h │ ├── src │ ├── attacher │ │ ├── attacher.c │ │ ├── attacher.rc │ │ └── attacher.vcxproj │ ├── usbip │ │ ├── usbip.c │ │ ├── usbip.h │ │ ├── usbip.rc │ │ ├── usbip.vcxproj │ │ ├── usbip_attach.c │ │ ├── usbip_bind.c │ │ ├── usbip_detach.c │ │ ├── usbip_dscr.c │ │ ├── usbip_dscr.h │ │ ├── usbip_install.c │ │ ├── usbip_list.c │ │ ├── usbip_list_local.c │ │ ├── usbip_list_remote.c │ │ ├── usbip_port.c │ │ ├── usbip_unbind.c │ │ ├── usbip_vhci.c │ │ └── usbip_vhci.h │ └── usbipd │ │ ├── usbipd.c │ │ ├── usbipd.h │ │ ├── usbipd.rc │ │ ├── usbipd.vcxproj │ │ ├── usbipd_accept.c │ │ ├── usbipd_import.c │ │ ├── usbipd_list.c │ │ ├── usbipd_sock.c │ │ ├── usbipd_stub.c │ │ └── usbipd_stub.h │ └── usb.ids ├── usbip_linux.go ├── usbip_windows.go └── util.go /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2023 BulwarkID Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SSH Passkey 2 | 3 | ssh_passkey is a utility to enable you to use an SSH key as a passkey for authenticating with websites. It is built on top of [VirtualFIDO](https://github.com/bulwarkid/virtual-fido), a project that lets you create a virtual USB FIDO device for use with WebAuthN. 4 | 5 | Note: this utility uses your public key as the public key for the passkey, so if you don't want to send your public key to a website do not use this with that website. 6 | 7 | ## Limitations 8 | 9 | VirtualFIDO relies on USB/IP to create the virtual USB device, so that library is limited to Windows/Linux right now. Mac support is in development, but Mac virtual USB drivers require an App to install so it might be hard to add Mac support to this utility. 10 | 11 | This utility supports ECDSA, Ed25519, and RSA keys, but many websites only support ECDSA keys, so you may need to use one of those. 12 | 13 | ## Usage 14 | 15 | If you wish to test this utility, [Yubico's WebAuthN test page](https://demo.yubico.com/webauthn-technical/registration) is fairly good and verified to work with ssh_passkey (at least with ECDSA keys). 16 | 17 | ### Windows 18 | 19 | 1. `.\usbip\bin\usbip.exe install` 20 | 2. `go run . start --key=` 21 | 22 | ### Linux 23 | 24 | 1. `sudo modprobe vhci-hcd` 25 | 2. `go run . start --key=` 26 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/bulwarkid/ssh-passkey 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230721233845-29effccf0ea2 // indirect 7 | github.com/fxamacker/cbor/v2 v2.4.0 // indirect 8 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 9 | github.com/spf13/cobra v1.7.0 // indirect 10 | github.com/spf13/pflag v1.0.5 // indirect 11 | github.com/x448/float16 v0.8.4 // indirect 12 | golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/bulwarkid/virtual-fido v0.2.0 h1:sQeh6Wiwc1USBBGjK5Z7rVyDm8NvjlyKe4Skzf1ugmI= 2 | github.com/bulwarkid/virtual-fido v0.2.0/go.mod h1:pNHOgvE3SmxJXBWOj13uKDDhSSfQAm/YavqWyxB1YJ4= 3 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230713194036-f78090336910 h1:uZswzIplj82TjW4KdIsINhLBeP3t9M3UXfRq7WfXXqI= 4 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230713194036-f78090336910/go.mod h1:pNHOgvE3SmxJXBWOj13uKDDhSSfQAm/YavqWyxB1YJ4= 5 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230713200753-476de0a4234b h1:v1EuuRlQ9R+afWdxNcFPykL3mCQ/0rTvDXQ6Awmf6Yo= 6 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230713200753-476de0a4234b/go.mod h1:pNHOgvE3SmxJXBWOj13uKDDhSSfQAm/YavqWyxB1YJ4= 7 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230713205819-774ee9343311 h1:cDWogAStfRFpUny9GNEKFOLA6mjjXBW+QtPVpgLU0B4= 8 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230713205819-774ee9343311/go.mod h1:pNHOgvE3SmxJXBWOj13uKDDhSSfQAm/YavqWyxB1YJ4= 9 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230717213406-f5a281331a25 h1:Chz/yoYKtuTRABogPQvVKVKRk4aHNwqIjg72H7FM/VU= 10 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230717213406-f5a281331a25/go.mod h1:pNHOgvE3SmxJXBWOj13uKDDhSSfQAm/YavqWyxB1YJ4= 11 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230719224141-356207434a94 h1:4LuQ281vq7GCYO9G7EKe7s1jHIROFx+HDDmmC2U/48I= 12 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230719224141-356207434a94/go.mod h1:pNHOgvE3SmxJXBWOj13uKDDhSSfQAm/YavqWyxB1YJ4= 13 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230720222245-5dc17f0130c0 h1:E+HdJqTA3S2jvW/M4+FFlQ5PIHjbBoiMOXUWriW7uIY= 14 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230720222245-5dc17f0130c0/go.mod h1:pNHOgvE3SmxJXBWOj13uKDDhSSfQAm/YavqWyxB1YJ4= 15 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230721233845-29effccf0ea2 h1:0n//3YJE0gLwXvljSflOaybknXdtUuYkyIxC/KWleZs= 16 | github.com/bulwarkid/virtual-fido v0.2.1-beta.2.0.20230721233845-29effccf0ea2/go.mod h1:pNHOgvE3SmxJXBWOj13uKDDhSSfQAm/YavqWyxB1YJ4= 17 | github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 18 | github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= 19 | github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= 20 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 21 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 22 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 23 | github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= 24 | github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 25 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 26 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 27 | github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= 28 | github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= 29 | golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A= 30 | golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 31 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 32 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 33 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/ecdsa" 5 | "crypto/ed25519" 6 | "crypto/rsa" 7 | "fmt" 8 | "io" 9 | "os" 10 | 11 | virtual_fido "github.com/bulwarkid/virtual-fido" 12 | "github.com/bulwarkid/virtual-fido/cose" 13 | "github.com/spf13/cobra" 14 | "golang.org/x/crypto/ssh" 15 | ) 16 | 17 | var keyFilename string 18 | 19 | func start(cmd *cobra.Command, args []string) { 20 | if keyFilename == "" { 21 | fmt.Println("No key specified") 22 | return 23 | } 24 | keyFile, err := os.Open(keyFilename) 25 | if err != nil { 26 | fmt.Println("Could not find key file") 27 | return 28 | } 29 | defer keyFile.Close() 30 | keyBytes, err := io.ReadAll(keyFile) 31 | if err != nil { 32 | fmt.Println("Could not read key file") 33 | return 34 | } 35 | key, err := ssh.ParseRawPrivateKey(keyBytes) 36 | coseKey := cose.SupportedCOSEPrivateKey{} 37 | if ecdsaKey, ok := key.(*ecdsa.PrivateKey); ok { 38 | coseKey.ECDSA = ecdsaKey 39 | } else if ed25519Key, ok := key.(*ed25519.PrivateKey); ok { 40 | coseKey.Ed25519 = ed25519Key 41 | } else if rsaKey, ok := key.(*rsa.PrivateKey); ok { 42 | coseKey.RSA = rsaKey 43 | } else { 44 | fmt.Println("Unsupported key format. This application only supports ECDSA, Ed25519, and RSA private keys.") 45 | return 46 | } 47 | client := NewSSHFIDOClient(&coseKey) 48 | virtual_fido.SetLogOutput(os.Stdout) 49 | done := make(chan bool) 50 | go func() { 51 | virtual_fido.Start(client) 52 | done <- true 53 | }() 54 | go func() { 55 | prog := usbipCommand() 56 | prog.Stdin = os.Stdin 57 | prog.Stdout = os.Stdout 58 | prog.Stderr = os.Stderr 59 | err := prog.Run() 60 | if err != nil { 61 | fmt.Printf("Error: %s\n", err) 62 | } 63 | done <- true 64 | }() 65 | <-done 66 | <-done 67 | } 68 | 69 | var rootCmd = &cobra.Command{ 70 | Use: "ssh_passkey", 71 | Short: "Create a FIDO authenticator using an SSH key", 72 | Long: `ssh_passkey allows you to use your SSH key for the keys in CTAP2 for WebAuthN/Passkeys`, 73 | } 74 | 75 | func init() { 76 | start := &cobra.Command{ 77 | Use: "start", 78 | Short: "Start up FIDO device", 79 | Run: start, 80 | } 81 | rootCmd.PersistentFlags().StringVar(&keyFilename, "key", "", "SSH private key to use") 82 | rootCmd.MarkFlagRequired("key") 83 | rootCmd.AddCommand(start) 84 | } 85 | 86 | func main() { 87 | if err := rootCmd.Execute(); err != nil { 88 | fmt.Fprintln(os.Stderr, err) 89 | os.Exit(1) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /usbip/bin/attacher.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/attacher.exe -------------------------------------------------------------------------------- /usbip/bin/usb.ids: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usb.ids -------------------------------------------------------------------------------- /usbip/bin/usbip.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usbip.exe -------------------------------------------------------------------------------- /usbip/bin/usbip_root.inf: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ; INF file for installing USB/IP vhci driver 4 | ; 5 | ;--*/ 6 | [Version] 7 | Signature="$WINDOWS NT$" 8 | Class=System 9 | ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318} 10 | 11 | Provider=%Provider% 12 | CatalogFile=usbip_vhci.cat 13 | 14 | PnpLockDown=1 15 | DriverVer = 07/19/2021,0.3.5.0 16 | 17 | [Manufacturer] 18 | %StdMfg%=Standard,NTamd64 19 | 20 | [Standard.NTamd64] 21 | %DeviceDesc%=usbip_vhci_Device, USBIPWIN\root 22 | 23 | [DestinationDirs] 24 | DefaultDestDir = 12 25 | 26 | [SourceDisksNames] 27 | 1 = %DiskId1%,,,"" 28 | 29 | [SourceDisksFiles] 30 | usbip_vhci.sys = 1,, 31 | 32 | [Drivers_Dir] 33 | usbip_vhci.sys 34 | 35 | [usbip_vhci_Device.NTamd64] 36 | CopyFiles=Drivers_Dir 37 | 38 | [usbip_vhci_Device.NTamd64.HW] 39 | AddReg=usbip_vhci_Device_AddReg 40 | 41 | [usbip_vhci_Device_AddReg] 42 | HKR,,DeviceCharacteristics,0x10001,0x0100 ; Use same security checks on relative opens 43 | 44 | ;-------------- Service installation 45 | [usbip_vhci_Device.NTamd64.Services] 46 | AddService = usbip_vhci,%SPSVCINST_ASSOCSERVICE%, usbip_vhci_Service_Inst 47 | 48 | ; -------------- vhci driver install sections 49 | [usbip_vhci_Service_Inst] 50 | DisplayName = %ServiceDesc% 51 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 52 | StartType = 3 ; SERVICE_DEMAND_START 53 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 54 | ServiceBinary = %12%\usbip_vhci.sys 55 | LoadOrderGroup = Extended Base 56 | 57 | [Strings] 58 | SPSVCINST_ASSOCSERVICE= 0x00000002 59 | Provider = "usbip-win project" 60 | StdMfg = "usbip-win" 61 | DiskId1 = "usbip-win VHCI Disk" 62 | DeviceDesc = "usbip-win VHCI Root" 63 | vhub_DeviceDesc = "usbip-win VHUB" 64 | ServiceDesc = "usbip-win VHCI Service" 65 | DisplayClassName = "usbip-win" 66 | -------------------------------------------------------------------------------- /usbip/bin/usbip_stub.inx: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ; INF file for installing USB/IP stub driver 4 | ; 5 | ;--*/ 6 | [Version] 7 | Signature="$WINDOWS NT$" 8 | ; USB class cannot be installed via legacy hardware. It can be done via devcon 9 | ;Class=USB 10 | ;ClassGUID={36FC9E60-C465-11CF-8056-444553540000} 11 | Class=System 12 | ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318} 13 | Provider=%OpenSource% 14 | CatalogFile=usbip_stub.cat 15 | DriverVer = 07/19/2021,0.3.5.0 16 | 17 | [Manufacturer] 18 | %StdMfg%=Standard,NTamd64 19 | 20 | [Standard.NTamd64] 21 | %DeviceDesc%=usbip_stub_Device, %hwid% 22 | 23 | [DestinationDirs] 24 | DefaultDestDir = 12 25 | 26 | [SourceDisksNames] 27 | 1 = %DiskId1%,,,"" 28 | 29 | [SourceDisksFiles] 30 | usbip_stub.sys = 1,, 31 | 32 | [Drivers_Dir] 33 | usbip_stub.sys 34 | 35 | [usbip_stub_Device.NTamd64] 36 | CopyFiles=Drivers_Dir 37 | 38 | [usbip_stub_Device.NTamd64.HW] 39 | AddReg=usbip_stub_Device_AddReg 40 | 41 | [usbip_stub_Device_AddReg] 42 | HKR,,DeviceCharacteristics,0x10001,0x0100 ; Use same security checks on relative opens 43 | ;Using default permissions so comment out next lines 44 | ;HKR,,Security,,"D:P(A;;GA;;;SY)(A;;GRGWGX;;;BA)(A;;GRGWGX;;;WD)(A;;GRGWGX;;;RC)" ; Allow generic-all access to all users 45 | ;HKR,,Security,,"D:P(A;;GA;;;BA)(A;;GA;;;SY)" ; Allow generic-all access to Built-in administrators and Local system 46 | 47 | ;-------------- Service installation 48 | [usbip_stub_Device.NTamd64.Services] 49 | AddService = usbip_stub,%SPSVCINST_ASSOCSERVICE%, usbip_stub_Service_Inst 50 | 51 | ; -------------- stub driver install sections 52 | [usbip_stub_Service_Inst] 53 | DisplayName = %ServiceDesc% 54 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 55 | StartType = 3 ; SERVICE_DEMAND_START 56 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 57 | ServiceBinary = %12%\usbip_stub.sys 58 | LoadOrderGroup = Extended Base 59 | 60 | 61 | [Strings] 62 | SPSVCINST_ASSOCSERVICE= 0x00000002 63 | OpenSource = "Open Source" 64 | StdMfg = "USB/IP Project" 65 | DiskId1 = "USB/IP STUB Disk" 66 | DeviceDesc = "USB/IP STUB" 67 | ServiceDesc = "USB/IP STUB Service" 68 | -------------------------------------------------------------------------------- /usbip/bin/usbip_stub.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usbip_stub.sys -------------------------------------------------------------------------------- /usbip/bin/usbip_test.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usbip_test.pfx -------------------------------------------------------------------------------- /usbip/bin/usbip_vhci.cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usbip_vhci.cat -------------------------------------------------------------------------------- /usbip/bin/usbip_vhci.inf: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ; INF file for installing USB/IP vhci driver 4 | ; 5 | ;--*/ 6 | [Version] 7 | Signature="$WINDOWS NT$" 8 | Class=USB 9 | ClassGuid={36FC9E60-C465-11CF-8056-444553540000} 10 | 11 | Provider=%Provider% 12 | CatalogFile=usbip_vhci.cat 13 | 14 | PnpLockDown=1 15 | DriverVer = 07/19/2021,0.3.5.0 16 | 17 | [Manufacturer] 18 | %StdMfg%=Standard,NTamd64 19 | 20 | [Standard.NTamd64] 21 | %DeviceDesc%=usbip_vhci_Device, USBIPWIN\vhci 22 | %vhub_DeviceDesc%=usbip_vhci_Device, USB\ROOT_HUB&VID_1209&PID_8250&REV_0000 23 | 24 | [DestinationDirs] 25 | DefaultDestDir = 12 26 | 27 | [SourceDisksNames] 28 | 1 = %DiskId1%,,,"" 29 | 30 | [SourceDisksFiles] 31 | usbip_vhci.sys = 1,, 32 | 33 | [Drivers_Dir] 34 | usbip_vhci.sys 35 | 36 | [usbip_vhci_Device.NTamd64] 37 | CopyFiles=Drivers_Dir 38 | 39 | [usbip_vhci_Device.NTamd64.HW] 40 | AddReg=usbip_vhci_Device_AddReg 41 | 42 | [usbip_vhci_Device_AddReg] 43 | HKR,,DeviceCharacteristics,0x10001,0x0100 ; Use same security checks on relative opens 44 | 45 | ;-------------- Service installation 46 | [usbip_vhci_Device.NTamd64.Services] 47 | AddService = usbip_vhci,%SPSVCINST_ASSOCSERVICE%, usbip_vhci_Service_Inst 48 | 49 | ; -------------- vhci driver install sections 50 | [usbip_vhci_Service_Inst] 51 | DisplayName = %ServiceDesc% 52 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 53 | StartType = 3 ; SERVICE_DEMAND_START 54 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 55 | ServiceBinary = %12%\usbip_vhci.sys 56 | LoadOrderGroup = Extended Base 57 | 58 | [Strings] 59 | SPSVCINST_ASSOCSERVICE= 0x00000002 60 | Provider = "usbip-win project" 61 | StdMfg = "usbip-win" 62 | DiskId1 = "usbip-win VHCI Disk" 63 | DeviceDesc = "usbip-win VHCI" 64 | vhub_DeviceDesc = "usbip-win VHUB" 65 | ServiceDesc = "usbip-win VHCI Service" 66 | DisplayClassName = "usbip-win" 67 | -------------------------------------------------------------------------------- /usbip/bin/usbip_vhci.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usbip_vhci.sys -------------------------------------------------------------------------------- /usbip/bin/usbip_vhci_ude.cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usbip_vhci_ude.cat -------------------------------------------------------------------------------- /usbip/bin/usbip_vhci_ude.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; usbip_vhci_ude.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=USB 8 | ClassGuid={36FC9E60-C465-11CF-8056-444553540000} 9 | Provider=%ManufacturerName% 10 | CatalogFile=usbip_vhci_ude.cat 11 | DriverVer = 07/19/2021,0.3.5.0 12 | PnpLockDown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | vhci_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | usbip_vhci_ude.sys = 1,, 23 | ; 24 | 25 | 26 | ;***************************************** 27 | ; Install Section 28 | ;***************************************** 29 | 30 | [Manufacturer] 31 | %ManufacturerName%=Standard,NTamd64 32 | 33 | [Standard.NTamd64] 34 | %vhci.DeviceDesc%=vhci_Device, ROOT\VHCI_ude 35 | 36 | [vhci_Device.NT] 37 | CopyFiles=Drivers_Dir 38 | 39 | [Drivers_Dir] 40 | usbip_vhci_ude.sys 41 | 42 | [vhci_Device.NT.HW] 43 | AddReg=vhci_AddReg 44 | 45 | [vhci_AddReg] 46 | ; By default, USBDevice class uses iProduct descriptor to name the device in 47 | ; Device Manager on Windows 8 and higher. 48 | ; Uncomment for this device to use %DeviceName% on Windows 8 and higher: 49 | ;HKR,,FriendlyName,,%vhci.DeviceDesc% 50 | 51 | ;-------------- Service installation 52 | [vhci_Device.NT.Services] 53 | AddService = usbip_vhci_ude,%SPSVCINST_ASSOCSERVICE%, vhci_Service_Inst 54 | 55 | ; -------------- vhci driver install sections 56 | [vhci_Service_Inst] 57 | DisplayName = %vhci.SVCDESC% 58 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 59 | StartType = 3 ; SERVICE_DEMAND_START 60 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 61 | ServiceBinary = %12%\usbip_vhci_ude.sys 62 | 63 | ; 64 | ;--- vhci_Device Coinstaller installation ------ 65 | ; 66 | 67 | [vhci_Device.NT.CoInstallers] 68 | AddReg=vhci_Device_CoInstaller_AddReg 69 | CopyFiles=vhci_Device_CoInstaller_CopyFiles 70 | 71 | [vhci_Device_CoInstaller_AddReg] 72 | ; 73 | 74 | 75 | [vhci_Device_CoInstaller_CopyFiles] 76 | ; 77 | 78 | 79 | [vhci_Device.NT.Wdf] 80 | KmdfService = usbip_vhci_ude, usbip_vhci_wdfsect 81 | [usbip_vhci_wdfsect] 82 | KmdfLibraryVersion = 1.15 83 | 84 | [Strings] 85 | SPSVCINST_ASSOCSERVICE= 0x00000002 86 | ManufacturerName="usbip-win project" 87 | DiskName = "usbip-win VHCI(ude) Disk" 88 | vhci.DeviceDesc = "usbip-win VHCI(ude)" 89 | vhci.SVCDESC = "usbip-win vhci(ude) Service" 90 | REG_MULTI_SZ = 0x00010000 91 | -------------------------------------------------------------------------------- /usbip/bin/usbip_vhci_ude.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usbip_vhci_ude.pdb -------------------------------------------------------------------------------- /usbip/bin/usbip_vhci_ude.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usbip_vhci_ude.sys -------------------------------------------------------------------------------- /usbip/bin/usbipd.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/bin/usbipd.exe -------------------------------------------------------------------------------- /usbip/usbip-win/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.aps 3 | *.vcxproj.user 4 | /.vs 5 | /Debug 6 | /Release 7 | -------------------------------------------------------------------------------- /usbip/usbip-win/AUTHORS: -------------------------------------------------------------------------------- 1 | KyungWoon Cho 2 | ------------------ 3 | Takahiro Hirofuchi 4 | Robert Leibl 5 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/dbgcode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef DBG 4 | 5 | #include 6 | #include 7 | 8 | #include "namecode.h" 9 | 10 | const char *dbg_namecode(namecode_t *namecodes, const char *codetype, unsigned int code); 11 | const char *dbg_namecode_buf(namecode_t *namecodes, const char *codetype, unsigned int code, char *buf, int buf_max); 12 | const char *dbg_ntstatus(NTSTATUS status); 13 | const char *dbg_usbd_status(USBD_STATUS status); 14 | const char *dbg_dispatch_major(UCHAR major); 15 | const char *dbg_pnp_minor(UCHAR minor); 16 | const char *dbg_bus_query_id_type(BUS_QUERY_ID_TYPE type); 17 | const char *dbg_dev_relation(DEVICE_RELATION_TYPE type); 18 | const char *dbg_wmi_minor(UCHAR minor); 19 | const char *dbg_power_minor(UCHAR minor); 20 | const char *dbg_system_power(SYSTEM_POWER_STATE state); 21 | const char *dbg_device_power(DEVICE_POWER_STATE state); 22 | const char *dbg_usb_descriptor_type(UCHAR dsc_type); 23 | 24 | #endif -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/dbgcommon.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "strutil.h" 4 | #include "dbgcode.h" 5 | #include "usbip_proto.h" 6 | 7 | #ifdef DBG 8 | 9 | static namecode_t namecodes_usbip_command[] = { 10 | K_V(USBIP_CMD_SUBMIT) 11 | K_V(USBIP_CMD_UNLINK) 12 | K_V(USBIP_RET_SUBMIT) 13 | K_V(USBIP_RET_UNLINK) 14 | {0,0} 15 | }; 16 | 17 | const char * 18 | dbg_command(UINT32 command) 19 | { 20 | return dbg_namecode(namecodes_usbip_command, "usbip command", command); 21 | } 22 | 23 | const char * 24 | dbg_usbip_hdr(struct usbip_header *hdr) 25 | { 26 | static char buf[512]; 27 | int n; 28 | 29 | n = libdrv_snprintf(buf, 512, "cmd:%s,seq:%u,%s,ep:%u", dbg_command(hdr->base.command), hdr->base.seqnum, hdr->base.direction ? "in" : "out", hdr->base.ep); 30 | switch (hdr->base.command) { 31 | case USBIP_CMD_SUBMIT: 32 | libdrv_snprintf(buf + n, 512 - n, ",tlen:%d,intv:%d", 33 | hdr->u.cmd_submit.transfer_buffer_length, hdr->u.cmd_submit.interval); 34 | break; 35 | case USBIP_RET_SUBMIT: 36 | libdrv_snprintf(buf + n, 512 - n, ",alen:%u", hdr->u.ret_submit.actual_length); 37 | break; 38 | case USBIP_CMD_UNLINK: 39 | libdrv_snprintf(buf + n, 512 - n, ",unlinkseq:%u", hdr->u.cmd_unlink.seqnum); 40 | break; 41 | case USBIP_RET_UNLINK: 42 | libdrv_snprintf(buf + n, 512 - n, ",st:%u", hdr->u.ret_unlink.status); 43 | break; 44 | default: 45 | break; 46 | } 47 | return buf; 48 | } 49 | 50 | #endif -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/dbgcommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /* DPFLTR_SYSTEM_ID emits too many unrelated kernel logs */ 6 | #define MY_DPFLTR DPFLTR_IHVDRIVER_ID 7 | 8 | #ifdef DBG 9 | 10 | #include "usbip_proto.h" 11 | 12 | #define DBGE(part, fmt, ...) DbgPrintEx(MY_DPFLTR, 0x01000000 | (part), DRVPREFIX ":(EE) " fmt, ## __VA_ARGS__) 13 | #define DBGW(part, fmt, ...) DbgPrintEx(MY_DPFLTR, 0x02000000 | (part), DRVPREFIX ":(WW) " fmt, ## __VA_ARGS__) 14 | #define DBGI(part, fmt, ...) DbgPrintEx(MY_DPFLTR, 0x04000000 | (part), DRVPREFIX ": " fmt, ## __VA_ARGS__) 15 | 16 | const char *dbg_usbip_hdr(struct usbip_header *hdr); 17 | const char *dbg_command(UINT32 command); 18 | 19 | #else 20 | 21 | #define DBGE(part, fmt, ...) 22 | #define DBGW(part, fmt, ...) 23 | #define DBGI(part, fmt, ...) 24 | 25 | #endif 26 | 27 | #define ERROR(fmt, ...) DbgPrintEx(MY_DPFLTR, 0xffffffff, DRVPREFIX ":(EE) " fmt, ## __VA_ARGS__) 28 | #define INFO(fmt, ...) DbgPrintEx(MY_DPFLTR, 0xffffffff, DRVPREFIX ": " fmt, ## __VA_ARGS__) 29 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/devconf.c: -------------------------------------------------------------------------------- 1 | #include "devconf.h" 2 | 3 | #include 4 | 5 | PUSB_INTERFACE_DESCRIPTOR 6 | dsc_find_first_intf(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf) 7 | { 8 | return (PUSB_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(dsc_conf, dsc_conf->wTotalLength, dsc_conf, USB_INTERFACE_DESCRIPTOR_TYPE); 9 | } 10 | 11 | PUSB_INTERFACE_DESCRIPTOR 12 | dsc_find_intf(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, UCHAR intf_num, USHORT alt_setting) 13 | { 14 | return USBD_ParseConfigurationDescriptorEx(dsc_conf, dsc_conf, intf_num, alt_setting, -1, -1, -1); 15 | } 16 | 17 | static BOOLEAN 18 | intf_has_matched_ep(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, PUSB_INTERFACE_DESCRIPTOR dsc_intf, PUSB_ENDPOINT_DESCRIPTOR dsc_ep) 19 | { 20 | PVOID start = dsc_intf; 21 | PUSB_ENDPOINT_DESCRIPTOR dsc_ep_try; 22 | UCHAR n_ep = dsc_intf->bNumEndpoints; 23 | 24 | while (n_ep > 0) { 25 | dsc_ep_try = dsc_next_ep(dsc_conf, start); 26 | if (dsc_ep_try == NULL) 27 | break; 28 | if (dsc_ep->bLength == dsc_ep_try->bLength) { 29 | if (RtlCompareMemory(dsc_ep, dsc_ep_try, dsc_ep->bLength) == dsc_ep->bLength) 30 | return TRUE; 31 | } 32 | start = dsc_ep_try; 33 | n_ep--; 34 | } 35 | return FALSE; 36 | } 37 | 38 | PUSB_INTERFACE_DESCRIPTOR 39 | dsc_find_intf_by_ep(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, PUSB_ENDPOINT_DESCRIPTOR dsc_ep) 40 | { 41 | PVOID start = dsc_conf; 42 | 43 | while (start != NULL) { 44 | PUSB_INTERFACE_DESCRIPTOR dsc_intf; 45 | 46 | dsc_intf = (PUSB_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(dsc_conf, dsc_conf->wTotalLength, start, USB_INTERFACE_DESCRIPTOR_TYPE); 47 | if (dsc_intf == NULL) 48 | break; 49 | if (intf_has_matched_ep(dsc_conf, dsc_intf, dsc_ep)) 50 | return dsc_intf; 51 | start = NEXT_DESC(dsc_intf); 52 | } 53 | return NULL; 54 | } 55 | 56 | PUSB_ENDPOINT_DESCRIPTOR 57 | dsc_find_intf_ep(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, PUSB_INTERFACE_DESCRIPTOR dsc_intf, UCHAR epaddr) 58 | { 59 | PVOID start = dsc_intf; 60 | PUSB_ENDPOINT_DESCRIPTOR dsc_ep; 61 | int i; 62 | 63 | for (i = 0; i < dsc_intf->bNumEndpoints; i++) { 64 | dsc_ep = dsc_next_ep(dsc_conf, start); 65 | if (dsc_ep == NULL) 66 | return NULL; 67 | if (dsc_ep->bEndpointAddress == epaddr) 68 | return dsc_ep; 69 | } 70 | return NULL; 71 | } 72 | 73 | PUSB_ENDPOINT_DESCRIPTOR 74 | dsc_next_ep(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, PVOID start) 75 | { 76 | PUSB_COMMON_DESCRIPTOR dsc = (PUSB_COMMON_DESCRIPTOR)start; 77 | if (dsc->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) 78 | dsc = NEXT_DESC(dsc); 79 | return (PUSB_ENDPOINT_DESCRIPTOR)USBD_ParseDescriptors(dsc_conf, dsc_conf->wTotalLength, dsc, USB_ENDPOINT_DESCRIPTOR_TYPE); 80 | } 81 | 82 | ULONG 83 | dsc_conf_get_n_intfs(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf) 84 | { 85 | PVOID start = dsc_conf; 86 | ULONG n_intfs = 0; 87 | 88 | while (start != NULL) { 89 | PUSB_COMMON_DESCRIPTOR desc = USBD_ParseDescriptors(dsc_conf, dsc_conf->wTotalLength, start, USB_INTERFACE_DESCRIPTOR_TYPE); 90 | if (desc == NULL) 91 | break; 92 | start = NEXT_DESC(desc); 93 | n_intfs++; 94 | } 95 | return n_intfs; 96 | } 97 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/devconf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define NEXT_DESC(dsc) (PUSB_COMMON_DESCRIPTOR)((PUCHAR)(dsc) + ((PUSB_COMMON_DESCRIPTOR)dsc)->bLength) 7 | #define NEXT_DESC_INTF(dsc) (PUSB_INTERFACE_DESCRIPTOR)NEXT_DESC(dsc) 8 | #define NEXT_DESC_EP(dsc) (PUSB_ENDPOINT_DESCRIPTOR)NEXT_DESC(dsc) 9 | 10 | PUSB_INTERFACE_DESCRIPTOR 11 | dsc_find_first_intf(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf); 12 | 13 | PUSB_INTERFACE_DESCRIPTOR 14 | dsc_find_intf(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, UCHAR intf_num, USHORT alt_setting); 15 | 16 | PUSB_INTERFACE_DESCRIPTOR 17 | dsc_find_intf_by_ep(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, PUSB_ENDPOINT_DESCRIPTOR dsc_ep); 18 | 19 | PUSB_ENDPOINT_DESCRIPTOR 20 | dsc_find_intf_ep(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, PUSB_INTERFACE_DESCRIPTOR dsc_intf, UCHAR epaddr); 21 | 22 | PUSB_ENDPOINT_DESCRIPTOR 23 | dsc_next_ep(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, PVOID start); 24 | 25 | ULONG 26 | dsc_conf_get_n_intfs(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf); 27 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/pdu.c: -------------------------------------------------------------------------------- 1 | #include "pdu.h" 2 | 3 | static void 4 | swap_cmd_submit(struct usbip_header_cmd_submit *cmd_submit) 5 | { 6 | cmd_submit->transfer_flags = RtlUlongByteSwap(cmd_submit->transfer_flags); 7 | cmd_submit->transfer_buffer_length = RtlUlongByteSwap(cmd_submit->transfer_buffer_length); 8 | cmd_submit->start_frame = RtlUlongByteSwap(cmd_submit->start_frame); 9 | cmd_submit->number_of_packets = RtlUlongByteSwap(cmd_submit->number_of_packets); 10 | cmd_submit->interval = RtlUlongByteSwap(cmd_submit->interval); 11 | } 12 | 13 | static void 14 | swap_ret_submit(struct usbip_header_ret_submit *ret_submit) 15 | { 16 | ret_submit->status = RtlUlongByteSwap(ret_submit->status); 17 | ret_submit->actual_length = RtlUlongByteSwap(ret_submit->actual_length); 18 | ret_submit->start_frame = RtlUlongByteSwap(ret_submit->start_frame); 19 | ret_submit->number_of_packets = RtlUlongByteSwap(ret_submit->number_of_packets); 20 | ret_submit->error_count = RtlUlongByteSwap(ret_submit->error_count); 21 | } 22 | 23 | static void 24 | swap_cmd_unlink(struct usbip_header_cmd_unlink *cmd_unlink) 25 | { 26 | cmd_unlink->seqnum = RtlUlongByteSwap(cmd_unlink->seqnum); 27 | } 28 | 29 | static void 30 | swap_ret_unlink(struct usbip_header_ret_unlink *ret_unlink) 31 | { 32 | ret_unlink->status = RtlUlongByteSwap(ret_unlink->status); 33 | } 34 | 35 | void 36 | swap_usbip_header(struct usbip_header *hdr) 37 | { 38 | hdr->base.seqnum = RtlUlongByteSwap(hdr->base.seqnum); 39 | hdr->base.devid = RtlUlongByteSwap(hdr->base.devid); 40 | hdr->base.direction = RtlUlongByteSwap(hdr->base.direction); 41 | hdr->base.ep = RtlUlongByteSwap(hdr->base.ep); 42 | 43 | switch (hdr->base.command) { 44 | case USBIP_CMD_SUBMIT: 45 | swap_cmd_submit(&hdr->u.cmd_submit); 46 | break; 47 | case USBIP_RET_SUBMIT: 48 | swap_ret_submit(&hdr->u.ret_submit); 49 | break; 50 | case USBIP_CMD_UNLINK: 51 | swap_cmd_unlink(&hdr->u.cmd_unlink); 52 | break; 53 | case USBIP_RET_UNLINK: 54 | swap_ret_unlink(&hdr->u.ret_unlink); 55 | break; 56 | default: 57 | break; 58 | } 59 | 60 | hdr->base.command = RtlUlongByteSwap(hdr->base.command); 61 | } 62 | 63 | void 64 | swap_usbip_iso_descs(struct usbip_header *hdr) 65 | { 66 | struct usbip_iso_packet_descriptor *iso_desc; 67 | int n_pkts; 68 | int i; 69 | 70 | n_pkts = hdr->u.ret_submit.number_of_packets; 71 | iso_desc = (struct usbip_iso_packet_descriptor *)((char *)(hdr + 1) + hdr->u.ret_submit.actual_length); 72 | for (i = 0; i < n_pkts; i++) { 73 | iso_desc->offset = RtlUlongByteSwap(iso_desc->offset); 74 | iso_desc->length = RtlUlongByteSwap(iso_desc->length); 75 | iso_desc->actual_length = RtlUlongByteSwap(iso_desc->actual_length); 76 | iso_desc->status = RtlUlongByteSwap(iso_desc->status); 77 | iso_desc++; 78 | } 79 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/pdu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "usbip_proto.h" 6 | 7 | void swap_usbip_header(struct usbip_header *hdr); 8 | void swap_usbip_iso_descs(struct usbip_header *hdr); -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/strutil.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "strutil.h" 6 | 7 | ULONG libdrv_pooltag = 'dbil'; 8 | 9 | size_t 10 | libdrv_strlenW(LPCWSTR cwstr) 11 | { 12 | size_t len; 13 | NTSTATUS status; 14 | 15 | if (cwstr == NULL) 16 | return 0; 17 | status = RtlStringCchLengthW(cwstr, NTSTRSAFE_MAX_CCH, &len); 18 | if (NT_ERROR(status)) 19 | return 0; 20 | return len; 21 | } 22 | 23 | LPWSTR 24 | libdrv_strdupW(LPCWSTR cwstr) 25 | { 26 | PWCHAR wstr_duped; 27 | size_t len; 28 | NTSTATUS status; 29 | 30 | if (cwstr == NULL) 31 | return NULL; 32 | status = RtlStringCchLengthW(cwstr, NTSTRSAFE_MAX_CCH, &len); 33 | if (NT_ERROR(status)) 34 | return NULL; 35 | wstr_duped = ExAllocatePoolWithTag(PagedPool, (len + 1) * sizeof(WCHAR), libdrv_pooltag); 36 | if (wstr_duped == NULL) 37 | return NULL; 38 | 39 | RtlStringCchPrintfW(wstr_duped, len + 1, cwstr); 40 | return wstr_duped; 41 | } 42 | 43 | int 44 | libdrv_snprintf(char *buf, int size, const char *fmt, ...) 45 | { 46 | va_list arglist; 47 | size_t len; 48 | NTSTATUS status; 49 | 50 | va_start(arglist, fmt); 51 | status = RtlStringCchVPrintfA(buf, size, fmt, arglist); 52 | va_end(arglist); 53 | 54 | if (NT_ERROR(status)) 55 | return 0; 56 | status = RtlStringCchLengthA(buf, size, &len); 57 | if (NT_ERROR(status)) 58 | return 0; 59 | return (int)len; 60 | } 61 | 62 | int 63 | libdrv_snprintfW(PWCHAR buf, int size, LPCWSTR fmt, ...) 64 | { 65 | va_list arglist; 66 | size_t len; 67 | NTSTATUS status; 68 | 69 | va_start(arglist, fmt); 70 | status = RtlStringCchVPrintfW(buf, size, fmt, arglist); 71 | va_end(arglist); 72 | 73 | if (NT_ERROR(status)) 74 | return 0; 75 | status = RtlStringCchLengthW(buf, size, &len); 76 | if (NT_ERROR(status)) 77 | return 0; 78 | return (int)len; 79 | } 80 | 81 | #define BUFMAX_ASPRINTF 128 82 | 83 | int 84 | libdrv_asprintfW(PWCHAR *pbuf, LPCWSTR fmt, ...) 85 | { 86 | WCHAR buf[BUFMAX_ASPRINTF]; 87 | va_list arglist; 88 | size_t len; 89 | NTSTATUS status; 90 | 91 | va_start(arglist, fmt); 92 | status = RtlStringCchVPrintfW(buf, BUFMAX_ASPRINTF, fmt, arglist); 93 | va_end(arglist); 94 | 95 | if (NT_ERROR(status)) 96 | return 0; 97 | status = RtlStringCchLengthW(buf, BUFMAX_ASPRINTF, &len); 98 | if (NT_ERROR(status)) 99 | return 0; 100 | *pbuf = libdrv_strdupW(buf); 101 | if (*pbuf == NULL) 102 | return 0; 103 | return (int)len; 104 | } 105 | 106 | VOID 107 | libdrv_free(PVOID data) 108 | { 109 | if (data) 110 | ExFreePoolWithTag(data, libdrv_pooltag); 111 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/strutil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | size_t libdrv_strlenW(LPCWSTR cwstr); 6 | LPWSTR libdrv_strdupW(LPCWSTR cwstr); 7 | 8 | int libdrv_snprintf(char *buf, int size, const char *fmt, ...); 9 | int libdrv_snprintfW(PWCHAR buf, int size, LPCWSTR fmt, ...); 10 | int libdrv_asprintfW(PWCHAR *pbuf, LPCWSTR fmt, ...); 11 | 12 | VOID libdrv_free(PVOID data); -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/usb_util.c: -------------------------------------------------------------------------------- 1 | #include "usb_util.h" 2 | 3 | #include "usbip_proto.h" 4 | 5 | USHORT 6 | get_usb_speed(USHORT bcdUSB) 7 | { 8 | switch (bcdUSB) { 9 | case 0x0100: 10 | return USB_SPEED_LOW; 11 | case 0x0110: 12 | return USB_SPEED_FULL; 13 | case 0x0200: 14 | return USB_SPEED_HIGH; 15 | case 0x0300: 16 | return USB_SPEED_SUPER; 17 | case 0x0310: 18 | return USB_SPEED_SUPER_PLUS; 19 | default: 20 | return USB_SPEED_LOW; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/usb_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | typedef USB_DEFAULT_PIPE_SETUP_PACKET usb_cspkt_t; 7 | 8 | USHORT get_usb_speed(USHORT bcdUSB); -------------------------------------------------------------------------------- /usbip/usbip-win/driver/lib/usbd_helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | USBD_STATUS to_usbd_status(int usbip_status); 7 | int to_usbip_status(USBD_STATUS usbd_status); 8 | 9 | ULONG to_usbd_flags(int flags); 10 | 11 | void to_usbd_iso_descs(ULONG n_pkts, USBD_ISO_PACKET_DESCRIPTOR *usbd_iso_descs, 12 | const struct usbip_iso_packet_descriptor *iso_descs, BOOLEAN as_result); 13 | 14 | void to_iso_descs(ULONG n_pkts, struct usbip_iso_packet_descriptor *iso_descs, const USBD_ISO_PACKET_DESCRIPTOR *usbd_iso_descs, BOOLEAN as_result); 15 | 16 | ULONG get_iso_descs_len(ULONG n_pkts, const struct usbip_iso_packet_descriptor *iso_descs, BOOLEAN is_actual); 17 | ULONG get_usbd_iso_descs_len(ULONG n_pkts, const USBD_ISO_PACKET_DESCRIPTOR *usbd_iso_descs); 18 | 19 | enum { USB_REQUEST_RESET_PIPE = 0xfe }; 20 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_cspkt.c: -------------------------------------------------------------------------------- 1 | #include "stub_driver.h" 2 | 3 | #include "dbgcode.h" 4 | #include "dbgcommon.h" 5 | 6 | #include "stub_cspkt.h" 7 | 8 | #ifdef DBG 9 | 10 | #include "strutil.h" 11 | 12 | #include 13 | 14 | static namecode_t namecodes_cspkt_reqtype[] = { 15 | K_V(BMREQUEST_STANDARD) 16 | K_V(BMREQUEST_CLASS) 17 | K_V(BMREQUEST_VENDOR) 18 | {0,0} 19 | }; 20 | 21 | static namecode_t namecodes_cspkt_recipient[] = { 22 | K_V(BMREQUEST_TO_DEVICE) 23 | K_V(BMREQUEST_TO_INTERFACE) 24 | K_V(BMREQUEST_TO_ENDPOINT) 25 | K_V(BMREQUEST_TO_OTHER) 26 | {0,0} 27 | }; 28 | 29 | static namecode_t namecodes_cspkt_request[] = { 30 | K_V(USB_REQUEST_GET_STATUS) 31 | K_V(USB_REQUEST_CLEAR_FEATURE) 32 | K_V(USB_REQUEST_SET_FEATURE) 33 | K_V(USB_REQUEST_SET_ADDRESS) 34 | K_V(USB_REQUEST_GET_DESCRIPTOR) 35 | K_V(USB_REQUEST_SET_DESCRIPTOR) 36 | K_V(USB_REQUEST_GET_CONFIGURATION) 37 | K_V(USB_REQUEST_SET_CONFIGURATION) 38 | K_V(USB_REQUEST_GET_INTERFACE) 39 | K_V(USB_REQUEST_SET_INTERFACE) 40 | K_V(USB_REQUEST_SYNC_FRAME) 41 | {0,0} 42 | }; 43 | 44 | static namecode_t namecodes_cspkt_desctype[] = { 45 | K_V(USB_DEVICE_DESCRIPTOR_TYPE) 46 | K_V(USB_CONFIGURATION_DESCRIPTOR_TYPE) 47 | K_V(USB_STRING_DESCRIPTOR_TYPE) 48 | K_V(USB_INTERFACE_DESCRIPTOR_TYPE) 49 | K_V(USB_ENDPOINT_DESCRIPTOR_TYPE) 50 | {0,0} 51 | }; 52 | 53 | const char * 54 | dbg_cspkt_reqtype(UCHAR reqtype) 55 | { 56 | return dbg_namecode(namecodes_cspkt_reqtype, "reqtype", reqtype); 57 | } 58 | 59 | const char * 60 | dbg_cspkt_recipient(UCHAR recip) 61 | { 62 | return dbg_namecode(namecodes_cspkt_recipient, "recipient", recip); 63 | } 64 | 65 | const char * 66 | dbg_cspkt_request(UCHAR req) 67 | { 68 | return dbg_namecode(namecodes_cspkt_request, "request", req); 69 | } 70 | 71 | const char * 72 | dbg_cspkt_desctype(UCHAR desctype) 73 | { 74 | return dbg_namecode(namecodes_cspkt_desctype, "descriptor type", desctype); 75 | } 76 | 77 | const char * 78 | dbg_ctlsetup_packet(usb_cspkt_t *csp) 79 | { 80 | static char buf[1024]; 81 | int n; 82 | 83 | n = libdrv_snprintf(buf, 1024, "%s", CSPKT_IS_IN(csp) ? "in": "out"); 84 | n += libdrv_snprintf(buf + n, 1024 - n, ",%s", dbg_cspkt_reqtype(CSPKT_REQUEST_TYPE(csp))); 85 | n += libdrv_snprintf(buf + n, 1024 - n, ",%s", dbg_cspkt_recipient(CSPKT_RECIPIENT(csp))); 86 | n += libdrv_snprintf(buf + n, 1024 - n, ",%s", dbg_cspkt_request(CSPKT_REQUEST(csp))); 87 | n += libdrv_snprintf(buf + n, 1024 - n, ",wIndex:%hu", csp->wIndex); 88 | n += libdrv_snprintf(buf + n, 1024 - n, ",wLength:%hu", csp->wLength); 89 | n += libdrv_snprintf(buf + n, 1024 - n, ",wValue:%hu", csp->wValue); 90 | 91 | return buf; 92 | } 93 | 94 | #endif -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_cspkt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "usb_util.h" 4 | 5 | #define CSPKT_DIRECTION(csp) (csp)->bmRequestType.Dir 6 | #define CSPKT_REQUEST_TYPE(csp) (csp)->bmRequestType.Type 7 | #define CSPKT_RECIPIENT(csp) (csp)->bmRequestType.Recipient 8 | #define CSPKT_REQUEST(csp) (csp)->bRequest 9 | #define CSPKT_DESCRIPTOR_TYPE(csp) (csp)->wValue.HiByte 10 | #define CSPKT_DESCRIPTOR_INDEX(csp) (csp)->wValue.LowByte 11 | 12 | #define CSPKT_IS_IN(csp) (CSPKT_DIRECTION(csp) == BMREQUEST_DEVICE_TO_HOST) 13 | 14 | #ifdef DBG 15 | 16 | const char *dbg_cspkt_reqtype(UCHAR reqtype); 17 | const char *dbg_cspkt_recipient(UCHAR recip); 18 | const char *dbg_cspkt_request(UCHAR req); 19 | const char *dbg_cspkt_desctype(UCHAR desctype); 20 | const char *dbg_ctlsetup_packet(usb_cspkt_t *csp); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_dbg.c: -------------------------------------------------------------------------------- 1 | #include "stub_driver.h" 2 | #include "stub_dev.h" 3 | #include "dbgcommon.h" 4 | 5 | #include 6 | #include "dbgcode.h" 7 | #include "usbip_stub_api.h" 8 | 9 | #ifdef DBG 10 | 11 | #include "strutil.h" 12 | 13 | const char * 14 | dbg_device(PDEVICE_OBJECT devobj) 15 | { 16 | static char buf[32]; 17 | ANSI_STRING name; 18 | 19 | if (devobj == NULL) 20 | return "null"; 21 | if (devobj->DriverObject) 22 | return "driver null"; 23 | if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name, &devobj->DriverObject->DriverName, TRUE))) { 24 | RtlStringCchCopyA(buf, 32, name.Buffer); 25 | RtlFreeAnsiString(&name); 26 | return buf; 27 | } 28 | else { 29 | return "error"; 30 | } 31 | } 32 | 33 | const char * 34 | dbg_devices(PDEVICE_OBJECT devobj, BOOLEAN is_attached) 35 | { 36 | static char buf[1024]; 37 | int n = 0; 38 | int i; 39 | 40 | for (i = 0; i < 16; i++) { 41 | if (devobj == NULL) 42 | break; 43 | n += libdrv_snprintf(buf + n, 1024 - n, "[%s]", dbg_device(devobj)); 44 | if (is_attached) 45 | devobj = devobj->AttachedDevice; 46 | else 47 | devobj = devobj->NextDevice; 48 | } 49 | return buf; 50 | } 51 | 52 | const char * 53 | dbg_devstub(usbip_stub_dev_t *devstub) 54 | { 55 | static char buf[512]; 56 | 57 | if (devstub == NULL) 58 | return ""; 59 | RtlStringCchPrintfA(buf, 512, "id:%d,hw:%s", devstub->id, devstub->id_hw); 60 | return buf; 61 | } 62 | 63 | static namecode_t namecodes_stub_ioctl[] = { 64 | K_V(IOCTL_USBIP_STUB_GET_DEVINFO) 65 | K_V(IOCTL_USBIP_STUB_EXPORT) 66 | {0,0} 67 | }; 68 | 69 | const char * 70 | dbg_stub_ioctl_code(ULONG ioctl_code) 71 | { 72 | return dbg_namecode(namecodes_stub_ioctl, "ioctl", ioctl_code); 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_dbg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DRVPREFIX "usbip_stub" 4 | #include "dbgcommon.h" 5 | #include "dbgcode.h" 6 | #include "stub_dev.h" 7 | 8 | #ifdef DBG 9 | 10 | #include "stub_devconf.h" 11 | 12 | /* NOTE: LSB cannot be used, which is system-wide mask. Thus, DBG_XXX start from 0x0002 */ 13 | #define DBG_GENERAL 0x0002 14 | #define DBG_DISPATCH 0x0004 15 | #define DBG_DEV 0x0008 16 | #define DBG_IOCTL 0x0010 17 | #define DBG_READWRITE 0x0020 18 | #define DBG_PNP 0x0040 19 | #define DBG_POWER 0x0080 20 | #define DBG_DEVCONF 0x0100 21 | 22 | const char *dbg_device(PDEVICE_OBJECT devobj); 23 | const char *dbg_devices(PDEVICE_OBJECT devobj, BOOLEAN is_attached); 24 | const char *dbg_devstub(usbip_stub_dev_t *devstub); 25 | 26 | const char *dbg_stub_ioctl_code(ULONG ioctl_code); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_dev.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "stub_devconf.h" 9 | 10 | #define N_DEVICES_USBIP_STUB 32 11 | 12 | typedef struct { 13 | long count; 14 | int remove_pending; 15 | KEVENT event; 16 | } usbip_stub_remove_lock_t; 17 | 18 | struct stub_res; 19 | 20 | typedef struct { 21 | PDEVICE_OBJECT self; 22 | PDEVICE_OBJECT pdo; 23 | PDEVICE_OBJECT next_stack_dev; 24 | usbip_stub_remove_lock_t remove_lock; 25 | BOOLEAN is_started; 26 | int id; 27 | 28 | char id_hw[256]; 29 | 30 | devconf_t *devconf; 31 | 32 | UNICODE_STRING interface_name; 33 | 34 | USBD_HANDLE hUSBD; 35 | 36 | KSPIN_LOCK lock_stub_res; 37 | PIRP irp_stub_read; 38 | /* save an ongoing stub result which has been sent partially */ 39 | struct stub_res *sres_ongoing; 40 | ULONG len_sent_partial; 41 | 42 | LIST_ENTRY sres_head_done; 43 | LIST_ENTRY sres_head_pending; 44 | } usbip_stub_dev_t; 45 | 46 | void init_dev_removal_lock(usbip_stub_dev_t *devstub); 47 | NTSTATUS lock_dev_removal(usbip_stub_dev_t *devstub); 48 | void unlock_dev_removal(usbip_stub_dev_t *devstub); 49 | void unlock_wait_dev_removal(usbip_stub_dev_t *devstub); 50 | 51 | void remove_devlink(usbip_stub_dev_t *devstub); 52 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_devconf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "devconf.h" 7 | 8 | #define INFO_INTF_SIZE(info_intf) (sizeof(USBD_INTERFACE_INFORMATION) + ((info_intf)->NumberOfPipes - 1) * sizeof(USBD_PIPE_INFORMATION)) 9 | 10 | typedef struct { 11 | UCHAR bConfigurationValue; 12 | UCHAR bNumInterfaces; 13 | USBD_CONFIGURATION_HANDLE hConf; 14 | PUSB_CONFIGURATION_DESCRIPTOR dsc_conf; 15 | PUSBD_INTERFACE_INFORMATION infos_intf[1]; 16 | } devconf_t; 17 | 18 | devconf_t *create_devconf(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, USBD_CONFIGURATION_HANDLE hconf, PUSBD_INTERFACE_LIST_ENTRY pintf_list); 19 | void free_devconf(devconf_t *devconf); 20 | void update_devconf(devconf_t *devconf, PUSBD_INTERFACE_INFORMATION info_intf); 21 | 22 | USHORT get_info_intf_size(devconf_t *devconf, UCHAR intf_num, USHORT alt_setting); 23 | PUSBD_PIPE_INFORMATION get_info_pipe(devconf_t *devconf, UCHAR epaddr); 24 | 25 | #ifdef DBG 26 | const char *dbg_info_intf(PUSBD_INTERFACE_INFORMATION info_intf); 27 | const char *dbg_info_pipe(PUSBD_PIPE_INFORMATION info_pipe); 28 | #endif -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_dispatch.c: -------------------------------------------------------------------------------- 1 | /* libusb-win32, Generic Windows USB Library 2 | * Copyright (c) 2002-2005 Stephan Meyer 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #include "stub_driver.h" 20 | #include "stub_dbg.h" 21 | #include "stub_irp.h" 22 | 23 | NTSTATUS stub_dispatch_pnp(usbip_stub_dev_t *devstub, IRP *irp); 24 | NTSTATUS stub_dispatch_power(usbip_stub_dev_t *devstub, IRP *irp); 25 | NTSTATUS stub_dispatch_ioctl(usbip_stub_dev_t *devstub, IRP *irp); 26 | NTSTATUS stub_dispatch_read(usbip_stub_dev_t *devstub, IRP *irp); 27 | NTSTATUS stub_dispatch_write(usbip_stub_dev_t *devstub, IRP *irp); 28 | 29 | NTSTATUS 30 | stub_dispatch(PDEVICE_OBJECT devobj, IRP *irp) 31 | { 32 | usbip_stub_dev_t *devstub = (usbip_stub_dev_t *)devobj->DeviceExtension; 33 | IO_STACK_LOCATION *irpstack = IoGetCurrentIrpStackLocation(irp); 34 | 35 | DBGI(DBG_GENERAL | DBG_DISPATCH, "stub_dispatch: %s: Enter\n", dbg_dispatch_major(irpstack->MajorFunction)); 36 | 37 | switch (irpstack->MajorFunction) { 38 | case IRP_MJ_PNP: 39 | return stub_dispatch_pnp(devstub, irp); 40 | case IRP_MJ_POWER: 41 | // ID: 2960644 (farthen) 42 | // You can't set the power state if the device is not handled at all 43 | if (devstub->next_stack_dev == NULL) { 44 | return complete_irp(irp, STATUS_INVALID_DEVICE_STATE, 0); 45 | } 46 | return stub_dispatch_power(devstub, irp); 47 | case IRP_MJ_DEVICE_CONTROL: 48 | return stub_dispatch_ioctl(devstub, irp); 49 | case IRP_MJ_READ: 50 | return stub_dispatch_read(devstub, irp); 51 | case IRP_MJ_WRITE: 52 | return stub_dispatch_write(devstub, irp); 53 | default: 54 | return pass_irp_down(devstub, irp, NULL, NULL); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_driver.c: -------------------------------------------------------------------------------- 1 | /* libusb-win32, Generic Windows USB Library 2 | * Copyright (c) 2002-2005 Stephan Meyer 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #include "stub_driver.h" 20 | #include "stub_dbg.h" 21 | #include "stub_dev.h" 22 | 23 | NTSTATUS stub_add_device(PDRIVER_OBJECT drvobj, PDEVICE_OBJECT pdo); 24 | NTSTATUS stub_dispatch(PDEVICE_OBJECT devobj, IRP *irp); 25 | 26 | static VOID 27 | stub_unload(DRIVER_OBJECT *drvobj) 28 | { 29 | UNREFERENCED_PARAMETER(drvobj); 30 | 31 | DBGI(DBG_DISPATCH, "unload\n"); 32 | } 33 | 34 | NTSTATUS 35 | DriverEntry(DRIVER_OBJECT *drvobj, UNICODE_STRING *regpath) 36 | { 37 | int i; 38 | 39 | UNREFERENCED_PARAMETER(regpath); 40 | 41 | DBGI(DBG_DISPATCH, "DriverEntry: Enter\n"); 42 | 43 | /* initialize the driver object's dispatch table */ 44 | for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { 45 | drvobj->MajorFunction[i] = stub_dispatch; 46 | } 47 | 48 | drvobj->DriverExtension->AddDevice = stub_add_device; 49 | drvobj->DriverUnload = stub_unload; 50 | 51 | return STATUS_SUCCESS; 52 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define USBIP_STUB_POOL_TAG (ULONG)'bUts' -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_ioctl.c: -------------------------------------------------------------------------------- 1 | /* libusb-win32, Generic Windows USB Library 2 | * Copyright (c) 2010 Travis Robinson 3 | * Copyright (c) 2002-2005 Stephan Meyer 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #include "stub_driver.h" 21 | #include "stub_dbg.h" 22 | #include "stub_irp.h" 23 | #include "usbip_stub_api.h" 24 | #include "usbip_proto.h" 25 | 26 | #include "stub_usbd.h" 27 | #include "stub_devconf.h" 28 | 29 | static UCHAR 30 | get_speed_from_bcdUSB(USHORT bcdUSB) 31 | { 32 | switch (bcdUSB) { 33 | case 0x0100: 34 | return USB_SPEED_LOW; 35 | case 0x0110: 36 | return USB_SPEED_FULL; 37 | case 0x0200: 38 | return USB_SPEED_HIGH; 39 | case 0x0250: 40 | return USB_SPEED_WIRELESS; 41 | case 0x0300: 42 | return USB_SPEED_SUPER; 43 | case 0x0310: 44 | return USB_SPEED_SUPER_PLUS; 45 | default: 46 | return USB_SPEED_UNKNOWN; 47 | } 48 | } 49 | 50 | static NTSTATUS 51 | process_get_devinfo(usbip_stub_dev_t *devstub, IRP *irp) 52 | { 53 | PIO_STACK_LOCATION irpStack; 54 | ULONG outlen; 55 | NTSTATUS status = STATUS_SUCCESS; 56 | 57 | irpStack = IoGetCurrentIrpStackLocation(irp); 58 | 59 | outlen = irpStack->Parameters.DeviceIoControl.OutputBufferLength; 60 | irp->IoStatus.Information = 0; 61 | if (outlen < sizeof(ioctl_usbip_stub_devinfo_t)) 62 | status = STATUS_INVALID_PARAMETER; 63 | else { 64 | USB_DEVICE_DESCRIPTOR desc; 65 | 66 | if (get_usb_device_desc(devstub, &desc)) { 67 | ioctl_usbip_stub_devinfo_t *devinfo; 68 | 69 | devinfo = (ioctl_usbip_stub_devinfo_t *)irp->AssociatedIrp.SystemBuffer; 70 | devinfo->vendor = desc.idVendor; 71 | devinfo->product = desc.idProduct; 72 | devinfo->speed = get_speed_from_bcdUSB(desc.bcdUSB); 73 | devinfo->class = desc.bDeviceClass; 74 | devinfo->subclass = desc.bDeviceSubClass; 75 | devinfo->protocol = desc.bDeviceProtocol; 76 | irp->IoStatus.Information = sizeof(ioctl_usbip_stub_devinfo_t); 77 | } 78 | else { 79 | status = STATUS_UNSUCCESSFUL; 80 | } 81 | } 82 | 83 | irp->IoStatus.Status = status; 84 | IoCompleteRequest(irp, IO_NO_INCREMENT); 85 | return status; 86 | } 87 | 88 | static NTSTATUS 89 | process_export(usbip_stub_dev_t *devstub, IRP *irp) 90 | { 91 | UNREFERENCED_PARAMETER(devstub); 92 | 93 | DBGI(DBG_IOCTL, "exporting: %s\n", dbg_devstub(devstub)); 94 | 95 | irp->IoStatus.Status = STATUS_SUCCESS; 96 | IoCompleteRequest(irp, IO_NO_INCREMENT); 97 | 98 | DBGI(DBG_IOCTL, "exported: %s\n", dbg_devstub(devstub)); 99 | 100 | return STATUS_SUCCESS; 101 | } 102 | 103 | NTSTATUS 104 | stub_dispatch_ioctl(usbip_stub_dev_t *devstub, IRP *irp) 105 | { 106 | PIO_STACK_LOCATION irpStack; 107 | ULONG ioctl_code; 108 | 109 | irpStack = IoGetCurrentIrpStackLocation(irp); 110 | ioctl_code = irpStack->Parameters.DeviceIoControl.IoControlCode; 111 | 112 | DBGI(DBG_IOCTL, "dispatch_ioctl: code: %s\n", dbg_stub_ioctl_code(ioctl_code)); 113 | 114 | switch (ioctl_code) { 115 | case IOCTL_USBIP_STUB_GET_DEVINFO: 116 | return process_get_devinfo(devstub, irp); 117 | case IOCTL_USBIP_STUB_EXPORT: 118 | return process_export(devstub, irp); 119 | default: 120 | return pass_irp_down(devstub, irp, NULL, NULL); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_irp.c: -------------------------------------------------------------------------------- 1 | #include "stub_driver.h" 2 | #include "stub_dbg.h" 3 | #include "stub_dev.h" 4 | 5 | NTSTATUS 6 | complete_irp(IRP *irp, NTSTATUS status, ULONG info) 7 | { 8 | irp->IoStatus.Status = status; 9 | irp->IoStatus.Information = info; 10 | IoCompleteRequest(irp, IO_NO_INCREMENT); 11 | 12 | return status; 13 | } 14 | 15 | NTSTATUS 16 | pass_irp_down(usbip_stub_dev_t *devstub, IRP *irp, PIO_COMPLETION_ROUTINE completion_routine, void *context) 17 | { 18 | if (completion_routine) { 19 | IoCopyCurrentIrpStackLocationToNext(irp); 20 | IoSetCompletionRoutine(irp, completion_routine, context, TRUE, TRUE, TRUE); 21 | } 22 | else { 23 | IoSkipCurrentIrpStackLocation(irp); 24 | } 25 | 26 | return IoCallDriver(devstub->next_stack_dev, irp); 27 | } 28 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_irp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "stub_dev.h" 5 | 6 | NTSTATUS complete_irp(IRP *irp, NTSTATUS status, ULONG info); 7 | NTSTATUS pass_irp_down(usbip_stub_dev_t *devstub, IRP *irp, PIO_COMPLETION_ROUTINE completion_routine, void *context); 8 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_pnp.c: -------------------------------------------------------------------------------- 1 | /* libusb-win32, Generic Windows USB Library 2 | * Copyright (c) 2002-2005 Stephan Meyer 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #include "stub_driver.h" 20 | #include "stub_dbg.h" 21 | #include "stub_irp.h" 22 | 23 | static NTSTATUS 24 | on_start_complete(DEVICE_OBJECT *devobj, IRP *irp, void *context) 25 | { 26 | usbip_stub_dev_t *devstub = (usbip_stub_dev_t *)devobj->DeviceExtension; 27 | 28 | UNREFERENCED_PARAMETER(context); 29 | 30 | if (irp->PendingReturned) { 31 | IoMarkIrpPending(irp); 32 | } 33 | 34 | devstub->is_started = TRUE; 35 | unlock_dev_removal(devstub); 36 | 37 | return STATUS_SUCCESS; 38 | } 39 | 40 | static void 41 | disable_interface(usbip_stub_dev_t *devstub) 42 | { 43 | NTSTATUS status; 44 | 45 | if (devstub->interface_name.Buffer == NULL) 46 | return; 47 | 48 | status = IoSetDeviceInterfaceState(&devstub->interface_name, FALSE); 49 | if (NT_ERROR(status)) { 50 | DBGE(DBG_PNP, "failed to disable interface: err: %s\n", dbg_ntstatus(status)); 51 | } 52 | if (devstub->interface_name.Buffer) { 53 | RtlFreeUnicodeString(&devstub->interface_name); 54 | devstub->interface_name.Buffer = NULL; 55 | } 56 | } 57 | 58 | NTSTATUS 59 | stub_dispatch_pnp(usbip_stub_dev_t *devstub, IRP *irp) 60 | { 61 | IO_STACK_LOCATION *irpstack = IoGetCurrentIrpStackLocation(irp); 62 | NTSTATUS status; 63 | 64 | DBGI(DBG_DISPATCH, "dispatch_pnp: minor: %s\n", dbg_pnp_minor(irpstack->MinorFunction)); 65 | 66 | status = lock_dev_removal(devstub); 67 | if (NT_ERROR(status)) { 68 | DBGI(DBG_PNP, "device is pending removal: %s\n", dbg_devstub(devstub)); 69 | return complete_irp(irp, status, 0); 70 | } 71 | 72 | switch (irpstack->MinorFunction) { 73 | case IRP_MN_START_DEVICE: 74 | status = IoSetDeviceInterfaceState(&devstub->interface_name, TRUE); 75 | if (NT_ERROR(status)) { 76 | DBGE(DBG_PNP, "failed to enable interface: err: %s\n", dbg_ntstatus(status)); 77 | } 78 | return pass_irp_down(devstub, irp, on_start_complete, NULL); 79 | case IRP_MN_REMOVE_DEVICE: 80 | disable_interface(devstub); 81 | 82 | devstub->is_started = FALSE; 83 | 84 | /* wait until all outstanding requests are finished */ 85 | unlock_wait_dev_removal(devstub); 86 | 87 | /* USBD_CloseHandle should be ahead of pass_irp_down */ 88 | USBD_CloseHandle(devstub->hUSBD); 89 | 90 | status = pass_irp_down(devstub, irp, NULL, NULL); 91 | 92 | DBGI(DBG_PNP, "deleting device: %s\n", dbg_devstub(devstub)); 93 | 94 | remove_devlink(devstub); 95 | free_devconf(devstub->devconf); 96 | devstub->devconf = NULL; 97 | 98 | /* delete the device object */ 99 | IoDetachDevice(devstub->next_stack_dev); 100 | IoDeleteDevice(devstub->self); 101 | return status; 102 | case IRP_MN_SURPRISE_REMOVAL: 103 | devstub->is_started = FALSE; 104 | 105 | disable_interface(devstub); 106 | status = STATUS_SUCCESS; 107 | break; 108 | case IRP_MN_STOP_DEVICE: 109 | devstub->is_started = FALSE; 110 | break; 111 | default: 112 | break; 113 | } 114 | 115 | unlock_dev_removal(devstub); 116 | return pass_irp_down(devstub, irp, NULL, NULL); 117 | } 118 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_power.c: -------------------------------------------------------------------------------- 1 | /* libusb-win32, Generic Windows USB Library 2 | * Copyright (c) 2002-2005 Stephan Meyer 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #include "stub_driver.h" 20 | #include "stub_dbg.h" 21 | 22 | NTSTATUS 23 | stub_dispatch_power(usbip_stub_dev_t *devstub, IRP *irp) 24 | { 25 | NTSTATUS status; 26 | 27 | status = lock_dev_removal(devstub); 28 | if (NT_ERROR(status)) { 29 | irp->IoStatus.Status = status; 30 | PoStartNextPowerIrp(irp); 31 | IoCompleteRequest(irp, IO_NO_INCREMENT); 32 | return status; 33 | } 34 | 35 | /* pass all other power IRPs down without setting a completion routine */ 36 | PoStartNextPowerIrp(irp); 37 | IoSkipCurrentIrpStackLocation(irp); 38 | status = PoCallDriver(devstub->next_stack_dev, irp); 39 | unlock_dev_removal(devstub); 40 | 41 | return status; 42 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_read.c: -------------------------------------------------------------------------------- 1 | /* libusb-win32, Generic Windows USB Library 2 | * Copyright (c) 2010 Travis Robinson 3 | * Copyright (c) 2002-2005 Stephan Meyer 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #include "stub_driver.h" 21 | #include "stub_dbg.h" 22 | #include "usbip_proto.h" 23 | 24 | #include "stub_res.h" 25 | 26 | static struct usbip_header * 27 | get_usbip_hdr_from_read_irp(PIRP irp) 28 | { 29 | PIO_STACK_LOCATION irpstack; 30 | ULONG len; 31 | 32 | irpstack = IoGetCurrentIrpStackLocation(irp); 33 | len = irpstack->Parameters.Read.Length; 34 | if (len < sizeof(struct usbip_header)) { 35 | return NULL; 36 | } 37 | irp->IoStatus.Information = len; 38 | return (struct usbip_header *)irp->AssociatedIrp.SystemBuffer; 39 | } 40 | 41 | NTSTATUS 42 | stub_dispatch_read(usbip_stub_dev_t *devstub, IRP *irp) 43 | { 44 | DBGI(DBG_GENERAL | DBG_READWRITE, "dispatch_read: enter\n"); 45 | 46 | return collect_done_stub_res(devstub, irp); 47 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_reg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stub_dev.h" 4 | 5 | char * 6 | reg_get_id_hw(PDEVICE_OBJECT pdo); 7 | char * 8 | reg_get_id_compat(PDEVICE_OBJECT pdo); 9 | BOOLEAN 10 | reg_get_properties(usbip_stub_dev_t *devstub); -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_res.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stub_dev.h" 4 | #include "usbip_proto.h" 5 | 6 | typedef struct stub_res { 7 | PIRP irp; 8 | struct usbip_header header; 9 | PVOID data; 10 | int data_len; 11 | LIST_ENTRY list; 12 | } stub_res_t; 13 | 14 | #ifdef DBG 15 | const char *dbg_stub_res(stub_res_t *sres, usbip_stub_dev_t* devstub); 16 | #endif 17 | 18 | stub_res_t * 19 | create_stub_res(unsigned int cmd, unsigned long seqnum, int err, PVOID data, int data_len, ULONG n_pkts, BOOLEAN need_copy); 20 | void free_stub_res(stub_res_t *sres); 21 | 22 | void add_pending_stub_res(usbip_stub_dev_t *devstub, stub_res_t *sres, PIRP irp); 23 | void del_pending_stub_res(usbip_stub_dev_t *devstub, stub_res_t *sres); 24 | BOOLEAN cancel_pending_stub_res(usbip_stub_dev_t *devstub, unsigned int seqnum); 25 | 26 | NTSTATUS collect_done_stub_res(usbip_stub_dev_t *devstub, PIRP irp_read); 27 | 28 | void reply_stub_req(usbip_stub_dev_t *devstub, stub_res_t *sres); 29 | 30 | void reply_stub_req_hdr(usbip_stub_dev_t *devstub, unsigned int cmd, unsigned long seqnum); 31 | void reply_stub_req_err(usbip_stub_dev_t *devstub, unsigned int cmd, unsigned long seqnum, int err); 32 | void reply_stub_req_data(usbip_stub_dev_t *devstub, unsigned long seqnum, PVOID data, int data_len, BOOLEAN need_copy); 33 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/stub_usbd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stub_dev.h" 4 | 5 | #include "usbip_proto.h" 6 | #include "usb_util.h" 7 | 8 | BOOLEAN get_usb_status(usbip_stub_dev_t *devstub, USHORT op, USHORT idx, PVOID buff, PUCHAR plen); 9 | BOOLEAN get_usb_device_desc(usbip_stub_dev_t *devstub, PUSB_DEVICE_DESCRIPTOR pdesc); 10 | BOOLEAN get_usb_desc(usbip_stub_dev_t *devstub, UCHAR descType, UCHAR idx, USHORT idLang, PVOID buff, ULONG *pbufflen); 11 | 12 | BOOLEAN select_usb_conf(usbip_stub_dev_t *devstub, USHORT idx); 13 | BOOLEAN select_usb_intf(usbip_stub_dev_t *devstub, UCHAR intf_num, USHORT alt_setting); 14 | 15 | BOOLEAN reset_pipe(usbip_stub_dev_t *devstub, USBD_PIPE_HANDLE hPipe); 16 | int set_feature(usbip_stub_dev_t *devstub, USHORT func, USHORT feature, USHORT index); 17 | 18 | int submit_class_vendor_req(usbip_stub_dev_t *devstub, BOOLEAN is_in, USHORT cmd, 19 | UCHAR rv, UCHAR request, USHORT value, USHORT index, PVOID data, PULONG plen); 20 | 21 | NTSTATUS 22 | submit_bulk_intr_transfer(usbip_stub_dev_t *devstub, USBD_PIPE_HANDLE hPipe, unsigned long seqnum, PVOID data, ULONG pdatalen, BOOLEAN is_in); 23 | 24 | NTSTATUS 25 | submit_iso_transfer(usbip_stub_dev_t *devstub, USBD_PIPE_HANDLE hPipe, unsigned long seqnum, ULONG usbd_flags, ULONG n_pkts, ULONG start_frame, 26 | struct usbip_iso_packet_descriptor *iso_descs, PVOID data, ULONG datalen); 27 | 28 | BOOLEAN 29 | submit_control_transfer(usbip_stub_dev_t *devstub, usb_cspkt_t *csp, PVOID data, PULONG pdata_len); 30 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/stub/usbip_stub.inx: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ; INF file for installing USB/IP stub driver 4 | ; 5 | ;--*/ 6 | [Version] 7 | Signature="$WINDOWS NT$" 8 | ; USB class cannot be installed via legacy hardware. It can be done via devcon 9 | ;Class=USB 10 | ;ClassGUID={36FC9E60-C465-11CF-8056-444553540000} 11 | Class=System 12 | ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318} 13 | Provider=%OpenSource% 14 | CatalogFile=usbip_stub.cat 15 | DriverVer = 07/19/2021,0.3.5.0 16 | 17 | [Manufacturer] 18 | %StdMfg%=Standard,NTamd64 19 | 20 | [Standard.NTamd64] 21 | %DeviceDesc%=usbip_stub_Device, %hwid% 22 | 23 | [DestinationDirs] 24 | DefaultDestDir = 12 25 | 26 | [SourceDisksNames] 27 | 1 = %DiskId1%,,,"" 28 | 29 | [SourceDisksFiles] 30 | usbip_stub.sys = 1,, 31 | 32 | [Drivers_Dir] 33 | usbip_stub.sys 34 | 35 | [usbip_stub_Device.NTamd64] 36 | CopyFiles=Drivers_Dir 37 | 38 | [usbip_stub_Device.NTamd64.HW] 39 | AddReg=usbip_stub_Device_AddReg 40 | 41 | [usbip_stub_Device_AddReg] 42 | HKR,,DeviceCharacteristics,0x10001,0x0100 ; Use same security checks on relative opens 43 | ;Using default permissions so comment out next lines 44 | ;HKR,,Security,,"D:P(A;;GA;;;SY)(A;;GRGWGX;;;BA)(A;;GRGWGX;;;WD)(A;;GRGWGX;;;RC)" ; Allow generic-all access to all users 45 | ;HKR,,Security,,"D:P(A;;GA;;;BA)(A;;GA;;;SY)" ; Allow generic-all access to Built-in administrators and Local system 46 | 47 | ;-------------- Service installation 48 | [usbip_stub_Device.NTamd64.Services] 49 | AddService = usbip_stub,%SPSVCINST_ASSOCSERVICE%, usbip_stub_Service_Inst 50 | 51 | ; -------------- stub driver install sections 52 | [usbip_stub_Service_Inst] 53 | DisplayName = %ServiceDesc% 54 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 55 | StartType = 3 ; SERVICE_DEMAND_START 56 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 57 | ServiceBinary = %12%\usbip_stub.sys 58 | LoadOrderGroup = Extended Base 59 | 60 | 61 | [Strings] 62 | SPSVCINST_ASSOCSERVICE= 0x00000002 63 | OpenSource = "Open Source" 64 | StdMfg = "USB/IP Project" 65 | DiskId1 = "USB/IP STUB Disk" 66 | DeviceDesc = "USB/IP STUB" 67 | ServiceDesc = "USB/IP STUB Service" 68 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/usbip_test.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/usbip-win/driver/usbip_test.pfx -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/basetype.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef ALLOC_PRAGMA 4 | 5 | #define PAGEABLE __declspec(code_seg("PAGE")) 6 | 7 | #else 8 | 9 | #define PAGEABLE 10 | 11 | #endif -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/gencat.bat: -------------------------------------------------------------------------------- 1 | cd %1 2 | if exist vhci_cat del /s /q vhci_cat 3 | mkdir vhci_cat 4 | cd vhci_cat 5 | copy ..\usbip_vhci.sys 6 | copy ..\usbip_vhci.inf 7 | copy ..\usbip_root.inf 8 | inf2cat /driver:.\ /os:%2 /uselocaltime 9 | signtool sign /f %3 /p usbip usbip_vhci.cat 10 | copy /y usbip_vhci.cat .. 11 | cd .. 12 | del /s /q vhci_cat 13 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct _GLOBALS 6 | { 7 | // Path to the driver's Services Key in the registry 8 | UNICODE_STRING RegistryPath; 9 | } GLOBALS; 10 | 11 | extern GLOBALS Globals; -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/trace.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Module Name: 4 | 5 | Trace.h 6 | 7 | Abstract: 8 | 9 | Header file for the debug tracing related function defintions and macros. 10 | 11 | Environment: 12 | 13 | Kernel mode 14 | 15 | --*/ 16 | 17 | // 18 | // Define the tracing flags. 19 | // 20 | // Tracing GUID - 8b56380d-5174-4b15-b6f4-4c47008801a4 21 | // 22 | 23 | #define WPP_CONTROL_GUIDS \ 24 | WPP_DEFINE_CONTROL_GUID( \ 25 | usbipTraceGuid, (8b56380d,5174,4b15,b6f4,4c47008801a4), \ 26 | \ 27 | WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ 28 | WPP_DEFINE_BIT(TRACE_DRIVER) \ 29 | WPP_DEFINE_BIT(TRACE_DEVICE) \ 30 | WPP_DEFINE_BIT(TRACE_QUEUE) \ 31 | ) 32 | 33 | #define WPP_FLAG_LEVEL_LOGGER(flag, level) \ 34 | WPP_LEVEL_LOGGER(flag) 35 | 36 | #define WPP_FLAG_LEVEL_ENABLED(flag, level) \ 37 | (WPP_LEVEL_ENABLED(flag) && \ 38 | WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) 39 | 40 | #define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \ 41 | WPP_LEVEL_LOGGER(flags) 42 | 43 | #define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \ 44 | (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) 45 | 46 | // 47 | // WPP orders static parameters before dynamic parameters. To support the Trace function 48 | // defined below which sets FLAGS=MYDRIVER_ALL_INFO, a custom macro must be defined to 49 | // reorder the arguments to what the .tpl configuration file expects. 50 | // 51 | #define WPP_RECORDER_FLAGS_LEVEL_ARGS(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_ARGS(lvl, flags) 52 | #define WPP_RECORDER_FLAGS_LEVEL_FILTER(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_FILTER(lvl, flags) 53 | 54 | // 55 | // This comment block is scanned by the trace preprocessor to define our 56 | // Trace function. 57 | // 58 | // begin_wpp config 59 | // FUNC Trace{FLAGS=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); 60 | // FUNC TraceEvents(LEVEL, FLAGS, MSG, ...); 61 | // end_wpp 62 | // 63 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/usbip_root.inf: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ; INF file for installing USB/IP vhci driver 4 | ; 5 | ;--*/ 6 | [Version] 7 | Signature="$WINDOWS NT$" 8 | Class=System 9 | ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318} 10 | 11 | Provider=%Provider% 12 | CatalogFile=usbip_vhci.cat 13 | 14 | PnpLockDown=1 15 | 16 | [Manufacturer] 17 | %StdMfg%=Standard,NT$ARCH$ 18 | 19 | [Standard.NT$ARCH$] 20 | %DeviceDesc%=usbip_vhci_Device, USBIPWIN\root 21 | 22 | [DestinationDirs] 23 | DefaultDestDir = 12 24 | 25 | [SourceDisksNames] 26 | 1 = %DiskId1%,,,"" 27 | 28 | [SourceDisksFiles] 29 | usbip_vhci.sys = 1,, 30 | 31 | [Drivers_Dir] 32 | usbip_vhci.sys 33 | 34 | [usbip_vhci_Device.NT$ARCH$] 35 | CopyFiles=Drivers_Dir 36 | 37 | [usbip_vhci_Device.NT$ARCH$.HW] 38 | AddReg=usbip_vhci_Device_AddReg 39 | 40 | [usbip_vhci_Device_AddReg] 41 | HKR,,DeviceCharacteristics,0x10001,0x0100 ; Use same security checks on relative opens 42 | 43 | ;-------------- Service installation 44 | [usbip_vhci_Device.NT$ARCH$.Services] 45 | AddService = usbip_vhci,%SPSVCINST_ASSOCSERVICE%, usbip_vhci_Service_Inst 46 | 47 | ; -------------- vhci driver install sections 48 | [usbip_vhci_Service_Inst] 49 | DisplayName = %ServiceDesc% 50 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 51 | StartType = 3 ; SERVICE_DEMAND_START 52 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 53 | ServiceBinary = %12%\usbip_vhci.sys 54 | LoadOrderGroup = Extended Base 55 | 56 | [Strings] 57 | SPSVCINST_ASSOCSERVICE= 0x00000002 58 | Provider = "usbip-win project" 59 | StdMfg = "usbip-win" 60 | DiskId1 = "usbip-win VHCI Disk" 61 | DeviceDesc = "usbip-win VHCI Root" 62 | vhub_DeviceDesc = "usbip-win VHUB" 63 | ServiceDesc = "usbip-win VHCI Service" 64 | DisplayClassName = "usbip-win" 65 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/usbip_vhci.inf: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ; INF file for installing USB/IP vhci driver 4 | ; 5 | ;--*/ 6 | [Version] 7 | Signature="$WINDOWS NT$" 8 | Class=USB 9 | ClassGuid={36FC9E60-C465-11CF-8056-444553540000} 10 | 11 | Provider=%Provider% 12 | CatalogFile=usbip_vhci.cat 13 | 14 | PnpLockDown=1 15 | 16 | [Manufacturer] 17 | %StdMfg%=Standard,NT$ARCH$ 18 | 19 | [Standard.NT$ARCH$] 20 | %DeviceDesc%=usbip_vhci_Device, USBIPWIN\vhci 21 | %vhub_DeviceDesc%=usbip_vhci_Device, USB\ROOT_HUB&VID_1209&PID_8250&REV_0000 22 | 23 | [DestinationDirs] 24 | DefaultDestDir = 12 25 | 26 | [SourceDisksNames] 27 | 1 = %DiskId1%,,,"" 28 | 29 | [SourceDisksFiles] 30 | usbip_vhci.sys = 1,, 31 | 32 | [Drivers_Dir] 33 | usbip_vhci.sys 34 | 35 | [usbip_vhci_Device.NT$ARCH$] 36 | CopyFiles=Drivers_Dir 37 | 38 | [usbip_vhci_Device.NT$ARCH$.HW] 39 | AddReg=usbip_vhci_Device_AddReg 40 | 41 | [usbip_vhci_Device_AddReg] 42 | HKR,,DeviceCharacteristics,0x10001,0x0100 ; Use same security checks on relative opens 43 | 44 | ;-------------- Service installation 45 | [usbip_vhci_Device.NT$ARCH$.Services] 46 | AddService = usbip_vhci,%SPSVCINST_ASSOCSERVICE%, usbip_vhci_Service_Inst 47 | 48 | ; -------------- vhci driver install sections 49 | [usbip_vhci_Service_Inst] 50 | DisplayName = %ServiceDesc% 51 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 52 | StartType = 3 ; SERVICE_DEMAND_START 53 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 54 | ServiceBinary = %12%\usbip_vhci.sys 55 | LoadOrderGroup = Extended Base 56 | 57 | [Strings] 58 | SPSVCINST_ASSOCSERVICE= 0x00000002 59 | Provider = "usbip-win project" 60 | StdMfg = "usbip-win" 61 | DiskId1 = "usbip-win VHCI Disk" 62 | DeviceDesc = "usbip-win VHCI" 63 | vhub_DeviceDesc = "usbip-win VHUB" 64 | ServiceDesc = "usbip-win VHCI Service" 65 | DisplayClassName = "usbip-win" 66 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/usbreq.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "usb_util.h" 7 | 8 | #include "vhci_dev.h" 9 | 10 | #define PIPE2DIRECT(handle) (((INT_PTR)(handle) & 0x80) ? USBIP_DIR_IN : USBIP_DIR_OUT) 11 | #define PIPE2ADDR(handle) ((unsigned char)((INT_PTR)(handle) & 0x7f)) 12 | #define PIPE2TYPE(handle) ((unsigned char)(((INT_PTR)(handle) & 0xff0000) >> 16)) 13 | #define PIPE2INTERVAL(handle) ((unsigned char)(((INT_PTR)(handle) & 0xff00) >> 8)) 14 | 15 | struct urb_req { 16 | pvpdo_dev_t vpdo; 17 | PIRP irp; 18 | KEVENT *event; 19 | unsigned long seq_num, seq_num_unlink; 20 | LIST_ENTRY list_all; 21 | LIST_ENTRY list_state; 22 | }; 23 | 24 | #define RemoveEntryListInit(le) do { RemoveEntryList(le); InitializeListHead(le); } while (0) 25 | 26 | extern void 27 | build_setup_packet(usb_cspkt_t *csp, unsigned char direct_in, unsigned char type, unsigned char recip, unsigned char request); 28 | 29 | extern NTSTATUS 30 | submit_urbr(pvpdo_dev_t vpdo, struct urb_req *urbr); 31 | 32 | extern struct urb_req * 33 | create_urbr(pvpdo_dev_t vpdo, PIRP irp, unsigned long seq_num_unlink); 34 | 35 | extern void 36 | free_urbr(struct urb_req *urbr); 37 | 38 | extern BOOLEAN 39 | is_port_urbr(struct urb_req *urbr, unsigned char epaddr); 40 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include // required for GUID definitions 6 | 7 | #include "basetype.h" 8 | #include "strutil.h" 9 | #include "vhci_dbg.h" 10 | #include "strutil.h" 11 | 12 | #define USBIP_VHCI_POOL_TAG (ULONG) 'VhcI' 13 | 14 | /* NOTE: a trailing string null character is included */ 15 | #define WTEXT_LEN(wtext) (sizeof(wtext) / sizeof(WCHAR)) 16 | 17 | extern NPAGED_LOOKASIDE_LIST g_lookaside; 18 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_dbg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DRVPREFIX "usbip_vhci" 4 | #include "dbgcommon.h" 5 | 6 | #ifdef DBG 7 | 8 | #include "vhci_dev.h" 9 | #include "usbreq.h" 10 | #include "dbgcode.h" 11 | 12 | /* NOTE: LSB cannot be used, which is system-wide mask. Thus, DBG_XXX start from 0x0002 */ 13 | #define DBG_GENERAL 0x0002 14 | #define DBG_READ 0x0004 15 | #define DBG_WRITE 0x0008 16 | #define DBG_PNP 0x0010 17 | #define DBG_IOCTL 0x0020 18 | #define DBG_POWER 0x0040 19 | #define DBG_WMI 0x0080 20 | #define DBG_URB 0x0100 21 | #define DBG_VDEV 0x0200 22 | #define DBG_ROOT 0x0400 23 | #define DBG_VHCI 0x0800 24 | #define DBG_CPDO 0x1000 25 | #define DBG_HPDO 0x2000 26 | #define DBG_VHUB 0x4000 27 | #define DBG_VPDO 0x8000 28 | 29 | extern const char *dbg_GUID(GUID *guid); 30 | 31 | extern const char *dbg_vdev_type(vdev_type_t type); 32 | extern const char *dbg_urbr(struct urb_req *urbr); 33 | 34 | extern const char *dbg_vhci_ioctl_code(unsigned int ioctl_code); 35 | extern const char *dbg_urbfunc(unsigned int urbfunc); 36 | 37 | extern const char *dbg_usb_user_request_code(ULONG code); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_dev.c: -------------------------------------------------------------------------------- 1 | #include "vhci.h" 2 | 3 | #include 4 | 5 | #include "vhci_dev.h" 6 | 7 | DEFINE_GUID(GUID_SD_USBIP_VHCI, 8 | 0x9d3039dd, 0xcca5, 0x4b4d, 0xb3, 0x3d, 0xe2, 0xdd, 0xc8, 0xa8, 0xc5, 0x2f); 9 | 10 | LPCWSTR devcodes[] = { 11 | L"ROOT", L"CPDO", L"VHCI", L"HPDO", L"VHUB", L"VPDO" 12 | }; 13 | 14 | static ULONG ext_sizes_per_devtype[] = { 15 | sizeof(root_dev_t), 16 | sizeof(cpdo_dev_t), 17 | sizeof(vhci_dev_t), 18 | sizeof(hpdo_dev_t), 19 | sizeof(vhub_dev_t), 20 | sizeof(vpdo_dev_t) 21 | }; 22 | 23 | LPWSTR 24 | get_device_prop(PDEVICE_OBJECT pdo, DEVICE_REGISTRY_PROPERTY prop, PULONG plen) 25 | { 26 | LPWSTR value; 27 | ULONG buflen; 28 | NTSTATUS status; 29 | 30 | status = IoGetDeviceProperty(pdo, prop, 0, NULL, &buflen); 31 | if (status != STATUS_BUFFER_TOO_SMALL) { 32 | DBGE(DBG_GENERAL, "failed to get device property size: %s\n", dbg_ntstatus(status)); 33 | return NULL; 34 | } 35 | value = ExAllocatePoolWithTag(PagedPool, buflen, USBIP_VHCI_POOL_TAG); 36 | if (value == NULL) { 37 | DBGE(DBG_GENERAL, "failed to get device property: out of memory\n"); 38 | return NULL; 39 | } 40 | status = IoGetDeviceProperty(pdo, prop, buflen, value, &buflen); 41 | if (NT_ERROR(status)) { 42 | DBGE(DBG_GENERAL, "failed to get device property: %s\n", dbg_ntstatus(status)); 43 | ExFreePoolWithTag(value, USBIP_VHCI_POOL_TAG); 44 | return NULL; 45 | } 46 | if (plen != NULL) 47 | *plen = buflen; 48 | return value; 49 | } 50 | 51 | PAGEABLE PDEVICE_OBJECT 52 | vdev_create(PDRIVER_OBJECT drvobj, vdev_type_t type) 53 | { 54 | pvdev_t vdev; 55 | PDEVICE_OBJECT devobj; 56 | ULONG extsize = ext_sizes_per_devtype[type]; 57 | NTSTATUS status; 58 | 59 | switch (type) { 60 | case VDEV_CPDO: 61 | case VDEV_HPDO: 62 | case VDEV_VPDO: 63 | status = IoCreateDeviceSecure(drvobj, extsize, NULL, 64 | FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, 65 | FALSE, &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX, // allow normal users to access the devices 66 | (LPCGUID)&GUID_SD_USBIP_VHCI, &devobj); 67 | break; 68 | default: 69 | status = IoCreateDevice(drvobj, extsize, NULL, 70 | FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &devobj); 71 | break; 72 | } 73 | if (!NT_SUCCESS(status)) { 74 | DBGE(DBG_GENERAL, "failed to create vdev(%s): status:%s\n", dbg_vdev_type(type), dbg_ntstatus(status)); 75 | return NULL; 76 | } 77 | 78 | vdev = DEVOBJ_TO_VDEV(devobj); 79 | RtlZeroMemory(vdev, extsize); 80 | 81 | vdev->DevicePnPState = NotStarted; 82 | vdev->PreviousPnPState = NotStarted; 83 | 84 | vdev->type = type; 85 | vdev->Self = devobj; 86 | 87 | vdev->DevicePowerState = PowerDeviceUnspecified; 88 | vdev->SystemPowerState = PowerSystemWorking; 89 | 90 | devobj->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO; 91 | 92 | return devobj; 93 | } 94 | 95 | void 96 | vdev_add_ref(pvdev_t vdev) 97 | { 98 | InterlockedIncrement(&vdev->n_refs); 99 | } 100 | 101 | VOID 102 | vdev_del_ref(pvdev_t vdev) 103 | { 104 | InterlockedDecrement(&vdev->n_refs); 105 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_devconf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "devconf.h" 4 | 5 | #include 6 | 7 | extern NTSTATUS 8 | setup_config(PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, PUSBD_INTERFACE_INFORMATION info_intf, PVOID end_info_intf, UCHAR speed); 9 | 10 | extern NTSTATUS 11 | setup_intf(USBD_INTERFACE_INFORMATION *intf_info, PUSB_CONFIGURATION_DESCRIPTOR dsc_conf, UCHAR speed); 12 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_ioctl.c: -------------------------------------------------------------------------------- 1 | #include "vhci.h" 2 | 3 | #include "vhci_dev.h" 4 | 5 | extern NTSTATUS 6 | vhci_ioctl_vhci(pvhci_dev_t vhci, PIO_STACK_LOCATION irpstack, ULONG ioctl_code, PVOID buffer, ULONG inlen, ULONG *poutlen); 7 | extern NTSTATUS 8 | vhci_ioctl_vhub(pvhub_dev_t vhub, PIRP irp, ULONG ioctl_code, PVOID buffer, ULONG inlen, ULONG *poutlen); 9 | 10 | PAGEABLE NTSTATUS 11 | vhci_ioctl(__in PDEVICE_OBJECT devobj, __in PIRP irp) 12 | { 13 | pvdev_t vdev = DEVOBJ_TO_VDEV(devobj); 14 | PIO_STACK_LOCATION irpstack; 15 | ULONG ioctl_code; 16 | PVOID buffer; 17 | ULONG inlen, outlen; 18 | NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; 19 | 20 | PAGED_CODE(); 21 | 22 | irpstack = IoGetCurrentIrpStackLocation(irp); 23 | ioctl_code = irpstack->Parameters.DeviceIoControl.IoControlCode; 24 | 25 | DBGI(DBG_GENERAL | DBG_IOCTL, "vhci_ioctl(%s): Enter: code:%s, irp:%p\n", 26 | dbg_vdev_type(DEVOBJ_VDEV_TYPE(devobj)), dbg_vhci_ioctl_code(ioctl_code), irp); 27 | 28 | // Check to see whether the bus is removed 29 | if (vdev->DevicePnPState == Deleted) { 30 | status = STATUS_NO_SUCH_DEVICE; 31 | goto END; 32 | } 33 | 34 | buffer = irp->AssociatedIrp.SystemBuffer; 35 | inlen = irpstack->Parameters.DeviceIoControl.InputBufferLength; 36 | outlen = irpstack->Parameters.DeviceIoControl.OutputBufferLength; 37 | 38 | switch (DEVOBJ_VDEV_TYPE(devobj)) { 39 | case VDEV_VHCI: 40 | status = vhci_ioctl_vhci(DEVOBJ_TO_VHCI(devobj), irpstack, ioctl_code, buffer, inlen, &outlen); 41 | break; 42 | case VDEV_VHUB: 43 | status = vhci_ioctl_vhub(DEVOBJ_TO_VHUB(devobj), irp, ioctl_code, buffer, inlen, &outlen); 44 | break; 45 | default: 46 | DBGW(DBG_IOCTL, "ioctl for %s is not allowed\n", dbg_vdev_type(DEVOBJ_VDEV_TYPE(devobj))); 47 | outlen = 0; 48 | break; 49 | } 50 | 51 | irp->IoStatus.Information = outlen; 52 | END: 53 | if (status != STATUS_PENDING) { 54 | irp->IoStatus.Status = status; 55 | IoCompleteRequest(irp, IO_NO_INCREMENT); 56 | } 57 | 58 | DBGI(DBG_GENERAL | DBG_IOCTL, "vhci_ioctl: Leave: irp:%p, status:%s\n", irp, dbg_ntstatus(status)); 59 | 60 | return status; 61 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_ioctl_usrreq.c: -------------------------------------------------------------------------------- 1 | #include "vhci.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "vhci_dev.h" 7 | 8 | static PAGEABLE NTSTATUS 9 | get_power_info(PVOID buffer, ULONG inlen, PULONG poutlen) 10 | { 11 | PUSB_POWER_INFO pinfo = (PUSB_POWER_INFO)buffer; 12 | 13 | if (inlen < sizeof(USB_POWER_INFO)) 14 | return STATUS_BUFFER_TOO_SMALL; 15 | 16 | pinfo->HcDeviceWake = WdmUsbPowerDeviceUnspecified; 17 | pinfo->HcSystemWake = WdmUsbPowerNotMapped; 18 | pinfo->RhDeviceWake = WdmUsbPowerDeviceD2; 19 | pinfo->RhSystemWake = WdmUsbPowerSystemWorking; 20 | pinfo->LastSystemSleepState = WdmUsbPowerNotMapped; 21 | 22 | switch (pinfo->SystemState) { 23 | case WdmUsbPowerSystemWorking: 24 | pinfo->HcDevicePowerState = WdmUsbPowerDeviceD0; 25 | pinfo->RhDevicePowerState = WdmUsbPowerNotMapped; 26 | break; 27 | case WdmUsbPowerSystemSleeping1: 28 | case WdmUsbPowerSystemSleeping2: 29 | case WdmUsbPowerSystemSleeping3: 30 | pinfo->HcDevicePowerState = WdmUsbPowerDeviceUnspecified; 31 | pinfo->RhDevicePowerState = WdmUsbPowerDeviceD3; 32 | break; 33 | case WdmUsbPowerSystemHibernate: 34 | pinfo->HcDevicePowerState = WdmUsbPowerDeviceD3; 35 | pinfo->RhDevicePowerState = WdmUsbPowerDeviceD3; 36 | break; 37 | case WdmUsbPowerSystemShutdown: 38 | pinfo->HcDevicePowerState = WdmUsbPowerNotMapped; 39 | pinfo->RhDevicePowerState = WdmUsbPowerNotMapped; 40 | break; 41 | } 42 | pinfo->CanWakeup = FALSE; 43 | pinfo->IsPowered = FALSE; 44 | 45 | *poutlen = sizeof(USB_POWER_INFO); 46 | 47 | return STATUS_SUCCESS; 48 | } 49 | 50 | static PAGEABLE NTSTATUS 51 | get_controller_info(PVOID buffer, ULONG inlen, PULONG poutlen) 52 | { 53 | PUSB_CONTROLLER_INFO_0 pinfo = (PUSB_CONTROLLER_INFO_0)buffer; 54 | 55 | if (inlen < sizeof(USB_CONTROLLER_INFO_0)) 56 | return STATUS_BUFFER_TOO_SMALL; 57 | pinfo->PciVendorId = 0; 58 | pinfo->PciDeviceId = 0; 59 | pinfo->PciRevision = 0; 60 | pinfo->NumberOfRootPorts = 1; 61 | pinfo->ControllerFlavor = EHCI_Generic; 62 | pinfo->HcFeatureFlags = 0; 63 | 64 | *poutlen = sizeof(USB_CONTROLLER_INFO_0); 65 | 66 | return STATUS_SUCCESS; 67 | } 68 | 69 | PAGEABLE NTSTATUS 70 | vhci_ioctl_user_request(pvhci_dev_t vhci, PVOID buffer, ULONG inlen, PULONG poutlen) 71 | { 72 | USBUSER_REQUEST_HEADER *hdr = (USBUSER_REQUEST_HEADER *)buffer; 73 | NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; 74 | 75 | UNREFERENCED_PARAMETER(vhci); 76 | 77 | if (inlen < sizeof(USBUSER_REQUEST_HEADER)) { 78 | return STATUS_BUFFER_TOO_SMALL; 79 | } 80 | 81 | DBGI(DBG_IOCTL, "usb user request: code: %s\n", dbg_usb_user_request_code(hdr->UsbUserRequest)); 82 | 83 | buffer = (PVOID)(hdr + 1); 84 | inlen -= sizeof(USBUSER_REQUEST_HEADER); 85 | (*poutlen) -= sizeof(USBUSER_REQUEST_HEADER); 86 | 87 | switch (hdr->UsbUserRequest) { 88 | case USBUSER_GET_POWER_STATE_MAP: 89 | status = get_power_info(buffer, inlen, poutlen); 90 | break; 91 | case USBUSER_GET_CONTROLLER_INFO_0: 92 | status = get_controller_info(hdr + 1, inlen, poutlen); 93 | break; 94 | default: 95 | DBGI(DBG_IOCTL, "usb user request: unhandled code: %s\n", dbg_usb_user_request_code(hdr->UsbUserRequest)); 96 | hdr->UsbUserStatusCode = UsbUserNotSupported; 97 | break; 98 | } 99 | 100 | if (NT_SUCCESS(status)) { 101 | (*poutlen) += sizeof(USBUSER_REQUEST_HEADER); 102 | hdr->UsbUserStatusCode = UsbUserSuccess; 103 | hdr->ActualBufferLength = *poutlen; 104 | } 105 | else { 106 | hdr->UsbUserStatusCode = UsbUserMiniportError;///TODO 107 | 108 | } 109 | return status; 110 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_irp.c: -------------------------------------------------------------------------------- 1 | #include "vhci.h" 2 | 3 | PAGEABLE NTSTATUS 4 | irp_pass_down(PDEVICE_OBJECT devobj, PIRP irp) 5 | { 6 | irp->IoStatus.Status = STATUS_SUCCESS; 7 | IoSkipCurrentIrpStackLocation(irp); 8 | return IoCallDriver(devobj, irp); 9 | } 10 | 11 | static NTSTATUS 12 | irp_completion_routine(__in PDEVICE_OBJECT devobj, __in PIRP irp, __in PVOID Context) 13 | { 14 | UNREFERENCED_PARAMETER(devobj); 15 | 16 | // If the lower driver didn't return STATUS_PENDING, we don't need to 17 | // set the event because we won't be waiting on it. 18 | // This optimization avoids grabbing the dispatcher lock and improves perf. 19 | if (irp->PendingReturned == TRUE) { 20 | KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); 21 | } 22 | return STATUS_MORE_PROCESSING_REQUIRED; // Keep this IRP 23 | } 24 | 25 | PAGEABLE NTSTATUS 26 | irp_send_synchronously(PDEVICE_OBJECT devobj, PIRP irp) 27 | { 28 | KEVENT event; 29 | NTSTATUS status; 30 | 31 | PAGED_CODE(); 32 | 33 | KeInitializeEvent(&event, NotificationEvent, FALSE); 34 | 35 | IoCopyCurrentIrpStackLocationToNext(irp); 36 | 37 | IoSetCompletionRoutine(irp, irp_completion_routine, &event, TRUE, TRUE, TRUE); 38 | 39 | status = IoCallDriver(devobj, irp); 40 | 41 | // Wait for lower drivers to be done with the Irp. 42 | // Important thing to note here is when you allocate 43 | // the memory for an event in the stack you must do a 44 | // KernelMode wait instead of UserMode to prevent 45 | // the stack from getting paged out. 46 | if (status == STATUS_PENDING) { 47 | KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 48 | status = irp->IoStatus.Status; 49 | } 50 | 51 | return status; 52 | } 53 | 54 | NTSTATUS 55 | irp_done(PIRP irp, NTSTATUS status) 56 | { 57 | irp->IoStatus.Status = status; 58 | IoCompleteRequest(irp, IO_NO_INCREMENT); 59 | return status; 60 | } 61 | 62 | NTSTATUS 63 | irp_success(PIRP irp) 64 | { 65 | return irp_done(irp, STATUS_SUCCESS); 66 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_irp.h: -------------------------------------------------------------------------------- 1 | #include "vhci.h" 2 | 3 | extern NTSTATUS irp_pass_down(PDEVICE_OBJECT devobj, PIRP irp); 4 | extern NTSTATUS irp_send_synchronously(PDEVICE_OBJECT devobj, PIRP irp); 5 | extern NTSTATUS irp_success(PIRP irp); 6 | extern NTSTATUS irp_done(PIRP irp, NTSTATUS status); -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_pnp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "basetype.h" 4 | #include "vhci_dev.h" 5 | 6 | #define HWID_ROOT L"USBIPWIN\\root" 7 | #define HWID_VHCI L"USBIPWIN\\vhci" 8 | 9 | #define VHUB_PREFIX L"USB\\ROOT_HUB" 10 | #define VHUB_VID L"1209" 11 | #define VHUB_PID L"8250" 12 | #define VHUB_REV L"0000" 13 | 14 | #define HWID_VHUB \ 15 | VHUB_PREFIX \ 16 | L"&VID_" VHUB_VID \ 17 | L"&PID_" VHUB_PID \ 18 | L"&REV_" VHUB_REV 19 | 20 | #define INITIALIZE_PNP_STATE(_Data_) \ 21 | (_Data_)->common.DevicePnPState = NotStarted;\ 22 | (_Data_)->common.PreviousPnPState = NotStarted; 23 | 24 | #define SET_NEW_PNP_STATE(vdev, _state_) \ 25 | do { (vdev)->PreviousPnPState = (vdev)->DevicePnPState;\ 26 | (vdev)->DevicePnPState = (_state_); } while (0) 27 | 28 | #define RESTORE_PREVIOUS_PNP_STATE(vdev) \ 29 | do { (vdev)->DevicePnPState = (vdev)->PreviousPnPState; } while (0) 30 | 31 | extern PAGEABLE NTSTATUS vhci_unplug_port(pvhci_dev_t vhci, CHAR port); 32 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_pnp_devtext.c: -------------------------------------------------------------------------------- 1 | #include "vhci.h" 2 | 3 | #include "vhci_dev.h" 4 | #include "vhci_irp.h" 5 | 6 | static LPCWSTR vdev_descs[] = { 7 | L"usbip-win ROOT", L"usbip-win CPDO", L"usbip-win VHCI", L"usbip-win HPDO", L"usbip-win VHUB", L"usbip-win VPDO" 8 | }; 9 | 10 | static LPCWSTR vdev_locinfos[] = { 11 | L"None", L"Root", L"Root", L"VHCI", L"VHCI", L"HPDO" 12 | }; 13 | 14 | PAGEABLE NTSTATUS 15 | pnp_query_device_text(pvdev_t vdev, PIRP irp, PIO_STACK_LOCATION irpstack) 16 | { 17 | NTSTATUS status; 18 | 19 | PAGED_CODE(); 20 | 21 | status = irp->IoStatus.Status; 22 | 23 | switch (irpstack->Parameters.QueryDeviceText.DeviceTextType) { 24 | case DeviceTextDescription: 25 | if (!irp->IoStatus.Information) { 26 | irp->IoStatus.Information = (ULONG_PTR)libdrv_strdupW(vdev_descs[vdev->type]); 27 | status = STATUS_SUCCESS; 28 | } 29 | break; 30 | case DeviceTextLocationInformation: 31 | if (!irp->IoStatus.Information) { 32 | irp->IoStatus.Information = (ULONG_PTR)libdrv_strdupW(vdev_locinfos[vdev->type]); 33 | status = STATUS_SUCCESS; 34 | } 35 | break; 36 | default: 37 | DBGI(DBG_PNP, "unsupported device text type: %u\n", irpstack->Parameters.QueryDeviceText.DeviceTextType); 38 | break; 39 | } 40 | 41 | return irp_done(irp, status); 42 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_pnp_resources.c: -------------------------------------------------------------------------------- 1 | #include "vhci.h" 2 | 3 | #include "vhci_dev.h" 4 | #include "vhci_irp.h" 5 | 6 | static PAGEABLE PIO_RESOURCE_REQUIREMENTS_LIST 7 | get_query_empty_resource_requirements(void) 8 | { 9 | PIO_RESOURCE_REQUIREMENTS_LIST reqs; 10 | 11 | reqs = ExAllocatePoolWithTag(PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST), USBIP_VHCI_POOL_TAG); 12 | if (reqs == NULL) { 13 | return NULL; 14 | } 15 | reqs->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST); 16 | reqs->BusNumber = 10; 17 | reqs->SlotNumber = 1; 18 | reqs->AlternativeLists = 0; 19 | reqs->List[0].Version = 1; 20 | reqs->List[0].Revision = 1; 21 | reqs->List[0].Count = 0; 22 | return reqs; 23 | } 24 | 25 | static PAGEABLE PCM_RESOURCE_LIST 26 | get_query_empty_resources(void) 27 | { 28 | PCM_RESOURCE_LIST rscs; 29 | 30 | rscs = ExAllocatePoolWithTag(PagedPool, sizeof(CM_RESOURCE_LIST), USBIP_VHCI_POOL_TAG); 31 | if (rscs == NULL) { 32 | return NULL; 33 | } 34 | rscs->Count = 0; 35 | return rscs; 36 | } 37 | 38 | PAGEABLE NTSTATUS 39 | pnp_query_resource_requirements(pvdev_t vdev, PIRP irp) 40 | { 41 | if (!IS_FDO(vdev->type)) { 42 | irp->IoStatus.Information = (ULONG_PTR)get_query_empty_resource_requirements(); 43 | return irp_done(irp, STATUS_SUCCESS); 44 | } 45 | else { 46 | return irp_pass_down(vdev->devobj_lower, irp); 47 | } 48 | } 49 | 50 | PAGEABLE NTSTATUS 51 | pnp_query_resources(pvdev_t vdev, PIRP irp) 52 | { 53 | if (!IS_FDO(vdev->type)) { 54 | irp->IoStatus.Information = (ULONG_PTR)get_query_empty_resources(); 55 | return irp_done(irp, STATUS_SUCCESS); 56 | } 57 | else { 58 | return irp_pass_down(vdev->devobj_lower, irp); 59 | } 60 | } 61 | 62 | PAGEABLE NTSTATUS 63 | pnp_filter_resource_requirements(pvdev_t vdev, PIRP irp) 64 | { 65 | if (IS_FDO(vdev->type)) { 66 | irp->IoStatus.Information = (ULONG_PTR)get_query_empty_resource_requirements(); 67 | return irp_done(irp, STATUS_SUCCESS); 68 | } 69 | else { 70 | return irp_done(irp, STATUS_NOT_SUPPORTED); 71 | } 72 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_pnp_vpdo.c: -------------------------------------------------------------------------------- 1 | #include "vhci.h" 2 | 3 | #include "vhci_dev.h" 4 | #include "vhci_irp.h" 5 | 6 | extern PAGEABLE void vhub_mark_unplugged_vpdo(pvhub_dev_t vhub, pvpdo_dev_t vpdo); 7 | 8 | // IRP_MN_DEVICE_ENUMERATED is included by default since Windows 7. 9 | #if WINVER<0x0701 10 | #define IRP_MN_DEVICE_ENUMERATED 0x19 11 | #endif 12 | 13 | PAGEABLE BOOLEAN 14 | process_pnp_vpdo(pvpdo_dev_t vpdo, PIRP irp, PIO_STACK_LOCATION irpstack) 15 | { 16 | NTSTATUS status; 17 | 18 | PAGED_CODE(); 19 | 20 | // NB: Because we are a bus enumerator, we have no one to whom we could 21 | // defer these irps. Therefore we do not pass them down but merely 22 | // return them. 23 | switch (irpstack->MinorFunction) { 24 | case IRP_MN_DEVICE_USAGE_NOTIFICATION: 25 | // OPTIONAL for bus drivers. 26 | // This bus drivers any of the bus's descendants 27 | // (child device, child of a child device, etc.) do not 28 | // contain a memory file namely paging file, dump file, 29 | // or hibernation file. So we fail this Irp. 30 | status = STATUS_UNSUCCESSFUL; 31 | break; 32 | case IRP_MN_EJECT: 33 | // For the device to be ejected, the device must be in the D3 34 | // device power state (off) and must be unlocked 35 | // (if the device supports locking). Any driver that returns success 36 | // for this IRP must wait until the device has been ejected before 37 | // completing the IRP. 38 | 39 | vhub_mark_unplugged_vpdo(VHUB_FROM_VPDO(vpdo), vpdo); 40 | 41 | status = STATUS_SUCCESS; 42 | break; 43 | case IRP_MN_DEVICE_ENUMERATED: 44 | // 45 | // This request notifies bus drivers that a device object exists and 46 | // that it has been fully enumerated by the plug and play manager. 47 | // 48 | status = STATUS_SUCCESS; 49 | break; 50 | case IRP_MN_QUERY_PNP_DEVICE_STATE: 51 | irp->IoStatus.Information = 0; 52 | status = irp->IoStatus.Status = STATUS_SUCCESS; 53 | break; 54 | case IRP_MN_QUERY_LEGACY_BUS_INFORMATION: 55 | case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: 56 | /* not handled */ 57 | status = irp->IoStatus.Status; 58 | break; 59 | default: 60 | return FALSE; 61 | } 62 | 63 | irp_done(irp, status); 64 | 65 | return TRUE; 66 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci/vhci_proto.c: -------------------------------------------------------------------------------- 1 | #include "vhci.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "usbreq.h" 5 | 6 | #define USBDEVFS_URB_SHORT_NOT_OK 0x01 7 | #define USBDEVFS_URB_ISO_ASAP 0x02 8 | #define USBDEVFS_URB_NO_FSBR 0x20 9 | #define USBDEVFS_URB_ZERO_PACKET 0x40 10 | #define USBDEVFS_URB_NO_INTERRUPT 0x80 11 | 12 | unsigned int 13 | transflag(unsigned int flags) 14 | { 15 | unsigned int linux_flags = 0; 16 | if (!(flags&USBD_SHORT_TRANSFER_OK)) 17 | linux_flags |= USBDEVFS_URB_SHORT_NOT_OK; 18 | if (flags&USBD_START_ISO_TRANSFER_ASAP) 19 | linux_flags |= USBDEVFS_URB_ISO_ASAP; 20 | return linux_flags; 21 | } 22 | 23 | void 24 | set_cmd_submit_usbip_header(struct usbip_header *h, unsigned long seqnum, unsigned int devid, 25 | unsigned int direct, USBD_PIPE_HANDLE pipe, unsigned int flags, unsigned int len) 26 | { 27 | h->base.command = USBIP_CMD_SUBMIT; 28 | h->base.seqnum = seqnum; 29 | h->base.devid = devid; 30 | h->base.direction = direct ? USBIP_DIR_IN : USBIP_DIR_OUT; 31 | h->base.ep = PIPE2ADDR(pipe); 32 | h->u.cmd_submit.transfer_flags = transflag(flags); 33 | h->u.cmd_submit.transfer_buffer_length = len; 34 | h->u.cmd_submit.start_frame = 0; 35 | h->u.cmd_submit.number_of_packets = 0; 36 | h->u.cmd_submit.interval = PIPE2INTERVAL(pipe); 37 | } 38 | 39 | void 40 | set_cmd_unlink_usbip_header(struct usbip_header *h, unsigned long seqnum, unsigned int devid, unsigned long seqnum_unlink) 41 | { 42 | h->base.command = USBIP_CMD_UNLINK; 43 | h->base.seqnum = seqnum; 44 | h->base.devid = devid; 45 | h->base.direction = USBIP_DIR_OUT; 46 | h->base.ep = 0; 47 | h->u.cmd_unlink.seqnum = seqnum_unlink; 48 | } 49 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/custom_wpp.ini: -------------------------------------------------------------------------------- 1 | DEFINE_CPLX_TYPE(SETUPPKT, DBG_SETUPPKT, PCUCHAR, ItemString, "s", _SETUPPKT_, 0, 1); 2 | WPP_FLAGS(-DDBG_SETUPPKT(x) WPP_LOGPAIR((dbg_usb_setup_packet(x), len_dbg_setup_packet), buf_dbg_setup_packet)); 3 | DEFINE_CPLX_TYPE(URBR, WPP_URBR, purb_req_t, ItemString, "s", _URBR_, 0); 4 | WPP_FLAGS(-DWPP_URBR(x) WPP_LOGPAIR((dbg_urbr(x), len_dbg_urbr), buf_dbg_urbr)); 5 | DEFINE_CPLX_TYPE(URBFUNC, WPP_URBFUNC, USHORT, ItemString, "s", _URBFUNC_, 0, 1); 6 | WPP_FLAGS(-DWPP_URBFUNC(x) WPP_LOGPAIR((dbg_urbfunc(x), len_dbg_urbfunc), buf_dbg_urbfunc)); 7 | DEFINE_CPLX_TYPE(IOCTL, WPP_IOCTL, unsigned int, ItemString, "s", _IOCTL_, 0, 1); 8 | WPP_FLAGS(-DWPP_IOCTL(x) WPP_LOGPAIR((dbg_vhci_ioctl_code(x), len_dbg_vhci_ioctl_code), buf_dbg_vhci_ioctl_code)); 9 | USEPREFIX (TRD, " %!FUNC!:"); 10 | USEPREFIX (TRW, "(WW)%!FUNC!:"); 11 | USEPREFIX (TRE, "(EE)%!FUNC!:"); 12 | FUNC TRD{LEVEL=TRACE_LEVEL_INFORMATION}(FLAGS, MSG, ...); 13 | FUNC TRW{LEVEL=TRACE_LEVEL_WARNING}(FLAGS, MSG, ...); 14 | FUNC TRE{LEVEL=TRACE_LEVEL_ERROR}(FLAGS, MSG, ...); 15 | CUSTOM_TYPE(epconf, ItemEnum(_UDECX_ENDPOINTS_CONFIGURE_TYPE)); -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/gencat.bat: -------------------------------------------------------------------------------- 1 | cd %1 2 | if exist vhci_ude_cat del /s /q vhci_ude_cat 3 | mkdir vhci_ude_cat 4 | cd vhci_ude_cat 5 | copy ..\usbip_vhci_ude.sys 6 | copy ..\usbip_vhci_ude.inf 7 | inf2cat /driver:.\ /os:%2 /uselocaltime 8 | signtool sign /f %3 /p usbip usbip_vhci_ude.cat 9 | copy /y usbip_vhci_ude.cat .. 10 | cd .. 11 | del /s /q vhci_ude_cat 12 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/usbip_vhci_ude.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; usbip_vhci_ude.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=USB 8 | ClassGuid={36FC9E60-C465-11CF-8056-444553540000} 9 | Provider=%ManufacturerName% 10 | CatalogFile=usbip_vhci_ude.cat 11 | DriverVer= 12 | PnpLockDown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | vhci_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | usbip_vhci_ude.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %vhci.DeviceDesc%=vhci_Device, ROOT\VHCI_ude 34 | 35 | [vhci_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | usbip_vhci_ude.sys 40 | 41 | [vhci_Device.NT.HW] 42 | AddReg=vhci_AddReg 43 | 44 | [vhci_AddReg] 45 | ; By default, USBDevice class uses iProduct descriptor to name the device in 46 | ; Device Manager on Windows 8 and higher. 47 | ; Uncomment for this device to use %DeviceName% on Windows 8 and higher: 48 | ;HKR,,FriendlyName,,%vhci.DeviceDesc% 49 | 50 | ;-------------- Service installation 51 | [vhci_Device.NT.Services] 52 | AddService = usbip_vhci_ude,%SPSVCINST_ASSOCSERVICE%, vhci_Service_Inst 53 | 54 | ; -------------- vhci driver install sections 55 | [vhci_Service_Inst] 56 | DisplayName = %vhci.SVCDESC% 57 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 58 | StartType = 3 ; SERVICE_DEMAND_START 59 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 60 | ServiceBinary = %12%\usbip_vhci_ude.sys 61 | 62 | ; 63 | ;--- vhci_Device Coinstaller installation ------ 64 | ; 65 | 66 | [vhci_Device.NT.CoInstallers] 67 | AddReg=vhci_Device_CoInstaller_AddReg 68 | CopyFiles=vhci_Device_CoInstaller_CopyFiles 69 | 70 | [vhci_Device_CoInstaller_AddReg] 71 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 72 | 73 | [vhci_Device_CoInstaller_CopyFiles] 74 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 75 | 76 | [vhci_Device.NT.Wdf] 77 | KmdfService = usbip_vhci_ude, usbip_vhci_wdfsect 78 | [usbip_vhci_wdfsect] 79 | KmdfLibraryVersion = $KMDFVERSION$ 80 | 81 | [Strings] 82 | SPSVCINST_ASSOCSERVICE= 0x00000002 83 | ManufacturerName="usbip-win project" 84 | DiskName = "usbip-win VHCI(ude) Disk" 85 | vhci.DeviceDesc = "usbip-win VHCI(ude)" 86 | vhci.SVCDESC = "usbip-win vhci(ude) Service" 87 | REG_MULTI_SZ = 0x00010000 88 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_dbg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dbgcommon.h" 4 | 5 | #include "vhci_dev.h" 6 | #include "vhci_urbr.h" 7 | #include "dbgcode.h" 8 | 9 | extern char buf_dbg_vhci_ioctl_code[]; 10 | extern char buf_dbg_urbfunc[]; 11 | extern char buf_dbg_setup_packet[]; 12 | extern char buf_dbg_urbr[]; 13 | 14 | extern int len_dbg_vhci_ioctl_code; 15 | extern int len_dbg_urbfunc; 16 | extern int len_dbg_setup_packet; 17 | extern int len_dbg_urbr; 18 | 19 | extern const char *dbg_vhci_ioctl_code(unsigned int ioctl_code); 20 | extern const char *dbg_urbfunc(USHORT urbfunc); 21 | extern const char *dbg_usb_setup_packet(PCUCHAR packet); 22 | extern const char *dbg_urbr(purb_req_t urbr); 23 | 24 | #ifndef DBG 25 | const char *dbg_usbd_status(USBD_STATUS status); 26 | #endif 27 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_dev.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | EXTERN_C_START 7 | 8 | #define MAX_HUB_20PORTS 12 9 | #define MAX_HUB_30PORTS 4 10 | 11 | struct _ctx_vusb; 12 | 13 | typedef struct 14 | { 15 | WDFDEVICE hdev; 16 | ULONG n_max_ports, n_used_ports; 17 | WDFQUEUE queue; 18 | struct _ctx_vusb **vusbs; 19 | WDFSPINLOCK spin_lock; 20 | } ctx_vhci_t, *pctx_vhci_t; 21 | 22 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(ctx_vhci_t, TO_VHCI) 23 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(pctx_vhci_t, TO_PVHCI) 24 | 25 | struct _urb_req; 26 | struct _ctx_ep; 27 | 28 | typedef struct _ctx_vusb 29 | { 30 | ULONG port; 31 | pctx_vhci_t vhci; 32 | UDECXUSBDEVICE ude_usbdev; 33 | /* 34 | * There's 2 endpoint allocation types for UDE device: Simple & Dynamic 35 | * vusb will try to create an EP in a simple way if possible. 36 | * This approach is based on the belief that a simple type is literally simple. 37 | */ 38 | BOOLEAN is_simple_ep_alloc; 39 | BOOLEAN invalid; 40 | /* reference count to prevent from removal while being used */ 41 | ULONG refcnt; 42 | 43 | // pending req which doesn't find an available urbr 44 | WDFREQUEST pending_req_read; 45 | // a partially transferred urbr 46 | struct _urb_req *urbr_sent_partial; 47 | // a partially transferred length of urbr_sent_partial 48 | ULONG len_sent_partial; 49 | // all urbr's. This list will be used for clear or cancellation. 50 | LIST_ENTRY head_urbr; 51 | // pending urbr's which are not transferred yet 52 | LIST_ENTRY head_urbr_pending; 53 | // urbr's which had been sent and have waited for response 54 | LIST_ENTRY head_urbr_sent; 55 | ULONG devid; 56 | ULONG seq_num; 57 | struct _ctx_ep *ep_default; 58 | WDFLOOKASIDE lookaside_urbr; 59 | WDFSPINLOCK spin_lock; 60 | 61 | /* keep these usbip port command */ 62 | USHORT id_vendor, id_product, dev_speed; 63 | 64 | // string index for USB serial 65 | UCHAR iSerial; 66 | // USB serial string 67 | PWCHAR wserial; 68 | 69 | /* Full-length configuration descriptor for finding an interface descriptor of EP */ 70 | PUCHAR dsc_conf; 71 | /* alt settings for interface. use SHORT for treating unassigned case(-1) */ 72 | PSHORT intf_altsettings; 73 | /* a first value in configuration descriptor */ 74 | UCHAR default_conf_value; 75 | } ctx_vusb_t, *pctx_vusb_t; 76 | 77 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(ctx_vusb_t, TO_VUSB) 78 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(pctx_vusb_t, TO_PVUSB) 79 | 80 | typedef struct _ctx_ep 81 | { 82 | pctx_vusb_t vusb; 83 | UCHAR type, addr, interval; 84 | /* 85 | * Information for a parent interface. 86 | * These are used for adjusting value of interface alternate setting. 87 | */ 88 | UCHAR intf_num, altsetting; 89 | UDECXUSBENDPOINT ude_ep; 90 | WDFQUEUE queue; 91 | } ctx_ep_t, *pctx_ep_t; 92 | 93 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(ctx_ep_t, TO_EP) 94 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(pctx_ep_t, TO_PEP) 95 | 96 | typedef struct _ctx_safe_vusb 97 | { 98 | pctx_vhci_t vhci; 99 | ULONG port; 100 | } ctx_safe_vusb_t, *pctx_safe_vusb_t; 101 | 102 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(ctx_safe_vusb_t, TO_SAFE_VUSB) 103 | 104 | #define TO_SAFE_VUSB_FROM_REQ(req) TO_SAFE_VUSB(WdfRequestGetFileObject(req)) 105 | 106 | #define VUSB_CREATING ((pctx_vusb_t)-1) 107 | #define VUSB_IS_VALID(vusb) ((vusb) != NULL && (vusb) != VUSB_CREATING && !(vusb)->invalid) 108 | 109 | extern NTSTATUS plugout_vusb(pctx_vhci_t vhci, CHAR port); 110 | 111 | extern pctx_vusb_t get_vusb(pctx_vhci_t vhci, ULONG port); 112 | extern pctx_vusb_t get_vusb_by_req(WDFREQUEST req); 113 | extern void put_vusb(pctx_vusb_t vusb); 114 | extern void put_vusb_passively(pctx_vusb_t vusb); 115 | 116 | EXTERN_C_END 117 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_driver.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_driver.tmh" 3 | 4 | extern NTSTATUS 5 | evt_add_vhci(_In_ WDFDRIVER drv, _Inout_ PWDFDEVICE_INIT dinit); 6 | 7 | static PAGEABLE VOID 8 | cleanup_vhci(_In_ WDFOBJECT drvobj) 9 | { 10 | PAGED_CODE(); 11 | 12 | TRD(DRIVER, "Enter"); 13 | 14 | WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)drvobj)); 15 | } 16 | 17 | static PAGEABLE VOID 18 | driver_unload(_In_ WDFDRIVER drvobj) 19 | { 20 | PAGED_CODE(); 21 | TRD(DRIVER, "Enter"); 22 | 23 | WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)drvobj)); 24 | } 25 | 26 | DRIVER_INITIALIZE DriverEntry; 27 | 28 | INITABLE NTSTATUS 29 | DriverEntry(_In_ PDRIVER_OBJECT drvobj, _In_ PUNICODE_STRING regpath) 30 | { 31 | WDF_DRIVER_CONFIG conf; 32 | NTSTATUS status; 33 | WDF_OBJECT_ATTRIBUTES attrs; 34 | 35 | PAGED_CODE(); 36 | WPP_INIT_TRACING(drvobj, regpath); 37 | 38 | TRD(DRIVER, "Enter"); 39 | 40 | WDF_OBJECT_ATTRIBUTES_INIT(&attrs); 41 | attrs.EvtCleanupCallback = cleanup_vhci; 42 | 43 | WDF_DRIVER_CONFIG_INIT(&conf, evt_add_vhci); 44 | conf.DriverPoolTag = VHCI_POOLTAG; 45 | conf.EvtDriverUnload = driver_unload; 46 | 47 | status = WdfDriverCreate(drvobj, regpath, &attrs, &conf, WDF_NO_HANDLE); 48 | if (!NT_SUCCESS(status)) { 49 | TRE(DRIVER, "WdfDriverCreate failed: %!STATUS!", status); 50 | WPP_CLEANUP(drvobj); 51 | return status; 52 | } 53 | 54 | TRD(DRIVER, "Leave: %!STATUS!", status); 55 | 56 | return status; 57 | } 58 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_driver.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "vhci_dev.h" 11 | #include "vhci_dbg.h" 12 | #include "vhci_trace.h" 13 | 14 | EXTERN_C_START 15 | 16 | #define INITABLE __declspec(code_seg("INIT")) 17 | #define PAGEABLE __declspec(code_seg("PAGE")) 18 | 19 | #define VHCI_POOLTAG 'ichv' 20 | 21 | EXTERN_C_END 22 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_plugout.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_plugout.tmh" 3 | 4 | #include "usbip_vhci_api.h" 5 | 6 | static VOID 7 | abort_pending_req_read(pctx_vusb_t vusb) 8 | { 9 | WDFREQUEST req_read_pending; 10 | 11 | WdfSpinLockAcquire(vusb->spin_lock); 12 | req_read_pending = vusb->pending_req_read; 13 | vusb->pending_req_read = NULL; 14 | WdfSpinLockRelease(vusb->spin_lock); 15 | 16 | if (req_read_pending != NULL) { 17 | TRD(PLUGIN, "abort read request"); 18 | WdfRequestUnmarkCancelable(req_read_pending); 19 | WdfRequestComplete(req_read_pending, STATUS_DEVICE_NOT_CONNECTED); 20 | } 21 | } 22 | 23 | static VOID 24 | abort_pending_urbr(purb_req_t urbr) 25 | { 26 | TRD(PLUGIN, "abort pending urbr: %!URBR!", urbr); 27 | complete_urbr(urbr, STATUS_DEVICE_NOT_CONNECTED); 28 | } 29 | 30 | static VOID 31 | abort_all_pending_urbrs(pctx_vusb_t vusb) 32 | { 33 | WdfSpinLockAcquire(vusb->spin_lock); 34 | 35 | while (!IsListEmpty(&vusb->head_urbr)) { 36 | purb_req_t urbr; 37 | 38 | urbr = CONTAINING_RECORD(vusb->head_urbr.Flink, urb_req_t, list_all); 39 | RemoveEntryListInit(&urbr->list_all); 40 | RemoveEntryListInit(&urbr->list_state); 41 | if (!unmark_cancelable_urbr(urbr)) 42 | continue; 43 | WdfSpinLockRelease(vusb->spin_lock); 44 | 45 | abort_pending_urbr(urbr); 46 | 47 | WdfSpinLockAcquire(vusb->spin_lock); 48 | } 49 | 50 | WdfSpinLockRelease(vusb->spin_lock); 51 | } 52 | 53 | static void 54 | vusb_plugout(pctx_vusb_t vusb) 55 | { 56 | /* 57 | * invalidate first to prevent requests from an upper layer. 58 | * If requests are consistently fed into a vusb about to be plugged out, 59 | * a live deadlock may occur where vusb aborts pending urbs indefinately. 60 | */ 61 | vusb->invalid = TRUE; 62 | abort_pending_req_read(vusb); 63 | abort_all_pending_urbrs(vusb); 64 | 65 | TRD(PLUGIN, "plugged out: port: %d", vusb->port); 66 | } 67 | 68 | static NTSTATUS 69 | plugout_all_vusbs(pctx_vhci_t vhci) 70 | { 71 | ULONG i; 72 | 73 | TRD(PLUGIN, "plugging out all the devices!"); 74 | 75 | for (i = 0; i < vhci->n_max_ports; i++) { 76 | pctx_vusb_t vusb; 77 | 78 | vusb = get_vusb(vhci, i); 79 | if (vusb == NULL) 80 | continue; 81 | 82 | vusb_plugout(vusb); 83 | put_vusb(vusb); 84 | } 85 | 86 | return STATUS_SUCCESS; 87 | } 88 | 89 | NTSTATUS 90 | plugout_vusb(pctx_vhci_t vhci, CHAR port) 91 | { 92 | pctx_vusb_t vusb; 93 | 94 | if (port < 0) 95 | return plugout_all_vusbs(vhci); 96 | 97 | TRD(IOCTL, "plugging out device: port: %u", port); 98 | 99 | vusb = get_vusb(vhci, port); 100 | if (vusb == NULL) { 101 | TRD(PLUGIN, "no matching vusb: port: %u", port); 102 | return STATUS_NO_SUCH_DEVICE; 103 | } 104 | 105 | vusb_plugout(vusb); 106 | put_vusb(vusb); 107 | 108 | TRD(IOCTL, "completed to plug out: port: %u", port); 109 | 110 | return STATUS_SUCCESS; 111 | } 112 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_proto.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "vhci_urbr.h" 5 | 6 | #define USBDEVFS_URB_SHORT_NOT_OK 0x01 7 | #define USBDEVFS_URB_ISO_ASAP 0x02 8 | #define USBDEVFS_URB_NO_FSBR 0x20 9 | #define USBDEVFS_URB_ZERO_PACKET 0x40 10 | #define USBDEVFS_URB_NO_INTERRUPT 0x80 11 | 12 | unsigned int 13 | transflag(unsigned int flags) 14 | { 15 | unsigned int linux_flags = 0; 16 | if (!(flags&USBD_SHORT_TRANSFER_OK)) 17 | linux_flags |= USBDEVFS_URB_SHORT_NOT_OK; 18 | if (flags&USBD_START_ISO_TRANSFER_ASAP) 19 | linux_flags |= USBDEVFS_URB_ISO_ASAP; 20 | return linux_flags; 21 | } 22 | 23 | void 24 | set_cmd_submit_usbip_header(struct usbip_header *h, unsigned long seqnum, unsigned int devid, 25 | unsigned int direct, pctx_ep_t ep, unsigned int flags, unsigned int len) 26 | { 27 | h->base.command = USBIP_CMD_SUBMIT; 28 | h->base.seqnum = seqnum; 29 | h->base.devid = devid; 30 | h->base.direction = direct ? USBIP_DIR_IN : USBIP_DIR_OUT; 31 | h->base.ep = ep ? (ep->addr & 0x7f): 0; 32 | h->u.cmd_submit.transfer_flags = transflag(flags); 33 | h->u.cmd_submit.transfer_buffer_length = len; 34 | h->u.cmd_submit.start_frame = 0; 35 | h->u.cmd_submit.number_of_packets = 0; 36 | h->u.cmd_submit.interval = ep ? ep->interval: 0; 37 | } 38 | 39 | void 40 | set_cmd_unlink_usbip_header(struct usbip_header *h, unsigned long seqnum, unsigned int devid, unsigned long seqnum_unlink) 41 | { 42 | h->base.command = USBIP_CMD_UNLINK; 43 | h->base.seqnum = seqnum; 44 | h->base.devid = devid; 45 | h->base.direction = USBIP_DIR_OUT; 46 | h->base.ep = 0; 47 | h->u.cmd_unlink.seqnum = seqnum_unlink; 48 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_queue_ep.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_queue_ep.tmh" 3 | 4 | static VOID 5 | internal_device_control(_In_ WDFQUEUE queue, _In_ WDFREQUEST req, 6 | _In_ size_t outlen, _In_ size_t inlen, _In_ ULONG ioctl_code) 7 | { 8 | NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; 9 | 10 | UNREFERENCED_PARAMETER(inlen); 11 | UNREFERENCED_PARAMETER(outlen); 12 | 13 | TRD(EP, "Enter"); 14 | 15 | if (ioctl_code != IOCTL_INTERNAL_USB_SUBMIT_URB) { 16 | TRE(EP, "unexpected ioctl: %!IOCTL!", ioctl_code); 17 | } 18 | else { 19 | pctx_ep_t ep = *TO_PEP(queue); 20 | if (ep->vusb->invalid) 21 | status = STATUS_DEVICE_DOES_NOT_EXIST; 22 | else 23 | status = submit_req_urb(*TO_PEP(queue), req); 24 | } 25 | 26 | if (status != STATUS_PENDING) 27 | UdecxUrbCompleteWithNtStatus(req, status); 28 | 29 | TRD(EP, "Leave: %!STATUS!", status); 30 | } 31 | 32 | static VOID 33 | io_default_ep(_In_ WDFQUEUE queue, _In_ WDFREQUEST req) 34 | { 35 | UNREFERENCED_PARAMETER(queue); 36 | UNREFERENCED_PARAMETER(req); 37 | 38 | TRE(EP, "unexpected io default callback"); 39 | } 40 | 41 | WDFQUEUE 42 | create_queue_ep(pctx_ep_t ep) 43 | { 44 | WDFQUEUE queue; 45 | WDF_IO_QUEUE_CONFIG conf; 46 | WDF_OBJECT_ATTRIBUTES attrs; 47 | NTSTATUS status; 48 | 49 | WDF_IO_QUEUE_CONFIG_INIT(&conf, WdfIoQueueDispatchParallel); 50 | conf.EvtIoInternalDeviceControl = internal_device_control; 51 | conf.EvtIoDefault = io_default_ep; 52 | 53 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attrs, pctx_ep_t); 54 | attrs.ParentObject = ep->ude_ep; 55 | attrs.SynchronizationScope = WdfSynchronizationScopeQueue; 56 | 57 | status = WdfIoQueueCreate(ep->vusb->vhci->hdev, &conf, &attrs, &queue); 58 | if (NT_ERROR(status)) { 59 | TRE(EP, "failed to create queue: %!STATUS!", status); 60 | return NULL; 61 | } 62 | 63 | *TO_PEP(queue) = ep; 64 | 65 | return queue; 66 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_queue_hc.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_queue_hc.tmh" 3 | 4 | extern VOID io_device_control(_In_ WDFQUEUE queue, _In_ WDFREQUEST req, 5 | _In_ size_t OutputBufferLength, _In_ size_t InputBufferLength, _In_ ULONG IoControlCode); 6 | extern VOID io_read(_In_ WDFQUEUE queue, _In_ WDFREQUEST req, _In_ size_t len); 7 | extern VOID io_write(_In_ WDFQUEUE queue, _In_ WDFREQUEST req, _In_ size_t len); 8 | 9 | static VOID 10 | io_default_hc(_In_ WDFQUEUE queue, _In_ WDFREQUEST req) 11 | { 12 | UNREFERENCED_PARAMETER(queue); 13 | UNREFERENCED_PARAMETER(req); 14 | 15 | TRE(QUEUE_HC, "unexpected io default callback"); 16 | } 17 | 18 | PAGEABLE NTSTATUS 19 | create_queue_hc(pctx_vhci_t vhci) 20 | { 21 | WDFQUEUE queue; 22 | WDF_IO_QUEUE_CONFIG conf; 23 | WDF_OBJECT_ATTRIBUTES attrs; 24 | NTSTATUS status; 25 | 26 | PAGED_CODE(); 27 | 28 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&conf, WdfIoQueueDispatchParallel); 29 | conf.EvtIoRead = io_read; 30 | conf.EvtIoWrite = io_write; 31 | conf.EvtIoDeviceControl = io_device_control; 32 | conf.EvtIoDefault = io_default_hc; 33 | 34 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attrs, pctx_vhci_t); 35 | attrs.SynchronizationScope = WdfSynchronizationScopeQueue; 36 | attrs.ExecutionLevel = WdfExecutionLevelPassive; 37 | status = WdfIoQueueCreate(vhci->hdev, &conf, &attrs, &queue); 38 | if (NT_SUCCESS(status)) { 39 | *TO_PVHCI(queue) = vhci; 40 | vhci->queue = queue; 41 | } 42 | else { 43 | TRE(QUEUE_HC, "failed to create queue: %!STATUS!", status); 44 | } 45 | return status; 46 | } 47 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_trace.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Define the tracing flags. 4 | // 5 | // Tracing GUID - 99b7a5cf-7cb0-4af5-838d-c45d78e49101 6 | // 7 | 8 | #define WPP_CONTROL_GUIDS \ 9 | WPP_DEFINE_CONTROL_GUID( \ 10 | vhciTraceGuid, (99b7a5cf,7cb0,4af5,838d,c45d78e49101), \ 11 | \ 12 | WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ 13 | WPP_DEFINE_BIT(DRIVER) \ 14 | WPP_DEFINE_BIT(VHCI) \ 15 | WPP_DEFINE_BIT(QUEUE_HC) \ 16 | WPP_DEFINE_BIT(VUSB) \ 17 | WPP_DEFINE_BIT(READ) \ 18 | WPP_DEFINE_BIT(WRITE) \ 19 | WPP_DEFINE_BIT(EP) \ 20 | WPP_DEFINE_BIT(QUEUE_EP) \ 21 | WPP_DEFINE_BIT(URBR) \ 22 | WPP_DEFINE_BIT(IOCTL) \ 23 | WPP_DEFINE_BIT(PLUGIN) \ 24 | ) 25 | 26 | #define WPP_FLAG_LEVEL_LOGGER(flag, level) \ 27 | WPP_LEVEL_LOGGER(flag) 28 | 29 | #define WPP_FLAG_LEVEL_ENABLED(flag, level) \ 30 | (WPP_LEVEL_ENABLED(flag) && \ 31 | WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) 32 | 33 | #define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \ 34 | WPP_LEVEL_LOGGER(flags) 35 | 36 | #define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \ 37 | (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) 38 | 39 | // 40 | // WPP orders static parameters before dynamic parameters. To support the Trace function 41 | // defined below which sets FLAGS=MYDRIVER_ALL_INFO, a custom macro must be defined to 42 | // reorder the arguments to what the .tpl configuration file expects. 43 | // 44 | #define WPP_RECORDER_FLAGS_LEVEL_ARGS(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_ARGS(lvl, flags) 45 | #define WPP_RECORDER_FLAGS_LEVEL_FILTER(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_FILTER(lvl, flags) 46 | 47 | // 48 | // This comment block is scanned by the trace preprocessor to define our 49 | // Trace function. 50 | // 51 | // begin_wpp config 52 | // FUNC Trace{FLAGS=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); 53 | // FUNC TraceEvents(LEVEL, FLAGS, MSG, ...); 54 | // end_wpp 55 | // 56 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "usb_util.h" 8 | 9 | #include "vhci_dev.h" 10 | 11 | typedef enum { 12 | URBR_TYPE_URB, 13 | URBR_TYPE_UNLINK, 14 | URBR_TYPE_SELECT_CONF, 15 | URBR_TYPE_SELECT_INTF, 16 | URBR_TYPE_RESET_PIPE 17 | } urbr_type_t; 18 | 19 | typedef struct _urb_req { 20 | pctx_ep_t ep; 21 | WDFREQUEST req; 22 | urbr_type_t type; 23 | unsigned long seq_num; 24 | union { 25 | struct { 26 | PURB urb; 27 | BOOLEAN cancelable; 28 | } urb; 29 | unsigned long seq_num_unlink; 30 | UCHAR conf_value; 31 | struct { 32 | UCHAR intf_num, alt_setting; 33 | } intf; 34 | } u; 35 | LIST_ENTRY list_all; 36 | LIST_ENTRY list_state; 37 | /* back reference to WDFMEMORY for deletion */ 38 | WDFMEMORY hmem; 39 | } urb_req_t, *purb_req_t; 40 | 41 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(urb_req_t, TO_URBR) 42 | 43 | #define IS_TRANSFER_FLAGS_IN(flags) ((flags) & USBD_TRANSFER_DIRECTION_IN) 44 | 45 | #define RemoveEntryListInit(le) do { RemoveEntryList(le); InitializeListHead(le); } while (0) 46 | 47 | extern struct usbip_header *get_hdr_from_req_read(WDFREQUEST req_read); 48 | extern PVOID get_data_from_req_read(WDFREQUEST req_read, ULONG length); 49 | 50 | extern ULONG get_read_payload_length(WDFREQUEST req_read); 51 | 52 | extern PVOID get_buf(PVOID buf, PMDL bufMDL); 53 | 54 | extern NTSTATUS 55 | copy_to_transfer_buffer(PVOID buf_dst, PMDL bufMDL, int dst_len, PVOID src, int src_len); 56 | 57 | extern void set_cmd_submit_usbip_header(struct usbip_header *hdr, unsigned long seqnum, unsigned int devid, 58 | unsigned int direct, pctx_ep_t ep, unsigned int flags, unsigned int len); 59 | extern void set_cmd_unlink_usbip_header(struct usbip_header *h, unsigned long seqnum, unsigned int devid, 60 | unsigned long seqnum_unlink); 61 | 62 | extern void 63 | build_setup_packet(usb_cspkt_t *csp, unsigned char direct_in, unsigned char type, unsigned char recip, unsigned char request); 64 | 65 | extern NTSTATUS 66 | submit_req_urb(pctx_ep_t ep, WDFREQUEST req); 67 | extern NTSTATUS 68 | submit_req_select(pctx_ep_t ep, WDFREQUEST req, BOOLEAN is_select_conf, UCHAR conf_value, UCHAR intf_num, UCHAR alt_setting); 69 | extern NTSTATUS 70 | submit_req_reset_pipe(pctx_ep_t ep, WDFREQUEST req); 71 | extern NTSTATUS 72 | store_urbr(WDFREQUEST req_read, purb_req_t urbr); 73 | 74 | extern BOOLEAN 75 | unmark_cancelable_urbr(purb_req_t urbr); 76 | extern void 77 | complete_urbr(purb_req_t urbr, NTSTATUS status); 78 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_fetch_bulk.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "vhci_urbr.h" 5 | 6 | NTSTATUS 7 | fetch_urbr_bulk_or_interrupt(PURB urb, struct usbip_header *hdr) 8 | { 9 | struct _URB_BULK_OR_INTERRUPT_TRANSFER *urb_bi = &urb->UrbBulkOrInterruptTransfer; 10 | 11 | if (IS_TRANSFER_FLAGS_IN(urb_bi->TransferFlags)) { 12 | NTSTATUS status; 13 | status = copy_to_transfer_buffer(urb_bi->TransferBuffer, urb_bi->TransferBufferMDL, 14 | urb_bi->TransferBufferLength, hdr + 1, hdr->u.ret_submit.actual_length); 15 | if (status == STATUS_SUCCESS) 16 | urb_bi->TransferBufferLength = hdr->u.ret_submit.actual_length; 17 | return status; 18 | } 19 | return STATUS_SUCCESS; 20 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_fetch_control.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "vhci_urbr.h" 5 | 6 | NTSTATUS 7 | fetch_urbr_control_transfer(PURB urb, struct usbip_header *hdr) 8 | { 9 | struct _URB_CONTROL_TRANSFER *urb_ctltrans = &urb->UrbControlTransfer; 10 | NTSTATUS status; 11 | 12 | if (!IS_TRANSFER_FLAGS_IN(urb_ctltrans->TransferFlags)) 13 | return STATUS_SUCCESS; 14 | status = copy_to_transfer_buffer(urb_ctltrans->TransferBuffer, urb_ctltrans->TransferBufferMDL, 15 | urb_ctltrans->TransferBufferLength, hdr + 1, hdr->u.ret_submit.actual_length); 16 | if (status == STATUS_SUCCESS) 17 | urb_ctltrans->TransferBufferLength = hdr->u.ret_submit.actual_length; 18 | return status; 19 | } 20 | 21 | NTSTATUS 22 | fetch_urbr_control_transfer_ex(PURB urb, struct usbip_header *hdr) 23 | { 24 | struct _URB_CONTROL_TRANSFER_EX *urb_ctltrans_ex = &urb->UrbControlTransferEx; 25 | NTSTATUS status; 26 | 27 | if (!IS_TRANSFER_FLAGS_IN(urb_ctltrans_ex->TransferFlags)) 28 | return STATUS_SUCCESS; 29 | status = copy_to_transfer_buffer(urb_ctltrans_ex->TransferBuffer, urb_ctltrans_ex->TransferBufferMDL, 30 | urb_ctltrans_ex->TransferBufferLength, hdr + 1, hdr->u.ret_submit.actual_length); 31 | if (status == STATUS_SUCCESS) 32 | urb_ctltrans_ex->TransferBufferLength = hdr->u.ret_submit.actual_length; 33 | return status; 34 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_fetch_dscr.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "vhci_urbr.h" 5 | 6 | NTSTATUS 7 | fetch_urbr_dscr(PURB urb, struct usbip_header *hdr) 8 | { 9 | struct _URB_CONTROL_DESCRIPTOR_REQUEST *urb_desc = &urb->UrbControlDescriptorRequest; 10 | NTSTATUS status; 11 | 12 | status = copy_to_transfer_buffer(urb_desc->TransferBuffer, urb_desc->TransferBufferMDL, 13 | urb_desc->TransferBufferLength, hdr + 1, hdr->u.ret_submit.actual_length); 14 | if (status == STATUS_SUCCESS) 15 | urb_desc->TransferBufferLength = hdr->u.ret_submit.actual_length; 16 | return status; 17 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_fetch_iso.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_urbr_fetch_iso.tmh" 3 | 4 | #include "usbip_proto.h" 5 | #include "vhci_urbr.h" 6 | #include "usbd_helper.h" 7 | 8 | static BOOLEAN 9 | save_iso_desc(struct _URB_ISOCH_TRANSFER *urb, struct usbip_iso_packet_descriptor *iso_desc) 10 | { 11 | ULONG i; 12 | 13 | for (i = 0; i < urb->NumberOfPackets; i++) { 14 | if (iso_desc->offset > urb->IsoPacket[i].Offset) { 15 | TRW(WRITE, "why offset changed?%d %d %d %d", i, iso_desc->offset, iso_desc->actual_length, urb->IsoPacket[i].Offset); 16 | return FALSE; 17 | } 18 | urb->IsoPacket[i].Length = iso_desc->actual_length; 19 | urb->IsoPacket[i].Status = to_usbd_status(iso_desc->status); 20 | iso_desc++; 21 | } 22 | return TRUE; 23 | } 24 | 25 | static void 26 | fetch_iso_data(char *dest, ULONG dest_len, char *src, ULONG src_len, struct _URB_ISOCH_TRANSFER *urb) 27 | { 28 | ULONG i; 29 | ULONG offset = 0; 30 | 31 | for (i = 0; i < urb->NumberOfPackets; i++) { 32 | if (urb->IsoPacket[i].Length == 0) 33 | continue; 34 | 35 | if (urb->IsoPacket[i].Offset + urb->IsoPacket[i].Length > dest_len) { 36 | TRW(WRITE, "Warning, why this?"); 37 | break; 38 | } 39 | if (offset + urb->IsoPacket[i].Length > src_len) { 40 | TRE(WRITE, "Warning, why that?"); 41 | break; 42 | } 43 | RtlCopyMemory(dest + urb->IsoPacket[i].Offset, src + offset, urb->IsoPacket[i].Length); 44 | offset += urb->IsoPacket[i].Length; 45 | } 46 | if (offset != src_len) { 47 | TRW(WRITE, "why not equal offset:%d src_len:%d", offset, src_len); 48 | } 49 | } 50 | 51 | NTSTATUS 52 | fetch_urbr_iso(PURB urb, struct usbip_header *hdr) 53 | { 54 | struct _URB_ISOCH_TRANSFER *urb_iso = &urb->UrbIsochronousTransfer; 55 | struct usbip_iso_packet_descriptor *iso_desc; 56 | PVOID buf; 57 | int in_len = 0; 58 | 59 | if (IS_TRANSFER_FLAGS_IN(urb_iso->TransferFlags)) 60 | in_len = hdr->u.ret_submit.actual_length; 61 | iso_desc = (struct usbip_iso_packet_descriptor *)((char *)(hdr + 1) + in_len); 62 | if (!save_iso_desc(urb_iso, iso_desc)) 63 | return STATUS_INVALID_PARAMETER; 64 | 65 | urb_iso->ErrorCount = hdr->u.ret_submit.error_count; 66 | /* The RET_SUBMIT packets of the OUT ISO transfer do not contain data buffer. */ 67 | if (!IS_TRANSFER_FLAGS_IN(urb_iso->TransferFlags)) 68 | return STATUS_SUCCESS; 69 | 70 | buf = get_buf(urb_iso->TransferBuffer, urb_iso->TransferBufferMDL); 71 | if (buf == NULL) 72 | return STATUS_INVALID_PARAMETER; 73 | fetch_iso_data(buf, urb_iso->TransferBufferLength, (char *)(hdr + 1), hdr->u.ret_submit.actual_length, urb_iso); 74 | urb_iso->TransferBufferLength = hdr->u.ret_submit.actual_length; 75 | return STATUS_SUCCESS; 76 | } 77 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_fetch_status.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "vhci_urbr.h" 5 | 6 | NTSTATUS 7 | fetch_urbr_status(PURB urb, struct usbip_header *hdr) 8 | { 9 | struct _URB_CONTROL_GET_STATUS_REQUEST *urb_status = &urb->UrbControlGetStatusRequest; 10 | NTSTATUS status; 11 | 12 | status = copy_to_transfer_buffer(urb_status->TransferBuffer, urb_status->TransferBufferMDL, 13 | urb_status->TransferBufferLength, hdr + 1, hdr->u.ret_submit.actual_length); 14 | if (status == STATUS_SUCCESS) 15 | urb_status->TransferBufferLength = hdr->u.ret_submit.actual_length; 16 | return status; 17 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_fetch_vendor.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "vhci_urbr.h" 5 | 6 | NTSTATUS 7 | fetch_urbr_vendor_or_class(PURB urb, struct usbip_header *hdr) 8 | { 9 | struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *urb_vendor_class = &urb->UrbControlVendorClassRequest; 10 | 11 | if (IS_TRANSFER_FLAGS_IN(urb_vendor_class->TransferFlags)) { 12 | NTSTATUS status; 13 | status = copy_to_transfer_buffer(urb_vendor_class->TransferBuffer, urb_vendor_class->TransferBufferMDL, 14 | urb_vendor_class->TransferBufferLength, hdr + 1, hdr->u.ret_submit.actual_length); 15 | if (status == STATUS_SUCCESS) 16 | urb_vendor_class->TransferBufferLength = hdr->u.ret_submit.actual_length; 17 | return status; 18 | } 19 | else { 20 | urb_vendor_class->TransferBufferLength = hdr->u.ret_submit.actual_length; 21 | } 22 | return STATUS_SUCCESS; 23 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_store_bulk.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_urbr_store_bulk.tmh" 3 | 4 | #include "usbip_proto.h" 5 | #include "vhci_urbr.h" 6 | 7 | NTSTATUS 8 | store_urbr_bulk_partial(WDFREQUEST req_read, purb_req_t urbr) 9 | { 10 | struct _URB_BULK_OR_INTERRUPT_TRANSFER *urb_bi = &urbr->u.urb.urb->UrbBulkOrInterruptTransfer; 11 | PVOID dst, src; 12 | NTSTATUS status; 13 | 14 | status = WdfRequestRetrieveOutputBuffer(req_read, urb_bi->TransferBufferLength, &dst, NULL); 15 | if (NT_ERROR(status)) 16 | return STATUS_BUFFER_TOO_SMALL; 17 | 18 | src = get_buf(urb_bi->TransferBuffer, urb_bi->TransferBufferMDL); 19 | if (src == NULL) 20 | return STATUS_INSUFFICIENT_RESOURCES; 21 | RtlCopyMemory(dst, src, urb_bi->TransferBufferLength); 22 | WdfRequestSetInformation(req_read, urb_bi->TransferBufferLength); 23 | urbr->ep->vusb->len_sent_partial = 0; 24 | 25 | return STATUS_SUCCESS; 26 | } 27 | 28 | NTSTATUS 29 | store_urbr_bulk(WDFREQUEST req_read, purb_req_t urbr) 30 | { 31 | struct _URB_BULK_OR_INTERRUPT_TRANSFER *urb_bi = &urbr->u.urb.urb->UrbBulkOrInterruptTransfer; 32 | struct usbip_header *hdr; 33 | int in, type; 34 | 35 | hdr = get_hdr_from_req_read(req_read); 36 | if (hdr == NULL) 37 | return STATUS_BUFFER_TOO_SMALL; 38 | 39 | /* Sometimes, direction in TransferFlags of _URB_BULK_OR_INTERRUPT_TRANSFER is not consistent with PipeHandle. 40 | * Use a direction flag in pipe handle. 41 | */ 42 | in = IS_TRANSFER_FLAGS_IN(urb_bi->TransferFlags); 43 | type = urbr->ep->type; 44 | if (type != USB_ENDPOINT_TYPE_BULK && type != USB_ENDPOINT_TYPE_INTERRUPT) { 45 | TRE(READ, "Error, not a bulk or a interrupt pipe\n"); 46 | return STATUS_INVALID_PARAMETER; 47 | } 48 | 49 | set_cmd_submit_usbip_header(hdr, urbr->seq_num, urbr->ep->vusb->devid, in, urbr->ep, 50 | urb_bi->TransferFlags, urb_bi->TransferBufferLength); 51 | RtlZeroMemory(hdr->u.cmd_submit.setup, 8); 52 | 53 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header)); 54 | 55 | if (!in) { 56 | if (get_read_payload_length(req_read) >= urb_bi->TransferBufferLength) { 57 | PVOID buf = get_buf(urb_bi->TransferBuffer, urb_bi->TransferBufferMDL); 58 | if (buf == NULL) 59 | return STATUS_INSUFFICIENT_RESOURCES; 60 | RtlCopyMemory(hdr + 1, buf, urb_bi->TransferBufferLength); 61 | } 62 | else { 63 | urbr->ep->vusb->len_sent_partial = sizeof(struct usbip_header); 64 | } 65 | } 66 | return STATUS_SUCCESS; 67 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_store_dscr.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "vhci_urbr.h" 5 | 6 | NTSTATUS 7 | store_urbr_dscr_dev(WDFREQUEST req_read, purb_req_t urbr) 8 | { 9 | struct _URB_CONTROL_DESCRIPTOR_REQUEST *urb_dscr = &urbr->u.urb.urb->UrbControlDescriptorRequest; 10 | struct usbip_header *hdr; 11 | usb_cspkt_t *csp; 12 | 13 | hdr = get_hdr_from_req_read(req_read); 14 | if (hdr == NULL) 15 | return STATUS_BUFFER_TOO_SMALL; 16 | 17 | csp = (usb_cspkt_t *)hdr->u.cmd_submit.setup; 18 | 19 | set_cmd_submit_usbip_header(hdr, urbr->seq_num, urbr->ep->vusb->devid, USBIP_DIR_IN, NULL, 20 | USBD_SHORT_TRANSFER_OK, urb_dscr->TransferBufferLength); 21 | build_setup_packet(csp, USBIP_DIR_IN, BMREQUEST_STANDARD, BMREQUEST_TO_DEVICE, USB_REQUEST_GET_DESCRIPTOR); 22 | 23 | csp->wLength = (unsigned short)urb_dscr->TransferBufferLength; 24 | csp->wValue.HiByte = urb_dscr->DescriptorType; 25 | csp->wValue.LowByte = urb_dscr->Index; 26 | 27 | switch (urb_dscr->DescriptorType) { 28 | case USB_DEVICE_DESCRIPTOR_TYPE: 29 | case USB_CONFIGURATION_DESCRIPTOR_TYPE: 30 | csp->wIndex.W = 0; 31 | break; 32 | case USB_INTERFACE_DESCRIPTOR_TYPE: 33 | csp->wIndex.W = urb_dscr->Index; 34 | break; 35 | case USB_STRING_DESCRIPTOR_TYPE: 36 | csp->wIndex.W = urb_dscr->LanguageId; 37 | break; 38 | default: 39 | return STATUS_INVALID_PARAMETER; 40 | } 41 | 42 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header)); 43 | return STATUS_SUCCESS; 44 | } 45 | 46 | NTSTATUS 47 | store_urbr_dscr_intf(WDFREQUEST req_read, purb_req_t urbr) 48 | { 49 | struct _URB_CONTROL_DESCRIPTOR_REQUEST *urb_dscr = &urbr->u.urb.urb->UrbControlDescriptorRequest; 50 | struct usbip_header *hdr; 51 | usb_cspkt_t *csp; 52 | 53 | hdr = get_hdr_from_req_read(req_read); 54 | if (hdr == NULL) 55 | return STATUS_BUFFER_TOO_SMALL; 56 | 57 | csp = (usb_cspkt_t *)hdr->u.cmd_submit.setup; 58 | 59 | set_cmd_submit_usbip_header(hdr, urbr->seq_num, urbr->ep->vusb->devid, USBIP_DIR_IN, NULL, 60 | USBD_SHORT_TRANSFER_OK, urb_dscr->TransferBufferLength); 61 | build_setup_packet(csp, USBIP_DIR_IN, BMREQUEST_STANDARD, BMREQUEST_TO_INTERFACE, USB_REQUEST_GET_DESCRIPTOR); 62 | 63 | csp->wLength = (unsigned short)urb_dscr->TransferBufferLength; 64 | csp->wValue.HiByte = urb_dscr->DescriptorType; 65 | csp->wValue.LowByte = urb_dscr->Index; 66 | csp->wIndex.W = urb_dscr->LanguageId; 67 | 68 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header)); 69 | return STATUS_SUCCESS; 70 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_store_iso.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_urbr_store_iso.tmh" 3 | 4 | #include "usbip_proto.h" 5 | #include "vhci_urbr.h" 6 | 7 | static NTSTATUS 8 | store_iso_data(PVOID dst, struct _URB_ISOCH_TRANSFER *urb_iso) 9 | { 10 | struct usbip_iso_packet_descriptor *iso_desc; 11 | char *buf; 12 | ULONG i, offset; 13 | 14 | buf = get_buf(urb_iso->TransferBuffer, urb_iso->TransferBufferMDL); 15 | if (buf == NULL) 16 | return STATUS_INSUFFICIENT_RESOURCES; 17 | 18 | if (IS_TRANSFER_FLAGS_IN(urb_iso->TransferFlags)) { 19 | iso_desc = (struct usbip_iso_packet_descriptor *)dst; 20 | } 21 | else { 22 | RtlCopyMemory(dst, buf, urb_iso->TransferBufferLength); 23 | iso_desc = (struct usbip_iso_packet_descriptor *)((char *)dst + urb_iso->TransferBufferLength); 24 | } 25 | 26 | offset = 0; 27 | for (i = 0; i < urb_iso->NumberOfPackets; i++) { 28 | if (urb_iso->IsoPacket[i].Offset < offset) { 29 | TRW(READ, "strange iso packet offset:%d %d", offset, urb_iso->IsoPacket[i].Offset); 30 | return STATUS_INVALID_PARAMETER; 31 | } 32 | iso_desc->offset = urb_iso->IsoPacket[i].Offset; 33 | if (i > 0) 34 | (iso_desc - 1)->length = urb_iso->IsoPacket[i].Offset - offset; 35 | offset = urb_iso->IsoPacket[i].Offset; 36 | iso_desc->actual_length = 0; 37 | iso_desc->status = 0; 38 | iso_desc++; 39 | } 40 | (iso_desc - 1)->length = urb_iso->TransferBufferLength - offset; 41 | 42 | return STATUS_SUCCESS; 43 | } 44 | 45 | static ULONG 46 | get_iso_payload_len(struct _URB_ISOCH_TRANSFER *urb_iso) 47 | { 48 | ULONG len_iso; 49 | 50 | len_iso = urb_iso->NumberOfPackets * sizeof(struct usbip_iso_packet_descriptor); 51 | if (!IS_TRANSFER_FLAGS_IN(urb_iso->TransferFlags)) { 52 | len_iso += urb_iso->TransferBufferLength; 53 | } 54 | return len_iso; 55 | } 56 | 57 | NTSTATUS 58 | store_urbr_iso_partial(WDFREQUEST req_read, purb_req_t urbr) 59 | { 60 | struct _URB_ISOCH_TRANSFER *urb_iso = &urbr->u.urb.urb->UrbIsochronousTransfer; 61 | ULONG len_iso; 62 | PVOID dst; 63 | 64 | len_iso = get_iso_payload_len(urb_iso); 65 | 66 | dst = get_data_from_req_read(req_read, len_iso); 67 | if (dst == NULL) 68 | return STATUS_BUFFER_TOO_SMALL; 69 | 70 | store_iso_data(dst, urb_iso); 71 | urbr->ep->vusb->len_sent_partial = 0; 72 | WdfRequestSetInformation(req_read, len_iso); 73 | 74 | return STATUS_SUCCESS; 75 | } 76 | 77 | NTSTATUS 78 | store_urbr_iso(WDFREQUEST req_read, purb_req_t urbr) 79 | { 80 | struct _URB_ISOCH_TRANSFER *urb_iso = &urbr->u.urb.urb->UrbIsochronousTransfer; 81 | struct usbip_header *hdr; 82 | int in, type; 83 | 84 | in = IS_TRANSFER_FLAGS_IN(urb_iso->TransferFlags); 85 | type = urbr->ep->type; 86 | if (type != USB_ENDPOINT_TYPE_ISOCHRONOUS) { 87 | TRE(READ, "Error, not a iso pipe"); 88 | return STATUS_INVALID_PARAMETER; 89 | } 90 | 91 | hdr = get_hdr_from_req_read(req_read); 92 | if (hdr == NULL) 93 | return STATUS_BUFFER_TOO_SMALL; 94 | 95 | set_cmd_submit_usbip_header(hdr, urbr->seq_num, urbr->ep->vusb->devid, in, urbr->ep, 96 | urb_iso->TransferFlags | USBD_SHORT_TRANSFER_OK, urb_iso->TransferBufferLength); 97 | hdr->u.cmd_submit.start_frame = urb_iso->StartFrame; 98 | hdr->u.cmd_submit.number_of_packets = urb_iso->NumberOfPackets; 99 | 100 | if (get_read_payload_length(req_read) >= get_iso_payload_len(urb_iso)) { 101 | store_iso_data(hdr + 1, urb_iso); 102 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header) + get_iso_payload_len(urb_iso)); 103 | } 104 | else { 105 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header)); 106 | urbr->ep->vusb->len_sent_partial = sizeof(struct usbip_header); 107 | } 108 | 109 | return STATUS_SUCCESS; 110 | } 111 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_store_reset.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "vhci_urbr.h" 5 | 6 | NTSTATUS 7 | store_urbr_reset_pipe(WDFREQUEST req_read, purb_req_t urbr) 8 | { 9 | struct usbip_header *hdr; 10 | usb_cspkt_t *csp; 11 | 12 | hdr = get_hdr_from_req_read(req_read); 13 | if (hdr == NULL) 14 | return STATUS_BUFFER_TOO_SMALL; 15 | 16 | csp = (usb_cspkt_t *)hdr->u.cmd_submit.setup; 17 | 18 | set_cmd_submit_usbip_header(hdr, urbr->seq_num, urbr->ep->vusb->devid, 0, 0, 0, 0); 19 | build_setup_packet(csp, 0, BMREQUEST_STANDARD, BMREQUEST_TO_ENDPOINT, USB_REQUEST_CLEAR_FEATURE); 20 | csp->wIndex.LowByte = urbr->ep->addr; // Specify enpoint address and direction 21 | csp->wIndex.HiByte = 0; 22 | csp->wValue.W = 0; // clear ENDPOINT_HALT 23 | csp->wLength = 0; 24 | 25 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header)); 26 | 27 | return STATUS_SUCCESS; 28 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_store_select.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "vhci_urbr.h" 5 | 6 | NTSTATUS 7 | store_urbr_select_config(WDFREQUEST req_read, purb_req_t urbr) 8 | { 9 | struct usbip_header *hdr; 10 | usb_cspkt_t *csp; 11 | 12 | hdr = get_hdr_from_req_read(req_read); 13 | if (hdr == NULL) 14 | return STATUS_BUFFER_TOO_SMALL; 15 | 16 | csp = (usb_cspkt_t *)hdr->u.cmd_submit.setup; 17 | 18 | set_cmd_submit_usbip_header(hdr, urbr->seq_num, urbr->ep->vusb->devid, 0, 0, 0, 0); 19 | build_setup_packet(csp, 0, BMREQUEST_STANDARD, BMREQUEST_TO_DEVICE, USB_REQUEST_SET_CONFIGURATION); 20 | csp->wLength = 0; 21 | csp->wValue.W = urbr->u.conf_value; 22 | csp->wIndex.W = 0; 23 | 24 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header)); 25 | return STATUS_SUCCESS; 26 | } 27 | 28 | NTSTATUS 29 | store_urbr_select_interface(WDFREQUEST req_read, purb_req_t urbr) 30 | { 31 | struct usbip_header *hdr; 32 | usb_cspkt_t *csp; 33 | 34 | hdr = get_hdr_from_req_read(req_read); 35 | if (hdr == NULL) 36 | return STATUS_BUFFER_TOO_SMALL; 37 | 38 | csp = (usb_cspkt_t *)hdr->u.cmd_submit.setup; 39 | 40 | set_cmd_submit_usbip_header(hdr, urbr->seq_num, urbr->ep->vusb->devid, 0, 0, 0, 0); 41 | build_setup_packet(csp, 0, BMREQUEST_STANDARD, BMREQUEST_TO_INTERFACE, USB_REQUEST_SET_INTERFACE); 42 | csp->wLength = 0; 43 | csp->wValue.W = urbr->u.intf.alt_setting; 44 | csp->wIndex.W = urbr->u.intf.intf_num; 45 | 46 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header)); 47 | return STATUS_SUCCESS; 48 | } 49 | -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_store_status.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_urbr_store_status.tmh" 3 | 4 | #include "usbip_proto.h" 5 | #include "vhci_urbr.h" 6 | 7 | NTSTATUS 8 | store_urbr_get_status(WDFREQUEST req_read, purb_req_t urbr) 9 | { 10 | struct _URB_CONTROL_GET_STATUS_REQUEST *urb_status = &urbr->u.urb.urb->UrbControlGetStatusRequest; 11 | struct usbip_header *hdr; 12 | USHORT urbfunc; 13 | char recip; 14 | usb_cspkt_t *csp; 15 | 16 | hdr = get_hdr_from_req_read(req_read); 17 | if (hdr == NULL) 18 | return STATUS_BUFFER_TOO_SMALL; 19 | 20 | csp = (usb_cspkt_t *)hdr->u.cmd_submit.setup; 21 | 22 | set_cmd_submit_usbip_header(hdr, urbr->seq_num, urbr->ep->vusb->devid, USBIP_DIR_IN, NULL, 23 | USBD_SHORT_TRANSFER_OK, urb_status->TransferBufferLength); 24 | 25 | urbfunc = urb_status->Hdr.Function; 26 | TRD(READ, "urbr: %!URBR!", urbr); 27 | 28 | switch (urbfunc) { 29 | case URB_FUNCTION_GET_STATUS_FROM_DEVICE: 30 | recip = BMREQUEST_TO_DEVICE; 31 | break; 32 | case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: 33 | recip = BMREQUEST_TO_INTERFACE; 34 | break; 35 | case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: 36 | recip = BMREQUEST_TO_ENDPOINT; 37 | break; 38 | case URB_FUNCTION_GET_STATUS_FROM_OTHER: 39 | recip = BMREQUEST_TO_OTHER; 40 | break; 41 | default: 42 | TRW(READ, "unhandled urb function: %!URBFUNC!: len: %d", urbfunc, urb_status->Hdr.Length); 43 | return STATUS_INVALID_PARAMETER; 44 | } 45 | 46 | build_setup_packet(csp, USBIP_DIR_IN, BMREQUEST_STANDARD, recip, USB_REQUEST_GET_STATUS); 47 | 48 | csp->wLength = (unsigned short)urb_status->TransferBufferLength; 49 | csp->wIndex.W = urb_status->Index; 50 | csp->wValue.W = 0; 51 | 52 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header)); 53 | return STATUS_SUCCESS; 54 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_urbr_store_vendor.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_urbr_store_vendor.tmh" 3 | 4 | #include "usbip_proto.h" 5 | #include "vhci_urbr.h" 6 | 7 | NTSTATUS 8 | store_urbr_vendor_class_partial(WDFREQUEST req_read, purb_req_t urbr) 9 | { 10 | struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *urb_vendor_class = &urbr->u.urb.urb->UrbControlVendorClassRequest; 11 | PVOID dst; 12 | char *buf; 13 | 14 | dst = get_data_from_req_read(req_read, urb_vendor_class->TransferBufferLength); 15 | if (dst == NULL) 16 | return STATUS_BUFFER_TOO_SMALL; 17 | 18 | /* 19 | * reading from TransferBuffer or TransferBufferMDL, 20 | * whichever of them is not null 21 | */ 22 | buf = get_buf(urb_vendor_class->TransferBuffer, urb_vendor_class->TransferBufferMDL); 23 | if (buf == NULL) 24 | return STATUS_INSUFFICIENT_RESOURCES; 25 | 26 | RtlCopyMemory(dst, buf, urb_vendor_class->TransferBufferLength); 27 | WdfRequestSetInformation(req_read, urb_vendor_class->TransferBufferLength); 28 | urbr->ep->vusb->len_sent_partial = 0; 29 | 30 | return STATUS_SUCCESS; 31 | } 32 | 33 | NTSTATUS 34 | store_urbr_vendor_class(WDFREQUEST req_read, purb_req_t urbr) 35 | { 36 | struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *urb_vendor_class = &urbr->u.urb.urb->UrbControlVendorClassRequest; 37 | struct usbip_header *hdr; 38 | usb_cspkt_t *csp; 39 | char type, recip; 40 | int in = IS_TRANSFER_FLAGS_IN(urb_vendor_class->TransferFlags); 41 | 42 | hdr = get_hdr_from_req_read(req_read); 43 | if (hdr == NULL) 44 | return STATUS_BUFFER_TOO_SMALL; 45 | 46 | switch (urb_vendor_class->Hdr.Function) { 47 | case URB_FUNCTION_CLASS_DEVICE: 48 | type = BMREQUEST_CLASS; 49 | recip = BMREQUEST_TO_DEVICE; 50 | break; 51 | case URB_FUNCTION_CLASS_INTERFACE: 52 | type = BMREQUEST_CLASS; 53 | recip = BMREQUEST_TO_INTERFACE; 54 | break; 55 | case URB_FUNCTION_CLASS_ENDPOINT: 56 | type = BMREQUEST_CLASS; 57 | recip = BMREQUEST_TO_ENDPOINT; 58 | break; 59 | case URB_FUNCTION_CLASS_OTHER: 60 | type = BMREQUEST_CLASS; 61 | recip = BMREQUEST_TO_OTHER; 62 | break; 63 | case URB_FUNCTION_VENDOR_DEVICE: 64 | type = BMREQUEST_VENDOR; 65 | recip = BMREQUEST_TO_DEVICE; 66 | break; 67 | case URB_FUNCTION_VENDOR_INTERFACE: 68 | type = BMREQUEST_VENDOR; 69 | recip = BMREQUEST_TO_INTERFACE; 70 | break; 71 | case URB_FUNCTION_VENDOR_ENDPOINT: 72 | type = BMREQUEST_VENDOR; 73 | recip = BMREQUEST_TO_ENDPOINT; 74 | break; 75 | case URB_FUNCTION_VENDOR_OTHER: 76 | type = BMREQUEST_VENDOR; 77 | recip = BMREQUEST_TO_OTHER; 78 | break; 79 | default: 80 | return STATUS_INVALID_PARAMETER; 81 | } 82 | 83 | csp = (usb_cspkt_t *)hdr->u.cmd_submit.setup; 84 | 85 | set_cmd_submit_usbip_header(hdr, urbr->seq_num, urbr->ep->vusb->devid, in, NULL, 86 | urb_vendor_class->TransferFlags | USBD_SHORT_TRANSFER_OK, urb_vendor_class->TransferBufferLength); 87 | build_setup_packet(csp, (unsigned char)in, type, recip, urb_vendor_class->Request); 88 | //FIXME what is the usage of RequestTypeReservedBits? 89 | csp->wLength = (unsigned short)urb_vendor_class->TransferBufferLength; 90 | csp->wValue.W = urb_vendor_class->Value; 91 | csp->wIndex.W = urb_vendor_class->Index; 92 | 93 | if (!in) { 94 | if (get_read_payload_length(req_read) >= urb_vendor_class->TransferBufferLength) { 95 | RtlCopyMemory(hdr + 1, urb_vendor_class->TransferBuffer, urb_vendor_class->TransferBufferLength); 96 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header) + urb_vendor_class->TransferBufferLength); 97 | } 98 | else { 99 | WdfRequestSetInformation(req_read, sizeof(struct usbip_header)); 100 | urbr->ep->vusb->len_sent_partial = sizeof(struct usbip_header); 101 | } 102 | } 103 | return STATUS_SUCCESS; 104 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_vusb.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_vusb.tmh" 3 | 4 | pctx_vusb_t 5 | get_vusb(pctx_vhci_t vhci, ULONG port) 6 | { 7 | pctx_vusb_t vusb; 8 | 9 | WdfSpinLockAcquire(vhci->spin_lock); 10 | 11 | vusb = vhci->vusbs[port]; 12 | if (vusb == NULL || vusb->invalid) { 13 | WdfSpinLockRelease(vhci->spin_lock); 14 | return NULL; 15 | } 16 | vusb->refcnt++; 17 | 18 | WdfSpinLockRelease(vhci->spin_lock); 19 | 20 | return vusb; 21 | } 22 | 23 | pctx_vusb_t 24 | get_vusb_by_req(WDFREQUEST req) 25 | { 26 | pctx_safe_vusb_t svusb; 27 | 28 | svusb = TO_SAFE_VUSB_FROM_REQ(req); 29 | return get_vusb(svusb->vhci, svusb->port); 30 | } 31 | 32 | void 33 | put_vusb(pctx_vusb_t vusb) 34 | { 35 | pctx_vhci_t vhci = vusb->vhci; 36 | 37 | WdfSpinLockAcquire(vhci->spin_lock); 38 | 39 | ASSERT(vusb->refcnt > 0); 40 | vusb->refcnt--; 41 | if (vusb->refcnt == 0 && vusb->invalid) { 42 | NTSTATUS status; 43 | 44 | vhci->vusbs[vusb->port] = NULL; 45 | vhci->n_used_ports--; 46 | WdfSpinLockRelease(vhci->spin_lock); 47 | 48 | status = UdecxUsbDevicePlugOutAndDelete(vusb->ude_usbdev); 49 | if (NT_ERROR(status)) { 50 | TRD(VUSB, "failed to plug out: %!STATUS!", status); 51 | } 52 | } 53 | else { 54 | WdfSpinLockRelease(vhci->spin_lock); 55 | } 56 | } 57 | 58 | static VOID 59 | async_put_vusb(WDFWORKITEM workitem) 60 | { 61 | pctx_vusb_t vusb = *TO_PVUSB(workitem); 62 | 63 | TRD(VUSB, "async put vusb"); 64 | put_vusb(vusb); 65 | WdfObjectDelete(workitem); 66 | } 67 | 68 | void 69 | put_vusb_passively(pctx_vusb_t vusb) 70 | { 71 | WDFWORKITEM workitem; 72 | WDF_WORKITEM_CONFIG conf; 73 | WDF_OBJECT_ATTRIBUTES attrs; 74 | NTSTATUS status; 75 | 76 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attrs, pctx_vusb_t); 77 | attrs.ParentObject = vusb->ude_usbdev; 78 | WDF_WORKITEM_CONFIG_INIT(&conf, async_put_vusb); 79 | 80 | status = WdfWorkItemCreate(&conf, &attrs, &workitem); 81 | if (NT_ERROR(status)) { 82 | TRW(VUSB, "failed to create a workitem: %!STATUS!", status); 83 | } 84 | else { 85 | *TO_PVUSB(workitem) = vusb; 86 | WdfWorkItemEnqueue(workitem); 87 | } 88 | } -------------------------------------------------------------------------------- /usbip/usbip-win/driver/vhci_ude/vhci_write.c: -------------------------------------------------------------------------------- 1 | #include "vhci_driver.h" 2 | #include "vhci_write.tmh" 3 | 4 | #include "usbip_proto.h" 5 | #include "vhci_urbr.h" 6 | 7 | extern purb_req_t 8 | find_sent_urbr(pctx_vusb_t vusb, struct usbip_header *hdr); 9 | 10 | extern NTSTATUS 11 | fetch_urbr(purb_req_t urbr, struct usbip_header *hdr); 12 | 13 | static struct usbip_header * 14 | get_hdr_from_req_write(WDFREQUEST req_write) 15 | { 16 | struct usbip_header *hdr; 17 | size_t len; 18 | NTSTATUS status; 19 | 20 | status = WdfRequestRetrieveInputBuffer(req_write, sizeof(struct usbip_header), &hdr, &len); 21 | if (NT_ERROR(status)) { 22 | WdfRequestSetInformation(req_write, 0); 23 | return NULL; 24 | } 25 | 26 | WdfRequestSetInformation(req_write, len); 27 | return hdr; 28 | } 29 | 30 | static VOID 31 | write_vusb(pctx_vusb_t vusb, WDFREQUEST req_write) 32 | { 33 | struct usbip_header *hdr; 34 | purb_req_t urbr; 35 | NTSTATUS status; 36 | 37 | TRD(WRITE, "Enter"); 38 | 39 | hdr = get_hdr_from_req_write(req_write); 40 | if (hdr == NULL) { 41 | TRE(WRITE, "small write irp\n"); 42 | status = STATUS_INVALID_PARAMETER; 43 | goto out; 44 | } 45 | 46 | urbr = find_sent_urbr(vusb, hdr); 47 | if (urbr == NULL) { 48 | // Might have been cancelled before, so return STATUS_SUCCESS 49 | TRW(WRITE, "no urbr: seqnum: %d", hdr->base.seqnum); 50 | status = STATUS_SUCCESS; 51 | goto out; 52 | } 53 | 54 | status = fetch_urbr(urbr, hdr); 55 | 56 | WdfSpinLockAcquire(vusb->spin_lock); 57 | if (unmark_cancelable_urbr(urbr)) { 58 | WdfSpinLockRelease(vusb->spin_lock); 59 | complete_urbr(urbr, status); 60 | } 61 | else { 62 | WdfSpinLockRelease(vusb->spin_lock); 63 | } 64 | out: 65 | TRD(WRITE, "Leave: %!STATUS!", status); 66 | } 67 | 68 | VOID 69 | io_write(_In_ WDFQUEUE queue, _In_ WDFREQUEST req, _In_ size_t len) 70 | { 71 | pctx_vusb_t vusb; 72 | NTSTATUS status; 73 | 74 | UNREFERENCED_PARAMETER(queue); 75 | 76 | TRD(WRITE, "Enter: len: %u", (ULONG)len); 77 | 78 | vusb = get_vusb_by_req(req); 79 | if (vusb == NULL) { 80 | TRD(WRITE, "vusb disconnected: port: %u", TO_SAFE_VUSB_FROM_REQ(req)->port); 81 | status = STATUS_DEVICE_NOT_CONNECTED; 82 | } 83 | else { 84 | write_vusb(vusb, req); 85 | put_vusb(vusb); 86 | status = STATUS_SUCCESS; 87 | } 88 | 89 | WdfRequestCompleteWithInformation(req, status, len); 90 | 91 | TRD(WRITE, "Leave"); 92 | } 93 | -------------------------------------------------------------------------------- /usbip/usbip-win/include/namecode.h: -------------------------------------------------------------------------------- 1 | #define K_V(a) {#a, (unsigned int)a}, 2 | 3 | typedef struct namecode { 4 | const char *name; 5 | unsigned int code; 6 | } namecode_t; 7 | -------------------------------------------------------------------------------- /usbip/usbip-win/include/usbip_proto.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma pack(push,1) 4 | 5 | /* 6 | * USB/IP request headers. 7 | * Currently, we define 4 request types: 8 | * 9 | * - CMD_SUBMIT transfers a USB request, corresponding to usb_submit_urb(). 10 | * (client to server) 11 | * - RET_RETURN transfers the result of CMD_SUBMIT. 12 | * (server to client) 13 | * - CMD_UNLINK transfers an unlink request of a pending USB request. 14 | * (client to server) 15 | * - RET_UNLINK transfers the result of CMD_UNLINK. 16 | * (server to client) 17 | * 18 | * Note: The below request formats are based on the USB subsystem of Linux. Its 19 | * details will be defined when other implementations come. 20 | * 21 | * 22 | */ 23 | 24 | struct usbip_header_basic { 25 | #define USBIP_CMD_SUBMIT 0x0001 26 | #define USBIP_CMD_UNLINK 0x0002 27 | #define USBIP_RET_SUBMIT 0x0003 28 | #define USBIP_RET_UNLINK 0x0004 29 | #define USBIP_RESET_DEV 0xFFFF 30 | UINT32 command; 31 | 32 | /* sequencial number which identifies requests. 33 | * incremented per connections */ 34 | UINT32 seqnum; 35 | 36 | /* devid is used to specify a remote USB device uniquely instead 37 | * of busnum and devnum in Linux. In the case of Linux stub_driver, 38 | * this value is ((busnum << 16) | devnum) */ 39 | UINT32 devid; 40 | 41 | #define USBIP_DIR_OUT 0 42 | #define USBIP_DIR_IN 1 43 | UINT32 direction; 44 | UINT32 ep; /* endpoint number */ 45 | }; 46 | 47 | /* 48 | * An additional header for a CMD_SUBMIT packet. 49 | */ 50 | struct usbip_header_cmd_submit { 51 | /* these values are basically the same as in a URB. */ 52 | 53 | /* the same in a URB. */ 54 | UINT32 transfer_flags; 55 | 56 | /* set the following data size (out), 57 | * or expected reading data size (in) */ 58 | INT32 transfer_buffer_length; 59 | 60 | /* it is difficult for usbip to sync frames (reserved only?) */ 61 | INT32 start_frame; 62 | 63 | /* the number of iso descriptors that follows this header */ 64 | INT32 number_of_packets; 65 | 66 | /* the maximum time within which this request works in a host 67 | * controller of a server side */ 68 | INT32 interval; 69 | 70 | /* set setup packet data for a CTRL request */ 71 | UINT8 setup[8]; 72 | }; 73 | 74 | /* 75 | * An additional header for a RET_SUBMIT packet. 76 | */ 77 | struct usbip_header_ret_submit { 78 | INT32 status; 79 | INT32 actual_length; /* returned data length */ 80 | INT32 start_frame; /* ISO and INT */ 81 | INT32 number_of_packets; /* ISO only */ 82 | INT32 error_count; /* ISO only */ 83 | }; 84 | 85 | /* 86 | * An additional header for a CMD_UNLINK packet. 87 | */ 88 | struct usbip_header_cmd_unlink { 89 | UINT32 seqnum; /* URB's seqnum which will be unlinked */ 90 | }; 91 | 92 | /* 93 | * An additional header for a RET_UNLINK packet. 94 | */ 95 | struct usbip_header_ret_unlink { 96 | INT32 status; 97 | }; 98 | 99 | /* the same as usb_iso_packet_descriptor but packed for pdu */ 100 | struct usbip_iso_packet_descriptor { 101 | UINT32 offset; 102 | UINT32 length; /* expected length */ 103 | UINT32 actual_length; 104 | UINT32 status; 105 | }; 106 | 107 | /* 108 | * All usbip packets use a common header to keep code simple. 109 | */ 110 | struct usbip_header { 111 | struct usbip_header_basic base; 112 | 113 | union { 114 | struct usbip_header_cmd_submit cmd_submit; 115 | struct usbip_header_ret_submit ret_submit; 116 | struct usbip_header_cmd_unlink cmd_unlink; 117 | struct usbip_header_ret_unlink ret_unlink; 118 | } u; 119 | }; 120 | 121 | #pragma pack(pop) 122 | 123 | enum usb_device_speed { 124 | USB_SPEED_UNKNOWN = 0, /* enumerating */ 125 | USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ 126 | USB_SPEED_HIGH, /* usb 2.0 */ 127 | USB_SPEED_WIRELESS, /* wireless (usb 2.5) */ 128 | USB_SPEED_SUPER, /* usb 3.0 */ 129 | USB_SPEED_SUPER_PLUS /* usb 3.1 */ 130 | }; -------------------------------------------------------------------------------- /usbip/usbip-win/include/usbip_stub_api.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #ifdef _NTDDK_ 5 | #include 6 | #else 7 | #include 8 | #endif 9 | 10 | // {FB265267-C609-41E6-8ECA-A20D92A833E6} 11 | DEFINE_GUID(GUID_DEVINTERFACE_STUB_USBIP, 12 | 0xfb265267, 0xc609, 0x41e6, 0x8e, 0xca, 0xa2, 0xd, 0x92, 0xa8, 0x33, 0xe6); 13 | 14 | #define USBIP_STUB_IOCTL(_index_) \ 15 | CTL_CODE(FILE_DEVICE_UNKNOWN, _index_, METHOD_BUFFERED, FILE_READ_DATA) 16 | 17 | #define IOCTL_USBIP_STUB_GET_DEVINFO USBIP_STUB_IOCTL(0x0) 18 | #define IOCTL_USBIP_STUB_EXPORT USBIP_STUB_IOCTL(0x1) 19 | 20 | #pragma pack(push,1) 21 | 22 | typedef struct _ioctl_usbip_stub_devinfo 23 | { 24 | unsigned short vendor; 25 | unsigned short product; 26 | unsigned char speed; 27 | unsigned char class; 28 | unsigned char subclass; 29 | unsigned char protocol; 30 | } ioctl_usbip_stub_devinfo_t; 31 | 32 | #pragma pack(pop) -------------------------------------------------------------------------------- /usbip/usbip-win/include/usbip_vhci_api.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #ifdef _NTDDK_ 5 | #include 6 | #else 7 | #include 8 | #endif 9 | 10 | // 11 | // Define an Interface Guid for bus vhci class. 12 | // This GUID is used to register (IoRegisterDeviceInterface) 13 | // an instance of an interface so that vhci application 14 | // can send an ioctl to the bus driver. 15 | // 16 | 17 | DEFINE_GUID(GUID_DEVINTERFACE_VHCI_USBIP, 18 | 0xD35F7840, 0x6A0C, 0x11d2, 0xB8, 0x41, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71); 19 | 20 | 21 | // 22 | // Define a Setup Class GUID for USBIP Class. This is same 23 | // as the TOASTSER CLASS guid in the INF files. 24 | // 25 | DEFINE_GUID(GUID_DEVCLASS_USBIP, 26 | 0xB85B7C50, 0x6A01, 0x11d2, 0xB8, 0x41, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71); 27 | //{B85B7C50-6A01-11d2-B841-00C04FAD5171} 28 | 29 | // 30 | // Define a WMI GUID to get vhci info. 31 | // 32 | DEFINE_GUID(USBIP_BUS_WMI_STD_DATA_GUID, 33 | 0x0006A660, 0x8F12, 0x11d2, 0xB8, 0x54, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71); 34 | //{0006A660-8F12-11d2-B854-00C04FAD5171} 35 | 36 | // 37 | // Define a WMI GUID to get USBIP device info. 38 | // 39 | DEFINE_GUID(USBIP_WMI_STD_DATA_GUID, 40 | 0xBBA21300, 0x6DD3, 0x11d2, 0xB8, 0x44, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71); 41 | //{BBA21300-6DD3-11d2-B844-00C04FAD5171} 42 | 43 | // 44 | // Define a WMI GUID to represent device arrival notification WMIEvent class. 45 | // 46 | DEFINE_GUID(USBIP_NOTIFY_DEVICE_ARRIVAL_EVENT, 47 | 0x01CDAFF1, 0xC901, 0x45B4, 0xB3, 0x59, 0xB5, 0x54, 0x27, 0x25, 0xE2, 0x9C); 48 | // {01CDAFF1-C901-45B4-B359-B5542725E29C} 49 | 50 | #define USBIP_VHCI_IOCTL(_index_) \ 51 | CTL_CODE(FILE_DEVICE_BUS_EXTENDER, _index_, METHOD_BUFFERED, FILE_READ_DATA) 52 | 53 | #define IOCTL_USBIP_VHCI_PLUGIN_HARDWARE USBIP_VHCI_IOCTL(0x0) 54 | #define IOCTL_USBIP_VHCI_UNPLUG_HARDWARE USBIP_VHCI_IOCTL(0x1) 55 | /* used by attacher */ 56 | #define IOCTL_USBIP_VHCI_SHUTDOWN_HARDWARE USBIP_VHCI_IOCTL(0x2) 57 | #define IOCTL_USBIP_VHCI_GET_PORTS_STATUS USBIP_VHCI_IOCTL(0x3) 58 | #define IOCTL_USBIP_VHCI_GET_IMPORTED_DEVICES USBIP_VHCI_IOCTL(0x4) 59 | 60 | #define MAX_VHCI_SERIAL_ID 127 61 | 62 | typedef struct _vhci_pluginfo 63 | { 64 | /* vhci_pluginfo_t structure size */ 65 | unsigned long size; 66 | unsigned int devid; 67 | signed char port; 68 | wchar_t wserial[MAX_VHCI_SERIAL_ID + 1]; 69 | unsigned char dscr_dev[18]; 70 | /* variable length. It's a full-length configuration descriptor */ 71 | unsigned char dscr_conf[9]; 72 | } vhci_pluginfo_t, *pvhci_pluginfo_t; 73 | 74 | /* usbip-win assumes max port is 127 */ 75 | typedef struct _ioctl_usbip_vhci_get_ports_status 76 | { 77 | /* maximum number of ports */ 78 | unsigned char n_max_ports; 79 | unsigned char port_status[127]; 80 | } ioctl_usbip_vhci_get_ports_status; 81 | 82 | typedef struct _ioctl_usbip_vhci_unplug 83 | { 84 | signed char addr; 85 | char unused[3]; 86 | } ioctl_usbip_vhci_unplug, *pvhci_unpluginfo_t; 87 | 88 | typedef struct usbip_imported_device { 89 | char port; 90 | enum usbip_device_status status; 91 | unsigned short vendor; 92 | unsigned short product; 93 | unsigned char speed; 94 | } ioctl_usbip_vhci_imported_dev, *pioctl_usbip_vhci_imported_dev_t; 95 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/config.h: -------------------------------------------------------------------------------- 1 | /* Preconfigured version of config.h for Windows */ 2 | #ifndef _USBIP_CONFIG_WINDOWS_H 3 | #define _USBIP_CONFIG_WINDOWS_H 4 | 5 | /* Define to the full name and version of this package. */ 6 | #define PACKAGE_STRING "usbip-win 0.3.5" 7 | 8 | /* numeric version number */ 9 | #define USBIP_VERSION 0x000111 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/doc/usbip.8: -------------------------------------------------------------------------------- 1 | .TH USBIP "8" "February 2009" "usbip" "System Administration Utilities" 2 | .SH NAME 3 | usbip \- manage USB/IP devices 4 | .SH SYNOPSIS 5 | .B usbip 6 | [\fIoptions\fR] 7 | 8 | .SH DESCRIPTION 9 | Devices exported by USB/IP servers can be listed, attached and 10 | detached using this program. 11 | 12 | .SH OPTIONS 13 | .HP 14 | \fB\-a\fR, \fB\-\-attach\fR 15 | .IP 16 | Attach a remote USB device. 17 | .PP 18 | 19 | .HP 20 | \fB\-x\fR, \fB\-\-attachall\fR 21 | .IP 22 | Attach all remote USB devices on the specific host. 23 | .PP 24 | 25 | .HP 26 | \fB\-d\fR, \fB\-\-detach\fR 27 | .IP 28 | Detach an imported USB device. 29 | .PP 30 | 31 | .HP 32 | \fB\-l\fR, \fB\-\-list\fR 33 | .IP 34 | List exported USB devices. 35 | .PP 36 | 37 | .HP 38 | \fB\-p\fR, \fB\-\-port\fR 39 | .IP 40 | List virtual USB port status. 41 | .PP 42 | 43 | .HP 44 | \fB\-D\fR, \fB\-\-debug\fR 45 | .IP 46 | Print debugging information. 47 | .PP 48 | 49 | .HP 50 | \fB\-v\fR, \fB\-\-version\fR 51 | .IP 52 | Show version. 53 | .PP 54 | 55 | .SH EXAMPLES 56 | 57 | client:# usbip --list server 58 | - List exportable usb devices on the server. 59 | 60 | client:# usbip --attach server 1-2 61 | - Connect the remote USB device. 62 | 63 | client:# usbip --port 64 | - Show virtual port status. 65 | 66 | client:# usbip --detach 0 67 | - Detach the usb device. 68 | 69 | .SH "SEE ALSO" 70 | \fBusbipd\fP\fB(8)\fB\fP, 71 | \fBusbip_attach_driver\fP\fB(8)\fB\fP 72 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/doc/usbip_bind_driver.8: -------------------------------------------------------------------------------- 1 | .TH USBIP_BIND_DRIVER "8" "February 2009" "usbip" "System Administration Utilities" 2 | .SH NAME 3 | usbip_bind_driver \- change driver binding for USB/IP 4 | 5 | .SH SYNOPSIS 6 | .B usbip_bind_driver 7 | [\fIoptions\fR] 8 | 9 | .SH DESCRIPTION 10 | Driver bindings for USB devices can be changed using 11 | this program. It is used to export and unexport USB 12 | devices over USB/IP. 13 | 14 | .SH OPTIONS 15 | .TP 16 | \fB\-u\fR, \fB\-\-usbip\fR 17 | Make a device exportable 18 | .TP 19 | \fB\-o\fR, \fB\-\-other\fR 20 | Use a device by a local driver 21 | .TP 22 | \fB\-l\fR, \fB\-\-list\fR 23 | Print usb devices and their drivers 24 | .TP 25 | \fB\-L\fR, \fB\-\-list2\fR 26 | Print usb devices and their drivers in parseable mode 27 | 28 | .SH EXAMPLES 29 | 30 | server:# usbip_bind_driver --list 31 | - List driver assignments for usb devices. 32 | 33 | server:# usbip_bind_driver --usbip 1-2 34 | - Bind usbip-host.ko to the device of busid 1-2. 35 | - A usb device 1-2 is now exportable to other hosts! 36 | 37 | server:# usbip_bind_driver --other 1-2 38 | - Shutdown exporting and use the device locally. 39 | 40 | .SH "SEE ALSO" 41 | \fBusbip\fP\fB(8)\fB\fP, 42 | \fBusbipd\fP\fB(8)\fB\fP 43 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/doc/usbipd.8: -------------------------------------------------------------------------------- 1 | .TH USBIP "8" "February 2009" "usbip" "System Administration Utilities" 2 | .SH NAME 3 | usbipd \- USB/IP server daemon 4 | .SH SYNOPSIS 5 | .B usbipd 6 | [\fIoptions\fR] 7 | 8 | .SH DESCRIPTION 9 | .B usbipd 10 | provides USB/IP clients access to exported USB devices. 11 | 12 | Devices have to explicitly be exported using 13 | .B usbip_bind_driver 14 | before usbipd makes them available to other hosts. 15 | 16 | The daemon accepts connections from USB/IP clients 17 | on TCP port 3240. 18 | 19 | .SH OPTIONS 20 | .HP 21 | \fB\-D\fR, \fB\-\-daemon\fR 22 | .IP 23 | Run as a daemon process. 24 | .PP 25 | 26 | .HP 27 | \fB\-d\fR, \fB\-\-debug\fR 28 | .IP 29 | Print debugging information. 30 | .PP 31 | 32 | .HP 33 | \fB\-v\fR, \fB\-\-version\fR 34 | .IP 35 | Show version. 36 | .PP 37 | 38 | .SH LIMITATIONS 39 | 40 | .B usbipd 41 | offers no authentication or authorization for USB/IP. Any 42 | USB/IP client can connect and use exported devices. 43 | 44 | .SH EXAMPLES 45 | 46 | server:# modprobe usbip 47 | 48 | server:# usbipd -D 49 | - Start usbip daemon. 50 | 51 | server:# usbip_bind_driver --list 52 | - List driver assignments for usb devices. 53 | 54 | server:# usbip_bind_driver --usbip 1-2 55 | - Bind usbip-host.ko to the device of busid 1-2. 56 | - A usb device 1-2 is now exportable to other hosts! 57 | - Use 'usbip_bind_driver --other 1-2' when you want to shutdown exporting and use the device locally. 58 | 59 | .SH "SEE ALSO" 60 | \fBusbip\fP\fB(8)\fB\fP, 61 | \fBusbip_attach_driver\fP\fB(8)\fB\fP 62 | 63 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/cscope.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/usbip-win/userspace/lib/cscope.out -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/dbgcode.c: -------------------------------------------------------------------------------- 1 | #include "namecode.h" 2 | 3 | #include "usbip_common.h" 4 | 5 | static namecode_t namecodes_op_code_status[] = { 6 | K_V(ST_OK) 7 | K_V(ST_NA) 8 | K_V(ST_DEV_BUSY) 9 | K_V(ST_DEV_ERR) 10 | K_V(ST_NODEV) 11 | K_V(ST_ERROR) 12 | {0,0} 13 | }; 14 | 15 | static namecode_t namecodes_err[] = { 16 | K_V(ERR_GENERAL) 17 | K_V(ERR_INVARG) 18 | K_V(ERR_NETWORK) 19 | K_V(ERR_VERSION) 20 | K_V(ERR_PROTOCOL) 21 | K_V(ERR_STATUS) 22 | K_V(ERR_EXIST) 23 | K_V(ERR_NOTEXIST) 24 | K_V(ERR_DRIVER) 25 | K_V(ERR_PORTFULL) 26 | K_V(ERR_ACCESS) 27 | {0,0} 28 | }; 29 | 30 | static const char * 31 | dbg_namecode(char *buf, int buf_max, namecode_t *namecodes, const char *codetype, int code) 32 | { 33 | int i; 34 | 35 | for (i = 0; namecodes[i].name; i++) { 36 | if (code == namecodes[i].code) { 37 | snprintf(buf, buf_max, "%s", namecodes[i].name); 38 | return buf; 39 | } 40 | } 41 | 42 | snprintf(buf, buf_max, "Unknown %s code: %x", codetype, code); 43 | return buf; 44 | } 45 | 46 | const char * 47 | dbg_opcode_status(int status) 48 | { 49 | static char buf[128]; 50 | 51 | return dbg_namecode(buf, 128, namecodes_op_code_status, "op_code_status", status); 52 | } 53 | 54 | const char * 55 | dbg_errcode(int err) 56 | { 57 | static char buf[128]; 58 | 59 | return dbg_namecode(buf, 128, namecodes_err, "err code", err); 60 | } 61 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/dbgcode.h: -------------------------------------------------------------------------------- 1 | #pragma 2 | 3 | extern const char * 4 | dbg_opcode_status(int status); 5 | 6 | extern const char * 7 | dbg_errcode(int err); 8 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/getopt.c: -------------------------------------------------------------------------------- 1 | /* 2 | Newsgroups: mod.std.unix 3 | Subject: public domain AT&T getopt source 4 | Date: 3 Nov 85 19:34:15 GMT 5 | 6 | Here's something you've all been waiting for: the AT&T public domain 7 | source for getopt(3). It is the code which was given out at the 1985 8 | UNIFORUM conference in Dallas. I obtained it by electronic mail 9 | directly from AT&T. The people there assure me that it is indeed 10 | in the public domain. 11 | */ 12 | 13 | /*LINTLIBRARY*/ 14 | 15 | #include 16 | 17 | extern int write(); 18 | 19 | //#define NULL 0 20 | #define EOF (-1) 21 | #define ERR(s, c) if(opterr){\ 22 | char errbuf[2];\ 23 | errbuf[0] = c; errbuf[1] = '\n';\ 24 | (void) write(2, argv[0], (unsigned)strlen(argv[0]));\ 25 | (void) write(2, s, (unsigned)strlen(s));\ 26 | (void) write(2, errbuf, 2);} 27 | 28 | 29 | int opterr = 1; 30 | int optind = 1; 31 | int optopt; 32 | char *optarg; 33 | 34 | int 35 | getopt(argc, argv, opts) 36 | int argc; 37 | char **argv, *opts; 38 | { 39 | static int sp = 1; 40 | register int c; 41 | register char *cp; 42 | 43 | if(sp == 1) 44 | if(optind >= argc || 45 | argv[optind][0] != '-' || argv[optind][1] == '\0') 46 | return(EOF); 47 | else if(strcmp(argv[optind], "--") == 0) { 48 | optind++; 49 | return(EOF); 50 | } 51 | optopt = c = argv[optind][sp]; 52 | if(c == ':' || (cp=strchr(opts, c)) == NULL) { 53 | ERR(": illegal option -- ", c); 54 | if(argv[optind][++sp] == '\0') { 55 | optind++; 56 | sp = 1; 57 | } 58 | return('?'); 59 | } 60 | if(*++cp == ':') { 61 | if(argv[optind][sp+1] != '\0') 62 | optarg = &argv[optind++][sp+1]; 63 | else if(++optind >= argc) { 64 | ERR(": option requires an argument -- ", c); 65 | sp = 1; 66 | return('?'); 67 | } else 68 | optarg = argv[optind++]; 69 | sp = 1; 70 | } else { 71 | if(argv[optind][++sp] == '\0') { 72 | sp = 1; 73 | optind++; 74 | } 75 | optarg = NULL; 76 | } 77 | return(c); 78 | } 79 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/getopt.h: -------------------------------------------------------------------------------- 1 | /* libext+gcc: getopt.h - $Id: getopt.h,v 1.1 2003/03/13 23:18:17 neis Exp $*/ 2 | 3 | /*- 4 | * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to The NetBSD Foundation 8 | * by Dieter Baron and Thomas Klausner. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. All advertising materials mentioning features or use of this software 19 | * must display the following acknowledgement: 20 | * This product includes software developed by the NetBSD 21 | * Foundation, Inc. and its contributors. 22 | * 4. Neither the name of The NetBSD Foundation nor the names of its 23 | * contributors may be used to endorse or promote products derived 24 | * from this software without specific prior written permission. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | * POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | #ifndef _GETOPT_H_ 40 | #define _GETOPT_H_ 41 | 42 | //#include 43 | 44 | /* 45 | * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions 46 | */ 47 | #define no_argument 0 48 | #define required_argument 1 49 | #define optional_argument 2 50 | 51 | struct option { 52 | /* name of long option */ 53 | const char *name; 54 | /* 55 | * one of no_argument, required_argument, and optional_argument: 56 | * whether option takes an argument 57 | */ 58 | int has_arg; 59 | /* if not NULL, set *flag to val when option found */ 60 | int *flag; 61 | /* if flag not NULL, value to set *flag to; else return value */ 62 | int val; 63 | }; 64 | 65 | int getopt_long(int, char * const *, const char *, 66 | const struct option *, int *); 67 | int getopt_long_only(int, char * const *, const char *, 68 | const struct option *, int *); 69 | #ifndef _GETOPT_DEFINED_ 70 | #define _GETOPT_DEFINED_ 71 | int getopt(int, char * const *, const char *); 72 | int getsubopt(char **, char * const *, char **); 73 | 74 | extern char *optarg; /* getopt(3) external variables */ 75 | extern int opterr; 76 | extern int optind; 77 | extern int optopt; 78 | extern int optreset; 79 | extern char *suboptarg; /* getsubopt(3) external variable */ 80 | #endif 81 | 82 | #endif /* !_GETOPT_H_ */ 83 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/list.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIST_H 2 | #define _LIST_H 3 | 4 | /* Stripped down implementation of linked list taken 5 | * from the Linux Kernel. 6 | */ 7 | 8 | /* 9 | * Simple doubly linked list implementation. 10 | * 11 | * Some of the internal functions ("__xxx") are useful when 12 | * manipulating whole lists rather than single entries, as 13 | * sometimes we already know the next/prev entries and we can 14 | * generate better code by using them directly rather than 15 | * using the generic single-entry routines. 16 | */ 17 | 18 | struct list_head { 19 | struct list_head *next, *prev; 20 | }; 21 | 22 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 23 | 24 | #define LIST_HEAD(name) \ 25 | struct list_head name = LIST_HEAD_INIT(name) 26 | 27 | static inline void INIT_LIST_HEAD(struct list_head *list) 28 | { 29 | list->next = list; 30 | list->prev = list; 31 | } 32 | 33 | /* 34 | * Insert a new entry between two known consecutive entries. 35 | * 36 | * This is only for internal list manipulation where we know 37 | * the prev/next entries already! 38 | */ 39 | static inline void __list_add(struct list_head *new_entry, 40 | struct list_head *prev, 41 | struct list_head *next) 42 | { 43 | next->prev = new_entry; 44 | new_entry->next = next; 45 | new_entry->prev = prev; 46 | prev->next = new_entry; 47 | } 48 | 49 | /** 50 | * list_add - add a new entry 51 | * @new: new entry to be added 52 | * @head: list head to add it after 53 | * 54 | * Insert a new entry after the specified head. 55 | * This is good for implementing stacks. 56 | */ 57 | static inline void list_add(struct list_head *new_entry, struct list_head *head) 58 | { 59 | __list_add(new_entry, head, head->next); 60 | } 61 | 62 | /* 63 | * Delete a list entry by making the prev/next entries 64 | * point to each other. 65 | * 66 | * This is only for internal list manipulation where we know 67 | * the prev/next entries already! 68 | */ 69 | static inline void __list_del(struct list_head * prev, struct list_head * next) 70 | { 71 | next->prev = prev; 72 | prev->next = next; 73 | } 74 | 75 | #define LIST_POISON1 ((struct list_head *)0x00100100) 76 | #define LIST_POISON2 ((struct list_head *)0x00200200) 77 | 78 | /** 79 | * list_del - deletes entry from list. 80 | * @entry: the element to delete from the list. 81 | * Note: list_empty() on entry does not return true after this, the entry is 82 | * in an undefined state. 83 | */ 84 | static inline void __list_del_entry(struct list_head *entry) 85 | { 86 | __list_del(entry->prev, entry->next); 87 | } 88 | 89 | static inline void list_del(struct list_head *entry) 90 | { 91 | __list_del(entry->prev, entry->next); 92 | entry->next = LIST_POISON1; 93 | entry->prev = LIST_POISON2; 94 | } 95 | 96 | /** 97 | * list_entry - get the struct for this entry 98 | * @ptr: the &struct list_head pointer. 99 | * @type: the type of the struct this is embedded in. 100 | * @member: the name of the list_head within the struct. 101 | */ 102 | #define list_entry(ptr, type, member) \ 103 | ((type *)((char *)(ptr)-(unsigned long)((char *)&((type *)0)->member - (char *)0))) 104 | 105 | /** 106 | * list_for_each - iterate over a list 107 | * @pos: the &struct list_head to use as a loop cursor. 108 | * @head: the head for your list. 109 | */ 110 | #define list_for_each(pos, head) \ 111 | for (pos = (head)->next; pos != (head); pos = pos->next) 112 | 113 | /** 114 | * list_for_each_safe - iterate over a list safe against removal of list entry 115 | * @pos: the &struct list_head to use as a loop cursor. 116 | * @n: another &struct list_head to use as temporary storage 117 | * @head: the head for your list. 118 | */ 119 | #define list_for_each_safe(pos, n, head) \ 120 | for (pos = (head)->next, n = pos->next; pos != (head); \ 121 | pos = n, n = pos->next) 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/names.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | 3 | /* 4 | * names.h -- USB name database manipulation routines 5 | * 6 | * Copyright (C) 1999, 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 | * 22 | * 23 | */ 24 | 25 | /* 26 | * Copyright (C) 2005 Takahiro Hirofuchi 27 | * - names_free() is added. 28 | */ 29 | 30 | /*****************************************************************************/ 31 | 32 | #ifndef _NAMES_H 33 | #define _NAMES_H 34 | 35 | #include 36 | 37 | /* used by usbip_common.c */ 38 | extern const char *names_vendor(uint16_t vendorid); 39 | extern const char *names_product(uint16_t vendorid, uint16_t productid); 40 | extern const char *names_class(uint8_t classid); 41 | extern const char *names_subclass(uint8_t classid, uint8_t subclassid); 42 | extern const char *names_protocol(uint8_t classid, uint8_t subclassid, uint8_t protocolid); 43 | 44 | extern int names_init(const char *path); 45 | extern void names_free(void); 46 | 47 | #endif /* _NAMES_H */ 48 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/usbip_forward.h: -------------------------------------------------------------------------------- 1 | #pragma 2 | 3 | #include 4 | 5 | void usbip_forward(HANDLE hdev_src, HANDLE hdev_dst, BOOL inbound); -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/usbip_setupdi.h: -------------------------------------------------------------------------------- 1 | #pragma 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | #include 6 | 7 | typedef unsigned char devno_t; 8 | 9 | typedef int (*walkfunc_t)(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data, devno_t devno, void *ctx); 10 | 11 | int traverse_usbdevs(walkfunc_t walker, BOOL present_only, void *ctx); 12 | int traverse_intfdevs(walkfunc_t walker, LPCGUID pguid, void *ctx); 13 | 14 | char *get_id_hw(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data); 15 | char *get_upper_filters(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data); 16 | char *get_id_inst(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data); 17 | PSP_DEVICE_INTERFACE_DETAIL_DATA get_intf_detail(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data, LPCGUID pguid); 18 | 19 | devno_t get_devno_from_busid(const char *busid); 20 | 21 | BOOL get_usbdev_info(const char *id_hw, unsigned short *pvendor, unsigned short *pproduct); 22 | BOOL set_device_state(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data, DWORD state); 23 | BOOL restart_device(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data); 24 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/usbip_stub.h: -------------------------------------------------------------------------------- 1 | #pragma 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | #include 6 | 7 | #include "usbip_setupdi.h" 8 | 9 | #define STUB_DRIVER_SVCNAME "usbip_stub" 10 | 11 | BOOL is_service_usbip_stub(HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data); 12 | 13 | int attach_stub_driver(devno_t devno); 14 | int detach_stub_driver(devno_t devno); -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/usbip_util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | wchar_t * 7 | utf8_to_wchar(const char *str) 8 | { 9 | wchar_t *wstr; 10 | int size; 11 | 12 | size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); 13 | if (size <= 1) 14 | return NULL; 15 | 16 | if ((wstr = (wchar_t *)calloc(size, sizeof(wchar_t))) == NULL) 17 | return NULL; 18 | if (MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, size) != size) { 19 | free(wstr); 20 | return NULL; 21 | } 22 | return wstr; 23 | } 24 | 25 | int 26 | vasprintf(char **strp, const char *fmt, va_list ap) 27 | { 28 | size_t size; 29 | char *str; 30 | int ret; 31 | 32 | int len = _vscprintf(fmt, ap); 33 | if (len == -1) { 34 | return -1; 35 | } 36 | size = (size_t)len + 1; 37 | str = malloc(size); 38 | if (!str) { 39 | return -1; 40 | } 41 | ret = vsprintf_s(str, len + 1, fmt, ap); 42 | if (ret == -1) { 43 | free(str); 44 | return -1; 45 | } 46 | *strp = str; 47 | return ret; 48 | } 49 | 50 | int 51 | asprintf(char **strp, const char *fmt, ...) 52 | { 53 | va_list ap; 54 | int ret; 55 | 56 | va_start(ap, fmt); 57 | ret = vasprintf(strp, fmt, ap); 58 | va_end(ap); 59 | return ret; 60 | } 61 | 62 | char * 63 | get_module_dir(void) 64 | { 65 | DWORD size = 1024; 66 | 67 | while (TRUE) { 68 | char *path_mod; 69 | 70 | path_mod = (char *)malloc(size); 71 | if (path_mod == NULL) 72 | return NULL; 73 | if (GetModuleFileName(NULL, path_mod, size) == size) { 74 | free(path_mod); 75 | if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 76 | return NULL; 77 | size += 1024; 78 | } 79 | else { 80 | char *last_sep; 81 | last_sep = strrchr(path_mod, '\\'); 82 | if (last_sep != NULL) 83 | *last_sep = '\0'; 84 | return path_mod; 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/usbip_util.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | wchar_t *utf8_to_wchar(const char *str); 4 | 5 | int vasprintf(char **strp, const char *fmt, va_list ap); 6 | int asprintf(char **strp, const char *fmt, ...); 7 | char *get_module_dir(void); -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/usbip_windows.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2005-2007 Takahiro Hirofuchi 4 | */ 5 | 6 | #include 7 | 8 | #include "usbip_windows.h" 9 | 10 | #include "usbip_common.h" 11 | 12 | int init_socket(void) 13 | { 14 | WSADATA wsaData; 15 | int err; 16 | 17 | err = WSAStartup(MAKEWORD(2, 2), &wsaData); 18 | if (err != 0) { 19 | dbg("WSAStartup failed: error: 0x%lx", err); 20 | return -1; 21 | } 22 | 23 | if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { 24 | dbg("cannot find a winsock 2.2 version"); 25 | WSACleanup(); 26 | return -1; 27 | } 28 | return 0; 29 | } 30 | 31 | int cleanup_socket(void) 32 | { 33 | WSACleanup(); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/lib/usbip_windows.h: -------------------------------------------------------------------------------- 1 | #pragma 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | 6 | #include "getopt.h" 7 | 8 | int init_socket(void); 9 | int cleanup_socket(void); 10 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/attacher/attacher.c: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #include 3 | 4 | #include "usbip_forward.h" 5 | #include "usbip_vhci_api.h" 6 | 7 | static HANDLE 8 | read_handle_value(HANDLE hStdin) 9 | { 10 | HANDLE handle; 11 | LPBYTE buf = (LPBYTE)&handle; 12 | DWORD buflen = sizeof(HANDLE); 13 | 14 | while (buflen > 0) { 15 | DWORD nread; 16 | 17 | if (!ReadFile(hStdin, buf + sizeof(HANDLE) - buflen, buflen, &nread, NULL)) { 18 | return INVALID_HANDLE_VALUE; 19 | } 20 | if (nread == 0) 21 | return INVALID_HANDLE_VALUE; 22 | buflen -= nread; 23 | } 24 | return handle; 25 | } 26 | 27 | static void 28 | shutdown_device(HANDLE hdev) 29 | { 30 | unsigned long unused; 31 | 32 | DeviceIoControl(hdev, IOCTL_USBIP_VHCI_SHUTDOWN_HARDWARE, NULL, 0, NULL, 0, &unused, NULL); 33 | } 34 | 35 | static BOOL 36 | setup_forwarder(void) 37 | { 38 | HANDLE hdev, sockfd; 39 | HANDLE hStdin, hStdout; 40 | 41 | hStdin = GetStdHandle(STD_INPUT_HANDLE); 42 | hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 43 | 44 | hdev = read_handle_value(hStdin); 45 | sockfd = read_handle_value(hStdin); 46 | 47 | usbip_forward(hdev, sockfd, FALSE); 48 | shutdown_device(hdev); 49 | 50 | CloseHandle(sockfd); 51 | CloseHandle(hdev); 52 | 53 | CloseHandle(hStdin); 54 | CloseHandle(hStdout); 55 | 56 | return TRUE; 57 | } 58 | 59 | int APIENTRY 60 | wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, 61 | _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) 62 | { 63 | UNREFERENCED_PARAMETER(hPrevInstance); 64 | UNREFERENCED_PARAMETER(lpCmdLine); 65 | 66 | if (!setup_forwarder()) 67 | return 1; 68 | 69 | return 0; 70 | } -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/attacher/attacher.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/usbip-win/userspace/src/attacher/attacher.rc -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #ifndef __USBIP_H 20 | #define __USBIP_H 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include "../config.h" 24 | #endif 25 | 26 | /* usbip commands */ 27 | int usbip_attach(int argc, char *argv[]); 28 | int usbip_detach(int argc, char *argv[]); 29 | int usbip_list(int argc, char *argv[]); 30 | int usbip_bind(int argc, char *argv[]); 31 | int usbip_unbind(int argc, char *argv[]); 32 | int usbip_install(int argc, char* argv[]); 33 | int usbip_uninstall(int argc, char *argv[]); 34 | int usbip_port_show(int argc, char* argv[]); 35 | 36 | void usbip_attach_usage(void); 37 | void usbip_detach_usage(void); 38 | void usbip_list_usage(void); 39 | void usbip_bind_usage(void); 40 | void usbip_unbind_usage(void); 41 | void usbip_install_usage(void); 42 | void usbip_uninstall_usage(void); 43 | void usbip_port_usage(void); 44 | 45 | #endif /* __USBIP_H */ 46 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/usbip-win/userspace/src/usbip/usbip.rc -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip_bind.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "usbip_windows.h" 20 | 21 | #include "usbip_common.h" 22 | #include "usbip_setupdi.h" 23 | #include "usbip_stub.h" 24 | 25 | static const char usbip_bind_usage_string[] = 26 | "usbip bind \n" 27 | " -b, --busid= Bind usbip stub to device " 28 | "on \n"; 29 | 30 | void usbip_bind_usage(void) 31 | { 32 | printf("usage: %s", usbip_bind_usage_string); 33 | } 34 | 35 | static int 36 | walker_bind(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data, devno_t devno, void *ctx) 37 | { 38 | devno_t *pdevno = (devno_t *)ctx; 39 | 40 | if (devno == *pdevno) { 41 | int ret; 42 | 43 | ret = attach_stub_driver(devno); 44 | if (ret == 0) { 45 | if (!restart_device(dev_info, pdev_info_data)) 46 | return ERR_DRIVER; 47 | return 1; 48 | } 49 | return ret; 50 | } 51 | return 0; 52 | } 53 | 54 | static int 55 | bind_device(const char *busid) 56 | { 57 | unsigned char devno; 58 | int rc; 59 | 60 | devno = get_devno_from_busid(busid); 61 | if (devno == 0) { 62 | err("invalid bus id: %s", busid); 63 | return 1; 64 | } 65 | rc = traverse_usbdevs(walker_bind, TRUE, (void *)&devno); 66 | if (rc != 1) { 67 | switch (rc) { 68 | case 0: 69 | case ERR_NOTEXIST: 70 | err("no such device on busid %s", busid); 71 | return 2; 72 | case ERR_CERTIFICATE: 73 | err("\"USBIP Test\" certficiate not installed or properly located in certificate store"); 74 | return 2; 75 | default: 76 | err("failed to bind device on busid %s", busid); 77 | return 3; 78 | } 79 | } 80 | info("bind device on busid %s: complete", busid); 81 | return 0; 82 | } 83 | 84 | int usbip_bind(int argc, char *argv[]) 85 | { 86 | static const struct option opts[] = { 87 | { "busid", required_argument, NULL, 'b' }, 88 | { NULL, 0, NULL, 0 } 89 | }; 90 | 91 | int opt; 92 | 93 | for (;;) { 94 | opt = getopt_long(argc, argv, "b:", opts, NULL); 95 | 96 | if (opt == -1) 97 | break; 98 | 99 | switch (opt) { 100 | case 'b': 101 | return bind_device(optarg); 102 | default: 103 | break; 104 | } 105 | } 106 | 107 | err("empty busid"); 108 | usbip_bind_usage(); 109 | return 1; 110 | } 111 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip_detach.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "usbip_windows.h" 20 | 21 | #include "usbip_common.h" 22 | #include "usbip_vhci.h" 23 | 24 | static const char usbip_detach_usage_string[] = 25 | "usbip detach \n" 26 | " -p, --port= " 27 | " port the device is on\n"; 28 | 29 | void usbip_detach_usage(void) 30 | { 31 | printf("usage: %s", usbip_detach_usage_string); 32 | } 33 | 34 | static int detach_port(const char *portstr) 35 | { 36 | HANDLE hdev; 37 | int port; 38 | int ret; 39 | 40 | if (*portstr == '*' && portstr[1] == '\0') 41 | port = -1; 42 | else if (sscanf_s(portstr, "%d", &port) != 1) { 43 | err("invalid port: %s", portstr); 44 | return 1; 45 | } 46 | hdev = usbip_vhci_driver_open(); 47 | if (hdev == INVALID_HANDLE_VALUE) { 48 | err("vhci driver is not loaded"); 49 | return 2; 50 | } 51 | 52 | ret = usbip_vhci_detach_device(hdev, port); 53 | usbip_vhci_driver_close(hdev); 54 | if (ret == 0) { 55 | if (port < 0) 56 | printf("all ports are detached\n"); 57 | else 58 | printf("port %d is succesfully detached\n", port); 59 | return 0; 60 | } 61 | switch (ret) { 62 | case ERR_INVARG: 63 | err("invalid port: %d", port); 64 | break; 65 | case ERR_NOTEXIST: 66 | err("non-existent port: %d", port); 67 | break; 68 | default: 69 | err("failed to detach"); 70 | break; 71 | } 72 | return 3; 73 | } 74 | 75 | int usbip_detach(int argc, char *argv[]) 76 | { 77 | static const struct option opts[] = { 78 | { "port", required_argument, NULL, 'p' }, 79 | { NULL, 0, NULL, 0 } 80 | }; 81 | 82 | for (;;) { 83 | int opt = getopt_long(argc, argv, "p:", opts, NULL); 84 | 85 | if (opt == -1) 86 | break; 87 | 88 | switch (opt) { 89 | case 'p': 90 | return detach_port(optarg); 91 | default: 92 | break; 93 | } 94 | } 95 | 96 | err("port is required"); 97 | usbip_detach_usage(); 98 | 99 | return 1; 100 | } -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip_dscr.c: -------------------------------------------------------------------------------- 1 | #include "usbip_windows.h" 2 | 3 | #include "usbip_proto.h" 4 | #include "usbip_network.h" 5 | 6 | /* sufficient large enough seq used to avoid conflict with normal vhci operation */ 7 | static unsigned seqnum = 0x7ffffff; 8 | 9 | static int 10 | fetch_descriptor(SOCKET sockfd, UINT8 dscr_type, unsigned devid, char *dscr, unsigned short dscr_size) 11 | { 12 | struct usbip_header uhdr; 13 | unsigned alen; 14 | 15 | memset(&uhdr, 0, sizeof(uhdr)); 16 | 17 | uhdr.base.command = htonl(USBIP_CMD_SUBMIT); 18 | uhdr.base.seqnum = seqnum++; 19 | uhdr.base.direction = htonl(USBIP_DIR_IN); 20 | uhdr.base.devid = htonl(devid); 21 | 22 | uhdr.u.cmd_submit.transfer_buffer_length = htonl(dscr_size); 23 | uhdr.u.cmd_submit.setup[0] = 0x80; /* IN/control port */ 24 | uhdr.u.cmd_submit.setup[1] = 6; /* GetDescriptor */ 25 | *(unsigned short *)(uhdr.u.cmd_submit.setup + 6) = (unsigned short)dscr_size; /* Length */ 26 | uhdr.u.cmd_submit.setup[3] = dscr_type; 27 | 28 | if (usbip_net_send(sockfd, &uhdr, sizeof(uhdr)) < 0) { 29 | dbg("fetch_descriptor: failed to send usbip header\n"); 30 | return -1; 31 | } 32 | if (usbip_net_recv(sockfd, &uhdr, sizeof(uhdr)) < 0) { 33 | dbg("fetch_descriptor: failed to recv usbip header\n"); 34 | return -1; 35 | } 36 | if (uhdr.u.ret_submit.status != 0) { 37 | dbg("fetch_descriptor: command submit error: %d\n", uhdr.u.ret_submit.status); 38 | return -1; 39 | } 40 | alen = ntohl(uhdr.u.ret_submit.actual_length); 41 | if (alen < dscr_size) { 42 | err("fetch_descriptor: too short response: actual length: %d\n", alen); 43 | return -1; 44 | } 45 | if (usbip_net_recv(sockfd, dscr, alen) < 0) { 46 | err("fetch_descriptor: failed to recv usbip payload\n"); 47 | return -1; 48 | } 49 | return 0; 50 | } 51 | 52 | /* assume the length of a device descriptor is 18 */ 53 | int 54 | fetch_device_descriptor(SOCKET sockfd, unsigned devid, char *dscr) 55 | { 56 | return fetch_descriptor(sockfd, 1, devid, dscr, 18); 57 | } 58 | 59 | int 60 | fetch_conf_descriptor(SOCKET sockfd, unsigned devid, char *dscr, unsigned short *plen) 61 | { 62 | char buf[9]; 63 | unsigned short alen; 64 | 65 | if (fetch_descriptor(sockfd, 2, devid, buf, 9) < 0) 66 | return -1; 67 | alen = *((unsigned short *)buf + 1); 68 | if (dscr == NULL) { 69 | *plen = alen; 70 | return 0; 71 | } 72 | if (*plen < alen) { 73 | err("fetch_conf_descriptor: too small descriptor buffer\n"); 74 | return -1; 75 | } 76 | *plen = alen; 77 | return fetch_descriptor(sockfd, 2, devid, dscr, alen); 78 | } 79 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip_dscr.h: -------------------------------------------------------------------------------- 1 | #ifndef _USBIP_DSCR_H_ 2 | #define _USBIP_DSCR_H_ 3 | 4 | #include 5 | 6 | extern int 7 | fetch_device_descriptor(SOCKET sockfd, unsigned devid, char *dscr); 8 | extern int 9 | fetch_conf_descriptor(SOCKET sockfd, unsigned devid, char *dscr, unsigned short *plen); 10 | 11 | #endif /* _USBIP_DSCR_H_ */ 12 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | 21 | #include "usbip_common.h" 22 | #include "usbip_network.h" 23 | 24 | #include "usbip_windows.h" 25 | #include "usbip_setupdi.h" 26 | 27 | int list_devices(BOOL parsable); 28 | int list_exported_devices(const char *host); 29 | 30 | static const char usbip_list_usage_string[] = 31 | "usbip list [-p|--parsable] \n" 32 | " -p, --parsable Parsable list format\n" 33 | " -r, --remote= List the exported USB devices on \n" 34 | " -l, --local List the local USB devices\n" 35 | ; 36 | 37 | void usbip_list_usage(void) 38 | { 39 | printf("usage: %s", usbip_list_usage_string); 40 | } 41 | 42 | int usbip_list(int argc, char *argv[]) 43 | { 44 | static const struct option opts[] = { 45 | { "parsable", no_argument, NULL, 'p' }, 46 | { "remote", required_argument, NULL, 'r' }, 47 | { "local", no_argument, NULL, 'l' }, 48 | { NULL, 0, NULL, 0 } 49 | }; 50 | BOOL parsable = FALSE; 51 | int opt; 52 | int ret = 1; 53 | 54 | if (usbip_names_init() != 0) 55 | dbg("failed to open usb id database"); 56 | 57 | for (;;) { 58 | opt = getopt_long(argc, argv, "pr:l", opts, NULL); 59 | 60 | if (opt == -1) 61 | break; 62 | 63 | switch (opt) { 64 | case 'p': 65 | parsable = TRUE; 66 | break; 67 | case 'r': 68 | ret = list_exported_devices(optarg); 69 | goto out; 70 | case 'l': 71 | ret = list_devices(parsable); 72 | goto out; 73 | default: 74 | break; 75 | } 76 | } 77 | 78 | err("-r or -l option required"); 79 | usbip_list_usage(); 80 | out: 81 | usbip_names_free(); 82 | 83 | return ret; 84 | } 85 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip_port.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | */ 15 | 16 | #include "usbip_windows.h" 17 | #include "usbip_common.h" 18 | #include "usbip_vhci.h" 19 | #include 20 | 21 | static const char usbip_port_usage_string[] = 22 | "usbip port \n" 23 | " -p, --port= list only given port(for port checking)\n"; 24 | 25 | void 26 | usbip_port_usage(void) 27 | { 28 | printf("usage: %s", usbip_port_usage_string); 29 | } 30 | 31 | static int 32 | usbip_vhci_imported_device_dump(pioctl_usbip_vhci_imported_dev_t idev) 33 | { 34 | char product_name[128]; 35 | 36 | if (idev->status == VDEV_ST_NULL || idev->status == VDEV_ST_NOTASSIGNED) 37 | return 0; 38 | 39 | printf("Port %02d: <%s> at %s\n", idev->port, usbip_status_string(idev->status), usbip_speed_string(idev->speed)); 40 | 41 | usbip_names_get_product(product_name, sizeof(product_name), idev->vendor, idev->product); 42 | 43 | printf(" %s\n", product_name); 44 | 45 | printf(" ?-? -> unknown host, remote port and remote busid\n"); 46 | printf(" -> remote bus/dev ???/???\n"); 47 | 48 | return 0; 49 | } 50 | 51 | static int 52 | list_imported_devices(int port) 53 | { 54 | HANDLE hdev; 55 | ioctl_usbip_vhci_imported_dev *idevs; 56 | BOOL found = FALSE; 57 | int res; 58 | int i; 59 | 60 | hdev = usbip_vhci_driver_open(); 61 | if (hdev == INVALID_HANDLE_VALUE) { 62 | err("failed to open vhci driver"); 63 | return 3; 64 | } 65 | 66 | res = usbip_vhci_get_imported_devs(hdev, &idevs); 67 | if (res < 0) { 68 | usbip_vhci_driver_close(hdev); 69 | err("failed to get attach information"); 70 | return 2; 71 | } 72 | 73 | printf("Imported USB devices\n"); 74 | printf("====================\n"); 75 | 76 | if (usbip_names_init()) { 77 | dbg("failed to open usb id database"); 78 | } 79 | 80 | for (i = 0; i < 127; i++) { 81 | if (idevs[i].port < 0) 82 | break; 83 | if (port >= 0) { 84 | if (port != idevs[i].port) 85 | continue; 86 | found = TRUE; 87 | } 88 | usbip_vhci_imported_device_dump(&idevs[i]); 89 | } 90 | 91 | free(idevs); 92 | 93 | usbip_vhci_driver_close(hdev); 94 | usbip_names_free(); 95 | 96 | if (port >= 0 && !found) { 97 | /* port check failed */ 98 | return 2; 99 | } 100 | return 0; 101 | } 102 | 103 | int 104 | usbip_port_show(int argc, char *argv[]) 105 | { 106 | static const struct option opts[] = { 107 | { "port", required_argument, NULL, 'p' }, 108 | { NULL, 0, NULL, 0 } 109 | }; 110 | int port = -1; 111 | 112 | for (;;) { 113 | int opt = getopt_long(argc, argv, "p:", opts, NULL); 114 | 115 | if (opt == -1) 116 | break; 117 | 118 | switch (opt) { 119 | case 'p': 120 | if (sscanf_s(optarg, "%d", &port) != 1) { 121 | err("invalid port: %s", optarg); 122 | usbip_port_usage(); 123 | return 1; 124 | } 125 | break; 126 | default: 127 | err("invalid option: %c", opt); 128 | usbip_port_usage(); 129 | return 1; 130 | } 131 | } 132 | return list_imported_devices(port); 133 | } 134 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip_unbind.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 matt mooney 3 | * 2005-2007 Takahiro Hirofuchi 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include "usbip_windows.h" 20 | 21 | #include "usbip_common.h" 22 | #include "usbip_setupdi.h" 23 | #include "usbip_stub.h" 24 | 25 | static const char usbip_unbind_usage_string[] = 26 | "usbip unbind \n" 27 | " -b, --busid= Unbind usbip stub from device on \n"; 28 | 29 | void usbip_unbind_usage(void) 30 | { 31 | printf("usage: %s", usbip_unbind_usage_string); 32 | } 33 | 34 | static int 35 | walker_unbind(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data, devno_t devno, void *ctx) 36 | { 37 | devno_t *pdevno = (devno_t *)ctx; 38 | 39 | if (devno == *pdevno) { 40 | int ret; 41 | 42 | ret = detach_stub_driver(devno); 43 | switch (ret) { 44 | case 0: 45 | if (!restart_device(dev_info, pdev_info_data)) 46 | return ERR_DRIVER; 47 | return 1; 48 | case ERR_NOTEXIST: 49 | return ERR_NOTEXIST; 50 | default: 51 | return ERR_GENERAL; 52 | } 53 | } 54 | return 0; 55 | } 56 | 57 | static int unbind_device(char *busid) 58 | { 59 | unsigned char devno; 60 | int rc; 61 | 62 | devno = get_devno_from_busid(busid); 63 | if (devno == 0) { 64 | err("invalid bus id: %s", busid); 65 | return 1; 66 | } 67 | rc = traverse_usbdevs(walker_unbind, TRUE, (void *)&devno); 68 | if (rc != 1) { 69 | switch (rc) { 70 | case 0: 71 | case ERR_NOTEXIST: 72 | err("no such device on busid %s", busid); 73 | return 2; 74 | default: 75 | err("failed to unbind device on busid %s", busid); 76 | return 3; 77 | } 78 | } 79 | info("unbind device on busid %s: complete", busid); 80 | return 0; 81 | } 82 | 83 | int usbip_unbind(int argc, char *argv[]) 84 | { 85 | static const struct option opts[] = { 86 | { "busid", required_argument, NULL, 'b' }, 87 | { NULL, 0, NULL, 0 } 88 | }; 89 | 90 | int opt; 91 | 92 | for (;;) { 93 | opt = getopt_long(argc, argv, "b:", opts, NULL); 94 | 95 | if (opt == -1) 96 | break; 97 | 98 | switch (opt) { 99 | case 'b': 100 | return unbind_device(optarg); 101 | default: 102 | break; 103 | } 104 | } 105 | 106 | err("empty busid"); 107 | usbip_unbind_usage(); 108 | return 1; 109 | } 110 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbip/usbip_vhci.h: -------------------------------------------------------------------------------- 1 | #ifndef __VHCI_DRIVER_H 2 | #define __VHCI_DRIVER_H 3 | 4 | #pragma 5 | 6 | #include "usbip_vhci_api.h" 7 | 8 | HANDLE usbip_vhci_driver_open(void); 9 | void usbip_vhci_driver_close(HANDLE hdev); 10 | int usbip_vhci_get_imported_devs(HANDLE hdev, pioctl_usbip_vhci_imported_dev_t *pidevs); 11 | int usbip_vhci_attach_device(HANDLE hdev, pvhci_pluginfo_t pluginfo); 12 | int usbip_vhci_detach_device(HANDLE hdev, int port); 13 | 14 | #endif /* __VHCI_DRIVER_H */ 15 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbipd/usbipd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "usbip_common.h" 7 | 8 | extern int recv_request_import(SOCKET sockfd); 9 | extern int recv_request_devlist(SOCKET connfd); -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbipd/usbipd.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/usbip-win/userspace/src/usbipd/usbipd.rc -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbipd/usbipd_accept.c: -------------------------------------------------------------------------------- 1 | #include "usbipd.h" 2 | 3 | #include 4 | 5 | #include "usbip_network.h" 6 | #include "usbipd_stub.h" 7 | 8 | static void 9 | recv_pdu(SOCKET connfd, BOOL *pneed_close_sockfd) 10 | { 11 | uint16_t code = OP_UNSPEC; 12 | int status; 13 | int ret; 14 | 15 | *pneed_close_sockfd = TRUE; 16 | 17 | ret = usbip_net_recv_op_common(connfd, &code, &status); 18 | if (ret < 0) { 19 | dbg("could not receive opcode: %#0x, %x", code, status); 20 | return; 21 | } 22 | 23 | switch (code) { 24 | case OP_REQ_DEVLIST: 25 | dbg("received request: %#0x - list devices", code); 26 | ret = recv_request_devlist(connfd); 27 | break; 28 | case OP_REQ_IMPORT: 29 | dbg("received request: %#0x - attach device", code); 30 | ret = recv_request_import(connfd); 31 | if (ret == 0) 32 | *pneed_close_sockfd = FALSE; 33 | break; 34 | case OP_REQ_DEVINFO: 35 | case OP_REQ_CRYPKEY: 36 | default: 37 | dbg("received an unknown opcode: %#0x", code); 38 | break; 39 | } 40 | 41 | dbg("request %#0x: done: err: %d", code, ret); 42 | } 43 | 44 | static SOCKET 45 | do_accept(SOCKET listenfd) 46 | { 47 | SOCKET connfd; 48 | struct sockaddr_storage ss; 49 | socklen_t len = sizeof(ss); 50 | 51 | memset(&ss, 0, sizeof(ss)); 52 | connfd = accept(listenfd, (struct sockaddr *)&ss, &len); 53 | if (connfd == INVALID_SOCKET) { 54 | err("failed to accept connection"); 55 | } 56 | else { 57 | char host[NI_MAXHOST], port[NI_MAXSERV]; 58 | int rc; 59 | 60 | rc = getnameinfo((struct sockaddr *)&ss, len, host, sizeof(host), 61 | port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); 62 | if (rc != 0) { 63 | dbg("getnameinfo: %s", gai_strerror(rc)); 64 | } 65 | dbg("connection from %s:%s", host, port); 66 | } 67 | return connfd; 68 | } 69 | 70 | static void 71 | process_request(SOCKET listenfd) 72 | { 73 | SOCKET connfd; 74 | BOOL need_close_sockfd; 75 | 76 | connfd = do_accept(listenfd); 77 | if (connfd == INVALID_SOCKET) 78 | return; 79 | 80 | recv_pdu(connfd, &need_close_sockfd); 81 | if (need_close_sockfd) 82 | closesocket(connfd); 83 | } 84 | 85 | void 86 | accept_request(SOCKET *sockfds, fd_set *pfds) 87 | { 88 | int i; 89 | 90 | for (i = 0; sockfds[i] != INVALID_SOCKET; i++) { 91 | if (FD_ISSET(sockfds[i], pfds)) { 92 | process_request(sockfds[i]); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbipd/usbipd_import.c: -------------------------------------------------------------------------------- 1 | #include "usbipd.h" 2 | 3 | #include "usbip_network.h" 4 | #include "usbipd_stub.h" 5 | #include "usbip_setupdi.h" 6 | #include "usbip_forward.h" 7 | 8 | typedef struct { 9 | HANDLE hdev; 10 | SOCKET sockfd; 11 | } forwarder_ctx_t; 12 | 13 | static VOID CALLBACK 14 | forwarder_stub(PTP_CALLBACK_INSTANCE inst, PVOID ctx, PTP_WORK work) 15 | { 16 | forwarder_ctx_t *pctx = (forwarder_ctx_t *)ctx; 17 | 18 | dbg("stub forwarding started"); 19 | 20 | usbip_forward((HANDLE)pctx->sockfd, pctx->hdev, TRUE); 21 | 22 | closesocket(pctx->sockfd); 23 | CloseHandle(pctx->hdev); 24 | free(pctx); 25 | 26 | CloseThreadpoolWork(work); 27 | 28 | dbg("stub forwarding stopped"); 29 | } 30 | 31 | static int 32 | export_device(devno_t devno, SOCKET sockfd) 33 | { 34 | PTP_WORK work; 35 | forwarder_ctx_t *pctx; 36 | 37 | pctx = (forwarder_ctx_t *)malloc(sizeof(forwarder_ctx_t)); 38 | if (pctx == NULL) { 39 | dbg("out of memory"); 40 | return ERR_GENERAL; 41 | } 42 | pctx->hdev = open_stub_dev(devno); 43 | if (pctx->hdev == INVALID_HANDLE_VALUE) { 44 | dbg("cannot open devno: %hhu", devno); 45 | return ERR_NOTEXIST; 46 | } 47 | pctx->sockfd = sockfd; 48 | 49 | work = CreateThreadpoolWork(forwarder_stub, pctx, NULL); 50 | if (work == NULL) { 51 | dbg("failed to create thread pool work: error: %lx", GetLastError()); 52 | CloseHandle(pctx->hdev); 53 | free(pctx); 54 | return ERR_GENERAL; 55 | } 56 | SubmitThreadpoolWork(work); 57 | return 0; 58 | } 59 | 60 | int 61 | recv_request_import(SOCKET sockfd) 62 | { 63 | struct op_import_request req; 64 | struct usbip_usb_device udev; 65 | devno_t devno; 66 | int rc; 67 | 68 | memset(&req, 0, sizeof(req)); 69 | 70 | rc = usbip_net_recv(sockfd, &req, sizeof(req)); 71 | if (rc < 0) { 72 | dbg("usbip_net_recv failed: import request"); 73 | return -1; 74 | } 75 | PACK_OP_IMPORT_REQUEST(0, &req); 76 | 77 | devno = get_devno_from_busid(req.busid); 78 | if (devno == 0) { 79 | dbg("invalid bus id: %s", req.busid); 80 | usbip_net_send_op_common(sockfd, OP_REP_IMPORT, ST_NODEV); 81 | return -1; 82 | } 83 | 84 | usbip_net_set_keepalive(sockfd); 85 | 86 | /* should set TCP_NODELAY for usbip */ 87 | usbip_net_set_nodelay(sockfd); 88 | 89 | /* export device needs a TCP/IP socket descriptor */ 90 | rc = export_device(devno, sockfd); 91 | if (rc < 0) { 92 | dbg("failed to export device: %s, err:%d", req.busid, rc); 93 | usbip_net_send_op_common(sockfd, OP_REP_IMPORT, ST_NA); 94 | return -1; 95 | } 96 | 97 | rc = usbip_net_send_op_common(sockfd, OP_REP_IMPORT, ST_OK); 98 | if (rc < 0) { 99 | dbg("usbip_net_send_op_common failed: %#0x", OP_REP_IMPORT); 100 | return -1; 101 | } 102 | 103 | build_udev(devno, &udev); 104 | usbip_net_pack_usb_device(1, &udev); 105 | 106 | rc = usbip_net_send(sockfd, &udev, sizeof(udev)); 107 | if (rc < 0) { 108 | dbg("usbip_net_send failed: devinfo"); 109 | return -1; 110 | } 111 | 112 | dbg("import request busid %s: complete", req.busid); 113 | 114 | return 0; 115 | } -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbipd/usbipd_list.c: -------------------------------------------------------------------------------- 1 | #include "usbipd.h" 2 | 3 | #include "usbip_network.h" 4 | #include "usbipd_stub.h" 5 | 6 | typedef struct { 7 | struct usbip_usb_device udev; 8 | struct list_head list; 9 | } edev_t; 10 | 11 | static int 12 | send_reply_devlist_devices(SOCKET connfd, struct list_head *pedev_list) 13 | { 14 | struct list_head *p; 15 | 16 | list_for_each(p, pedev_list) { 17 | edev_t *edev; 18 | int rc; 19 | 20 | edev = list_entry(p, edev_t, list); 21 | dump_usb_device(&edev->udev); 22 | usbip_net_pack_usb_device(1, &edev->udev); 23 | 24 | rc = usbip_net_send(connfd, &edev->udev, sizeof(edev->udev)); 25 | if (rc < 0) { 26 | dbg("usbip_net_send failed: udev"); 27 | return -1; 28 | } 29 | /* usb interface count is always zero */ 30 | } 31 | return 0; 32 | } 33 | 34 | typedef struct { 35 | struct list_head *head; 36 | int n_edevs; 37 | } edev_list_ctx_t; 38 | 39 | static int 40 | walker_edev_list(HDEVINFO dev_info, PSP_DEVINFO_DATA pdev_info_data, devno_t devno, void *ctx) 41 | { 42 | edev_t *edev; 43 | edev_list_ctx_t *pctx = (edev_list_ctx_t *)ctx; 44 | 45 | edev = (edev_t *)malloc(sizeof(edev_t)); 46 | if (edev == NULL) { 47 | dbg("out of memory"); 48 | return 0; 49 | } 50 | if (!is_stub_devno(devno)) 51 | return 0; 52 | if (!build_udev(devno, &edev->udev)) { 53 | dbg("cannot build usbip dev"); 54 | free(edev); 55 | return 0; 56 | } 57 | list_add(&edev->list, pctx->head->prev); 58 | pctx->n_edevs++; 59 | return 0; 60 | } 61 | 62 | static void 63 | get_edev_list(struct list_head *head, int *pn_edevs) 64 | { 65 | edev_list_ctx_t ctx; 66 | 67 | INIT_LIST_HEAD(head); 68 | ctx.head = head; 69 | ctx.n_edevs = 0; 70 | traverse_usbdevs(walker_edev_list, TRUE, &ctx); 71 | *pn_edevs = ctx.n_edevs; 72 | } 73 | 74 | static void 75 | free_edev_list(struct list_head *head) 76 | { 77 | struct list_head *p, *n; 78 | 79 | list_for_each_safe(p, n, head) { 80 | edev_t *edev; 81 | 82 | edev = list_entry(p, edev_t, list); 83 | list_del(&edev->list); 84 | free(edev); 85 | } 86 | } 87 | 88 | static int 89 | send_reply_devlist(SOCKET connfd) 90 | { 91 | struct op_devlist_reply reply; 92 | struct list_head edev_list; 93 | int n_edevs; 94 | int rc; 95 | 96 | get_edev_list(&edev_list, &n_edevs); 97 | dbg("exportable devices: %d", n_edevs); 98 | 99 | reply.ndev = n_edevs; 100 | 101 | rc = usbip_net_send_op_common(connfd, OP_REP_DEVLIST, ST_OK); 102 | if (rc < 0) { 103 | dbg("usbip_net_send_op_common failed: %#0x", OP_REP_DEVLIST); 104 | free_edev_list(&edev_list); 105 | return -1; 106 | } 107 | PACK_OP_DEVLIST_REPLY(1, &reply); 108 | 109 | rc = usbip_net_send(connfd, &reply, sizeof(reply)); 110 | if (rc < 0) { 111 | dbg("usbip_net_send failed: %#0x", OP_REP_DEVLIST); 112 | free_edev_list(&edev_list); 113 | return -1; 114 | } 115 | 116 | if (send_reply_devlist_devices(connfd, &edev_list) < 0) { 117 | free_edev_list(&edev_list); 118 | return -1; 119 | } 120 | 121 | free_edev_list(&edev_list); 122 | return 0; 123 | } 124 | 125 | int 126 | recv_request_devlist(SOCKET connfd) 127 | { 128 | int rc; 129 | 130 | rc = send_reply_devlist(connfd); 131 | if (rc < 0) { 132 | dbg("send_reply_devlist failed"); 133 | return -1; 134 | } 135 | 136 | return 0; 137 | } 138 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbipd/usbipd_sock.c: -------------------------------------------------------------------------------- 1 | #include "usbipd.h" 2 | 3 | #include 4 | 5 | #include "usbip_network.h" 6 | 7 | static void 8 | setup_addrinfo_desc(struct addrinfo *ainfo, char buf[], size_t size) 9 | { 10 | char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; 11 | 12 | if (getnameinfo(ainfo->ai_addr, (socklen_t)ainfo->ai_addrlen, hbuf, sizeof(hbuf), 13 | sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) != 0) { 14 | buf[0] = '\0'; 15 | } 16 | snprintf(buf, size, "%s:%s", hbuf, sbuf); 17 | } 18 | 19 | static int 20 | get_n_addrinfos(struct addrinfo *ainfos) 21 | { 22 | struct addrinfo *ainfo; 23 | int count = 0; 24 | 25 | for (ainfo = ainfos; ainfo != NULL; ainfo = ainfo->ai_next) { 26 | count++; 27 | } 28 | return count; 29 | } 30 | 31 | static SOCKET 32 | build_sockfd(struct addrinfo *ainfo) 33 | { 34 | SOCKET sockfd; 35 | char desc[NI_MAXHOST + NI_MAXSERV + 2]; 36 | 37 | setup_addrinfo_desc(ainfo, desc, sizeof(desc)); 38 | dbg("opening %s", desc); 39 | 40 | sockfd = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol); 41 | if (sockfd != INVALID_SOCKET) { 42 | usbip_net_set_reuseaddr(sockfd); 43 | usbip_net_set_nodelay(sockfd); 44 | usbip_net_set_v6only(sockfd); 45 | 46 | if (bind(sockfd, ainfo->ai_addr, (int)ainfo->ai_addrlen) == SOCKET_ERROR) { 47 | dbg("failed to bind: %s: err: %d", desc, WSAGetLastError()); 48 | closesocket(sockfd); 49 | return INVALID_SOCKET; 50 | } 51 | 52 | if (listen(sockfd, SOMAXCONN) == SOCKET_ERROR) { 53 | dbg("failed to listen: %s: err: %d", desc, WSAGetLastError()); 54 | closesocket(sockfd); 55 | return INVALID_SOCKET; 56 | } 57 | info("listening on %s", desc); 58 | } 59 | else { 60 | dbg("socket error: %s: err: (%d)", desc, WSAGetLastError()); 61 | } 62 | 63 | return sockfd; 64 | } 65 | 66 | static SOCKET * 67 | build_sockfds(struct addrinfo *ainfos) 68 | { 69 | SOCKET *sockfds; 70 | struct addrinfo *ainfo; 71 | int n_infos, idx = 0; 72 | 73 | n_infos = get_n_addrinfos(ainfos); 74 | if (n_infos == 0) 75 | return NULL; 76 | sockfds = (SOCKET *)malloc(sizeof(SOCKET) * (n_infos + 1)); 77 | if (sockfds == NULL) 78 | return NULL; 79 | for (ainfo = ainfos; ainfo != NULL; ainfo = ainfo->ai_next) { 80 | SOCKET sockfd; 81 | 82 | sockfd = build_sockfd(ainfo); 83 | if (sockfd != INVALID_SOCKET) { 84 | sockfds[idx] = sockfd; 85 | idx++; 86 | } 87 | } 88 | if (idx == 0) { 89 | free(sockfds); 90 | return NULL; 91 | 92 | } 93 | sockfds[idx] = INVALID_SOCKET; 94 | return sockfds; 95 | } 96 | 97 | SOCKET * 98 | get_listen_sockfds(int family) 99 | { 100 | struct addrinfo *ainfos, hints; 101 | SOCKET *sockfds; 102 | int rc; 103 | 104 | memset(&hints, 0, sizeof(hints)); 105 | hints.ai_family = family; 106 | hints.ai_socktype = SOCK_STREAM; 107 | hints.ai_flags = AI_PASSIVE; 108 | 109 | rc = getaddrinfo(NULL, usbip_port_string, &hints, &ainfos); 110 | if (rc != 0) { 111 | dbg("failed to get a network address %s: %s", usbip_port_string, gai_strerror(rc)); 112 | return NULL; 113 | } 114 | 115 | sockfds = build_sockfds(ainfos); 116 | freeaddrinfo(ainfos); 117 | return sockfds; 118 | } -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/src/usbipd/usbipd_stub.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2016 Samsung Electronics 3 | * Igor Kotrasinski 4 | * Krzysztof Opasiak 5 | * 6 | * Refactored from usbip_host_driver.c, which is: 7 | * Copyright (C) 2011 matt mooney 8 | * 2005-2007 Takahiro Hirofuchi 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | */ 23 | 24 | #pragma once 25 | 26 | #include 27 | #include "list.h" 28 | #include "usbip_common.h" 29 | #include "usbip_setupdi.h" 30 | 31 | #include 32 | 33 | BOOL is_stub_devno(devno_t devno); 34 | BOOL build_udev(devno_t devno, struct usbip_usb_device *pudev); 35 | HANDLE open_stub_dev(devno_t devno); 36 | -------------------------------------------------------------------------------- /usbip/usbip-win/userspace/usb.ids: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bulwarkid/ssh-passkey/58ee97e06cd3ed5b6e0fe9837652ef69773f8587/usbip/usbip-win/userspace/usb.ids -------------------------------------------------------------------------------- /usbip_linux.go: -------------------------------------------------------------------------------- 1 | //go:build linux 2 | 3 | package main 4 | 5 | import ( 6 | "os/exec" 7 | ) 8 | 9 | func usbipCommand() *exec.Cmd { 10 | return exec.Command("sudo", "usbip", "attach", "-r", "127.0.0.1", "-b", "2-2") 11 | } 12 | -------------------------------------------------------------------------------- /usbip_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package main 4 | 5 | import ( 6 | "os/exec" 7 | ) 8 | 9 | func usbipCommand() *exec.Cmd { 10 | command := exec.Command(".\\usbip.exe", "attach", "-r", "127.0.0.1", "-b", "2-2") 11 | command.Dir = ".\\usbip\\bin" 12 | return command 13 | } 14 | -------------------------------------------------------------------------------- /util.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func checkErr(err error, msg string) { 6 | if err != nil { 7 | panic(fmt.Sprintf("Error: %s - %s", err, msg)) 8 | } 9 | } 10 | --------------------------------------------------------------------------------