USB detection for Windows (alternative implementation with OLE)

This commit is contained in:
Cristian Maglie
2016-10-22 18:55:05 +02:00
parent ad7966a434
commit 3d6dd00ccb
2 changed files with 116 additions and 0 deletions

113
usb_ole_windows.go Normal file
View File

@@ -0,0 +1,113 @@
//
// Copyright 2014-2016 Lars Knudsen, Cristian Maglie. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// +build ignore
package serial
import (
"log"
"regexp"
ole "github.com/go-ole/go-ole"
"github.com/go-ole/go-ole/oleutil"
)
func init() {
err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
if err != nil {
log.Fatal("Init error: ", err)
}
}
func nativeGetDetailedPortsList() ([]*PortDetails, error) {
unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
if err != nil {
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
}
defer unknown.Release()
wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
if err != nil {
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
}
defer wmi.Release()
serviceRaw, err := wmi.CallMethod("ConnectServer")
if err != nil {
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
}
service := serviceRaw.ToIDispatch()
defer service.Release()
query := "SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0 and Name like '%(COM%'"
queryResult, err := oleutil.CallMethod(service, "ExecQuery", query)
if err != nil {
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
}
result := queryResult.ToIDispatch()
defer result.Release()
countVar, err := result.GetProperty("Count")
if err != nil {
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
}
count := int(countVar.Val)
res := []*PortDetails{}
// Retrieve all items
for i := 0; i < count; i++ {
itemRaw, err := result.CallMethod("ItemIndex", i)
if err != nil {
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
}
item := itemRaw.ToIDispatch()
defer item.Release()
detail := &PortDetails{}
if err := getPortDetails(item, detail); err != nil {
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
}
// SerialPort{Path: path, VendorId: VID, ProductId: PID, DisplayName: displayName.ToString()}
res = append(res, detail)
}
return res, nil
}
func getPortDetails(item *ole.IDispatch, res *PortDetails) error {
// Find port name
itemName, err := item.GetProperty("Name")
if err != nil {
return err
}
re := regexp.MustCompile("\\((COM[0-9]+)\\)").FindAllStringSubmatch(itemName.ToString(), 1)
if re == nil || len(re[0]) < 2 {
// Discard items that are not serial ports
return nil
}
res.Name = re[0][1]
//itemPnPDeviceID, err := item.GetProperty("PnPDeviceID")
//if err != nil {
// return err
//}
//PnPDeviceID := itemPnPDeviceID.ToString()
itemDeviceID, err := item.GetProperty("DeviceID")
if err != nil {
return err
}
parseDeviceID(itemDeviceID.ToString(), res)
itemManufacturer, err := item.GetProperty("Product")
if err != nil {
return err
}
res.Manufacturer = itemManufacturer.ToString()
return nil
}

View File

@@ -51,6 +51,9 @@ func parseDeviceID(deviceID string, details *PortDetails) {
// Other unidentified device type // Other unidentified device type
} }
// setupapi based
// --------------
//sys setupDiClassGuidsFromNameInternal(class string, guid *guid, guidSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiClassGuidsFromNameW //sys setupDiClassGuidsFromNameInternal(class string, guid *guid, guidSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiClassGuidsFromNameW
//sys setupDiGetClassDevs(guid *guid, enumerator *string, hwndParent uintptr, flags uint32) (set devicesSet, err error) = setupapi.SetupDiGetClassDevsW //sys setupDiGetClassDevs(guid *guid, enumerator *string, hwndParent uintptr, flags uint32) (set devicesSet, err error) = setupapi.SetupDiGetClassDevsW
//sys setupDiDestroyDeviceInfoList(set devicesSet) (err error) = setupapi.SetupDiDestroyDeviceInfoList //sys setupDiDestroyDeviceInfoList(set devicesSet) (err error) = setupapi.SetupDiDestroyDeviceInfoList