diff --git a/glide.yaml b/glide.yaml index 03575f96128..d86cbf3fbc3 100644 --- a/glide.yaml +++ b/glide.yaml @@ -56,7 +56,7 @@ import: - package: github.com/satori/go.uuid version: v1.1.0 - package: github.com/StackExchange/wmi - version: f3e2bae1e0cb5aef83e319133eabfee30013a4a5 + version: e54cbda6595d7293a7a468ccf9525f6bc8887f99 - package: github.com/go-ole/go-ole version: v1.2.0 - package: github.com/miekg/dns diff --git a/vendor/github.com/StackExchange/wmi/wmi.go b/vendor/github.com/StackExchange/wmi/wmi.go index b931ca57afc..5cb56ff1ec9 100644 --- a/vendor/github.com/StackExchange/wmi/wmi.go +++ b/vendor/github.com/StackExchange/wmi/wmi.go @@ -45,9 +45,15 @@ var l = log.New(os.Stdout, "", log.LstdFlags) var ( ErrInvalidEntityType = errors.New("wmi: invalid entity type") - lock sync.Mutex + // ErrNilCreateObject is the error returned if CreateObject returns nil even + // if the error was nil. + ErrNilCreateObject = errors.New("wmi: create object returned nil") + lock sync.Mutex ) +// S_FALSE is returned by CoInitializeEx if it was already called on this thread. +const S_FALSE = 0x00000001 + // QueryNamespace invokes Query with the given namespace on the local machine. func QueryNamespace(query string, dst interface{}, namespace string) error { return Query(query, dst, nil, namespace) @@ -126,21 +132,18 @@ func (c *Client) Query(query string, dst interface{}, connectServerArgs ...inter err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED) if err != nil { - oleerr := err.(*ole.OleError) - // S_FALSE = 0x00000001 // CoInitializeEx was already called on this thread - if oleerr.Code() != ole.S_OK && oleerr.Code() != 0x00000001 { + oleCode := err.(*ole.OleError).Code() + if oleCode != ole.S_OK && oleCode != S_FALSE { return err } - } else { - // Only invoke CoUninitialize if the thread was not initizlied before. - // This will allow other go packages based on go-ole play along - // with this library. - defer ole.CoUninitialize() } + defer ole.CoUninitialize() unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator") if err != nil { return err + } else if unknown == nil { + return ErrNilCreateObject } defer unknown.Release() @@ -171,19 +174,34 @@ func (c *Client) Query(query string, dst interface{}, connectServerArgs ...inter return err } + enumProperty, err := result.GetProperty("_NewEnum") + if err != nil { + return err + } + defer enumProperty.Clear() + + enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant) + if err != nil { + return err + } + if enum == nil { + return fmt.Errorf("can't get IEnumVARIANT, enum is nil") + } + defer enum.Release() + // Initialize a slice with Count capacity dv.Set(reflect.MakeSlice(dv.Type(), 0, int(count))) var errFieldMismatch error - for i := int64(0); i < count; i++ { + for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) { + if err != nil { + return err + } + err := func() error { // item is a SWbemObject, but really a Win32_Process - itemRaw, err := oleutil.CallMethod(result, "ItemIndex", i) - if err != nil { - return err - } item := itemRaw.ToIDispatch() - defer itemRaw.Clear() + defer item.Release() ev := reflect.New(elemType) if err = c.loadEntity(ev.Interface(), item); err != nil { @@ -332,6 +350,17 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat Reason: "not a bool", } } + case float32: + switch f.Kind() { + case reflect.Float32: + f.SetFloat(float64(val)) + default: + return &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: "not a Float32", + } + } default: typeof := reflect.TypeOf(val) if typeof == nil && (isPtr || c.NonePtrZero) {