From 9f1e4228faf7165dd27b0446fd9bfb65c9d46cc6 Mon Sep 17 00:00:00 2001 From: report02 <160653666+report02@users.noreply.github.com> Date: Thu, 21 May 2026 17:09:55 -0600 Subject: [PATCH] fix(windows): release remaining WinRT resources --- gap_windows.go | 41 ++++++++++++++++++++++++++++------------- gattc_windows.go | 17 +++++++++++++++++ gatts_windows.go | 18 +++++++++++++++--- 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/gap_windows.go b/gap_windows.go index 8f108081..6c9a00b0 100644 --- a/gap_windows.go +++ b/gap_windows.go @@ -73,6 +73,7 @@ func (a *Advertisement) Configure(options AdvertisementOptions) error { if err != nil { return err } + defer vec.Release() for _, optManData := range options.ManufacturerData { writer, err := streams.NewDataWriter() @@ -90,11 +91,13 @@ func (a *Advertisement) Configure(options AdvertisementOptions) error { if err != nil { return err } + defer buf.Release() manData, err := advertisement.BluetoothLEManufacturerDataCreate(optManData.CompanyID, buf) if err != nil { return err } + defer manData.Release() if err = vec.Append(unsafe.Pointer(&manData.IUnknown.RawVTable)); err != nil { return err @@ -233,27 +236,36 @@ func getScanResultFromArgs(args *advertisement.BluetoothLEAdvertisementReceivedE var manufacturerData []ManufacturerDataElement var serviceUUIDs []UUID - if winAdv, err := args.GetAdvertisement(); err == nil && winAdv != nil { - // Extract manufacturer data - vector, _ := winAdv.GetManufacturerData() - size, _ := vector.GetSize() + + // Extract manufacturer data + manDataVector, _ := winAdv.GetManufacturerData() + if manDataVector != nil { + defer manDataVector.Release() + size, _ := manDataVector.GetSize() for i := uint32(0); i < size; i++ { - element, _ := vector.GetAt(i) + element, _ := manDataVector.GetAt(i) manData := (*advertisement.BluetoothLEManufacturerData)(element) companyID, _ := manData.GetCompanyId() buffer, _ := manData.GetData() - manufacturerData = append(manufacturerData, ManufacturerDataElement{ - CompanyID: companyID, - Data: bufferToSlice(buffer), - }) + if buffer != nil { + manufacturerData = append(manufacturerData, ManufacturerDataElement{ + CompanyID: companyID, + Data: bufferToSlice(buffer), + }) + buffer.Release() + } + manData.Release() } + } - // Extract service UUIDs - vector, _ = winAdv.GetServiceUuids() - size, _ = vector.GetSize() + // Extract service UUIDs + serviceUuidsVector, _ := winAdv.GetServiceUuids() + if serviceUuidsVector != nil { + defer serviceUuidsVector.Release() + size, _ := serviceUuidsVector.GetSize() for i := uint32(0); i < size; i++ { - element, _ := vector.GetAt(i) + element, _ := serviceUuidsVector.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)) @@ -342,6 +354,7 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err if err != nil { return Device{}, err } + defer bleDeviceOp.Release() // We need to pass the signature of the parameter returned by the async operation: // IAsyncOperation @@ -367,6 +380,7 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err if err != nil { return Device{}, err } + defer dID.Release() // Windows does not support explicitly connecting to a device. // Instead it has the concept of a GATT session that is owned @@ -375,6 +389,7 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err if err != nil { return Device{}, err } + defer gattSessionOp.Release() if err := awaitAsyncOperation(gattSessionOp, genericattributeprofile.SignatureGattSession); err != nil { return Device{}, fmt.Errorf("error getting gatt session: %w", err) diff --git a/gattc_windows.go b/gattc_windows.go index 222c77ec..7df7ed70 100644 --- a/gattc_windows.go +++ b/gattc_windows.go @@ -53,6 +53,7 @@ func (d Device) DiscoverServices(filterUUIDs []UUID) ([]DeviceService, error) { if err != nil { return nil, err } + defer getServicesOperation.Release() if err := awaitAsyncOperation(getServicesOperation, genericattributeprofile.SignatureGattDeviceServicesResult); err != nil { return nil, err @@ -64,6 +65,7 @@ func (d Device) DiscoverServices(filterUUIDs []UUID) ([]DeviceService, error) { } servicesResult := (*genericattributeprofile.GattDeviceServicesResult)(res) + defer servicesResult.Release() status, err := servicesResult.GetStatus() if err != nil { @@ -77,6 +79,7 @@ func (d Device) DiscoverServices(filterUUIDs []UUID) ([]DeviceService, error) { if err != nil { return nil, err } + defer servicesVector.Release() // Convert services vector to array servicesSize, err := servicesVector.GetSize() @@ -197,6 +200,7 @@ func (s DeviceService) DiscoverCharacteristics(filterUUIDs []UUID) ([]DeviceChar if err != nil { return nil, err } + defer getCharacteristicsOp.Release() // IAsyncOperation if err := awaitAsyncOperation(getCharacteristicsOp, genericattributeprofile.SignatureGattCharacteristicsResult); err != nil { @@ -209,12 +213,14 @@ func (s DeviceService) DiscoverCharacteristics(filterUUIDs []UUID) ([]DeviceChar } gattCharResult := (*genericattributeprofile.GattCharacteristicsResult)(res) + defer gattCharResult.Release() // IVectorView charVector, err := gattCharResult.GetCharacteristics() if err != nil { return nil, err } + defer charVector.Release() // Convert characteristics vector to array characteristicsSize, err := charVector.GetSize() @@ -361,9 +367,14 @@ func (c DeviceCharacteristic) write(p []byte, mode genericattributeprofile.GattW if err != nil { return 0, err } + defer value.Release() // IAsyncOperation asyncOp, err := c.characteristic.WriteValueWithOptionAsync(value, mode) + if err != nil { + return 0, err + } + defer asyncOp.Release() if err := awaitAsyncOperation(asyncOp, genericattributeprofile.SignatureGattCommunicationStatus); err != nil { return 0, err @@ -395,6 +406,7 @@ func (c DeviceCharacteristic) Read(data []byte) (int, error) { if err != nil { return 0, err } + defer readOp.Release() // IAsyncOperation if err := awaitAsyncOperation(readOp, genericattributeprofile.SignatureGattReadResult); err != nil { @@ -407,16 +419,19 @@ func (c DeviceCharacteristic) Read(data []byte) (int, error) { } result := (*genericattributeprofile.GattReadResult)(res) + defer result.Release() buffer, err := result.GetValue() if err != nil { return 0, err } + defer buffer.Release() datareader, err := streams.DataReaderFromBuffer(buffer) if err != nil { return 0, err } + defer datareader.Release() bufferlen, err := buffer.GetLength() if err != nil { @@ -500,6 +515,7 @@ func (c DeviceCharacteristic) EnableNotificationsWithMode(mode NotificationMode, if err != nil { return } + defer buf.Release() reader, err := streams.DataReaderFromBuffer(buf) if err != nil { @@ -531,6 +547,7 @@ func (c DeviceCharacteristic) EnableNotificationsWithMode(mode NotificationMode, if err != nil { return err } + defer writeOp.Release() // IAsyncOperation if err := awaitAsyncOperation(writeOp, genericattributeprofile.SignatureGattCommunicationStatus); err != nil { diff --git a/gatts_windows.go b/gatts_windows.go index 598bb137..2cba4e2f 100644 --- a/gatts_windows.go +++ b/gatts_windows.go @@ -29,10 +29,10 @@ type Characteristic struct { // Service struct. func (a *Adapter) AddService(s *Service) error { gattServiceOp, err := genericattributeprofile.GattServiceProviderCreateAsync(syscallUUIDFromUUID(s.UUID)) - if err != nil { return err } + defer gattServiceOp.Release() if err = awaitAsyncOperation(gattServiceOp, genericattributeprofile.SignatureGattServiceProviderResult); err != nil { return err @@ -44,6 +44,7 @@ func (a *Adapter) AddService(s *Service) error { } serviceProviderResult := (*genericattributeprofile.GattServiceProviderResult)(res) + defer serviceProviderResult.Release() serviceProvider, err := serviceProviderResult.GetServiceProvider() if err != nil { return err @@ -73,6 +74,7 @@ func (a *Adapter) AddService(s *Service) error { if err != nil { return } + defer reqAsyncOp.Release() if err = awaitAsyncOperation(reqAsyncOp, genericattributeprofile.SignatureGattWriteRequest); err != nil { return @@ -84,11 +86,13 @@ func (a *Adapter) AddService(s *Service) error { } gattWriteRequest := (*genericattributeprofile.GattWriteRequest)(res) + defer gattWriteRequest.Release() buf, err := gattWriteRequest.GetValue() if err != nil { return } + defer buf.Release() offset, err := gattWriteRequest.GetOffset() if err != nil { @@ -126,6 +130,7 @@ func (a *Adapter) AddService(s *Service) error { if err != nil { return } + defer reqAsyncOp.Release() if err = awaitAsyncOperation(reqAsyncOp, genericattributeprofile.SignatureGattReadRequest); err != nil { return @@ -137,6 +142,7 @@ func (a *Adapter) AddService(s *Service) error { } gattReadRequest := (*genericattributeprofile.GattReadRequest)(res) + defer gattReadRequest.Release() characteristic := (*genericattributeprofile.GattLocalCharacteristic)(sender) uuid, err := characteristic.GetUuid() @@ -167,9 +173,9 @@ func (a *Adapter) AddService(s *Service) error { if err != nil { return } + defer buf.Release() gattReadRequest.RespondWithValue(buf) - buf.Release() }) for _, char := range s.Characteristics { @@ -179,14 +185,17 @@ func (a *Adapter) AddService(s *Service) error { } if err = params.SetCharacteristicProperties(genericattributeprofile.GattCharacteristicProperties(char.Flags)); err != nil { + params.Release() return err } uuid := syscallUUIDFromUUID(char.UUID) createCharOp, err := localService.CreateCharacteristicAsync(uuid, params) + params.Release() if err != nil { return err } + defer createCharOp.Release() if err = awaitAsyncOperation(createCharOp, genericattributeprofile.SignatureGattLocalCharacteristicResult); err != nil { return err @@ -198,6 +207,7 @@ func (a *Adapter) AddService(s *Service) error { } characteristicResults := (*genericattributeprofile.GattLocalCharacteristicResult)(res) + defer characteristicResults.Release() characteristic, err := characteristicResults.GetCharacteristic() if err != nil { return err @@ -228,6 +238,7 @@ func (a *Adapter) AddService(s *Service) error { if err != nil { return err } + defer params.Release() if err = params.SetIsConnectable(true); err != nil { return err @@ -243,10 +254,10 @@ func (a *Adapter) AddService(s *Service) error { // RemoveService stops advertising the service and removes it. func (a *Adapter) RemoveService(s *Service) error { gattServiceOp, err := genericattributeprofile.GattServiceProviderCreateAsync(syscallUUIDFromUUID(s.UUID)) - if err != nil { return err } + defer gattServiceOp.Release() if err = awaitAsyncOperation(gattServiceOp, genericattributeprofile.SignatureGattServiceProviderResult); err != nil { return err @@ -258,6 +269,7 @@ func (a *Adapter) RemoveService(s *Service) error { } serviceProviderResult := (*genericattributeprofile.GattServiceProviderResult)(res) + defer serviceProviderResult.Release() serviceProvider, err := serviceProviderResult.GetServiceProvider() if err != nil { return err