-
Notifications
You must be signed in to change notification settings - Fork 90
/
device.go
170 lines (151 loc) · 4.29 KB
/
device.go
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
// +build windows
// Package device supports querying information about the local device.
package device
import (
"errors"
"fmt"
"os"
"strings"
"github.com/StackExchange/wmi"
)
var (
// ErrWMIEmptyResult indicates a condition where WMI failed to return the expected values.
ErrWMIEmptyResult = errors.New("WMI returned without error, but zero results")
)
// Win32_SystemEnclosure models the WMI object of the same name.
type Win32_SystemEnclosure struct {
ChassisTypes []int
}
// Type is a device type as reported by the system enclosure.
type Type string
var (
// Laptop indicates a laptop chassis.
Laptop Type = "Laptop"
// Desktop indicates a desktop chassis.
Desktop Type = "Desktop"
// Other indicates an "other" chassis type.
Other Type = "Other"
// Unknown indicates an "unknown" chassis type.
Unknown Type = "Unknown"
)
// ChassisType attempts to distinguish the chassis type for the device.
func ChassisType() (Type, error) {
var result []Win32_SystemEnclosure
if err := wmi.Query(wmi.CreateQuery(&result, ""), &result); err != nil {
return Unknown, err
}
if len(result) < 1 || len(result[0].ChassisTypes) < 1 {
return Unknown, ErrWMIEmptyResult
}
switch result[0].ChassisTypes[0] {
case -1:
return Unknown, nil
case 3, 35:
return Desktop, nil
case 8, 9, 10, 11, 12, 14, 30, 31, 32:
return Laptop, nil
default:
return Other, nil
}
}
// Win32_ComputerSystem models the WMI object of the same name.
type Win32_ComputerSystem struct {
DNSHostName string
Domain string
DomainRole int
Model string
SystemFamily string
Manufacturer string
}
func sysInfo() (*Win32_ComputerSystem, error) {
var result []Win32_ComputerSystem
if err := wmi.Query(wmi.CreateQuery(&result, ""), &result); err != nil {
return nil, err
}
if len(result) < 1 {
return nil, ErrWMIEmptyResult
}
return &result[0], nil
}
// DomainRole indicates the role of a host on an Active Directory domain.
type DomainRole string
var (
// Workstation corresponds to a domain workstation.
Workstation DomainRole = "Workstation"
// Server corresponds to a domain server.
Server DomainRole = "Server"
// DomainController corresponds to an Active Directory domain controller.
DomainController DomainRole = "Domain Controller"
// RoleUnknown indicates an unknown domain role.
RoleUnknown DomainRole = "Unknown"
)
// GetDomainRole attempts to determine the host's Active Directory role.
func GetDomainRole() (DomainRole, error) {
si, err := sysInfo()
if err != nil {
return RoleUnknown, err
}
switch si.DomainRole {
case 0, 1:
return Workstation, nil
case 2, 3:
return Server, nil
case 4, 5:
return DomainController, nil
default:
return RoleUnknown, nil
}
}
// Model returns the system model.
func Model() (string, error) {
si, err := sysInfo()
if err != nil {
return "unknown", err
}
if strings.EqualFold(si.Manufacturer, "lenovo") {
return si.SystemFamily, nil
}
return si.Model, nil
}
// Win32_NTDomain models the WMI object of the same name.
type Win32_NTDomain struct {
ClientSiteName string
DomainControllerName string
}
// Site returns the client's Active Directory site code.
func Site(domain string) (string, error) {
var result []Win32_NTDomain
err := wmi.Query(wmi.CreateQuery(&result, fmt.Sprintf("WHERE DomainName='%s'", domain)), &result)
if err == nil && len(result) > 0 {
return result[0].ClientSiteName, nil
}
return "", err
}
// UserProfiles returns a list of user profiles on the local device.
func UserProfiles() ([]string, error) {
users := []string{}
files, err := os.ReadDir(os.Getenv("SystemDrive") + `\Users`)
if err != nil {
return users, err
}
for _, f := range files {
if f.IsDir() {
users = append(users, f.Name())
}
}
return users, nil
}