-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathhwid.go
More file actions
95 lines (83 loc) · 2.43 KB
/
hwid.go
File metadata and controls
95 lines (83 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* ipp-usb - HTTP reverse proxy, backed by IPP-over-USB connection to device
*
* Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com)
* See LICENSE for license terms and conditions
*
* USB devices matching by HWID
*/
package main
import "strconv"
// HWIDPattern defines matching rule for matching USB devices by
// the hardware ID
type HWIDPattern struct {
vid, pid uint16 // Vendor/Product IDs
anypid bool // Pattern matches any PID
}
// ParseHWIDPattern parses supplied string as the HWID-style
// pattern.
//
// HWID pattern may take one of the following forms:
//
// VVVV:DDDD - matches devices by vendor and device IDs
// VVVV:* - matches devices by vendor ID with any device ID
//
// VVVV and DDDD are device/vendor IDs, represented as sequence of
// the four hexadecimal digits.
//
// It returns *HWIDPattern or nil, if string doesn't match HWIDPattern
// syntax.
func ParseHWIDPattern(pattern string) *HWIDPattern {
// Split pattern into VID and PID
if len(pattern) != 6 && len(pattern) != 9 {
return nil
}
if pattern[4] != ':' {
return nil
}
strVID := pattern[:4]
strPID := pattern[5:]
// Parse parts
var vid, pid uint64
var anypid bool
var err error
vid, err = strconv.ParseUint(strVID, 16, 16)
if err != nil {
return nil
}
if strPID == "*" {
anypid = true
} else {
pid, err = strconv.ParseUint(strPID, 16, 16)
if err != nil {
return nil
}
}
return &HWIDPattern{vid: uint16(vid), pid: uint16(pid), anypid: anypid}
}
// Match reports if the USB device VID/PID matches the pattern.
//
// It returns the "matching weight" which allows to prioritize
// quirks, if there are multiple matches, as more or less specific
// (the more the weight, the more specific the quirk is).
//
// The matching weight is the math.MaxInt32 for the exact match (VID+PID)
// and 1 for the wildcard match (VID only). It makes the exact match to
// be considered as very specific, while wildcard match to be considered
// only slightly more specific, that the all-wildcard (i.e., the default)
// match by the model name.
//
// If there is no match, it returns -1.
//
// See also [GlobMatch] documentation for comparison with the
// similar function, used for match-by-model-name purpose.
func (p *HWIDPattern) Match(vid, pid uint16) int {
ok := vid == p.vid && (p.anypid || pid == p.pid)
switch {
case !ok:
return -1 // No match
case p.anypid:
return 1 // Match by VID only
default:
return 1000 // Match by VID+PID
}
}