commit a6c09a58908bbfc43d96f629f0211d20a4755c71 Author: Alex Savin Date: Fri Aug 22 17:42:23 2025 -0400 first commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d207b18 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.go text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..acf56c4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin +.vscode diff --git a/.go-builder/.errcheck.exclude b/.go-builder/.errcheck.exclude new file mode 100644 index 0000000..d84134f --- /dev/null +++ b/.go-builder/.errcheck.exclude @@ -0,0 +1,4 @@ +(github.com/saltosystems/x/log.Logger).Error +(github.com/saltosystems/x/log.Logger).Info +(github.com/saltosystems/x/log.Logger).Warn +(github.com/saltosystems/x/log.Logger).Debug diff --git a/.go-builder/.golangci.yml b/.go-builder/.golangci.yml new file mode 100644 index 0000000..3f2dfb8 --- /dev/null +++ b/.go-builder/.golangci.yml @@ -0,0 +1,56 @@ +linters: + enable: + # golangci-lint curated list of linters (as of 1.42.1) + - deadcode + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + # Our own extra sauce + # Temporarily disable this linter until underlying issues for the 1.18 support + # are fixed: + # * https://github.com/go-critic/go-critic/issues/1193 + #- gocritic + - goimports + - revive + - exportloopref + - unparam + - ifshort + - gosec + disable-all: true + +issues: + exclude-use-default: false + exclude: + # Ignore err, ctx and ok variables shadowing, which are quite common and in principle, uncritical cases. + - 'declaration of "err|ctx|ok" shadows declaration at' + +linters-settings: + errcheck: + exclude: .go-builder/.errcheck.exclude + + gocritic: + enabled-tags: + - diagnostic + - style + - performance + disabled-checks: + - unnamedResult + + govet: + check-shadowing: true + + gosec: + excludes: + - G104 + +run: + build-tags: + - integration + - unit + - e2e diff --git a/.go-builder/Makefile b/.go-builder/Makefile new file mode 100644 index 0000000..b23a89c --- /dev/null +++ b/.go-builder/Makefile @@ -0,0 +1,142 @@ +SHELL ?= /bin/bash +NAME = $(shell echo $(PACKAGE) | rev | cut -d/ -f1 | rev) +PLATFORM ?= linux darwin windows +DOCKER = $(shell command -v docker 2>/dev/null) +REPORTS_DIR ?= .reports +PREFIX ?= gcr.io/salto-containers +BUILD_TAGS ?= +SANITY_CHECKING_CONFIG ?= .go-builder/.golangci.yml + +# Overridable by CI + +COMMIT_SHORT ?= $(shell git rev-parse --verify --short HEAD) +VERSION ?= v0.0.0-sha.$(COMMIT_SHORT) +VERSION_NOPREFIX ?= $(shell echo $(VERSION) | sed -e 's/^[[v]]*//') + +# +# Common methodology based targets +# + +prepare_targets = mod-download +sanity_check_targets = check-sync golangci-lint mod-verify mod-check +build_targets = go-build +test_targets = +release_targets = +clean_targets = app-clean + +# If there's a build container then also run the docker build and release +ifneq ("$(wildcard build/container/Dockerfile)","") +build_targets += docker-build +release_targets += docker-push +endif + +# +# Global checks +# + +ifndef PACKAGE +$(error You must define the mandatory PACKAGE variable) +endif + +ifndef PKG +$(error You must define the mandatory PKG variable) +endif + +ifndef APP +$(error You must define the mandatory APP variable) +endif + +# +# Custom project related targets +# + +.PHONY: mod-download +mod-download: + @echo "Running mod download..." + @go mod download + +.PHONY: golangci-lint +golangci-lint: + @echo "Running golangci-lint..." + @golangci-lint run $(PKG) --timeout 30m -v --config=$(SANITY_CHECKING_CONFIG) + + +# Another modules verification apart from mod-verify step should be to ensure that go mod tidy has been run on dev box when this gets fixed: +# https://github.com/golang/go/issues/27005 +.PHONY: mod-verify +mod-verify: + @echo "Running mod verify..." + @go mod verify + +# Replace this temporary "hack" with `go mod check` feature once implemented: +# https://github.com/golang/go/issues/27005 +.PHONY: mod-check +mod-check: + @echo "Running mod check..." + @go mod tidy && git diff --exit-code -- 'go.mod' 'go.sum' > /dev/null \ + || (echo "mod-check failed, run \"go mod tidy\", commit the \"go.mod\" and/or \"go.sum\" files and try again"; exit 1) + +.PHONY: go-build +go-build: + @for app in $(APP) ; do \ + for os in $(PLATFORM) ; do \ + ext=""; \ + if [ "$$os" == "windows" ]; then \ + ext=".exe"; \ + fi; \ + GOOS=$$os GOARCH=amd64 CGO_ENABLED=0 \ + go build \ + -a -x -tags "$(BUILD_TAGS)" -installsuffix cgo -installsuffix netgo \ + -ldflags " \ + -X main.Version=$(VERSION_NOPREFIX) \ + -X main.GitRev=$(COMMIT_SHORT) \ + " \ + -o ./bin/$$app-$(VERSION_NOPREFIX)-$$os-amd64$$ext \ + ./cmd/$$app; \ + done; \ + done + +.PHONY: docker-build +docker-build: + @echo "Building docker image..." + @for app in $(APP) ; do \ + cp bin/$$app-$(VERSION_NOPREFIX)-linux-amd64 build/container/$$app-linux-amd64; \ + chmod 0755 build/container/$$app-linux-amd64; \ + done; \ + "$(DOCKER)" build \ + -f build/container/Dockerfile \ + -t $(PREFIX)/$(NAME):$(VERSION) \ + build/container/ + +.PHONY: docker-push +docker-push: + @echo "Pushing docker image..." + "$(DOCKER)" push $(PREFIX)/$(NAME):$(VERSION); \ + +.PHONY: app-clean +app-clean: + rm -f ./bin/* + @for app in $(APP) ; do \ + rm -f cmd/$$app/*-linux-amd64; \ + done + +.PHONY: check-sync +check-sync: + @echo "Checking if everything is in sync..." + @.go-builder/scripts/check-sync.sh + +.PHONY: sync-local +sync-local: + @echo "Synchronizing..." + @mv .go-builder .go-builder-tmp + @if docker run -v $(shell pwd):/workspace --rm -it $(shell docker build -q -f Dockerfile.build . | head -n 1) cp -r /etc/go-builder /workspace/.go-builder; then \ + rm -r .go-builder-tmp; \ + else \ + mv .go-builder-tmp .go-builder; \ + fi + +# +# Debug any makefile variable +# Usage: print- +# +print-% : ; @echo $* = $($*) diff --git a/.go-builder/scripts/check-sync.sh b/.go-builder/scripts/check-sync.sh new file mode 100644 index 0000000..d96c2b4 --- /dev/null +++ b/.go-builder/scripts/check-sync.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -u +set -e + +if [ -d /etc/go-builder ]; then + diff -rq .go-builder /etc/go-builder + exit $? +else + echo "check-sync is not running in builder's docker image. Skipping..." + exit 0 +fi diff --git a/Dockerfile.build b/Dockerfile.build new file mode 100644 index 0000000..24333c8 --- /dev/null +++ b/Dockerfile.build @@ -0,0 +1,10 @@ +FROM saltosystems/go-builder:2471083 + +ENV PKGPATH github.com/saltosystems/winrt-go + +# include workspace .gitconfig in global .gitconfig +RUN git config --global include.path "${GOPATH}/src/${PKGPATH}/.gitconfig" + +# copy current workspace +COPY . ${GOPATH}/src/${PKGPATH} +WORKDIR ${GOPATH}/src/${PKGPATH} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d0ef47e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 SALTO SYSTEMS, S.L + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..567dcaf --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +PACKAGE = github.com/saltosystems/winrt-go +PKG ?= ./... +APP ?= winrt-go-gen +BUILD_TAGS ?= + +include .go-builder/Makefile + +.PHONY: prepare +prepare: $(prepare_targets) + +.PHONY: sanity-check +sanity-check: $(sanity_check_targets) check-generated + +.PHONY: build +build: $(build_targets) + +.PHONY: test +test: $(test_targets) go-test + +.PHONY: release +release: $(release_targets) + +.PHONY: clean +clean: $(clean_targets) + +.PHONY: gen-files +gen-files: + rm -rf $(CURDIR)/windows + go generate github.com/saltosystems/winrt-go/... + +.PHONY: check-generated +check-generated: export WINRT_GO_GEN_VALIDATE=1 +check-generated: + go generate github.com/saltosystems/winrt-go/... + +.PHONY: go-test +go-test: + go test github.com/saltosystems/winrt-go/... diff --git a/README.md b/README.md new file mode 100644 index 0000000..7df90eb --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# The WinRT Go language projection + +WinRT Go is an autogenerated language projection for Windows Runtime (WinRT) APIs. + +The project was originally intended to assist in the development of the Windows implementation of the [tinygo-org/bluetooth](https://github.com/tinygo-org/bluetooth) library. +That's why it currently only contains WinRT APIs related to Bluetooth, but we are open to include new APIs if requested. + +> [!IMPORTANT] +> Due to the nature of this project we decided not to tag any releases. +> All commits to the `main` branch are considered stable, and we encourage you to use the latest commit available. +> +> Breaking changes in the `main` branch should be an exception, but we may include them in favor of the simplicity of the project. + +The project also contains the `winrt-go-gen` code generator and the source Windows Metadata (WinMD) files (located in `/internal/winmd/metadata`) that describe the WinRT APIs. + +Notice that the code generator is not capable of generating any WinRT types. +It will work with most of them, but we've added the functionalities we exclusively needed to generate the BLE APIs. +So some things may still be missing. +Check out the [known missing features](#known-missing-features) section below for more information. + +## Generated code + +All the generated code is stored in the `windows` folder, and is divided in folders that match the namespace of each class. + +Since our goal was to only use a subset of the WinRT APIs, the generated classes may only contain a subset of their methods. +This helps us generate less code, because we can remove dependencies between classes and completely skip their generation. + +Also notice that the generated method names may differ from the ones defined in the WinRT API. +This is because Go does not support method overloading, so we are using the overload name defined in the WinMD files. +The [`GetGattServicesAsync` method](https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothledevice.getgattservicesasync?view=winrt-22621), for example, has an attribute defining the following overload name: `GetGattServicesWithCacheModeAsync`. + +This also affects static methods, which include their class name as prefix to avoid collisions between classes inside the same package. + +## Generating the code + +The code is generated using `go generate`. But the Makefile includes a target (`make gen-files`) that removes all generated code and executes the `go generate` command. + +You can also call the code generator manually. + +``` +Usage of winrt-go-gen: + -class string + The class to generate. This should include the namespace and the class name, e.g. 'System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken'. + -config string + config file (optional) + -debug + Enables the debug logging. + -method-filter value + The filter to use when generating the methods. This option can be set several times, + the given filters will be applied in order, and the first that matches will determine the result. The generator + will allow any method by default. The filter uses the overloaded method name to discriminate between overloaded + methods. + + You can use the '!' character to negate a filter. For example, to generate all methods except the 'Add' method: + -method-filter !Add + + You can also use the '*' character to match any method, so if you want to generate only the 'Add' method, you can do: + -method-filter Add -method-filter !* +``` + +## Known missing features + +- If an interface extends another one, the methods of the parent interface are not generated. +- There are still some unsupported data types: + - Multi-dimensional arrays (`ELEMENT_TYPE_ARRAY`) + - References (`ELEMENT_TYPE_BYREF`) + - Pointer to functions (`ELEMENT_TYPE_FNPTR`) + - Pointer types (`ELEMENT_TYPE_PTR`) + - Typed references (`ELEMENT_TYPE_TYPEDBYREF`) diff --git a/cmd/winrt-go-gen/main.go b/cmd/winrt-go-gen/main.go new file mode 100644 index 0000000..c06a78f --- /dev/null +++ b/cmd/winrt-go-gen/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "flag" + "os" + "strings" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + "github.com/peterbourgon/ff/v3" + "github.com/saltosystems/winrt-go/internal/cli" +) + +func main() { + logger := createLogger() + winrtGoGenCmd := cli.NewGenerateCommand(logger) + + err := winrtGoGenCmd.Execute(os.Args[1:], func(fs *flag.FlagSet, args []string) error { + return ff.Parse(fs, args, + ff.WithConfigFileFlag("config"), + ff.WithConfigFileParser(ff.PlainParser), + ff.WithEnvVarPrefix(strings.ToUpper(strings.ReplaceAll(winrtGoGenCmd.Name(), "-", "_"))), + ) + }) + if err != nil { + _ = level.Error(logger).Log("err", err) + os.Exit(1) + } +} + +func createLogger() log.Logger { + var logger log.Logger + logger = log.NewLogfmtLogger(os.Stderr) + logger = log.With(logger, "ts", log.DefaultTimestampUTC) + logger = level.NewInjector(logger, level.InfoValue()) + + return logger +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..26ee8f2 --- /dev/null +++ b/go.mod @@ -0,0 +1,22 @@ +module github.com/saltosystems/winrt-go + +go 1.18 + +require ( + github.com/glerchundi/subcommands v0.0.0-20181212083838-923a6ccb11f8 + github.com/go-kit/log v0.2.1 + github.com/go-ole/go-ole v1.2.6 + github.com/peterbourgon/ff/v3 v3.1.2 + github.com/stretchr/testify v1.7.5 + github.com/tdakkota/win32metadata v0.1.0 + golang.org/x/sys v0.0.0-20220624220833-87e55d714810 + golang.org/x/tools v0.1.11 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logfmt/logfmt v0.5.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..1f400f2 --- /dev/null +++ b/go.sum @@ -0,0 +1,58 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/glerchundi/subcommands v0.0.0-20181212083838-923a6ccb11f8 h1:RlQI4RJwlknlSycN+MmXzq1O3k9ruRWRlYHfLgRy824= +github.com/glerchundi/subcommands v0.0.0-20181212083838-923a6ccb11f8/go.mod h1:r0g3O7Y5lrWXgDfcFBRgnAKzjmPgTzwoMC2ieB345FY= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= +github.com/peterbourgon/ff/v3 v3.1.2 h1:0GNhbRhO9yHA4CC27ymskOsuRpmX0YQxwxM9UPiP6JM= +github.com/peterbourgon/ff/v3 v3.1.2/go.mod h1:XNJLY8EIl6MjMVjBS4F0+G0LYoAqs0DTa4rmHHukKDE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q= +github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/tdakkota/win32metadata v0.1.0 h1:0xoy5sPaOy8QDRc16hdvuFD4suyCVO2m37V8zdIk2kI= +github.com/tdakkota/win32metadata v0.1.0/go.mod h1:77e6YvX0LIVW+O81fhWLnXAxxcyu/wdZdG7iwed7Fyk= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810 h1:rHZQSjJdAI4Xf5Qzeh2bBc5YJIkPFVM6oDtMFYmgws0= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY= +golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/cli/cli.go b/internal/cli/cli.go new file mode 100644 index 0000000..811293a --- /dev/null +++ b/internal/cli/cli.go @@ -0,0 +1,44 @@ +package cli + +import ( + "flag" + + "github.com/glerchundi/subcommands" + "github.com/go-kit/log" + "github.com/go-kit/log/level" + + "github.com/saltosystems/winrt-go/internal/codegen" +) + +const methodFilterUsage = `The filter to use when generating the methods. This option can be set several times, +the given filters will be applied in order, and the first that matches will determine the result. The generator +will allow any method by default. The filter uses the overloaded method name to discriminate between overloaded +methods. + +You can use the '!' character to negate a filter. For example, to generate all methods except the 'Add' method: + -method-filter !Add + +You can also use the '*' character to match any method, so if you want to generate only the 'Add' method, you can do: + -method-filter Add -method-filter !*` + +// NewGenerateCommand returns a new subcommand for generating code. +func NewGenerateCommand(logger log.Logger) *subcommands.Command { + cfg := codegen.NewConfig() + fs := flag.NewFlagSet("winrt-go-gen", flag.ExitOnError) + _ = fs.String("config", "", "config file (optional)") + fs.BoolVar(&cfg.ValidateOnly, "validate", cfg.ValidateOnly, "validate the existing code instead of generating it") + fs.StringVar(&cfg.Class, "class", cfg.Class, "The class to generate. This should include the namespace and the class name, e.g. 'System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken'.") + fs.Func("method-filter", methodFilterUsage, func(m string) error { + cfg.AddMethodFilter(m) + return nil + }) + fs.BoolVar(&cfg.Debug, "debug", cfg.Debug, "Enables the debug logging.") + return subcommands.NewCommand(fs.Name(), fs, func() error { + if cfg.Debug { + logger = level.NewFilter(logger, level.AllowDebug()) + } else { + logger = level.NewFilter(logger, level.AllowInfo()) + } + return codegen.Generate(cfg, logger) + }) +} diff --git a/internal/codegen/codegen.go b/internal/codegen/codegen.go new file mode 100644 index 0000000..27b8a50 --- /dev/null +++ b/internal/codegen/codegen.go @@ -0,0 +1,1260 @@ +package codegen + +import ( + "bytes" + "fmt" + "go/format" + "os" + "path/filepath" + "strings" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + "github.com/saltosystems/winrt-go" + "github.com/saltosystems/winrt-go/internal/winmd" + "github.com/tdakkota/win32metadata/types" + "golang.org/x/tools/imports" +) + +// Delegate constants +const ( + invokeMethodName = "Invoke" +) + +type generator struct { + class string + validateOnly bool + methodFilter *MethodFilter + + logger log.Logger + + genDataFiles []*genDataFile + + mdStore *winmd.Store +} + +// Generate generates the code for the given config. +func Generate(cfg *Config, logger log.Logger) error { + if err := cfg.Validate(); err != nil { + return err + } + + mdStore, err := winmd.NewStore(logger) + if err != nil { + return err + } + + g := &generator{ + class: cfg.Class, + validateOnly: cfg.ValidateOnly, + methodFilter: cfg.MethodFilter(), + logger: logger, + mdStore: mdStore, + } + return g.run() +} + +func (g *generator) run() error { + _ = level.Debug(g.logger).Log("msg", "starting code generation", "class", g.class) + + typeDef, err := g.mdStore.TypeDefByName(g.class) + if err != nil { + return err + } + + return g.generate(typeDef) +} + +func (g *generator) generate(typeDef *winmd.TypeDef) error { + + // we only support WinRT types: check the tdWindowsRuntime flag (0x4000) + // https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files#runtime-classes + if typeDef.Flags&0x4000 == 0 { + return fmt.Errorf("%s.%s is not a WinRT class", typeDef.TypeNamespace, typeDef.TypeName) + } + + // get data & execute templates + if err := g.loadCodeGenData(typeDef); err != nil { + return err + } + + for _, fData := range g.genDataFiles { + if err := g.generateDataFile(fData, typeDef); err != nil { + return err + } + } + return nil +} + +func (g *generator) generateDataFile(fData *genDataFile, typeDef *winmd.TypeDef) error { + // get templates + tmpl, err := getTemplates() + if err != nil { + return err + } + + fData.Data.ComputeImports(typeDef) + + var buf bytes.Buffer + if err := tmpl.ExecuteTemplate(&buf, "file.tmpl", fData.Data); err != nil { + return err + } + + // use go imports to cleanup imports + goimported, err := imports.Process(fData.Filename, buf.Bytes(), nil) + if err != nil { + return err + } + + // format the output source code + formatted, err := format.Source(goimported) + if err != nil { + return err + } + + if g.validateOnly { + // validate existing file content + return g.validateFileContent(fData, formatted) + } + + // create file & write contents + return g.writeFile(fData, formatted) +} + +func (g *generator) validateFileContent(fData *genDataFile, genContent []byte) error { + // validate existing content + existingContent, err := os.ReadFile(fData.Filename) + if err != nil { + return err + } + + // compare existing content to generated + _ = level.Debug(g.logger).Log("msg", "validating generated code", "filename", fData.Filename) + if string(existingContent) != string(genContent) { + return fmt.Errorf("file %s does not contain expected content", fData.Filename) + } + return nil +} + +func (g *generator) writeFile(fData *genDataFile, content []byte) error { + parts := strings.Split(fData.Filename, "/") + folder := strings.Join(parts[:len(parts)-1], "/") + err := os.MkdirAll(folder, os.ModePerm) + if err != nil { + return err + } + file, err := os.Create(filepath.Clean(fData.Filename)) + if err != nil { + return err + } + defer func() { _ = file.Close() }() + + // and write it to file + _, err = file.Write(content) + if err != nil { + return err + } + + return nil +} + +func (g *generator) loadCodeGenData(typeDef *winmd.TypeDef) error { + f := g.addFile(typeDef, "") + + switch { + case typeDef.IsInterface(): + _ = level.Info(g.logger).Log("msg", "generating interface", "interface", typeDef.TypeNamespace+"."+typeDef.TypeName) + + if err := g.validateInterface(typeDef); err != nil { + return err + } + + iface, err := g.createGenInterface(typeDef, false) + if err != nil { + return err + } + f.Data.Interfaces = append(f.Data.Interfaces, iface) + case typeDef.IsEnum(): + _ = level.Info(g.logger).Log("msg", "generating enum", "enum", typeDef.TypeNamespace+"."+typeDef.TypeName) + + enum, err := g.createGenEnum(typeDef) + if err != nil { + return err + } + f.Data.Enums = append(f.Data.Enums, enum) + case typeDef.IsStruct(): + _ = level.Info(g.logger).Log("msg", "generating struct", "struct", typeDef.TypeNamespace+"."+typeDef.TypeName) + + genStruct, err := g.createGenStruct(typeDef) + if err != nil { + return err + } + f.Data.Structs = append(f.Data.Structs, genStruct) + case typeDef.IsDelegate(): + delegate, err := g.createGenDelegate(typeDef) + if err != nil { + return err + } + f.Data.Delegates = append(f.Data.Delegates, delegate) + default: + _ = level.Info(g.logger).Log("msg", "generating class", "class", typeDef.TypeNamespace+"."+typeDef.TypeName) + + class, err := g.createGenClass(typeDef) + if err != nil { + return err + } + f.Data.Classes = append(f.Data.Classes, class) + } + + return nil +} + +func (g *generator) addFile(typeDef *winmd.TypeDef, suffix string) *genDataFile { + folder := typeToFolder(typeDef.TypeNamespace, typeDef.TypeName) + filename := folder + "/" + typeFilename(typeDef.TypeName) + suffix + ".go" + f := genDataFile{ + Filename: filename, + Data: genData{ + Package: typePackage(typeDef.TypeNamespace, typeDef.TypeName), + }, + } + g.genDataFiles = append(g.genDataFiles, &f) + return &f +} + +func (g *generator) validateInterface(typeDef *winmd.TypeDef) error { + // Any WinRT interface with private visibility must have a single ExclusiveToAttribute. + // the ExclusiveToAttribute must reference a runtime class. + + // we do not support generating these types of classes, they are exclusive to a runtime class, + // and thus will be generated when the runtime class is generated. + + if typeDef.Flags.NotPublic() { + return fmt.Errorf("interface %s is not public", typeDef.TypeNamespace+"."+typeDef.TypeName) + } + return nil +} + +// https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files#interfaces +func (g *generator) createGenInterface(typeDef *winmd.TypeDef, requiresActivation bool) (*genInterface, error) { + funcs, err := g.getGenFuncs(typeDef, requiresActivation) + if err != nil { + return nil, err + } + + // Interfaces' TypeDef rows must have a GuidAttribute as well as a VersionAttribute. + guid, err := typeDef.GUID() + if err != nil { + return nil, err + } + + typeSig, err := g.Signature(typeDef) + if err != nil { + return nil, err + } + + return &genInterface{ + Name: typeDefGoName(typeDef.TypeName, typeDef.Flags.Public()), + GUID: guid, + Signature: typeSig, + Funcs: funcs, + }, nil +} + +// https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files#runtime-classes +func (g *generator) createGenClass(typeDef *winmd.TypeDef) (*genClass, error) { + var requiredImports []*genImport + var exclusiveInterfaceTypes []*winmd.TypeDef + + // true => interface requires activation, false => interface is implemented by this class + activatedInterfaces := make(map[string]bool) + + // get all the interfaces this class implements + interfaces, err := typeDef.GetImplementedInterfaces() + if err != nil { + return nil, err + } + implInterfaces := make([]*genInterface, 0, len(interfaces)) + for _, iface := range interfaces { + // the interface needs to be implemented by this class + requiredImports = append(requiredImports, &genImport{iface.Namespace, iface.Name}) + + ifaceTypeDef, err := g.mdStore.TypeDefByName(iface.Namespace + "." + iface.Name) + if err != nil { + return nil, err + } + + itf, err := g.createGenInterface(ifaceTypeDef, false) + if err != nil { + return nil, err + } + + pkg := "" + if typeDef.TypeNamespace != ifaceTypeDef.TypeNamespace { + pkg = typePackage(iface.Namespace, iface.Name) + } + for _, f := range itf.Funcs { + f.InheritedFrom = winmd.QualifiedID{ + Namespace: pkg, + Name: typeDefGoName(ifaceTypeDef.TypeName, ifaceTypeDef.Flags.Public()), + } + } + + implInterfaces = append(implInterfaces, itf) + + // The interface we implement may be exclusive to this class, in which case we need to generate it. + // An exclusive (private) interface should always belong to the same winmd file. So even if this is + // a TypeRef, the class should be found using its name. + if td, err := g.mdStore.TypeDefByName(iface.Namespace + "." + iface.Name); err == nil { + if _, ok := g.interfaceIsExclusiveTo(td); ok { + exclusiveInterfaceTypes = append(exclusiveInterfaceTypes, td) + activatedInterfaces[td.TypeNamespace+"."+td.TypeName] = false // implemented interfaces do not require activation + } + } + } + + // Runtime classes have zero or more StaticAttribute custom attributes + // https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files#static-interfaces + staticAttributeBlobs := typeDef.GetTypeDefAttributesWithType(winmd.AttributeTypeStaticAttribute) + for _, blob := range staticAttributeBlobs { + class := extractClassFromBlob(blob) + _ = level.Debug(g.logger).Log("msg", "found static interface", "class", class) + staticClass, err := g.mdStore.TypeDefByName(class) + if err != nil { + _ = level.Error(g.logger).Log("msg", "static class defined in StaticAttribute not found", "class", class, "err", err) + return nil, err + } + + exclusiveInterfaceTypes = append(exclusiveInterfaceTypes, staticClass) + activatedInterfaces[staticClass.TypeNamespace+"."+staticClass.TypeName] = true // static interfaces require activation + } + + // Runtime classes have zero or more ActivatableAttribute custom attributes + // https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files#activation + activatableAttributeBlobs := typeDef.GetTypeDefAttributesWithType(winmd.AttributeTypeActivatableAttribute) + hasEmptyConstructor := false + for _, blob := range activatableAttributeBlobs { + // check for empty constructor + if activatableAttrIsEmpty(blob) { + // this activatable attribute is empty, so the class has an empty constructor + hasEmptyConstructor = true + continue + } + + // check for an activation interface + class := extractClassFromBlob(blob) + _ = level.Debug(g.logger).Log("msg", "found activatable interface", "class", class) + activatableClass, err := g.mdStore.TypeDefByName(class) + if err != nil { + // the activatable class may be empty in some cases, example: + // https://github.com/tpn/winsdk-10/blob/9b69fd26ac0c7d0b83d378dba01080e93349c2ed/Include/10.0.14393.0/winrt/windows.devices.bluetooth.advertisement.idl#L518 + _ = level.Error(g.logger).Log("msg", "activatable class defined in ActivatableAttribute not found", "class", class, "err", err) + + // so do not fail + continue + } + exclusiveInterfaceTypes = append(exclusiveInterfaceTypes, activatableClass) + activatedInterfaces[activatableClass.TypeNamespace+"."+activatableClass.TypeName] = true // activatable interfaces require activation + } + + // generate exclusive interfaces + var exclusiveGenInterfaces []*genInterface + for _, iface := range exclusiveInterfaceTypes { + requiresActivation := activatedInterfaces[iface.TypeNamespace+"."+iface.TypeName] + isExtendedInterface := !requiresActivation + + ifaceGen, err := g.createGenInterface(iface, requiresActivation) + if err != nil { + return nil, err + } + + // if all methods from the exclusive interface have been filtered, and the interface + // is an activated interface, then we can skip it. + impl := false + for _, m := range ifaceGen.Funcs { + if m.Implement { + impl = true + } + } + + // Extended interfaces always need to be generated (even if they have no method). + if isExtendedInterface || impl { + exclusiveGenInterfaces = append(exclusiveGenInterfaces, ifaceGen) + } + } + + typeSig, err := g.Signature(typeDef) + if err != nil { + return nil, err + } + + return &genClass{ + Name: typeDefGoName(typeDef.TypeName, typeDef.Flags.Public()), + Signature: typeSig, + RequiresImports: requiredImports, + FullyQualifiedName: typeDef.TypeNamespace + "." + typeDef.TypeName, + ImplInterfaces: implInterfaces, + ExclusiveInterfaces: exclusiveGenInterfaces, + HasEmptyConstructor: hasEmptyConstructor, + IsAbstract: typeDef.Flags.Abstract(), + }, nil +} + +// https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files#enums +func (g *generator) createGenEnum(typeDef *winmd.TypeDef) (*genEnum, error) { + fields, err := typeDef.ResolveFieldList(typeDef.Ctx()) + if err != nil { + return nil, err + } + + // An enum has a single instance field that specifies the underlying integer type for the enum, + // as well as zero or more static fields; one for each enum value defined by the enum type. + if len(fields) == 0 { + return nil, fmt.Errorf("enum %s has no fields", typeDef.TypeName) + } + + // the first row should be the underlying integer type of the enum. It must have the following flags: + if !(fields[0].Flags.Private() && fields[0].Flags.SpecialName() && fields[0].Flags.RTSpecialName()) { + return nil, fmt.Errorf("enum %s has more than one instance field, expected 1", typeDef.TypeNamespace+"."+typeDef.TypeName) + } + + fieldSig, err := fields[0].Signature.Reader().Field(typeDef.Ctx()) + if err != nil { + return nil, err + } + elType, err := g.elementType(typeDef.Ctx(), fieldSig.Field) + if err != nil { + return nil, err + } + // this will always be a primitive type, so we can just use the name + enumType := elType.name + + // After the enum value definition comes a field definition for each of the values in the enumeration. + var enumValues []*genEnumValue + for i, field := range fields[1:] { + if !(field.Flags.Public() && field.Flags.Static() && field.Flags.Literal() && field.Flags.HasDefault()) { + return nil, + fmt.Errorf( + "enum %s field value does not comply with the spec. Checkout https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files#enums", + typeDef.TypeNamespace+"."+typeDef.TypeName, + ) + } + + var fieldIndex uint32 = typeDef.FieldList.Start() + 1 + uint32(i) + enumRawValue, err := typeDef.GetValueForEnumField(fieldIndex) + if err != nil { + return nil, err + } + + enumValues = append(enumValues, &genEnumValue{ + Name: enumName(typeDef.TypeName, field.Name), + Value: enumRawValue, + }) + } + + typeSig, err := g.Signature(typeDef) + if err != nil { + return nil, err + } + + return &genEnum{ + Name: typeDefGoName(typeDef.TypeName, typeDef.Flags.Public()), + Type: enumType, + Signature: typeSig, + Values: enumValues, + }, nil +} + +// https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files#structs +func (g *generator) createGenStruct(typeDef *winmd.TypeDef) (*genStruct, error) { + // structs do not have methods, only fields + fields, err := typeDef.ResolveFieldList(typeDef.Ctx()) + if err != nil { + return nil, err + } + + curPkg := typePackage(typeDef.TypeNamespace, typeDef.TypeName) + + var genFields []*genParam + for _, f := range fields { + fSig, err := f.Signature.Reader().Field(typeDef.Ctx()) + if err != nil { + return nil, err + } + + fieldType, err := g.elementType(typeDef.Ctx(), fSig.Field) + if err != nil { + return nil, err + } + + // Struct fields must be fundamental types, enums, or other structs + genFields = append(genFields, &genParam{ + callerPackage: curPkg, + varName: cleanReservedWords(f.Name), + IsOut: false, + Type: fieldType, + }) + } + + typeSig, err := g.Signature(typeDef) + if err != nil { + return nil, err + } + + return &genStruct{ + Name: typeDefGoName(typeDef.TypeName, typeDef.Flags.Public()), + Signature: typeSig, + Fields: genFields, + }, nil +} + +// https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files#delegates +func (g *generator) createGenDelegate(typeDef *winmd.TypeDef) (*genDelegate, error) { + // FieldList: must be empty + // MethodList: An index into the MethodDef table (ECMA II.22.26), marking the first of a contiguous run of methods owned by this type. + // Delegates' TypeDef rows must have a GuidAttribute + guid, err := typeDef.GUID() + if err != nil { + return nil, err + } + + // Delegates have exactly two MethodDef table entries. The first defines a constructor. + methods, err := typeDef.ResolveMethodList(typeDef.Ctx()) + if err != nil { + return nil, err + } + + if len(methods) != 2 { + return nil, fmt.Errorf("delegate %s has more than two methods", typeDef.TypeNamespace+"."+typeDef.TypeName) + } + + // This constructor is a compatibility marker. WinRT Delegates have no such constructor method. + + // We only care about the invoke method + invokeMethod := methods[1] + if invokeMethod.Name != invokeMethodName { + return nil, fmt.Errorf("found method '%s' on delegate %s but expected '%s'", + invokeMethod.Name, + typeDef.TypeNamespace+"."+typeDef.TypeName, + invokeMethodName, + ) + } + + // this is going to be used to define the callback type. We don't + // really need the whole function, only its input parameters, + // so we can reuse the logic used for getting them. + f, err := g.genFuncFromMethod(typeDef, &invokeMethod, "", false) + if err != nil { + return nil, err + } + + typeSig, err := g.Signature(typeDef) + if err != nil { + return nil, err + } + + return &genDelegate{ + Name: typeDefGoName(typeDef.TypeName, true), + GUID: guid, + Signature: typeSig, + InParams: f.InParams, + }, nil +} + +func (g *generator) interfaceIsExclusiveTo(typeDef *winmd.TypeDef) (string, bool) { + exclusiveToBlob, err := typeDef.GetAttributeWithType(winmd.AttributeTypeExclusiveTo) + // an error here is fine, we just won't have the ExclusiveTo attribute + if err != nil { + return "", false + } + exclusiveToClass := extractClassFromBlob(exclusiveToBlob) + return exclusiveToClass, true +} + +func activatableAttrIsEmpty(blob []byte) bool { + // the activatable attribute is empty if the size is 0 + // 01 00 - header + // 00 - size + return len(blob) >= 3 && blob[0] == 0x01 && blob[1] == 0x00 && blob[2] == 0x00 +} + +func extractClassFromBlob(blob []byte) string { + // the blob contains a two byte header + // 01 00 + // followed by a byte with the size + // XX + // followed by the type name + + // so we need at least 4 bytes + if len(blob) < 4 { + return "" + } + size := blob[2] + class := blob[3 : 3+size] + return string(class) +} + +func (g *generator) getGenFuncs(typeDef *winmd.TypeDef, requiresActivation bool) ([]*genFunc, error) { + var genFuncs []*genFunc + + methods, err := typeDef.ResolveMethodList(typeDef.Ctx()) + if err != nil { + return nil, err + } + + var exclusiveToType string + if ex, ok := g.interfaceIsExclusiveTo(typeDef); ok { + exclusiveToType = ex + } + + for _, m := range methods { + methodDef := m + generatedFunc, err := g.genFuncFromMethod(typeDef, &methodDef, exclusiveToType, requiresActivation) + if err != nil { + return nil, err + } + + genFuncs = append(genFuncs, generatedFunc) + } + + return genFuncs, nil +} + +func (g *generator) genFuncFromMethod(typeDef *winmd.TypeDef, methodDef *types.MethodDef, exclusiveTo string, requiresActivation bool) (*genFunc, error) { + // add the type imports to the top of the file + // only if the method is going to be implemented + + overloadName := winmd.GetMethodOverloadName(typeDef.Ctx(), methodDef) + implement := g.shouldImplementMethod(overloadName) + if !implement { + // if we don't implement the method, we don't need to gather + // all the information, just the name of it is enough + return &genFunc{ + Name: overloadName, + RequiresImports: nil, + Implement: implement, + InParams: nil, + ReturnParams: nil, + FuncOwner: typeDefGoName(typeDef.TypeName, typeDef.Flags.Public()), + ExclusiveTo: exclusiveTo, + RequiresActivation: requiresActivation, + }, nil + } + + curPackage := typePackage(typeDef.TypeNamespace, typeDef.TypeName) + + params, err := g.getInParameters(curPackage, typeDef, methodDef) + if err != nil { + return nil, err + } + + retParams, err := g.getReturnParameters(curPackage, typeDef, methodDef) + if err != nil { + return nil, err + } + + // iterate over all parameters (in or out) to gather the required imports + // and calculate if we need the package name when referencing a type + // based on the current package + var allImplementedParams []*genParam + allImplementedParams = append(allImplementedParams, params...) + allImplementedParams = append(allImplementedParams, retParams...) + + var requiredImports []*genImport + for _, p := range allImplementedParams { + p.callerPackage = curPackage + if !p.Type.IsPrimitive { + requiredImports = append(requiredImports, &genImport{p.Type.namespace, p.Type.name}) + } + } + + return &genFunc{ + Name: overloadName, + RequiresImports: requiredImports, + Implement: implement, + InParams: params, + ReturnParams: retParams, + FuncOwner: typeDefGoName(typeDef.TypeName, typeDef.Flags.Public()), + ExclusiveTo: exclusiveTo, + RequiresActivation: requiresActivation, + }, nil +} + +func (g *generator) shouldImplementMethod(methodName string) bool { + return g.methodFilter.Filter(methodName) +} + +func (g *generator) getInParameters(curPackage string, typeDef *winmd.TypeDef, methodDef *types.MethodDef) ([]*genParam, error) { + + params, err := methodDef.ResolveParamList(typeDef.Ctx()) + if err != nil { + return nil, err + } + + // the signature contains the parameter + // types and return type of the method + r := methodDef.Signature.Reader() + mr, err := r.Method(typeDef.Ctx()) + if err != nil { + return nil, err + } + + var genParams []*genParam + for i, e := range mr.Params { + param := getParamByIndex(params, uint16(i+1)) + if param == nil { + _ = level.Error(g.logger).Log("msg", "Parameter with index not found", "index", i+1) + continue // do not fail + } + + // When encoding an Array parameter for any interface member type, the array length + // parameter that immediately precedes the array parameter is omitted from both the + // MethodDefSig blob as well from as the params table. => so we need to add it manually. + // Do not trust e.IsArray variable, it's only true for the ELEMENT_TYPE_ARRAY, it + if e.Type.Kind == types.ELEMENT_TYPE_SZARRAY || e.Type.Kind == types.ELEMENT_TYPE_ARRAY { + // The direction of the array parameter is directly encoded in metadata.The direction of + // the array length parameter may be inferred as follows. + // - If the array parameter is an in parameter, the array length parameter must also + // be an IN PARAMETER. + // - If the array parameter is an out parameter and is not carrying the BYREF + // marker, the array length is an IN PARAMETER. + + // - If the array parameter is an out parameter and carries the BYREF marker, the + // array length is an OUT PARAMETER. + sizeIsOutParam := param.Flags.Out() && e.ByRef + genParams = append(genParams, &genParam{ + callerPackage: curPackage, + // Do not change this without also changing the code in the templates + varName: cleanReservedWords(param.Name + "Size"), + IsOut: sizeIsOutParam, + Type: &genParamType{ + namespace: "", + name: "uint32", + defaultValue: genDefaultValue{"0", true}, + IsPrimitive: true, + IsPointer: false, + IsArray: false, + }, + }) + } + + elType, err := g.elementType(typeDef.Ctx(), e) + if err != nil { + return nil, err + } + genParams = append(genParams, &genParam{ + callerPackage: curPackage, + varName: cleanReservedWords(getParamName(params, uint16(i+1))), + IsOut: param.Flags.Out(), + Type: elType, + }) + } + + return genParams, nil +} + +func (g *generator) getReturnParameters(curPackage string, typeDef *winmd.TypeDef, methodDef *types.MethodDef) ([]*genParam, error) { + // the signature contains the parameter + // types and return type of the method + r := methodDef.Signature.Reader() + methodSignature, err := r.Method(typeDef.Ctx()) + if err != nil { + return nil, err + } + + var genParams []*genParam + + // ignore void types + if methodSignature.Return.Type.Kind == types.ELEMENT_TYPE_VOID { + return genParams, nil + } + + elType, err := g.elementType(typeDef.Ctx(), methodSignature.Return) + if err != nil { + return nil, err + } + + genParams = append(genParams, &genParam{ + // return param always has an index of zero + callerPackage: curPackage, + varName: "out", + IsOut: true, + Type: elType, + }) + + return genParams, nil +} + +func getParamName(params []types.Param, i uint16) string { + for _, p := range params { + if p.Sequence == i { + return p.Name + } + } + return fmt.Sprintf("__ERROR_PARAM_%d_NOT_FOUND__", i) +} + +func getParamByIndex(params []types.Param, i uint16) *types.Param { + for _, p := range params { + if p.Sequence == i { + return &p + } + } + return nil +} + +func (g *generator) elementType(ctx *types.Context, e types.Element) (*genParamType, error) { + switch e.Type.Kind { + case types.ELEMENT_TYPE_BOOLEAN: + return &genParamType{ + namespace: "", + name: "bool", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_CHAR: + return &genParamType{ + namespace: "", + name: "byte", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_I1: + return &genParamType{ + namespace: "", + name: "int8", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_U1: + return &genParamType{ + namespace: "", + name: "uint8", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_I2: + return &genParamType{ + namespace: "", + name: "int16", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_U2: + return &genParamType{ + namespace: "", + name: "uint16", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_I4: + return &genParamType{ + namespace: "", + name: "int32", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_U4: + return &genParamType{ + namespace: "", + name: "uint32", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_I8: + return &genParamType{ + namespace: "", + name: "int64", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_U8: + return &genParamType{ + namespace: "", + name: "uint64", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_R4: + return &genParamType{ + namespace: "", + name: "float32", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_R8: + return &genParamType{ + namespace: "", + name: "float64", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_STRING: + return &genParamType{ + namespace: "", + name: "string", + IsPointer: false, + IsPrimitive: true, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_GENERICINST: + fallthrough + case types.ELEMENT_TYPE_CLASS: + // return class name + namespace, name, err := ctx.ResolveTypeDefOrRefName(e.Type.TypeDef.Index) + if err != nil { + return nil, err + } + return &genParamType{ + namespace: namespace, + name: name, + IsPointer: true, + IsPrimitive: false, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_VALUETYPE: + namespace, name, err := ctx.ResolveTypeDefOrRefName(e.Type.TypeDef.Index) + if err != nil { + return nil, err + } + + // Check for system types + if t, ok := isSystemType(namespace, name); ok { + return t, nil + } + + elementTypeDef, err := g.mdStore.TypeDefByName(namespace + "." + name) + if err != nil { + return nil, err + } + + // if its an enum, we will need the underlying type + isEnum := false + enumType := "" + if elementTypeDef.IsEnum() { + enumData, err := g.createGenEnum(elementTypeDef) + if err != nil { + return nil, err + } + + // Treat the enum as a primitive + isEnum = true + enumType = enumData.Type + } + return &genParamType{ + namespace: namespace, + name: name, + IsPointer: false, + IsPrimitive: false, + IsArray: false, + IsEnum: isEnum, + UnderlyingEnumType: enumType, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_VAR: + // Generic types are not fully supported yet, + // so we will just pass the raw unsafe.Pointer up to the user. + return &genParamType{ + namespace: "unsafe", + name: "Pointer", + IsGeneric: true, + IsPointer: false, + IsPrimitive: false, + IsArray: false, + defaultValue: g.elementDefaultValue(ctx, e), + }, nil + case types.ELEMENT_TYPE_SZARRAY: + //A single-dimensional, zero lower-bound array type modifier + + // e.Type.SZArray.Elem should be non-nil + param, err := g.elementType(ctx, *e.Type.SZArray.Elem) + if err != nil { + return nil, err + } + + param.IsArray = true + // override default val + param.defaultValue = genDefaultValue{"nil", true} + + return param, err + case types.ELEMENT_TYPE_OBJECT: + // This represents System.Object, so just use a pointer + return &genParamType{ + namespace: "unsafe", + name: "Pointer", + IsPointer: false, + IsPrimitive: false, + IsArray: false, + defaultValue: genDefaultValue{"nil", true}, + }, nil + default: + return nil, fmt.Errorf("unsupported element type: %v", e.Type.Kind) + } +} + +func isSystemType(namespace, name string) (*genParamType, bool) { + if namespace != "System" { + return nil, false + } + switch name { + case "Guid": + // System.Guid is a struct (value type), so we can just + // use syscall.GUID which has the same structure + return &genParamType{ + namespace: "syscall", + name: "GUID", + IsPointer: false, + IsPrimitive: false, + IsArray: false, + IsEnum: false, + defaultValue: genDefaultValue{value: "GUID{}", isPrimitive: false}, + }, true + } + + return nil, false +} + +func (g *generator) elementDefaultValue(ctx *types.Context, e types.Element) genDefaultValue { + switch e.Type.Kind { + case types.ELEMENT_TYPE_BOOLEAN: + return genDefaultValue{"false", true} + case types.ELEMENT_TYPE_CHAR, + types.ELEMENT_TYPE_I1, types.ELEMENT_TYPE_U1, + types.ELEMENT_TYPE_I2, types.ELEMENT_TYPE_U2, + types.ELEMENT_TYPE_I4, types.ELEMENT_TYPE_U4, + types.ELEMENT_TYPE_I8, types.ELEMENT_TYPE_U8: + return genDefaultValue{"0", true} + case types.ELEMENT_TYPE_R4, types.ELEMENT_TYPE_R8: + return genDefaultValue{"0.0", true} + case types.ELEMENT_TYPE_STRING: + return genDefaultValue{"\"\"", true} + case types.ELEMENT_TYPE_CLASS, + types.ELEMENT_TYPE_GENERICINST, types.ELEMENT_TYPE_SZARRAY: + return genDefaultValue{"nil", true} + case types.ELEMENT_TYPE_VALUETYPE: + // we need to get the underlying type (enum, struct, etc...) + namespace, name, err := ctx.ResolveTypeDefOrRefName(e.Type.TypeDef.Index) + if err != nil { + return genDefaultValue{"__ERROR_" + err.Error(), true} + } + elementTypeDef, err := g.mdStore.TypeDefByName(namespace + "." + name) + if err != nil { + return genDefaultValue{"__ERROR_" + err.Error(), true} + } + + if elementTypeDef.IsEnum() { + // return the first enum value + fields, err := elementTypeDef.ResolveFieldList(ctx) + if err != nil { + return genDefaultValue{"__ERROR_" + err.Error(), true} + } + // the first field defines the enum type, the second is the first value + if len(fields) < 2 { + return genDefaultValue{"__ERROR_" + fmt.Errorf("enum %v has no fields", namespace+"."+name).Error(), true} + } + + return genDefaultValue{enumName(elementTypeDef.TypeName, fields[1].Name), false} + } else if elementTypeDef.IsStruct() { + return genDefaultValue{elementTypeDef.TypeName + "{}", false} + } + + return genDefaultValue{"nil", true} + case types.ELEMENT_TYPE_VAR: + return genDefaultValue{"nil", true} + case types.ELEMENT_TYPE_OBJECT: + return genDefaultValue{"nil", true} + default: + return genDefaultValue{"__ERROR_" + fmt.Errorf("unsupported element type: %v", e.Type.Kind).Error(), true} + } +} + +func (g *generator) Signature(typeDef *winmd.TypeDef) (string, error) { + // Signature generation defined in + // https://docs.microsoft.com/en-us/uwp/winrt-cref/winrt-type-system#guid-generation-for-parameterized-types + + // type_signature => (only relevant types included) + // - interface_signature + // - delegate_signature + // - interface_group_signature + // - runtime_class_signature + // - struct_signature + // - enum_signature + // # these instance signatures cannot be generated until instantiated + // - pinterface_instance_signature + // - pdelegate_instance_signature + // + // Where: + // - interface_signature => guid + // - delegate_signature => "delegate(" guid ")" + // - interface_group_signature => "ig(" interface_group_name ";" default_interface ")" + // - runtime_class_signature => "rc(" runtime_class_name ";" default_interface ")" + // - struct_signature => "struct(" struct_name ";" args ")" + // - enum_signature => "enum(" enum_name ";" enum_underlying_type ")" + + switch { + case typeDef.IsInterface(): + // interface_signature => guid + guid, err := typeDef.GUID() + if err != nil { + return "", err + } + + return fmt.Sprintf("{%s}", guid), nil + case typeDef.IsEnum(): + // enum_signature => "enum(" enum_name ";" enum_underlying_type ")" + // the first field should be the underlying integer type of the enum. It must have the following flags: + fields, err := typeDef.ResolveFieldList(typeDef.Ctx()) + if err != nil { + return "", err + } + fieldSig, err := fields[0].Signature.Reader().Field(typeDef.Ctx()) + if err != nil { + return "", err + } + + enumType := primitiveTypeSignature(fieldSig.Field.Type.Kind) + return fmt.Sprintf(`enum(%s;%s)`, typeDef.TypeNamespace+"."+typeDef.TypeName, enumType), nil + case typeDef.IsStruct(): + // struct_signature => "struct(" struct_name ";" args ")" + fields, err := typeDef.ResolveFieldList(typeDef.Ctx()) + if err != nil { + return "", err + } + structArgs := []string{} + for _, f := range fields { + fSig, err := f.Signature.Reader().Field(typeDef.Ctx()) + if err != nil { + return "", err + } + + // Struct fields must be fundamental types, enums, or other structs + if fSig.Field.Type.Kind == types.ELEMENT_TYPE_VALUETYPE { + // this is an struct or an enum + fieldType, err := g.elementType(typeDef.Ctx(), fSig.Field) + if err != nil { + return "", err + } + + t, err := g.mdStore.TypeDefByName(fieldType.namespace + "." + fieldType.name) + if err != nil { + return "", err + } + + sig, err := g.Signature(t) + if err != nil { + return "", err + } + structArgs = append(structArgs, sig) + } else { + // Assume everything else is a fundamental type + structArgs = append(structArgs, primitiveTypeSignature(fSig.Field.Type.Kind)) + } + } + return fmt.Sprintf(`struct(%s;%s)`, typeDef.TypeNamespace+"."+typeDef.TypeName, strings.Join(structArgs, ";")), nil + case typeDef.IsDelegate(): + //delegate_signature => "delegate(" guid ")" + guid, err := typeDef.GUID() + if err != nil { + return "", err + } + + return fmt.Sprintf(`delegate({%s})`, guid), nil + case typeDef.IsRuntimeClass(): + // Static only classes carry the abstract flag. + // These cannot be instantiated so no signature needed. + if typeDef.Flags.Abstract() { + return "", nil + } + + // runtime_class_signature => "rc(" runtime_class_name ";" default_interface ")" + + // Runtime classes must specify the DefaultAttribute on exactly one of their InterfaceImpl rows. + defaultInterface, err := typeDef.GetAttributeWithType(winmd.AttributeTypeDefaultAttribute) + if err != nil { + // Some classes (Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher) do not + // define a runtime class. I'm not sure if this is an error in the IDL or the documentation. + // But we are not going to fail here. Just default to the first implemented interface + ifs, ifserr := typeDef.GetImplementedInterfaces() + if ifserr != nil { + return "", err + } + + if len(ifs) == 0 { + return "", err + } + defaultInterface = []byte(ifs[0].Namespace + "." + ifs[0].Name) + } + + td, err := g.mdStore.TypeDefByName(string(defaultInterface)) + if err != nil { + return "", err + } + + defaultInterfaceSignature, err := g.Signature(td) + if err != nil { + return "", err + } + return fmt.Sprintf(`rc(%s;%s)`, typeDef.TypeNamespace+"."+typeDef.TypeName, defaultInterfaceSignature), nil + default: + return "", fmt.Errorf("unsupported type: %v", typeDef.TypeName) + } +} + +func primitiveTypeSignature(kind types.ElementTypeKind) string { + switch kind { + // Fundamental types + case types.ELEMENT_TYPE_U1: + return winrt.SignatureUInt8 + case types.ELEMENT_TYPE_U2: + return winrt.SignatureUInt16 + case types.ELEMENT_TYPE_U4: + return winrt.SignatureUInt32 + case types.ELEMENT_TYPE_U8: + return winrt.SignatureUInt64 + case types.ELEMENT_TYPE_I1: + return winrt.SignatureInt8 + case types.ELEMENT_TYPE_I2: + return winrt.SignatureInt16 + case types.ELEMENT_TYPE_I4: + return winrt.SignatureInt32 + case types.ELEMENT_TYPE_I8: + return winrt.SignatureInt64 + case types.ELEMENT_TYPE_R4: + return winrt.SignatureFloat32 + case types.ELEMENT_TYPE_R8: + return winrt.SignatureFloat64 + case types.ELEMENT_TYPE_BOOLEAN: + return winrt.SignatureBool + case types.ELEMENT_TYPE_CHAR: + return winrt.SignatureChar + case types.ELEMENT_TYPE_STRING: + return winrt.SignatureString + } + return "" +} diff --git a/internal/codegen/config.go b/internal/codegen/config.go new file mode 100644 index 0000000..1a5d65b --- /dev/null +++ b/internal/codegen/config.go @@ -0,0 +1,41 @@ +package codegen + +import ( + "fmt" +) + +// Config is the configuration for the code generation. +type Config struct { + Debug bool + Class string + ValidateOnly bool + methodFilters []string +} + +// NewConfig returns a new Config with default values. +func NewConfig() *Config { + return &Config{} +} + +// AddMethodFilter adds a method to the list of methodFilters to generate. +func (cfg *Config) AddMethodFilter(methodFilter string) { + cfg.methodFilters = append(cfg.methodFilters, methodFilter) +} + +// MethodFilter creates and returns a new method filter for the current config. +func (cfg *Config) MethodFilter() *MethodFilter { + return NewMethodFilter(cfg.methodFilters) +} + +// Validate validates the Config and returns an error if there's any problem. +func (cfg *Config) Validate() error { + if cfg == nil { + return fmt.Errorf("config is nil") + } + + if cfg.Class == "" { + return fmt.Errorf("generated classes may not be empty") + } + + return nil +} diff --git a/internal/codegen/methodfilter.go b/internal/codegen/methodfilter.go new file mode 100644 index 0000000..7ba7461 --- /dev/null +++ b/internal/codegen/methodfilter.go @@ -0,0 +1,28 @@ +package codegen + +// MethodFilter is a filter for methods to be generated. +type MethodFilter struct { + filters []string +} + +// NewMethodFilter creates a new MethodFilter. +func NewMethodFilter(filters []string) *MethodFilter { + return &MethodFilter{filters} +} + +// Filter returns true if the method matches one of the filters. +// In case no filter matches the method, the method is allowed. +func (md *MethodFilter) Filter(method string) bool { + for _, filter := range md.filters { + result := true + if filter[0] == '!' { + filter = filter[1:] + result = false + } + + if filter == "*" || filter == method { + return result + } + } + return true // everything matches by default +} diff --git a/internal/codegen/templates.go b/internal/codegen/templates.go new file mode 100644 index 0000000..2469173 --- /dev/null +++ b/internal/codegen/templates.go @@ -0,0 +1,311 @@ +package codegen + +import ( + "embed" + "strings" + "text/template" + + "github.com/saltosystems/winrt-go/internal/winmd" +) + +type genDataFile struct { + Filename string + Data genData +} + +type genData struct { + Package string + Imports []string + Classes []*genClass + Enums []*genEnum + Interfaces []*genInterface + Structs []*genStruct + Delegates []*genDelegate +} + +func (g *genData) ComputeImports(typeDef *winmd.TypeDef) { + // gather all imports + imports := make([]*genImport, 0) + if g.Classes != nil { + for _, c := range g.Classes { + imports = append(imports, c.GetRequiredImports()...) + } + } + if g.Interfaces != nil { + for _, i := range g.Interfaces { + imports = append(imports, i.GetRequiredImports()...) + } + } + + for _, i := range imports { + if typeDef.TypeNamespace != i.Namespace { + g.Imports = append(g.Imports, i.ToGoImport()) + } + } +} + +type genInterface struct { + Name string + GUID string + Signature string + Funcs []*genFunc +} + +func (g *genInterface) GetRequiredImports() []*genImport { + imports := make([]*genImport, 0) + for _, f := range g.Funcs { + imports = append(imports, f.RequiresImports...) + } + return imports +} + +type genClass struct { + Name string + Signature string + RequiresImports []*genImport + FullyQualifiedName string + ImplInterfaces []*genInterface + ExclusiveInterfaces []*genInterface + HasEmptyConstructor bool + IsAbstract bool +} + +func (g *genClass) GetRequiredImports() []*genImport { + imports := make([]*genImport, 0) + if g.RequiresImports != nil { + imports = append(imports, g.RequiresImports...) + } + if g.ExclusiveInterfaces != nil { + for _, i := range g.ExclusiveInterfaces { + imports = append(imports, i.GetRequiredImports()...) + } + } + + return imports +} + +type genDelegate struct { + Name string + GUID string + Signature string + InParams []*genParam + ReturnParam *genParam // this may be nil +} + +type genEnum struct { + Name string + Type string + Signature string + Values []*genEnumValue +} +type genEnumValue struct { + Name string + Value string +} + +type genFunc struct { + Name string + RequiresImports []*genImport + Implement bool + FuncOwner string + InParams []*genParam + ReturnParams []*genParam // this may be empty + + // ExclusiveTo is the name of the class that this function is exclusive to. + // The funcion will be called statically using the RoGetActivationFactory function. + ExclusiveTo string + RequiresActivation bool + + InheritedFrom winmd.QualifiedID +} + +type genImport struct { + Namespace, Name string +} + +func (i genImport) ToGoImport() string { + if !strings.Contains(i.Namespace, ".") && i.Namespace != "Windows" { + // This is probably a built-in package + return i.Namespace + } + + folder := typeToFolder(i.Namespace, i.Name) + return "github.com/saltosystems/winrt-go/" + folder +} + +// some of the variables are not public to avoid using them +// by mistake in the code. +type genDefaultValue struct { + value string + isPrimitive bool +} + +// some of the variables are not public to avoid using them +// by mistake in the code. +type genParamType struct { + namespace string + name string + + IsPointer bool + IsGeneric bool + IsArray bool + IsPrimitive bool + IsEnum bool + UnderlyingEnumType string + + defaultValue genDefaultValue +} + +// some of the variables are not public to avoid using them +// by mistake in the code. +type genParam struct { + callerPackage string + + varName string + + Type *genParamType + + IsOut bool +} + +func (g *genParam) GoVarName() string { + return typeNameToGoName(g.varName, true) // assume all are public +} + +func (g *genParam) GoTypeName() string { + if g.Type.IsPrimitive { + return g.Type.name + } + + name := typeNameToGoName(g.Type.name, true) // assume all are public + + pkg := typePackage(g.Type.namespace, g.Type.name) + if g.callerPackage != pkg { + name = pkg + "." + name + } + + return name +} + +func (g *genParam) GoDefaultValue() string { + if g.Type.defaultValue.isPrimitive { + return g.Type.defaultValue.value + } + + pkg := typePackage(g.Type.namespace, g.Type.name) + if g.callerPackage != pkg { + return pkg + "." + g.Type.defaultValue.value + } + + return g.Type.defaultValue.value +} + +type genStruct struct { + Name string + Signature string + Fields []*genParam +} + +//go:embed templates/* +var templatesFS embed.FS + +func getTemplates() (*template.Template, error) { + return template.New(""). + Funcs(funcs()). + ParseFS(templatesFS, "templates/*") +} + +func funcs() template.FuncMap { + return template.FuncMap{ + "funcName": funcName, + "concat": func(a, b []*genParam) []*genParam { + return append(a, b...) + }, + "toLower": func(s string) string { + return strings.ToLower(s[:1]) + s[1:] + }, + } +} + +// funcName is used to generate the name of a function. +func funcName(m genFunc) string { + // There are some special prefixes applied to methods that we need to replace + replacer := strings.NewReplacer( + "get_", "Get", + "put_", "Set", + "add_", "Add", + "remove_", "Remove", + ) + name := replacer.Replace(m.Name) + + // Add a prefix to static methods to include the owner class of the method. + // This is necessary to avoid conflicts with method names within the same package. + // Static methods are those that are exclusive to a class and require activation. + prefix := "" + if m.ExclusiveTo != "" && m.RequiresActivation { + nsAndName := strings.Split(m.ExclusiveTo, ".") + prefix = typeNameToGoName(nsAndName[len(nsAndName)-1], true) + } + + return prefix + name +} + +func typeToFolder(ns, name string) string { + fullName := ns + return strings.ToLower(strings.Replace(fullName, ".", "/", -1)) +} + +func typePackage(ns, name string) string { + sns := strings.Split(ns, ".") + return strings.ToLower(sns[len(sns)-1]) +} + +func enumName(typeName string, enumName string) string { + return typeName + enumName +} + +func typeDefGoName(typeName string, public bool) string { + name := typeName + + if isParameterizedName(typeName) { + name = strings.Split(name, "`")[0] + } + + if !public { + name = strings.ToLower(name[0:1]) + name[1:] + } + return name +} + +func isParameterizedName(typeName string) bool { + // parameterized types contain a '`' followed by the amount of generic parameters in their name. + return strings.Contains(typeName, "`") +} + +func typeFilename(typeName string) string { + // public boolean is not relevant, we are going to lower everything + goname := typeDefGoName(typeName, true) + return strings.ToLower(goname) +} + +// removes Go reserved words from param names +func cleanReservedWords(name string) string { + switch name { + case "type": + return "mType" + } + return name +} + +func typeNameToGoName(typeName string, public bool) string { + name := typeName + + if isParameterizedName(typeName) { + name = strings.Split(name, "`")[0] + } + + if !public { + name = strings.ToLower(name[0:1]) + name[1:] + } + return name +} diff --git a/internal/codegen/templates/class.tmpl b/internal/codegen/templates/class.tmpl new file mode 100644 index 0000000..37e3821 --- /dev/null +++ b/internal/codegen/templates/class.tmpl @@ -0,0 +1,60 @@ +{{if not .IsAbstract}} +const Signature{{.Name}} string = "{{.Signature}}" + +type {{.Name}} struct { + ole.IUnknown +} + +{{if .HasEmptyConstructor}} +func New{{.Name}}() (*{{.Name}}, error) { + inspectable, err := ole.RoActivateInstance("{{.FullyQualifiedName}}") + if err != nil { + return nil, err + } + return (*{{.Name}})(unsafe.Pointer(inspectable)), nil +} +{{end}} +{{end}} + +{{$owner := .Name}} +{{range .ImplInterfaces}} + {{range .Funcs}} + {{if not .Implement}}{{continue}}{{end}} + func (impl *{{$owner}}) {{funcName .}} ( + {{- range .InParams -}} + {{/*do not include out parameters, they are used as return values*/ -}} + {{ if .IsOut }}{{continue}}{{ end -}} + {{.GoVarName}} {{template "variabletype.tmpl" . }}, + {{- end -}} + ) + + {{- /* return params */ -}} + + ( {{range .InParams -}} + {{ if not .IsOut }}{{continue}}{{ end -}} + {{template "variabletype.tmpl" . }},{{end -}} + {{range .ReturnParams}}{{template "variabletype.tmpl" . }},{{end}} error ) + + {{- /* method body */ -}} + + { + itf := impl.MustQueryInterface(ole.NewGUID({{if .InheritedFrom.Namespace}}{{.InheritedFrom.Namespace}}.{{end}}GUID{{.InheritedFrom.Name}})) + defer itf.Release() + v := (*{{if .InheritedFrom.Namespace}}{{.InheritedFrom.Namespace}}.{{end}}{{.InheritedFrom.Name}})(unsafe.Pointer(itf)) + return v.{{funcName . -}} + ( + {{- range .InParams -}} + {{if .IsOut -}} + {{continue -}} + {{end -}} + {{.GoVarName -}} + , + {{- end -}} + ) + } + {{end}} +{{end}} + +{{range .ExclusiveInterfaces}} + {{ template "interface.tmpl" .}} +{{end}} diff --git a/internal/codegen/templates/delegate.tmpl b/internal/codegen/templates/delegate.tmpl new file mode 100644 index 0000000..3206168 --- /dev/null +++ b/internal/codegen/templates/delegate.tmpl @@ -0,0 +1,204 @@ + +const GUID{{.Name}} string = "{{.GUID}}" +const Signature{{.Name}} string = "{{.Signature}}" + +type {{.Name}} struct { + ole.IUnknown + sync.Mutex + refs uintptr + IID ole.GUID +} + +type {{.Name}}Vtbl struct { + ole.IUnknownVtbl + Invoke uintptr +} + +type {{.Name}}Callback func(instance *{{.Name}},{{- range .InParams -}} + {{.GoVarName}} {{template "variabletype.tmpl" . }}, +{{- end -}}) + +var callbacks{{.Name}} = &{{.Name | toLower}}Callbacks { + mu: &sync.Mutex{}, + callbacks: make(map[unsafe.Pointer]{{.Name}}Callback), +} + +var releaseChannels{{.Name}} = &{{.Name | toLower}}ReleaseChannels { + mu: &sync.Mutex{}, + chans: make(map[unsafe.Pointer]chan struct{}), +} + +func New{{.Name}}(iid *ole.GUID, callback {{.Name}}Callback) *{{.Name}} { + // create type instance + size := unsafe.Sizeof(*(*{{.Name}})(nil)) + instPtr := kernel32.Malloc(size) + inst := (*{{.Name}})(instPtr) + + // get the callbacks for the VTable + callbacks := delegate.RegisterCallbacks(instPtr, inst) + + // the VTable should also be allocated in the heap + sizeVTable := unsafe.Sizeof(*(*{{.Name}}Vtbl)(nil)) + vTablePtr := kernel32.Malloc(sizeVTable) + + inst.RawVTable = (*interface{})(vTablePtr) + + vTable := (*{{.Name}}Vtbl)(vTablePtr) + vTable.IUnknownVtbl = ole.IUnknownVtbl{ + QueryInterface: callbacks.QueryInterface, + AddRef: callbacks.AddRef, + Release: callbacks.Release, + } + vTable.Invoke = callbacks.Invoke + + // Initialize all properties: the malloc may contain garbage + inst.IID = *iid // copy contents + inst.Mutex = sync.Mutex{} + inst.refs = 0 + + callbacks{{.Name}}.add(unsafe.Pointer(inst), callback) + + // See the docs in the releaseChannels{{.Name}} struct + releaseChannels{{.Name}}.acquire(unsafe.Pointer(inst)) + + inst.addRef() + return inst +} + +func (r *{{.Name}}) GetIID() *ole.GUID { + return &r.IID +} + +// addRef increments the reference counter by one +func (r *{{.Name}}) addRef() uintptr { + r.Lock() + defer r.Unlock() + r.refs++ + return r.refs +} + +// removeRef decrements the reference counter by one. If it was already zero, it will just return zero. +func (r *{{.Name}}) removeRef() uintptr { + r.Lock() + defer r.Unlock() + + if r.refs > 0 { + r.refs-- + } + + return r.refs +} + +func (instance *{{.Name}}) Invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8 unsafe.Pointer) uintptr { + {{range $i, $arg := .InParams -}} + {{- if $arg.Type.IsEnum -}} + {{$arg.GoVarName}}Raw := ({{$arg.Type.UnderlyingEnumType}})(uintptr(rawArgs{{$i}})) + {{- else -}} + {{$arg.GoVarName}}Ptr := rawArgs{{$i}} + {{- end}} + {{end}} + + // See the quote above. + {{range .InParams -}} + {{if .Type.IsEnum -}} + {{.GoVarName}} := ({{template "variabletype.tmpl" . }})({{.GoVarName}}Raw) + {{else -}} + {{.GoVarName}} := ({{template "variabletype.tmpl" . }})({{.GoVarName}}Ptr) + {{end -}} + {{end -}} + if callback, ok := callbacks{{.Name}}.get(instancePtr); ok { + callback(instance, {{range .InParams}}{{.GoVarName}},{{end}}) + } + return ole.S_OK +} + +func (instance *{{.Name}}) AddRef() uintptr { + return instance.addRef() +} + +func (instance *{{.Name}}) Release() uintptr { + rem := instance.removeRef() + if rem == 0 { + // We're done. + instancePtr := unsafe.Pointer(instance) + callbacks{{.Name}}.delete(instancePtr) + + // stop release channels used to avoid + // https://github.com/golang/go/issues/55015 + releaseChannels{{.Name}}.release(instancePtr) + + kernel32.Free(unsafe.Pointer(instance.RawVTable)) + kernel32.Free(instancePtr) + } + return rem +} + +type {{.Name | toLower}}Callbacks struct { + mu *sync.Mutex + callbacks map[unsafe.Pointer]{{.Name}}Callback +} + +func (m *{{.Name | toLower}}Callbacks) add(p unsafe.Pointer, v {{.Name}}Callback) { + m.mu.Lock() + defer m.mu.Unlock() + + m.callbacks[p] = v +} + +func (m *{{.Name | toLower}}Callbacks) get(p unsafe.Pointer) ({{.Name}}Callback, bool) { + m.mu.Lock() + defer m.mu.Unlock() + + v, ok := m.callbacks[p] + return v, ok +} + +func (m *{{.Name | toLower}}Callbacks) delete(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + delete(m.callbacks, p) +} + +// typedEventHandlerReleaseChannels keeps a map with channels +// used to keep a goroutine alive during the lifecycle of this object. +// This is required to avoid causing a deadlock error. +// See this: https://github.com/golang/go/issues/55015 +type {{.Name | toLower}}ReleaseChannels struct { + mu *sync.Mutex + chans map[unsafe.Pointer]chan struct{} +} + +func (m *{{.Name | toLower}}ReleaseChannels) acquire(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + c := make(chan struct{}) + m.chans[p] = c + + go func() { + // we need a timer to trick the go runtime into + // thinking there's still something going on here + // but we are only really interested in <-c + t := time.NewTimer(time.Minute) + for { + select { + case <-t.C: + t.Reset(time.Minute) + case <-c: + t.Stop() + return + } + } + }() +} + +func (m *{{.Name | toLower}}ReleaseChannels) release(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + if c, ok := m.chans[p]; ok { + close(c) + delete(m.chans, p) + } +} diff --git a/internal/codegen/templates/enum.tmpl b/internal/codegen/templates/enum.tmpl new file mode 100644 index 0000000..9d88c2b --- /dev/null +++ b/internal/codegen/templates/enum.tmpl @@ -0,0 +1,6 @@ +type {{.Name}} {{.Type}} +const Signature{{.Name}} string = "{{.Signature}}" + +const ({{range .Values}} + {{.Name}} {{$.Name}} = {{.Value}}{{end}} +) diff --git a/internal/codegen/templates/file.tmpl b/internal/codegen/templates/file.tmpl new file mode 100644 index 0000000..d8760dd --- /dev/null +++ b/internal/codegen/templates/file.tmpl @@ -0,0 +1,36 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package {{.Package}} + +import ( + "syscall" + "unsafe" + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go" + "github.com/saltosystems/winrt-go/internal/kernel32" + {{range .Imports}}"{{.}}" + {{end}} +) + +{{range .Interfaces}} + {{template "interface.tmpl" .}} +{{end}} + +{{range .Classes}} + {{template "class.tmpl" .}} +{{end}} + +{{range .Enums}} + {{template "enum.tmpl" .}} +{{end}} + +{{range .Structs}} + {{template "struct.tmpl" .}} +{{end}} + +{{range .Delegates}} + {{template "delegate.tmpl" .}} +{{end}} diff --git a/internal/codegen/templates/func.tmpl b/internal/codegen/templates/func.tmpl new file mode 100644 index 0000000..3075d58 --- /dev/null +++ b/internal/codegen/templates/func.tmpl @@ -0,0 +1,30 @@ +{{if .Implement}} + func {{if and .FuncOwner (not .RequiresActivation)}} + (v *{{.FuncOwner}}) + {{- end -}} + + {{funcName .}} + + {{- /* in params */ -}} + + ( + {{- range .InParams -}} + {{/*do not include out parameters, they are used as return values*/ -}} + {{ if .IsOut }}{{continue}}{{ end -}} + {{.GoVarName}} {{template "variabletype.tmpl" . }}, + {{- end -}} + ) + + {{- /* return params */ -}} + + ( {{range .InParams -}} + {{ if not .IsOut }}{{continue}}{{ end -}} + {{template "variabletype.tmpl" . }},{{end -}} + {{range .ReturnParams}}{{template "variabletype.tmpl" . }},{{end}} error ) + + {{- /* method body */ -}} + + { + {{template "funcimpl.tmpl" .}} + } +{{end}} diff --git a/internal/codegen/templates/funcimpl.tmpl b/internal/codegen/templates/funcimpl.tmpl new file mode 100644 index 0000000..03c79a2 --- /dev/null +++ b/internal/codegen/templates/funcimpl.tmpl @@ -0,0 +1,86 @@ +{{if .RequiresActivation}}{{/*Activate class*/ -}} +inspectable, err := ole.RoGetActivationFactory("{{.ExclusiveTo}}", ole.NewGUID(GUID{{.FuncOwner}})) +if err != nil { + return {{range .ReturnParams -}} + {{.GoDefaultValue}}, {{end}}err +} +v := (*{{.FuncOwner}})(unsafe.Pointer(inspectable)) + +{{end -}} + +{{- /* Declare out variables*/ -}} + +{{range (concat .InParams .ReturnParams) -}} + {{ if not .IsOut}}{{continue}}{{end -}} + {{if eq .GoTypeName "string" -}} + var {{.GoVarName}}HStr ole.HString + {{ else -}} + var {{.GoVarName}} {{template "variabletype.tmpl" . -}} + {{if .Type.IsArray}} = make({{template "variabletype.tmpl" . -}}, {{.GoVarName}}Size){{end}} + {{ end -}} +{{ end -}} + +{{- /* Convert in variables to winrt types */ -}} + +{{range .InParams -}} + {{ if .IsOut}}{{continue}}{{end -}} + {{if eq .GoTypeName "string" -}} + {{.GoVarName}}HStr, err := ole.NewHString({{.GoVarName}}) + if err != nil{ + return {{range $.InParams}}{{if .IsOut}}{{.GoDefaultValue}}, {{end}}{{end -}} + {{range $.ReturnParams }}{{.GoDefaultValue}}, {{end}}err + } + {{ end -}} +{{ end -}} +hr, _, _ := syscall.SyscallN( + v.VTable().{{funcName .}}, + uintptr(unsafe.Pointer(v)), // this + {{range (concat .InParams .ReturnParams) -}} + {{if .Type.IsArray -}} + {{/* Arrays need to pass a pointer to their first element */ -}} + uintptr(unsafe.Pointer(&{{.GoVarName}}[0])), // {{if .IsOut}}out{{else}}in{{end}} {{.GoTypeName}} + {{else if .IsOut -}} + {{if (or .Type.IsPrimitive .Type.IsEnum) -}} + {{if eq .GoTypeName "string" -}} + uintptr(unsafe.Pointer(&{{.GoVarName}}HStr)), // out {{.GoTypeName}} + {{else -}} + uintptr(unsafe.Pointer(&{{.GoVarName}})), // out {{.GoTypeName}} + {{end -}} + {{else -}} + uintptr(unsafe.Pointer(&{{.GoVarName}})), // out {{.GoTypeName}} + {{end -}} + {{else if .Type.IsPointer -}} + uintptr(unsafe.Pointer({{.GoVarName}})), // in {{.GoTypeName}} + {{else if (or .Type.IsPrimitive .Type.IsEnum) -}} + {{ if eq .GoTypeName "bool" -}} + uintptr(*(*byte)(unsafe.Pointer(&{{.GoVarName}}))), // in {{.GoTypeName}} + {{ else if eq .GoTypeName "string" -}} + uintptr({{.GoVarName}}HStr), // in {{.GoTypeName}} + {{else -}} + uintptr({{.GoVarName}}), // in {{.GoTypeName}} + {{end -}} + {{else if .Type.IsGeneric -}} + uintptr({{.GoVarName}}), // in {{.GoTypeName}} + {{else -}} + uintptr(unsafe.Pointer(&{{.GoVarName}})), // in {{.GoTypeName}} + {{end -}} + {{end -}} +) + +if hr != 0 { + return {{range .InParams}}{{if .IsOut}}{{.GoDefaultValue}}, {{end}}{{end -}} + {{range .ReturnParams }}{{.GoDefaultValue}}, {{end}}ole.NewError(hr) +} + +{{range (concat .InParams .ReturnParams) -}} + {{ if not .IsOut}}{{continue}}{{end -}} + {{if eq .GoTypeName "string" -}} + {{.GoVarName}} := {{.GoVarName}}HStr.String() + ole.DeleteHString({{.GoVarName}}HStr) + {{ end -}} +{{ end -}} + + +return {{range .InParams}}{{if .IsOut}}{{.GoVarName}}, {{end}}{{end -}} + {{range .ReturnParams }}{{.GoVarName}},{{end}} nil +{{- /* remove trailing white space*/ -}} diff --git a/internal/codegen/templates/interface.tmpl b/internal/codegen/templates/interface.tmpl new file mode 100644 index 0000000..477c67a --- /dev/null +++ b/internal/codegen/templates/interface.tmpl @@ -0,0 +1,22 @@ +const GUID{{.Name}} string = "{{.GUID}}" +const Signature{{.Name}} string = "{{.Signature}}" + +type {{.Name}} struct { + ole.IInspectable +} + +type {{.Name}}Vtbl struct { + ole.IInspectableVtbl + + {{range .Funcs}} + {{funcName .}} uintptr + {{- end}} +} + +func (v *{{.Name}}) VTable() *{{.Name}}Vtbl { + return (*{{.Name}}Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +{{range .Funcs}} +{{template "func.tmpl" .}} +{{end}} diff --git a/internal/codegen/templates/struct.tmpl b/internal/codegen/templates/struct.tmpl new file mode 100644 index 0000000..02c4c61 --- /dev/null +++ b/internal/codegen/templates/struct.tmpl @@ -0,0 +1,7 @@ +const Signature{{.Name}} string = "{{.Signature}}" + +type {{.Name}} struct { + {{range .Fields}} + {{.GoVarName}} {{.GoTypeName}} + {{end}} +} diff --git a/internal/codegen/templates/variabletype.tmpl b/internal/codegen/templates/variabletype.tmpl new file mode 100644 index 0000000..c602ca5 --- /dev/null +++ b/internal/codegen/templates/variabletype.tmpl @@ -0,0 +1,5 @@ +{{if .Type.IsArray}}[]{{end -}} +{{if .Type.IsPointer}}*{{end -}} +{{.GoTypeName -}} + +{{- /*remove trailing whitespace*/ -}} diff --git a/internal/delegate/delegate.go b/internal/delegate/delegate.go new file mode 100644 index 0000000..3ed91ac --- /dev/null +++ b/internal/delegate/delegate.go @@ -0,0 +1,139 @@ +//go:build windows + +package delegate + +import ( + "sync" + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +// Only a limited number of callbacks may be created in a single Go process, +// and any memory allocated for these callbacks is never released. +// Between NewCallback and NewCallbackCDecl, at least 1024 callbacks can always be created. +var ( + queryInterfaceCallback = syscall.NewCallback(queryInterface) + addRefCallback = syscall.NewCallback(addRef) + releaseCallback = syscall.NewCallback(release) + invokeCallback = syscall.NewCallback(invoke) +) + +// Delegate represents a WinRT delegate class. +type Delegate interface { + GetIID() *ole.GUID + Invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8 unsafe.Pointer) uintptr + AddRef() uintptr + Release() uintptr +} + +// Callbacks contains the syscalls registered on Windows. +type Callbacks struct { + QueryInterface uintptr + AddRef uintptr + Release uintptr + Invoke uintptr +} + +var mutex = sync.RWMutex{} +var instances = make(map[uintptr]Delegate) + +// RegisterCallbacks adds the given pointer and the Delegate it points to to our instances. +// This is required to redirect received callbacks to the correct object instance. +// The function returns the callbacks to use when creating a new delegate instance. +func RegisterCallbacks(ptr unsafe.Pointer, inst Delegate) *Callbacks { + mutex.Lock() + defer mutex.Unlock() + instances[uintptr(ptr)] = inst + + return &Callbacks{ + QueryInterface: queryInterfaceCallback, + AddRef: addRefCallback, + Release: releaseCallback, + Invoke: invokeCallback, + } +} + +func getInstance(ptr unsafe.Pointer) (Delegate, bool) { + mutex.RLock() // locks writing, allows concurrent read + defer mutex.RUnlock() + + i, ok := instances[uintptr(ptr)] + return i, ok +} + +func removeInstance(ptr unsafe.Pointer) { + mutex.Lock() + defer mutex.Unlock() + delete(instances, uintptr(ptr)) +} + +func queryInterface(instancePtr unsafe.Pointer, iidPtr unsafe.Pointer, ppvObject *unsafe.Pointer) uintptr { + instance, ok := getInstance(instancePtr) + if !ok { + // instance not found + return ole.E_POINTER + } + + // Checkout these sources for more information about the QueryInterface method. + // - https://docs.microsoft.com/en-us/cpp/atl/queryinterface + // - https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface(refiid_void) + + if ppvObject == nil { + // If ppvObject (the address) is nullptr, then this method returns E_POINTER. + return ole.E_POINTER + } + + // This function must adhere to the QueryInterface defined here: + // https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iunknown + if iid := (*ole.GUID)(iidPtr); ole.IsEqualGUID(iid, instance.GetIID()) || ole.IsEqualGUID(iid, ole.IID_IUnknown) || ole.IsEqualGUID(iid, ole.IID_IInspectable) { + *ppvObject = instancePtr + } else { + *ppvObject = nil + // Return E_NOINTERFACE if the interface is not supported + return ole.E_NOINTERFACE + } + + // If the COM object implements the interface, then it returns + // a pointer to that interface after calling IUnknown::AddRef on it. + (*ole.IUnknown)(*ppvObject).AddRef() + + // Return S_OK if the interface is supported + return ole.S_OK +} + +func invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8 unsafe.Pointer) uintptr { + instance, ok := getInstance(instancePtr) + if !ok { + // instance not found + return ole.E_FAIL + } + + return instance.Invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8) +} + +func addRef(instancePtr unsafe.Pointer) uintptr { + instance, ok := getInstance(instancePtr) + if !ok { + // instance not found + return ole.E_FAIL + } + + return instance.AddRef() +} + +func release(instancePtr unsafe.Pointer) uintptr { + instance, ok := getInstance(instancePtr) + if !ok { + // instance not found + return ole.E_FAIL + } + + rem := instance.Release() + if rem == 0 { + // remove this delegate + removeInstance(instancePtr) + } + return rem +} diff --git a/internal/kernel32/kernel32.go b/internal/kernel32/kernel32.go new file mode 100644 index 0000000..8d81b34 --- /dev/null +++ b/internal/kernel32/kernel32.go @@ -0,0 +1,78 @@ +//go:build windows + +package kernel32 + +import ( + "sync/atomic" + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +type ( + heapHandle = uintptr + win32Error uint32 + heapFlags uint32 +) + +const ( + heapNone heapFlags = 0 + heapZeroMemory heapFlags = 8 // The allocated memory will be initialized to zero. +) + +var ( + libKernel32 = windows.NewLazySystemDLL("kernel32.dll") + + pHeapFree uintptr + pHeapAlloc uintptr + pGetProcessHeap uintptr + + hHeap heapHandle +) + +func init() { + hHeap, _ = getProcessHeap() +} + +// Malloc allocates the given amount of bytes in the heap +func Malloc(size uintptr) unsafe.Pointer { + return heapAlloc(hHeap, heapZeroMemory, size) +} + +// Free releases the given unsafe pointer from the heap +func Free(inst unsafe.Pointer) { + _, _ = heapFree(hHeap, heapNone, inst) +} + +// https://docs.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapalloc +func heapAlloc(hHeap heapHandle, dwFlags heapFlags, dwBytes uintptr) unsafe.Pointer { + addr := getProcAddr(&pHeapAlloc, libKernel32, "HeapAlloc") + allocatedPtr, _, _ := syscall.SyscallN(addr, hHeap, uintptr(dwFlags), dwBytes) + // Since this pointer is allocated in the heap by Windows, it will never be + // GCd by Go, so this is a safe operation. + // But linter thinks it is not (probably because we are not using CGO) and fails. + return unsafe.Pointer(allocatedPtr) //nolint:gosec,govet +} + +// https://docs.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapfree +func heapFree(hHeap heapHandle, dwFlags heapFlags, lpMem unsafe.Pointer) (bool, win32Error) { + addr := getProcAddr(&pHeapFree, libKernel32, "HeapFree") + ret, _, err := syscall.SyscallN(addr, hHeap, uintptr(dwFlags), uintptr(lpMem)) + return ret == 0, win32Error(err) +} + +func getProcessHeap() (heapHandle, win32Error) { + addr := getProcAddr(&pGetProcessHeap, libKernel32, "GetProcessHeap") + ret, _, err := syscall.SyscallN(addr) + return ret, win32Error(err) +} + +func getProcAddr(pAddr *uintptr, lib *windows.LazyDLL, procName string) uintptr { + addr := atomic.LoadUintptr(pAddr) + if addr == 0 { + addr = lib.NewProc(procName).Addr() + atomic.StoreUintptr(pAddr, addr) + } + return addr +} diff --git a/internal/winmd/metadata/Windows.AI.winmd b/internal/winmd/metadata/Windows.AI.winmd new file mode 100644 index 0000000..ed903dc Binary files /dev/null and b/internal/winmd/metadata/Windows.AI.winmd differ diff --git a/internal/winmd/metadata/Windows.ApplicationModel.winmd b/internal/winmd/metadata/Windows.ApplicationModel.winmd new file mode 100644 index 0000000..4d0fabf Binary files /dev/null and b/internal/winmd/metadata/Windows.ApplicationModel.winmd differ diff --git a/internal/winmd/metadata/Windows.Data.winmd b/internal/winmd/metadata/Windows.Data.winmd new file mode 100644 index 0000000..4b40ddd Binary files /dev/null and b/internal/winmd/metadata/Windows.Data.winmd differ diff --git a/internal/winmd/metadata/Windows.Devices.winmd b/internal/winmd/metadata/Windows.Devices.winmd new file mode 100644 index 0000000..1bef7d2 Binary files /dev/null and b/internal/winmd/metadata/Windows.Devices.winmd differ diff --git a/internal/winmd/metadata/Windows.Foundation.winmd b/internal/winmd/metadata/Windows.Foundation.winmd new file mode 100644 index 0000000..0d879db Binary files /dev/null and b/internal/winmd/metadata/Windows.Foundation.winmd differ diff --git a/internal/winmd/metadata/Windows.Gaming.winmd b/internal/winmd/metadata/Windows.Gaming.winmd new file mode 100644 index 0000000..dfff26f Binary files /dev/null and b/internal/winmd/metadata/Windows.Gaming.winmd differ diff --git a/internal/winmd/metadata/Windows.Globalization.winmd b/internal/winmd/metadata/Windows.Globalization.winmd new file mode 100644 index 0000000..3ddce37 Binary files /dev/null and b/internal/winmd/metadata/Windows.Globalization.winmd differ diff --git a/internal/winmd/metadata/Windows.Graphics.winmd b/internal/winmd/metadata/Windows.Graphics.winmd new file mode 100644 index 0000000..f07ccc8 Binary files /dev/null and b/internal/winmd/metadata/Windows.Graphics.winmd differ diff --git a/internal/winmd/metadata/Windows.Management.Setup.winmd b/internal/winmd/metadata/Windows.Management.Setup.winmd new file mode 100644 index 0000000..75e1b0b Binary files /dev/null and b/internal/winmd/metadata/Windows.Management.Setup.winmd differ diff --git a/internal/winmd/metadata/Windows.Management.winmd b/internal/winmd/metadata/Windows.Management.winmd new file mode 100644 index 0000000..67cca1a Binary files /dev/null and b/internal/winmd/metadata/Windows.Management.winmd differ diff --git a/internal/winmd/metadata/Windows.Media.winmd b/internal/winmd/metadata/Windows.Media.winmd new file mode 100644 index 0000000..d2309af Binary files /dev/null and b/internal/winmd/metadata/Windows.Media.winmd differ diff --git a/internal/winmd/metadata/Windows.Networking.winmd b/internal/winmd/metadata/Windows.Networking.winmd new file mode 100644 index 0000000..a06a638 Binary files /dev/null and b/internal/winmd/metadata/Windows.Networking.winmd differ diff --git a/internal/winmd/metadata/Windows.Perception.winmd b/internal/winmd/metadata/Windows.Perception.winmd new file mode 100644 index 0000000..b169dc7 Binary files /dev/null and b/internal/winmd/metadata/Windows.Perception.winmd differ diff --git a/internal/winmd/metadata/Windows.Security.winmd b/internal/winmd/metadata/Windows.Security.winmd new file mode 100644 index 0000000..9d995af Binary files /dev/null and b/internal/winmd/metadata/Windows.Security.winmd differ diff --git a/internal/winmd/metadata/Windows.Services.winmd b/internal/winmd/metadata/Windows.Services.winmd new file mode 100644 index 0000000..bb35c75 Binary files /dev/null and b/internal/winmd/metadata/Windows.Services.winmd differ diff --git a/internal/winmd/metadata/Windows.Storage.winmd b/internal/winmd/metadata/Windows.Storage.winmd new file mode 100644 index 0000000..1179309 Binary files /dev/null and b/internal/winmd/metadata/Windows.Storage.winmd differ diff --git a/internal/winmd/metadata/Windows.System.winmd b/internal/winmd/metadata/Windows.System.winmd new file mode 100644 index 0000000..1c0a96b Binary files /dev/null and b/internal/winmd/metadata/Windows.System.winmd differ diff --git a/internal/winmd/metadata/Windows.UI.Xaml.winmd b/internal/winmd/metadata/Windows.UI.Xaml.winmd new file mode 100644 index 0000000..6daeed9 Binary files /dev/null and b/internal/winmd/metadata/Windows.UI.Xaml.winmd differ diff --git a/internal/winmd/metadata/Windows.UI.winmd b/internal/winmd/metadata/Windows.UI.winmd new file mode 100644 index 0000000..9611d7a Binary files /dev/null and b/internal/winmd/metadata/Windows.UI.winmd differ diff --git a/internal/winmd/metadata/Windows.Web.winmd b/internal/winmd/metadata/Windows.Web.winmd new file mode 100644 index 0000000..2a0dbb5 Binary files /dev/null and b/internal/winmd/metadata/Windows.Web.winmd differ diff --git a/internal/winmd/methoddef.go b/internal/winmd/methoddef.go new file mode 100644 index 0000000..2efb680 --- /dev/null +++ b/internal/winmd/methoddef.go @@ -0,0 +1,76 @@ +package winmd + +import ( + "github.com/tdakkota/win32metadata/md" + "github.com/tdakkota/win32metadata/types" +) + +// GetMethodOverloadName finds and returns the overload attribute for the given method +func GetMethodOverloadName(ctx *types.Context, methodDef *types.MethodDef) string { + cAttrTable := ctx.Table(md.CustomAttribute) + for i := uint32(0); i < cAttrTable.RowCount(); i++ { + var cAttr types.CustomAttribute + if err := cAttr.FromRow(cAttrTable.Row(i)); err != nil { + continue + } + + // - Parent: The owner of the Attribute must be the given func + if cAttrParentTable, _ := cAttr.Parent.Table(); cAttrParentTable != md.MethodDef { + continue + } + + var parentMethodDef types.MethodDef + row, ok := cAttr.Parent.Row(ctx) + if !ok { + continue + } + if err := parentMethodDef.FromRow(row); err != nil { + continue + } + + // does the blob belong to the method we're looking for? + if parentMethodDef.Name != methodDef.Name || string(parentMethodDef.Signature) != string(methodDef.Signature) { + continue + } + + // - Type: the attribute type must be the given type + // the cAttr.Type table can be either a MemberRef or a MethodRef. + // Since we are looking for a type, we will only consider the MemberRef. + if cAttrTypeTable, _ := cAttr.Type.Table(); cAttrTypeTable != md.MemberRef { + continue + } + + var attrTypeMemberRef types.MemberRef + row, ok = cAttr.Type.Row(ctx) + if !ok { + continue + } + if err := attrTypeMemberRef.FromRow(row); err != nil { + continue + } + + // we need to check the MemberRef Class + // the value can belong to several tables, but we are only going to check for TypeRef + if classTable, _ := attrTypeMemberRef.Class.Table(); classTable != md.TypeRef { + continue + } + + var attrTypeRef types.TypeRef + row, ok = attrTypeMemberRef.Class.Row(ctx) + if !ok { + continue + } + if err := attrTypeRef.FromRow(row); err != nil { + continue + } + + if attrTypeRef.TypeNamespace+"."+attrTypeRef.TypeName == AttributeTypeOverloadAttribute { + // Metadata values start with 0x01 0x00 and ends with 0x00 0x00 + mdVal := cAttr.Value[2 : len(cAttr.Value)-2] + // the next value is the length of the string + mdVal = mdVal[1:] + return string(mdVal) + } + } + return methodDef.Name +} diff --git a/internal/winmd/store.go b/internal/winmd/store.go new file mode 100644 index 0000000..7f86f53 --- /dev/null +++ b/internal/winmd/store.go @@ -0,0 +1,89 @@ +package winmd + +import ( + "fmt" + + "github.com/go-kit/log" + "github.com/tdakkota/win32metadata/md" + "github.com/tdakkota/win32metadata/types" +) + +// ClassNotFoundError is returned when a class is not found. +type ClassNotFoundError struct { + Class string +} + +func (e *ClassNotFoundError) Error() string { + return fmt.Sprintf("class %s was not found", e.Class) +} + +// Store holds the windows metadata contexts. It can be used to get the metadata across multiple files. +type Store struct { + contexts map[string]*types.Context + logger log.Logger +} + +// NewStore loads all windows metadata files and returns a new Store. +func NewStore(logger log.Logger) (*Store, error) { + contexts := make(map[string]*types.Context) + + winmdFiles, err := allFiles() + if err != nil { + return nil, err + } + + // parse and store all files in memory + for _, f := range winmdFiles { + winmdCtx, err := parseWinMDFile(f.Name()) + if err != nil { + return nil, err + } + contexts[f.Name()] = winmdCtx + } + + return &Store{ + contexts: contexts, + logger: logger, + }, nil +} + +func parseWinMDFile(path string) (*types.Context, error) { + f, err := open(path) + if err != nil { + return nil, err + } + defer func() { _ = f.Close() }() + + return types.FromPE(f) +} + +// TypeDefByName returns a type definition that matches the given name. +func (mds *Store) TypeDefByName(class string) (*TypeDef, error) { + // the type can belong to any of the contexts + for _, ctx := range mds.contexts { + if td := mds.typeDefByNameAndCtx(class, ctx); td != nil { + return td, nil // return the first match + } + } + return nil, &ClassNotFoundError{Class: class} +} + +func (mds *Store) typeDefByNameAndCtx(class string, ctx *types.Context) *TypeDef { + typeDefTable := ctx.Table(md.TypeDef) + for i := uint32(0); i < typeDefTable.RowCount(); i++ { + var typeDef types.TypeDef + if err := typeDef.FromRow(typeDefTable.Row(i)); err != nil { + continue // keep searching instead of failing + } + + if typeDef.TypeNamespace+"."+typeDef.TypeName == class { + return &TypeDef{ + TypeDef: typeDef, + HasContext: HasContext{ctx}, + logger: mds.logger, + } + } + } + + return nil +} diff --git a/internal/winmd/typedef.go b/internal/winmd/typedef.go new file mode 100644 index 0000000..a2ff215 --- /dev/null +++ b/internal/winmd/typedef.go @@ -0,0 +1,310 @@ +package winmd + +import ( + "fmt" + "strconv" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + "github.com/tdakkota/win32metadata/md" + "github.com/tdakkota/win32metadata/types" +) + +// TypeDef is a helper struct that wraps types.TypeDef and stores the original context +// of the typeDef. +type TypeDef struct { + types.TypeDef + HasContext + + logger log.Logger +} + +// QualifiedID holds the namespace and the name of a qualified element. This may be a type, a static function or a field +type QualifiedID struct { + Namespace string + Name string +} + +// GetValueForEnumField returns the value of the requested enum field. +func (typeDef *TypeDef) GetValueForEnumField(fieldIndex uint32) (string, error) { + // For each Enum value definition, there is a corresponding row in the Constant table to store the integer value for the enum value. + tableConstants := typeDef.Ctx().Table(md.Constant) + for i := uint32(0); i < tableConstants.RowCount(); i++ { + var constant types.Constant + if err := constant.FromRow(tableConstants.Row(i)); err != nil { + return "", err + } + + if t, _ := constant.Parent.Table(); t != md.Field { + continue + } + + // does the blob belong to the field we're looking for? + // The parent is an index into the field table that holds the associated enum value record + if constant.Parent.TableIndex() != fieldIndex { + continue + } + + // The value is a blob that we need to read as little endian + var blobIndex uint32 + for i, b := range constant.Value { + blobIndex += uint32(b) << (i * 8) + } + return strconv.Itoa(int(blobIndex)), nil + } + + return "", fmt.Errorf("no value found for field %d", fieldIndex) +} + +// GetAttributeWithType returns the value of the given attribute type and fails if not found. +func (typeDef *TypeDef) GetAttributeWithType(lookupAttrTypeClass string) ([]byte, error) { + result := typeDef.GetTypeDefAttributesWithType(lookupAttrTypeClass) + if len(result) == 0 { + return nil, fmt.Errorf("type %s has no custom attribute %s", typeDef.TypeNamespace+"."+typeDef.TypeName, lookupAttrTypeClass) + } else if len(result) > 1 { + _ = level.Warn(typeDef.logger).Log( + "msg", "type has multiple custom attributes, returning the first one", + "type", typeDef.TypeNamespace+"."+typeDef.TypeName, + "attr", lookupAttrTypeClass, + ) + } + + return result[0], nil +} + +// GetTypeDefAttributesWithType returns the values of all the attributes that match the given type. +func (typeDef *TypeDef) GetTypeDefAttributesWithType(lookupAttrTypeClass string) [][]byte { + result := make([][]byte, 0) + cAttrTable := typeDef.Ctx().Table(md.CustomAttribute) + for i := uint32(0); i < cAttrTable.RowCount(); i++ { + var cAttr types.CustomAttribute + if err := cAttr.FromRow(cAttrTable.Row(i)); err != nil { + continue + } + + // - Parent: The owner of the Attribute must be the given typeDef + if cAttrParentTable, _ := cAttr.Parent.Table(); cAttrParentTable != md.TypeDef { + continue + } + + var parentTypeDef TypeDef + row, ok := cAttr.Parent.Row(typeDef.Ctx()) + if !ok { + continue + } + if err := parentTypeDef.FromRow(row); err != nil { + continue + } + + // does the blob belong to the type we're looking for? + if parentTypeDef.TypeNamespace != typeDef.TypeNamespace || parentTypeDef.TypeName != typeDef.TypeName { + continue + } + + // - Type: the attribute type must be the given type + // the cAttr.Type table can be either a MemberRef or a MethodRef. + // Since we are looking for a type, we will only consider the MemberRef. + if cAttrTypeTable, _ := cAttr.Type.Table(); cAttrTypeTable != md.MemberRef { + continue + } + + var attrTypeMemberRef types.MemberRef + row, ok = cAttr.Type.Row(typeDef.Ctx()) + if !ok { + continue + } + if err := attrTypeMemberRef.FromRow(row); err != nil { + continue + } + + // we need to check the MemberRef Class + // the value can belong to several tables, but we are only going to check for TypeRef + if classTable, _ := attrTypeMemberRef.Class.Table(); classTable != md.TypeRef { + continue + } + + var attrTypeRef types.TypeRef + row, ok = attrTypeMemberRef.Class.Row(typeDef.Ctx()) + if !ok { + continue + } + if err := attrTypeRef.FromRow(row); err != nil { + continue + } + + if attrTypeRef.TypeNamespace+"."+attrTypeRef.TypeName == lookupAttrTypeClass { + result = append(result, cAttr.Value) + } + } + + return result +} + +// GetImplementedInterfaces returns the interfaces implemented by the type. +func (typeDef *TypeDef) GetImplementedInterfaces() ([]QualifiedID, error) { + interfaces := make([]QualifiedID, 0) + + tableInterfaceImpl := typeDef.Ctx().Table(md.InterfaceImpl) + for i := uint32(0); i < tableInterfaceImpl.RowCount(); i++ { + var interfaceImpl types.InterfaceImpl + if err := interfaceImpl.FromRow(tableInterfaceImpl.Row(i)); err != nil { + return nil, err + } + + classTd, err := interfaceImpl.ResolveClass(typeDef.Ctx()) + if err != nil { + return nil, err + } + + if classTd.TypeNamespace+"."+classTd.TypeName != typeDef.TypeNamespace+"."+typeDef.TypeName { + // not the class we are looking for + continue + } + + if t, ok := interfaceImpl.Interface.Table(); ok && t == md.TypeSpec { + // ignore type spec rows + continue + } + + ifaceNS, ifaceName, err := typeDef.Ctx().ResolveTypeDefOrRefName(interfaceImpl.Interface) + if err != nil { + return nil, err + } + + interfaces = append(interfaces, QualifiedID{Namespace: ifaceNS, Name: ifaceName}) + } + + return interfaces, nil +} + +// Extends returns true if the type extends the given class +func (typeDef *TypeDef) Extends(class string) (bool, error) { + ns, name, err := typeDef.Ctx().ResolveTypeDefOrRefName(typeDef.TypeDef.Extends) + if err != nil { + return false, err + } + return ns+"."+name == class, nil +} + +// GetGenericParams returns the generic parameters of the type. +func (typeDef *TypeDef) GetGenericParams() ([]*types.GenericParam, error) { + params := make([]*types.GenericParam, 0) + tableGenericParam := typeDef.Ctx().Table(md.GenericParam) + for i := uint32(0); i < tableGenericParam.RowCount(); i++ { + var genericParam types.GenericParam + if err := genericParam.FromRow(tableGenericParam.Row(i)); err != nil { + continue + } + + // - Owner: The owner of the Attribute must be the given typeDef + if genericParamOwnerTable, _ := genericParam.Owner.Table(); genericParamOwnerTable != md.TypeDef { + continue + } + + var ownerTypeDef types.TypeDef + row, ok := genericParam.Owner.Row(typeDef.Ctx()) + if !ok { + continue + } + if err := ownerTypeDef.FromRow(row); err != nil { + continue + } + + // does the blob belong to the type we're looking for? + if ownerTypeDef.TypeNamespace != typeDef.TypeNamespace || ownerTypeDef.TypeName != typeDef.TypeName { + continue + } + + params = append(params, &genericParam) + } + if len(params) == 0 { + return nil, fmt.Errorf("could not find generic params for type %s.%s", typeDef.TypeNamespace, typeDef.TypeName) + } + + return params, nil +} + +// IsInterface returns true if the type is an interface +func (typeDef *TypeDef) IsInterface() bool { + return typeDef.Flags.Interface() +} + +// IsEnum returns true if the type is an enum +func (typeDef *TypeDef) IsEnum() bool { + ok, err := typeDef.Extends("System.Enum") + if err != nil { + _ = level.Error(typeDef.logger).Log("msg", "error resolving type extends, all classes should extend at least System.Object", "err", err) + return false + } + return ok +} + +// IsDelegate returns true if the type is a delegate +func (typeDef *TypeDef) IsDelegate() bool { + if !(typeDef.Flags.Public() && typeDef.Flags.Sealed()) { + return false + } + + ok, err := typeDef.Extends("System.MulticastDelegate") + if err != nil { + _ = level.Error(typeDef.logger).Log("msg", "error resolving type extends, all classes should extend at least System.Object", "err", err) + return false + } + + return ok +} + +// IsStruct returns true if the type is a struct +func (typeDef *TypeDef) IsStruct() bool { + ok, err := typeDef.Extends("System.ValueType") + if err != nil { + _ = level.Error(typeDef.logger).Log("msg", "error resolving type extends, all classes should extend at least System.Object", "err", err) + return false + } + return ok +} + +// IsRuntimeClass returns true if the type is a runtime class +func (typeDef *TypeDef) IsRuntimeClass() bool { + // Flags: all runtime classes must carry the public, auto layout, class, and tdWindowsRuntime flags. + return typeDef.Flags.Public() && typeDef.Flags.AutoLayout() && typeDef.Flags.Class() && typeDef.Flags&0x4000 != 0 +} + +// GUID returns the GUID of the type. +func (typeDef *TypeDef) GUID() (string, error) { + blob, err := typeDef.GetAttributeWithType(AttributeTypeGUID) + if err != nil { + return "", err + } + return guidBlobToString(blob) +} + +// guidBlobToString converts an array into the textual representation of a GUID +func guidBlobToString(b types.Blob) (string, error) { + // the guid is a blob of 20 bytes + if len(b) != 20 { + return "", fmt.Errorf("invalid GUID blob length: %d", len(b)) + } + + // that starts with 0100 + if b[0] != 0x01 || b[1] != 0x00 { + return "", fmt.Errorf("invalid GUID blob header, expected '0x01 0x00' but found '0x%02x 0x%02x'", b[0], b[1]) + } + + // and ends with 0000 + if b[18] != 0x00 || b[19] != 0x00 { + return "", fmt.Errorf("invalid GUID blob footer, expected '0x00 0x00' but found '0x%02x 0x%02x'", b[18], b[19]) + } + + guid := b[2 : len(b)-2] + // the string version has 5 parts separated by '-' + return fmt.Sprintf("%08x-%04x-%04x-%04x-%04x%08x", + // The first 3 are encoded as little endian + uint32(guid[0])|uint32(guid[1])<<8|uint32(guid[2])<<16|uint32(guid[3])<<24, + uint16(guid[4])|uint16(guid[5])<<8, + uint16(guid[6])|uint16(guid[7])<<8, + //the rest is not + uint16(guid[8])<<8|uint16(guid[9]), + uint16(guid[10])<<8|uint16(guid[11]), + uint32(guid[12])<<24|uint32(guid[13])<<16|uint32(guid[14])<<8|uint32(guid[15])), nil +} diff --git a/internal/winmd/winmd.go b/internal/winmd/winmd.go new file mode 100644 index 0000000..f505063 --- /dev/null +++ b/internal/winmd/winmd.go @@ -0,0 +1,61 @@ +package winmd + +import ( + "bytes" + "debug/pe" + "embed" + "io/fs" + "io/ioutil" + + "github.com/tdakkota/win32metadata/types" +) + +// Custom Attributes +const ( + AttributeTypeGUID = "Windows.Foundation.Metadata.GuidAttribute" + AttributeTypeExclusiveTo = "Windows.Foundation.Metadata.ExclusiveToAttribute" + AttributeTypeStaticAttribute = "Windows.Foundation.Metadata.StaticAttribute" + AttributeTypeActivatableAttribute = "Windows.Foundation.Metadata.ActivatableAttribute" + AttributeTypeDefaultAttribute = "Windows.Foundation.Metadata.DefaultAttribute" + AttributeTypeOverloadAttribute = "Windows.Foundation.Metadata.OverloadAttribute" +) + +// HasContext is a helper struct that holds the original context of a metadata element. +type HasContext struct { + originalCtx *types.Context +} + +// Ctx return the original context of the element. +func (hctx *HasContext) Ctx() *types.Context { + return hctx.originalCtx +} + +//go:embed metadata/*.winmd +var files embed.FS + +// allFiles returns all winmd files embedded in the binary. +func allFiles() ([]fs.DirEntry, error) { + return files.ReadDir("metadata") +} + +// open reads the given file and returns a pe.File instance. +// The user should close the returned instance once he is done working with it. +func open(path string) (*pe.File, error) { + f, err := files.Open("metadata/" + path) + if err != nil { + return nil, err + } + defer func() { _ = f.Close() }() + + data, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + + pef, err := pe.NewFile(bytes.NewReader(data)) + if err != nil { + return nil, err + } + + return pef, nil +} diff --git a/signature.go b/signature.go new file mode 100644 index 0000000..e2aa252 --- /dev/null +++ b/signature.go @@ -0,0 +1,70 @@ +package winrt + +import ( + "crypto/sha1" // #nosec this is not used for security purposes + "encoding/binary" + "fmt" + "strings" + + "github.com/go-ole/go-ole" +) + +// Primitive types signatures +const ( + SignatureUInt8 = "u1" + SignatureUInt16 = "u2" + SignatureUInt32 = "u4" + SignatureUInt64 = "u8" + SignatureInt8 = "i1" + SignatureInt16 = "i2" + SignatureInt32 = "i4" + SignatureInt64 = "i8" + SignatureFloat32 = "f4" + SignatureFloat64 = "f8" + SignatureBool = "b1" + SignatureChar = "c2" + SignatureString = "string" + SignatureGUID = "g16" +) + +// ParameterizedInstanceGUID creates a `GUID` for a "generic" WinRT delegate or interface. This was ported from the RUST implementation +// of WinRT, checkout for the source code: +// https://github.com/microsoft/windows-rs/blob/68576f37df4c02f09bc6e4dd1ed8ed8844c6eb9c/crates/libs/windows/src/core/guid.rs#L44 +// +// Checkout the following link for documentation on how the signatures are generated: +// https://docs.microsoft.com/en-us/uwp/winrt-cref/winrt-type-system#guid-generation-for-parameterized-types +func ParameterizedInstanceGUID(baseGUID string, signatures ...string) string { + res := fmt.Sprintf("pinterface({%s};%s)", baseGUID, strings.Join(signatures, ";")) + return guidFromSignature(res) +} + +func guidFromSignature(signature string) string { + // base wrt_pinterface_namespace => 11f47ad5-7b73-42c0-abae-878b1e16adee + data := []byte{0x11, 0xf4, 0x7a, 0xd5, 0x7b, 0x73, 0x42, 0xc0, 0xab, 0xae, 0x87, 0x8b, 0x1e, 0x16, 0xad, 0xee} + + data = append(data, []byte(signature)...) + + hash := sha1.New() // #nosec this is not used for security purposes + if _, err := hash.Write(data); err != nil { + return "_ERROR_" + } + + bytes := hash.Sum(nil) + first := binary.BigEndian.Uint32(bytes[0:4]) + second := binary.BigEndian.Uint16(bytes[4:6]) + third := binary.BigEndian.Uint16(bytes[6:8]) + third = (third & 0x0fff) | (5 << 12) + fourth := (bytes[8] & 0x3f) | 0x80 + + guid := guidFromValues(first, second, third, [8]byte{fourth, bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]}) + return guid.String() +} + +func guidFromValues(first uint32, second, third uint16, rest [8]byte) ole.GUID { + return ole.GUID{ + Data1: first, + Data2: second, + Data3: third, + Data4: rest, + } +} diff --git a/signature_test.go b/signature_test.go new file mode 100644 index 0000000..c8bb466 --- /dev/null +++ b/signature_test.go @@ -0,0 +1,31 @@ +package winrt + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +// Test that we can create a `GUID` for a "generic" WinRT type. +const ( + guidTypedEventHandler = "9de1c534-6ae1-11e0-84e1-18a905bcc53f" + signatureBluetoothLEAdvertisementWatcher = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher;{a6ac336f-f3d3-4297-8d6c-c81ea6623f40})" + signatureBluetoothLEAdvertisementReceivedEventArgs = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementReceivedEventArgs;{27987ddf-e596-41be-8d43-9e6731d4a913})" + signatureBluetoothLEAdvertisementWatcherStoppedEventArgs = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcherStoppedEventArgs;{dd40f84d-e7b9-43e3-9c04-0685d085fd8c})" +) + +// TypedEventHandler +func TestParametrizedReceivedEvent(t *testing.T) { + expected := "{90EB4ECA-D465-5EA0-A61C-033C8C5ECEF2}" + guid := ParameterizedInstanceGUID(guidTypedEventHandler, signatureBluetoothLEAdvertisementWatcher, signatureBluetoothLEAdvertisementReceivedEventArgs) + + assert.Equal(t, expected, guid) +} + +// TypedEventHandler +func TestParametrizedStoppedEvent(t *testing.T) { + expected := "{9936A4DB-DC99-55C3-9E9B-BF4854BD9EAB}" + guid := ParameterizedInstanceGUID(guidTypedEventHandler, signatureBluetoothLEAdvertisementWatcher, signatureBluetoothLEAdvertisementWatcherStoppedEventArgs) + + assert.Equal(t, expected, guid) +} diff --git a/windows/devices/bluetooth/advertisement/bluetoothleadvertisement.go b/windows/devices/bluetooth/advertisement/bluetoothleadvertisement.go new file mode 100644 index 0000000..abe19f4 --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothleadvertisement.go @@ -0,0 +1,168 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation/collections" +) + +const SignatureBluetoothLEAdvertisement string = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisement;{066fb2b7-33d1-4e7d-8367-cf81d0f79653})" + +type BluetoothLEAdvertisement struct { + ole.IUnknown +} + +func NewBluetoothLEAdvertisement() (*BluetoothLEAdvertisement, error) { + inspectable, err := ole.RoActivateInstance("Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisement") + if err != nil { + return nil, err + } + return (*BluetoothLEAdvertisement)(unsafe.Pointer(inspectable)), nil +} + +func (impl *BluetoothLEAdvertisement) GetLocalName() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisement)) + defer itf.Release() + v := (*iBluetoothLEAdvertisement)(unsafe.Pointer(itf)) + return v.GetLocalName() +} + +func (impl *BluetoothLEAdvertisement) SetLocalName(value string) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisement)) + defer itf.Release() + v := (*iBluetoothLEAdvertisement)(unsafe.Pointer(itf)) + return v.SetLocalName(value) +} + +func (impl *BluetoothLEAdvertisement) GetServiceUuids() (*collections.IVector, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisement)) + defer itf.Release() + v := (*iBluetoothLEAdvertisement)(unsafe.Pointer(itf)) + return v.GetServiceUuids() +} + +func (impl *BluetoothLEAdvertisement) GetManufacturerData() (*collections.IVector, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisement)) + defer itf.Release() + v := (*iBluetoothLEAdvertisement)(unsafe.Pointer(itf)) + return v.GetManufacturerData() +} + +func (impl *BluetoothLEAdvertisement) GetDataSections() (*collections.IVector, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisement)) + defer itf.Release() + v := (*iBluetoothLEAdvertisement)(unsafe.Pointer(itf)) + return v.GetDataSections() +} + +const GUIDiBluetoothLEAdvertisement string = "066fb2b7-33d1-4e7d-8367-cf81d0f79653" +const SignatureiBluetoothLEAdvertisement string = "{066fb2b7-33d1-4e7d-8367-cf81d0f79653}" + +type iBluetoothLEAdvertisement struct { + ole.IInspectable +} + +type iBluetoothLEAdvertisementVtbl struct { + ole.IInspectableVtbl + + GetFlags uintptr + SetFlags uintptr + GetLocalName uintptr + SetLocalName uintptr + GetServiceUuids uintptr + GetManufacturerData uintptr + GetDataSections uintptr + GetManufacturerDataByCompanyId uintptr + GetSectionsByType uintptr +} + +func (v *iBluetoothLEAdvertisement) VTable() *iBluetoothLEAdvertisementVtbl { + return (*iBluetoothLEAdvertisementVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEAdvertisement) GetLocalName() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetLocalName, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +func (v *iBluetoothLEAdvertisement) SetLocalName(value string) error { + valueHStr, err := ole.NewHString(value) + if err != nil { + return err + } + hr, _, _ := syscall.SyscallN( + v.VTable().SetLocalName, + uintptr(unsafe.Pointer(v)), // this + uintptr(valueHStr), // in string + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iBluetoothLEAdvertisement) GetServiceUuids() (*collections.IVector, error) { + var out *collections.IVector + hr, _, _ := syscall.SyscallN( + v.VTable().GetServiceUuids, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVector + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisement) GetManufacturerData() (*collections.IVector, error) { + var out *collections.IVector + hr, _, _ := syscall.SyscallN( + v.VTable().GetManufacturerData, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVector + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisement) GetDataSections() (*collections.IVector, error) { + var out *collections.IVector + hr, _, _ := syscall.SyscallN( + v.VTable().GetDataSections, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVector + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/advertisement/bluetoothleadvertisementdatasection.go b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementdatasection.go new file mode 100644 index 0000000..76005cb --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementdatasection.go @@ -0,0 +1,69 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const SignatureBluetoothLEAdvertisementDataSection string = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementDataSection;{d7213314-3a43-40f9-b6f0-92bfefc34ae3})" + +type BluetoothLEAdvertisementDataSection struct { + ole.IUnknown +} + +func NewBluetoothLEAdvertisementDataSection() (*BluetoothLEAdvertisementDataSection, error) { + inspectable, err := ole.RoActivateInstance("Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementDataSection") + if err != nil { + return nil, err + } + return (*BluetoothLEAdvertisementDataSection)(unsafe.Pointer(inspectable)), nil +} + +func (impl *BluetoothLEAdvertisementDataSection) GetDataType() (uint8, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementDataSection)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementDataSection)(unsafe.Pointer(itf)) + return v.GetDataType() +} + +const GUIDiBluetoothLEAdvertisementDataSection string = "d7213314-3a43-40f9-b6f0-92bfefc34ae3" +const SignatureiBluetoothLEAdvertisementDataSection string = "{d7213314-3a43-40f9-b6f0-92bfefc34ae3}" + +type iBluetoothLEAdvertisementDataSection struct { + ole.IInspectable +} + +type iBluetoothLEAdvertisementDataSectionVtbl struct { + ole.IInspectableVtbl + + GetDataType uintptr + SetDataType uintptr + GetData uintptr + SetData uintptr +} + +func (v *iBluetoothLEAdvertisementDataSection) VTable() *iBluetoothLEAdvertisementDataSectionVtbl { + return (*iBluetoothLEAdvertisementDataSectionVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEAdvertisementDataSection) GetDataType() (uint8, error) { + var out uint8 + hr, _, _ := syscall.SyscallN( + v.VTable().GetDataType, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint8 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/advertisement/bluetoothleadvertisementpublisher.go b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementpublisher.go new file mode 100644 index 0000000..46865c9 --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementpublisher.go @@ -0,0 +1,157 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const SignatureBluetoothLEAdvertisementPublisher string = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementPublisher;{cde820f9-d9fa-43d6-a264-ddd8b7da8b78})" + +type BluetoothLEAdvertisementPublisher struct { + ole.IUnknown +} + +func NewBluetoothLEAdvertisementPublisher() (*BluetoothLEAdvertisementPublisher, error) { + inspectable, err := ole.RoActivateInstance("Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementPublisher") + if err != nil { + return nil, err + } + return (*BluetoothLEAdvertisementPublisher)(unsafe.Pointer(inspectable)), nil +} + +func (impl *BluetoothLEAdvertisementPublisher) GetStatus() (BluetoothLEAdvertisementPublisherStatus, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementPublisher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementPublisher)(unsafe.Pointer(itf)) + return v.GetStatus() +} + +func (impl *BluetoothLEAdvertisementPublisher) GetAdvertisement() (*BluetoothLEAdvertisement, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementPublisher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementPublisher)(unsafe.Pointer(itf)) + return v.GetAdvertisement() +} + +func (impl *BluetoothLEAdvertisementPublisher) Start() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementPublisher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementPublisher)(unsafe.Pointer(itf)) + return v.Start() +} + +func (impl *BluetoothLEAdvertisementPublisher) Stop() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementPublisher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementPublisher)(unsafe.Pointer(itf)) + return v.Stop() +} + +const GUIDiBluetoothLEAdvertisementPublisher string = "cde820f9-d9fa-43d6-a264-ddd8b7da8b78" +const SignatureiBluetoothLEAdvertisementPublisher string = "{cde820f9-d9fa-43d6-a264-ddd8b7da8b78}" + +type iBluetoothLEAdvertisementPublisher struct { + ole.IInspectable +} + +type iBluetoothLEAdvertisementPublisherVtbl struct { + ole.IInspectableVtbl + + GetStatus uintptr + GetAdvertisement uintptr + Start uintptr + Stop uintptr + AddStatusChanged uintptr + RemoveStatusChanged uintptr +} + +func (v *iBluetoothLEAdvertisementPublisher) VTable() *iBluetoothLEAdvertisementPublisherVtbl { + return (*iBluetoothLEAdvertisementPublisherVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEAdvertisementPublisher) GetStatus() (BluetoothLEAdvertisementPublisherStatus, error) { + var out BluetoothLEAdvertisementPublisherStatus + hr, _, _ := syscall.SyscallN( + v.VTable().GetStatus, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out BluetoothLEAdvertisementPublisherStatus + ) + + if hr != 0 { + return BluetoothLEAdvertisementPublisherStatusCreated, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisementPublisher) GetAdvertisement() (*BluetoothLEAdvertisement, error) { + var out *BluetoothLEAdvertisement + hr, _, _ := syscall.SyscallN( + v.VTable().GetAdvertisement, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out BluetoothLEAdvertisement + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisementPublisher) Start() error { + hr, _, _ := syscall.SyscallN( + v.VTable().Start, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iBluetoothLEAdvertisementPublisher) Stop() error { + hr, _, _ := syscall.SyscallN( + v.VTable().Stop, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiBluetoothLEAdvertisementPublisher2 string = "fbdb545e-56f1-510f-a434-217fbd9e7bd2" +const SignatureiBluetoothLEAdvertisementPublisher2 string = "{fbdb545e-56f1-510f-a434-217fbd9e7bd2}" + +type iBluetoothLEAdvertisementPublisher2 struct { + ole.IInspectable +} + +type iBluetoothLEAdvertisementPublisher2Vtbl struct { + ole.IInspectableVtbl + + GetPreferredTransmitPowerLevelInDBm uintptr + SetPreferredTransmitPowerLevelInDBm uintptr + GetUseExtendedAdvertisement uintptr + SetUseExtendedAdvertisement uintptr + GetIsAnonymous uintptr + SetIsAnonymous uintptr + GetIncludeTransmitPowerLevel uintptr + SetIncludeTransmitPowerLevel uintptr +} + +func (v *iBluetoothLEAdvertisementPublisher2) VTable() *iBluetoothLEAdvertisementPublisher2Vtbl { + return (*iBluetoothLEAdvertisementPublisher2Vtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/windows/devices/bluetooth/advertisement/bluetoothleadvertisementpublisherstatus.go b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementpublisherstatus.go new file mode 100644 index 0000000..37632f2 --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementpublisherstatus.go @@ -0,0 +1,19 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +type BluetoothLEAdvertisementPublisherStatus int32 + +const SignatureBluetoothLEAdvertisementPublisherStatus string = "enum(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementPublisherStatus;i4)" + +const ( + BluetoothLEAdvertisementPublisherStatusCreated BluetoothLEAdvertisementPublisherStatus = 0 + BluetoothLEAdvertisementPublisherStatusWaiting BluetoothLEAdvertisementPublisherStatus = 1 + BluetoothLEAdvertisementPublisherStatusStarted BluetoothLEAdvertisementPublisherStatus = 2 + BluetoothLEAdvertisementPublisherStatusStopping BluetoothLEAdvertisementPublisherStatus = 3 + BluetoothLEAdvertisementPublisherStatusStopped BluetoothLEAdvertisementPublisherStatus = 4 + BluetoothLEAdvertisementPublisherStatusAborted BluetoothLEAdvertisementPublisherStatus = 5 +) diff --git a/windows/devices/bluetooth/advertisement/bluetoothleadvertisementreceivedeventargs.go b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementreceivedeventargs.go new file mode 100644 index 0000000..b236183 --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementreceivedeventargs.go @@ -0,0 +1,129 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const SignatureBluetoothLEAdvertisementReceivedEventArgs string = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementReceivedEventArgs;{27987ddf-e596-41be-8d43-9e6731d4a913})" + +type BluetoothLEAdvertisementReceivedEventArgs struct { + ole.IUnknown +} + +func (impl *BluetoothLEAdvertisementReceivedEventArgs) GetRawSignalStrengthInDBm() (int16, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementReceivedEventArgs)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementReceivedEventArgs)(unsafe.Pointer(itf)) + return v.GetRawSignalStrengthInDBm() +} + +func (impl *BluetoothLEAdvertisementReceivedEventArgs) GetBluetoothAddress() (uint64, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementReceivedEventArgs)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementReceivedEventArgs)(unsafe.Pointer(itf)) + return v.GetBluetoothAddress() +} + +func (impl *BluetoothLEAdvertisementReceivedEventArgs) GetAdvertisement() (*BluetoothLEAdvertisement, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementReceivedEventArgs)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementReceivedEventArgs)(unsafe.Pointer(itf)) + return v.GetAdvertisement() +} + +const GUIDiBluetoothLEAdvertisementReceivedEventArgs string = "27987ddf-e596-41be-8d43-9e6731d4a913" +const SignatureiBluetoothLEAdvertisementReceivedEventArgs string = "{27987ddf-e596-41be-8d43-9e6731d4a913}" + +type iBluetoothLEAdvertisementReceivedEventArgs struct { + ole.IInspectable +} + +type iBluetoothLEAdvertisementReceivedEventArgsVtbl struct { + ole.IInspectableVtbl + + GetRawSignalStrengthInDBm uintptr + GetBluetoothAddress uintptr + GetAdvertisementType uintptr + GetTimestamp uintptr + GetAdvertisement uintptr +} + +func (v *iBluetoothLEAdvertisementReceivedEventArgs) VTable() *iBluetoothLEAdvertisementReceivedEventArgsVtbl { + return (*iBluetoothLEAdvertisementReceivedEventArgsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEAdvertisementReceivedEventArgs) GetRawSignalStrengthInDBm() (int16, error) { + var out int16 + hr, _, _ := syscall.SyscallN( + v.VTable().GetRawSignalStrengthInDBm, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out int16 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisementReceivedEventArgs) GetBluetoothAddress() (uint64, error) { + var out uint64 + hr, _, _ := syscall.SyscallN( + v.VTable().GetBluetoothAddress, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint64 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisementReceivedEventArgs) GetAdvertisement() (*BluetoothLEAdvertisement, error) { + var out *BluetoothLEAdvertisement + hr, _, _ := syscall.SyscallN( + v.VTable().GetAdvertisement, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out BluetoothLEAdvertisement + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +const GUIDiBluetoothLEAdvertisementReceivedEventArgs2 string = "12d9c87b-0399-5f0e-a348-53b02b6b162e" +const SignatureiBluetoothLEAdvertisementReceivedEventArgs2 string = "{12d9c87b-0399-5f0e-a348-53b02b6b162e}" + +type iBluetoothLEAdvertisementReceivedEventArgs2 struct { + ole.IInspectable +} + +type iBluetoothLEAdvertisementReceivedEventArgs2Vtbl struct { + ole.IInspectableVtbl + + GetBluetoothAddressType uintptr + GetTransmitPowerLevelInDBm uintptr + GetIsAnonymous uintptr + GetIsConnectable uintptr + GetIsScannable uintptr + GetIsDirected uintptr + GetIsScanResponse uintptr +} + +func (v *iBluetoothLEAdvertisementReceivedEventArgs2) VTable() *iBluetoothLEAdvertisementReceivedEventArgs2Vtbl { + return (*iBluetoothLEAdvertisementReceivedEventArgs2Vtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/windows/devices/bluetooth/advertisement/bluetoothleadvertisementwatcher.go b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementwatcher.go new file mode 100644 index 0000000..0b02f2f --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementwatcher.go @@ -0,0 +1,315 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureBluetoothLEAdvertisementWatcher string = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher;{a6ac336f-f3d3-4297-8d6c-c81ea6623f40})" + +type BluetoothLEAdvertisementWatcher struct { + ole.IUnknown +} + +func NewBluetoothLEAdvertisementWatcher() (*BluetoothLEAdvertisementWatcher, error) { + inspectable, err := ole.RoActivateInstance("Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher") + if err != nil { + return nil, err + } + return (*BluetoothLEAdvertisementWatcher)(unsafe.Pointer(inspectable)), nil +} + +func (impl *BluetoothLEAdvertisementWatcher) GetStatus() (BluetoothLEAdvertisementWatcherStatus, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher)(unsafe.Pointer(itf)) + return v.GetStatus() +} + +func (impl *BluetoothLEAdvertisementWatcher) GetScanningMode() (BluetoothLEScanningMode, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher)(unsafe.Pointer(itf)) + return v.GetScanningMode() +} + +func (impl *BluetoothLEAdvertisementWatcher) SetScanningMode(value BluetoothLEScanningMode) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher)(unsafe.Pointer(itf)) + return v.SetScanningMode(value) +} + +func (impl *BluetoothLEAdvertisementWatcher) Start() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher)(unsafe.Pointer(itf)) + return v.Start() +} + +func (impl *BluetoothLEAdvertisementWatcher) Stop() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher)(unsafe.Pointer(itf)) + return v.Stop() +} + +func (impl *BluetoothLEAdvertisementWatcher) AddReceived(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher)(unsafe.Pointer(itf)) + return v.AddReceived(handler) +} + +func (impl *BluetoothLEAdvertisementWatcher) RemoveReceived(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher)(unsafe.Pointer(itf)) + return v.RemoveReceived(token) +} + +func (impl *BluetoothLEAdvertisementWatcher) AddStopped(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher)(unsafe.Pointer(itf)) + return v.AddStopped(handler) +} + +func (impl *BluetoothLEAdvertisementWatcher) RemoveStopped(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher)(unsafe.Pointer(itf)) + return v.RemoveStopped(token) +} + +func (impl *BluetoothLEAdvertisementWatcher) GetAllowExtendedAdvertisements() (bool, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher2)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher2)(unsafe.Pointer(itf)) + return v.GetAllowExtendedAdvertisements() +} + +func (impl *BluetoothLEAdvertisementWatcher) SetAllowExtendedAdvertisements(value bool) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcher2)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcher2)(unsafe.Pointer(itf)) + return v.SetAllowExtendedAdvertisements(value) +} + +const GUIDiBluetoothLEAdvertisementWatcher string = "a6ac336f-f3d3-4297-8d6c-c81ea6623f40" +const SignatureiBluetoothLEAdvertisementWatcher string = "{a6ac336f-f3d3-4297-8d6c-c81ea6623f40}" + +type iBluetoothLEAdvertisementWatcher struct { + ole.IInspectable +} + +type iBluetoothLEAdvertisementWatcherVtbl struct { + ole.IInspectableVtbl + + GetMinSamplingInterval uintptr + GetMaxSamplingInterval uintptr + GetMinOutOfRangeTimeout uintptr + GetMaxOutOfRangeTimeout uintptr + GetStatus uintptr + GetScanningMode uintptr + SetScanningMode uintptr + GetSignalStrengthFilter uintptr + SetSignalStrengthFilter uintptr + GetAdvertisementFilter uintptr + SetAdvertisementFilter uintptr + Start uintptr + Stop uintptr + AddReceived uintptr + RemoveReceived uintptr + AddStopped uintptr + RemoveStopped uintptr +} + +func (v *iBluetoothLEAdvertisementWatcher) VTable() *iBluetoothLEAdvertisementWatcherVtbl { + return (*iBluetoothLEAdvertisementWatcherVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEAdvertisementWatcher) GetStatus() (BluetoothLEAdvertisementWatcherStatus, error) { + var out BluetoothLEAdvertisementWatcherStatus + hr, _, _ := syscall.SyscallN( + v.VTable().GetStatus, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out BluetoothLEAdvertisementWatcherStatus + ) + + if hr != 0 { + return BluetoothLEAdvertisementWatcherStatusCreated, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisementWatcher) GetScanningMode() (BluetoothLEScanningMode, error) { + var out BluetoothLEScanningMode + hr, _, _ := syscall.SyscallN( + v.VTable().GetScanningMode, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out BluetoothLEScanningMode + ) + + if hr != 0 { + return BluetoothLEScanningModePassive, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisementWatcher) SetScanningMode(value BluetoothLEScanningMode) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetScanningMode, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in BluetoothLEScanningMode + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iBluetoothLEAdvertisementWatcher) Start() error { + hr, _, _ := syscall.SyscallN( + v.VTable().Start, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iBluetoothLEAdvertisementWatcher) Stop() error { + hr, _, _ := syscall.SyscallN( + v.VTable().Stop, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iBluetoothLEAdvertisementWatcher) AddReceived(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddReceived, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisementWatcher) RemoveReceived(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveReceived, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iBluetoothLEAdvertisementWatcher) AddStopped(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddStopped, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisementWatcher) RemoveStopped(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveStopped, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiBluetoothLEAdvertisementWatcher2 string = "01bf26bc-b164-5805-90a3-e8a7997ff225" +const SignatureiBluetoothLEAdvertisementWatcher2 string = "{01bf26bc-b164-5805-90a3-e8a7997ff225}" + +type iBluetoothLEAdvertisementWatcher2 struct { + ole.IInspectable +} + +type iBluetoothLEAdvertisementWatcher2Vtbl struct { + ole.IInspectableVtbl + + GetAllowExtendedAdvertisements uintptr + SetAllowExtendedAdvertisements uintptr +} + +func (v *iBluetoothLEAdvertisementWatcher2) VTable() *iBluetoothLEAdvertisementWatcher2Vtbl { + return (*iBluetoothLEAdvertisementWatcher2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEAdvertisementWatcher2) GetAllowExtendedAdvertisements() (bool, error) { + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().GetAllowExtendedAdvertisements, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return false, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEAdvertisementWatcher2) SetAllowExtendedAdvertisements(value bool) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetAllowExtendedAdvertisements, + uintptr(unsafe.Pointer(v)), // this + uintptr(*(*byte)(unsafe.Pointer(&value))), // in bool + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} diff --git a/windows/devices/bluetooth/advertisement/bluetoothleadvertisementwatcherstatus.go b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementwatcherstatus.go new file mode 100644 index 0000000..911d165 --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementwatcherstatus.go @@ -0,0 +1,18 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +type BluetoothLEAdvertisementWatcherStatus int32 + +const SignatureBluetoothLEAdvertisementWatcherStatus string = "enum(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcherStatus;i4)" + +const ( + BluetoothLEAdvertisementWatcherStatusCreated BluetoothLEAdvertisementWatcherStatus = 0 + BluetoothLEAdvertisementWatcherStatusStarted BluetoothLEAdvertisementWatcherStatus = 1 + BluetoothLEAdvertisementWatcherStatusStopping BluetoothLEAdvertisementWatcherStatus = 2 + BluetoothLEAdvertisementWatcherStatusStopped BluetoothLEAdvertisementWatcherStatus = 3 + BluetoothLEAdvertisementWatcherStatusAborted BluetoothLEAdvertisementWatcherStatus = 4 +) diff --git a/windows/devices/bluetooth/advertisement/bluetoothleadvertisementwatcherstoppedeventargs.go b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementwatcherstoppedeventargs.go new file mode 100644 index 0000000..0d12fdd --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothleadvertisementwatcherstoppedeventargs.go @@ -0,0 +1,59 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/devices/bluetooth" +) + +const SignatureBluetoothLEAdvertisementWatcherStoppedEventArgs string = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcherStoppedEventArgs;{dd40f84d-e7b9-43e3-9c04-0685d085fd8c})" + +type BluetoothLEAdvertisementWatcherStoppedEventArgs struct { + ole.IUnknown +} + +func (impl *BluetoothLEAdvertisementWatcherStoppedEventArgs) GetError() (bluetooth.BluetoothError, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEAdvertisementWatcherStoppedEventArgs)) + defer itf.Release() + v := (*iBluetoothLEAdvertisementWatcherStoppedEventArgs)(unsafe.Pointer(itf)) + return v.GetError() +} + +const GUIDiBluetoothLEAdvertisementWatcherStoppedEventArgs string = "dd40f84d-e7b9-43e3-9c04-0685d085fd8c" +const SignatureiBluetoothLEAdvertisementWatcherStoppedEventArgs string = "{dd40f84d-e7b9-43e3-9c04-0685d085fd8c}" + +type iBluetoothLEAdvertisementWatcherStoppedEventArgs struct { + ole.IInspectable +} + +type iBluetoothLEAdvertisementWatcherStoppedEventArgsVtbl struct { + ole.IInspectableVtbl + + GetError uintptr +} + +func (v *iBluetoothLEAdvertisementWatcherStoppedEventArgs) VTable() *iBluetoothLEAdvertisementWatcherStoppedEventArgsVtbl { + return (*iBluetoothLEAdvertisementWatcherStoppedEventArgsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEAdvertisementWatcherStoppedEventArgs) GetError() (bluetooth.BluetoothError, error) { + var out bluetooth.BluetoothError + hr, _, _ := syscall.SyscallN( + v.VTable().GetError, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bluetooth.BluetoothError + ) + + if hr != 0 { + return bluetooth.BluetoothErrorSuccess, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/advertisement/bluetoothlemanufacturerdata.go b/windows/devices/bluetooth/advertisement/bluetoothlemanufacturerdata.go new file mode 100644 index 0000000..d4f3e2f --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothlemanufacturerdata.go @@ -0,0 +1,174 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureBluetoothLEManufacturerData string = "rc(Windows.Devices.Bluetooth.Advertisement.BluetoothLEManufacturerData;{912dba18-6963-4533-b061-4694dafb34e5})" + +type BluetoothLEManufacturerData struct { + ole.IUnknown +} + +func NewBluetoothLEManufacturerData() (*BluetoothLEManufacturerData, error) { + inspectable, err := ole.RoActivateInstance("Windows.Devices.Bluetooth.Advertisement.BluetoothLEManufacturerData") + if err != nil { + return nil, err + } + return (*BluetoothLEManufacturerData)(unsafe.Pointer(inspectable)), nil +} + +func (impl *BluetoothLEManufacturerData) GetCompanyId() (uint16, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEManufacturerData)) + defer itf.Release() + v := (*iBluetoothLEManufacturerData)(unsafe.Pointer(itf)) + return v.GetCompanyId() +} + +func (impl *BluetoothLEManufacturerData) SetCompanyId(value uint16) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEManufacturerData)) + defer itf.Release() + v := (*iBluetoothLEManufacturerData)(unsafe.Pointer(itf)) + return v.SetCompanyId(value) +} + +func (impl *BluetoothLEManufacturerData) GetData() (*streams.IBuffer, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEManufacturerData)) + defer itf.Release() + v := (*iBluetoothLEManufacturerData)(unsafe.Pointer(itf)) + return v.GetData() +} + +func (impl *BluetoothLEManufacturerData) SetData(value *streams.IBuffer) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEManufacturerData)) + defer itf.Release() + v := (*iBluetoothLEManufacturerData)(unsafe.Pointer(itf)) + return v.SetData(value) +} + +const GUIDiBluetoothLEManufacturerData string = "912dba18-6963-4533-b061-4694dafb34e5" +const SignatureiBluetoothLEManufacturerData string = "{912dba18-6963-4533-b061-4694dafb34e5}" + +type iBluetoothLEManufacturerData struct { + ole.IInspectable +} + +type iBluetoothLEManufacturerDataVtbl struct { + ole.IInspectableVtbl + + GetCompanyId uintptr + SetCompanyId uintptr + GetData uintptr + SetData uintptr +} + +func (v *iBluetoothLEManufacturerData) VTable() *iBluetoothLEManufacturerDataVtbl { + return (*iBluetoothLEManufacturerDataVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEManufacturerData) GetCompanyId() (uint16, error) { + var out uint16 + hr, _, _ := syscall.SyscallN( + v.VTable().GetCompanyId, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint16 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEManufacturerData) SetCompanyId(value uint16) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetCompanyId, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in uint16 + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iBluetoothLEManufacturerData) GetData() (*streams.IBuffer, error) { + var out *streams.IBuffer + hr, _, _ := syscall.SyscallN( + v.VTable().GetData, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out streams.IBuffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEManufacturerData) SetData(value *streams.IBuffer) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetData, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in streams.IBuffer + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiBluetoothLEManufacturerDataFactory string = "c09b39f8-319a-441e-8de5-66a81e877a6c" +const SignatureiBluetoothLEManufacturerDataFactory string = "{c09b39f8-319a-441e-8de5-66a81e877a6c}" + +type iBluetoothLEManufacturerDataFactory struct { + ole.IInspectable +} + +type iBluetoothLEManufacturerDataFactoryVtbl struct { + ole.IInspectableVtbl + + BluetoothLEManufacturerDataCreate uintptr +} + +func (v *iBluetoothLEManufacturerDataFactory) VTable() *iBluetoothLEManufacturerDataFactoryVtbl { + return (*iBluetoothLEManufacturerDataFactoryVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func BluetoothLEManufacturerDataCreate(companyId uint16, data *streams.IBuffer) (*BluetoothLEManufacturerData, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Bluetooth.Advertisement.BluetoothLEManufacturerData", ole.NewGUID(GUIDiBluetoothLEManufacturerDataFactory)) + if err != nil { + return nil, err + } + v := (*iBluetoothLEManufacturerDataFactory)(unsafe.Pointer(inspectable)) + + var out *BluetoothLEManufacturerData + hr, _, _ := syscall.SyscallN( + v.VTable().BluetoothLEManufacturerDataCreate, + uintptr(unsafe.Pointer(v)), // this + uintptr(companyId), // in uint16 + uintptr(unsafe.Pointer(data)), // in streams.IBuffer + uintptr(unsafe.Pointer(&out)), // out BluetoothLEManufacturerData + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/advertisement/bluetoothlescanningmode.go b/windows/devices/bluetooth/advertisement/bluetoothlescanningmode.go new file mode 100644 index 0000000..f4768f1 --- /dev/null +++ b/windows/devices/bluetooth/advertisement/bluetoothlescanningmode.go @@ -0,0 +1,16 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package advertisement + +type BluetoothLEScanningMode int32 + +const SignatureBluetoothLEScanningMode string = "enum(Windows.Devices.Bluetooth.Advertisement.BluetoothLEScanningMode;i4)" + +const ( + BluetoothLEScanningModePassive BluetoothLEScanningMode = 0 + BluetoothLEScanningModeActive BluetoothLEScanningMode = 1 + BluetoothLEScanningModeNone BluetoothLEScanningMode = 2 +) diff --git a/windows/devices/bluetooth/bluetoothaddresstype.go b/windows/devices/bluetooth/bluetoothaddresstype.go new file mode 100644 index 0000000..cb8442f --- /dev/null +++ b/windows/devices/bluetooth/bluetoothaddresstype.go @@ -0,0 +1,16 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package bluetooth + +type BluetoothAddressType int32 + +const SignatureBluetoothAddressType string = "enum(Windows.Devices.Bluetooth.BluetoothAddressType;i4)" + +const ( + BluetoothAddressTypePublic BluetoothAddressType = 0 + BluetoothAddressTypeRandom BluetoothAddressType = 1 + BluetoothAddressTypeUnspecified BluetoothAddressType = 2 +) diff --git a/windows/devices/bluetooth/bluetoothcachemode.go b/windows/devices/bluetooth/bluetoothcachemode.go new file mode 100644 index 0000000..e53eed1 --- /dev/null +++ b/windows/devices/bluetooth/bluetoothcachemode.go @@ -0,0 +1,15 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package bluetooth + +type BluetoothCacheMode int32 + +const SignatureBluetoothCacheMode string = "enum(Windows.Devices.Bluetooth.BluetoothCacheMode;i4)" + +const ( + BluetoothCacheModeCached BluetoothCacheMode = 0 + BluetoothCacheModeUncached BluetoothCacheMode = 1 +) diff --git a/windows/devices/bluetooth/bluetoothconnectionstatus.go b/windows/devices/bluetooth/bluetoothconnectionstatus.go new file mode 100644 index 0000000..d42e6b0 --- /dev/null +++ b/windows/devices/bluetooth/bluetoothconnectionstatus.go @@ -0,0 +1,15 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package bluetooth + +type BluetoothConnectionStatus int32 + +const SignatureBluetoothConnectionStatus string = "enum(Windows.Devices.Bluetooth.BluetoothConnectionStatus;i4)" + +const ( + BluetoothConnectionStatusDisconnected BluetoothConnectionStatus = 0 + BluetoothConnectionStatusConnected BluetoothConnectionStatus = 1 +) diff --git a/windows/devices/bluetooth/bluetoothdeviceid.go b/windows/devices/bluetooth/bluetoothdeviceid.go new file mode 100644 index 0000000..dddd296 --- /dev/null +++ b/windows/devices/bluetooth/bluetoothdeviceid.go @@ -0,0 +1,106 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package bluetooth + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const SignatureBluetoothDeviceId string = "rc(Windows.Devices.Bluetooth.BluetoothDeviceId;{c17949af-57c1-4642-bcce-e6c06b20ae76})" + +type BluetoothDeviceId struct { + ole.IUnknown +} + +func (impl *BluetoothDeviceId) GetId() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothDeviceId)) + defer itf.Release() + v := (*iBluetoothDeviceId)(unsafe.Pointer(itf)) + return v.GetId() +} + +func (impl *BluetoothDeviceId) GetIsClassicDevice() (bool, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothDeviceId)) + defer itf.Release() + v := (*iBluetoothDeviceId)(unsafe.Pointer(itf)) + return v.GetIsClassicDevice() +} + +func (impl *BluetoothDeviceId) GetIsLowEnergyDevice() (bool, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothDeviceId)) + defer itf.Release() + v := (*iBluetoothDeviceId)(unsafe.Pointer(itf)) + return v.GetIsLowEnergyDevice() +} + +const GUIDiBluetoothDeviceId string = "c17949af-57c1-4642-bcce-e6c06b20ae76" +const SignatureiBluetoothDeviceId string = "{c17949af-57c1-4642-bcce-e6c06b20ae76}" + +type iBluetoothDeviceId struct { + ole.IInspectable +} + +type iBluetoothDeviceIdVtbl struct { + ole.IInspectableVtbl + + GetId uintptr + GetIsClassicDevice uintptr + GetIsLowEnergyDevice uintptr +} + +func (v *iBluetoothDeviceId) VTable() *iBluetoothDeviceIdVtbl { + return (*iBluetoothDeviceIdVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothDeviceId) GetId() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetId, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +func (v *iBluetoothDeviceId) GetIsClassicDevice() (bool, error) { + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().GetIsClassicDevice, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return false, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothDeviceId) GetIsLowEnergyDevice() (bool, error) { + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().GetIsLowEnergyDevice, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return false, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/bluetootherror.go b/windows/devices/bluetooth/bluetootherror.go new file mode 100644 index 0000000..315b407 --- /dev/null +++ b/windows/devices/bluetooth/bluetootherror.go @@ -0,0 +1,23 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package bluetooth + +type BluetoothError int32 + +const SignatureBluetoothError string = "enum(Windows.Devices.Bluetooth.BluetoothError;i4)" + +const ( + BluetoothErrorSuccess BluetoothError = 0 + BluetoothErrorRadioNotAvailable BluetoothError = 1 + BluetoothErrorResourceInUse BluetoothError = 2 + BluetoothErrorDeviceNotConnected BluetoothError = 3 + BluetoothErrorOtherError BluetoothError = 4 + BluetoothErrorDisabledByPolicy BluetoothError = 5 + BluetoothErrorNotSupported BluetoothError = 6 + BluetoothErrorDisabledByUser BluetoothError = 7 + BluetoothErrorConsentRequired BluetoothError = 8 + BluetoothErrorTransportNotSupported BluetoothError = 9 +) diff --git a/windows/devices/bluetooth/bluetoothledevice.go b/windows/devices/bluetooth/bluetoothledevice.go new file mode 100644 index 0000000..89df867 --- /dev/null +++ b/windows/devices/bluetooth/bluetoothledevice.go @@ -0,0 +1,373 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package bluetooth + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureBluetoothLEDevice string = "rc(Windows.Devices.Bluetooth.BluetoothLEDevice;{b5ee2f7b-4ad8-4642-ac48-80a0b500e887})" + +type BluetoothLEDevice struct { + ole.IUnknown +} + +func (impl *BluetoothLEDevice) GetConnectionStatus() (BluetoothConnectionStatus, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEDevice)) + defer itf.Release() + v := (*iBluetoothLEDevice)(unsafe.Pointer(itf)) + return v.GetConnectionStatus() +} + +func (impl *BluetoothLEDevice) AddConnectionStatusChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEDevice)) + defer itf.Release() + v := (*iBluetoothLEDevice)(unsafe.Pointer(itf)) + return v.AddConnectionStatusChanged(handler) +} + +func (impl *BluetoothLEDevice) RemoveConnectionStatusChanged(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEDevice)) + defer itf.Release() + v := (*iBluetoothLEDevice)(unsafe.Pointer(itf)) + return v.RemoveConnectionStatusChanged(token) +} + +func (impl *BluetoothLEDevice) GetGattServicesAsync() (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEDevice3)) + defer itf.Release() + v := (*iBluetoothLEDevice3)(unsafe.Pointer(itf)) + return v.GetGattServicesAsync() +} + +func (impl *BluetoothLEDevice) GetGattServicesWithCacheModeAsync(cacheMode BluetoothCacheMode) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEDevice3)) + defer itf.Release() + v := (*iBluetoothLEDevice3)(unsafe.Pointer(itf)) + return v.GetGattServicesWithCacheModeAsync(cacheMode) +} + +func (impl *BluetoothLEDevice) GetBluetoothDeviceId() (*BluetoothDeviceId, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiBluetoothLEDevice4)) + defer itf.Release() + v := (*iBluetoothLEDevice4)(unsafe.Pointer(itf)) + return v.GetBluetoothDeviceId() +} + +func (impl *BluetoothLEDevice) Close() error { + itf := impl.MustQueryInterface(ole.NewGUID(foundation.GUIDIClosable)) + defer itf.Release() + v := (*foundation.IClosable)(unsafe.Pointer(itf)) + return v.Close() +} + +const GUIDiBluetoothLEDevice string = "b5ee2f7b-4ad8-4642-ac48-80a0b500e887" +const SignatureiBluetoothLEDevice string = "{b5ee2f7b-4ad8-4642-ac48-80a0b500e887}" + +type iBluetoothLEDevice struct { + ole.IInspectable +} + +type iBluetoothLEDeviceVtbl struct { + ole.IInspectableVtbl + + GetDeviceId uintptr + GetName uintptr + GetGattServices uintptr + GetConnectionStatus uintptr + GetBluetoothAddress uintptr + GetGattService uintptr + AddNameChanged uintptr + RemoveNameChanged uintptr + AddGattServicesChanged uintptr + RemoveGattServicesChanged uintptr + AddConnectionStatusChanged uintptr + RemoveConnectionStatusChanged uintptr +} + +func (v *iBluetoothLEDevice) VTable() *iBluetoothLEDeviceVtbl { + return (*iBluetoothLEDeviceVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEDevice) GetConnectionStatus() (BluetoothConnectionStatus, error) { + var out BluetoothConnectionStatus + hr, _, _ := syscall.SyscallN( + v.VTable().GetConnectionStatus, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out BluetoothConnectionStatus + ) + + if hr != 0 { + return BluetoothConnectionStatusDisconnected, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEDevice) AddConnectionStatusChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddConnectionStatusChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEDevice) RemoveConnectionStatusChanged(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveConnectionStatusChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiBluetoothLEDevice2 string = "26f062b3-7aee-4d31-baba-b1b9775f5916" +const SignatureiBluetoothLEDevice2 string = "{26f062b3-7aee-4d31-baba-b1b9775f5916}" + +type iBluetoothLEDevice2 struct { + ole.IInspectable +} + +type iBluetoothLEDevice2Vtbl struct { + ole.IInspectableVtbl + + GetDeviceInformation uintptr + GetAppearance uintptr + GetBluetoothAddressType uintptr +} + +func (v *iBluetoothLEDevice2) VTable() *iBluetoothLEDevice2Vtbl { + return (*iBluetoothLEDevice2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +const GUIDiBluetoothLEDevice3 string = "aee9e493-44ac-40dc-af33-b2c13c01ca46" +const SignatureiBluetoothLEDevice3 string = "{aee9e493-44ac-40dc-af33-b2c13c01ca46}" + +type iBluetoothLEDevice3 struct { + ole.IInspectable +} + +type iBluetoothLEDevice3Vtbl struct { + ole.IInspectableVtbl + + GetDeviceAccessInformation uintptr + RequestAccessAsync uintptr + GetGattServicesAsync uintptr + GetGattServicesWithCacheModeAsync uintptr + GetGattServicesForUuidAsync uintptr + GetGattServicesForUuidWithCacheModeAsync uintptr +} + +func (v *iBluetoothLEDevice3) VTable() *iBluetoothLEDevice3Vtbl { + return (*iBluetoothLEDevice3Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEDevice3) GetGattServicesAsync() (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GetGattServicesAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iBluetoothLEDevice3) GetGattServicesWithCacheModeAsync(cacheMode BluetoothCacheMode) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GetGattServicesWithCacheModeAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(cacheMode), // in BluetoothCacheMode + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +const GUIDiBluetoothLEDevice4 string = "2b605031-2248-4b2f-acf0-7cee36fc5870" +const SignatureiBluetoothLEDevice4 string = "{2b605031-2248-4b2f-acf0-7cee36fc5870}" + +type iBluetoothLEDevice4 struct { + ole.IInspectable +} + +type iBluetoothLEDevice4Vtbl struct { + ole.IInspectableVtbl + + GetBluetoothDeviceId uintptr +} + +func (v *iBluetoothLEDevice4) VTable() *iBluetoothLEDevice4Vtbl { + return (*iBluetoothLEDevice4Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iBluetoothLEDevice4) GetBluetoothDeviceId() (*BluetoothDeviceId, error) { + var out *BluetoothDeviceId + hr, _, _ := syscall.SyscallN( + v.VTable().GetBluetoothDeviceId, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out BluetoothDeviceId + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +const GUIDiBluetoothLEDevice5 string = "9d6a1260-5287-458e-95ba-17c8b7bb326e" +const SignatureiBluetoothLEDevice5 string = "{9d6a1260-5287-458e-95ba-17c8b7bb326e}" + +type iBluetoothLEDevice5 struct { + ole.IInspectable +} + +type iBluetoothLEDevice5Vtbl struct { + ole.IInspectableVtbl + + GetWasSecureConnectionUsedForPairing uintptr +} + +func (v *iBluetoothLEDevice5) VTable() *iBluetoothLEDevice5Vtbl { + return (*iBluetoothLEDevice5Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +const GUIDiBluetoothLEDevice6 string = "ca7190ef-0cae-573c-a1ca-e1fc5bfc39e2" +const SignatureiBluetoothLEDevice6 string = "{ca7190ef-0cae-573c-a1ca-e1fc5bfc39e2}" + +type iBluetoothLEDevice6 struct { + ole.IInspectable +} + +type iBluetoothLEDevice6Vtbl struct { + ole.IInspectableVtbl + + GetConnectionParameters uintptr + GetConnectionPhy uintptr + RequestPreferredConnectionParameters uintptr + AddConnectionParametersChanged uintptr + RemoveConnectionParametersChanged uintptr + AddConnectionPhyChanged uintptr + RemoveConnectionPhyChanged uintptr +} + +func (v *iBluetoothLEDevice6) VTable() *iBluetoothLEDevice6Vtbl { + return (*iBluetoothLEDevice6Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +const GUIDiBluetoothLEDeviceStatics2 string = "5f12c06b-3bac-43e8-ad16-563271bd41c2" +const SignatureiBluetoothLEDeviceStatics2 string = "{5f12c06b-3bac-43e8-ad16-563271bd41c2}" + +type iBluetoothLEDeviceStatics2 struct { + ole.IInspectable +} + +type iBluetoothLEDeviceStatics2Vtbl struct { + ole.IInspectableVtbl + + BluetoothLEDeviceGetDeviceSelectorFromPairingState uintptr + BluetoothLEDeviceGetDeviceSelectorFromConnectionStatus uintptr + BluetoothLEDeviceGetDeviceSelectorFromDeviceName uintptr + BluetoothLEDeviceGetDeviceSelectorFromBluetoothAddress uintptr + BluetoothLEDeviceGetDeviceSelectorFromBluetoothAddressWithBluetoothAddressType uintptr + BluetoothLEDeviceGetDeviceSelectorFromAppearance uintptr + BluetoothLEDeviceFromBluetoothAddressWithBluetoothAddressTypeAsync uintptr +} + +func (v *iBluetoothLEDeviceStatics2) VTable() *iBluetoothLEDeviceStatics2Vtbl { + return (*iBluetoothLEDeviceStatics2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func BluetoothLEDeviceFromBluetoothAddressWithBluetoothAddressTypeAsync(bluetoothAddress uint64, bluetoothAddressType BluetoothAddressType) (*foundation.IAsyncOperation, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Bluetooth.BluetoothLEDevice", ole.NewGUID(GUIDiBluetoothLEDeviceStatics2)) + if err != nil { + return nil, err + } + v := (*iBluetoothLEDeviceStatics2)(unsafe.Pointer(inspectable)) + + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().BluetoothLEDeviceFromBluetoothAddressWithBluetoothAddressTypeAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(bluetoothAddress), // in uint64 + uintptr(bluetoothAddressType), // in BluetoothAddressType + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +const GUIDiBluetoothLEDeviceStatics string = "c8cf1a19-f0b6-4bf0-8689-41303de2d9f4" +const SignatureiBluetoothLEDeviceStatics string = "{c8cf1a19-f0b6-4bf0-8689-41303de2d9f4}" + +type iBluetoothLEDeviceStatics struct { + ole.IInspectable +} + +type iBluetoothLEDeviceStaticsVtbl struct { + ole.IInspectableVtbl + + BluetoothLEDeviceFromIdAsync uintptr + BluetoothLEDeviceFromBluetoothAddressAsync uintptr + BluetoothLEDeviceGetDeviceSelector uintptr +} + +func (v *iBluetoothLEDeviceStatics) VTable() *iBluetoothLEDeviceStaticsVtbl { + return (*iBluetoothLEDeviceStaticsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func BluetoothLEDeviceFromBluetoothAddressAsync(bluetoothAddress uint64) (*foundation.IAsyncOperation, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Bluetooth.BluetoothLEDevice", ole.NewGUID(GUIDiBluetoothLEDeviceStatics)) + if err != nil { + return nil, err + } + v := (*iBluetoothLEDeviceStatics)(unsafe.Pointer(inspectable)) + + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().BluetoothLEDeviceFromBluetoothAddressAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(bluetoothAddress), // in uint64 + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattcharacteristic.go b/windows/devices/bluetooth/genericattributeprofile/gattcharacteristic.go new file mode 100644 index 0000000..68d2e0b --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattcharacteristic.go @@ -0,0 +1,298 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/devices/bluetooth" + "github.com/saltosystems/winrt-go/windows/foundation" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureGattCharacteristic string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristic;{59cb50c1-5934-4f68-a198-eb864fa44e6b})" + +type GattCharacteristic struct { + ole.IUnknown +} + +func (impl *GattCharacteristic) GetCharacteristicProperties() (GattCharacteristicProperties, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristic)) + defer itf.Release() + v := (*iGattCharacteristic)(unsafe.Pointer(itf)) + return v.GetCharacteristicProperties() +} + +func (impl *GattCharacteristic) GetUuid() (syscall.GUID, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristic)) + defer itf.Release() + v := (*iGattCharacteristic)(unsafe.Pointer(itf)) + return v.GetUuid() +} + +func (impl *GattCharacteristic) ReadValueAsync() (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristic)) + defer itf.Release() + v := (*iGattCharacteristic)(unsafe.Pointer(itf)) + return v.ReadValueAsync() +} + +func (impl *GattCharacteristic) ReadValueWithCacheModeAsync(cacheMode bluetooth.BluetoothCacheMode) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristic)) + defer itf.Release() + v := (*iGattCharacteristic)(unsafe.Pointer(itf)) + return v.ReadValueWithCacheModeAsync(cacheMode) +} + +func (impl *GattCharacteristic) WriteValueAsync(value *streams.IBuffer) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristic)) + defer itf.Release() + v := (*iGattCharacteristic)(unsafe.Pointer(itf)) + return v.WriteValueAsync(value) +} + +func (impl *GattCharacteristic) WriteValueWithOptionAsync(value *streams.IBuffer, writeOption GattWriteOption) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristic)) + defer itf.Release() + v := (*iGattCharacteristic)(unsafe.Pointer(itf)) + return v.WriteValueWithOptionAsync(value, writeOption) +} + +func (impl *GattCharacteristic) WriteClientCharacteristicConfigurationDescriptorAsync(clientCharacteristicConfigurationDescriptorValue GattClientCharacteristicConfigurationDescriptorValue) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristic)) + defer itf.Release() + v := (*iGattCharacteristic)(unsafe.Pointer(itf)) + return v.WriteClientCharacteristicConfigurationDescriptorAsync(clientCharacteristicConfigurationDescriptorValue) +} + +func (impl *GattCharacteristic) AddValueChanged(valueChangedHandler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristic)) + defer itf.Release() + v := (*iGattCharacteristic)(unsafe.Pointer(itf)) + return v.AddValueChanged(valueChangedHandler) +} + +func (impl *GattCharacteristic) RemoveValueChanged(valueChangedEventCookie foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristic)) + defer itf.Release() + v := (*iGattCharacteristic)(unsafe.Pointer(itf)) + return v.RemoveValueChanged(valueChangedEventCookie) +} + +const GUIDiGattCharacteristic string = "59cb50c1-5934-4f68-a198-eb864fa44e6b" +const SignatureiGattCharacteristic string = "{59cb50c1-5934-4f68-a198-eb864fa44e6b}" + +type iGattCharacteristic struct { + ole.IInspectable +} + +type iGattCharacteristicVtbl struct { + ole.IInspectableVtbl + + GetDescriptors uintptr + GetCharacteristicProperties uintptr + GetProtectionLevel uintptr + SetProtectionLevel uintptr + GetUserDescription uintptr + GetUuid uintptr + GetAttributeHandle uintptr + GetPresentationFormats uintptr + ReadValueAsync uintptr + ReadValueWithCacheModeAsync uintptr + WriteValueAsync uintptr + WriteValueWithOptionAsync uintptr + ReadClientCharacteristicConfigurationDescriptorAsync uintptr + WriteClientCharacteristicConfigurationDescriptorAsync uintptr + AddValueChanged uintptr + RemoveValueChanged uintptr +} + +func (v *iGattCharacteristic) VTable() *iGattCharacteristicVtbl { + return (*iGattCharacteristicVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattCharacteristic) GetCharacteristicProperties() (GattCharacteristicProperties, error) { + var out GattCharacteristicProperties + hr, _, _ := syscall.SyscallN( + v.VTable().GetCharacteristicProperties, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattCharacteristicProperties + ) + + if hr != 0 { + return GattCharacteristicPropertiesNone, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattCharacteristic) GetUuid() (syscall.GUID, error) { + var out syscall.GUID + hr, _, _ := syscall.SyscallN( + v.VTable().GetUuid, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out syscall.GUID + ) + + if hr != 0 { + return syscall.GUID{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattCharacteristic) ReadValueAsync() (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().ReadValueAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattCharacteristic) ReadValueWithCacheModeAsync(cacheMode bluetooth.BluetoothCacheMode) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().ReadValueWithCacheModeAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(cacheMode), // in bluetooth.BluetoothCacheMode + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattCharacteristic) WriteValueAsync(value *streams.IBuffer) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().WriteValueAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in streams.IBuffer + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattCharacteristic) WriteValueWithOptionAsync(value *streams.IBuffer, writeOption GattWriteOption) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().WriteValueWithOptionAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in streams.IBuffer + uintptr(writeOption), // in GattWriteOption + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattCharacteristic) WriteClientCharacteristicConfigurationDescriptorAsync(clientCharacteristicConfigurationDescriptorValue GattClientCharacteristicConfigurationDescriptorValue) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().WriteClientCharacteristicConfigurationDescriptorAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(clientCharacteristicConfigurationDescriptorValue), // in GattClientCharacteristicConfigurationDescriptorValue + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattCharacteristic) AddValueChanged(valueChangedHandler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddValueChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(valueChangedHandler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattCharacteristic) RemoveValueChanged(valueChangedEventCookie foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveValueChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&valueChangedEventCookie)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiGattCharacteristic2 string = "ae1ab578-ec06-4764-b780-9835a1d35d6e" +const SignatureiGattCharacteristic2 string = "{ae1ab578-ec06-4764-b780-9835a1d35d6e}" + +type iGattCharacteristic2 struct { + ole.IInspectable +} + +type iGattCharacteristic2Vtbl struct { + ole.IInspectableVtbl + + GetService uintptr + GetAllDescriptors uintptr +} + +func (v *iGattCharacteristic2) VTable() *iGattCharacteristic2Vtbl { + return (*iGattCharacteristic2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +const GUIDiGattCharacteristic3 string = "3f3c663e-93d4-406b-b817-db81f8ed53b3" +const SignatureiGattCharacteristic3 string = "{3f3c663e-93d4-406b-b817-db81f8ed53b3}" + +type iGattCharacteristic3 struct { + ole.IInspectable +} + +type iGattCharacteristic3Vtbl struct { + ole.IInspectableVtbl + + GetDescriptorsAsync uintptr + GetDescriptorsWithCacheModeAsync uintptr + GetDescriptorsForUuidAsync uintptr + GetDescriptorsForUuidWithCacheModeAsync uintptr + WriteValueWithResultAsync uintptr + WriteValueWithResultAndOptionAsync uintptr + WriteClientCharacteristicConfigurationDescriptorWithResultAsync uintptr +} + +func (v *iGattCharacteristic3) VTable() *iGattCharacteristic3Vtbl { + return (*iGattCharacteristic3Vtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattcharacteristicproperties.go b/windows/devices/bluetooth/genericattributeprofile/gattcharacteristicproperties.go new file mode 100644 index 0000000..5a97ae4 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattcharacteristicproperties.go @@ -0,0 +1,24 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +type GattCharacteristicProperties uint32 + +const SignatureGattCharacteristicProperties string = "enum(Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristicProperties;u4)" + +const ( + GattCharacteristicPropertiesNone GattCharacteristicProperties = 0 + GattCharacteristicPropertiesBroadcast GattCharacteristicProperties = 1 + GattCharacteristicPropertiesRead GattCharacteristicProperties = 2 + GattCharacteristicPropertiesWriteWithoutResponse GattCharacteristicProperties = 4 + GattCharacteristicPropertiesWrite GattCharacteristicProperties = 8 + GattCharacteristicPropertiesNotify GattCharacteristicProperties = 16 + GattCharacteristicPropertiesIndicate GattCharacteristicProperties = 32 + GattCharacteristicPropertiesAuthenticatedSignedWrites GattCharacteristicProperties = 64 + GattCharacteristicPropertiesExtendedProperties GattCharacteristicProperties = 128 + GattCharacteristicPropertiesReliableWrites GattCharacteristicProperties = 256 + GattCharacteristicPropertiesWritableAuxiliaries GattCharacteristicProperties = 512 +) diff --git a/windows/devices/bluetooth/genericattributeprofile/gattcharacteristicsresult.go b/windows/devices/bluetooth/genericattributeprofile/gattcharacteristicsresult.go new file mode 100644 index 0000000..9f1354e --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattcharacteristicsresult.go @@ -0,0 +1,83 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation/collections" +) + +const SignatureGattCharacteristicsResult string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristicsResult;{1194945c-b257-4f3e-9db7-f68bc9a9aef2})" + +type GattCharacteristicsResult struct { + ole.IUnknown +} + +func (impl *GattCharacteristicsResult) GetStatus() (GattCommunicationStatus, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristicsResult)) + defer itf.Release() + v := (*iGattCharacteristicsResult)(unsafe.Pointer(itf)) + return v.GetStatus() +} + +func (impl *GattCharacteristicsResult) GetCharacteristics() (*collections.IVectorView, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattCharacteristicsResult)) + defer itf.Release() + v := (*iGattCharacteristicsResult)(unsafe.Pointer(itf)) + return v.GetCharacteristics() +} + +const GUIDiGattCharacteristicsResult string = "1194945c-b257-4f3e-9db7-f68bc9a9aef2" +const SignatureiGattCharacteristicsResult string = "{1194945c-b257-4f3e-9db7-f68bc9a9aef2}" + +type iGattCharacteristicsResult struct { + ole.IInspectable +} + +type iGattCharacteristicsResultVtbl struct { + ole.IInspectableVtbl + + GetStatus uintptr + GetProtocolError uintptr + GetCharacteristics uintptr +} + +func (v *iGattCharacteristicsResult) VTable() *iGattCharacteristicsResultVtbl { + return (*iGattCharacteristicsResultVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattCharacteristicsResult) GetStatus() (GattCommunicationStatus, error) { + var out GattCommunicationStatus + hr, _, _ := syscall.SyscallN( + v.VTable().GetStatus, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattCommunicationStatus + ) + + if hr != 0 { + return GattCommunicationStatusSuccess, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattCharacteristicsResult) GetCharacteristics() (*collections.IVectorView, error) { + var out *collections.IVectorView + hr, _, _ := syscall.SyscallN( + v.VTable().GetCharacteristics, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVectorView + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattclientcharacteristicconfigurationdescriptorvalue.go b/windows/devices/bluetooth/genericattributeprofile/gattclientcharacteristicconfigurationdescriptorvalue.go new file mode 100644 index 0000000..3529282 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattclientcharacteristicconfigurationdescriptorvalue.go @@ -0,0 +1,16 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +type GattClientCharacteristicConfigurationDescriptorValue int32 + +const SignatureGattClientCharacteristicConfigurationDescriptorValue string = "enum(Windows.Devices.Bluetooth.GenericAttributeProfile.GattClientCharacteristicConfigurationDescriptorValue;i4)" + +const ( + GattClientCharacteristicConfigurationDescriptorValueNone GattClientCharacteristicConfigurationDescriptorValue = 0 + GattClientCharacteristicConfigurationDescriptorValueNotify GattClientCharacteristicConfigurationDescriptorValue = 1 + GattClientCharacteristicConfigurationDescriptorValueIndicate GattClientCharacteristicConfigurationDescriptorValue = 2 +) diff --git a/windows/devices/bluetooth/genericattributeprofile/gattclientnotificationresult.go b/windows/devices/bluetooth/genericattributeprofile/gattclientnotificationresult.go new file mode 100644 index 0000000..1316105 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattclientnotificationresult.go @@ -0,0 +1,144 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureGattClientNotificationResult string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattClientNotificationResult;{506d5599-0112-419a-8e3b-ae21afabd2c2})" + +type GattClientNotificationResult struct { + ole.IUnknown +} + +func (impl *GattClientNotificationResult) GetSubscribedClient() (*GattSubscribedClient, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattClientNotificationResult)) + defer itf.Release() + v := (*iGattClientNotificationResult)(unsafe.Pointer(itf)) + return v.GetSubscribedClient() +} + +func (impl *GattClientNotificationResult) GetStatus() (GattCommunicationStatus, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattClientNotificationResult)) + defer itf.Release() + v := (*iGattClientNotificationResult)(unsafe.Pointer(itf)) + return v.GetStatus() +} + +func (impl *GattClientNotificationResult) GetProtocolError() (*foundation.IReference, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattClientNotificationResult)) + defer itf.Release() + v := (*iGattClientNotificationResult)(unsafe.Pointer(itf)) + return v.GetProtocolError() +} + +func (impl *GattClientNotificationResult) GetBytesSent() (uint16, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattClientNotificationResult2)) + defer itf.Release() + v := (*iGattClientNotificationResult2)(unsafe.Pointer(itf)) + return v.GetBytesSent() +} + +const GUIDiGattClientNotificationResult string = "506d5599-0112-419a-8e3b-ae21afabd2c2" +const SignatureiGattClientNotificationResult string = "{506d5599-0112-419a-8e3b-ae21afabd2c2}" + +type iGattClientNotificationResult struct { + ole.IInspectable +} + +type iGattClientNotificationResultVtbl struct { + ole.IInspectableVtbl + + GetSubscribedClient uintptr + GetStatus uintptr + GetProtocolError uintptr +} + +func (v *iGattClientNotificationResult) VTable() *iGattClientNotificationResultVtbl { + return (*iGattClientNotificationResultVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattClientNotificationResult) GetSubscribedClient() (*GattSubscribedClient, error) { + var out *GattSubscribedClient + hr, _, _ := syscall.SyscallN( + v.VTable().GetSubscribedClient, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattSubscribedClient + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattClientNotificationResult) GetStatus() (GattCommunicationStatus, error) { + var out GattCommunicationStatus + hr, _, _ := syscall.SyscallN( + v.VTable().GetStatus, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattCommunicationStatus + ) + + if hr != 0 { + return GattCommunicationStatusSuccess, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattClientNotificationResult) GetProtocolError() (*foundation.IReference, error) { + var out *foundation.IReference + hr, _, _ := syscall.SyscallN( + v.VTable().GetProtocolError, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IReference + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +const GUIDiGattClientNotificationResult2 string = "8faec497-45e0-497e-9582-29a1fe281ad5" +const SignatureiGattClientNotificationResult2 string = "{8faec497-45e0-497e-9582-29a1fe281ad5}" + +type iGattClientNotificationResult2 struct { + ole.IInspectable +} + +type iGattClientNotificationResult2Vtbl struct { + ole.IInspectableVtbl + + GetBytesSent uintptr +} + +func (v *iGattClientNotificationResult2) VTable() *iGattClientNotificationResult2Vtbl { + return (*iGattClientNotificationResult2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattClientNotificationResult2) GetBytesSent() (uint16, error) { + var out uint16 + hr, _, _ := syscall.SyscallN( + v.VTable().GetBytesSent, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint16 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattcommunicationstatus.go b/windows/devices/bluetooth/genericattributeprofile/gattcommunicationstatus.go new file mode 100644 index 0000000..c957636 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattcommunicationstatus.go @@ -0,0 +1,17 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +type GattCommunicationStatus int32 + +const SignatureGattCommunicationStatus string = "enum(Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus;i4)" + +const ( + GattCommunicationStatusSuccess GattCommunicationStatus = 0 + GattCommunicationStatusUnreachable GattCommunicationStatus = 1 + GattCommunicationStatusProtocolError GattCommunicationStatus = 2 + GattCommunicationStatusAccessDenied GattCommunicationStatus = 3 +) diff --git a/windows/devices/bluetooth/genericattributeprofile/gattdeviceservice.go b/windows/devices/bluetooth/genericattributeprofile/gattdeviceservice.go new file mode 100644 index 0000000..eac17c0 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattdeviceservice.go @@ -0,0 +1,165 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/devices/bluetooth" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureGattDeviceService string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceService;{ac7b7c05-b33c-47cf-990f-6b8f5577df71})" + +type GattDeviceService struct { + ole.IUnknown +} + +func (impl *GattDeviceService) GetUuid() (syscall.GUID, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattDeviceService)) + defer itf.Release() + v := (*iGattDeviceService)(unsafe.Pointer(itf)) + return v.GetUuid() +} + +func (impl *GattDeviceService) Close() error { + itf := impl.MustQueryInterface(ole.NewGUID(foundation.GUIDIClosable)) + defer itf.Release() + v := (*foundation.IClosable)(unsafe.Pointer(itf)) + return v.Close() +} + +func (impl *GattDeviceService) GetCharacteristicsAsync() (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattDeviceService3)) + defer itf.Release() + v := (*iGattDeviceService3)(unsafe.Pointer(itf)) + return v.GetCharacteristicsAsync() +} + +func (impl *GattDeviceService) GetCharacteristicsWithCacheModeAsync(cacheMode bluetooth.BluetoothCacheMode) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattDeviceService3)) + defer itf.Release() + v := (*iGattDeviceService3)(unsafe.Pointer(itf)) + return v.GetCharacteristicsWithCacheModeAsync(cacheMode) +} + +const GUIDiGattDeviceService string = "ac7b7c05-b33c-47cf-990f-6b8f5577df71" +const SignatureiGattDeviceService string = "{ac7b7c05-b33c-47cf-990f-6b8f5577df71}" + +type iGattDeviceService struct { + ole.IInspectable +} + +type iGattDeviceServiceVtbl struct { + ole.IInspectableVtbl + + GetCharacteristics uintptr + GetIncludedServices uintptr + GetDeviceId uintptr + GetUuid uintptr + GetAttributeHandle uintptr +} + +func (v *iGattDeviceService) VTable() *iGattDeviceServiceVtbl { + return (*iGattDeviceServiceVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattDeviceService) GetUuid() (syscall.GUID, error) { + var out syscall.GUID + hr, _, _ := syscall.SyscallN( + v.VTable().GetUuid, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out syscall.GUID + ) + + if hr != 0 { + return syscall.GUID{}, ole.NewError(hr) + } + + return out, nil +} + +const GUIDiGattDeviceService2 string = "fc54520b-0b0d-4708-bae0-9ffd9489bc59" +const SignatureiGattDeviceService2 string = "{fc54520b-0b0d-4708-bae0-9ffd9489bc59}" + +type iGattDeviceService2 struct { + ole.IInspectable +} + +type iGattDeviceService2Vtbl struct { + ole.IInspectableVtbl + + GetDevice uintptr + GetParentServices uintptr + GetAllCharacteristics uintptr + GetAllIncludedServices uintptr +} + +func (v *iGattDeviceService2) VTable() *iGattDeviceService2Vtbl { + return (*iGattDeviceService2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +const GUIDiGattDeviceService3 string = "b293a950-0c53-437c-a9b3-5c3210c6e569" +const SignatureiGattDeviceService3 string = "{b293a950-0c53-437c-a9b3-5c3210c6e569}" + +type iGattDeviceService3 struct { + ole.IInspectable +} + +type iGattDeviceService3Vtbl struct { + ole.IInspectableVtbl + + GetDeviceAccessInformation uintptr + GetSession uintptr + GetSharingMode uintptr + RequestAccessAsync uintptr + OpenAsync uintptr + GetCharacteristicsAsync uintptr + GetCharacteristicsWithCacheModeAsync uintptr + GetCharacteristicsForUuidAsync uintptr + GetCharacteristicsForUuidWithCacheModeAsync uintptr + GetIncludedServicesAsync uintptr + GetIncludedServicesWithCacheModeAsync uintptr + GetIncludedServicesForUuidAsync uintptr + GetIncludedServicesForUuidWithCacheModeAsync uintptr +} + +func (v *iGattDeviceService3) VTable() *iGattDeviceService3Vtbl { + return (*iGattDeviceService3Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattDeviceService3) GetCharacteristicsAsync() (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GetCharacteristicsAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattDeviceService3) GetCharacteristicsWithCacheModeAsync(cacheMode bluetooth.BluetoothCacheMode) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GetCharacteristicsWithCacheModeAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(cacheMode), // in bluetooth.BluetoothCacheMode + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattdeviceservicesresult.go b/windows/devices/bluetooth/genericattributeprofile/gattdeviceservicesresult.go new file mode 100644 index 0000000..09271ca --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattdeviceservicesresult.go @@ -0,0 +1,83 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation/collections" +) + +const SignatureGattDeviceServicesResult string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceServicesResult;{171dd3ee-016d-419d-838a-576cf475a3d8})" + +type GattDeviceServicesResult struct { + ole.IUnknown +} + +func (impl *GattDeviceServicesResult) GetStatus() (GattCommunicationStatus, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattDeviceServicesResult)) + defer itf.Release() + v := (*iGattDeviceServicesResult)(unsafe.Pointer(itf)) + return v.GetStatus() +} + +func (impl *GattDeviceServicesResult) GetServices() (*collections.IVectorView, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattDeviceServicesResult)) + defer itf.Release() + v := (*iGattDeviceServicesResult)(unsafe.Pointer(itf)) + return v.GetServices() +} + +const GUIDiGattDeviceServicesResult string = "171dd3ee-016d-419d-838a-576cf475a3d8" +const SignatureiGattDeviceServicesResult string = "{171dd3ee-016d-419d-838a-576cf475a3d8}" + +type iGattDeviceServicesResult struct { + ole.IInspectable +} + +type iGattDeviceServicesResultVtbl struct { + ole.IInspectableVtbl + + GetStatus uintptr + GetProtocolError uintptr + GetServices uintptr +} + +func (v *iGattDeviceServicesResult) VTable() *iGattDeviceServicesResultVtbl { + return (*iGattDeviceServicesResultVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattDeviceServicesResult) GetStatus() (GattCommunicationStatus, error) { + var out GattCommunicationStatus + hr, _, _ := syscall.SyscallN( + v.VTable().GetStatus, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattCommunicationStatus + ) + + if hr != 0 { + return GattCommunicationStatusSuccess, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattDeviceServicesResult) GetServices() (*collections.IVectorView, error) { + var out *collections.IVectorView + hr, _, _ := syscall.SyscallN( + v.VTable().GetServices, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVectorView + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattlocalcharacteristic.go b/windows/devices/bluetooth/genericattributeprofile/gattlocalcharacteristic.go new file mode 100644 index 0000000..3b33649 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattlocalcharacteristic.go @@ -0,0 +1,459 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" + "github.com/saltosystems/winrt-go/windows/foundation/collections" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureGattLocalCharacteristic string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristic;{aede376d-5412-4d74-92a8-8deb8526829c})" + +type GattLocalCharacteristic struct { + ole.IUnknown +} + +func (impl *GattLocalCharacteristic) GetUuid() (syscall.GUID, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.GetUuid() +} + +func (impl *GattLocalCharacteristic) GetStaticValue() (*streams.IBuffer, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.GetStaticValue() +} + +func (impl *GattLocalCharacteristic) GetCharacteristicProperties() (GattCharacteristicProperties, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.GetCharacteristicProperties() +} + +func (impl *GattLocalCharacteristic) GetReadProtectionLevel() (GattProtectionLevel, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.GetReadProtectionLevel() +} + +func (impl *GattLocalCharacteristic) GetWriteProtectionLevel() (GattProtectionLevel, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.GetWriteProtectionLevel() +} + +func (impl *GattLocalCharacteristic) CreateDescriptorAsync(descriptorUuid syscall.GUID, parameters *GattLocalDescriptorParameters) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.CreateDescriptorAsync(descriptorUuid, parameters) +} + +func (impl *GattLocalCharacteristic) GetDescriptors() (*collections.IVectorView, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.GetDescriptors() +} + +func (impl *GattLocalCharacteristic) GetUserDescription() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.GetUserDescription() +} + +func (impl *GattLocalCharacteristic) GetPresentationFormats() (*collections.IVectorView, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.GetPresentationFormats() +} + +func (impl *GattLocalCharacteristic) GetSubscribedClients() (*collections.IVectorView, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.GetSubscribedClients() +} + +func (impl *GattLocalCharacteristic) AddSubscribedClientsChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.AddSubscribedClientsChanged(handler) +} + +func (impl *GattLocalCharacteristic) RemoveSubscribedClientsChanged(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.RemoveSubscribedClientsChanged(token) +} + +func (impl *GattLocalCharacteristic) AddReadRequested(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.AddReadRequested(handler) +} + +func (impl *GattLocalCharacteristic) RemoveReadRequested(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.RemoveReadRequested(token) +} + +func (impl *GattLocalCharacteristic) AddWriteRequested(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.AddWriteRequested(handler) +} + +func (impl *GattLocalCharacteristic) RemoveWriteRequested(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.RemoveWriteRequested(token) +} + +func (impl *GattLocalCharacteristic) NotifyValueAsync(value *streams.IBuffer) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.NotifyValueAsync(value) +} + +func (impl *GattLocalCharacteristic) NotifyValueForSubscribedClientAsync(value *streams.IBuffer, subscribedClient *GattSubscribedClient) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristic)) + defer itf.Release() + v := (*iGattLocalCharacteristic)(unsafe.Pointer(itf)) + return v.NotifyValueForSubscribedClientAsync(value, subscribedClient) +} + +const GUIDiGattLocalCharacteristic string = "aede376d-5412-4d74-92a8-8deb8526829c" +const SignatureiGattLocalCharacteristic string = "{aede376d-5412-4d74-92a8-8deb8526829c}" + +type iGattLocalCharacteristic struct { + ole.IInspectable +} + +type iGattLocalCharacteristicVtbl struct { + ole.IInspectableVtbl + + GetUuid uintptr + GetStaticValue uintptr + GetCharacteristicProperties uintptr + GetReadProtectionLevel uintptr + GetWriteProtectionLevel uintptr + CreateDescriptorAsync uintptr + GetDescriptors uintptr + GetUserDescription uintptr + GetPresentationFormats uintptr + GetSubscribedClients uintptr + AddSubscribedClientsChanged uintptr + RemoveSubscribedClientsChanged uintptr + AddReadRequested uintptr + RemoveReadRequested uintptr + AddWriteRequested uintptr + RemoveWriteRequested uintptr + NotifyValueAsync uintptr + NotifyValueForSubscribedClientAsync uintptr +} + +func (v *iGattLocalCharacteristic) VTable() *iGattLocalCharacteristicVtbl { + return (*iGattLocalCharacteristicVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattLocalCharacteristic) GetUuid() (syscall.GUID, error) { + var out syscall.GUID + hr, _, _ := syscall.SyscallN( + v.VTable().GetUuid, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out syscall.GUID + ) + + if hr != 0 { + return syscall.GUID{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) GetStaticValue() (*streams.IBuffer, error) { + var out *streams.IBuffer + hr, _, _ := syscall.SyscallN( + v.VTable().GetStaticValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out streams.IBuffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) GetCharacteristicProperties() (GattCharacteristicProperties, error) { + var out GattCharacteristicProperties + hr, _, _ := syscall.SyscallN( + v.VTable().GetCharacteristicProperties, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattCharacteristicProperties + ) + + if hr != 0 { + return GattCharacteristicPropertiesNone, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) GetReadProtectionLevel() (GattProtectionLevel, error) { + var out GattProtectionLevel + hr, _, _ := syscall.SyscallN( + v.VTable().GetReadProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattProtectionLevel + ) + + if hr != 0 { + return GattProtectionLevelPlain, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) GetWriteProtectionLevel() (GattProtectionLevel, error) { + var out GattProtectionLevel + hr, _, _ := syscall.SyscallN( + v.VTable().GetWriteProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattProtectionLevel + ) + + if hr != 0 { + return GattProtectionLevelPlain, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) CreateDescriptorAsync(descriptorUuid syscall.GUID, parameters *GattLocalDescriptorParameters) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().CreateDescriptorAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&descriptorUuid)), // in syscall.GUID + uintptr(unsafe.Pointer(parameters)), // in GattLocalDescriptorParameters + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) GetDescriptors() (*collections.IVectorView, error) { + var out *collections.IVectorView + hr, _, _ := syscall.SyscallN( + v.VTable().GetDescriptors, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVectorView + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) GetUserDescription() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetUserDescription, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +func (v *iGattLocalCharacteristic) GetPresentationFormats() (*collections.IVectorView, error) { + var out *collections.IVectorView + hr, _, _ := syscall.SyscallN( + v.VTable().GetPresentationFormats, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVectorView + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) GetSubscribedClients() (*collections.IVectorView, error) { + var out *collections.IVectorView + hr, _, _ := syscall.SyscallN( + v.VTable().GetSubscribedClients, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVectorView + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) AddSubscribedClientsChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddSubscribedClientsChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) RemoveSubscribedClientsChanged(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveSubscribedClientsChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalCharacteristic) AddReadRequested(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddReadRequested, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) RemoveReadRequested(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveReadRequested, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalCharacteristic) AddWriteRequested(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddWriteRequested, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) RemoveWriteRequested(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveWriteRequested, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalCharacteristic) NotifyValueAsync(value *streams.IBuffer) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().NotifyValueAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in streams.IBuffer + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristic) NotifyValueForSubscribedClientAsync(value *streams.IBuffer, subscribedClient *GattSubscribedClient) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().NotifyValueForSubscribedClientAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in streams.IBuffer + uintptr(unsafe.Pointer(subscribedClient)), // in GattSubscribedClient + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattlocalcharacteristicparameters.go b/windows/devices/bluetooth/genericattributeprofile/gattlocalcharacteristicparameters.go new file mode 100644 index 0000000..542bf35 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattlocalcharacteristicparameters.go @@ -0,0 +1,299 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation/collections" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureGattLocalCharacteristicParameters string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristicParameters;{faf73db4-4cff-44c7-8445-040e6ead0063})" + +type GattLocalCharacteristicParameters struct { + ole.IUnknown +} + +func NewGattLocalCharacteristicParameters() (*GattLocalCharacteristicParameters, error) { + inspectable, err := ole.RoActivateInstance("Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristicParameters") + if err != nil { + return nil, err + } + return (*GattLocalCharacteristicParameters)(unsafe.Pointer(inspectable)), nil +} + +func (impl *GattLocalCharacteristicParameters) SetStaticValue(value *streams.IBuffer) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.SetStaticValue(value) +} + +func (impl *GattLocalCharacteristicParameters) GetStaticValue() (*streams.IBuffer, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.GetStaticValue() +} + +func (impl *GattLocalCharacteristicParameters) SetCharacteristicProperties(value GattCharacteristicProperties) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.SetCharacteristicProperties(value) +} + +func (impl *GattLocalCharacteristicParameters) GetCharacteristicProperties() (GattCharacteristicProperties, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.GetCharacteristicProperties() +} + +func (impl *GattLocalCharacteristicParameters) SetReadProtectionLevel(value GattProtectionLevel) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.SetReadProtectionLevel(value) +} + +func (impl *GattLocalCharacteristicParameters) GetReadProtectionLevel() (GattProtectionLevel, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.GetReadProtectionLevel() +} + +func (impl *GattLocalCharacteristicParameters) SetWriteProtectionLevel(value GattProtectionLevel) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.SetWriteProtectionLevel(value) +} + +func (impl *GattLocalCharacteristicParameters) GetWriteProtectionLevel() (GattProtectionLevel, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.GetWriteProtectionLevel() +} + +func (impl *GattLocalCharacteristicParameters) SetUserDescription(value string) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.SetUserDescription(value) +} + +func (impl *GattLocalCharacteristicParameters) GetUserDescription() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.GetUserDescription() +} + +func (impl *GattLocalCharacteristicParameters) GetPresentationFormats() (*collections.IVector, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicParameters)) + defer itf.Release() + v := (*iGattLocalCharacteristicParameters)(unsafe.Pointer(itf)) + return v.GetPresentationFormats() +} + +const GUIDiGattLocalCharacteristicParameters string = "faf73db4-4cff-44c7-8445-040e6ead0063" +const SignatureiGattLocalCharacteristicParameters string = "{faf73db4-4cff-44c7-8445-040e6ead0063}" + +type iGattLocalCharacteristicParameters struct { + ole.IInspectable +} + +type iGattLocalCharacteristicParametersVtbl struct { + ole.IInspectableVtbl + + SetStaticValue uintptr + GetStaticValue uintptr + SetCharacteristicProperties uintptr + GetCharacteristicProperties uintptr + SetReadProtectionLevel uintptr + GetReadProtectionLevel uintptr + SetWriteProtectionLevel uintptr + GetWriteProtectionLevel uintptr + SetUserDescription uintptr + GetUserDescription uintptr + GetPresentationFormats uintptr +} + +func (v *iGattLocalCharacteristicParameters) VTable() *iGattLocalCharacteristicParametersVtbl { + return (*iGattLocalCharacteristicParametersVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattLocalCharacteristicParameters) SetStaticValue(value *streams.IBuffer) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetStaticValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in streams.IBuffer + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalCharacteristicParameters) GetStaticValue() (*streams.IBuffer, error) { + var out *streams.IBuffer + hr, _, _ := syscall.SyscallN( + v.VTable().GetStaticValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out streams.IBuffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristicParameters) SetCharacteristicProperties(value GattCharacteristicProperties) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetCharacteristicProperties, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in GattCharacteristicProperties + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalCharacteristicParameters) GetCharacteristicProperties() (GattCharacteristicProperties, error) { + var out GattCharacteristicProperties + hr, _, _ := syscall.SyscallN( + v.VTable().GetCharacteristicProperties, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattCharacteristicProperties + ) + + if hr != 0 { + return GattCharacteristicPropertiesNone, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristicParameters) SetReadProtectionLevel(value GattProtectionLevel) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetReadProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in GattProtectionLevel + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalCharacteristicParameters) GetReadProtectionLevel() (GattProtectionLevel, error) { + var out GattProtectionLevel + hr, _, _ := syscall.SyscallN( + v.VTable().GetReadProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattProtectionLevel + ) + + if hr != 0 { + return GattProtectionLevelPlain, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristicParameters) SetWriteProtectionLevel(value GattProtectionLevel) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetWriteProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in GattProtectionLevel + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalCharacteristicParameters) GetWriteProtectionLevel() (GattProtectionLevel, error) { + var out GattProtectionLevel + hr, _, _ := syscall.SyscallN( + v.VTable().GetWriteProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattProtectionLevel + ) + + if hr != 0 { + return GattProtectionLevelPlain, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristicParameters) SetUserDescription(value string) error { + valueHStr, err := ole.NewHString(value) + if err != nil { + return err + } + hr, _, _ := syscall.SyscallN( + v.VTable().SetUserDescription, + uintptr(unsafe.Pointer(v)), // this + uintptr(valueHStr), // in string + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalCharacteristicParameters) GetUserDescription() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetUserDescription, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +func (v *iGattLocalCharacteristicParameters) GetPresentationFormats() (*collections.IVector, error) { + var out *collections.IVector + hr, _, _ := syscall.SyscallN( + v.VTable().GetPresentationFormats, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVector + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattlocalcharacteristicresult.go b/windows/devices/bluetooth/genericattributeprofile/gattlocalcharacteristicresult.go new file mode 100644 index 0000000..ebcce90 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattlocalcharacteristicresult.go @@ -0,0 +1,82 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/devices/bluetooth" +) + +const SignatureGattLocalCharacteristicResult string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristicResult;{7975de9b-0170-4397-9666-92f863f12ee6})" + +type GattLocalCharacteristicResult struct { + ole.IUnknown +} + +func (impl *GattLocalCharacteristicResult) GetCharacteristic() (*GattLocalCharacteristic, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicResult)) + defer itf.Release() + v := (*iGattLocalCharacteristicResult)(unsafe.Pointer(itf)) + return v.GetCharacteristic() +} + +func (impl *GattLocalCharacteristicResult) GetError() (bluetooth.BluetoothError, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalCharacteristicResult)) + defer itf.Release() + v := (*iGattLocalCharacteristicResult)(unsafe.Pointer(itf)) + return v.GetError() +} + +const GUIDiGattLocalCharacteristicResult string = "7975de9b-0170-4397-9666-92f863f12ee6" +const SignatureiGattLocalCharacteristicResult string = "{7975de9b-0170-4397-9666-92f863f12ee6}" + +type iGattLocalCharacteristicResult struct { + ole.IInspectable +} + +type iGattLocalCharacteristicResultVtbl struct { + ole.IInspectableVtbl + + GetCharacteristic uintptr + GetError uintptr +} + +func (v *iGattLocalCharacteristicResult) VTable() *iGattLocalCharacteristicResultVtbl { + return (*iGattLocalCharacteristicResultVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattLocalCharacteristicResult) GetCharacteristic() (*GattLocalCharacteristic, error) { + var out *GattLocalCharacteristic + hr, _, _ := syscall.SyscallN( + v.VTable().GetCharacteristic, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattLocalCharacteristic + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalCharacteristicResult) GetError() (bluetooth.BluetoothError, error) { + var out bluetooth.BluetoothError + hr, _, _ := syscall.SyscallN( + v.VTable().GetError, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bluetooth.BluetoothError + ) + + if hr != 0 { + return bluetooth.BluetoothErrorSuccess, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattlocaldescriptorparameters.go b/windows/devices/bluetooth/genericattributeprofile/gattlocaldescriptorparameters.go new file mode 100644 index 0000000..1bf5495 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattlocaldescriptorparameters.go @@ -0,0 +1,179 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureGattLocalDescriptorParameters string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalDescriptorParameters;{5fdede6a-f3c1-4b66-8c4b-e3d2293b40e9})" + +type GattLocalDescriptorParameters struct { + ole.IUnknown +} + +func NewGattLocalDescriptorParameters() (*GattLocalDescriptorParameters, error) { + inspectable, err := ole.RoActivateInstance("Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalDescriptorParameters") + if err != nil { + return nil, err + } + return (*GattLocalDescriptorParameters)(unsafe.Pointer(inspectable)), nil +} + +func (impl *GattLocalDescriptorParameters) SetStaticValue(value *streams.IBuffer) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalDescriptorParameters)) + defer itf.Release() + v := (*iGattLocalDescriptorParameters)(unsafe.Pointer(itf)) + return v.SetStaticValue(value) +} + +func (impl *GattLocalDescriptorParameters) GetStaticValue() (*streams.IBuffer, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalDescriptorParameters)) + defer itf.Release() + v := (*iGattLocalDescriptorParameters)(unsafe.Pointer(itf)) + return v.GetStaticValue() +} + +func (impl *GattLocalDescriptorParameters) SetReadProtectionLevel(value GattProtectionLevel) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalDescriptorParameters)) + defer itf.Release() + v := (*iGattLocalDescriptorParameters)(unsafe.Pointer(itf)) + return v.SetReadProtectionLevel(value) +} + +func (impl *GattLocalDescriptorParameters) GetReadProtectionLevel() (GattProtectionLevel, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalDescriptorParameters)) + defer itf.Release() + v := (*iGattLocalDescriptorParameters)(unsafe.Pointer(itf)) + return v.GetReadProtectionLevel() +} + +func (impl *GattLocalDescriptorParameters) SetWriteProtectionLevel(value GattProtectionLevel) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalDescriptorParameters)) + defer itf.Release() + v := (*iGattLocalDescriptorParameters)(unsafe.Pointer(itf)) + return v.SetWriteProtectionLevel(value) +} + +func (impl *GattLocalDescriptorParameters) GetWriteProtectionLevel() (GattProtectionLevel, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalDescriptorParameters)) + defer itf.Release() + v := (*iGattLocalDescriptorParameters)(unsafe.Pointer(itf)) + return v.GetWriteProtectionLevel() +} + +const GUIDiGattLocalDescriptorParameters string = "5fdede6a-f3c1-4b66-8c4b-e3d2293b40e9" +const SignatureiGattLocalDescriptorParameters string = "{5fdede6a-f3c1-4b66-8c4b-e3d2293b40e9}" + +type iGattLocalDescriptorParameters struct { + ole.IInspectable +} + +type iGattLocalDescriptorParametersVtbl struct { + ole.IInspectableVtbl + + SetStaticValue uintptr + GetStaticValue uintptr + SetReadProtectionLevel uintptr + GetReadProtectionLevel uintptr + SetWriteProtectionLevel uintptr + GetWriteProtectionLevel uintptr +} + +func (v *iGattLocalDescriptorParameters) VTable() *iGattLocalDescriptorParametersVtbl { + return (*iGattLocalDescriptorParametersVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattLocalDescriptorParameters) SetStaticValue(value *streams.IBuffer) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetStaticValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in streams.IBuffer + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalDescriptorParameters) GetStaticValue() (*streams.IBuffer, error) { + var out *streams.IBuffer + hr, _, _ := syscall.SyscallN( + v.VTable().GetStaticValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out streams.IBuffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalDescriptorParameters) SetReadProtectionLevel(value GattProtectionLevel) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetReadProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in GattProtectionLevel + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalDescriptorParameters) GetReadProtectionLevel() (GattProtectionLevel, error) { + var out GattProtectionLevel + hr, _, _ := syscall.SyscallN( + v.VTable().GetReadProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattProtectionLevel + ) + + if hr != 0 { + return GattProtectionLevelPlain, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalDescriptorParameters) SetWriteProtectionLevel(value GattProtectionLevel) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetWriteProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in GattProtectionLevel + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattLocalDescriptorParameters) GetWriteProtectionLevel() (GattProtectionLevel, error) { + var out GattProtectionLevel + hr, _, _ := syscall.SyscallN( + v.VTable().GetWriteProtectionLevel, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattProtectionLevel + ) + + if hr != 0 { + return GattProtectionLevelPlain, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattlocalservice.go b/windows/devices/bluetooth/genericattributeprofile/gattlocalservice.go new file mode 100644 index 0000000..e31a89b --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattlocalservice.go @@ -0,0 +1,108 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" + "github.com/saltosystems/winrt-go/windows/foundation/collections" +) + +const SignatureGattLocalService string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalService;{f513e258-f7f7-4902-b803-57fcc7d6fe83})" + +type GattLocalService struct { + ole.IUnknown +} + +func (impl *GattLocalService) GetUuid() (syscall.GUID, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalService)) + defer itf.Release() + v := (*iGattLocalService)(unsafe.Pointer(itf)) + return v.GetUuid() +} + +func (impl *GattLocalService) CreateCharacteristicAsync(characteristicUuid syscall.GUID, parameters *GattLocalCharacteristicParameters) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalService)) + defer itf.Release() + v := (*iGattLocalService)(unsafe.Pointer(itf)) + return v.CreateCharacteristicAsync(characteristicUuid, parameters) +} + +func (impl *GattLocalService) GetCharacteristics() (*collections.IVectorView, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattLocalService)) + defer itf.Release() + v := (*iGattLocalService)(unsafe.Pointer(itf)) + return v.GetCharacteristics() +} + +const GUIDiGattLocalService string = "f513e258-f7f7-4902-b803-57fcc7d6fe83" +const SignatureiGattLocalService string = "{f513e258-f7f7-4902-b803-57fcc7d6fe83}" + +type iGattLocalService struct { + ole.IInspectable +} + +type iGattLocalServiceVtbl struct { + ole.IInspectableVtbl + + GetUuid uintptr + CreateCharacteristicAsync uintptr + GetCharacteristics uintptr +} + +func (v *iGattLocalService) VTable() *iGattLocalServiceVtbl { + return (*iGattLocalServiceVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattLocalService) GetUuid() (syscall.GUID, error) { + var out syscall.GUID + hr, _, _ := syscall.SyscallN( + v.VTable().GetUuid, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out syscall.GUID + ) + + if hr != 0 { + return syscall.GUID{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalService) CreateCharacteristicAsync(characteristicUuid syscall.GUID, parameters *GattLocalCharacteristicParameters) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().CreateCharacteristicAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&characteristicUuid)), // in syscall.GUID + uintptr(unsafe.Pointer(parameters)), // in GattLocalCharacteristicParameters + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattLocalService) GetCharacteristics() (*collections.IVectorView, error) { + var out *collections.IVectorView + hr, _, _ := syscall.SyscallN( + v.VTable().GetCharacteristics, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out collections.IVectorView + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattprotectionlevel.go b/windows/devices/bluetooth/genericattributeprofile/gattprotectionlevel.go new file mode 100644 index 0000000..a1f1804 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattprotectionlevel.go @@ -0,0 +1,17 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +type GattProtectionLevel int32 + +const SignatureGattProtectionLevel string = "enum(Windows.Devices.Bluetooth.GenericAttributeProfile.GattProtectionLevel;i4)" + +const ( + GattProtectionLevelPlain GattProtectionLevel = 0 + GattProtectionLevelAuthenticationRequired GattProtectionLevel = 1 + GattProtectionLevelEncryptionRequired GattProtectionLevel = 2 + GattProtectionLevelEncryptionAndAuthenticationRequired GattProtectionLevel = 3 +) diff --git a/windows/devices/bluetooth/genericattributeprofile/gattreadrequest.go b/windows/devices/bluetooth/genericattributeprofile/gattreadrequest.go new file mode 100644 index 0000000..5f039e9 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattreadrequest.go @@ -0,0 +1,196 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureGattReadRequest string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadRequest;{f1dd6535-6acd-42a6-a4bb-d789dae0043e})" + +type GattReadRequest struct { + ole.IUnknown +} + +func (impl *GattReadRequest) GetOffset() (uint32, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequest)) + defer itf.Release() + v := (*iGattReadRequest)(unsafe.Pointer(itf)) + return v.GetOffset() +} + +func (impl *GattReadRequest) GetLength() (uint32, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequest)) + defer itf.Release() + v := (*iGattReadRequest)(unsafe.Pointer(itf)) + return v.GetLength() +} + +func (impl *GattReadRequest) GetState() (GattRequestState, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequest)) + defer itf.Release() + v := (*iGattReadRequest)(unsafe.Pointer(itf)) + return v.GetState() +} + +func (impl *GattReadRequest) AddStateChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequest)) + defer itf.Release() + v := (*iGattReadRequest)(unsafe.Pointer(itf)) + return v.AddStateChanged(handler) +} + +func (impl *GattReadRequest) RemoveStateChanged(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequest)) + defer itf.Release() + v := (*iGattReadRequest)(unsafe.Pointer(itf)) + return v.RemoveStateChanged(token) +} + +func (impl *GattReadRequest) RespondWithValue(value *streams.IBuffer) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequest)) + defer itf.Release() + v := (*iGattReadRequest)(unsafe.Pointer(itf)) + return v.RespondWithValue(value) +} + +func (impl *GattReadRequest) RespondWithProtocolError(protocolError uint8) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequest)) + defer itf.Release() + v := (*iGattReadRequest)(unsafe.Pointer(itf)) + return v.RespondWithProtocolError(protocolError) +} + +const GUIDiGattReadRequest string = "f1dd6535-6acd-42a6-a4bb-d789dae0043e" +const SignatureiGattReadRequest string = "{f1dd6535-6acd-42a6-a4bb-d789dae0043e}" + +type iGattReadRequest struct { + ole.IInspectable +} + +type iGattReadRequestVtbl struct { + ole.IInspectableVtbl + + GetOffset uintptr + GetLength uintptr + GetState uintptr + AddStateChanged uintptr + RemoveStateChanged uintptr + RespondWithValue uintptr + RespondWithProtocolError uintptr +} + +func (v *iGattReadRequest) VTable() *iGattReadRequestVtbl { + return (*iGattReadRequestVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattReadRequest) GetOffset() (uint32, error) { + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetOffset, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattReadRequest) GetLength() (uint32, error) { + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetLength, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattReadRequest) GetState() (GattRequestState, error) { + var out GattRequestState + hr, _, _ := syscall.SyscallN( + v.VTable().GetState, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattRequestState + ) + + if hr != 0 { + return GattRequestStatePending, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattReadRequest) AddStateChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddStateChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattReadRequest) RemoveStateChanged(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveStateChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattReadRequest) RespondWithValue(value *streams.IBuffer) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RespondWithValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in streams.IBuffer + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattReadRequest) RespondWithProtocolError(protocolError uint8) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RespondWithProtocolError, + uintptr(unsafe.Pointer(v)), // this + uintptr(protocolError), // in uint8 + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattreadrequestedeventargs.go b/windows/devices/bluetooth/genericattributeprofile/gattreadrequestedeventargs.go new file mode 100644 index 0000000..aa82a32 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattreadrequestedeventargs.go @@ -0,0 +1,105 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureGattReadRequestedEventArgs string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadRequestedEventArgs;{93497243-f39c-484b-8ab6-996ba486cfa3})" + +type GattReadRequestedEventArgs struct { + ole.IUnknown +} + +func (impl *GattReadRequestedEventArgs) GetSession() (*GattSession, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequestedEventArgs)) + defer itf.Release() + v := (*iGattReadRequestedEventArgs)(unsafe.Pointer(itf)) + return v.GetSession() +} + +func (impl *GattReadRequestedEventArgs) GetDeferral() (*foundation.Deferral, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequestedEventArgs)) + defer itf.Release() + v := (*iGattReadRequestedEventArgs)(unsafe.Pointer(itf)) + return v.GetDeferral() +} + +func (impl *GattReadRequestedEventArgs) GetRequestAsync() (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadRequestedEventArgs)) + defer itf.Release() + v := (*iGattReadRequestedEventArgs)(unsafe.Pointer(itf)) + return v.GetRequestAsync() +} + +const GUIDiGattReadRequestedEventArgs string = "93497243-f39c-484b-8ab6-996ba486cfa3" +const SignatureiGattReadRequestedEventArgs string = "{93497243-f39c-484b-8ab6-996ba486cfa3}" + +type iGattReadRequestedEventArgs struct { + ole.IInspectable +} + +type iGattReadRequestedEventArgsVtbl struct { + ole.IInspectableVtbl + + GetSession uintptr + GetDeferral uintptr + GetRequestAsync uintptr +} + +func (v *iGattReadRequestedEventArgs) VTable() *iGattReadRequestedEventArgsVtbl { + return (*iGattReadRequestedEventArgsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattReadRequestedEventArgs) GetSession() (*GattSession, error) { + var out *GattSession + hr, _, _ := syscall.SyscallN( + v.VTable().GetSession, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattSession + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattReadRequestedEventArgs) GetDeferral() (*foundation.Deferral, error) { + var out *foundation.Deferral + hr, _, _ := syscall.SyscallN( + v.VTable().GetDeferral, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.Deferral + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattReadRequestedEventArgs) GetRequestAsync() (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GetRequestAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattreadresult.go b/windows/devices/bluetooth/genericattributeprofile/gattreadresult.go new file mode 100644 index 0000000..29c9b59 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattreadresult.go @@ -0,0 +1,99 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureGattReadResult string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadResult;{63a66f08-1aea-4c4c-a50f-97bae474b348})" + +type GattReadResult struct { + ole.IUnknown +} + +func (impl *GattReadResult) GetStatus() (GattCommunicationStatus, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadResult)) + defer itf.Release() + v := (*iGattReadResult)(unsafe.Pointer(itf)) + return v.GetStatus() +} + +func (impl *GattReadResult) GetValue() (*streams.IBuffer, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattReadResult)) + defer itf.Release() + v := (*iGattReadResult)(unsafe.Pointer(itf)) + return v.GetValue() +} + +const GUIDiGattReadResult string = "63a66f08-1aea-4c4c-a50f-97bae474b348" +const SignatureiGattReadResult string = "{63a66f08-1aea-4c4c-a50f-97bae474b348}" + +type iGattReadResult struct { + ole.IInspectable +} + +type iGattReadResultVtbl struct { + ole.IInspectableVtbl + + GetStatus uintptr + GetValue uintptr +} + +func (v *iGattReadResult) VTable() *iGattReadResultVtbl { + return (*iGattReadResultVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattReadResult) GetStatus() (GattCommunicationStatus, error) { + var out GattCommunicationStatus + hr, _, _ := syscall.SyscallN( + v.VTable().GetStatus, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattCommunicationStatus + ) + + if hr != 0 { + return GattCommunicationStatusSuccess, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattReadResult) GetValue() (*streams.IBuffer, error) { + var out *streams.IBuffer + hr, _, _ := syscall.SyscallN( + v.VTable().GetValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out streams.IBuffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +const GUIDiGattReadResult2 string = "a10f50a0-fb43-48af-baaa-638a5c6329fe" +const SignatureiGattReadResult2 string = "{a10f50a0-fb43-48af-baaa-638a5c6329fe}" + +type iGattReadResult2 struct { + ole.IInspectable +} + +type iGattReadResult2Vtbl struct { + ole.IInspectableVtbl + + GetProtocolError uintptr +} + +func (v *iGattReadResult2) VTable() *iGattReadResult2Vtbl { + return (*iGattReadResult2Vtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattrequeststate.go b/windows/devices/bluetooth/genericattributeprofile/gattrequeststate.go new file mode 100644 index 0000000..a340caa --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattrequeststate.go @@ -0,0 +1,16 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +type GattRequestState int32 + +const SignatureGattRequestState string = "enum(Windows.Devices.Bluetooth.GenericAttributeProfile.GattRequestState;i4)" + +const ( + GattRequestStatePending GattRequestState = 0 + GattRequestStateCompleted GattRequestState = 1 + GattRequestStateCanceled GattRequestState = 2 +) diff --git a/windows/devices/bluetooth/genericattributeprofile/gattserviceprovider.go b/windows/devices/bluetooth/genericattributeprofile/gattserviceprovider.go new file mode 100644 index 0000000..753e0cd --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattserviceprovider.go @@ -0,0 +1,231 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureGattServiceProvider string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProvider;{7822b3cd-2889-4f86-a051-3f0aed1c2760})" + +type GattServiceProvider struct { + ole.IUnknown +} + +func (impl *GattServiceProvider) GetService() (*GattLocalService, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProvider)) + defer itf.Release() + v := (*iGattServiceProvider)(unsafe.Pointer(itf)) + return v.GetService() +} + +func (impl *GattServiceProvider) GetAdvertisementStatus() (GattServiceProviderAdvertisementStatus, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProvider)) + defer itf.Release() + v := (*iGattServiceProvider)(unsafe.Pointer(itf)) + return v.GetAdvertisementStatus() +} + +func (impl *GattServiceProvider) AddAdvertisementStatusChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProvider)) + defer itf.Release() + v := (*iGattServiceProvider)(unsafe.Pointer(itf)) + return v.AddAdvertisementStatusChanged(handler) +} + +func (impl *GattServiceProvider) RemoveAdvertisementStatusChanged(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProvider)) + defer itf.Release() + v := (*iGattServiceProvider)(unsafe.Pointer(itf)) + return v.RemoveAdvertisementStatusChanged(token) +} + +func (impl *GattServiceProvider) StartAdvertising() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProvider)) + defer itf.Release() + v := (*iGattServiceProvider)(unsafe.Pointer(itf)) + return v.StartAdvertising() +} + +func (impl *GattServiceProvider) StartAdvertisingWithParameters(parameters *GattServiceProviderAdvertisingParameters) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProvider)) + defer itf.Release() + v := (*iGattServiceProvider)(unsafe.Pointer(itf)) + return v.StartAdvertisingWithParameters(parameters) +} + +func (impl *GattServiceProvider) StopAdvertising() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProvider)) + defer itf.Release() + v := (*iGattServiceProvider)(unsafe.Pointer(itf)) + return v.StopAdvertising() +} + +const GUIDiGattServiceProvider string = "7822b3cd-2889-4f86-a051-3f0aed1c2760" +const SignatureiGattServiceProvider string = "{7822b3cd-2889-4f86-a051-3f0aed1c2760}" + +type iGattServiceProvider struct { + ole.IInspectable +} + +type iGattServiceProviderVtbl struct { + ole.IInspectableVtbl + + GetService uintptr + GetAdvertisementStatus uintptr + AddAdvertisementStatusChanged uintptr + RemoveAdvertisementStatusChanged uintptr + StartAdvertising uintptr + StartAdvertisingWithParameters uintptr + StopAdvertising uintptr +} + +func (v *iGattServiceProvider) VTable() *iGattServiceProviderVtbl { + return (*iGattServiceProviderVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattServiceProvider) GetService() (*GattLocalService, error) { + var out *GattLocalService + hr, _, _ := syscall.SyscallN( + v.VTable().GetService, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattLocalService + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattServiceProvider) GetAdvertisementStatus() (GattServiceProviderAdvertisementStatus, error) { + var out GattServiceProviderAdvertisementStatus + hr, _, _ := syscall.SyscallN( + v.VTable().GetAdvertisementStatus, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattServiceProviderAdvertisementStatus + ) + + if hr != 0 { + return GattServiceProviderAdvertisementStatusCreated, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattServiceProvider) AddAdvertisementStatusChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddAdvertisementStatusChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattServiceProvider) RemoveAdvertisementStatusChanged(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveAdvertisementStatusChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattServiceProvider) StartAdvertising() error { + hr, _, _ := syscall.SyscallN( + v.VTable().StartAdvertising, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattServiceProvider) StartAdvertisingWithParameters(parameters *GattServiceProviderAdvertisingParameters) error { + hr, _, _ := syscall.SyscallN( + v.VTable().StartAdvertisingWithParameters, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(parameters)), // in GattServiceProviderAdvertisingParameters + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattServiceProvider) StopAdvertising() error { + hr, _, _ := syscall.SyscallN( + v.VTable().StopAdvertising, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiGattServiceProviderStatics string = "31794063-5256-4054-a4f4-7bbe7755a57e" +const SignatureiGattServiceProviderStatics string = "{31794063-5256-4054-a4f4-7bbe7755a57e}" + +type iGattServiceProviderStatics struct { + ole.IInspectable +} + +type iGattServiceProviderStaticsVtbl struct { + ole.IInspectableVtbl + + GattServiceProviderCreateAsync uintptr +} + +func (v *iGattServiceProviderStatics) VTable() *iGattServiceProviderStaticsVtbl { + return (*iGattServiceProviderStaticsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func GattServiceProviderCreateAsync(serviceUuid syscall.GUID) (*foundation.IAsyncOperation, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProvider", ole.NewGUID(GUIDiGattServiceProviderStatics)) + if err != nil { + return nil, err + } + v := (*iGattServiceProviderStatics)(unsafe.Pointer(inspectable)) + + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GattServiceProviderCreateAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&serviceUuid)), // in syscall.GUID + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattserviceprovideradvertisementstatus.go b/windows/devices/bluetooth/genericattributeprofile/gattserviceprovideradvertisementstatus.go new file mode 100644 index 0000000..d72535e --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattserviceprovideradvertisementstatus.go @@ -0,0 +1,18 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +type GattServiceProviderAdvertisementStatus int32 + +const SignatureGattServiceProviderAdvertisementStatus string = "enum(Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProviderAdvertisementStatus;i4)" + +const ( + GattServiceProviderAdvertisementStatusCreated GattServiceProviderAdvertisementStatus = 0 + GattServiceProviderAdvertisementStatusStopped GattServiceProviderAdvertisementStatus = 1 + GattServiceProviderAdvertisementStatusStarted GattServiceProviderAdvertisementStatus = 2 + GattServiceProviderAdvertisementStatusAborted GattServiceProviderAdvertisementStatus = 3 + GattServiceProviderAdvertisementStatusStartedWithoutAllAdvertisementData GattServiceProviderAdvertisementStatus = 4 +) diff --git a/windows/devices/bluetooth/genericattributeprofile/gattserviceprovideradvertisingparameters.go b/windows/devices/bluetooth/genericattributeprofile/gattserviceprovideradvertisingparameters.go new file mode 100644 index 0000000..66a5f74 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattserviceprovideradvertisingparameters.go @@ -0,0 +1,195 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureGattServiceProviderAdvertisingParameters string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProviderAdvertisingParameters;{e2ce31ab-6315-4c22-9bd7-781dbc3d8d82})" + +type GattServiceProviderAdvertisingParameters struct { + ole.IUnknown +} + +func NewGattServiceProviderAdvertisingParameters() (*GattServiceProviderAdvertisingParameters, error) { + inspectable, err := ole.RoActivateInstance("Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProviderAdvertisingParameters") + if err != nil { + return nil, err + } + return (*GattServiceProviderAdvertisingParameters)(unsafe.Pointer(inspectable)), nil +} + +func (impl *GattServiceProviderAdvertisingParameters) SetIsConnectable(value bool) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProviderAdvertisingParameters)) + defer itf.Release() + v := (*iGattServiceProviderAdvertisingParameters)(unsafe.Pointer(itf)) + return v.SetIsConnectable(value) +} + +func (impl *GattServiceProviderAdvertisingParameters) GetIsConnectable() (bool, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProviderAdvertisingParameters)) + defer itf.Release() + v := (*iGattServiceProviderAdvertisingParameters)(unsafe.Pointer(itf)) + return v.GetIsConnectable() +} + +func (impl *GattServiceProviderAdvertisingParameters) SetIsDiscoverable(value bool) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProviderAdvertisingParameters)) + defer itf.Release() + v := (*iGattServiceProviderAdvertisingParameters)(unsafe.Pointer(itf)) + return v.SetIsDiscoverable(value) +} + +func (impl *GattServiceProviderAdvertisingParameters) GetIsDiscoverable() (bool, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProviderAdvertisingParameters)) + defer itf.Release() + v := (*iGattServiceProviderAdvertisingParameters)(unsafe.Pointer(itf)) + return v.GetIsDiscoverable() +} + +func (impl *GattServiceProviderAdvertisingParameters) SetServiceData(value *streams.IBuffer) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProviderAdvertisingParameters2)) + defer itf.Release() + v := (*iGattServiceProviderAdvertisingParameters2)(unsafe.Pointer(itf)) + return v.SetServiceData(value) +} + +func (impl *GattServiceProviderAdvertisingParameters) GetServiceData() (*streams.IBuffer, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProviderAdvertisingParameters2)) + defer itf.Release() + v := (*iGattServiceProviderAdvertisingParameters2)(unsafe.Pointer(itf)) + return v.GetServiceData() +} + +const GUIDiGattServiceProviderAdvertisingParameters string = "e2ce31ab-6315-4c22-9bd7-781dbc3d8d82" +const SignatureiGattServiceProviderAdvertisingParameters string = "{e2ce31ab-6315-4c22-9bd7-781dbc3d8d82}" + +type iGattServiceProviderAdvertisingParameters struct { + ole.IInspectable +} + +type iGattServiceProviderAdvertisingParametersVtbl struct { + ole.IInspectableVtbl + + SetIsConnectable uintptr + GetIsConnectable uintptr + SetIsDiscoverable uintptr + GetIsDiscoverable uintptr +} + +func (v *iGattServiceProviderAdvertisingParameters) VTable() *iGattServiceProviderAdvertisingParametersVtbl { + return (*iGattServiceProviderAdvertisingParametersVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattServiceProviderAdvertisingParameters) SetIsConnectable(value bool) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetIsConnectable, + uintptr(unsafe.Pointer(v)), // this + uintptr(*(*byte)(unsafe.Pointer(&value))), // in bool + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattServiceProviderAdvertisingParameters) GetIsConnectable() (bool, error) { + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().GetIsConnectable, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return false, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattServiceProviderAdvertisingParameters) SetIsDiscoverable(value bool) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetIsDiscoverable, + uintptr(unsafe.Pointer(v)), // this + uintptr(*(*byte)(unsafe.Pointer(&value))), // in bool + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattServiceProviderAdvertisingParameters) GetIsDiscoverable() (bool, error) { + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().GetIsDiscoverable, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return false, ole.NewError(hr) + } + + return out, nil +} + +const GUIDiGattServiceProviderAdvertisingParameters2 string = "ff68468d-ca92-4434-9743-0e90988ad879" +const SignatureiGattServiceProviderAdvertisingParameters2 string = "{ff68468d-ca92-4434-9743-0e90988ad879}" + +type iGattServiceProviderAdvertisingParameters2 struct { + ole.IInspectable +} + +type iGattServiceProviderAdvertisingParameters2Vtbl struct { + ole.IInspectableVtbl + + SetServiceData uintptr + GetServiceData uintptr +} + +func (v *iGattServiceProviderAdvertisingParameters2) VTable() *iGattServiceProviderAdvertisingParameters2Vtbl { + return (*iGattServiceProviderAdvertisingParameters2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattServiceProviderAdvertisingParameters2) SetServiceData(value *streams.IBuffer) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetServiceData, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in streams.IBuffer + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattServiceProviderAdvertisingParameters2) GetServiceData() (*streams.IBuffer, error) { + var out *streams.IBuffer + hr, _, _ := syscall.SyscallN( + v.VTable().GetServiceData, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out streams.IBuffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattserviceproviderresult.go b/windows/devices/bluetooth/genericattributeprofile/gattserviceproviderresult.go new file mode 100644 index 0000000..f704b2f --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattserviceproviderresult.go @@ -0,0 +1,82 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/devices/bluetooth" +) + +const SignatureGattServiceProviderResult string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProviderResult;{764696d8-c53e-428c-8a48-67afe02c3ae6})" + +type GattServiceProviderResult struct { + ole.IUnknown +} + +func (impl *GattServiceProviderResult) GetError() (bluetooth.BluetoothError, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProviderResult)) + defer itf.Release() + v := (*iGattServiceProviderResult)(unsafe.Pointer(itf)) + return v.GetError() +} + +func (impl *GattServiceProviderResult) GetServiceProvider() (*GattServiceProvider, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattServiceProviderResult)) + defer itf.Release() + v := (*iGattServiceProviderResult)(unsafe.Pointer(itf)) + return v.GetServiceProvider() +} + +const GUIDiGattServiceProviderResult string = "764696d8-c53e-428c-8a48-67afe02c3ae6" +const SignatureiGattServiceProviderResult string = "{764696d8-c53e-428c-8a48-67afe02c3ae6}" + +type iGattServiceProviderResult struct { + ole.IInspectable +} + +type iGattServiceProviderResultVtbl struct { + ole.IInspectableVtbl + + GetError uintptr + GetServiceProvider uintptr +} + +func (v *iGattServiceProviderResult) VTable() *iGattServiceProviderResultVtbl { + return (*iGattServiceProviderResultVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattServiceProviderResult) GetError() (bluetooth.BluetoothError, error) { + var out bluetooth.BluetoothError + hr, _, _ := syscall.SyscallN( + v.VTable().GetError, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bluetooth.BluetoothError + ) + + if hr != 0 { + return bluetooth.BluetoothErrorSuccess, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattServiceProviderResult) GetServiceProvider() (*GattServiceProvider, error) { + var out *GattServiceProvider + hr, _, _ := syscall.SyscallN( + v.VTable().GetServiceProvider, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattServiceProvider + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattsession.go b/windows/devices/bluetooth/genericattributeprofile/gattsession.go new file mode 100644 index 0000000..8a4cb0c --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattsession.go @@ -0,0 +1,224 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/devices/bluetooth" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureGattSession string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattSession;{d23b5143-e04e-4c24-999c-9c256f9856b1})" + +type GattSession struct { + ole.IUnknown +} + +func (impl *GattSession) GetCanMaintainConnection() (bool, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSession)) + defer itf.Release() + v := (*iGattSession)(unsafe.Pointer(itf)) + return v.GetCanMaintainConnection() +} + +func (impl *GattSession) SetMaintainConnection(value bool) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSession)) + defer itf.Release() + v := (*iGattSession)(unsafe.Pointer(itf)) + return v.SetMaintainConnection(value) +} + +func (impl *GattSession) GetMaintainConnection() (bool, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSession)) + defer itf.Release() + v := (*iGattSession)(unsafe.Pointer(itf)) + return v.GetMaintainConnection() +} + +func (impl *GattSession) GetMaxPduSize() (uint16, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSession)) + defer itf.Release() + v := (*iGattSession)(unsafe.Pointer(itf)) + return v.GetMaxPduSize() +} + +func (impl *GattSession) AddMaxPduSizeChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSession)) + defer itf.Release() + v := (*iGattSession)(unsafe.Pointer(itf)) + return v.AddMaxPduSizeChanged(handler) +} + +func (impl *GattSession) RemoveMaxPduSizeChanged(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSession)) + defer itf.Release() + v := (*iGattSession)(unsafe.Pointer(itf)) + return v.RemoveMaxPduSizeChanged(token) +} + +func (impl *GattSession) Close() error { + itf := impl.MustQueryInterface(ole.NewGUID(foundation.GUIDIClosable)) + defer itf.Release() + v := (*foundation.IClosable)(unsafe.Pointer(itf)) + return v.Close() +} + +const GUIDiGattSession string = "d23b5143-e04e-4c24-999c-9c256f9856b1" +const SignatureiGattSession string = "{d23b5143-e04e-4c24-999c-9c256f9856b1}" + +type iGattSession struct { + ole.IInspectable +} + +type iGattSessionVtbl struct { + ole.IInspectableVtbl + + GetDeviceId uintptr + GetCanMaintainConnection uintptr + SetMaintainConnection uintptr + GetMaintainConnection uintptr + GetMaxPduSize uintptr + GetSessionStatus uintptr + AddMaxPduSizeChanged uintptr + RemoveMaxPduSizeChanged uintptr + AddSessionStatusChanged uintptr + RemoveSessionStatusChanged uintptr +} + +func (v *iGattSession) VTable() *iGattSessionVtbl { + return (*iGattSessionVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattSession) GetCanMaintainConnection() (bool, error) { + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().GetCanMaintainConnection, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return false, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattSession) SetMaintainConnection(value bool) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetMaintainConnection, + uintptr(unsafe.Pointer(v)), // this + uintptr(*(*byte)(unsafe.Pointer(&value))), // in bool + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattSession) GetMaintainConnection() (bool, error) { + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().GetMaintainConnection, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return false, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattSession) GetMaxPduSize() (uint16, error) { + var out uint16 + hr, _, _ := syscall.SyscallN( + v.VTable().GetMaxPduSize, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint16 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattSession) AddMaxPduSizeChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddMaxPduSizeChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattSession) RemoveMaxPduSizeChanged(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveMaxPduSizeChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiGattSessionStatics string = "2e65b95c-539f-4db7-82a8-73bdbbf73ebf" +const SignatureiGattSessionStatics string = "{2e65b95c-539f-4db7-82a8-73bdbbf73ebf}" + +type iGattSessionStatics struct { + ole.IInspectable +} + +type iGattSessionStaticsVtbl struct { + ole.IInspectableVtbl + + GattSessionFromDeviceIdAsync uintptr +} + +func (v *iGattSessionStatics) VTable() *iGattSessionStaticsVtbl { + return (*iGattSessionStaticsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func GattSessionFromDeviceIdAsync(deviceId *bluetooth.BluetoothDeviceId) (*foundation.IAsyncOperation, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Bluetooth.GenericAttributeProfile.GattSession", ole.NewGUID(GUIDiGattSessionStatics)) + if err != nil { + return nil, err + } + v := (*iGattSessionStatics)(unsafe.Pointer(inspectable)) + + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GattSessionFromDeviceIdAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(deviceId)), // in bluetooth.BluetoothDeviceId + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattsubscribedclient.go b/windows/devices/bluetooth/genericattributeprofile/gattsubscribedclient.go new file mode 100644 index 0000000..7cc5c44 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattsubscribedclient.go @@ -0,0 +1,128 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureGattSubscribedClient string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattSubscribedClient;{736e9001-15a4-4ec2-9248-e3f20d463be9})" + +type GattSubscribedClient struct { + ole.IUnknown +} + +func (impl *GattSubscribedClient) GetSession() (*GattSession, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSubscribedClient)) + defer itf.Release() + v := (*iGattSubscribedClient)(unsafe.Pointer(itf)) + return v.GetSession() +} + +func (impl *GattSubscribedClient) GetMaxNotificationSize() (uint16, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSubscribedClient)) + defer itf.Release() + v := (*iGattSubscribedClient)(unsafe.Pointer(itf)) + return v.GetMaxNotificationSize() +} + +func (impl *GattSubscribedClient) AddMaxNotificationSizeChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSubscribedClient)) + defer itf.Release() + v := (*iGattSubscribedClient)(unsafe.Pointer(itf)) + return v.AddMaxNotificationSizeChanged(handler) +} + +func (impl *GattSubscribedClient) RemoveMaxNotificationSizeChanged(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattSubscribedClient)) + defer itf.Release() + v := (*iGattSubscribedClient)(unsafe.Pointer(itf)) + return v.RemoveMaxNotificationSizeChanged(token) +} + +const GUIDiGattSubscribedClient string = "736e9001-15a4-4ec2-9248-e3f20d463be9" +const SignatureiGattSubscribedClient string = "{736e9001-15a4-4ec2-9248-e3f20d463be9}" + +type iGattSubscribedClient struct { + ole.IInspectable +} + +type iGattSubscribedClientVtbl struct { + ole.IInspectableVtbl + + GetSession uintptr + GetMaxNotificationSize uintptr + AddMaxNotificationSizeChanged uintptr + RemoveMaxNotificationSizeChanged uintptr +} + +func (v *iGattSubscribedClient) VTable() *iGattSubscribedClientVtbl { + return (*iGattSubscribedClientVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattSubscribedClient) GetSession() (*GattSession, error) { + var out *GattSession + hr, _, _ := syscall.SyscallN( + v.VTable().GetSession, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattSession + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattSubscribedClient) GetMaxNotificationSize() (uint16, error) { + var out uint16 + hr, _, _ := syscall.SyscallN( + v.VTable().GetMaxNotificationSize, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint16 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattSubscribedClient) AddMaxNotificationSizeChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddMaxNotificationSizeChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattSubscribedClient) RemoveMaxNotificationSizeChanged(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveMaxNotificationSizeChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattvaluechangedeventargs.go b/windows/devices/bluetooth/genericattributeprofile/gattvaluechangedeventargs.go new file mode 100644 index 0000000..015ca77 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattvaluechangedeventargs.go @@ -0,0 +1,83 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureGattValueChangedEventArgs string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattValueChangedEventArgs;{d21bdb54-06e3-4ed8-a263-acfac8ba7313})" + +type GattValueChangedEventArgs struct { + ole.IUnknown +} + +func (impl *GattValueChangedEventArgs) GetCharacteristicValue() (*streams.IBuffer, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattValueChangedEventArgs)) + defer itf.Release() + v := (*iGattValueChangedEventArgs)(unsafe.Pointer(itf)) + return v.GetCharacteristicValue() +} + +func (impl *GattValueChangedEventArgs) GetTimestamp() (foundation.DateTime, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattValueChangedEventArgs)) + defer itf.Release() + v := (*iGattValueChangedEventArgs)(unsafe.Pointer(itf)) + return v.GetTimestamp() +} + +const GUIDiGattValueChangedEventArgs string = "d21bdb54-06e3-4ed8-a263-acfac8ba7313" +const SignatureiGattValueChangedEventArgs string = "{d21bdb54-06e3-4ed8-a263-acfac8ba7313}" + +type iGattValueChangedEventArgs struct { + ole.IInspectable +} + +type iGattValueChangedEventArgsVtbl struct { + ole.IInspectableVtbl + + GetCharacteristicValue uintptr + GetTimestamp uintptr +} + +func (v *iGattValueChangedEventArgs) VTable() *iGattValueChangedEventArgsVtbl { + return (*iGattValueChangedEventArgsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattValueChangedEventArgs) GetCharacteristicValue() (*streams.IBuffer, error) { + var out *streams.IBuffer + hr, _, _ := syscall.SyscallN( + v.VTable().GetCharacteristicValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out streams.IBuffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattValueChangedEventArgs) GetTimestamp() (foundation.DateTime, error) { + var out foundation.DateTime + hr, _, _ := syscall.SyscallN( + v.VTable().GetTimestamp, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.DateTime + ) + + if hr != 0 { + return foundation.DateTime{}, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattwriteoption.go b/windows/devices/bluetooth/genericattributeprofile/gattwriteoption.go new file mode 100644 index 0000000..384a430 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattwriteoption.go @@ -0,0 +1,15 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +type GattWriteOption int32 + +const SignatureGattWriteOption string = "enum(Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteOption;i4)" + +const ( + GattWriteOptionWriteWithResponse GattWriteOption = 0 + GattWriteOptionWriteWithoutResponse GattWriteOption = 1 +) diff --git a/windows/devices/bluetooth/genericattributeprofile/gattwriterequest.go b/windows/devices/bluetooth/genericattributeprofile/gattwriterequest.go new file mode 100644 index 0000000..150753c --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattwriterequest.go @@ -0,0 +1,218 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" + "github.com/saltosystems/winrt-go/windows/storage/streams" +) + +const SignatureGattWriteRequest string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteRequest;{aeb6a9ed-de2f-4fc2-a9a8-94ea7844f13d})" + +type GattWriteRequest struct { + ole.IUnknown +} + +func (impl *GattWriteRequest) GetValue() (*streams.IBuffer, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequest)) + defer itf.Release() + v := (*iGattWriteRequest)(unsafe.Pointer(itf)) + return v.GetValue() +} + +func (impl *GattWriteRequest) GetOffset() (uint32, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequest)) + defer itf.Release() + v := (*iGattWriteRequest)(unsafe.Pointer(itf)) + return v.GetOffset() +} + +func (impl *GattWriteRequest) GetOption() (GattWriteOption, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequest)) + defer itf.Release() + v := (*iGattWriteRequest)(unsafe.Pointer(itf)) + return v.GetOption() +} + +func (impl *GattWriteRequest) GetState() (GattRequestState, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequest)) + defer itf.Release() + v := (*iGattWriteRequest)(unsafe.Pointer(itf)) + return v.GetState() +} + +func (impl *GattWriteRequest) AddStateChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequest)) + defer itf.Release() + v := (*iGattWriteRequest)(unsafe.Pointer(itf)) + return v.AddStateChanged(handler) +} + +func (impl *GattWriteRequest) RemoveStateChanged(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequest)) + defer itf.Release() + v := (*iGattWriteRequest)(unsafe.Pointer(itf)) + return v.RemoveStateChanged(token) +} + +func (impl *GattWriteRequest) Respond() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequest)) + defer itf.Release() + v := (*iGattWriteRequest)(unsafe.Pointer(itf)) + return v.Respond() +} + +func (impl *GattWriteRequest) RespondWithProtocolError(protocolError uint8) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequest)) + defer itf.Release() + v := (*iGattWriteRequest)(unsafe.Pointer(itf)) + return v.RespondWithProtocolError(protocolError) +} + +const GUIDiGattWriteRequest string = "aeb6a9ed-de2f-4fc2-a9a8-94ea7844f13d" +const SignatureiGattWriteRequest string = "{aeb6a9ed-de2f-4fc2-a9a8-94ea7844f13d}" + +type iGattWriteRequest struct { + ole.IInspectable +} + +type iGattWriteRequestVtbl struct { + ole.IInspectableVtbl + + GetValue uintptr + GetOffset uintptr + GetOption uintptr + GetState uintptr + AddStateChanged uintptr + RemoveStateChanged uintptr + Respond uintptr + RespondWithProtocolError uintptr +} + +func (v *iGattWriteRequest) VTable() *iGattWriteRequestVtbl { + return (*iGattWriteRequestVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattWriteRequest) GetValue() (*streams.IBuffer, error) { + var out *streams.IBuffer + hr, _, _ := syscall.SyscallN( + v.VTable().GetValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out streams.IBuffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattWriteRequest) GetOffset() (uint32, error) { + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetOffset, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattWriteRequest) GetOption() (GattWriteOption, error) { + var out GattWriteOption + hr, _, _ := syscall.SyscallN( + v.VTable().GetOption, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattWriteOption + ) + + if hr != 0 { + return GattWriteOptionWriteWithResponse, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattWriteRequest) GetState() (GattRequestState, error) { + var out GattRequestState + hr, _, _ := syscall.SyscallN( + v.VTable().GetState, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattRequestState + ) + + if hr != 0 { + return GattRequestStatePending, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattWriteRequest) AddStateChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddStateChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattWriteRequest) RemoveStateChanged(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveStateChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattWriteRequest) Respond() error { + hr, _, _ := syscall.SyscallN( + v.VTable().Respond, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGattWriteRequest) RespondWithProtocolError(protocolError uint8) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RespondWithProtocolError, + uintptr(unsafe.Pointer(v)), // this + uintptr(protocolError), // in uint8 + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} diff --git a/windows/devices/bluetooth/genericattributeprofile/gattwriterequestedeventargs.go b/windows/devices/bluetooth/genericattributeprofile/gattwriterequestedeventargs.go new file mode 100644 index 0000000..1cd05d8 --- /dev/null +++ b/windows/devices/bluetooth/genericattributeprofile/gattwriterequestedeventargs.go @@ -0,0 +1,105 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package genericattributeprofile + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureGattWriteRequestedEventArgs string = "rc(Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteRequestedEventArgs;{2dec8bbe-a73a-471a-94d5-037deadd0806})" + +type GattWriteRequestedEventArgs struct { + ole.IUnknown +} + +func (impl *GattWriteRequestedEventArgs) GetSession() (*GattSession, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequestedEventArgs)) + defer itf.Release() + v := (*iGattWriteRequestedEventArgs)(unsafe.Pointer(itf)) + return v.GetSession() +} + +func (impl *GattWriteRequestedEventArgs) GetDeferral() (*foundation.Deferral, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequestedEventArgs)) + defer itf.Release() + v := (*iGattWriteRequestedEventArgs)(unsafe.Pointer(itf)) + return v.GetDeferral() +} + +func (impl *GattWriteRequestedEventArgs) GetRequestAsync() (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGattWriteRequestedEventArgs)) + defer itf.Release() + v := (*iGattWriteRequestedEventArgs)(unsafe.Pointer(itf)) + return v.GetRequestAsync() +} + +const GUIDiGattWriteRequestedEventArgs string = "2dec8bbe-a73a-471a-94d5-037deadd0806" +const SignatureiGattWriteRequestedEventArgs string = "{2dec8bbe-a73a-471a-94d5-037deadd0806}" + +type iGattWriteRequestedEventArgs struct { + ole.IInspectable +} + +type iGattWriteRequestedEventArgsVtbl struct { + ole.IInspectableVtbl + + GetSession uintptr + GetDeferral uintptr + GetRequestAsync uintptr +} + +func (v *iGattWriteRequestedEventArgs) VTable() *iGattWriteRequestedEventArgsVtbl { + return (*iGattWriteRequestedEventArgsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGattWriteRequestedEventArgs) GetSession() (*GattSession, error) { + var out *GattSession + hr, _, _ := syscall.SyscallN( + v.VTable().GetSession, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out GattSession + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattWriteRequestedEventArgs) GetDeferral() (*foundation.Deferral, error) { + var out *foundation.Deferral + hr, _, _ := syscall.SyscallN( + v.VTable().GetDeferral, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.Deferral + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGattWriteRequestedEventArgs) GetRequestAsync() (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GetRequestAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/devices/geolocation/geolocator.go b/windows/devices/geolocation/geolocator.go new file mode 100644 index 0000000..6605192 --- /dev/null +++ b/windows/devices/geolocation/geolocator.go @@ -0,0 +1,606 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package geolocation + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureGeolocator string = "rc(Windows.Devices.Geolocation.Geolocator;{a9c3bf62-4524-4989-8aa9-de019d2e551f})" + +type Geolocator struct { + ole.IUnknown +} + +func NewGeolocator() (*Geolocator, error) { + inspectable, err := ole.RoActivateInstance("Windows.Devices.Geolocation.Geolocator") + if err != nil { + return nil, err + } + return (*Geolocator)(unsafe.Pointer(inspectable)), nil +} + +func (impl *Geolocator) GetDesiredAccuracy() (PositionAccuracy, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.GetDesiredAccuracy() +} + +func (impl *Geolocator) SetDesiredAccuracy(value PositionAccuracy) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.SetDesiredAccuracy(value) +} + +func (impl *Geolocator) GetMovementThreshold() (float64, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.GetMovementThreshold() +} + +func (impl *Geolocator) SetMovementThreshold(value float64) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.SetMovementThreshold(value) +} + +func (impl *Geolocator) GetReportInterval() (uint32, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.GetReportInterval() +} + +func (impl *Geolocator) SetReportInterval(value uint32) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.SetReportInterval(value) +} + +func (impl *Geolocator) GetLocationStatus() (PositionStatus, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.GetLocationStatus() +} + +func (impl *Geolocator) GetGeopositionAsync() (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.GetGeopositionAsync() +} + +func (impl *Geolocator) GetGeopositionAsyncWithAgeAndTimeout(maximumAge foundation.TimeSpan, timeout foundation.TimeSpan) (*foundation.IAsyncOperation, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.GetGeopositionAsyncWithAgeAndTimeout(maximumAge, timeout) +} + +func (impl *Geolocator) AddPositionChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.AddPositionChanged(handler) +} + +func (impl *Geolocator) RemovePositionChanged(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.RemovePositionChanged(token) +} + +func (impl *Geolocator) AddStatusChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.AddStatusChanged(handler) +} + +func (impl *Geolocator) RemoveStatusChanged(token foundation.EventRegistrationToken) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator)) + defer itf.Release() + v := (*iGeolocator)(unsafe.Pointer(itf)) + return v.RemoveStatusChanged(token) +} + +func (impl *Geolocator) GetDesiredAccuracyInMeters() (*foundation.IReference, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocatorWithScalarAccuracy)) + defer itf.Release() + v := (*iGeolocatorWithScalarAccuracy)(unsafe.Pointer(itf)) + return v.GetDesiredAccuracyInMeters() +} + +func (impl *Geolocator) SetDesiredAccuracyInMeters(value *foundation.IReference) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocatorWithScalarAccuracy)) + defer itf.Release() + v := (*iGeolocatorWithScalarAccuracy)(unsafe.Pointer(itf)) + return v.SetDesiredAccuracyInMeters(value) +} + +func (impl *Geolocator) AllowFallbackToConsentlessPositions() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiGeolocator2)) + defer itf.Release() + v := (*iGeolocator2)(unsafe.Pointer(itf)) + return v.AllowFallbackToConsentlessPositions() +} + +const GUIDiGeolocator string = "a9c3bf62-4524-4989-8aa9-de019d2e551f" +const SignatureiGeolocator string = "{a9c3bf62-4524-4989-8aa9-de019d2e551f}" + +type iGeolocator struct { + ole.IInspectable +} + +type iGeolocatorVtbl struct { + ole.IInspectableVtbl + + GetDesiredAccuracy uintptr + SetDesiredAccuracy uintptr + GetMovementThreshold uintptr + SetMovementThreshold uintptr + GetReportInterval uintptr + SetReportInterval uintptr + GetLocationStatus uintptr + GetGeopositionAsync uintptr + GetGeopositionAsyncWithAgeAndTimeout uintptr + AddPositionChanged uintptr + RemovePositionChanged uintptr + AddStatusChanged uintptr + RemoveStatusChanged uintptr +} + +func (v *iGeolocator) VTable() *iGeolocatorVtbl { + return (*iGeolocatorVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGeolocator) GetDesiredAccuracy() (PositionAccuracy, error) { + var out PositionAccuracy + hr, _, _ := syscall.SyscallN( + v.VTable().GetDesiredAccuracy, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out PositionAccuracy + ) + + if hr != 0 { + return PositionAccuracyDefault, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGeolocator) SetDesiredAccuracy(value PositionAccuracy) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetDesiredAccuracy, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in PositionAccuracy + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGeolocator) GetMovementThreshold() (float64, error) { + var out float64 + hr, _, _ := syscall.SyscallN( + v.VTable().GetMovementThreshold, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out float64 + ) + + if hr != 0 { + return 0.0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGeolocator) SetMovementThreshold(value float64) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetMovementThreshold, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in float64 + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGeolocator) GetReportInterval() (uint32, error) { + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetReportInterval, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGeolocator) SetReportInterval(value uint32) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetReportInterval, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in uint32 + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGeolocator) GetLocationStatus() (PositionStatus, error) { + var out PositionStatus + hr, _, _ := syscall.SyscallN( + v.VTable().GetLocationStatus, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out PositionStatus + ) + + if hr != 0 { + return PositionStatusReady, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGeolocator) GetGeopositionAsync() (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GetGeopositionAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGeolocator) GetGeopositionAsyncWithAgeAndTimeout(maximumAge foundation.TimeSpan, timeout foundation.TimeSpan) (*foundation.IAsyncOperation, error) { + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GetGeopositionAsyncWithAgeAndTimeout, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&maximumAge)), // in foundation.TimeSpan + uintptr(unsafe.Pointer(&timeout)), // in foundation.TimeSpan + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGeolocator) AddPositionChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddPositionChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGeolocator) RemovePositionChanged(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemovePositionChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *iGeolocator) AddStatusChanged(handler *foundation.TypedEventHandler) (foundation.EventRegistrationToken, error) { + var out foundation.EventRegistrationToken + hr, _, _ := syscall.SyscallN( + v.VTable().AddStatusChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in foundation.TypedEventHandler + uintptr(unsafe.Pointer(&out)), // out foundation.EventRegistrationToken + ) + + if hr != 0 { + return foundation.EventRegistrationToken{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGeolocator) RemoveStatusChanged(token foundation.EventRegistrationToken) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveStatusChanged, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&token)), // in foundation.EventRegistrationToken + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiGeolocatorWithScalarAccuracy string = "96f5d3c1-b80f-460a-994d-a96c47a51aa4" +const SignatureiGeolocatorWithScalarAccuracy string = "{96f5d3c1-b80f-460a-994d-a96c47a51aa4}" + +type iGeolocatorWithScalarAccuracy struct { + ole.IInspectable +} + +type iGeolocatorWithScalarAccuracyVtbl struct { + ole.IInspectableVtbl + + GetDesiredAccuracyInMeters uintptr + SetDesiredAccuracyInMeters uintptr +} + +func (v *iGeolocatorWithScalarAccuracy) VTable() *iGeolocatorWithScalarAccuracyVtbl { + return (*iGeolocatorWithScalarAccuracyVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGeolocatorWithScalarAccuracy) GetDesiredAccuracyInMeters() (*foundation.IReference, error) { + var out *foundation.IReference + hr, _, _ := syscall.SyscallN( + v.VTable().GetDesiredAccuracyInMeters, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IReference + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *iGeolocatorWithScalarAccuracy) SetDesiredAccuracyInMeters(value *foundation.IReference) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetDesiredAccuracyInMeters, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in foundation.IReference + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiGeolocator2 string = "d1b42e6d-8891-43b4-ad36-27c6fe9a97b1" +const SignatureiGeolocator2 string = "{d1b42e6d-8891-43b4-ad36-27c6fe9a97b1}" + +type iGeolocator2 struct { + ole.IInspectable +} + +type iGeolocator2Vtbl struct { + ole.IInspectableVtbl + + AllowFallbackToConsentlessPositions uintptr +} + +func (v *iGeolocator2) VTable() *iGeolocator2Vtbl { + return (*iGeolocator2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iGeolocator2) AllowFallbackToConsentlessPositions() error { + hr, _, _ := syscall.SyscallN( + v.VTable().AllowFallbackToConsentlessPositions, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiGeolocatorStatics string = "9a8e7571-2df5-4591-9f87-eb5fd894e9b7" +const SignatureiGeolocatorStatics string = "{9a8e7571-2df5-4591-9f87-eb5fd894e9b7}" + +type iGeolocatorStatics struct { + ole.IInspectable +} + +type iGeolocatorStaticsVtbl struct { + ole.IInspectableVtbl + + GeolocatorRequestAccessAsync uintptr + GeolocatorGetGeopositionHistoryAsync uintptr + GeolocatorGetGeopositionHistoryWithDurationAsync uintptr +} + +func (v *iGeolocatorStatics) VTable() *iGeolocatorStaticsVtbl { + return (*iGeolocatorStaticsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func GeolocatorRequestAccessAsync() (*foundation.IAsyncOperation, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Geolocation.Geolocator", ole.NewGUID(GUIDiGeolocatorStatics)) + if err != nil { + return nil, err + } + v := (*iGeolocatorStatics)(unsafe.Pointer(inspectable)) + + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GeolocatorRequestAccessAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func GeolocatorGetGeopositionHistoryAsync(startTime foundation.DateTime) (*foundation.IAsyncOperation, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Geolocation.Geolocator", ole.NewGUID(GUIDiGeolocatorStatics)) + if err != nil { + return nil, err + } + v := (*iGeolocatorStatics)(unsafe.Pointer(inspectable)) + + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GeolocatorGetGeopositionHistoryAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&startTime)), // in foundation.DateTime + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func GeolocatorGetGeopositionHistoryWithDurationAsync(startTime foundation.DateTime, duration foundation.TimeSpan) (*foundation.IAsyncOperation, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Geolocation.Geolocator", ole.NewGUID(GUIDiGeolocatorStatics)) + if err != nil { + return nil, err + } + v := (*iGeolocatorStatics)(unsafe.Pointer(inspectable)) + + var out *foundation.IAsyncOperation + hr, _, _ := syscall.SyscallN( + v.VTable().GeolocatorGetGeopositionHistoryWithDurationAsync, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&startTime)), // in foundation.DateTime + uintptr(unsafe.Pointer(&duration)), // in foundation.TimeSpan + uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +const GUIDiGeolocatorStatics2 string = "993011a2-fa1c-4631-a71d-0dbeb1250d9c" +const SignatureiGeolocatorStatics2 string = "{993011a2-fa1c-4631-a71d-0dbeb1250d9c}" + +type iGeolocatorStatics2 struct { + ole.IInspectable +} + +type iGeolocatorStatics2Vtbl struct { + ole.IInspectableVtbl + + GeolocatorGetIsDefaultGeopositionRecommended uintptr + GeolocatorSetDefaultGeoposition uintptr + GeolocatorGetDefaultGeoposition uintptr +} + +func (v *iGeolocatorStatics2) VTable() *iGeolocatorStatics2Vtbl { + return (*iGeolocatorStatics2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func GeolocatorGetIsDefaultGeopositionRecommended() (bool, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Geolocation.Geolocator", ole.NewGUID(GUIDiGeolocatorStatics2)) + if err != nil { + return false, err + } + v := (*iGeolocatorStatics2)(unsafe.Pointer(inspectable)) + + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().GeolocatorGetIsDefaultGeopositionRecommended, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return false, ole.NewError(hr) + } + + return out, nil +} + +func GeolocatorSetDefaultGeoposition(value *foundation.IReference) error { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Geolocation.Geolocator", ole.NewGUID(GUIDiGeolocatorStatics2)) + if err != nil { + return err + } + v := (*iGeolocatorStatics2)(unsafe.Pointer(inspectable)) + + hr, _, _ := syscall.SyscallN( + v.VTable().GeolocatorSetDefaultGeoposition, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(value)), // in foundation.IReference + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func GeolocatorGetDefaultGeoposition() (*foundation.IReference, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Devices.Geolocation.Geolocator", ole.NewGUID(GUIDiGeolocatorStatics2)) + if err != nil { + return nil, err + } + v := (*iGeolocatorStatics2)(unsafe.Pointer(inspectable)) + + var out *foundation.IReference + hr, _, _ := syscall.SyscallN( + v.VTable().GeolocatorGetDefaultGeoposition, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out foundation.IReference + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/foundation/asyncoperationcompletedhandler.go b/windows/foundation/asyncoperationcompletedhandler.go new file mode 100644 index 0000000..99deace --- /dev/null +++ b/windows/foundation/asyncoperationcompletedhandler.go @@ -0,0 +1,208 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +import ( + "sync" + "time" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/internal/delegate" + "github.com/saltosystems/winrt-go/internal/kernel32" +) + +const GUIDAsyncOperationCompletedHandler string = "fcdcf02c-e5d8-4478-915a-4d90b74b83a5" +const SignatureAsyncOperationCompletedHandler string = "delegate({fcdcf02c-e5d8-4478-915a-4d90b74b83a5})" + +type AsyncOperationCompletedHandler struct { + ole.IUnknown + sync.Mutex + refs uintptr + IID ole.GUID +} + +type AsyncOperationCompletedHandlerVtbl struct { + ole.IUnknownVtbl + Invoke uintptr +} + +type AsyncOperationCompletedHandlerCallback func(instance *AsyncOperationCompletedHandler, asyncInfo *IAsyncOperation, asyncStatus AsyncStatus) + +var callbacksAsyncOperationCompletedHandler = &asyncOperationCompletedHandlerCallbacks{ + mu: &sync.Mutex{}, + callbacks: make(map[unsafe.Pointer]AsyncOperationCompletedHandlerCallback), +} + +var releaseChannelsAsyncOperationCompletedHandler = &asyncOperationCompletedHandlerReleaseChannels{ + mu: &sync.Mutex{}, + chans: make(map[unsafe.Pointer]chan struct{}), +} + +func NewAsyncOperationCompletedHandler(iid *ole.GUID, callback AsyncOperationCompletedHandlerCallback) *AsyncOperationCompletedHandler { + // create type instance + size := unsafe.Sizeof(*(*AsyncOperationCompletedHandler)(nil)) + instPtr := kernel32.Malloc(size) + inst := (*AsyncOperationCompletedHandler)(instPtr) + + // get the callbacks for the VTable + callbacks := delegate.RegisterCallbacks(instPtr, inst) + + // the VTable should also be allocated in the heap + sizeVTable := unsafe.Sizeof(*(*AsyncOperationCompletedHandlerVtbl)(nil)) + vTablePtr := kernel32.Malloc(sizeVTable) + + inst.RawVTable = (*interface{})(vTablePtr) + + vTable := (*AsyncOperationCompletedHandlerVtbl)(vTablePtr) + vTable.IUnknownVtbl = ole.IUnknownVtbl{ + QueryInterface: callbacks.QueryInterface, + AddRef: callbacks.AddRef, + Release: callbacks.Release, + } + vTable.Invoke = callbacks.Invoke + + // Initialize all properties: the malloc may contain garbage + inst.IID = *iid // copy contents + inst.Mutex = sync.Mutex{} + inst.refs = 0 + + callbacksAsyncOperationCompletedHandler.add(unsafe.Pointer(inst), callback) + + // See the docs in the releaseChannelsAsyncOperationCompletedHandler struct + releaseChannelsAsyncOperationCompletedHandler.acquire(unsafe.Pointer(inst)) + + inst.addRef() + return inst +} + +func (r *AsyncOperationCompletedHandler) GetIID() *ole.GUID { + return &r.IID +} + +// addRef increments the reference counter by one +func (r *AsyncOperationCompletedHandler) addRef() uintptr { + r.Lock() + defer r.Unlock() + r.refs++ + return r.refs +} + +// removeRef decrements the reference counter by one. If it was already zero, it will just return zero. +func (r *AsyncOperationCompletedHandler) removeRef() uintptr { + r.Lock() + defer r.Unlock() + + if r.refs > 0 { + r.refs-- + } + + return r.refs +} + +func (instance *AsyncOperationCompletedHandler) Invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8 unsafe.Pointer) uintptr { + asyncInfoPtr := rawArgs0 + asyncStatusRaw := (int32)(uintptr(rawArgs1)) + + // See the quote above. + asyncInfo := (*IAsyncOperation)(asyncInfoPtr) + asyncStatus := (AsyncStatus)(asyncStatusRaw) + if callback, ok := callbacksAsyncOperationCompletedHandler.get(instancePtr); ok { + callback(instance, asyncInfo, asyncStatus) + } + return ole.S_OK +} + +func (instance *AsyncOperationCompletedHandler) AddRef() uintptr { + return instance.addRef() +} + +func (instance *AsyncOperationCompletedHandler) Release() uintptr { + rem := instance.removeRef() + if rem == 0 { + // We're done. + instancePtr := unsafe.Pointer(instance) + callbacksAsyncOperationCompletedHandler.delete(instancePtr) + + // stop release channels used to avoid + // https://github.com/golang/go/issues/55015 + releaseChannelsAsyncOperationCompletedHandler.release(instancePtr) + + kernel32.Free(unsafe.Pointer(instance.RawVTable)) + kernel32.Free(instancePtr) + } + return rem +} + +type asyncOperationCompletedHandlerCallbacks struct { + mu *sync.Mutex + callbacks map[unsafe.Pointer]AsyncOperationCompletedHandlerCallback +} + +func (m *asyncOperationCompletedHandlerCallbacks) add(p unsafe.Pointer, v AsyncOperationCompletedHandlerCallback) { + m.mu.Lock() + defer m.mu.Unlock() + + m.callbacks[p] = v +} + +func (m *asyncOperationCompletedHandlerCallbacks) get(p unsafe.Pointer) (AsyncOperationCompletedHandlerCallback, bool) { + m.mu.Lock() + defer m.mu.Unlock() + + v, ok := m.callbacks[p] + return v, ok +} + +func (m *asyncOperationCompletedHandlerCallbacks) delete(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + delete(m.callbacks, p) +} + +// typedEventHandlerReleaseChannels keeps a map with channels +// used to keep a goroutine alive during the lifecycle of this object. +// This is required to avoid causing a deadlock error. +// See this: https://github.com/golang/go/issues/55015 +type asyncOperationCompletedHandlerReleaseChannels struct { + mu *sync.Mutex + chans map[unsafe.Pointer]chan struct{} +} + +func (m *asyncOperationCompletedHandlerReleaseChannels) acquire(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + c := make(chan struct{}) + m.chans[p] = c + + go func() { + // we need a timer to trick the go runtime into + // thinking there's still something going on here + // but we are only really interested in <-c + t := time.NewTimer(time.Minute) + for { + select { + case <-t.C: + t.Reset(time.Minute) + case <-c: + t.Stop() + return + } + } + }() +} + +func (m *asyncOperationCompletedHandlerReleaseChannels) release(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + if c, ok := m.chans[p]; ok { + close(c) + delete(m.chans, p) + } +} diff --git a/windows/foundation/asyncstatus.go b/windows/foundation/asyncstatus.go new file mode 100644 index 0000000..41eeaae --- /dev/null +++ b/windows/foundation/asyncstatus.go @@ -0,0 +1,17 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +type AsyncStatus int32 + +const SignatureAsyncStatus string = "enum(Windows.Foundation.AsyncStatus;i4)" + +const ( + AsyncStatusCanceled AsyncStatus = 2 + AsyncStatusCompleted AsyncStatus = 1 + AsyncStatusError AsyncStatus = 3 + AsyncStatusStarted AsyncStatus = 0 +) diff --git a/windows/foundation/collections/ivector.go b/windows/foundation/collections/ivector.go new file mode 100644 index 0000000..0484a3c --- /dev/null +++ b/windows/foundation/collections/ivector.go @@ -0,0 +1,223 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package collections + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const GUIDIVector string = "913337e9-11a1-4345-a3a2-4e7f956e222d" +const SignatureIVector string = "{913337e9-11a1-4345-a3a2-4e7f956e222d}" + +type IVector struct { + ole.IInspectable +} + +type IVectorVtbl struct { + ole.IInspectableVtbl + + GetAt uintptr + GetSize uintptr + GetView uintptr + IndexOf uintptr + SetAt uintptr + InsertAt uintptr + RemoveAt uintptr + Append uintptr + RemoveAtEnd uintptr + Clear uintptr + GetMany uintptr + ReplaceAll uintptr +} + +func (v *IVector) VTable() *IVectorVtbl { + return (*IVectorVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IVector) GetAt(index uint32) (unsafe.Pointer, error) { + var out unsafe.Pointer + hr, _, _ := syscall.SyscallN( + v.VTable().GetAt, + uintptr(unsafe.Pointer(v)), // this + uintptr(index), // in uint32 + uintptr(unsafe.Pointer(&out)), // out unsafe.Pointer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *IVector) GetSize() (uint32, error) { + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetSize, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *IVector) GetView() (*IVectorView, error) { + var out *IVectorView + hr, _, _ := syscall.SyscallN( + v.VTable().GetView, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out IVectorView + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *IVector) IndexOf(value unsafe.Pointer) (uint32, bool, error) { + var index uint32 + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().IndexOf, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in unsafe.Pointer + uintptr(unsafe.Pointer(&index)), // out uint32 + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return 0, false, ole.NewError(hr) + } + + return index, out, nil +} + +func (v *IVector) SetAt(index uint32, value unsafe.Pointer) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetAt, + uintptr(unsafe.Pointer(v)), // this + uintptr(index), // in uint32 + uintptr(value), // in unsafe.Pointer + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *IVector) InsertAt(index uint32, value unsafe.Pointer) error { + hr, _, _ := syscall.SyscallN( + v.VTable().InsertAt, + uintptr(unsafe.Pointer(v)), // this + uintptr(index), // in uint32 + uintptr(value), // in unsafe.Pointer + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *IVector) RemoveAt(index uint32) error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveAt, + uintptr(unsafe.Pointer(v)), // this + uintptr(index), // in uint32 + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *IVector) Append(value unsafe.Pointer) error { + hr, _, _ := syscall.SyscallN( + v.VTable().Append, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in unsafe.Pointer + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *IVector) RemoveAtEnd() error { + hr, _, _ := syscall.SyscallN( + v.VTable().RemoveAtEnd, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *IVector) Clear() error { + hr, _, _ := syscall.SyscallN( + v.VTable().Clear, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *IVector) GetMany(startIndex uint32, itemsSize uint32) ([]unsafe.Pointer, uint32, error) { + var items []unsafe.Pointer = make([]unsafe.Pointer, itemsSize) + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetMany, + uintptr(unsafe.Pointer(v)), // this + uintptr(startIndex), // in uint32 + uintptr(itemsSize), // in uint32 + uintptr(unsafe.Pointer(&items[0])), // out unsafe.Pointer + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return nil, 0, ole.NewError(hr) + } + + return items, out, nil +} + +func (v *IVector) ReplaceAll(itemsSize uint32, items []unsafe.Pointer) error { + hr, _, _ := syscall.SyscallN( + v.VTable().ReplaceAll, + uintptr(unsafe.Pointer(v)), // this + uintptr(itemsSize), // in uint32 + uintptr(unsafe.Pointer(&items[0])), // in unsafe.Pointer + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} diff --git a/windows/foundation/collections/ivectorview.go b/windows/foundation/collections/ivectorview.go new file mode 100644 index 0000000..e982875 --- /dev/null +++ b/windows/foundation/collections/ivectorview.go @@ -0,0 +1,101 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package collections + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const GUIDIVectorView string = "bbe1fa4c-b0e3-4583-baef-1f1b2e483e56" +const SignatureIVectorView string = "{bbe1fa4c-b0e3-4583-baef-1f1b2e483e56}" + +type IVectorView struct { + ole.IInspectable +} + +type IVectorViewVtbl struct { + ole.IInspectableVtbl + + GetAt uintptr + GetSize uintptr + IndexOf uintptr + GetMany uintptr +} + +func (v *IVectorView) VTable() *IVectorViewVtbl { + return (*IVectorViewVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IVectorView) GetAt(index uint32) (unsafe.Pointer, error) { + var out unsafe.Pointer + hr, _, _ := syscall.SyscallN( + v.VTable().GetAt, + uintptr(unsafe.Pointer(v)), // this + uintptr(index), // in uint32 + uintptr(unsafe.Pointer(&out)), // out unsafe.Pointer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *IVectorView) GetSize() (uint32, error) { + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetSize, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *IVectorView) IndexOf(value unsafe.Pointer) (uint32, bool, error) { + var index uint32 + var out bool + hr, _, _ := syscall.SyscallN( + v.VTable().IndexOf, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in unsafe.Pointer + uintptr(unsafe.Pointer(&index)), // out uint32 + uintptr(unsafe.Pointer(&out)), // out bool + ) + + if hr != 0 { + return 0, false, ole.NewError(hr) + } + + return index, out, nil +} + +func (v *IVectorView) GetMany(startIndex uint32, itemsSize uint32) ([]unsafe.Pointer, uint32, error) { + var items []unsafe.Pointer = make([]unsafe.Pointer, itemsSize) + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetMany, + uintptr(unsafe.Pointer(v)), // this + uintptr(startIndex), // in uint32 + uintptr(itemsSize), // in uint32 + uintptr(unsafe.Pointer(&items[0])), // out unsafe.Pointer + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return nil, 0, ole.NewError(hr) + } + + return items, out, nil +} diff --git a/windows/foundation/datetime.go b/windows/foundation/datetime.go new file mode 100644 index 0000000..b6b75da --- /dev/null +++ b/windows/foundation/datetime.go @@ -0,0 +1,12 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +const SignatureDateTime string = "struct(Windows.Foundation.DateTime;i8)" + +type DateTime struct { + UniversalTime int64 +} diff --git a/windows/foundation/deferral.go b/windows/foundation/deferral.go new file mode 100644 index 0000000..7643482 --- /dev/null +++ b/windows/foundation/deferral.go @@ -0,0 +1,102 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const SignatureDeferral string = "rc(Windows.Foundation.Deferral;{d6269732-3b7f-46a7-b40b-4fdca2a2c693})" + +type Deferral struct { + ole.IUnknown +} + +func (impl *Deferral) Complete() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiDeferral)) + defer itf.Release() + v := (*iDeferral)(unsafe.Pointer(itf)) + return v.Complete() +} + +func (impl *Deferral) Close() error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDIClosable)) + defer itf.Release() + v := (*IClosable)(unsafe.Pointer(itf)) + return v.Close() +} + +const GUIDiDeferral string = "d6269732-3b7f-46a7-b40b-4fdca2a2c693" +const SignatureiDeferral string = "{d6269732-3b7f-46a7-b40b-4fdca2a2c693}" + +type iDeferral struct { + ole.IInspectable +} + +type iDeferralVtbl struct { + ole.IInspectableVtbl + + Complete uintptr +} + +func (v *iDeferral) VTable() *iDeferralVtbl { + return (*iDeferralVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iDeferral) Complete() error { + hr, _, _ := syscall.SyscallN( + v.VTable().Complete, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +const GUIDiDeferralFactory string = "65a1ecc5-3fb5-4832-8ca9-f061b281d13a" +const SignatureiDeferralFactory string = "{65a1ecc5-3fb5-4832-8ca9-f061b281d13a}" + +type iDeferralFactory struct { + ole.IInspectable +} + +type iDeferralFactoryVtbl struct { + ole.IInspectableVtbl + + DeferralCreate uintptr +} + +func (v *iDeferralFactory) VTable() *iDeferralFactoryVtbl { + return (*iDeferralFactoryVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func DeferralCreate(handler *DeferralCompletedHandler) (*Deferral, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Foundation.Deferral", ole.NewGUID(GUIDiDeferralFactory)) + if err != nil { + return nil, err + } + v := (*iDeferralFactory)(unsafe.Pointer(inspectable)) + + var out *Deferral + hr, _, _ := syscall.SyscallN( + v.VTable().DeferralCreate, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in DeferralCompletedHandler + uintptr(unsafe.Pointer(&out)), // out Deferral + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/foundation/deferralcompletedhandler.go b/windows/foundation/deferralcompletedhandler.go new file mode 100644 index 0000000..989225c --- /dev/null +++ b/windows/foundation/deferralcompletedhandler.go @@ -0,0 +1,204 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +import ( + "sync" + "time" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/internal/delegate" + "github.com/saltosystems/winrt-go/internal/kernel32" +) + +const GUIDDeferralCompletedHandler string = "ed32a372-f3c8-4faa-9cfb-470148da3888" +const SignatureDeferralCompletedHandler string = "delegate({ed32a372-f3c8-4faa-9cfb-470148da3888})" + +type DeferralCompletedHandler struct { + ole.IUnknown + sync.Mutex + refs uintptr + IID ole.GUID +} + +type DeferralCompletedHandlerVtbl struct { + ole.IUnknownVtbl + Invoke uintptr +} + +type DeferralCompletedHandlerCallback func(instance *DeferralCompletedHandler) + +var callbacksDeferralCompletedHandler = &deferralCompletedHandlerCallbacks{ + mu: &sync.Mutex{}, + callbacks: make(map[unsafe.Pointer]DeferralCompletedHandlerCallback), +} + +var releaseChannelsDeferralCompletedHandler = &deferralCompletedHandlerReleaseChannels{ + mu: &sync.Mutex{}, + chans: make(map[unsafe.Pointer]chan struct{}), +} + +func NewDeferralCompletedHandler(iid *ole.GUID, callback DeferralCompletedHandlerCallback) *DeferralCompletedHandler { + // create type instance + size := unsafe.Sizeof(*(*DeferralCompletedHandler)(nil)) + instPtr := kernel32.Malloc(size) + inst := (*DeferralCompletedHandler)(instPtr) + + // get the callbacks for the VTable + callbacks := delegate.RegisterCallbacks(instPtr, inst) + + // the VTable should also be allocated in the heap + sizeVTable := unsafe.Sizeof(*(*DeferralCompletedHandlerVtbl)(nil)) + vTablePtr := kernel32.Malloc(sizeVTable) + + inst.RawVTable = (*interface{})(vTablePtr) + + vTable := (*DeferralCompletedHandlerVtbl)(vTablePtr) + vTable.IUnknownVtbl = ole.IUnknownVtbl{ + QueryInterface: callbacks.QueryInterface, + AddRef: callbacks.AddRef, + Release: callbacks.Release, + } + vTable.Invoke = callbacks.Invoke + + // Initialize all properties: the malloc may contain garbage + inst.IID = *iid // copy contents + inst.Mutex = sync.Mutex{} + inst.refs = 0 + + callbacksDeferralCompletedHandler.add(unsafe.Pointer(inst), callback) + + // See the docs in the releaseChannelsDeferralCompletedHandler struct + releaseChannelsDeferralCompletedHandler.acquire(unsafe.Pointer(inst)) + + inst.addRef() + return inst +} + +func (r *DeferralCompletedHandler) GetIID() *ole.GUID { + return &r.IID +} + +// addRef increments the reference counter by one +func (r *DeferralCompletedHandler) addRef() uintptr { + r.Lock() + defer r.Unlock() + r.refs++ + return r.refs +} + +// removeRef decrements the reference counter by one. If it was already zero, it will just return zero. +func (r *DeferralCompletedHandler) removeRef() uintptr { + r.Lock() + defer r.Unlock() + + if r.refs > 0 { + r.refs-- + } + + return r.refs +} + +func (instance *DeferralCompletedHandler) Invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8 unsafe.Pointer) uintptr { + + // See the quote above. + if callback, ok := callbacksDeferralCompletedHandler.get(instancePtr); ok { + callback(instance) + } + return ole.S_OK +} + +func (instance *DeferralCompletedHandler) AddRef() uintptr { + return instance.addRef() +} + +func (instance *DeferralCompletedHandler) Release() uintptr { + rem := instance.removeRef() + if rem == 0 { + // We're done. + instancePtr := unsafe.Pointer(instance) + callbacksDeferralCompletedHandler.delete(instancePtr) + + // stop release channels used to avoid + // https://github.com/golang/go/issues/55015 + releaseChannelsDeferralCompletedHandler.release(instancePtr) + + kernel32.Free(unsafe.Pointer(instance.RawVTable)) + kernel32.Free(instancePtr) + } + return rem +} + +type deferralCompletedHandlerCallbacks struct { + mu *sync.Mutex + callbacks map[unsafe.Pointer]DeferralCompletedHandlerCallback +} + +func (m *deferralCompletedHandlerCallbacks) add(p unsafe.Pointer, v DeferralCompletedHandlerCallback) { + m.mu.Lock() + defer m.mu.Unlock() + + m.callbacks[p] = v +} + +func (m *deferralCompletedHandlerCallbacks) get(p unsafe.Pointer) (DeferralCompletedHandlerCallback, bool) { + m.mu.Lock() + defer m.mu.Unlock() + + v, ok := m.callbacks[p] + return v, ok +} + +func (m *deferralCompletedHandlerCallbacks) delete(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + delete(m.callbacks, p) +} + +// typedEventHandlerReleaseChannels keeps a map with channels +// used to keep a goroutine alive during the lifecycle of this object. +// This is required to avoid causing a deadlock error. +// See this: https://github.com/golang/go/issues/55015 +type deferralCompletedHandlerReleaseChannels struct { + mu *sync.Mutex + chans map[unsafe.Pointer]chan struct{} +} + +func (m *deferralCompletedHandlerReleaseChannels) acquire(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + c := make(chan struct{}) + m.chans[p] = c + + go func() { + // we need a timer to trick the go runtime into + // thinking there's still something going on here + // but we are only really interested in <-c + t := time.NewTimer(time.Minute) + for { + select { + case <-t.C: + t.Reset(time.Minute) + case <-c: + t.Stop() + return + } + } + }() +} + +func (m *deferralCompletedHandlerReleaseChannels) release(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + if c, ok := m.chans[p]; ok { + close(c) + delete(m.chans, p) + } +} diff --git a/windows/foundation/eventregistrationtoken.go b/windows/foundation/eventregistrationtoken.go new file mode 100644 index 0000000..b146a3b --- /dev/null +++ b/windows/foundation/eventregistrationtoken.go @@ -0,0 +1,12 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +const SignatureEventRegistrationToken string = "struct(Windows.Foundation.EventRegistrationToken;i8)" + +type EventRegistrationToken struct { + Value int64 +} diff --git a/windows/foundation/iasyncoperation.go b/windows/foundation/iasyncoperation.go new file mode 100644 index 0000000..3fe533d --- /dev/null +++ b/windows/foundation/iasyncoperation.go @@ -0,0 +1,76 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const GUIDIAsyncOperation string = "9fc2b0bb-e446-44e2-aa61-9cab8f636af2" +const SignatureIAsyncOperation string = "{9fc2b0bb-e446-44e2-aa61-9cab8f636af2}" + +type IAsyncOperation struct { + ole.IInspectable +} + +type IAsyncOperationVtbl struct { + ole.IInspectableVtbl + + SetCompleted uintptr + GetCompleted uintptr + GetResults uintptr +} + +func (v *IAsyncOperation) VTable() *IAsyncOperationVtbl { + return (*IAsyncOperationVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IAsyncOperation) SetCompleted(handler *AsyncOperationCompletedHandler) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetCompleted, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(handler)), // in AsyncOperationCompletedHandler + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *IAsyncOperation) GetCompleted() (*AsyncOperationCompletedHandler, error) { + var out *AsyncOperationCompletedHandler + hr, _, _ := syscall.SyscallN( + v.VTable().GetCompleted, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out AsyncOperationCompletedHandler + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} + +func (v *IAsyncOperation) GetResults() (unsafe.Pointer, error) { + var out unsafe.Pointer + hr, _, _ := syscall.SyscallN( + v.VTable().GetResults, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out unsafe.Pointer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/foundation/iclosable.go b/windows/foundation/iclosable.go new file mode 100644 index 0000000..bf14242 --- /dev/null +++ b/windows/foundation/iclosable.go @@ -0,0 +1,43 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const GUIDIClosable string = "30d5a829-7fa4-4026-83bb-d75bae4ea99e" +const SignatureIClosable string = "{30d5a829-7fa4-4026-83bb-d75bae4ea99e}" + +type IClosable struct { + ole.IInspectable +} + +type IClosableVtbl struct { + ole.IInspectableVtbl + + Close uintptr +} + +func (v *IClosable) VTable() *IClosableVtbl { + return (*IClosableVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IClosable) Close() error { + hr, _, _ := syscall.SyscallN( + v.VTable().Close, + uintptr(unsafe.Pointer(v)), // this + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} diff --git a/windows/foundation/ireference.go b/windows/foundation/ireference.go new file mode 100644 index 0000000..016f1b9 --- /dev/null +++ b/windows/foundation/ireference.go @@ -0,0 +1,45 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const GUIDIReference string = "61c17706-2d65-11e0-9ae8-d48564015472" +const SignatureIReference string = "{61c17706-2d65-11e0-9ae8-d48564015472}" + +type IReference struct { + ole.IInspectable +} + +type IReferenceVtbl struct { + ole.IInspectableVtbl + + GetValue uintptr +} + +func (v *IReference) VTable() *IReferenceVtbl { + return (*IReferenceVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IReference) GetValue() (unsafe.Pointer, error) { + var out unsafe.Pointer + hr, _, _ := syscall.SyscallN( + v.VTable().GetValue, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out unsafe.Pointer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/foundation/typedeventhandler.go b/windows/foundation/typedeventhandler.go new file mode 100644 index 0000000..725179c --- /dev/null +++ b/windows/foundation/typedeventhandler.go @@ -0,0 +1,208 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package foundation + +import ( + "sync" + "time" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/internal/delegate" + "github.com/saltosystems/winrt-go/internal/kernel32" +) + +const GUIDTypedEventHandler string = "9de1c534-6ae1-11e0-84e1-18a905bcc53f" +const SignatureTypedEventHandler string = "delegate({9de1c534-6ae1-11e0-84e1-18a905bcc53f})" + +type TypedEventHandler struct { + ole.IUnknown + sync.Mutex + refs uintptr + IID ole.GUID +} + +type TypedEventHandlerVtbl struct { + ole.IUnknownVtbl + Invoke uintptr +} + +type TypedEventHandlerCallback func(instance *TypedEventHandler, sender unsafe.Pointer, args unsafe.Pointer) + +var callbacksTypedEventHandler = &typedEventHandlerCallbacks{ + mu: &sync.Mutex{}, + callbacks: make(map[unsafe.Pointer]TypedEventHandlerCallback), +} + +var releaseChannelsTypedEventHandler = &typedEventHandlerReleaseChannels{ + mu: &sync.Mutex{}, + chans: make(map[unsafe.Pointer]chan struct{}), +} + +func NewTypedEventHandler(iid *ole.GUID, callback TypedEventHandlerCallback) *TypedEventHandler { + // create type instance + size := unsafe.Sizeof(*(*TypedEventHandler)(nil)) + instPtr := kernel32.Malloc(size) + inst := (*TypedEventHandler)(instPtr) + + // get the callbacks for the VTable + callbacks := delegate.RegisterCallbacks(instPtr, inst) + + // the VTable should also be allocated in the heap + sizeVTable := unsafe.Sizeof(*(*TypedEventHandlerVtbl)(nil)) + vTablePtr := kernel32.Malloc(sizeVTable) + + inst.RawVTable = (*interface{})(vTablePtr) + + vTable := (*TypedEventHandlerVtbl)(vTablePtr) + vTable.IUnknownVtbl = ole.IUnknownVtbl{ + QueryInterface: callbacks.QueryInterface, + AddRef: callbacks.AddRef, + Release: callbacks.Release, + } + vTable.Invoke = callbacks.Invoke + + // Initialize all properties: the malloc may contain garbage + inst.IID = *iid // copy contents + inst.Mutex = sync.Mutex{} + inst.refs = 0 + + callbacksTypedEventHandler.add(unsafe.Pointer(inst), callback) + + // See the docs in the releaseChannelsTypedEventHandler struct + releaseChannelsTypedEventHandler.acquire(unsafe.Pointer(inst)) + + inst.addRef() + return inst +} + +func (r *TypedEventHandler) GetIID() *ole.GUID { + return &r.IID +} + +// addRef increments the reference counter by one +func (r *TypedEventHandler) addRef() uintptr { + r.Lock() + defer r.Unlock() + r.refs++ + return r.refs +} + +// removeRef decrements the reference counter by one. If it was already zero, it will just return zero. +func (r *TypedEventHandler) removeRef() uintptr { + r.Lock() + defer r.Unlock() + + if r.refs > 0 { + r.refs-- + } + + return r.refs +} + +func (instance *TypedEventHandler) Invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8 unsafe.Pointer) uintptr { + senderPtr := rawArgs0 + argsPtr := rawArgs1 + + // See the quote above. + sender := (unsafe.Pointer)(senderPtr) + args := (unsafe.Pointer)(argsPtr) + if callback, ok := callbacksTypedEventHandler.get(instancePtr); ok { + callback(instance, sender, args) + } + return ole.S_OK +} + +func (instance *TypedEventHandler) AddRef() uintptr { + return instance.addRef() +} + +func (instance *TypedEventHandler) Release() uintptr { + rem := instance.removeRef() + if rem == 0 { + // We're done. + instancePtr := unsafe.Pointer(instance) + callbacksTypedEventHandler.delete(instancePtr) + + // stop release channels used to avoid + // https://github.com/golang/go/issues/55015 + releaseChannelsTypedEventHandler.release(instancePtr) + + kernel32.Free(unsafe.Pointer(instance.RawVTable)) + kernel32.Free(instancePtr) + } + return rem +} + +type typedEventHandlerCallbacks struct { + mu *sync.Mutex + callbacks map[unsafe.Pointer]TypedEventHandlerCallback +} + +func (m *typedEventHandlerCallbacks) add(p unsafe.Pointer, v TypedEventHandlerCallback) { + m.mu.Lock() + defer m.mu.Unlock() + + m.callbacks[p] = v +} + +func (m *typedEventHandlerCallbacks) get(p unsafe.Pointer) (TypedEventHandlerCallback, bool) { + m.mu.Lock() + defer m.mu.Unlock() + + v, ok := m.callbacks[p] + return v, ok +} + +func (m *typedEventHandlerCallbacks) delete(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + delete(m.callbacks, p) +} + +// typedEventHandlerReleaseChannels keeps a map with channels +// used to keep a goroutine alive during the lifecycle of this object. +// This is required to avoid causing a deadlock error. +// See this: https://github.com/golang/go/issues/55015 +type typedEventHandlerReleaseChannels struct { + mu *sync.Mutex + chans map[unsafe.Pointer]chan struct{} +} + +func (m *typedEventHandlerReleaseChannels) acquire(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + c := make(chan struct{}) + m.chans[p] = c + + go func() { + // we need a timer to trick the go runtime into + // thinking there's still something going on here + // but we are only really interested in <-c + t := time.NewTimer(time.Minute) + for { + select { + case <-t.C: + t.Reset(time.Minute) + case <-c: + t.Stop() + return + } + } + }() +} + +func (m *typedEventHandlerReleaseChannels) release(p unsafe.Pointer) { + m.mu.Lock() + defer m.mu.Unlock() + + if c, ok := m.chans[p]; ok { + close(c) + delete(m.chans, p) + } +} diff --git a/windows/security/exchangeactivesyncprovisioning/easclientdeviceinformation.go b/windows/security/exchangeactivesyncprovisioning/easclientdeviceinformation.go new file mode 100644 index 0000000..4867b4b --- /dev/null +++ b/windows/security/exchangeactivesyncprovisioning/easclientdeviceinformation.go @@ -0,0 +1,257 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package exchangeactivesyncprovisioning + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const SignatureEasClientDeviceInformation string = "rc(Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation;{54dfd981-1968-4ca3-b958-e595d16505eb})" + +type EasClientDeviceInformation struct { + ole.IUnknown +} + +func NewEasClientDeviceInformation() (*EasClientDeviceInformation, error) { + inspectable, err := ole.RoActivateInstance("Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation") + if err != nil { + return nil, err + } + return (*EasClientDeviceInformation)(unsafe.Pointer(inspectable)), nil +} + +func (impl *EasClientDeviceInformation) GetId() (syscall.GUID, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiEasClientDeviceInformation)) + defer itf.Release() + v := (*iEasClientDeviceInformation)(unsafe.Pointer(itf)) + return v.GetId() +} + +func (impl *EasClientDeviceInformation) GetOperatingSystem() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiEasClientDeviceInformation)) + defer itf.Release() + v := (*iEasClientDeviceInformation)(unsafe.Pointer(itf)) + return v.GetOperatingSystem() +} + +func (impl *EasClientDeviceInformation) GetFriendlyName() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiEasClientDeviceInformation)) + defer itf.Release() + v := (*iEasClientDeviceInformation)(unsafe.Pointer(itf)) + return v.GetFriendlyName() +} + +func (impl *EasClientDeviceInformation) GetSystemManufacturer() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiEasClientDeviceInformation)) + defer itf.Release() + v := (*iEasClientDeviceInformation)(unsafe.Pointer(itf)) + return v.GetSystemManufacturer() +} + +func (impl *EasClientDeviceInformation) GetSystemProductName() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiEasClientDeviceInformation)) + defer itf.Release() + v := (*iEasClientDeviceInformation)(unsafe.Pointer(itf)) + return v.GetSystemProductName() +} + +func (impl *EasClientDeviceInformation) GetSystemSku() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiEasClientDeviceInformation)) + defer itf.Release() + v := (*iEasClientDeviceInformation)(unsafe.Pointer(itf)) + return v.GetSystemSku() +} + +func (impl *EasClientDeviceInformation) GetSystemHardwareVersion() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiEasClientDeviceInformation2)) + defer itf.Release() + v := (*iEasClientDeviceInformation2)(unsafe.Pointer(itf)) + return v.GetSystemHardwareVersion() +} + +func (impl *EasClientDeviceInformation) GetSystemFirmwareVersion() (string, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDiEasClientDeviceInformation2)) + defer itf.Release() + v := (*iEasClientDeviceInformation2)(unsafe.Pointer(itf)) + return v.GetSystemFirmwareVersion() +} + +const GUIDiEasClientDeviceInformation string = "54dfd981-1968-4ca3-b958-e595d16505eb" +const SignatureiEasClientDeviceInformation string = "{54dfd981-1968-4ca3-b958-e595d16505eb}" + +type iEasClientDeviceInformation struct { + ole.IInspectable +} + +type iEasClientDeviceInformationVtbl struct { + ole.IInspectableVtbl + + GetId uintptr + GetOperatingSystem uintptr + GetFriendlyName uintptr + GetSystemManufacturer uintptr + GetSystemProductName uintptr + GetSystemSku uintptr +} + +func (v *iEasClientDeviceInformation) VTable() *iEasClientDeviceInformationVtbl { + return (*iEasClientDeviceInformationVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iEasClientDeviceInformation) GetId() (syscall.GUID, error) { + var out syscall.GUID + hr, _, _ := syscall.SyscallN( + v.VTable().GetId, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out syscall.GUID + ) + + if hr != 0 { + return syscall.GUID{}, ole.NewError(hr) + } + + return out, nil +} + +func (v *iEasClientDeviceInformation) GetOperatingSystem() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetOperatingSystem, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +func (v *iEasClientDeviceInformation) GetFriendlyName() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetFriendlyName, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +func (v *iEasClientDeviceInformation) GetSystemManufacturer() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetSystemManufacturer, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +func (v *iEasClientDeviceInformation) GetSystemProductName() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetSystemProductName, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +func (v *iEasClientDeviceInformation) GetSystemSku() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetSystemSku, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +const GUIDiEasClientDeviceInformation2 string = "ffb35923-bb26-4d6a-81bc-165aee0ad754" +const SignatureiEasClientDeviceInformation2 string = "{ffb35923-bb26-4d6a-81bc-165aee0ad754}" + +type iEasClientDeviceInformation2 struct { + ole.IInspectable +} + +type iEasClientDeviceInformation2Vtbl struct { + ole.IInspectableVtbl + + GetSystemHardwareVersion uintptr + GetSystemFirmwareVersion uintptr +} + +func (v *iEasClientDeviceInformation2) VTable() *iEasClientDeviceInformation2Vtbl { + return (*iEasClientDeviceInformation2Vtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *iEasClientDeviceInformation2) GetSystemHardwareVersion() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetSystemHardwareVersion, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} + +func (v *iEasClientDeviceInformation2) GetSystemFirmwareVersion() (string, error) { + var outHStr ole.HString + hr, _, _ := syscall.SyscallN( + v.VTable().GetSystemFirmwareVersion, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&outHStr)), // out string + ) + + if hr != 0 { + return "", ole.NewError(hr) + } + + out := outHStr.String() + ole.DeleteHString(outHStr) + return out, nil +} diff --git a/windows/storage/streams/buffer.go b/windows/storage/streams/buffer.go new file mode 100644 index 0000000..e3e1fc5 --- /dev/null +++ b/windows/storage/streams/buffer.go @@ -0,0 +1,79 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package streams + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const SignatureBuffer string = "rc(Windows.Storage.Streams.Buffer;{905a0fe0-bc53-11df-8c49-001e4fc686da})" + +type Buffer struct { + ole.IUnknown +} + +func (impl *Buffer) GetCapacity() (uint32, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDIBuffer)) + defer itf.Release() + v := (*IBuffer)(unsafe.Pointer(itf)) + return v.GetCapacity() +} + +func (impl *Buffer) GetLength() (uint32, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDIBuffer)) + defer itf.Release() + v := (*IBuffer)(unsafe.Pointer(itf)) + return v.GetLength() +} + +func (impl *Buffer) SetLength(value uint32) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDIBuffer)) + defer itf.Release() + v := (*IBuffer)(unsafe.Pointer(itf)) + return v.SetLength(value) +} + +const GUIDiBufferFactory string = "71af914d-c10f-484b-bc50-14bc623b3a27" +const SignatureiBufferFactory string = "{71af914d-c10f-484b-bc50-14bc623b3a27}" + +type iBufferFactory struct { + ole.IInspectable +} + +type iBufferFactoryVtbl struct { + ole.IInspectableVtbl + + BufferCreate uintptr +} + +func (v *iBufferFactory) VTable() *iBufferFactoryVtbl { + return (*iBufferFactoryVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func BufferCreate(capacity uint32) (*Buffer, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Storage.Streams.Buffer", ole.NewGUID(GUIDiBufferFactory)) + if err != nil { + return nil, err + } + v := (*iBufferFactory)(unsafe.Pointer(inspectable)) + + var out *Buffer + hr, _, _ := syscall.SyscallN( + v.VTable().BufferCreate, + uintptr(unsafe.Pointer(v)), // this + uintptr(capacity), // in uint32 + uintptr(unsafe.Pointer(&out)), // out Buffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/storage/streams/datareader.go b/windows/storage/streams/datareader.go new file mode 100644 index 0000000..0ba263b --- /dev/null +++ b/windows/storage/streams/datareader.go @@ -0,0 +1,65 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package streams + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const SignatureDataReader string = "rc(Windows.Storage.Streams.DataReader;{e2b50029-b4c1-4314-a4b8-fb813a2f275e})" + +type DataReader struct { + ole.IUnknown +} + +func (impl *DataReader) ReadBytes(valueSize uint32) ([]uint8, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDIDataReader)) + defer itf.Release() + v := (*IDataReader)(unsafe.Pointer(itf)) + return v.ReadBytes(valueSize) +} + +const GUIDiDataReaderStatics string = "11fcbfc8-f93a-471b-b121-f379e349313c" +const SignatureiDataReaderStatics string = "{11fcbfc8-f93a-471b-b121-f379e349313c}" + +type iDataReaderStatics struct { + ole.IInspectable +} + +type iDataReaderStaticsVtbl struct { + ole.IInspectableVtbl + + DataReaderFromBuffer uintptr +} + +func (v *iDataReaderStatics) VTable() *iDataReaderStaticsVtbl { + return (*iDataReaderStaticsVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func DataReaderFromBuffer(buffer *IBuffer) (*DataReader, error) { + inspectable, err := ole.RoGetActivationFactory("Windows.Storage.Streams.DataReader", ole.NewGUID(GUIDiDataReaderStatics)) + if err != nil { + return nil, err + } + v := (*iDataReaderStatics)(unsafe.Pointer(inspectable)) + + var out *DataReader + hr, _, _ := syscall.SyscallN( + v.VTable().DataReaderFromBuffer, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(buffer)), // in IBuffer + uintptr(unsafe.Pointer(&out)), // out DataReader + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/windows/storage/streams/datawriter.go b/windows/storage/streams/datawriter.go new file mode 100644 index 0000000..ad7bed8 --- /dev/null +++ b/windows/storage/streams/datawriter.go @@ -0,0 +1,48 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package streams + +import ( + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go/windows/foundation" +) + +const SignatureDataWriter string = "rc(Windows.Storage.Streams.DataWriter;{64b89265-d341-4922-b38a-dd4af8808c4e})" + +type DataWriter struct { + ole.IUnknown +} + +func NewDataWriter() (*DataWriter, error) { + inspectable, err := ole.RoActivateInstance("Windows.Storage.Streams.DataWriter") + if err != nil { + return nil, err + } + return (*DataWriter)(unsafe.Pointer(inspectable)), nil +} + +func (impl *DataWriter) WriteBytes(valueSize uint32, value []uint8) error { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDIDataWriter)) + defer itf.Release() + v := (*IDataWriter)(unsafe.Pointer(itf)) + return v.WriteBytes(valueSize, value) +} + +func (impl *DataWriter) DetachBuffer() (*IBuffer, error) { + itf := impl.MustQueryInterface(ole.NewGUID(GUIDIDataWriter)) + defer itf.Release() + v := (*IDataWriter)(unsafe.Pointer(itf)) + return v.DetachBuffer() +} + +func (impl *DataWriter) Close() error { + itf := impl.MustQueryInterface(ole.NewGUID(foundation.GUIDIClosable)) + defer itf.Release() + v := (*foundation.IClosable)(unsafe.Pointer(itf)) + return v.Close() +} diff --git a/windows/storage/streams/ibuffer.go b/windows/storage/streams/ibuffer.go new file mode 100644 index 0000000..9710215 --- /dev/null +++ b/windows/storage/streams/ibuffer.go @@ -0,0 +1,76 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package streams + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const GUIDIBuffer string = "905a0fe0-bc53-11df-8c49-001e4fc686da" +const SignatureIBuffer string = "{905a0fe0-bc53-11df-8c49-001e4fc686da}" + +type IBuffer struct { + ole.IInspectable +} + +type IBufferVtbl struct { + ole.IInspectableVtbl + + GetCapacity uintptr + GetLength uintptr + SetLength uintptr +} + +func (v *IBuffer) VTable() *IBufferVtbl { + return (*IBufferVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IBuffer) GetCapacity() (uint32, error) { + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetCapacity, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *IBuffer) GetLength() (uint32, error) { + var out uint32 + hr, _, _ := syscall.SyscallN( + v.VTable().GetLength, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out uint32 + ) + + if hr != 0 { + return 0, ole.NewError(hr) + } + + return out, nil +} + +func (v *IBuffer) SetLength(value uint32) error { + hr, _, _ := syscall.SyscallN( + v.VTable().SetLength, + uintptr(unsafe.Pointer(v)), // this + uintptr(value), // in uint32 + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} diff --git a/windows/storage/streams/idatareader.go b/windows/storage/streams/idatareader.go new file mode 100644 index 0000000..f836d84 --- /dev/null +++ b/windows/storage/streams/idatareader.go @@ -0,0 +1,71 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package streams + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const GUIDIDataReader string = "e2b50029-b4c1-4314-a4b8-fb813a2f275e" +const SignatureIDataReader string = "{e2b50029-b4c1-4314-a4b8-fb813a2f275e}" + +type IDataReader struct { + ole.IInspectable +} + +type IDataReaderVtbl struct { + ole.IInspectableVtbl + + GetUnconsumedBufferLength uintptr + GetUnicodeEncoding uintptr + SetUnicodeEncoding uintptr + GetByteOrder uintptr + SetByteOrder uintptr + GetInputStreamOptions uintptr + SetInputStreamOptions uintptr + ReadByte uintptr + ReadBytes uintptr + ReadBuffer uintptr + ReadBoolean uintptr + ReadGuid uintptr + ReadInt16 uintptr + ReadInt32 uintptr + ReadInt64 uintptr + ReadUInt16 uintptr + ReadUInt32 uintptr + ReadUInt64 uintptr + ReadSingle uintptr + ReadDouble uintptr + ReadString uintptr + ReadDateTime uintptr + ReadTimeSpan uintptr + LoadAsync uintptr + DetachBuffer uintptr + DetachStream uintptr +} + +func (v *IDataReader) VTable() *IDataReaderVtbl { + return (*IDataReaderVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IDataReader) ReadBytes(valueSize uint32) ([]uint8, error) { + var value []uint8 = make([]uint8, valueSize) + hr, _, _ := syscall.SyscallN( + v.VTable().ReadBytes, + uintptr(unsafe.Pointer(v)), // this + uintptr(valueSize), // in uint32 + uintptr(unsafe.Pointer(&value[0])), // out uint8 + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return value, nil +} diff --git a/windows/storage/streams/idatawriter.go b/windows/storage/streams/idatawriter.go new file mode 100644 index 0000000..8ba597d --- /dev/null +++ b/windows/storage/streams/idatawriter.go @@ -0,0 +1,86 @@ +// Code generated by winrt-go-gen. DO NOT EDIT. + +//go:build windows + +//nolint:all +package streams + +import ( + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const GUIDIDataWriter string = "64b89265-d341-4922-b38a-dd4af8808c4e" +const SignatureIDataWriter string = "{64b89265-d341-4922-b38a-dd4af8808c4e}" + +type IDataWriter struct { + ole.IInspectable +} + +type IDataWriterVtbl struct { + ole.IInspectableVtbl + + GetUnstoredBufferLength uintptr + GetUnicodeEncoding uintptr + SetUnicodeEncoding uintptr + GetByteOrder uintptr + SetByteOrder uintptr + WriteByte uintptr + WriteBytes uintptr + WriteBuffer uintptr + WriteBufferRange uintptr + WriteBoolean uintptr + WriteGuid uintptr + WriteInt16 uintptr + WriteInt32 uintptr + WriteInt64 uintptr + WriteUInt16 uintptr + WriteUInt32 uintptr + WriteUInt64 uintptr + WriteSingle uintptr + WriteDouble uintptr + WriteDateTime uintptr + WriteTimeSpan uintptr + WriteString uintptr + MeasureString uintptr + StoreAsync uintptr + FlushAsync uintptr + DetachBuffer uintptr + DetachStream uintptr +} + +func (v *IDataWriter) VTable() *IDataWriterVtbl { + return (*IDataWriterVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IDataWriter) WriteBytes(valueSize uint32, value []uint8) error { + hr, _, _ := syscall.SyscallN( + v.VTable().WriteBytes, + uintptr(unsafe.Pointer(v)), // this + uintptr(valueSize), // in uint32 + uintptr(unsafe.Pointer(&value[0])), // in uint8 + ) + + if hr != 0 { + return ole.NewError(hr) + } + + return nil +} + +func (v *IDataWriter) DetachBuffer() (*IBuffer, error) { + var out *IBuffer + hr, _, _ := syscall.SyscallN( + v.VTable().DetachBuffer, + uintptr(unsafe.Pointer(v)), // this + uintptr(unsafe.Pointer(&out)), // out IBuffer + ) + + if hr != 0 { + return nil, ole.NewError(hr) + } + + return out, nil +} diff --git a/winrt.go b/winrt.go new file mode 100644 index 0000000..7ef0efc --- /dev/null +++ b/winrt.go @@ -0,0 +1,76 @@ +package winrt + +// common +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.IClosable +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.IAsyncOperation`1 +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.AsyncOperationCompletedHandler`1 +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.AsyncStatus +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.DateTime +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.Deferral +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.DeferralCompletedHandler +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.IReference`1 + +// advertisement +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcherStatus +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher -method-filter add_Received -method-filter remove_Received -method-filter add_Stopped -method-filter remove_Stopped -method-filter Start -method-filter Stop -method-filter get_Status -method-filter get_AllowExtendedAdvertisements -method-filter put_AllowExtendedAdvertisements -method-filter get_ScanningMode -method-filter put_ScanningMode -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementReceivedEventArgs -method-filter get_RawSignalStrengthInDBm -method-filter get_BluetoothAddress -method-filter get_Advertisement -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcherStoppedEventArgs +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEManufacturerData +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisement -method-filter get_LocalName -method-filter put_LocalName -method-filter get_ServiceUuids -method-filter get_ManufacturerData -method-filter get_DataSections -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementDataSection -method-filter get_DataType -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementPublisher -method-filter get_Advertisement -method-filter Start -method-filter Stop -method-filter get_Status -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementPublisherStatus +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.Advertisement.BluetoothLEScanningMode + +// bluetooth +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.BluetoothLEDevice -method-filter FromBluetoothAddressAsync -method-filter FromBluetoothAddressWithBluetoothAddressTypeAsync -method-filter Close -method-filter get_ConnectionStatus -method-filter add_ConnectionStatusChanged -method-filter remove_ConnectionStatusChanged -method-filter get_BluetoothDeviceId -method-filter GetGattServicesWithCacheModeAsync -method-filter GetGattServicesAsync -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.BluetoothConnectionStatus +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.BluetoothAddressType +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.BluetoothDeviceId -method-filter !FromId +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.BluetoothCacheMode +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.BluetoothError + +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattSession -method-filter FromDeviceIdAsync -method-filter get_MaintainConnection -method-filter put_MaintainConnection -method-filter get_CanMaintainConnection -method-filter Close -method-filter get_MaxPduSize -method-filter add_MaxPduSizeChanged -method-filter remove_MaxPduSizeChanged -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceServicesResult -method-filter !get_ProtocolError +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceService -method-filter get_Uuid -method-filter Close -method-filter GetCharacteristicsAsync -method-filter GetCharacteristicsWithCacheModeAsync -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristicsResult -method-filter !get_ProtocolError +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristic -method-filter get_Uuid -method-filter get_CharacteristicProperties -method-filter WriteValueWithOptionAsync -method-filter WriteValueAsync -method-filter ReadValueWithCacheModeAsync -method-filter ReadValueAsync -method-filter WriteClientCharacteristicConfigurationDescriptorAsync -method-filter add_ValueChanged -method-filter remove_ValueChanged -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristicProperties +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteOption +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadResult -method-filter !get_ProtocolError +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattClientCharacteristicConfigurationDescriptorValue +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattValueChangedEventArgs +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattClientNotificationResult +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristic +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristicParameters +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristicResult +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalDescriptorParameters +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalService +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattProtectionLevel +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadRequest +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadRequestedEventArgs +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattRequestState +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProvider +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProviderAdvertisementStatus +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProviderAdvertisingParameters +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProviderResult +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattSubscribedClient +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteRequest +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteRequestedEventArgs + +// event +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.TypedEventHandler`2 +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.EventRegistrationToken + +// buffer +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Storage.Streams.IBuffer +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Storage.Streams.Buffer -method-filter !CreateCopyFromMemoryBuffer -method-filter !CreateMemoryBufferOverIBuffer +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Storage.Streams.IDataReader -method-filter ReadBytes -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Storage.Streams.DataReader -method-filter FromBuffer -method-filter ReadBytes -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Storage.Streams.IDataWriter -method-filter WriteBytes -method-filter DetachBuffer -method-filter !* +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Storage.Streams.DataWriter -method-filter WriteBytes -method-filter DetachBuffer -method-filter DataWriter -method-filter Close -method-filter !* + +// vector +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.Collections.IVector`1 +//go:generate go run github.com/saltosystems/winrt-go/cmd/winrt-go-gen -debug -class Windows.Foundation.Collections.IVectorView`1