diff --git a/swbemservices.go b/swbemservices.go index 3ff8756..a250c84 100644 --- a/swbemservices.go +++ b/swbemservices.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package wmi diff --git a/swbemservices_test.go b/swbemservices_test.go index 1d619af..30a1f8d 100644 --- a/swbemservices_test.go +++ b/swbemservices_test.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package wmi @@ -103,8 +104,8 @@ func WbemGetMemoryUsageMB(s *SWbemServices) (float64, float64, float64) { //Run all benchmarks (should run for at least 60s to get a stable number): //go test -run=NONE -bench=Version -benchtime=120s -//Individual benchmarks: -//go test -run=NONE -bench=NewVersion -benchtime=120s +// Individual benchmarks: +// go test -run=NONE -bench=NewVersion -benchtime=120s func BenchmarkNewVersion(b *testing.B) { s, err := InitializeSWbemServices(DefaultClient) if err != nil { @@ -128,7 +129,7 @@ func BenchmarkNewVersion(b *testing.B) { } } -//go test -run=NONE -bench=OldVersion -benchtime=120s +// go test -run=NONE -bench=OldVersion -benchtime=120s func BenchmarkOldVersion(b *testing.B) { var dst []Win32_OperatingSystem q := CreateQuery(&dst, "") diff --git a/wmi.go b/wmi.go index b4bb4f0..26c3581 100644 --- a/wmi.go +++ b/wmi.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows /* @@ -20,7 +21,6 @@ Example code to print names of running processes: println(i, v.Name) } } - */ package wmi @@ -338,11 +338,6 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat f := v.Field(i) of := f isPtr := f.Kind() == reflect.Ptr - if isPtr { - ptr := reflect.New(f.Type().Elem()) - f.Set(ptr) - f = f.Elem() - } n := v.Type().Field(i).Name if n[0] < 'A' || n[0] > 'Z' { continue @@ -367,6 +362,12 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat } defer prop.Clear() + if isPtr && !(c.PtrNil && prop.VT == 0x1) { + ptr := reflect.New(f.Type().Elem()) + f.Set(ptr) + f = f.Elem() + } + if prop.VT == 0x1 { //VT_NULL continue } diff --git a/wmi_test.go b/wmi_test.go index 32c4dcd..6587f2c 100644 --- a/wmi_test.go +++ b/wmi_test.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package wmi @@ -39,6 +40,87 @@ func TestFieldMismatch(t *testing.T) { } } +func TestMissingFields(t *testing.T) { + type s struct { + Name string + Missing uint32 + MissingPointer *uint32 + } + + var dst []s + + client := &Client{ + AllowMissingFields: true, + } + err := client.Query("SELECT Name FROM Win32_Process", &dst) + if err != nil { + t.Fatal(err) + } + for i := range dst { + if dst[i].Missing != 0 { + t.Fatal("Expected Missing field to be 0") + } + if dst[i].MissingPointer != nil { + t.Fatal("Expected MissingPointer field to be nil") + } + } + + // NonePtrZero and PtrNil should only affect the behavior of fields that + // exist as result properties, not missing fields. + client = &Client{ + NonePtrZero: true, + PtrNil: true, + AllowMissingFields: true, + } + dst = []s{} + err = client.Query("SELECT Name FROM Win32_Process", &dst) + if err != nil { + t.Fatal(err) + } + for i := range dst { + if dst[i].Missing != 0 { + t.Fatal("Expected Missing field to be 0") + } + if dst[i].MissingPointer != nil { + t.Fatal("Expected MissingPointer field to be nil") + } + } +} + +func TestNullPointerField(t *testing.T) { + type s struct { + Name string + Status *string + } + + var dst []s + + client := &Client{} + err := client.Query("SELECT Name, Status FROM Win32_Process WHERE Status IS NULL", &dst) + if err != nil { + t.Fatal(err) + } + for i := range dst { + if dst[i].Status == nil { + t.Fatal("Expected Status field to not be nil") + } + } + + client = &Client{ + PtrNil: true, + } + dst = []s{} + err = client.Query("SELECT Name, Status FROM Win32_Process WHERE Status IS NULL", &dst) + if err != nil { + t.Fatal(err) + } + for i := range dst { + if dst[i].Status != nil { + t.Fatal("Expected Status field to be nil") + } + } +} + func TestStrings(t *testing.T) { printed := false f := func() {