Skip to content

Commit

Permalink
wmi: improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
sni committed Jul 25, 2023
1 parent 60b26d8 commit d3a3263
Showing 1 changed file with 50 additions and 40 deletions.
90 changes: 50 additions & 40 deletions pkg/wmi/wmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,37 @@ type Data struct {
}

func Query(query string) (querydata [][]Data, err error) {
var ret [][]Data

err = ole.CoInitialize(0)
if err != nil {
return nil, fmt.Errorf("check_service: couldn't initialize COM connection: %s", err.Error())
return nil, fmt.Errorf("wmi: ole.CoInitialize failed: %s", err.Error())
}
defer ole.CoUninitialize()

unknown, _ := oleutil.CreateObject("WbemScripting.SWbemLocator")
unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
if err != nil {
return nil, fmt.Errorf("wmi: CreateObject WbemScripting.SWbemLocator failed: %s", err.Error())
}
defer unknown.Release()

wmi, _ := unknown.QueryInterface(ole.IID_IDispatch)
wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
if err != nil {
return nil, fmt.Errorf("wmi: QueryInterface ole.IID_IDispatch failed: %s", err.Error())
}
defer wmi.Release()

// service is a SWbemServices
serviceRaw, _ := oleutil.CallMethod(wmi, "ConnectServer")
serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer")
if err != nil {
return nil, fmt.Errorf("wmi: CallMethod ConnectServer failed: %s", err.Error())
}
service := serviceRaw.ToIDispatch()
defer service.Release()

// result is a SWBemObjectSet
resultRaw, _ := oleutil.CallMethod(service, "ExecQuery", query)
resultRaw, err := oleutil.CallMethod(service, "ExecQuery", query)
if err != nil {
return nil, fmt.Errorf("wmi: CallMethod ExecQuery failed: %s", err.Error())
}
result := resultRaw.ToIDispatch()
defer result.Release()

Expand All @@ -45,47 +55,47 @@ func Query(query string) (querydata [][]Data, err error) {
re := regexp.MustCompile(`\w+\s+((?:\w+\s*,\s*)*\w+)`)
values := strings.Split(re.FindStringSubmatch(query)[1], ",")

ret := make([][]Data, 0)
for i := 0; i < count; i++ {
// item is a SWbemObject, but really a Win32_Process
err = func() error {
itemRaw, err := oleutil.CallMethod(result, "ItemIndex", i)
if err != nil {
return fmt.Errorf("wmi call failed: %s", err.Error())
}
item := itemRaw.ToIDispatch()
defer item.Release()

var obj []Data

for _, val := range values {
var value string
property, err := oleutil.GetProperty(item, strings.TrimSpace(val))
if err != nil {
return fmt.Errorf("WMI: error getting property from item (%s)", err.Error())
}
if property.Value() == nil {
value = ""
} else {
switch t := property.Value().(type) {
case int32:
value = fmt.Sprintf("%d", t)
default:
value = property.ToString()
}
}
obj = append(obj, Data{Key: strings.TrimSpace(val), Value: value})
}
obj, err := processResult(values, result, i)
if err != nil {
return nil, err
}
ret = append(ret, obj)
}

ret = append(ret, obj)
return ret, nil
}

return nil
}()
func processResult(values []string, result *ole.IDispatch, i int) (obj []Data, err error) {
itemRaw, err := oleutil.CallMethod(result, "ItemIndex", i)
if err != nil {
return nil, fmt.Errorf("oleutil.CallMethod failed: %s", err.Error())
}
item := itemRaw.ToIDispatch()
defer item.Release()

for _, val := range values {
var value string
property, err := oleutil.GetProperty(item, strings.TrimSpace(val))
if err != nil {
return nil, fmt.Errorf("wmi error: %s", err.Error())
return nil, fmt.Errorf("oleutil.GetProperty failed for item: %s (%s)", val, err.Error())
}
if property.Value() == nil {
value = ""
} else {
switch t := property.Value().(type) {
case int32:
value = fmt.Sprintf("%d", t)
default:
value = property.ToString()
}
}
obj = append(obj, Data{Key: strings.TrimSpace(val), Value: value})
}

return ret, nil
return obj, nil
}

func ResultToMap(queryResult [][]Data) []map[string]string {
Expand Down

0 comments on commit d3a3263

Please sign in to comment.