forked from iamacarpet/go-win64api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
winupdate.go
executable file
·128 lines (107 loc) · 3.58 KB
/
winupdate.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
// +build windows,amd64
package winapi
import (
"fmt"
"time"
ole "github.com/go-ole/go-ole"
"github.com/go-ole/go-ole/oleutil"
so "github.com/iamacarpet/go-win64api/shared"
)
var updateResultStatus []string = []string{
"Pending",
"In Progress",
"Completed",
"Completed With Errors",
"Failed",
"Aborted",
}
func UpdatesPending() (*so.WindowsUpdate, error) {
retData := &so.WindowsUpdate{}
ole.CoInitialize(0)
defer ole.CoUninitialize()
unknown, err := oleutil.CreateObject("Microsoft.Update.Session")
if err != nil {
return nil, fmt.Errorf("Unable to create initial object, %s", err.Error())
}
defer unknown.Release()
update, err := unknown.QueryInterface(ole.IID_IDispatch)
if err != nil {
return nil, fmt.Errorf("Unable to create query interface, %s", err.Error())
}
defer update.Release()
oleutil.PutProperty(update, "ClientApplicationID", "GoLang Windows API")
us, err := oleutil.CallMethod(update, "CreateUpdateSearcher")
if err != nil {
return nil, fmt.Errorf("Error creating update searcher, %s", err.Error())
}
usd := us.ToIDispatch()
defer usd.Release()
usr, err := oleutil.CallMethod(usd, "Search", "IsInstalled=0 and Type='Software' and IsHidden=0")
if err != nil {
return nil, fmt.Errorf("Error performing update search, %s", err.Error())
}
usrd := usr.ToIDispatch()
defer usrd.Release()
upd, err := oleutil.GetProperty(usrd, "Updates")
if err != nil {
return nil, fmt.Errorf("Error getting Updates collection, %s", err.Error())
}
updd := upd.ToIDispatch()
defer updd.Release()
updn, err := oleutil.GetProperty(updd, "Count")
if err != nil {
return nil, fmt.Errorf("Error getting update count, %s", err.Error())
}
retData.NumUpdates = int(updn.Val)
thc, err := oleutil.CallMethod(usd, "GetTotalHistoryCount")
if err != nil {
return nil, fmt.Errorf("Error getting update history count, %s", err.Error())
}
thcn := int(thc.Val)
uhistRaw, err := oleutil.CallMethod(usd, "QueryHistory", 0, thcn)
if err != nil {
return nil, fmt.Errorf("Error querying update history, %s", err.Error())
}
uhist := uhistRaw.ToIDispatch()
defer uhist.Release()
countUhist, err := oleutil.GetProperty(uhist, "Count")
if err != nil {
return nil, fmt.Errorf("Unable to get property Count while processing Windows Update history: %s", err.Error())
}
count := int(countUhist.Val)
for i := 0; i < count; i++ {
err = func() error {
itemRaw, err := oleutil.GetProperty(uhist, "Item", i)
if err != nil {
return fmt.Errorf("Failed to fetch result row while processing Windows Update history. %s", err.Error())
}
item := itemRaw.ToIDispatch()
defer item.Release()
updateName, err := oleutil.GetProperty(item, "Title")
if err != nil {
return fmt.Errorf("Error while getting property Title from Windows Update history. %s", err.Error())
}
updateDate, err := oleutil.GetProperty(item, "Date")
if err != nil {
return fmt.Errorf("Error while getting property Title from Windows Update history. %s", err.Error())
}
resultCode, err := oleutil.GetProperty(item, "ResultCode")
if err != nil {
return fmt.Errorf("Error while getting property Title from Windows Update history. %s", err.Error())
}
retData.UpdateHistory = append(retData.UpdateHistory, &so.WindowsUpdateHistory{
EventDate: updateDate.Value().(time.Time),
Status: updateResultStatus[int(resultCode.Val)],
UpdateName: updateName.Value().(string),
})
return nil
}()
if err != nil {
return nil, fmt.Errorf("Unable to process update history entry: %d. %s", i, err)
}
}
if retData.NumUpdates > 0 {
retData.UpdatesReq = true
}
return retData, nil
}