mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 10:09:05 +02:00
118 lines
3.3 KiB
Go
118 lines
3.3 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
// Copyright The Prometheus Authors
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// Package ole provides native COM initialization, interface calls, strings,
|
|
// variants, and iteration shared by the taskschd and wuapi bindings. Native
|
|
// interfaces and strings have explicit ownership.
|
|
package ole
|
|
|
|
import (
|
|
"fmt"
|
|
"iter"
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
// HRESULT preserves the 32-bit COM status code, including when wrapped.
|
|
type HRESULT uint32
|
|
|
|
func (h HRESULT) Error() string { return formatHRESULT(h) }
|
|
|
|
// ResultError returns an error only for failed HRESULTs.
|
|
func ResultError(result uintptr) error {
|
|
if int32(result) < 0 {
|
|
return HRESULT(uint32(result))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DATE is an OLE Automation date: days since 1899-12-30, with the absolute
|
|
// fractional part representing the time of day, including for negative dates.
|
|
type DATE float64
|
|
|
|
func (d DATE) Time() (time.Time, error) {
|
|
value := float64(d)
|
|
if math.IsNaN(value) || math.IsInf(value, 0) || value <= -657435 || value >= 2958466 {
|
|
return time.Time{}, fmt.Errorf("invalid OLE date: %g", value)
|
|
}
|
|
|
|
days, fraction := math.Modf(value)
|
|
date := time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC).AddDate(0, 0, int(days))
|
|
millis := int64(math.Round(math.Abs(fraction) * 86400000))
|
|
|
|
date = date.Add(time.Duration(millis) * time.Millisecond)
|
|
if date.Year() > 9999 {
|
|
return time.Time{}, fmt.Errorf("invalid OLE date: %g", value)
|
|
}
|
|
|
|
return date, nil
|
|
}
|
|
|
|
// CollectionItemError identifies an unreadable index within a COM collection.
|
|
// The iterator can still read later indices; a count failure is not an item error.
|
|
type CollectionItemError struct {
|
|
Index int32
|
|
Err error
|
|
}
|
|
|
|
func (e *CollectionItemError) Error() string {
|
|
return fmt.Sprintf("get collection item %d: %v", e.Index, e.Err)
|
|
}
|
|
|
|
func (e *CollectionItemError) Unwrap() error { return e.Err }
|
|
|
|
// BorrowedItems releases each item even when yield stops early or panics. Items
|
|
// are valid only during yield; callers must not retain them or release them.
|
|
// Item errors are yielded as CollectionItemError, and iteration continues if
|
|
// yield returns true. Count errors stop iteration because there are no indices.
|
|
func BorrowedItems[T any](count func() (int32, error), item func(int32) (T, error), release func(T)) iter.Seq2[T, error] {
|
|
return func(yield func(T, error) bool) {
|
|
var zero T
|
|
|
|
n, err := count()
|
|
if err != nil {
|
|
yield(zero, fmt.Errorf("get collection count: %w", err))
|
|
|
|
return
|
|
}
|
|
|
|
if n < 0 {
|
|
yield(zero, fmt.Errorf("invalid collection count: %d", n))
|
|
|
|
return
|
|
}
|
|
|
|
for i := range n {
|
|
value, err := item(i)
|
|
if err != nil {
|
|
if !yield(zero, &CollectionItemError{Index: i, Err: err}) {
|
|
return
|
|
}
|
|
|
|
continue
|
|
}
|
|
|
|
if !func() bool {
|
|
defer release(value)
|
|
|
|
return yield(value, nil)
|
|
}() {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|