From 63efa92be7398883072dbb8fc15d11fc09f58621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Thu, 27 Mar 2025 07:26:51 +0100 Subject: [PATCH] service: fix windows.EnumServicesStatusEx reports buffer too small (#1954) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- internal/collector/service/service.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/internal/collector/service/service.go b/internal/collector/service/service.go index 1812c137..94a147fb 100644 --- a/internal/collector/service/service.go +++ b/internal/collector/service/service.go @@ -366,9 +366,9 @@ func (c *Collector) collectService(ch chan<- prometheus.Metric, serviceName stri // This is realized by ask Service Manager directly. func (c *Collector) queryAllServices() ([]windows.ENUM_SERVICE_STATUS_PROCESS, error) { var ( - bytesNeeded uint32 - servicesReturned uint32 - err error + additionalBytesNeeded uint32 + servicesReturned uint32 + err error ) for { @@ -381,7 +381,7 @@ func (c *Collector) queryAllServices() ([]windows.ENUM_SERVICE_STATUS_PROCESS, e windows.SERVICE_STATE_ALL, &c.queryAllServicesBuffer[0], currentBufferSize, - &bytesNeeded, + &additionalBytesNeeded, &servicesReturned, nil, nil, @@ -395,11 +395,14 @@ func (c *Collector) queryAllServices() ([]windows.ENUM_SERVICE_STATUS_PROCESS, e return nil, err } - if bytesNeeded <= currentBufferSize { - return nil, fmt.Errorf("windows.EnumServicesStatusEx reports buffer too small (%d), but buffer is large enough (%d)", currentBufferSize, bytesNeeded) - } + /* + Unlike other WIN32 API calls, additionalBytesNeeded is not returning the absolute amount bytes needed, + but the additional bytes needed relative to the cbBufSize parameter. + ref: + https://stackoverflow.com/questions/14756347/when-calling-enumservicesstatusex-twice-i-still-get-eror-more-data-in-c + */ - c.queryAllServicesBuffer = make([]byte, bytesNeeded) + c.queryAllServicesBuffer = make([]byte, currentBufferSize+additionalBytesNeeded) } if servicesReturned == 0 {