代码拉取完成,页面将自动刷新
package winusb
import (
"fmt"
"strings"
"syscall"
"unsafe"
)
type SetupDi struct {
setupapi *syscall.DLL
setupDiGetClassDevs *syscall.Proc
setupDiDestroyDeviceInfoList *syscall.Proc
setupDiEnumDeviceInfo *syscall.Proc
setupDiGetDeviceInstanceId *syscall.Proc
setupDiEnumDeviceInterfaces *syscall.Proc
setupDiGetDeviceInterfaceDetail *syscall.Proc
}
func NewSetupDi() (* SetupDi, error) {
var sdi SetupDi
sdll, err := syscall.LoadDLL( "SetupAPI.dll" )
if err != nil {
return nil, err
}
sdi.setupapi = sdll
sdi.setupDiGetClassDevs, err = sdll.FindProc( "SetupDiGetClassDevsW" )
if err != nil {
return nil, err
}
sdi.setupDiDestroyDeviceInfoList, err = sdll.FindProc( "SetupDiDestroyDeviceInfoList" )
if err != nil {
return nil, err
}
sdi.setupDiEnumDeviceInfo, err = sdll.FindProc( "SetupDiEnumDeviceInfo" )
if err != nil {
return nil, err
}
sdi.setupDiGetDeviceInstanceId, err = sdll.FindProc( "SetupDiGetDeviceInstanceIdW" )
if err != nil {
return nil, err
}
sdi.setupDiEnumDeviceInterfaces, err = sdll.FindProc( "SetupDiEnumDeviceInterfaces" )
if err != nil {
return nil, err
}
sdi.setupDiGetDeviceInterfaceDetail, err = sdll.FindProc( "SetupDiGetDeviceInterfaceDetailW" )
if err != nil {
return nil, err
}
return &sdi, nil
}
type SP_DEVICE_INTERFACE_DATA struct {
cbsiz uint32
guid syscall.GUID
flags uint32
rsved uintptr
}
func (sdi * SetupDi)GetDetailPath( hdi uintptr, did uintptr ) (string, error) {
var bret uintptr
var reqlen uint32
bret, _, err := sdi.setupDiGetDeviceInterfaceDetail.Call( hdi, did, 0, 0, uintptr( unsafe.Pointer(&reqlen)), 0 )
if bret != 0 {
// 结果必须是 false.
return "", syscall.ERROR_OPERATION_ABORTED
}
if eno, ok := err.(syscall.Errno); ok {
if eno != syscall.ERROR_INSUFFICIENT_BUFFER {
fmt.Println( "eno =", uint32(eno) )
return "", err
}
} else {
return "", err
}
//
tary := make( []uint16, (reqlen/2 + 1) )
tary[0] = 8;
tary[1] = 0;
bret, _, err = sdi.setupDiGetDeviceInterfaceDetail.Call( hdi, did, uintptr( unsafe.Pointer(&tary[0])), uintptr(reqlen), uintptr( unsafe.Pointer(&reqlen)), 0 )
if bret == 0 {
return "", err
}
//
upth := syscall.UTF16ToString( tary[2:] )
return upth, nil
}
func (sdi * SetupDi)ScanUsbDev( vid uint16, pid uint16 ) (string, error) {
var bret uintptr
var sdid SP_DEVICE_INTERFACE_DATA
var patn string
patn = fmt.Sprintf( "\\\\?\\usb#vid_%04x&pid_%04x#", vid, pid )
// GUID_DEVINTERFACE_USB_DEVICE
ugid := syscall.GUID{ Data1: 0xa5dcbf10, Data2:0x6530, Data3 :0x11d2, Data4: [8]byte{ 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed } }
// DIGCF_PRESENT = 0x00000002
// DIGCF_DEVICEINTERFACE 0x00000010
hdi, _, err := sdi.setupDiGetClassDevs.Call( uintptr( unsafe.Pointer(&ugid) ), 0, 0, uintptr(0x12) )
if hdi == uintptr( syscall.InvalidHandle ) {
return "", err
}
defer sdi.setupDiDestroyDeviceInfoList.Call( hdi )
//
for i:=0; i<256; i++ {
sdid.cbsiz = uint32( unsafe.Sizeof(sdid) )
bret, _, err = sdi.setupDiEnumDeviceInterfaces.Call( hdi, 0, uintptr( unsafe.Pointer(&ugid) ), uintptr(i), uintptr( unsafe.Pointer(&sdid)) )
if bret == 0 {
// fmt.Println( "index =", i )
return "", err
}
upth, err := sdi.GetDetailPath( hdi, uintptr( unsafe.Pointer(&sdid) ) )
if err != nil {
return "", err
}
//
if strings.HasPrefix( upth, patn ) {
return upth, nil
}
}
return "", syscall.ERROR_NOT_FOUND
}
type SP_DEVINFO_DATA struct {
cbSize uint32
clsGuid syscall.GUID
devInst uint32
rsvd uintptr
}
func (sdi * SetupDi)GetInstanceID( hdi uintptr, sdd uintptr ) (string, error) {
var bret uintptr
var reqlen uint32
bret, _, err := sdi.setupDiGetDeviceInstanceId.Call( hdi, sdd, 0, 0, uintptr( unsafe.Pointer(&reqlen)) )
if bret != 0 {
// 结果必须是 false.
return "", syscall.ERROR_OPERATION_ABORTED
}
if eno, ok := err.(syscall.Errno); ok {
if eno != syscall.ERROR_INSUFFICIENT_BUFFER {
fmt.Println( "eno =", uint32(eno) )
return "", err
}
} else {
return "", err
}
//
tary := make( []uint16, (reqlen + 1) )
bret, _, err = sdi.setupDiGetDeviceInstanceId.Call( hdi, sdd, uintptr( unsafe.Pointer(&tary[0])), uintptr(reqlen + 1), 0 )
if bret == 0 {
return "", err
}
//
upth := syscall.UTF16ToString( tary[:] )
return upth, nil
}
/*
port, serial, ???
*/
func (sdi * SetupDi)EnumUsbDev( vid uint16, pid uint16 ) ([]string, error) {
var bret uintptr
var sdd SP_DEVINFO_DATA
var patn string
var rult []string
// USB\VID_0BDA&PID_4853
patn = fmt.Sprintf( "USB\\VID_%04X&PID_%04X\\", vid, pid )
// GUID_DEVINTERFACE_USB_DEVICE
ugid := syscall.GUID{ Data1: 0xa5dcbf10, Data2:0x6530, Data3 :0x11d2, Data4: [8]byte{ 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed } }
// DIGCF_PRESENT = 0x00000002
// DIGCF_DEVICEINTERFACE 0x00000010
hdi, _, err := sdi.setupDiGetClassDevs.Call( uintptr( unsafe.Pointer(&ugid) ), 0, 0, uintptr(0x12) )
if hdi == uintptr( syscall.InvalidHandle ) {
return nil, err
}
defer sdi.setupDiDestroyDeviceInfoList.Call( hdi )
//
for i:=0; i<256; i++ {
sdd.cbSize = uint32( unsafe.Sizeof(sdd) )
bret, _, err = sdi.setupDiEnumDeviceInfo.Call( hdi, uintptr(i), uintptr( unsafe.Pointer(&sdd)) )
if bret == 0 {
if erid, ok := err.(syscall.Errno); ok {
// ERROR_NO_MORE_ITEMS, 259(0x103)
if uintptr(erid) == 259 {
return rult, nil
}
}
return nil, err
}
//
isid, err := sdi.GetInstanceID( hdi, uintptr( unsafe.Pointer(&sdd)) )
if err != nil {
return nil, err
}
// filter by pid.
if !strings.HasPrefix( isid, patn ) {
continue
}
//
rult = append( rult, isid )
// fmt.Printf( "%v: %s\n", i, isid )
}
return rult, nil
}
/*
使用 InstanceID 查找 SP_DEVINFO_DATA.
再使用 SP_DEVINFO_DATA 来获取 DetailPath.
*/
func (sdi * SetupDi)TransFullPath( insid string ) (string, error) {
var bret uintptr
var sdd SP_DEVINFO_DATA
var sdid SP_DEVICE_INTERFACE_DATA
// GUID_DEVINTERFACE_USB_DEVICE
ugid := syscall.GUID{ Data1: 0xa5dcbf10, Data2:0x6530, Data3 :0x11d2, Data4: [8]byte{ 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed } }
// DIGCF_PRESENT = 0x00000002
// DIGCF_DEVICEINTERFACE 0x00000010
hdi, _, err := sdi.setupDiGetClassDevs.Call( uintptr( unsafe.Pointer(&ugid) ), 0, 0, uintptr(0x12) )
if hdi == uintptr( syscall.InvalidHandle ) {
return "", err
}
defer sdi.setupDiDestroyDeviceInfoList.Call( hdi )
//
for i:=0; i<256; i++ {
sdd.cbSize = uint32( unsafe.Sizeof(sdd) )
bret, _, err = sdi.setupDiEnumDeviceInfo.Call( hdi, uintptr(i), uintptr( unsafe.Pointer(&sdd)) )
if bret == 0 {
return "", err
}
//
isid, err := sdi.GetInstanceID( hdi, uintptr( unsafe.Pointer(&sdd)) )
if err != nil {
return "", err
}
//
if isid == insid {
break
}
}
//
sdid.cbsiz = uint32( unsafe.Sizeof(sdid) )
bret, _, err = sdi.setupDiEnumDeviceInterfaces.Call( hdi, uintptr( unsafe.Pointer(&sdd)), uintptr( unsafe.Pointer(&ugid) ), uintptr(0), uintptr( unsafe.Pointer(&sdid)) )
if bret == 0 {
// fmt.Println( "index =", i )
return "", err
}
upth, err := sdi.GetDetailPath( hdi, uintptr( unsafe.Pointer(&sdid) ) )
if err != nil {
return "", err
}
return upth, nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。