From 1a98472ad987308b74a991b1fbb618f086a7a21b Mon Sep 17 00:00:00 2001 From: Alexis Couvreur Date: Fri, 20 Mar 2026 16:58:05 -0400 Subject: [PATCH 1/2] fix(windows): add missing service UUIDs in scan results --- gap_windows.go | 58 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/gap_windows.go b/gap_windows.go index 171f96b6..a38db167 100644 --- a/gap_windows.go +++ b/gap_windows.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "syscall" "unsafe" "github.com/go-ole/go-ole" @@ -231,21 +232,44 @@ func getScanResultFromArgs(args *advertisement.BluetoothLEAdvertisementReceivedE defer winAdv.Release() var manufacturerData []ManufacturerDataElement - mVector, _ := winAdv.GetManufacturerData() - if mVector != nil { - defer mVector.Release() - mSize, _ := mVector.GetSize() - for i := uint32(0); i < mSize; i++ { - element, _ := mVector.GetAt(i) + var serviceUUIDs []UUID + if winAdv, err := args.GetAdvertisement(); err == nil && winAdv != nil { + // Extract manufacturer data + vector, _ := winAdv.GetManufacturerData() + size, _ := vector.GetSize() + for i := uint32(0); i < size; i++ { + element, _ := vector.GetAt(i) manData := (*advertisement.BluetoothLEManufacturerData)(element) + companyID, _ := manData.GetCompanyId() buffer, _ := manData.GetData() manufacturerData = append(manufacturerData, ManufacturerDataElement{ CompanyID: companyID, Data: bufferToSlice(buffer), }) - buffer.Release() - manData.Release() + } + + // Extract service UUIDs + vector, _ = winAdv.GetServiceUuids() + size, _ = vector.GetSize() + for i := uint32(0); i < size; i++ { + // Maybe we can use + // element, _ := vector.GetAt(i) + // serviceGUID := (*syscall.GUID)(element) + // ? + var outGuid syscall.GUID + hr, _, _ := syscall.SyscallN( + vector.VTable().GetAt, + uintptr(unsafe.Pointer(vector)), + uintptr(i), + uintptr(unsafe.Pointer(&outGuid)), + ) + if hr != 0 { + println("failed to get service UUID") + continue + } + uuid := GUIDToUUID(outGuid) + serviceUUIDs = append(serviceUUIDs, uuid) } } @@ -254,6 +278,7 @@ func getScanResultFromArgs(args *advertisement.BluetoothLEAdvertisementReceivedE result.AdvertisementPayload = &advertisementFields{ AdvertisementFields{ LocalName: localName, + ServiceUUIDs: serviceUUIDs, ManufacturerData: manufacturerData, }, } @@ -261,6 +286,23 @@ func getScanResultFromArgs(args *advertisement.BluetoothLEAdvertisementReceivedE return result } +func GUIDToUUID(guid syscall.GUID) UUID { + return NewUUID([16]byte{ + byte(guid.Data1 >> 24), + byte(guid.Data1 >> 16), + byte(guid.Data1 >> 8), + byte(guid.Data1), + byte(guid.Data2 >> 8), + byte(guid.Data2), + byte(guid.Data3 >> 8), + byte(guid.Data3), + guid.Data4[0], guid.Data4[1], + guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], + guid.Data4[6], guid.Data4[7], + }) +} + func bufferToSlice(buffer *streams.IBuffer) []byte { dataReader, _ := streams.DataReaderFromBuffer(buffer) defer dataReader.Release() From ec2e68788fe8360471aa9751ddce75a7f1c873a7 Mon Sep 17 00:00:00 2001 From: Alexis Couvreur Date: Fri, 10 Apr 2026 17:26:42 +0200 Subject: [PATCH 2/2] apply code review feedback --- gap_windows.go | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/gap_windows.go b/gap_windows.go index a38db167..f580fb99 100644 --- a/gap_windows.go +++ b/gap_windows.go @@ -253,22 +253,11 @@ func getScanResultFromArgs(args *advertisement.BluetoothLEAdvertisementReceivedE vector, _ = winAdv.GetServiceUuids() size, _ = vector.GetSize() for i := uint32(0); i < size; i++ { - // Maybe we can use - // element, _ := vector.GetAt(i) - // serviceGUID := (*syscall.GUID)(element) - // ? - var outGuid syscall.GUID - hr, _, _ := syscall.SyscallN( - vector.VTable().GetAt, - uintptr(unsafe.Pointer(vector)), - uintptr(i), - uintptr(unsafe.Pointer(&outGuid)), - ) - if hr != 0 { - println("failed to get service UUID") - continue - } - uuid := GUIDToUUID(outGuid) + element, _ := vector.GetAt(i) + // element is not a pointer, but a GUID struct. But we cannot convert + // unsafe.Pointer to a non-pointer type, so instead we are doing this: + serviceGUID := (*syscall.GUID)(unsafe.Pointer(&element)) + uuid := GUIDToUUID(*serviceGUID) serviceUUIDs = append(serviceUUIDs, uuid) } }