forked from iamacarpet/go-win64api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sysinfo_extended.go
168 lines (150 loc) · 5.43 KB
/
sysinfo_extended.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
//go:build windows
// +build windows
package winapi
import (
"fmt"
"syscall"
"unsafe"
ole "github.com/go-ole/go-ole"
"github.com/go-ole/go-ole/oleutil"
)
var (
krnGetFirmwareEnvironmentVariable = modKernel32.NewProc("GetFirmwareEnvironmentVariableW")
)
const (
ERROR_INVALID_FUNCTION = 1
)
func sysinfo_uefi_check() (bool, error) {
blankStringPtr, _ := syscall.UTF16PtrFromString("")
blankUUIDPtr, _ := syscall.UTF16PtrFromString("{00000000-0000-0000-0000-000000000000}")
_, _, err := krnGetFirmwareEnvironmentVariable.Call(uintptr(unsafe.Pointer(blankStringPtr)), uintptr(unsafe.Pointer(blankUUIDPtr)), uintptr(0), uintptr(uint32(0)))
if val, ok := err.(syscall.Errno); !ok {
return false, fmt.Errorf("Unknown Error! - %s", err)
} else if val == ERROR_INVALID_FUNCTION {
return false, nil
} else {
return true, nil
}
}
func sysinfo_secureboot_check() (bool, error) {
procAssignCorrectPrivs(PROC_SE_SYSTEM_ENVIRONMENT_PRIV)
nameStrPtr, _ := syscall.UTF16PtrFromString("SecureBoot")
UUIDStrPtr, _ := syscall.UTF16PtrFromString("{8be4df61-93ca-11d2-aa0d-00e098032b8c}")
var secureBootResult bool
_, _, err := krnGetFirmwareEnvironmentVariable.Call(uintptr(unsafe.Pointer(nameStrPtr)), uintptr(unsafe.Pointer(UUIDStrPtr)), uintptr(unsafe.Pointer(&secureBootResult)), uintptr(uint32(unsafe.Sizeof(secureBootResult))))
if val, ok := err.(syscall.Errno); !ok {
return false, fmt.Errorf("Unknown Error! - %s", err)
} else if val == ERROR_INVALID_FUNCTION {
// BIOS - SecureBoot Unsupported
return false, nil
} else {
if secureBootResult {
return true, nil
} else {
return false, nil
}
}
}
// return enabled, encrypted, error
func sysinfo_bitlocker_check(driveName string) (bool, bool, error) {
unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
if err != nil {
return false, false, fmt.Errorf("Unable to create initial object, %s", err.Error())
}
defer unknown.Release()
wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
if err != nil {
return false, false, fmt.Errorf("Unable to create initial object, %s", err.Error())
}
defer wmi.Release()
serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", nil, `\\.\ROOT\CIMV2\Security\MicrosoftVolumeEncryption`)
if err != nil {
return false, false, fmt.Errorf("Permission Denied - %s", err)
}
service := serviceRaw.ToIDispatch()
defer service.Release()
resultRaw, err := oleutil.CallMethod(service, "ExecQuery", "SELECT ConversionStatus FROM Win32_EncryptableVolume WHERE DriveLetter = '"+driveName+"'")
if err != nil {
return false, false, fmt.Errorf("Unable to execute query while getting BitLocker status. %s", err.Error())
}
result := resultRaw.ToIDispatch()
defer result.Release()
countVar, err := oleutil.GetProperty(result, "Count")
if err != nil {
return false, false, fmt.Errorf("Unable to get property Count while processing BitLocker status. %s", err.Error())
}
count := int(countVar.Val)
if count > 0 {
itemRaw, err := oleutil.CallMethod(result, "ItemIndex", 0)
if err != nil {
return false, false, fmt.Errorf("Failed to fetch result row while processing BitLocker status. %s", err.Error())
}
item := itemRaw.ToIDispatch()
defer item.Release()
resStatus, err := oleutil.GetProperty(item, "ConversionStatus")
if err != nil {
return false, false, fmt.Errorf("Error while getting property ConversionStatus in BitLocker Status. %s", err.Error())
}
if status, ok := resStatus.Value().(int32); ok {
if status == 0 {
return false, false, nil
} else if status == 1 {
return true, true, nil
} else {
return true, false, nil
}
} else {
return false, false, fmt.Errorf("Unable to convert status to uint32 in BitLocker Status")
}
} else {
return false, false, nil
}
}
func sysinfo_tpm_specversion() (string, error) {
unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
if err != nil {
return "", fmt.Errorf("Unable to create initial object, %s", err.Error())
}
defer unknown.Release()
wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
if err != nil {
return "", fmt.Errorf("Unable to create initial object, %s", err.Error())
}
defer wmi.Release()
serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", nil, `\\.\ROOT\CIMV2\Security\MicrosoftTpm`)
if err != nil {
return "", fmt.Errorf("Permission Denied - %s", err)
}
service := serviceRaw.ToIDispatch()
defer service.Release()
resultRaw, err := oleutil.CallMethod(service, "ExecQuery", "SELECT SpecVersion FROM Win32_Tpm")
if err != nil {
return "", fmt.Errorf("Unable to execute query while getting TPM info. %s", err.Error())
}
result := resultRaw.ToIDispatch()
defer result.Release()
countVar, err := oleutil.GetProperty(result, "Count")
if err != nil {
return "", fmt.Errorf("Unable to get property Count while processing TPM info. %s", err.Error())
}
count := int(countVar.Val)
if count > 0 {
itemRaw, err := oleutil.CallMethod(result, "ItemIndex", 0)
if err != nil {
return "", fmt.Errorf("Failed to fetch result row while processing TPM info. %s", err.Error())
}
item := itemRaw.ToIDispatch()
defer item.Release()
resVersion, err := oleutil.GetProperty(item, "SpecVersion")
if err != nil {
return "", fmt.Errorf("Error while getting property SpecVersion in TPM info. %s", err.Error())
}
if version, ok := resVersion.Value().(string); ok {
return version, nil
} else {
return "", fmt.Errorf("Unable to convert SpecVersion to string in TPM info")
}
} else {
return "Not Installed", nil
}
}