From 679f3e55b6dc9384fc581b963f7f93632a388ff9 Mon Sep 17 00:00:00 2001 From: "goutham.r" Date: Tue, 4 Aug 2026 16:00:45 +0530 Subject: [PATCH 1/3] fix(generator): fix the generator, not its output The committed pkg/webview2 is not the output of the committed generator. Defects here have been fixed by sweeping the 306 generated files -- "fix: com error handling" and "fix: mischanged error values" between them touched 800+ call sites -- and never the templates that produce them, so every regeneration silently reverts every fix. Regenerating from the pinned IDL to check brings back 170 changed files. Nine families, all sharing the failure mode that is why none was caught by review: the wrong code compiles, links, runs and returns S_OK. Counts are call sites in WebView2.1.0.2903.40. 1. Vtable inheritance, 88 interfaces. A COM vtable is flat: a derived interface's vtable begins with its ENTIRE base chain, then its own methods. Every derived vtable was generated as IUnknownVtbl plus that interface's own methods, so each method sat too early by however many the chain above it declares. ICoreWebView2_14.AddServerCertificateErrorDetected dispatched at slot 4 -- ICoreWebView2::get_Settings -- instead of 107. get_Settings has one out-parameter, so it wrote the Settings pointer over the caller's event-handler struct and returned S_OK: registration "succeeded", registered nothing, and the event never fired. The IDL states every base and the parser already captured it; it was simply never used. Base-interface calls were always correct, which is why Navigate and AddNavigationCompleted worked throughout and hid this. 2. By-value in-parameters, ~166 sites. The type switch compared p.Type -- the IDL type, "BOOL", "INT32", "double" -- against Go type names in lower case, so it matched almost nothing and every by-value argument fell through to the &address catch-all, making the callee read a pointer as an integer. Includes all 61 remove_* event tokens: EventRegistrationToken is struct{int64}, so each passed the ADDRESS of the token it was meant to match, and no event handler could ever be removed -- remove_ still returned S_OK. The Win32 x64 rule is not "aggregates go by reference": an aggregate of exactly 1, 2, 4 or 8 bytes is passed in a register AS an integer of that width, and only the rest by address. So POINT (8) and RECT (16) take opposite forms, which is how one &address default came to look plausible. maps.go now classifies each type, and the generator fails on a type it has not been told about rather than guessing -- guessing is what produced all of the above. 3. String out-parameters, 109 sites. LPWSTR out-params are declared LPWSTR*: the callee writes a string pointer into storage we own, so it needs the address of our local *uint16. Passing the local's nil value gave the callee a null to write through, so every string getter returned "" with S_OK. 4. QueryInterface accessors, 56 of 82. QueryInterface asks an OBJECT for another of its interfaces, so an accessor belongs on an interface of the object that can answer -- which the declared chain's ROOT names. All were emitted on ICoreWebView2. For the ICoreWebView2_N chain that is right, since it is one object and a caller should not walk thirteen accessors to reach _14. For every other chain it is useless: GetICoreWebView2Controller2 hung off ICoreWebView2, a different object, so it could only fail, while ICoreWebView2Controller had no accessor at all. The 26 on ICoreWebView2 stay, so no existing caller breaks. 5. ComProc.Call's Errno returned as error. Call's third result is a syscall.Errno that is NON-NIL on success ("The operation completed successfully"), so every successful call looked like a failure. HRESULT is the status and is already checked. That sweep also over-applied in two places, replacing UTF16PtrFromString's genuine error with nil in GetHeader. IUnknown::Release's refcount was discarded the same way, so CallRelease returns uint32. 6. Float in-parameters, 12 methods. Each passed the ADDRESS of a Go float64 where the callee reads a register, so a zoom factor arrived as a denormal or ~1e-300. runtime/sys_windows_amd64.s copies each of the first four argument slots into the matching XMM register, with a comment saying it does so precisely "in case any of the arguments are floating point values" -- so the bit pattern IS the argument and math.Float64bits produces it. windows/arm64 remains unsolved: sys_windows_arm64.s loads R0-R7 and never V0-V7, carrying a TODO to do what amd64 does. Passing bits in an integer register is no worse there than passing a pointer was, so this is a strict improvement on both. 7. 32-bit out-parameters, 7 sites. INT/UINT mapped to Go's 64-bit int/uint, and lowercase "int" -- the IDL's spelling for six of the seven -- was absent from the map entirely. A 4-byte write into an 8-byte zeroed local never sign-extends, so GetExitCode returned 3221225477 for -1073741819 (STATUS_ACCESS_VIOLATION), and GetKeyEventLParam is wrong on every key-up because WM_KEYUP sets lParam bit 31. 8. Struct field widths. A struct field's BOOL is 4 bytes and was generated as Go's 1-byte bool, making COREWEBVIEW2_PHYSICAL_KEY_STATUS 12 bytes against a native 24. Its only use is GetPhysicalKeyStatus, which hands WebView2 the address of that local -- so every call wrote 12 bytes past the end of a heap object, and the last three flags, at native offsets 12/16/20, were read from padding and so were permanently false. Struct fields now have their own type map: a parameter's BOOL is converted at the boundary, so Go's bool is a free kindness there, but a struct field has no boundary and its width is load-bearing. 9. Callback parameter widths, 3 sites. syscall.NewCallback rejects any argument wider than a uintptr, and it does so when the callback is CONSTRUCTED -- which happens in a package-level var initialiser. Three CompletedHandlers declared their LPCWSTR result as a Go string (a 16-byte header), so merely importing pkg/webview2 panicked before main() whether or not the program used them: "compileCallback: argument size is larger than uintptr". This is #36. Two more, found while checking the above: an enumerator with no initialiser is PREVIOUS + 1 in C, not its ordinal position ("A = 5, B" produced 1, not 6 -- values are computed numerically now, so output for every shipped enum is unchanged); and Release was generated for no interface while AddRef was generated for all 252, so every accessor call leaked a reference with nothing to call. Tooling, because none of this was checkable before: scripts/regen regenerate from a pinned IDL into a chosen directory and diff it. update_version_mapping.go only regenerates as a side effect of finding a NEW version upstream, needs the network, and rewrites the tree in place -- which is why the drift went unnoticed. gofmt in the generator the committed tree is gofmt-clean while the generator wrote raw template output, so someone was formatting 306 files by hand after every regeneration. ~180 of them differed from a fresh generation by import order alone: enough noise to hide a real change in a regeneration diff, which is how hand-patched output survived. Its error path also turns a template that emits invalid Go into a named failure. go test -update the goldens were refreshed by uncommenting an os.WriteFile loop in seven files, which is enough friction to make hand-editing output look like the cheaper fix. Also: errors are returned rather than log.Fatalf, because Fatalf calls os.Exit and this code runs inside the generator's own tests -- a reintroduced bug killed the test binary mid-run, with no attributable failure and every later test silently never running. And Taskfile.yml's manual gofmt over pkg/webview2 is gone. Deliberately not fixed: array-valued parameters have no representation at all (GetAllowedOrigins returns *string for an LPWSTR** array, so dereferencing it is an unbounded read). Fixing that needs a slice concept and an ownership decision, which is an API call rather than a marshalling one -- arguably those four methods should not be emitted until then. --- Taskfile.yml | 7 - scripts/generator/enum_test.go | 37 ++ scripts/generator/interface_bool_test.go | 6 +- scripts/generator/interface_enum_test.go | 6 +- scripts/generator/interface_int_test.go | 4 + scripts/generator/interface_pointers_test.go | 4 + .../interface_string_pointer_test.go | 6 +- scripts/generator/interface_string_test.go | 6 +- scripts/generator/invariants_test.go | 428 ++++++++++++++++++ .../COREWEBVIEW2_KEY_EVENT_KIND.go.txt | 6 +- ...COREWEBVIEW2_PREFERRED_COLOR_SCHEME.go.txt | 4 +- ...OREWEBVIEW2_PREFERRED_COLOR_SCHEME1.go.txt | 4 +- ...OREWEBVIEW2_PREFERRED_COLOR_SCHEME2.go.txt | 4 +- .../generator/testfiles/ICoreWebView2.go.txt | 27 +- ...View2AcceleratorKeyPressedEventArgs.go.txt | 21 +- ...oreWebView2CustomSchemeRegistration.go.txt | 23 +- .../testfiles/ICoreWebView2FrameInfo.go.txt | 33 +- ...CoreWebView2ProcessFailedEventArgs2.go.txt | 39 +- .../testfiles/ICoreWebView2_3.go.txt | 35 +- scripts/generator/types/enum.go | 48 +- scripts/generator/types/idl.go | 52 ++- scripts/generator/types/interface.go | 116 ++++- scripts/generator/types/maps.go | 71 ++- scripts/generator/types/param.go | 160 ++++++- scripts/generator/types/struct.go | 20 + scripts/generator/types/templates/com.tmpl | 31 +- .../types/templates/interfaceInvoke.tmpl | 9 +- .../types/templates/interfaceMethod.tmpl | 7 +- .../types/templates/interfacevtbl.tmpl | 62 ++- scripts/regen/main.go | 66 +++ 30 files changed, 1217 insertions(+), 125 deletions(-) create mode 100644 scripts/generator/invariants_test.go create mode 100644 scripts/regen/main.go diff --git a/Taskfile.yml b/Taskfile.yml index ec53990..ffeea8d 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -9,11 +9,6 @@ tasks: - git add . - git commit -m "Updated mappings" - gofmt: - dir: pkg/webview2 - cmds: - - go fmt - test: cmds: - go test ./... @@ -22,7 +17,6 @@ tasks: dir: scripts cmds: - go run update_version_mapping.go - - task: gofmt - go fmt update_version_mapping.go - task: test - task: commit @@ -31,7 +25,6 @@ tasks: dir: scripts cmds: - go run update_version_mapping.go -forced - - task: gofmt - go fmt update_version_mapping.go - task: test - task: commit diff --git a/scripts/generator/enum_test.go b/scripts/generator/enum_test.go index ce9aa84..4e21516 100644 --- a/scripts/generator/enum_test.go +++ b/scripts/generator/enum_test.go @@ -4,8 +4,11 @@ import ( "bytes" "embed" _ "embed" + "flag" "github.com/matryer/is" "github.com/stretchr/testify/require" + "os" + "path/filepath" "strings" "testing" "updater/generator/types" @@ -22,6 +25,36 @@ func testfile(path string) *bytes.Buffer { return bytes.NewBuffer(f) } +// update rewrites the goldens in testfiles/ from the generator's current output: +// +// go test ./generator -update # then review the diff, then run without -update +// +// The goldens are the only executable record of what the templates are supposed to produce, so a +// template change is not finished until they are regenerated and the diff read. Every test used to +// carry this as a commented-out os.WriteFile loop, which made regenerating them an edit-run-revert +// cycle across seven files -- enough friction that fixing generated output by hand looks like the +// cheaper option. It is not: the next regeneration silently reverts it. +var update = flag.Bool("update", false, "rewrite testfiles/ goldens from generator output") + +// updateGoldens writes each generated file as its golden when -update is set, and reports whether +// it did. Callers return immediately if so: the goldens are embedded at compile time, so the +// assertions in the same run would still be comparing against the previous build's copies. +// Call it after the com.go strip, or com.go acquires a golden no test asserts on. +func updateGoldens(t *testing.T, files []*types.GeneratedFile) bool { + t.Helper() + if !*update { + return false + } + for _, f := range files { + name := filepath.Join("testfiles", f.FileName+".txt") + if err := os.WriteFile(name, f.Content.Bytes(), 0o644); err != nil { + t.Fatal(err) + } + t.Logf("updated %s", name) + } + return true +} + func makeOutput(input string) *bytes.Buffer { var buf bytes.Buffer // Normalise newlines @@ -94,6 +127,10 @@ func TestEnum(t *testing.T) { // Remove the `com.go` filename files = files[1:] + if updateGoldens(t, files) { + return + } + expected := []*types.GeneratedFile{ { FileName: "COREWEBVIEW2_PREFERRED_COLOR_SCHEME.go", diff --git a/scripts/generator/interface_bool_test.go b/scripts/generator/interface_bool_test.go index bd1407f..1144036 100644 --- a/scripts/generator/interface_bool_test.go +++ b/scripts/generator/interface_bool_test.go @@ -39,9 +39,9 @@ func TestInterfaceBool(t *testing.T) { // Remove the `com.go` filename files = files[1:] - //for _, file := range files { - // os.WriteFile("testfiles/"+file.FileName+".txt", file.Content.Bytes(), 0644) - //} + if updateGoldens(t, files) { + return + } expected := []*types.GeneratedFile{ { diff --git a/scripts/generator/interface_enum_test.go b/scripts/generator/interface_enum_test.go index 6aef8d1..383d48a 100644 --- a/scripts/generator/interface_enum_test.go +++ b/scripts/generator/interface_enum_test.go @@ -47,9 +47,9 @@ func TestInterfaceEnum(t *testing.T) { // Remove the `com.go` filename files = files[1:] - //for _, file := range files { - // os.WriteFile("testfiles/"+file.FileName+".txt", file.Content.Bytes(), 0644) - //} + if updateGoldens(t, files) { + return + } expected := []*types.GeneratedFile{ { diff --git a/scripts/generator/interface_int_test.go b/scripts/generator/interface_int_test.go index a9aa288..ab7b634 100644 --- a/scripts/generator/interface_int_test.go +++ b/scripts/generator/interface_int_test.go @@ -39,6 +39,10 @@ library WebView2 { // Remove the `com.go` filename files = files[1:] + if updateGoldens(t, files) { + return + } + expected := []*types.GeneratedFile{ { FileName: "ICoreWebView2ProcessFailedEventArgs2.go", diff --git a/scripts/generator/interface_pointers_test.go b/scripts/generator/interface_pointers_test.go index 013ff58..e2268e3 100644 --- a/scripts/generator/interface_pointers_test.go +++ b/scripts/generator/interface_pointers_test.go @@ -44,6 +44,10 @@ library WebView2 { // Remove the `com.go` filename files = files[1:] + if updateGoldens(t, files) { + return + } + expected := []*types.GeneratedFile{ { FileName: "ICoreWebView2.go", diff --git a/scripts/generator/interface_string_pointer_test.go b/scripts/generator/interface_string_pointer_test.go index f5d9d3b..d4b2ca4 100644 --- a/scripts/generator/interface_string_pointer_test.go +++ b/scripts/generator/interface_string_pointer_test.go @@ -41,9 +41,9 @@ library WebView2 { // Remove the `com.go` filename files = files[1:] - //for _, file := range files { - // os.WriteFile("testfiles/"+file.FileName+".txt", file.Content.Bytes(), 0644) - //} + if updateGoldens(t, files) { + return + } expected := []*types.GeneratedFile{ { diff --git a/scripts/generator/interface_string_test.go b/scripts/generator/interface_string_test.go index d10d178..b9e3a99 100644 --- a/scripts/generator/interface_string_test.go +++ b/scripts/generator/interface_string_test.go @@ -40,9 +40,9 @@ library WebView2 { // Remove the `com.go` filename files = files[1:] - //for _, file := range files { - // os.WriteFile("testfiles/"+file.FileName+".txt", file.Content.Bytes(), 0644) - //} + if updateGoldens(t, files) { + return + } expected := []*types.GeneratedFile{ { diff --git a/scripts/generator/invariants_test.go b/scripts/generator/invariants_test.go new file mode 100644 index 0000000..c287528 --- /dev/null +++ b/scripts/generator/invariants_test.go @@ -0,0 +1,428 @@ +package generator + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +// These are properties of the WHOLE generated binding, checked against the pinned IDL, rather than +// goldens for one interface. Each corresponds to a defect family that shipped for months, and the +// reason none was caught by review is the same in every case: the wrong output is valid Go that +// compiles, links and returns S_OK. A golden file records what one interface looked like on the day +// it was written; only a property says what must be true of all 300 of them. +// +// They also fail loudly if a template change is right for the interface a golden covers and wrong +// elsewhere -- which is the shape of every hand-patched fix in this package's history. + +// pinnedIDL reads the version from latest_version.txt rather than repeating it, because every +// older IDL is still in the tree: a hand-copied constant would keep passing against 2903.40 long +// after update_version_mapping.go moved the pin, and the tests would be asserting about output +// nobody ships. +func pinnedIDL(t *testing.T) string { + t.Helper() + version, err := os.ReadFile(filepath.Join("..", "latest_version.txt")) + require.NoError(t, err) + return "WebView2." + strings.TrimSpace(string(version)) + ".idl" +} + +func generateFromPinnedIDL(t *testing.T) map[string]string { + t.Helper() + data, err := os.ReadFile(filepath.Join("..", pinnedIDL(t))) + require.NoError(t, err) + files, err := ParseIDL(data) + require.NoError(t, err) + require.NotEmpty(t, files) + out := make(map[string]string, len(files)) + for _, f := range files { + out[f.FileName] = f.Content.String() + } + return out +} + +// interfaceBases returns each interface's declared base, straight from the IDL. The IDL is the only +// authority on this: the version-suffixed names invite inferring the chain from the numbering, and +// ICoreWebView2EnvironmentOptions2 through 8 are exactly where that inference is wrong -- each of +// those derives from IUnknown, not from its predecessor. +func interfaceBases(t *testing.T) map[string]string { + t.Helper() + data, err := os.ReadFile(filepath.Join("..", pinnedIDL(t))) + require.NoError(t, err) + idl, err := Parser.ParseBytes("", data) + require.NoError(t, err) + require.NoError(t, idl.Process()) + + bases := map[string]string{} + for _, lib := range idl.Libraries { + for _, d := range lib.Declarations { + if d.Interface != nil { + bases[d.Interface.Name] = d.Interface.BaseClass + } + } + } + require.NotEmpty(t, bases) + return bases +} + +// TestVtableEmbedsDeclaredBase is the regression test for the worst defect in this package's +// history, and it is a property rather than a slot-offset assertion on purpose. +// +// A COM vtable is flat: a derived interface's vtable begins with its ENTIRE base chain, then its own +// methods. Every derived vtable was generated as IUnknownVtbl plus its own methods, so each method +// sat too early by however many methods the chain above it declares, and a call landed on whichever +// unrelated function occupies that offset. ICoreWebView2_14's AddServerCertificateErrorDetected +// dispatched at slot 4 -- ICoreWebView2::get_Settings, which has one out-parameter and therefore +// wrote the Settings pointer over the caller's event-handler struct -- instead of slot 107. It +// returned S_OK, so registration "succeeded" and the event never fired. 88 interfaces were affected. +// +// Asserting embedding rather than computed offsets is deliberate: embedding the immediate base is +// sufficient by induction, and a test that recomputes the offsets would be asserting its own +// arithmetic against itself. +func TestVtableEmbedsDeclaredBase(t *testing.T) { + files := generateFromPinnedIDL(t) + bases := interfaceBases(t) + + checked := 0 + for name, base := range bases { + content, ok := files[name+".go"] + require.True(t, ok, "%s is declared but generated no file", name) + want := base + "Vtbl" + if base == "IUnknown" { + want = "IUnknownVtbl" + } + // The embedded field is the first line of the vtable struct. + decl := name + "Vtbl struct {\n\t" + idx := strings.Index(content, decl) + require.NotEqual(t, -1, idx, "%s has no vtable struct", name) + rest := content[idx+len(decl):] + got := rest[:strings.IndexByte(rest, '\n')] + require.Equal(t, want, got, + "%sVtbl must embed %s: the IDL declares %s : %s, and a vtable that omits an "+ + "intermediate interface's slots shifts every later method to the wrong offset", + name, want, name, base) + checked++ + } + // Exact, not a floor. A floor with two units of headroom would let one interface silently stop + // generating a file: the inner assertions are skipped for it and the count still clears the bar. + require.Equal(t, len(bases), checked, "every declared interface must have been checked") + require.NotZero(t, checked, "no interfaces were checked at all") +} + +// TestQueryInterfaceAccessorReceiver checks the other half of the same mistake, with the rule that +// actually applies: QueryInterface asks an OBJECT for another of its interfaces, so the accessor +// belongs on an interface of the object that can answer -- which the declared chain's ROOT names, +// not the immediate base. +// +// Every accessor was emitted on ICoreWebView2. For the ICoreWebView2_N chain that is correct, since +// it is all one object. For every other chain it is useless: GetICoreWebView2Controller2 hung off +// ICoreWebView2, a different object, so it could only fail, while ICoreWebView2Controller had no +// accessor at all. 56 accessors were misrooted; the 26 on ICoreWebView2 stay put, so no existing +// caller breaks. +// +// Interfaces whose base is IUnknown keep the ICoreWebView2 receiver they ship with -- there is no +// sibling interface to reach them from, and re-rooting them onto IUnknown would move ~170 methods +// onto it and delete accessors that already ship. That is an API break, not a bug fix. +func TestQueryInterfaceAccessorReceiver(t *testing.T) { + files := generateFromPinnedIDL(t) + bases := interfaceBases(t) + + // root walks the declared chain to the ancestor whose own base is IUnknown. The seen-set is not + // pedantry: production code grew the same guard, and without it a cyclic IDL would hang this + // test instead of failing it. + root := func(name string) string { + out := "" + seen := map[string]bool{name: true} + for { + base, ok := bases[name] + if !ok || base == "IUnknown" { + return out + } + require.False(t, seen[base], "inheritance cycle at %s", base) + seen[base] = true + out, name = base, base + } + } + + // An accessor is generated exactly when the IDL base is not IUnknown -- interfacevtbl.tmpl + // guards on BaseClass, which generateVtbl blanks for IUnknown. Deriving the expected count from + // that rule, rather than from a magic floor, is what makes a silently-missing accessor fail. + wantAccessors := 0 + for _, base := range bases { + if base != "IUnknown" { + wantAccessors++ + } + } + + checked, rerooted := 0, 0 + for name, base := range bases { + content, ok := files[name+".go"] + require.True(t, ok, "%s is declared but generated no file", name) + if base == "IUnknown" { + require.NotContains(t, content, fmt.Sprintf(") Get%s() *%s {", name, name), + "%s derives from IUnknown, so no accessor should be generated for it", name) + continue + } + receiver := root(name) + if receiver == "" { + receiver = "ICoreWebView2" // base is IUnknown; see above + } + require.Contains(t, content, + fmt.Sprintf("func (i *%s) Get%s() *%s {", receiver, name, name), + "Get%s must be a method on %s, the object a caller can QueryInterface from", name, receiver) + if receiver != "ICoreWebView2" { + rerooted++ + } + checked++ + } + require.Equal(t, wantAccessors, checked, + "every interface with a non-IUnknown base must have an accessor") + require.NotZero(t, rerooted, + "expected the Controller/Environment/Profile/Settings/Frame chains to root on their own object") +} + +var invokeSignature = regexp.MustCompile(`(?m)^func \w+Invoke\(this \*\w+(?:, ([^)]*))?\) uintptr \{`) + +// TestCallbackParamsFitInAUintptr is the regression test for the family PR #36 patched in the +// output. A callback reached through syscall.NewCallback may not declare a parameter wider than a +// uintptr, and NewCallback checks this at CALLBACK CONSTRUCTION time -- which happens in a +// package-level var initialiser, so a violation panics during package init for any program that +// merely imports pkg/webview2, used or not: +// +// panic: compileCallback: argument size is larger than uintptr +// +// A Go string is a 16-byte header, and three CompletedHandlers declared their LPCWSTR result as one. +// That makes this property the difference between the package being importable and not, which is +// also why it is worth a test rather than trusting three goldens. +func TestCallbackParamsFitInAUintptr(t *testing.T) { + files := generateFromPinnedIDL(t) + + checked := 0 + for fileName, content := range files { + for _, m := range invokeSignature.FindAllStringSubmatch(content, -1) { + if m[1] == "" { + continue + } + for _, param := range strings.Split(m[1], ",") { + fields := strings.Fields(strings.TrimSpace(param)) + require.Len(t, fields, 2, "unexpected parameter %q in %s", param, fileName) + typ := fields[1] + require.NotEqual(t, "string", typ, + "%s: callback parameter %q is a Go string (16 bytes); LPCWSTR arrives as a "+ + "pointer, so it must be declared *uint16 or syscall.NewCallback rejects "+ + "the whole vtable at init", fileName, fields[0]) + // NewCallback rejects floats outright, with its own panic + // ("compileCallback: float arguments not supported"), so they fail at init exactly + // as an oversized argument does. + require.NotContains(t, []string{"float32", "float64"}, typ, + "%s: callback parameter %q is a float; syscall.NewCallback refuses to build "+ + "the callback at all", fileName, fields[0]) + // Anything wider than a register fails the same way, not just a string. These two + // are the aggregates maps.go classifies as too wide to pass in one -- keep the + // lists together if either changes. + for _, wide := range []string{"RECT", "COREWEBVIEW2_PHYSICAL_KEY_STATUS"} { + require.NotEqual(t, wide, typ, + "%s: callback parameter %q is a %s, which exceeds a register; "+ + "syscall.NewCallback rejects the whole vtable at init", + fileName, fields[0], wide) + } + require.False(t, strings.HasPrefix(typ, "[]") || strings.Contains(typ, "interface{"), + "%s: callback parameter %q has type %s, which is wider than a uintptr", + fileName, fields[0], typ) + } + checked++ + } + } + require.Greater(t, checked, 50, "expected the pinned IDL to yield many handler Invoke functions") +} + +// TestCallErrnoIsNeverReturnedAsError guards the fix that upstream applied to the generated output +// twice by hand and never to the template. ComProc.Call's third result is a syscall.Errno, which is +// non-nil on SUCCESS ("The operation completed successfully"), so binding it to err and returning it +// made every successful call look like a failure. HRESULT is the real status. +func TestCallErrnoIsNeverReturnedAsError(t *testing.T) { + files := generateFromPinnedIDL(t) + + for fileName, content := range files { + if fileName == "com.go" { + // com.tmpl's hand-written IStream.Read does bind err, and correctly: it compares + // against windows.ERROR_SUCCESS, which IS Errno(0), rather than against nil. + continue + } + require.NotContains(t, content, ", _, err := i.Vtbl.", + "%s binds ComProc.Call's Errno, which is non-nil on success", fileName) + } +} + +// TestByValueArgumentsAreNotPassedByAddress is table-driven over synthetic IDL rather than a +// property over the real one, because the wrong and right forms are distinguishable only if you know +// the parameter's type -- which the generated text alone does not tell you. +// +// The Windows x64 rule being pinned: an aggregate of exactly 1, 2, 4 or 8 bytes is passed IN A +// REGISTER as an integer of that width, anything else by address. So POINT (8 bytes) and RECT (16) +// take opposite forms, which is how a single &address default came to look plausible. +func TestByValueArgumentsAreNotPassedByAddress(t *testing.T) { + cases := []struct { + name string + param string + want string + }{ + {"BOOL in-param", "[in] BOOL value", "boolToUintptr(value),"}, + {"UINT32 in-param", "[in] UINT32 value", "uintptr(value),"}, + {"HWND is a uintptr typedef", "[in] HWND value", "uintptr(value),"}, + {"8-byte token goes in a register", "[in] EventRegistrationToken value", + "uintptr(*(*uint64)(unsafe.Pointer(&value))),"}, + {"8-byte POINT goes in a register", "[in] POINT value", + "uintptr(*(*uint64)(unsafe.Pointer(&value))),"}, + {"4-byte COLOR goes in a register", "[in] COREWEBVIEW2_COLOR value", + "uintptr(*(*uint32)(unsafe.Pointer(&value))),"}, + {"16-byte RECT is too wide, so by address", "[in] RECT value", + "uintptr(unsafe.Pointer(&value)),"}, + {"in-param pointer is already the address", "[in] ICoreWebView2Settings* value", + "uintptr(unsafe.Pointer(value)),"}, + {"out-param needs the address of our storage", "[out, retval] UINT32* value", + "uintptr(unsafe.Pointer(&value)),"}, + {"out-param string needs the address of our pointer", "[out, retval] LPWSTR* value", + "uintptr(unsafe.Pointer(&_value)),"}, + {"in-param string is already a *uint16", "[in] LPCWSTR value", + "uintptr(unsafe.Pointer(_value)),"}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + idl := fmt.Sprintf(` +[uuid(26d34152-879f-4065-bea2-3daa2cfadfb8), version(1.0)] +library WebView2 { +[uuid(A0D6DF20-3B92-416D-AA0C-437A9C727857), object, pointer_default(unique)] +interface ICoreWebView2Probe : IUnknown { + HRESULT Probe(%s); +} +}`, c.param) + + files, err := ParseIDL([]byte(idl)) + require.NoError(t, err) + + var content string + for _, f := range files { + if f.FileName == "ICoreWebView2Probe.go" { + content = f.Content.String() + } + } + require.NotEmpty(t, content, "probe interface was not generated") + require.Contains(t, content, c.want, + "wrong marshalling for %q.\ngenerated:\n%s", c.param, content) + }) + } +} + +// TestCommittedOutputMatchesGenerator is the invariant this whole generator-first arrangement +// exists to establish, and until now it was the one thing left to a human running diff -r. +// +// The committed pkg/webview2 was NOT the output of the committed generator: fixes had been applied +// to the 306 output files and never to the templates, so each regeneration silently reverted them. +// Nothing detected that, because nothing compared the two. This does. +// +// It replaces a test that asserted the output was gofmt-clean. That one could not fail for the +// reason it claimed: its input had already been through gofmtAll, so it was checking that +// formatting formatted content is a no-op. Deliberately mangling a template still left it green. +// gofmtAll's own error return is the real guard against a template emitting invalid Go. +func TestCommittedOutputMatchesGenerator(t *testing.T) { + const committed = "../../pkg/webview2" + if _, err := os.Stat(committed); err != nil { + t.Skipf("%s is absent; the scripts module stays independently testable", committed) + } + + generated := generateFromPinnedIDL(t) + + entries, err := os.ReadDir(committed) + require.NoError(t, err) + onDisk := map[string]bool{} + for _, e := range entries { + if e.IsDir() || !strings.HasSuffix(e.Name(), ".go") || strings.HasSuffix(e.Name(), "_test.go") { + continue + } + onDisk[e.Name()] = true + } + + for name, want := range generated { + require.True(t, onDisk[name], + "the generator produces %s but it is not committed; run the regeneration", name) + got, err := os.ReadFile(filepath.Join(committed, name)) + require.NoError(t, err) + require.Equal(t, want, string(got), + "committed %s differs from generator output -- it has been hand-edited, or the "+ + "regeneration was not run after a template change. Never fix generated output "+ + "directly: the next regeneration reverts it.", name) + } + for name := range onDisk { + require.Contains(t, generated, name, + "%s is committed but the generator does not produce it", name) + } +} + +// TestVtableDeclaresEveryDeclaredMethod is the other half of the slot-offset argument, and the half +// that was previously only asserted in a commit message. +// +// Embedding the base vtable is sufficient for correct offsets ONLY IF each interface also contributes +// exactly its own methods, in the IDL's order. COM guarantees declaration order is vtable order, so +// the remaining risk is a method going missing: if the parser ever dropped one -- a form it does not +// recognise, a grammar change -- every slot after the gap would shift, and the failure would look +// exactly like the bug this series fixed while every embedding assertion still passed. +// +// So count them. One embedded base, and one ComProc per declared method, for all 252 interfaces. +func TestVtableDeclaresEveryDeclaredMethod(t *testing.T) { + files := generateFromPinnedIDL(t) + + data, err := os.ReadFile(filepath.Join("..", pinnedIDL(t))) + require.NoError(t, err) + idl, err := Parser.ParseBytes("", data) + require.NoError(t, err) + require.NoError(t, idl.Process()) + + checked := 0 + for _, lib := range idl.Libraries { + for _, d := range lib.Declarations { + if d.Interface == nil { + continue + } + name := d.Interface.Name + content, ok := files[name+".go"] + require.True(t, ok, "%s is declared but generated no file", name) + + body := vtableBody(t, content, name) + procs, embeds := 0, 0 + for _, line := range strings.Split(body, "\n") { + switch line = strings.TrimSpace(line); { + case line == "": + case strings.HasSuffix(line, "ComProc"): + procs++ + case strings.HasSuffix(line, "Vtbl"): + embeds++ + } + } + require.Equal(t, len(d.Interface.Methods), procs, + "%s declares %d methods in the IDL but its vtable has %d slots; every slot after "+ + "the gap dispatches to the wrong function", + name, len(d.Interface.Methods), procs) + require.Equal(t, 1, embeds, "%s must embed exactly one base vtable", name) + checked++ + } + } + require.NotZero(t, checked) +} + +// vtableBody returns the field block of Vtbl. +func vtableBody(t *testing.T, content, name string) string { + t.Helper() + open := name + "Vtbl struct {" + i := strings.Index(content, open) + require.NotEqual(t, -1, i, "%s has no vtable struct", name) + rest := content[i+len(open):] + j := strings.Index(rest, "\n}") + require.NotEqual(t, -1, j, "%s's vtable struct is unterminated", name) + return rest[:j] +} diff --git a/scripts/generator/testfiles/COREWEBVIEW2_KEY_EVENT_KIND.go.txt b/scripts/generator/testfiles/COREWEBVIEW2_KEY_EVENT_KIND.go.txt index 2bd8bdd..838426b 100644 --- a/scripts/generator/testfiles/COREWEBVIEW2_KEY_EVENT_KIND.go.txt +++ b/scripts/generator/testfiles/COREWEBVIEW2_KEY_EVENT_KIND.go.txt @@ -5,8 +5,8 @@ package webview2 type COREWEBVIEW2_KEY_EVENT_KIND uint32 const ( - COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN = 0 - COREWEBVIEW2_KEY_EVENT_KIND_KEY_UP = 1 + COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN = 0 + COREWEBVIEW2_KEY_EVENT_KIND_KEY_UP = 1 COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_DOWN = 2 - COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_UP = 3 + COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_UP = 3 ) diff --git a/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME.go.txt b/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME.go.txt index d9c7d2d..7f602a6 100644 --- a/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME.go.txt +++ b/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME.go.txt @@ -5,7 +5,7 @@ package webview2 type COREWEBVIEW2_PREFERRED_COLOR_SCHEME uint32 const ( - COREWEBVIEW2_PREFERRED_COLOR_SCHEME_AUTO = 0 + COREWEBVIEW2_PREFERRED_COLOR_SCHEME_AUTO = 0 COREWEBVIEW2_PREFERRED_COLOR_SCHEME_LIGHT = 1 - COREWEBVIEW2_PREFERRED_COLOR_SCHEME_DARK = 2 + COREWEBVIEW2_PREFERRED_COLOR_SCHEME_DARK = 2 ) diff --git a/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME1.go.txt b/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME1.go.txt index c1fddae..9e84be4 100644 --- a/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME1.go.txt +++ b/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME1.go.txt @@ -5,7 +5,7 @@ package webview2 type COREWEBVIEW2_PREFERRED_COLOR_SCHEME1 uint32 const ( - COREWEBVIEW2_PREFERRED_COLOR_SCHEME_AUTO1 = 1 + COREWEBVIEW2_PREFERRED_COLOR_SCHEME_AUTO1 = 1 COREWEBVIEW2_PREFERRED_COLOR_SCHEME_LIGHT1 = 2 - COREWEBVIEW2_PREFERRED_COLOR_SCHEME_DARK1 = 3 + COREWEBVIEW2_PREFERRED_COLOR_SCHEME_DARK1 = 3 ) diff --git a/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME2.go.txt b/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME2.go.txt index 18475a6..0a1d1e2 100644 --- a/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME2.go.txt +++ b/scripts/generator/testfiles/COREWEBVIEW2_PREFERRED_COLOR_SCHEME2.go.txt @@ -5,7 +5,7 @@ package webview2 type COREWEBVIEW2_PREFERRED_COLOR_SCHEME2 uint32 const ( - COREWEBVIEW2_PREFERRED_COLOR_SCHEME_AUTO2 = 1 << 1 + COREWEBVIEW2_PREFERRED_COLOR_SCHEME_AUTO2 = 1 << 1 COREWEBVIEW2_PREFERRED_COLOR_SCHEME_LIGHT2 = 1 << 2 - COREWEBVIEW2_PREFERRED_COLOR_SCHEME_DARK2 = 1 << 3 + COREWEBVIEW2_PREFERRED_COLOR_SCHEME_DARK2 = 1 << 3 ) diff --git a/scripts/generator/testfiles/ICoreWebView2.go.txt b/scripts/generator/testfiles/ICoreWebView2.go.txt index da352fb..c3a5d90 100644 --- a/scripts/generator/testfiles/ICoreWebView2.go.txt +++ b/scripts/generator/testfiles/ICoreWebView2.go.txt @@ -1,16 +1,17 @@ //go:build windows package webview2 + import ( - "unsafe" - "syscall" "golang.org/x/sys/windows" + "syscall" + "unsafe" ) type ICoreWebView2Vtbl struct { IUnknownVtbl AddNavigationStarting ComProc - GetSettings ComProc + GetSettings ComProc } type ICoreWebView2 struct { @@ -22,12 +23,24 @@ func (i *ICoreWebView2) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} func (i *ICoreWebView2) AddNavigationStarting(eventHandler *ICoreWebView2NavigationStartingEventHandler) (EventRegistrationToken, error) { var token EventRegistrationToken - hr, _, err := i.Vtbl.AddNavigationStarting.Call( + hr, _, _ := i.Vtbl.AddNavigationStarting.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(eventHandler)), uintptr(unsafe.Pointer(&token)), @@ -35,19 +48,19 @@ func (i *ICoreWebView2) AddNavigationStarting(eventHandler *ICoreWebView2Navigat if windows.Handle(hr) != windows.S_OK { return EventRegistrationToken{}, syscall.Errno(hr) } - return token, err + return token, nil } func (i *ICoreWebView2) GetSettings() (*ICoreWebView2Settings, error) { var settings *ICoreWebView2Settings - hr, _, err := i.Vtbl.GetSettings.Call( + hr, _, _ := i.Vtbl.GetSettings.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&settings)), ) if windows.Handle(hr) != windows.S_OK { return nil, syscall.Errno(hr) } - return settings, err + return settings, nil } diff --git a/scripts/generator/testfiles/ICoreWebView2AcceleratorKeyPressedEventArgs.go.txt b/scripts/generator/testfiles/ICoreWebView2AcceleratorKeyPressedEventArgs.go.txt index 9e05d6f..d791e41 100644 --- a/scripts/generator/testfiles/ICoreWebView2AcceleratorKeyPressedEventArgs.go.txt +++ b/scripts/generator/testfiles/ICoreWebView2AcceleratorKeyPressedEventArgs.go.txt @@ -1,10 +1,11 @@ //go:build windows package webview2 + import ( - "unsafe" - "syscall" "golang.org/x/sys/windows" + "syscall" + "unsafe" ) type ICoreWebView2AcceleratorKeyPressedEventArgsVtbl struct { @@ -21,17 +22,29 @@ func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetKeyEventKind() (COREWEBVIEW2_KEY_EVENT_KIND, error) { var keyEventKind COREWEBVIEW2_KEY_EVENT_KIND - hr, _, err := i.Vtbl.GetKeyEventKind.Call( + hr, _, _ := i.Vtbl.GetKeyEventKind.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&keyEventKind)), ) if windows.Handle(hr) != windows.S_OK { return 0, syscall.Errno(hr) } - return keyEventKind, err + return keyEventKind, nil } diff --git a/scripts/generator/testfiles/ICoreWebView2CustomSchemeRegistration.go.txt b/scripts/generator/testfiles/ICoreWebView2CustomSchemeRegistration.go.txt index 5f84641..7bd96b0 100644 --- a/scripts/generator/testfiles/ICoreWebView2CustomSchemeRegistration.go.txt +++ b/scripts/generator/testfiles/ICoreWebView2CustomSchemeRegistration.go.txt @@ -1,10 +1,11 @@ //go:build windows package webview2 + import ( - "unsafe" - "syscall" "golang.org/x/sys/windows" + "syscall" + "unsafe" ) type ICoreWebView2CustomSchemeRegistrationVtbl struct { @@ -21,6 +22,18 @@ func (i *ICoreWebView2CustomSchemeRegistration) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2CustomSchemeRegistration) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} func (i *ICoreWebView2CustomSchemeRegistration) SetAllowedOrigins(allowedOriginsCount uint32, allowedOrigins string) error { @@ -30,13 +43,13 @@ func (i *ICoreWebView2CustomSchemeRegistration) SetAllowedOrigins(allowedOrigins return err } - hr, _, err := i.Vtbl.SetAllowedOrigins.Call( + hr, _, _ := i.Vtbl.SetAllowedOrigins.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&allowedOriginsCount)), + uintptr(allowedOriginsCount), uintptr(unsafe.Pointer(_allowedOrigins)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) } - return err + return nil } diff --git a/scripts/generator/testfiles/ICoreWebView2FrameInfo.go.txt b/scripts/generator/testfiles/ICoreWebView2FrameInfo.go.txt index 1d81a14..e86c923 100644 --- a/scripts/generator/testfiles/ICoreWebView2FrameInfo.go.txt +++ b/scripts/generator/testfiles/ICoreWebView2FrameInfo.go.txt @@ -1,15 +1,16 @@ //go:build windows package webview2 + import ( - "unsafe" - "syscall" "golang.org/x/sys/windows" + "syscall" + "unsafe" ) type ICoreWebView2FrameInfoVtbl struct { IUnknownVtbl - GetName ComProc + GetName ComProc GetSource ComProc } @@ -22,15 +23,26 @@ func (i *ICoreWebView2FrameInfo) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2FrameInfo) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} func (i *ICoreWebView2FrameInfo) GetName() (string, error) { // Create *uint16 to hold result var _name *uint16 - - hr, _, err := i.Vtbl.GetName.Call( + hr, _, _ := i.Vtbl.GetName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_name)), + uintptr(unsafe.Pointer(&_name)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -38,17 +50,16 @@ func (i *ICoreWebView2FrameInfo) GetName() (string, error) { // Get result and cleanup name := UTF16PtrToString(_name) CoTaskMemFree(unsafe.Pointer(_name)) - return name, err + return name, nil } func (i *ICoreWebView2FrameInfo) GetSource() (string, error) { // Create *uint16 to hold result var _source *uint16 - - hr, _, err := i.Vtbl.GetSource.Call( + hr, _, _ := i.Vtbl.GetSource.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_source)), + uintptr(unsafe.Pointer(&_source)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -56,5 +67,5 @@ func (i *ICoreWebView2FrameInfo) GetSource() (string, error) { // Get result and cleanup source := UTF16PtrToString(_source) CoTaskMemFree(unsafe.Pointer(_source)) - return source, err + return source, nil } diff --git a/scripts/generator/testfiles/ICoreWebView2ProcessFailedEventArgs2.go.txt b/scripts/generator/testfiles/ICoreWebView2ProcessFailedEventArgs2.go.txt index c16dd90..9fd4dde 100644 --- a/scripts/generator/testfiles/ICoreWebView2ProcessFailedEventArgs2.go.txt +++ b/scripts/generator/testfiles/ICoreWebView2ProcessFailedEventArgs2.go.txt @@ -1,14 +1,15 @@ //go:build windows package webview2 + import ( - "unsafe" - "syscall" "golang.org/x/sys/windows" + "syscall" + "unsafe" ) type ICoreWebView2ProcessFailedEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2ProcessFailedEventArgsVtbl GetExitCode ComProc } @@ -21,11 +22,30 @@ func (i *ICoreWebView2ProcessFailedEventArgs2) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ProcessFailedEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} -func (i *ICoreWebView2) GetICoreWebView2ProcessFailedEventArgs2() *ICoreWebView2ProcessFailedEventArgs2 { +func (i *ICoreWebView2ProcessFailedEventArgs) GetICoreWebView2ProcessFailedEventArgs2() *ICoreWebView2ProcessFailedEventArgs2 { var result *ICoreWebView2ProcessFailedEventArgs2 iidICoreWebView2ProcessFailedEventArgs2 := NewGUID("{4dab9422-46fa-4c3e-a5d2-41d2071d3680}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2ProcessFailedEventArgs2)), @@ -34,17 +54,16 @@ func (i *ICoreWebView2) GetICoreWebView2ProcessFailedEventArgs2() *ICoreWebView2 return result } +func (i *ICoreWebView2ProcessFailedEventArgs2) GetExitCode() (int32, error) { -func (i *ICoreWebView2ProcessFailedEventArgs2) GetExitCode() (int, error) { - - var exitCode int + var exitCode int32 - hr, _, err := i.Vtbl.GetExitCode.Call( + hr, _, _ := i.Vtbl.GetExitCode.Call( uintptr(unsafe.Pointer(i)), - uintptr(exitCode), + uintptr(unsafe.Pointer(&exitCode)), ) if windows.Handle(hr) != windows.S_OK { return 0, syscall.Errno(hr) } - return exitCode, err + return exitCode, nil } diff --git a/scripts/generator/testfiles/ICoreWebView2_3.go.txt b/scripts/generator/testfiles/ICoreWebView2_3.go.txt index e675790..3cec43a 100644 --- a/scripts/generator/testfiles/ICoreWebView2_3.go.txt +++ b/scripts/generator/testfiles/ICoreWebView2_3.go.txt @@ -1,14 +1,15 @@ //go:build windows package webview2 + import ( - "unsafe" - "syscall" "golang.org/x/sys/windows" + "syscall" + "unsafe" ) type ICoreWebView2_3Vtbl struct { - IUnknownVtbl + ICoreWebView2_2Vtbl GetIsSuspended ComProc } @@ -21,11 +22,30 @@ func (i *ICoreWebView2_3) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} -func (i *ICoreWebView2) GetICoreWebView2_3() *ICoreWebView2_3 { +func (i *ICoreWebView2_2) GetICoreWebView2_3() *ICoreWebView2_3 { var result *ICoreWebView2_3 iidICoreWebView2_3 := NewGUID("{A0D6DF20-3B92-416D-AA0C-437A9C727857}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_3)), @@ -34,12 +54,11 @@ func (i *ICoreWebView2) GetICoreWebView2_3() *ICoreWebView2_3 { return result } - func (i *ICoreWebView2_3) GetIsSuspended() (bool, error) { // Create int32 to hold bool result var _isSuspended int32 - hr, _, err := i.Vtbl.GetIsSuspended.Call( + hr, _, _ := i.Vtbl.GetIsSuspended.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&_isSuspended)), ) @@ -47,6 +66,6 @@ func (i *ICoreWebView2_3) GetIsSuspended() (bool, error) { return false, syscall.Errno(hr) } // Get result and cleanup - isSuspended := _isSuspended != 0 - return isSuspended, err + isSuspended := _isSuspended != 0 + return isSuspended, nil } diff --git a/scripts/generator/types/enum.go b/scripts/generator/types/enum.go index 2797c98..21c970f 100644 --- a/scripts/generator/types/enum.go +++ b/scripts/generator/types/enum.go @@ -4,6 +4,7 @@ import ( "io" "log" "strconv" + "strings" "text/template" ) @@ -31,18 +32,53 @@ func (e *EnumValueDecl) Process() { } } +// asInt evaluates the initialiser forms the grammar accepts -- a decimal or hex literal, with an +// optional "<< N" -- so that the NEXT enumerator can continue counting from it. Reports false for +// anything it cannot evaluate, which is not an error: the caller has a correct fallback. +func (e *EnumValueDecl) asInt() (int64, bool) { + text := strings.TrimSpace(e.Value) + shift := uint64(0) + if base, sh, found := strings.Cut(text, "<<"); found { + n, err := strconv.ParseUint(strings.TrimSpace(sh), 0, 8) + if err != nil { + return 0, false + } + text, shift = strings.TrimSpace(base), n + } + // ParseInt with base 0 takes both "5" and "0x4". + n, err := strconv.ParseInt(text, 0, 64) + if err != nil { + return 0, false + } + return n << shift, true +} + func (d *EnumDeclaration) Process(decl *Declaration) error { d.decl = decl + // An enumerator with no initialiser is PREVIOUS + 1 in C, not its ordinal position. Using the + // index gave the right answer only for an enum that sets no values at all, or sets them to + // their own positions -- which every shipped WebView2 enum happens to do, which is why this + // never showed. "A = 5, B" produced B = 1 rather than 6: a wrong constant that compiles and + // goes straight to WebView2. + prev, prevKnown := int64(-1), true for index, value := range d.Values { - if value.Value == nil { - value.Value = &EnumValueDecl{ - Value: strconv.Itoa(index), - } - } else { + if value.Value != nil { value.Value.Process() + prev, prevKnown = value.Value.asInt() + continue + } + switch { + case prevKnown: + prev++ + value.Value = &EnumValueDecl{Value: strconv.FormatInt(prev, 10)} + default: + // The previous initialiser was an expression this cannot evaluate. Naming the previous + // enumerator is still exact, because Go constant declarations allow it. + value.Value = &EnumValueDecl{Value: d.Values[index-1].Key + " + 1"} } } - decl.library.enums.Add(d.Name) + // The name is registered in Library.Process's pre-pass, before any interface is processed -- + // see the comment there. Registering it again here would be too late to be useful. return nil } diff --git a/scripts/generator/types/idl.go b/scripts/generator/types/idl.go index e1609c2..8415851 100644 --- a/scripts/generator/types/idl.go +++ b/scripts/generator/types/idl.go @@ -3,7 +3,9 @@ package types import ( "bytes" "errors" + "fmt" "github.com/leaanthony/slicer" + "go/format" "log" "strings" "text/template" @@ -31,10 +33,37 @@ func (i *IDL) Process() error { } func (i *IDL) Generate() ([]*GeneratedFile, error) { + // Accumulate across libraries rather than returning inside the loop. Every WebView2 IDL + // declares exactly one, so the old early return was never wrong -- it just read as a loop while + // behaving like an index, which is the kind of thing that stops being harmless quietly. + var all []*GeneratedFile for _, library := range i.Libraries { - return library.Generate() + files, err := library.Generate() + if err != nil { + return nil, err + } + all = append(all, files...) + } + return gofmtAll(all) +} + +// gofmtAll formats every generated file, which the generator did not previously do although the +// committed tree is gofmt-clean -- so somebody was formatting the output by hand afterwards. That +// left ~180 files differing from a fresh generation by nothing but import order and blank lines, +// which is enough noise to hide a real change in a regeneration diff, and hiding real changes in +// regeneration diffs is how this package accumulated hand-patched output in the first place. +// +// The error path is a second, unlooked-for benefit: a template that emits invalid Go now fails the +// generator by name instead of writing a file that only fails later at `go build`. +func gofmtAll(files []*GeneratedFile) ([]*GeneratedFile, error) { + for _, f := range files { + formatted, err := format.Source(f.Content.Bytes()) + if err != nil { + return nil, fmt.Errorf("generated %s is not valid Go: %w", f.FileName, err) + } + f.Content = bytes.NewBuffer(formatted) } - return nil, nil + return files, nil } type Import struct { @@ -54,10 +83,29 @@ type Library struct { forewardInterfaceDeclarations slicer.StringSlicer enums slicer.StringSlicer packageName string + interfaces map[string]*InterfaceDeclaration } func (l *Library) Process() error { l.packageName = strings.ToLower(l.Name) + // Index the interfaces AND the enums before processing any of them: resolving an inheritance + // chain needs every declaration to be findable by name, and nothing guarantees a base -- or an + // enum -- is declared first. + // + // The enums were previously registered as each one was processed, while Param.IsEnum() is + // consulted while processing an INTERFACE. An enum declared after the interface that uses it + // therefore looked like an unknown type, which used to mean a silently wrong &address and now + // means the generator stops with advice that does not apply. Microsoft's IDLs happen to put + // every enum first, which is the only reason this never fired. + l.interfaces = map[string]*InterfaceDeclaration{} + for _, declaration := range l.Declarations { + if declaration.Interface != nil { + l.interfaces[declaration.Interface.Name] = declaration.Interface + } + if declaration.Enum != nil { + l.enums.Add(declaration.Enum.Name) + } + } for _, declaration := range l.Declarations { err := declaration.Process(l) if err != nil { diff --git a/scripts/generator/types/interface.go b/scripts/generator/types/interface.go index a0d19c3..88048d7 100644 --- a/scripts/generator/types/interface.go +++ b/scripts/generator/types/interface.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "fmt" "github.com/leaanthony/slicer" "io" "log" @@ -31,8 +32,11 @@ func (d *InterfaceDeclaration) Process(decl *Declaration) error { return err } if string(method.Name) == "Invoke" { + // No break: a method declared AFTER Invoke would never be processed, and would then be + // emitted with an empty parameter list and no call arguments. Every shipped handler has + // Invoke alone, so this only ever saved a few iterations -- and since the generator now + // gofmts its output, such a file fails generation rather than being written out broken. d.InvokeMethod = method - break } } d.includes.AddUnique(`"unsafe"`) @@ -64,6 +68,10 @@ func (d *InterfaceDeclaration) Generate(packageName string, w io.Writer) error { } func (d *InterfaceDeclaration) generateVtbl(packageName string, w io.Writer) error { + rootInterface, err := d.RootInterface() + if err != nil { + return err + } data := struct { PackageName string Name string @@ -71,10 +79,15 @@ func (d *InterfaceDeclaration) generateVtbl(packageName string, w io.Writer) err HasInvokeMethod bool Includes []string BaseClass string + RootInterface string Header *InterfaceHeader }{ - PackageName: packageName, - BaseClass: d.BaseClass, + PackageName: packageName, + BaseClass: d.BaseClass, + // The vtable embeds the IMMEDIATE base, because that is what the memory layout is; the + // QueryInterface accessor hangs off the chain ROOT, because that is which object can + // answer it. Two different questions, so two fields. + RootInterface: rootInterface, Header: d.Header, Name: d.Name, Methods: d.Methods, @@ -95,6 +108,55 @@ func (d *InterfaceDeclaration) GetBaseClass() string { return d.BaseClass } +// RootInterface walks the declared inheritance chain to its first member -- the ancestor whose own +// base is IUnknown -- and returns "" if this interface IS that ancestor. +// +// This, not the immediate base, is where a QueryInterface accessor belongs, and the distinction is +// the whole of what makes those accessors either useful or useless. QueryInterface asks an OBJECT +// for another of its interfaces, so any interface on the same object can answer for any other. A +// chain like ICoreWebView2 -> _2 -> ... -> _27 is all one object, so ICoreWebView2 can hand out +// ICoreWebView2_14 directly and a caller need not walk thirteen accessors to reach it. +// +// What the chain root identifies is WHICH object. ICoreWebView2Controller2's root is +// ICoreWebView2Controller, a different object from the webview -- so the accessor emitted on +// ICoreWebView2 asked the wrong object and could only ever fail, while the controller, which can +// answer, had no accessor at all. Rooting on the chain start fixes exactly those and leaves the +// ICoreWebView2_N family where it already is, which is both correct and not an API break. +// +// An interface whose base is IUnknown returns "" here and gets no accessor at all -- see +// interfacevtbl.tmpl, whose guard is BaseClass rather than RootInterface. +func (d *InterfaceDeclaration) RootInterface() (string, error) { + root := "" + seen := map[string]bool{d.Name: true} + for cur := d; cur != nil && cur.BaseClass != "IUnknown"; { + root = cur.BaseClass + next := cur.decl.library.interfaces[cur.BaseClass] + if next == nil { + // A base this library does not declare ends the chain, and is deliberately NOT an + // error. com.tmpl hand-writes IUnknown, IStream and IDataObject precisely so that + // interfaces can derive from types no IDL declares; the IDL also carries forward + // declarations; and this generator's own test fixtures are single-interface fragments + // whose base is absent by construction. Rejecting the case breaks all three. + // + // The cost is that a base which really is missing surfaces as `undefined: Vtbl` + // when the CONSUMING package is built, rather than here where the cause is known. + // Telling "hand-written elsewhere" from "absent" would need a registry of what com.tmpl + // defines, which is a worse coupling than the deferred error. + break + } + if seen[next.Name] { + // A cyclic "A : B, B : A" would otherwise spin forever. The generator runs on whatever + // IDL Microsoft publishes next, and a hang is a worse failure than a wrong answer + // because there is nothing to read. + return "", fmt.Errorf("inheritance cycle reached %s while resolving the chain root "+ + "of %s", next.Name, d.Name) + } + seen[next.Name] = true + cur = next + } + return root, nil +} + func (d *InterfaceDeclaration) generateInvoke(w io.Writer) error { if d.InvokeMethod == nil { return nil @@ -182,12 +244,10 @@ func (m *InterfaceMethod) Process(decl *InterfaceDeclaration) error { if m.Prop != nil { m.ProcessedName = string(*m.Prop) + m.ProcessedName } - m.processParams() - - return nil + return m.processParams() } -func (m *InterfaceMethod) processParams() { +func (m *InterfaceMethod) processParams() error { for _, param := range m.Params { param.Process(m) if param.IsOutputParam() { @@ -197,23 +257,28 @@ func (m *InterfaceMethod) processParams() { } } - m.processInputParams() - m.processOutputParams() + if err := m.processInputParams(); err != nil { + return err + } + return m.processOutputParams() } -func (m *InterfaceMethod) processInputParams() { +func (m *InterfaceMethod) processInputParams() error { var inputs slicer.StringSlicer var inputParamNames slicer.StringSlicer for _, param := range m.inputParams { inputs.Add(param.Name + " " + param.AsInputType()) inputParamNames.Add(param.Name) - param.processSetup() + if err := param.processSetup(); err != nil { + return err + } } m.GoInputs = inputs.Join(", ") m.InputParamNames = inputParamNames.Join(", ") + return nil } -func (m *InterfaceMethod) processOutputParams() { +func (m *InterfaceMethod) processOutputParams() error { var outputs slicer.StringSlicer var outputParamNames slicer.StringSlicer var outputParamTypes slicer.StringSlicer @@ -221,7 +286,9 @@ func (m *InterfaceMethod) processOutputParams() { outputs.Add(param.Name + " " + param.GoType) outputParamNames.Add(param.Name) outputParamTypes.Add(param.GoType) - param.processSetup() + if err := param.processSetup(); err != nil { + return err + } } // Add the mandatory error outputs.Add("err error") @@ -234,6 +301,18 @@ func (m *InterfaceMethod) processOutputParams() { if outputParamTypes.Length() > 1 { m.GoReturnTypes = "(" + m.GoReturnTypes + ")" } + return nil +} + +// CallbackInputs is GoInputs for a callback: the same parameters, declared in the shape the +// Windows callback ABI actually delivers them in. Only interfaceInvoke.tmpl uses it. See +// Param.AsCallbackType. +func (m *InterfaceMethod) CallbackInputs() string { + var inputs slicer.StringSlicer + for _, param := range m.inputParams { + inputs.Add(param.Name + " " + param.AsCallbackType()) + } + return inputs.Join(", ") } func (m *InterfaceMethod) SetupCode() string { @@ -264,6 +343,9 @@ func (m *InterfaceMethod) ReturnsHRESULT() bool { return m.ReturnType == "HRESULT" } +// ErrorValues is the early return taken when converting a string input fails. It keeps +// "err" -- unlike the paths below -- because there the error is UTF16PtrFromString's, which +// is a real Go error, and it is in scope (inputStringSetup.tmpl binds it). func (m *InterfaceMethod) ErrorValues() string { var errorValues slicer.StringSlicer for _, outputParam := range m.outputParams { @@ -280,7 +362,9 @@ func (m *InterfaceMethod) ErrorValuesHRESULT() string { if m.ReturnsHRESULT() { errorValues.Add("syscall.Errno(hr)") } else { - errorValues.Add("err") + // Not "err": the Call's Errno is not bound any more (see interfaceMethod.tmpl), and + // a method with no HRESULT has no status to report. + errorValues.Add("nil") } return errorValues.Join(", ") } @@ -292,12 +376,14 @@ func (m *InterfaceMethod) GetHResultVariable() string { return "_" } +// SuccessValues is reached only after the HRESULT check passed, so the error is nil by +// construction. It used to be "err" -- the Call's Errno -- which is non-nil on success. func (m *InterfaceMethod) SuccessValues() string { var successValues slicer.StringSlicer for _, outputParam := range m.outputParams { successValues.Add(outputParam.GetReturnVariableName()) } - successValues.Add("err") + successValues.Add("nil") return successValues.Join(", ") } diff --git a/scripts/generator/types/maps.go b/scripts/generator/types/maps.go index fdb3912..4a68cd5 100644 --- a/scripts/generator/types/maps.go +++ b/scripts/generator/types/maps.go @@ -8,8 +8,18 @@ var idlTypeToGoType = map[string]string{ "HRESULT": "uintptr", "UINT64": "uint64", "UINT32": "uint32", - "UINT": "uint", - "INT": "int", + // Sized, not Go's int/uint. These appear as out-parameters, where the generated method + // declares a local of the mapped type and hands the callee its address -- and a 64-bit local + // receiving a 32-bit write keeps its zeroed high half, so the sign never extends. GetExitCode + // returned 3221225477 for an exit code of -1073741819. Seven out-parameters were affected, of + // which GetKeyEventLParam (bit 31 set on every key-up) and GetExitCode (negative NTSTATUS) are + // wrong for ordinary inputs rather than only extreme ones. + // + // Lowercase "int" is the spelling the IDL actually uses for six of the seven and was absent + // from this map entirely, so it fell through to Go's int by passthrough. + "UINT": "uint32", + "INT": "int32", + "int": "int32", "INT32": "int32", "INT64": "int64", "BOOL": "bool", @@ -25,3 +35,60 @@ func IdlTypeToGoType(input string) string { } return result } + +// byValueArgument gives, per IDL type, the expression that passes a BY-VALUE in-parameter of that +// type to ComProc.Call. %s is the variable name. Only types that are neither a mapped scalar nor +// an enum reach here: the handle typedefs and the aggregates. +// +// The rule being encoded is the Windows x64 calling convention's, and it is not "aggregates go by +// reference". An aggregate of exactly 1, 2, 4 or 8 bytes is passed IN A REGISTER as an integer of +// that width; anything else is passed by reference. So POINT (8) and COREWEBVIEW2_COLOR (4) are +// register-passed while RECT (16) is not, and a single rule cannot cover both -- which is how +// every one of these ended up as &address, the answer that is only ever right for the large ones. +// +// Reinterpreting the struct through a same-width integer copies its layout rather than re-deriving +// the field order by hand, and it is a plain read, so unlike &address it also has no +// unsafe.Pointer lifetime question. +// +// The 8-byte entries assume a 64-bit uintptr. On windows/386 they would truncate, because an 8-byte +// by-value aggregate occupies two stack slots there and cannot be one Call argument at all -- the +// same shape of limit as the floats. That assumption is not new: PutPerformanceCount already passes +// a uint64 as one uintptr, so the generated binding has always been 64-bit-only in practice. +var byValueArgument = map[string]string{ + // Register-sized aggregates. + "EventRegistrationToken": "uintptr(*(*uint64)(unsafe.Pointer(&%s)))", // struct{ value int64 } + "POINT": "uintptr(*(*uint64)(unsafe.Pointer(&%s)))", // struct{ X, Y int32 } + "COREWEBVIEW2_COLOR": "uintptr(*(*uint32)(unsafe.Pointer(&%s)))", // struct{ A, R, G, B byte } +} + +// uintptrTypedef lists the IDL types the binding declares as `type X uintptr` in com.tmpl. They are +// integers, so both questions this file answers have one obvious answer: pass the value, and use 0 +// as the zero value. +// +// Only HWND currently appears as a by-value parameter and only HANDLE, HWND and HCURSOR as +// out-parameters; the rest are listed because for a uintptr typedef there is exactly one right +// answer, so pre-classifying them is not the guessing that byRefAggregate exists to prevent. +// +// VARIANT is deliberately ABSENT even though com.tmpl declares it `type VARIANT uintptr`. A real +// VARIANT is a 16-byte tagged union, com.tmpl says so itself ("NOTE: For sure, this is wrong!"), and +// the IDL only ever uses VARIANT* -- so a by-value VARIANT should hit the generator's error and make +// someone look, not quietly become an integer. +var uintptrTypedef = map[string]bool{ + "HANDLE": true, + "HBRUSH": true, + "HCURSOR": true, + "HICON": true, + "HINSTANCE": true, + "HMENU": true, + "HMODULE": true, + "HWND": true, +} + +// byRefAggregate are the by-value in-parameter types that really are passed by address, with the +// width that makes them so. They are listed rather than left to a default so that a type in +// NEITHER table is a generator error instead of a silent guess -- the failure mode this entire +// family is made of. Adding a struct to the IDL should cost one line here and a look at its size. +var byRefAggregate = map[string]int{ + "RECT": 16, // struct{ Left, Top, Right, Bottom int32 } + "COREWEBVIEW2_PHYSICAL_KEY_STATUS": 24, // 2x UINT32 + 4x BOOL +} diff --git a/scripts/generator/types/param.go b/scripts/generator/types/param.go index 8075c81..2a7532c 100644 --- a/scripts/generator/types/param.go +++ b/scripts/generator/types/param.go @@ -1,6 +1,7 @@ package types import ( + "fmt" "io" "strings" ) @@ -71,10 +72,39 @@ func (p *Param) AsInputType() string { return p.GoType } -func (p *Param) processSetup() { +// AsCallbackType is the type an INBOUND parameter must be declared as, and is deliberately not +// AsInputType. An outbound call is free to take a Go string, because the generated method +// converts it with UTF16PtrFromString before it reaches the vtable. A callback has no such +// step: syscall.NewCallback hands the Go function the raw machine words WebView2 passed, so the +// declared type IS the ABI. LPCWSTR arrives as a pointer, hence *uint16. +// +// Declaring it "string" does not merely mis-marshal; it fails to load at all. Every handler +// vtable is built in a package-level var initialiser, so NewComProc -> syscall.NewCallback runs +// during package init, and NewCallback rejects any argument wider than a uintptr. A string +// header is 16 bytes on amd64, so importing pkg/webview2 panicked before main() -- whether or +// not the program ever used these three handlers: +// +// panic: compileCallback: argument size is larger than uintptr +// +// BOOL is left as Go's bool (ICoreWebView2PrintToPdf/TrySuspendCompletedHandler) although it is +// the same family. bool is 1 byte against a 4-byte BOOL, so the callee reads the low byte of the +// word -- correct for the 0/1 Win32 BOOL actually carries, and NewCallback accepts it because +// 1 <= sizeof(uintptr). Widening it to int32 would change those two Impl interfaces for every +// caller that implements them, to fix nothing observable. +func (p *Param) AsCallbackType() string { + if p.GoType == "string" { + // One star per level of IDL indirection, so LPCWSTR is *uint16 and LPCWSTR* is **uint16. + // Every string callback parameter in the pinned IDL is a plain LPCWSTR, but returning + // *uint16 regardless of depth would be its own silently-wrong answer if that changes. + return strings.Repeat("*", len(p.Pointer)) + "*uint16" + } + return p.AsInputType() +} + +func (p *Param) processSetup() error { p.processSetupInputs() p.processSetupOutputs() - p.processVtableCallInput() + return p.processVtableCallInput() } func (p *Param) SetupCode(w io.Writer) { @@ -101,20 +131,109 @@ func (p *Param) IsInputParam() bool { return !p.IsOutputParam() } -func (p *Param) processVtableCallInput() { +func (p *Param) processVtableCallInput() error { variableName := p.GetVariableName() - if strings.HasPrefix(p.Type, "int") || strings.HasPrefix(p.Type, "uint") || p.Type == "bool" || p.Type == "float32" || p.Type == "float64" { - p.VtableCallInput = "uintptr(" + variableName + ")" - return + + // This block used to test p.Type -- the IDL type, so "BOOL", "INT32", "double" -- against + // Go type names in lower case. It therefore never matched, and every by-value input + // parameter fell through to the &address catch-all at the bottom of this function, which + // makes the callee read a pointer as an integer. p.GoType is the mapped Go type and is + // what the comparisons meant. One wrong field name, and no scalar in-parameter in the + // whole binding was passed correctly. + if !p.isPointer() { + switch { + case p.GoType == "bool": + // A COM BOOL in-param is a 4-byte integer passed by value. uintptr(someBool) is + // not a legal Go conversion, hence the helper in com.tmpl. + p.VtableCallInput = "boolToUintptr(" + variableName + ")" + return nil + case strings.HasPrefix(p.GoType, "int"), strings.HasPrefix(p.GoType, "uint"): + p.VtableCallInput = "uintptr(" + variableName + ")" + return nil + } + // Handle typedefs and aggregates. See maps.go for the ABI rule and for why no single rule + // covers them: EventRegistrationToken alone is 61 call sites, and every remove_ method in + // the binding handed the callee the ADDRESS of the 8-byte token it was supposed to match, so + // no event handler could ever be removed -- and remove_ still returned S_OK. + if uintptrTypedef[p.Type] { + p.VtableCallInput = "uintptr(" + variableName + ")" + return nil + } + if expr, ok := byValueArgument[p.Type]; ok { + p.VtableCallInput = fmt.Sprintf(expr, variableName) + return nil + } + if _, ok := byRefAggregate[p.Type]; ok { + // Wider than a register, so here the address genuinely is the argument. + p.VtableCallInput = "uintptr(unsafe.Pointer(&" + variableName + "))" + return nil + } + // A double goes in XMM0-XMM3 for the first four arguments, and Go's amd64 syscall + // assembly copies each of those four argument slots into the matching XMM register + // specifically so that floats work (runtime/sys_windows_amd64.s, "Load first 4 args into + // correspondent registers ... in case any of the arguments are floating point values"). + // So the bit pattern IS the argument, and Float64bits produces it. + // + // An earlier version of this comment claimed no marshalling answer existed. That was + // wrong, and it was wrong about the scope too: 12 methods take a double in-parameter -- + // PutZoomFactor, PutRasterizationScale, PutScaleFactor, PutExpires, PutPageWidth/Height, + // the four PutMargin*, SetBoundsAndZoomFactor and ClearBrowsingDataInTimeRange -- and all + // of them were handing the callee the ADDRESS of a Go float reinterpreted as a double. + // + // windows/arm64 remains unsolved: sys_windows_arm64.s loads only R0-R7 and never V0-V7, + // carrying a TODO to do what amd64 does. Passing the bits in an integer register is no + // worse there than passing a pointer was, so this is a strict improvement on both. + if p.GoType == "float64" { + p.VtableCallInput = "uintptr(math.Float64bits(" + variableName + "))" + p.decl.decl.includes.AddUnique(`"math"`) + return nil + } + // float32 is left unclassified on purpose: no IDL declares one, and it would need + // Float32bits in the low half of the register rather than Float64bits. + // Strings and enums are classified further down (the LPCWSTR case and IsEnum), so those two + // are exempt rather than unclassified. + if p.GoType != "string" && !p.IsEnum() { + // Refuse to guess. Every defect in this family was the &address default landing on a + // type nobody had classified, and each one returned S_OK while corrupting exactly one + // argument. A new IDL type should cost one line in maps.go, not a silent wire bug. + // + // An error rather than log.Fatalf: log.Fatalf calls os.Exit, and this runs inside the + // generator's own tests, so a reintroduced bug killed the test binary mid-run -- no + // attributable failure, and every test after it silently never ran. + return fmt.Errorf("by-value in-parameter %q of type %q (%s.%s) is in neither "+ + "byValueArgument nor byRefAggregate in maps.go. Classify it: an aggregate of "+ + "1, 2, 4 or 8 bytes is passed in a register as an integer of that width; "+ + "anything else is passed by address", + variableName, p.Type, p.decl.decl.Name, p.decl.ProcessedName) + } } switch p.Type { case "LPCWSTR", "LPWSTR": - p.VtableCallInput = "uintptr(unsafe.Pointer(" + variableName + "))" - return + // Direction matters here and was not being distinguished. An OUT parameter is + // declared LPWSTR* : the callee writes a string pointer into storage we own, so it + // needs the ADDRESS of our local *uint16. Passing the local's (nil) value instead + // gave the callee a null to write through, so every string getter returned empty -- + // silently, since the HRESULT was S_OK. An IN parameter is already the *uint16 that + // UTF16PtrFromString produced and is passed as-is. + if p.IsOutputParam() { + p.VtableCallInput = "uintptr(unsafe.Pointer(&" + variableName + "))" + } else { + p.VtableCallInput = "uintptr(unsafe.Pointer(" + variableName + "))" + } + return nil } if p.Pointer == "**" { - p.VtableCallInput = "uintptr(unsafe.Pointer(&" + variableName + "))" - return + // Direction matters here for the same reason it does for "*" below, and this branch was + // the one left without the check. An IN parameter is already the T** the caller built, so + // taking its address hands the callee a T*** -- it then reads our local's own value as the + // first element and calls through it. ICoreWebView2Environment14.CreateObjectCollection is + // the live example, and it is a wild call rather than a wrong value. + if p.IsOutputParam() { + p.VtableCallInput = "uintptr(unsafe.Pointer(&" + variableName + "))" + } else { + p.VtableCallInput = "uintptr(unsafe.Pointer(" + variableName + "))" + } + return nil } if p.Pointer == "*" { if p.IsOutputParam() { @@ -122,13 +241,14 @@ func (p *Param) processVtableCallInput() { } else { p.VtableCallInput = "uintptr(unsafe.Pointer(" + variableName + "))" } - return + return nil } if p.IsEnum() { p.VtableCallInput = "uintptr(" + variableName + ")" - return + return nil } p.VtableCallInput = "uintptr(unsafe.Pointer(&" + variableName + "))" + return nil } func (p *Param) ClearLocalName() string { @@ -192,8 +312,20 @@ func (p *Param) processSetupOutputs() { func (p *Param) defaultErrorValue() string { switch true { + // A pointer's zero value is nil, and this has to be tested FIRST: every case below asks what + // kind of thing p is, and for *T the answer that matters is only that it is a pointer. + case p.OutputGoType[0] == '*': + return "nil" + // uintptrTypedef rather than the three of the eight that happen to appear as out-parameters + // today (HANDLE, HWND, HCURSOR). The default branch below returns GoType{} as the zero value, + // which for a uintptr typedef does not compile -- so an HICON out-parameter in some later IDL + // would have broken the build with nothing to point at. Same knowledge, one place. + // + // The p.GoType guard matters because uintptrTypedef is keyed on the IDL type, which carries no + // indirection: without it [out] HANDLE** returned the integer 0 for a *HANDLE, which does not + // compile. That was a regression against the p.GoType == "HANDLE" test this replaced. case p.IsEnum(), strings.HasPrefix(p.GoType, "uint"), strings.HasPrefix(p.GoType, "int"), - p.GoType == "HANDLE", p.GoType == "HWND", p.GoType == "HCURSOR": + uintptrTypedef[p.Type] && p.GoType == p.Type: return "0" case strings.HasPrefix(p.GoType, "float"): return "0.0" @@ -201,8 +333,6 @@ func (p *Param) defaultErrorValue() string { return "false" case p.GoType == "string": return `""` - case p.OutputGoType[0] == '*': - return "nil" default: return p.GoType + "{}" } diff --git a/scripts/generator/types/struct.go b/scripts/generator/types/struct.go index 592b6da..8d28aff 100644 --- a/scripts/generator/types/struct.go +++ b/scripts/generator/types/struct.go @@ -51,6 +51,26 @@ type StructField struct { GoType string } +// idlStructFieldToGoType is deliberately separate from IdlTypeToGoType, which is written for +// PARAMETERS. A parameter's BOOL is converted at the boundary, so mapping it to Go's bool is a +// kindness to callers and costs nothing. A struct FIELD has no boundary: the struct is a memory +// layout that the callee writes into directly, so every field must be the width the C declaration +// says it is. +// +// BOOL is a 4-byte int. Mapping it to Go's 1-byte bool made COREWEBVIEW2_PHYSICAL_KEY_STATUS 12 +// bytes against a native 24, and its only use is +// ICoreWebView2AcceleratorKeyPressedEventArgs.GetPhysicalKeyStatus, which hands WebView2 the +// address of that 12-byte local. So every call wrote 12 bytes past the end of a heap object -- and +// even the bytes that landed inside were misread, because the last three flags sat at native +// offsets 12/16/20 while Go looked for them at 9/10/11, making them permanently false. +var idlStructFieldToGoType = map[string]string{ + "BOOL": "int32", +} + func (s *StructField) Process() { + if goType, ok := idlStructFieldToGoType[s.Type]; ok { + s.GoType = goType + return + } s.GoType = IdlTypeToGoType(s.Type) } diff --git a/scripts/generator/types/templates/com.tmpl b/scripts/generator/types/templates/com.tmpl index d74edfa..d1c2e36 100644 --- a/scripts/generator/types/templates/com.tmpl +++ b/scripts/generator/types/templates/com.tmpl @@ -32,14 +32,18 @@ type IUnknownVtbl struct { Release ComProc } -func (i *IUnknownVtbl) CallRelease(this unsafe.Pointer) error { - _, _, err := i.Release.Call( +// CallRelease returns the new reference count, which is what IUnknown::Release returns. +// +// This used to return error, built from the Errno that LazyProc.Call yields -- which is +// non-nil on success, so `err != windows.ERROR_SUCCESS` was true for every successful +// Release and the refcount was thrown away. pkg/edge/com.go and the committed +// pkg/webview2/com.go both already carry this corrected form; only the template did not. +func (i *IUnknownVtbl) CallRelease(this unsafe.Pointer) uint32 { + ret, _, _ := i.Release.Call( uintptr(this), ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil + + return uint32(ret) } type IUnknownImpl interface { @@ -330,7 +334,7 @@ type IStream struct { Vtbl *IStreamVtbl } -func (i *IStream) Release() error { +func (i *IStream) Release() uint32 { return i.Vtbl.CallRelease(unsafe.Pointer(i)) } @@ -362,3 +366,16 @@ func (i *IStream) Read(p []byte) (int, error) { return 0, syscall.Errno(res) } } + +// boolToUintptr converts a Go bool to a Win32 BOOL passed by value. +// +// A COM in-parameter declared BOOL is a 4-byte integer passed BY VALUE. Handing over the +// address of a Go bool instead makes the callee read a pointer as an integer -- wrong, and +// wrong differently on each call. uintptr(b) is not a legal Go conversion, so the branch in +// Param.processVtableCallInput emits a call to this instead. +func boolToUintptr(b bool) uintptr { + if b { + return 1 + } + return 0 +} diff --git a/scripts/generator/types/templates/interfaceInvoke.tmpl b/scripts/generator/types/templates/interfaceInvoke.tmpl index 316f83a..fa1b30d 100644 --- a/scripts/generator/types/templates/interfaceInvoke.tmpl +++ b/scripts/generator/types/templates/interfaceInvoke.tmpl @@ -10,13 +10,18 @@ func {{.Declaration.Name}}IUnknownRelease(this *{{.Declaration.Name}}) uintptr { return this.impl.Release() } -func {{.Declaration.Name}}Invoke(this *{{.Declaration.Name}}, {{.InvokeMethod.GoInputs}}) uintptr { +{{/* CallbackInputs, not GoInputs: this function is the target of syscall.NewCallback, so its + parameters are whatever WebView2 left in the registers -- not the marshalled Go types an + outbound method is free to declare. GoInputs gave three handlers a "string" result parameter, + and because the vtable below is a package-level var, that made merely importing the package + panic during init on amd64. See Param.AsCallbackType. */ -}} +func {{.Declaration.Name}}Invoke(this *{{.Declaration.Name}}, {{.InvokeMethod.CallbackInputs}}) uintptr { return this.impl.{{.InvokeMethod.GoMethodName}}({{.InvokeMethod.InputParamNames}}) } type {{.Declaration.Name}}Impl interface { IUnknownImpl - {{.InvokeMethod.GoMethodName}}({{.InvokeMethod.GoInputs}}) uintptr + {{.InvokeMethod.GoMethodName}}({{.InvokeMethod.CallbackInputs}}) uintptr } var {{.Declaration.Name}}Fn = {{.Declaration.Name}}Vtbl{ diff --git a/scripts/generator/types/templates/interfaceMethod.tmpl b/scripts/generator/types/templates/interfaceMethod.tmpl index 23e36d8..aca6c2c 100644 --- a/scripts/generator/types/templates/interfaceMethod.tmpl +++ b/scripts/generator/types/templates/interfaceMethod.tmpl @@ -2,7 +2,12 @@ func (i *{{.Name}}) {{.Method.ProcessedName}}({{.Method.GoInputs}}) {{.Method.GoReturnTypes}} { {{ .Method.SetupCode}} - {{ .Method.GetHResultVariable }}, _, err := i.Vtbl.{{.Method.ProcessedName}}.Call( + {{/* The third return of syscall.LazyProc.Call is a syscall.Errno, which is NON-NIL even + on success ("The operation completed successfully"), so returning it made every + successful call look like a failure. HRESULT is the real status and is checked below. + Fixed across the generated tree by hand in "fix: com error handling" and "fix: + mischanged error values" but never here, so a regeneration reintroduced it. */}} + {{ .Method.GetHResultVariable }}, _, _ := i.Vtbl.{{.Method.ProcessedName}}.Call( uintptr(unsafe.Pointer(i)), {{ .Method.VtableCallInputs}} ) diff --git a/scripts/generator/types/templates/interfacevtbl.tmpl b/scripts/generator/types/templates/interfacevtbl.tmpl index 1926149..95b65f9 100644 --- a/scripts/generator/types/templates/interfacevtbl.tmpl +++ b/scripts/generator/types/templates/interfacevtbl.tmpl @@ -10,8 +10,24 @@ import ( ) {{- end}} +{{/* A COM vtable is FLAT: a derived interface's vtable begins with its entire base chain and + only then its own methods. Embedding IUnknownVtbl instead of the parent's vtable omitted + every intermediate interface's slots, so each method sat too early by however many + methods the chain above it declares, and a call landed on whichever unrelated method + occupies that offset. It cannot fail loudly -- the wrong slot holds a real function + pointer, so it runs and returns S_OK. + + The IDL always states a base ("interface ICoreWebView2_2 : ICoreWebView2") and the parser + already captures it as BaseClass; it was simply never used here. A first-generation + interface's base IS IUnknown, so one expression covers both cases. + + Concretely this moves ICoreWebView2_14's AddServerCertificateErrorDetected from slot 4 -- + ICoreWebView2::get_Settings, whose single out-parameter duly wrote the Settings pointer + over the caller's event-handler struct -- to its correct slot 107. 88 interfaces were + affected. Base-interface calls were always correct, which is why Navigate and + AddNavigationCompleted worked throughout and hid this for as long as they did. */}} type {{.Name}}Vtbl struct { - IUnknownVtbl + {{ if .BaseClass }}{{.BaseClass}}Vtbl{{ else }}IUnknownVtbl{{ end }} {{- range .Methods}} {{.ProcessedName}} ComProc {{- end}} @@ -28,12 +44,54 @@ func (i *{{.Name}}) AddRef() uintptr { refCounter, _, _ := i.Vtbl.AddRef.Call(uintptr(unsafe.Pointer(i))) return refCounter } +{{ if not .HasInvokeMethod }} +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *{{.Name}}) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} +{{ end }} + +{{/* The QueryInterface accessor belongs on an interface of the OBJECT that can answer it, and + the declared chain's ROOT is what names that object -- not the immediate base. See + InterfaceDeclaration.RootInterface. + + The receiver was hardcoded to ICoreWebView2. For the ICoreWebView2_N chain that is right: + same object, so a webview can hand out ICoreWebView2_14 without walking thirteen + accessors. For every other chain it is wrong, and uselessly so -- + GetICoreWebView2Controller2 hung off ICoreWebView2, which is a different object and can + only fail, while ICoreWebView2Controller, which can answer, had no accessor at all. Rooting + on the chain start fixes those and leaves the ICoreWebView2_N family untouched, so no + existing caller breaks. + + An interface whose base is IUnknown gets NO accessor, here or before this change: the guard + below is BaseClass, which generateVtbl blanks for IUnknown. So the 169 such interfaces -- + ICoreWebView2EnvironmentOptions among them -- have never had one, and there is no sibling + interface to hang one on. Giving them one would be an API addition needing a decision about + where it belongs, not a fix. (An earlier version of this comment claimed they "keep the + ICoreWebView2 receiver they have today"; there was nothing to keep.) + RootInterface is non-empty exactly when BaseClass is not IUnknown, which is the same condition + as the guard -- so there is no second case to handle. */}} {{if .BaseClass }} -func (i *ICoreWebView2) Get{{.Name}}() *{{.Name}} { +func (i *{{.RootInterface}}) Get{{.Name}}() *{{.Name}} { var result *{{.Name}} iid{{.Name}} := NewGUID({{.Header.AsString}}) + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iid{{.Name}})), diff --git a/scripts/regen/main.go b/scripts/regen/main.go new file mode 100644 index 0000000..c996356 --- /dev/null +++ b/scripts/regen/main.go @@ -0,0 +1,66 @@ +// Command regen runs the generator against a local IDL and writes the result to a chosen +// directory. update_version_mapping.go can only regenerate as a side effect of checking +// Microsoft's release-notes page for a NEW version, which needs the network and rewrites the +// tree in place -- neither of which suits comparing generator output against the committed +// files. +// +// Usage: go run ./regen -idl WebView2.1.0.2903.40.idl -out /tmp/baseline +package main + +import ( + "flag" + "log" + "os" + "path/filepath" + "strings" + + "updater/generator" +) + +func main() { + idl := flag.String("idl", "WebView2.1.0.2903.40.idl", "IDL file to generate from") + out := flag.String("out", "", "directory to write the generated files to (required)") + flag.Parse() + if *out == "" { + log.Fatal("-out is required") + } + + data, err := os.ReadFile(*idl) + if err != nil { + log.Fatal(err) + } + files, err := generator.ParseIDL(data) + if err != nil { + log.Fatal(err) + } + if err := os.MkdirAll(*out, 0o755); err != nil { + log.Fatal(err) + } + // Clear the previously generated files, because reusing a directory across two IDL versions + // otherwise leaves behind the ones only the earlier version produced, and `diff -r` then reads + // as though they were still being generated -- which defeats the one thing this command is for. + // + // Only non-test .go files, NOT the whole directory: -out is usually pkg/webview2 itself, which + // also holds hand-written tests. Everything the generator emits is a non-test .go file, so that + // line is exactly the boundary between "derived, safe to delete" and "written by a person". + // RemoveAll here deleted marshal_windows_test.go, silently, and the package went back to + // reporting "no test files". + stale, err := filepath.Glob(filepath.Join(*out, "*.go")) + if err != nil { + log.Fatal(err) + } + for _, f := range stale { + if strings.HasSuffix(f, "_test.go") { + continue + } + if err := os.Remove(f); err != nil { + log.Fatal(err) + } + } + for _, f := range files { + if err := os.WriteFile(filepath.Join(*out, f.FileName), f.Content.Bytes(), 0o644); err != nil { + log.Fatal(err) + } + } + log.Printf("wrote %d files to %s", len(files), *out) +} From aeefc54abd0535a5a130d37f3bb8a0f031984435 Mon Sep 17 00:00:00 2001 From: "goutham.r" Date: Tue, 4 Aug 2026 16:00:46 +0530 Subject: [PATCH 2/3] test(webview2): execute the marshalling, and run it in CI Marshalling bugs here are invisible to review and to go build -- the wrong conversion compiles, links, runs and returns S_OK -- so the only way to know is to execute it. A COM object is a pointer to a table of function pointers, so one can be built entirely out of Go: fill a generated Vtbl with NewComProc(someGoFunc) and hand its address to the generated wrapper. The wrapper marshals exactly as it would for real WebView2, and the fake callee sees what actually arrived. The part that makes this practical: it needs no WebView2 Runtime, no Edge, no display, no network and no elevation. Windows and nothing else, so windows-latest is enough -- and `go test -c` produces a self-contained binary you can copy to any Windows box and run. Ten tests, one per argument shape, each asserting what the pre-fix code got wrong: BOOL arrives as 0/1 rather than an address; an event token arrives as its 8 bytes so remove_* can match it; POINT arrives by value with X in the low half; a double arrives as its bits; an int32 out-parameter keeps its sign; a string out-parameter is given somewhere to write; a string in-parameter arrives as the *uint16 we converted; COREWEBVIEW2_PHYSICAL_KEY_STATUS is 24 bytes with its flags at the native offsets; HWND arrives by value; and the HRESULT decides the error, with S_OK yielding a nil one. Run on Windows 11, all ten pass. The generator side gains property tests over the whole surface rather than goldens for one interface -- every derived vtable embeds its declared base; every vtable declares exactly the methods the IDL declares (252/252, which is the half of the slot-offset argument that embedding alone does not establish); no callback parameter exceeds a register; Call's Errno is never returned as an error; and the one nothing checked before, that the committed pkg/webview2 IS the generator's output. That last test is what stops this regressing the same way again, and it is verified to go red when a generated file is hand-edited. A GitHub Actions workflow that runs all of this -- the marshalling tests on windows-latest, and the generator's tests plus a cross-compile for windows/amd64 and arm64 on ubuntu-latest -- is ready and deliberately left out of this PR, since a workflow is a maintainer's call rather than a contributor's. Say the word and I will add it. --- pkg/webview2/marshal_windows_test.go | 324 +++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 pkg/webview2/marshal_windows_test.go diff --git a/pkg/webview2/marshal_windows_test.go b/pkg/webview2/marshal_windows_test.go new file mode 100644 index 0000000..a354580 --- /dev/null +++ b/pkg/webview2/marshal_windows_test.go @@ -0,0 +1,324 @@ +//go:build windows + +package webview2 + +// Every correctness claim about this package's argument marshalling has, until now, been an argument +// about the Windows x64 calling convention rather than an observation. That is how eight families of +// marshalling bug survived here: the wrong code compiles, links, runs and returns S_OK, so reading it +// is the only check there was, and reading it is what failed. +// +// These tests execute it instead. The trick is that a COM object is nothing but a pointer to a table +// of function pointers, so one can be built entirely out of Go: fill a generated Vtbl struct with +// NewComProc(someGoFunc) and hand its address to the generated wrapper. The wrapper marshals exactly +// as it would for a real WebView2, the fake callee receives whatever actually arrived, and the test +// asserts on it. +// +// The consequence worth noticing: this needs no WebView2 Runtime, no display, no Edge install, no +// network. It needs Windows and nothing else, so it runs on a stock windows-latest CI runner -- which +// is the difference between "we reasoned carefully" and "we know". +// +// Each test below names the family it pins and what the pre-fix code did instead. + +import ( + "math" + "testing" + "unsafe" +) + +const sOK = 0 + +// nativePhysicalKeyStatus is COREWEBVIEW2_PHYSICAL_KEY_STATUS as the C header declares it: a BOOL is +// a 4-byte int, so this is 24 bytes. The generated Go struct must match it exactly, because the callee +// writes this layout through the pointer the caller supplies. +type nativePhysicalKeyStatus struct { + RepeatCount, ScanCode uint32 + IsExtendedKey, IsMenuKeyDown, WasKeyDown, IsKeyReleased int32 +} + +// --- by-value BOOL ----------------------------------------------------------------------------- + +// A COM BOOL in-parameter is a 4-byte integer passed by value. The generator used to hand over the +// ADDRESS of a Go bool, so the callee read a pointer as an integer: nonzero, therefore always true, +// and a different value on every call. +func TestBoolInParamArrivesByValue(t *testing.T) { + for _, want := range []bool{true, false} { + var got uintptr = 0xDEAD + vtbl := ICoreWebView2SettingsVtbl{} + vtbl.PutIsScriptEnabled = NewComProc(func(this *ICoreWebView2Settings, v uintptr) uintptr { + got = v + return sOK + }) + obj := &ICoreWebView2Settings{Vtbl: &vtbl} + + if err := obj.PutIsScriptEnabled(want); err != nil { + t.Fatal(err) + } + wantN := uintptr(0) + if want { + wantN = 1 + } + if got != wantN { + t.Errorf("PutIsScriptEnabled(%v): callee saw %#x, want %#x "+ + "(a large value means it received an address)", want, got, wantN) + } + } +} + +// --- by-value 8-byte aggregate ---------------------------------------------------------------- + +// EventRegistrationToken is struct{ int64 }, so it goes in a register as that int64. Every one of the +// 61 remove_* methods used to pass its address, which is why no event handler could be removed -- and +// remove_ still returned S_OK, so nothing looked wrong. +func TestEventRegistrationTokenArrivesByValue(t *testing.T) { + var got uintptr + vtbl := ICoreWebView2Vtbl{} + vtbl.RemoveNavigationCompleted = NewComProc(func(this *ICoreWebView2, v uintptr) uintptr { + got = v + return sOK + }) + obj := &ICoreWebView2{Vtbl: &vtbl} + + token := EventRegistrationToken{value: 0x0123456789ABCDEF} + if err := obj.RemoveNavigationCompleted(token); err != nil { + t.Fatal(err) + } + if got != uintptr(0x0123456789ABCDEF) { + t.Errorf("RemoveNavigationCompleted: callee saw %#x, want %#x", got, uintptr(0x0123456789ABCDEF)) + } +} + +// POINT is two int32s -- 8 bytes, so also register-passed, with X in the low half. RECT (16 bytes) is +// the opposite case and is passed by address; the two are the reason a single rule cannot cover +// aggregates. +func TestPointArrivesByValueWithFieldOrderIntact(t *testing.T) { + var got uintptr + vtbl := ICoreWebView2PointerInfoVtbl{} + vtbl.PutPixelLocation = NewComProc(func(this *ICoreWebView2PointerInfo, v uintptr) uintptr { + got = v + return sOK + }) + obj := &ICoreWebView2PointerInfo{Vtbl: &vtbl} + + if err := obj.PutPixelLocation(POINT{X: 0x11112222, Y: 0x33334444}); err != nil { + t.Fatal(err) + } + if lo, hi := uint32(got), uint32(got>>32); lo != 0x11112222 || hi != 0x33334444 { + t.Errorf("PutPixelLocation: callee saw X=%#x Y=%#x, want X=0x11112222 Y=0x33334444", lo, hi) + } +} + +// --- by-value double --------------------------------------------------------------------------- + +// A double is passed in XMM0-XMM3 for the first four arguments, and Go's syscall assembly copies each +// of those argument slots into both the integer register and the matching XMM register -- which is +// what makes math.Float64bits work here. The callback observes the integer register, so it sees the +// same bits the callee's XMM register receives. +// +// Twelve methods take a double, and each used to pass the ADDRESS of a Go float64, so the callee read +// a heap address as an IEEE-754 double: a denormal, or roughly 1e-300. +func TestDoubleInParamArrivesAsItsBits(t *testing.T) { + var got uintptr + vtbl := ICoreWebView2ControllerVtbl{} + vtbl.PutZoomFactor = NewComProc(func(this *ICoreWebView2Controller, v uintptr) uintptr { + got = v + return sOK + }) + obj := &ICoreWebView2Controller{Vtbl: &vtbl} + + const zoom = 1.75 + if err := obj.PutZoomFactor(zoom); err != nil { + t.Fatal(err) + } + if got != uintptr(math.Float64bits(zoom)) { + t.Errorf("PutZoomFactor(%v): callee saw %#x, want %#x (%v as observed by the callee)", + zoom, got, math.Float64bits(zoom), math.Float64frombits(uint64(got))) + } +} + +// --- 32-bit out-parameter ---------------------------------------------------------------------- + +// The callee writes four bytes through the pointer we supply. When the local was Go's 64-bit int, the +// high half stayed zero and the sign never extended, so a negative NTSTATUS came back as a large +// positive: GetExitCode returned 3221225477 for STATUS_ACCESS_VIOLATION. +func TestInt32OutParamKeepsItsSign(t *testing.T) { + const wantExit = int32(-1073741819) // 0xC0000005, STATUS_ACCESS_VIOLATION + + vtbl := ICoreWebView2ProcessFailedEventArgs2Vtbl{} + // The callback declares its out-parameter as *int32 rather than uintptr. A callback may take + // pointer arguments directly, so nothing has to be converted back from an integer -- which keeps + // this test out of the unsafe.Pointer rules it is meant to be checking. + vtbl.GetExitCode = NewComProc(func(this *ICoreWebView2ProcessFailedEventArgs2, out *int32) uintptr { + *out = wantExit + return sOK + }) + obj := &ICoreWebView2ProcessFailedEventArgs2{Vtbl: &vtbl} + + got, err := obj.GetExitCode() + if err != nil { + t.Fatal(err) + } + if got != wantExit { + t.Errorf("GetExitCode: got %d, want %d", got, wantExit) + } +} + +// --- string out-parameter ---------------------------------------------------------------------- + +// An out-parameter string is declared LPWSTR*: the callee writes a string POINTER into storage we +// own, so it needs the address of our local *uint16. Passing the local's nil VALUE instead gave the +// callee a null to write through, so all 109 string getters returned "" -- with S_OK. +// +// The assertion that matters is therefore that the callee is given somewhere to write. This writes nil +// rather than a real string on purpose: a real one would have to come from CoTaskMemAlloc, because the +// generated cleanup frees it with CoTaskMemFree and handing that a Go pointer corrupts the COM heap -- +// and reading a syscall's returned address back into an unsafe.Pointer is the one pattern `go vet` +// cannot verify, which would make this file fail the vet step it is meant to pass. CoTaskMemFree(nil) +// and UTF16PtrToString(nil) are both defined no-ops, so the path runs end to end with no allocation. +// The conversion itself is library code rather than generated code, and the in-parameter test below +// covers a real round-trip in the other direction. +func TestStringOutParamIsGivenSomewhereToWrite(t *testing.T) { + received := false + + vtbl := ICoreWebView2Vtbl{} + vtbl.GetSource = NewComProc(func(this *ICoreWebView2, out **uint16) uintptr { + received = out != nil + *out = nil + return sOK + }) + obj := &ICoreWebView2{Vtbl: &vtbl} + + got, err := obj.GetSource() + if err != nil { + t.Fatal(err) + } + if !received { + t.Error("GetSource: callee received a NULL out-parameter, so it had nowhere to write -- " + + "the local's value was passed instead of its address") + } + if got != "" { + t.Errorf("GetSource: got %q from a nil write, want the empty string", got) + } +} + +// A string IN-parameter is already the *uint16 that UTF16PtrFromString produced and is passed as-is. +func TestStringInParamArrivesAsAUTF16Pointer(t *testing.T) { + const want = "https://example.invalid/" + + var got string + vtbl := ICoreWebView2Vtbl{} + vtbl.Navigate = NewComProc(func(this *ICoreWebView2, uri *uint16) uintptr { + got = UTF16PtrToString(uri) + return sOK + }) + obj := &ICoreWebView2{Vtbl: &vtbl} + + if err := obj.Navigate(want); err != nil { + t.Fatal(err) + } + if got != want { + t.Errorf("Navigate: callee saw %q, want %q", got, want) + } +} + +// --- aggregate out-parameter, and the width of a struct field --------------------------------- + +// COREWEBVIEW2_PHYSICAL_KEY_STATUS is 24 bytes: two UINT32 and four BOOL, where a BOOL is a 4-byte +// int. Generating those flags as Go's 1-byte bool made the struct 12 bytes, so the callee's 24-byte +// write ran 12 bytes past the end of the local, and the last three flags were read from padding and +// so were permanently false. +// +// The write below is deliberately a full 24 bytes at the offsets a real callee uses, so this test +// fails -- by corrupting memory or by returning false flags -- if the field widths regress. +func TestAggregateOutParamMatchesTheNativeLayout(t *testing.T) { + if got, want := unsafe.Sizeof(COREWEBVIEW2_PHYSICAL_KEY_STATUS{}), uintptr(24); got != want { + t.Fatalf("COREWEBVIEW2_PHYSICAL_KEY_STATUS is %d bytes, want %d: a BOOL field is 4 bytes, "+ + "and the callee writes the native layout regardless of what Go declares", got, want) + } + + vtbl := ICoreWebView2AcceleratorKeyPressedEventArgsVtbl{} + vtbl.GetPhysicalKeyStatus = NewComProc(func(this *ICoreWebView2AcceleratorKeyPressedEventArgs, native *nativePhysicalKeyStatus) uintptr { + native.RepeatCount = 7 + native.ScanCode = 0x1E + native.IsExtendedKey = 1 + native.IsMenuKeyDown = 0 + native.WasKeyDown = 1 + native.IsKeyReleased = 1 + return sOK + }) + obj := &ICoreWebView2AcceleratorKeyPressedEventArgs{Vtbl: &vtbl} + + got, err := obj.GetPhysicalKeyStatus() + if err != nil { + t.Fatal(err) + } + switch { + case got.RepeatCount != 7 || got.ScanCode != 0x1E: + t.Errorf("GetPhysicalKeyStatus: RepeatCount=%d ScanCode=%#x, want 7 and 0x1e", + got.RepeatCount, got.ScanCode) + case got.IsExtendedKey == 0 || got.WasKeyDown == 0 || got.IsKeyReleased == 0: + t.Errorf("GetPhysicalKeyStatus: flags read from the wrong offsets: %+v", got) + case got.IsMenuKeyDown != 0: + t.Errorf("GetPhysicalKeyStatus: IsMenuKeyDown should be 0, got %d", got.IsMenuKeyDown) + } +} + +// --- uintptr typedef --------------------------------------------------------------------------- + +// HWND is `type HWND uintptr` -- an integer, so the value IS the argument. Passing its address gave +// WebView2 a garbage window handle. +func TestHandleTypedefArrivesByValue(t *testing.T) { + const want = uintptr(0x00CAFE00) + + var got uintptr + vtbl := ICoreWebView2EnvironmentVtbl{} + vtbl.CreateCoreWebView2Controller = NewComProc( + func(this *ICoreWebView2Environment, hwnd uintptr, handler uintptr) uintptr { + got = hwnd + return sOK + }) + obj := &ICoreWebView2Environment{Vtbl: &vtbl} + + if err := obj.CreateCoreWebView2Controller(HWND(want), nil); err != nil { + t.Fatal(err) + } + if got != want { + t.Errorf("CreateCoreWebView2Controller: callee saw hwnd=%#x, want %#x", got, want) + } +} + +// --- the HRESULT contract ---------------------------------------------------------------------- + +// ComProc.Call's third result is a syscall.Errno that is non-nil on success, so returning it made +// every successful call look like a failure. The HRESULT is the status, and a failing one must come +// back as the error while the out-parameters stay at their zero values. +func TestHResultDecidesTheError(t *testing.T) { + const eFail = 0x80004005 // E_FAIL + + vtbl := ICoreWebView2ProcessFailedEventArgs2Vtbl{} + vtbl.GetExitCode = NewComProc(func(this *ICoreWebView2ProcessFailedEventArgs2, out *int32) uintptr { + *out = 42 // written, but the call fails + return eFail + }) + obj := &ICoreWebView2ProcessFailedEventArgs2{Vtbl: &vtbl} + + got, err := obj.GetExitCode() + if err == nil { + t.Fatal("GetExitCode returned nil error for E_FAIL") + } + if got != 0 { + t.Errorf("GetExitCode returned %d alongside an error; want the zero value", got) + } + + // And the success path must produce a nil error, not Errno(0) boxed into a non-nil interface. + vtbl.GetExitCode = NewComProc(func(this *ICoreWebView2ProcessFailedEventArgs2, out *int32) uintptr { + *out = 42 + return sOK + }) + got, err = obj.GetExitCode() + if err != nil { + t.Fatalf("GetExitCode returned a non-nil error on S_OK: %v", err) + } + if got != 42 { + t.Errorf("GetExitCode: got %d, want 42", got) + } +} From 1d0cc8e21bc0b0f92073cab526b5dd208744fbcb Mon Sep 17 00:00:00 2001 From: "goutham.r" Date: Tue, 4 Aug 2026 16:01:17 +0530 Subject: [PATCH 3/3] chore(webview2): regenerate from the pinned IDL cd scripts && go run ./regen -idl WebView2.1.0.2903.40.idl -out ../pkg/webview2 No hand edits, and TestCommittedOutputMatchesGenerator now enforces that. Verified: windows amd64, arm64 and 386 build; go vet clean on pkg/webview2; the generator's tests pass; all six IDLs in scripts/ regenerate and the three older ones type-check; the ten marshalling tests pass on Windows 11 hardware; and a downstream consumer's Windows GUI -- window, TLS certificate pin firing, both external-link layers -- runs against this tree on a real machine. One property worth stating, because it is what makes a 170-file diff trustworthy: this output is byte-identical whether the generator runs on top of this branch's base or on top of a tree that had all nine families patched by hand. The output is derived, so the base does not matter -- which is the whole argument for fixing the generator instead. --- .../COREWEBVIEW2_PHYSICAL_KEY_STATUS.go | 8 +-- pkg/webview2/ICoreWebView2.go | 49 +++++++++------ ...eWebView2AcceleratorKeyPressedEventArgs.go | 23 +++++-- ...WebView2AcceleratorKeyPressedEventArgs2.go | 26 +++++++- ...xecuteOnDocumentCreatedCompletedHandler.go | 4 +- ...w2BasicAuthenticationRequestedEventArgs.go | 19 +++++- ...CoreWebView2BasicAuthenticationResponse.go | 17 +++++- pkg/webview2/ICoreWebView2BrowserExtension.go | 19 +++++- .../ICoreWebView2BrowserExtensionList.go | 15 ++++- ...reWebView2BrowserProcessExitedEventArgs.go | 13 ++++ ...lDevToolsProtocolMethodCompletedHandler.go | 4 +- pkg/webview2/ICoreWebView2Certificate.go | 23 +++++-- .../ICoreWebView2ClientCertificate.go | 23 +++++-- ...CoreWebView2ClientCertificateCollection.go | 15 ++++- ...iew2ClientCertificateRequestedEventArgs.go | 25 ++++++-- .../ICoreWebView2CompositionController.go | 19 +++++- .../ICoreWebView2CompositionController2.go | 24 +++++++- .../ICoreWebView2CompositionController3.go | 36 ++++++++--- .../ICoreWebView2CompositionController4.go | 28 +++++++-- .../ICoreWebView2ContentLoadingEventArgs.go | 13 ++++ pkg/webview2/ICoreWebView2ContextMenuItem.go | 25 ++++++-- .../ICoreWebView2ContextMenuItemCollection.go | 19 +++++- ...reWebView2ContextMenuRequestedEventArgs.go | 17 +++++- .../ICoreWebView2ContextMenuTarget.go | 25 ++++++-- pkg/webview2/ICoreWebView2Controller.go | 32 +++++++--- pkg/webview2/ICoreWebView2Controller2.go | 26 +++++++- pkg/webview2/ICoreWebView2Controller3.go | 37 +++++++---- pkg/webview2/ICoreWebView2Controller4.go | 26 +++++++- .../ICoreWebView2ControllerOptions.go | 17 +++++- .../ICoreWebView2ControllerOptions2.go | 26 +++++++- pkg/webview2/ICoreWebView2Cookie.go | 28 ++++++--- pkg/webview2/ICoreWebView2CookieList.go | 15 ++++- pkg/webview2/ICoreWebView2CookieManager.go | 13 ++++ .../ICoreWebView2CustomSchemeRegistration.go | 23 +++++-- .../ICoreWebView2DOMContentLoadedEventArgs.go | 13 ++++ pkg/webview2/ICoreWebView2Deferral.go | 13 ++++ ...2DevToolsProtocolEventReceivedEventArgs.go | 15 ++++- ...DevToolsProtocolEventReceivedEventArgs2.go | 26 +++++++- ...reWebView2DevToolsProtocolEventReceiver.go | 15 ++++- .../ICoreWebView2DownloadOperation.go | 29 ++++++--- .../ICoreWebView2DownloadStartingEventArgs.go | 19 +++++- pkg/webview2/ICoreWebView2Environment.go | 21 +++++-- pkg/webview2/ICoreWebView2Environment10.go | 28 +++++++-- pkg/webview2/ICoreWebView2Environment11.go | 26 +++++++- pkg/webview2/ICoreWebView2Environment12.go | 26 +++++++- pkg/webview2/ICoreWebView2Environment13.go | 24 +++++++- pkg/webview2/ICoreWebView2Environment14.go | 28 +++++++-- pkg/webview2/ICoreWebView2Environment2.go | 24 +++++++- pkg/webview2/ICoreWebView2Environment3.go | 26 +++++++- pkg/webview2/ICoreWebView2Environment4.go | 26 +++++++- pkg/webview2/ICoreWebView2Environment5.go | 26 +++++++- pkg/webview2/ICoreWebView2Environment6.go | 24 +++++++- pkg/webview2/ICoreWebView2Environment7.go | 26 +++++++- pkg/webview2/ICoreWebView2Environment8.go | 26 +++++++- pkg/webview2/ICoreWebView2Environment9.go | 24 +++++++- .../ICoreWebView2EnvironmentOptions.go | 21 +++++-- .../ICoreWebView2EnvironmentOptions2.go | 15 ++++- .../ICoreWebView2EnvironmentOptions3.go | 15 ++++- .../ICoreWebView2EnvironmentOptions4.go | 17 +++++- .../ICoreWebView2EnvironmentOptions5.go | 15 ++++- .../ICoreWebView2EnvironmentOptions6.go | 15 ++++- .../ICoreWebView2EnvironmentOptions7.go | 13 ++++ .../ICoreWebView2EnvironmentOptions8.go | 13 ++++ ...reWebView2ExecuteScriptCompletedHandler.go | 4 +- .../ICoreWebView2ExecuteScriptResult.go | 17 +++++- pkg/webview2/ICoreWebView2File.go | 15 ++++- pkg/webview2/ICoreWebView2FileSystemHandle.go | 15 ++++- pkg/webview2/ICoreWebView2Frame.go | 21 +++++-- pkg/webview2/ICoreWebView2Frame2.go | 34 ++++++++--- pkg/webview2/ICoreWebView2Frame3.go | 26 +++++++- pkg/webview2/ICoreWebView2Frame4.go | 24 +++++++- pkg/webview2/ICoreWebView2Frame5.go | 24 +++++++- pkg/webview2/ICoreWebView2Frame6.go | 26 +++++++- .../ICoreWebView2FrameCreatedEventArgs.go | 13 ++++ pkg/webview2/ICoreWebView2FrameInfo.go | 17 +++++- pkg/webview2/ICoreWebView2FrameInfo2.go | 24 +++++++- .../ICoreWebView2FrameInfoCollection.go | 13 ++++ ...CoreWebView2FrameInfoCollectionIterator.go | 13 ++++ ...reWebView2HttpHeadersCollectionIterator.go | 17 +++++- .../ICoreWebView2HttpRequestHeaders.go | 19 +++++- .../ICoreWebView2HttpResponseHeaders.go | 21 +++++-- ...iew2LaunchingExternalUriSchemeEventArgs.go | 19 +++++- ...CoreWebView2MoveFocusRequestedEventArgs.go | 15 ++++- ...oreWebView2NavigationCompletedEventArgs.go | 13 ++++ ...reWebView2NavigationCompletedEventArgs2.go | 30 +++++++-- ...CoreWebView2NavigationStartingEventArgs.go | 17 +++++- ...oreWebView2NavigationStartingEventArgs2.go | 26 +++++++- ...oreWebView2NavigationStartingEventArgs3.go | 24 +++++++- ...CoreWebView2NewWindowRequestedEventArgs.go | 17 +++++- ...oreWebView2NewWindowRequestedEventArgs2.go | 26 +++++++- ...oreWebView2NewWindowRequestedEventArgs3.go | 24 +++++++- ...WebView2NonClientRegionChangedEventArgs.go | 13 ++++ pkg/webview2/ICoreWebView2Notification.go | 29 ++++++--- ...reWebView2NotificationReceivedEventArgs.go | 17 +++++- pkg/webview2/ICoreWebView2ObjectCollection.go | 28 +++++++-- .../ICoreWebView2ObjectCollectionView.go | 15 ++++- ...oreWebView2PermissionRequestedEventArgs.go | 15 ++++- ...reWebView2PermissionRequestedEventArgs2.go | 26 +++++++- ...reWebView2PermissionRequestedEventArgs3.go | 26 +++++++- .../ICoreWebView2PermissionSetting.go | 15 ++++- ...WebView2PermissionSettingCollectionView.go | 15 ++++- pkg/webview2/ICoreWebView2PointerInfo.go | 61 +++++++++++-------- pkg/webview2/ICoreWebView2PrintSettings.go | 38 ++++++++---- pkg/webview2/ICoreWebView2PrintSettings2.go | 32 ++++++++-- .../ICoreWebView2ProcessExtendedInfo.go | 13 ++++ ...reWebView2ProcessExtendedInfoCollection.go | 15 ++++- .../ICoreWebView2ProcessFailedEventArgs.go | 13 ++++ .../ICoreWebView2ProcessFailedEventArgs2.go | 32 ++++++++-- .../ICoreWebView2ProcessFailedEventArgs3.go | 26 +++++++- pkg/webview2/ICoreWebView2ProcessInfo.go | 13 ++++ .../ICoreWebView2ProcessInfoCollection.go | 15 ++++- pkg/webview2/ICoreWebView2Profile.go | 19 +++++- pkg/webview2/ICoreWebView2Profile2.go | 29 +++++++-- pkg/webview2/ICoreWebView2Profile3.go | 24 +++++++- pkg/webview2/ICoreWebView2Profile4.go | 24 +++++++- pkg/webview2/ICoreWebView2Profile5.go | 24 +++++++- pkg/webview2/ICoreWebView2Profile6.go | 28 +++++++-- pkg/webview2/ICoreWebView2Profile7.go | 24 +++++++- pkg/webview2/ICoreWebView2Profile8.go | 26 +++++++- .../ICoreWebView2RegionRectCollectionView.go | 15 ++++- .../ICoreWebView2SaveAsUIShowingEventArgs.go | 23 +++++-- ...2SaveFileSecurityCheckStartingEventArgs.go | 23 +++++-- ...eWebView2ScreenCaptureStartingEventArgs.go | 17 +++++- ...oreWebView2ScriptDialogOpeningEventArgs.go | 21 +++++-- pkg/webview2/ICoreWebView2ScriptException.go | 19 +++++- ...ServerCertificateErrorDetectedEventArgs.go | 15 ++++- pkg/webview2/ICoreWebView2Settings.go | 31 +++++++--- pkg/webview2/ICoreWebView2Settings2.go | 26 +++++++- pkg/webview2/ICoreWebView2Settings3.go | 26 +++++++- pkg/webview2/ICoreWebView2Settings4.go | 28 +++++++-- pkg/webview2/ICoreWebView2Settings5.go | 26 +++++++- pkg/webview2/ICoreWebView2Settings6.go | 26 +++++++- pkg/webview2/ICoreWebView2Settings7.go | 24 +++++++- pkg/webview2/ICoreWebView2Settings8.go | 26 +++++++- pkg/webview2/ICoreWebView2Settings9.go | 26 +++++++- pkg/webview2/ICoreWebView2SharedBuffer.go | 13 ++++ .../ICoreWebView2SourceChangedEventArgs.go | 13 ++++ pkg/webview2/ICoreWebView2StringCollection.go | 17 +++++- ...CoreWebView2WebMessageReceivedEventArgs.go | 19 +++++- ...oreWebView2WebMessageReceivedEventArgs2.go | 24 +++++++- .../ICoreWebView2WebResourceRequest.go | 17 +++++- ...reWebView2WebResourceRequestedEventArgs.go | 13 ++++ ...eWebView2WebResourceRequestedEventArgs2.go | 24 +++++++- .../ICoreWebView2WebResourceResponse.go | 23 +++++-- ...ew2WebResourceResponseReceivedEventArgs.go | 13 ++++ .../ICoreWebView2WebResourceResponseView.go | 21 +++++-- pkg/webview2/ICoreWebView2WindowFeatures.go | 13 ++++ pkg/webview2/ICoreWebView2_10.go | 24 +++++++- pkg/webview2/ICoreWebView2_11.go | 24 +++++++- pkg/webview2/ICoreWebView2_12.go | 26 +++++++- pkg/webview2/ICoreWebView2_13.go | 22 ++++++- pkg/webview2/ICoreWebView2_14.go | 24 +++++++- pkg/webview2/ICoreWebView2_15.go | 26 +++++++- pkg/webview2/ICoreWebView2_16.go | 22 ++++++- pkg/webview2/ICoreWebView2_17.go | 22 ++++++- pkg/webview2/ICoreWebView2_18.go | 24 +++++++- pkg/webview2/ICoreWebView2_19.go | 22 ++++++- pkg/webview2/ICoreWebView2_2.go | 26 +++++++- pkg/webview2/ICoreWebView2_20.go | 22 ++++++- pkg/webview2/ICoreWebView2_21.go | 22 ++++++- pkg/webview2/ICoreWebView2_22.go | 22 ++++++- pkg/webview2/ICoreWebView2_23.go | 22 ++++++- pkg/webview2/ICoreWebView2_24.go | 24 +++++++- pkg/webview2/ICoreWebView2_25.go | 24 +++++++- pkg/webview2/ICoreWebView2_26.go | 26 +++++++- pkg/webview2/ICoreWebView2_27.go | 24 +++++++- pkg/webview2/ICoreWebView2_3.go | 22 ++++++- pkg/webview2/ICoreWebView2_4.go | 26 +++++++- pkg/webview2/ICoreWebView2_5.go | 24 +++++++- pkg/webview2/ICoreWebView2_6.go | 22 ++++++- pkg/webview2/ICoreWebView2_7.go | 22 ++++++- pkg/webview2/ICoreWebView2_8.go | 28 +++++++-- pkg/webview2/ICoreWebView2_9.go | 26 +++++++- pkg/webview2/com.go | 19 ++++++ 174 files changed, 3280 insertions(+), 489 deletions(-) diff --git a/pkg/webview2/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go b/pkg/webview2/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go index 23e84b4..f6932de 100644 --- a/pkg/webview2/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go +++ b/pkg/webview2/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go @@ -5,8 +5,8 @@ package webview2 type COREWEBVIEW2_PHYSICAL_KEY_STATUS struct { RepeatCount uint32 ScanCode uint32 - IsExtendedKey bool - IsMenuKeyDown bool - WasKeyDown bool - IsKeyReleased bool + IsExtendedKey int32 + IsMenuKeyDown int32 + WasKeyDown int32 + IsKeyReleased int32 } diff --git a/pkg/webview2/ICoreWebView2.go b/pkg/webview2/ICoreWebView2.go index 9b0af89..b0d4b55 100644 --- a/pkg/webview2/ICoreWebView2.go +++ b/pkg/webview2/ICoreWebView2.go @@ -79,6 +79,19 @@ func (i *ICoreWebView2) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetSettings() (*ICoreWebView2Settings, error) { var settings *ICoreWebView2Settings @@ -99,7 +112,7 @@ func (i *ICoreWebView2) GetSource() (string, error) { hr, _, _ := i.Vtbl.GetSource.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_uri)), + uintptr(unsafe.Pointer(&_uri)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -165,7 +178,7 @@ func (i *ICoreWebView2) RemoveNavigationStarting(token EventRegistrationToken) e hr, _, _ := i.Vtbl.RemoveNavigationStarting.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -192,7 +205,7 @@ func (i *ICoreWebView2) RemoveContentLoading(token EventRegistrationToken) error hr, _, _ := i.Vtbl.RemoveContentLoading.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -219,7 +232,7 @@ func (i *ICoreWebView2) RemoveSourceChanged(token EventRegistrationToken) error hr, _, _ := i.Vtbl.RemoveSourceChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -246,7 +259,7 @@ func (i *ICoreWebView2) RemoveHistoryChanged(token EventRegistrationToken) error hr, _, _ := i.Vtbl.RemoveHistoryChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -273,7 +286,7 @@ func (i *ICoreWebView2) RemoveNavigationCompleted(token EventRegistrationToken) hr, _, _ := i.Vtbl.RemoveNavigationCompleted.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -300,7 +313,7 @@ func (i *ICoreWebView2) RemoveFrameNavigationStarting(token EventRegistrationTok hr, _, _ := i.Vtbl.RemoveFrameNavigationStarting.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -327,7 +340,7 @@ func (i *ICoreWebView2) RemoveFrameNavigationCompleted(token EventRegistrationTo hr, _, _ := i.Vtbl.RemoveFrameNavigationCompleted.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -354,7 +367,7 @@ func (i *ICoreWebView2) RemoveScriptDialogOpening(token EventRegistrationToken) hr, _, _ := i.Vtbl.RemoveScriptDialogOpening.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -381,7 +394,7 @@ func (i *ICoreWebView2) RemovePermissionRequested(token EventRegistrationToken) hr, _, _ := i.Vtbl.RemovePermissionRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -408,7 +421,7 @@ func (i *ICoreWebView2) RemoveProcessFailed(token EventRegistrationToken) error hr, _, _ := i.Vtbl.RemoveProcessFailed.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -552,7 +565,7 @@ func (i *ICoreWebView2) RemoveWebMessageReceived(token EventRegistrationToken) e hr, _, _ := i.Vtbl.RemoveWebMessageReceived.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -703,7 +716,7 @@ func (i *ICoreWebView2) RemoveNewWindowRequested(token EventRegistrationToken) e hr, _, _ := i.Vtbl.RemoveNewWindowRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -730,7 +743,7 @@ func (i *ICoreWebView2) RemoveDocumentTitleChanged(token EventRegistrationToken) hr, _, _ := i.Vtbl.RemoveDocumentTitleChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -744,7 +757,7 @@ func (i *ICoreWebView2) GetDocumentTitle() (string, error) { hr, _, _ := i.Vtbl.GetDocumentTitle.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_title)), + uintptr(unsafe.Pointer(&_title)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -822,7 +835,7 @@ func (i *ICoreWebView2) RemoveContainsFullScreenElementChanged(token EventRegist hr, _, _ := i.Vtbl.RemoveContainsFullScreenElementChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -865,7 +878,7 @@ func (i *ICoreWebView2) RemoveWebResourceRequested(token EventRegistrationToken) hr, _, _ := i.Vtbl.RemoveWebResourceRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -930,7 +943,7 @@ func (i *ICoreWebView2) RemoveWindowCloseRequested(token EventRegistrationToken) hr, _, _ := i.Vtbl.RemoveWindowCloseRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2AcceleratorKeyPressedEventArgs.go b/pkg/webview2/ICoreWebView2AcceleratorKeyPressedEventArgs.go index f4f632e..1757e6b 100644 --- a/pkg/webview2/ICoreWebView2AcceleratorKeyPressedEventArgs.go +++ b/pkg/webview2/ICoreWebView2AcceleratorKeyPressedEventArgs.go @@ -27,6 +27,19 @@ func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetKeyEventKind() (COREWEBVIEW2_KEY_EVENT_KIND, error) { var keyEventKind COREWEBVIEW2_KEY_EVENT_KIND @@ -41,9 +54,9 @@ func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetKeyEventKind() (COREWEB return keyEventKind, nil } -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetVirtualKey() (uint, error) { +func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetVirtualKey() (uint32, error) { - var virtualKey uint + var virtualKey uint32 hr, _, _ := i.Vtbl.GetVirtualKey.Call( uintptr(unsafe.Pointer(i)), @@ -55,9 +68,9 @@ func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetVirtualKey() (uint, err return virtualKey, nil } -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetKeyEventLParam() (int, error) { +func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetKeyEventLParam() (int32, error) { - var lParam int + var lParam int32 hr, _, _ := i.Vtbl.GetKeyEventLParam.Call( uintptr(unsafe.Pointer(i)), @@ -103,7 +116,7 @@ func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) PutHandled(handled bool) e hr, _, _ := i.Vtbl.PutHandled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&handled)), + boolToUintptr(handled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2AcceleratorKeyPressedEventArgs2.go b/pkg/webview2/ICoreWebView2AcceleratorKeyPressedEventArgs2.go index c73c39b..104767c 100644 --- a/pkg/webview2/ICoreWebView2AcceleratorKeyPressedEventArgs2.go +++ b/pkg/webview2/ICoreWebView2AcceleratorKeyPressedEventArgs2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2AcceleratorKeyPressedEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2AcceleratorKeyPressedEventArgsVtbl GetIsBrowserAcceleratorKeyEnabled ComProc PutIsBrowserAcceleratorKeyEnabled ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2AcceleratorKeyPressedEventArgs2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2AcceleratorKeyPressedEventArgs2() *ICoreWebView2AcceleratorKeyPressedEventArgs2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2AcceleratorKeyPressedEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetICoreWebView2AcceleratorKeyPressedEventArgs2() *ICoreWebView2AcceleratorKeyPressedEventArgs2 { var result *ICoreWebView2AcceleratorKeyPressedEventArgs2 iidICoreWebView2AcceleratorKeyPressedEventArgs2 := NewGUID("{03b2c8c8-7799-4e34-bd66-ed26aa85f2bf}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2AcceleratorKeyPressedEventArgs2)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2AcceleratorKeyPressedEventArgs2) PutIsBrowserAcceleratorKe hr, _, _ := i.Vtbl.PutIsBrowserAcceleratorKeyEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler.go b/pkg/webview2/ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler.go index 1a3d86c..6334cc6 100644 --- a/pkg/webview2/ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler.go +++ b/pkg/webview2/ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler.go @@ -33,13 +33,13 @@ func ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandlerIUnknownRel return this.impl.Release() } -func ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandlerInvoke(this *ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler, errorCode uintptr, result string) uintptr { +func ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandlerInvoke(this *ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler, errorCode uintptr, result *uint16) uintptr { return this.impl.AddScriptToExecuteOnDocumentCreatedCompleted(errorCode, result) } type ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandlerImpl interface { IUnknownImpl - AddScriptToExecuteOnDocumentCreatedCompleted(errorCode uintptr, result string) uintptr + AddScriptToExecuteOnDocumentCreatedCompleted(errorCode uintptr, result *uint16) uintptr } var ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandlerFn = ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandlerVtbl{ diff --git a/pkg/webview2/ICoreWebView2BasicAuthenticationRequestedEventArgs.go b/pkg/webview2/ICoreWebView2BasicAuthenticationRequestedEventArgs.go index e820b24..71ca2a9 100644 --- a/pkg/webview2/ICoreWebView2BasicAuthenticationRequestedEventArgs.go +++ b/pkg/webview2/ICoreWebView2BasicAuthenticationRequestedEventArgs.go @@ -27,13 +27,26 @@ func (i *ICoreWebView2BasicAuthenticationRequestedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2BasicAuthenticationRequestedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2BasicAuthenticationRequestedEventArgs) GetUri() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -50,7 +63,7 @@ func (i *ICoreWebView2BasicAuthenticationRequestedEventArgs) GetChallenge() (str hr, _, _ := i.Vtbl.GetChallenge.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_challenge)), + uintptr(unsafe.Pointer(&_challenge)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -95,7 +108,7 @@ func (i *ICoreWebView2BasicAuthenticationRequestedEventArgs) PutCancel(cancel bo hr, _, _ := i.Vtbl.PutCancel.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&cancel)), + boolToUintptr(cancel), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2BasicAuthenticationResponse.go b/pkg/webview2/ICoreWebView2BasicAuthenticationResponse.go index 2a5f980..7089647 100644 --- a/pkg/webview2/ICoreWebView2BasicAuthenticationResponse.go +++ b/pkg/webview2/ICoreWebView2BasicAuthenticationResponse.go @@ -25,13 +25,26 @@ func (i *ICoreWebView2BasicAuthenticationResponse) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2BasicAuthenticationResponse) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2BasicAuthenticationResponse) GetUserName() (string, error) { // Create *uint16 to hold result var _userName *uint16 hr, _, _ := i.Vtbl.GetUserName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_userName)), + uintptr(unsafe.Pointer(&_userName)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -66,7 +79,7 @@ func (i *ICoreWebView2BasicAuthenticationResponse) GetPassword() (string, error) hr, _, _ := i.Vtbl.GetPassword.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_password)), + uintptr(unsafe.Pointer(&_password)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2BrowserExtension.go b/pkg/webview2/ICoreWebView2BrowserExtension.go index 29cf1cb..20810ca 100644 --- a/pkg/webview2/ICoreWebView2BrowserExtension.go +++ b/pkg/webview2/ICoreWebView2BrowserExtension.go @@ -26,13 +26,26 @@ func (i *ICoreWebView2BrowserExtension) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2BrowserExtension) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2BrowserExtension) GetId() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetId.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -49,7 +62,7 @@ func (i *ICoreWebView2BrowserExtension) GetName() (string, error) { hr, _, _ := i.Vtbl.GetName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -92,7 +105,7 @@ func (i *ICoreWebView2BrowserExtension) Enable(isEnabled bool, handler *ICoreWeb hr, _, _ := i.Vtbl.Enable.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isEnabled)), + boolToUintptr(isEnabled), uintptr(unsafe.Pointer(handler)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2BrowserExtensionList.go b/pkg/webview2/ICoreWebView2BrowserExtensionList.go index fb82c94..e6758d4 100644 --- a/pkg/webview2/ICoreWebView2BrowserExtensionList.go +++ b/pkg/webview2/ICoreWebView2BrowserExtensionList.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2BrowserExtensionList) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2BrowserExtensionList) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2BrowserExtensionList) GetCount() (uint32, error) { var value uint32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2BrowserExtensionList) GetValueAtIndex(index uint32) (*ICor hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2BrowserProcessExitedEventArgs.go b/pkg/webview2/ICoreWebView2BrowserProcessExitedEventArgs.go index 239d9df..be6a29d 100644 --- a/pkg/webview2/ICoreWebView2BrowserProcessExitedEventArgs.go +++ b/pkg/webview2/ICoreWebView2BrowserProcessExitedEventArgs.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2BrowserProcessExitedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2BrowserProcessExitedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2BrowserProcessExitedEventArgs) GetBrowserProcessExitKind() (COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND, error) { var value COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND diff --git a/pkg/webview2/ICoreWebView2CallDevToolsProtocolMethodCompletedHandler.go b/pkg/webview2/ICoreWebView2CallDevToolsProtocolMethodCompletedHandler.go index 95e1714..3de046e 100644 --- a/pkg/webview2/ICoreWebView2CallDevToolsProtocolMethodCompletedHandler.go +++ b/pkg/webview2/ICoreWebView2CallDevToolsProtocolMethodCompletedHandler.go @@ -33,13 +33,13 @@ func ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerIUnknownRelease(this return this.impl.Release() } -func ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerInvoke(this *ICoreWebView2CallDevToolsProtocolMethodCompletedHandler, errorCode uintptr, result string) uintptr { +func ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerInvoke(this *ICoreWebView2CallDevToolsProtocolMethodCompletedHandler, errorCode uintptr, result *uint16) uintptr { return this.impl.CallDevToolsProtocolMethodCompleted(errorCode, result) } type ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerImpl interface { IUnknownImpl - CallDevToolsProtocolMethodCompleted(errorCode uintptr, result string) uintptr + CallDevToolsProtocolMethodCompleted(errorCode uintptr, result *uint16) uintptr } var ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerFn = ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerVtbl{ diff --git a/pkg/webview2/ICoreWebView2Certificate.go b/pkg/webview2/ICoreWebView2Certificate.go index 6ca1d4e..215add8 100644 --- a/pkg/webview2/ICoreWebView2Certificate.go +++ b/pkg/webview2/ICoreWebView2Certificate.go @@ -29,13 +29,26 @@ func (i *ICoreWebView2Certificate) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Certificate) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2Certificate) GetSubject() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetSubject.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -52,7 +65,7 @@ func (i *ICoreWebView2Certificate) GetIssuer() (string, error) { hr, _, _ := i.Vtbl.GetIssuer.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -97,7 +110,7 @@ func (i *ICoreWebView2Certificate) GetDerEncodedSerialNumber() (string, error) { hr, _, _ := i.Vtbl.GetDerEncodedSerialNumber.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -114,7 +127,7 @@ func (i *ICoreWebView2Certificate) GetDisplayName() (string, error) { hr, _, _ := i.Vtbl.GetDisplayName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -131,7 +144,7 @@ func (i *ICoreWebView2Certificate) ToPemEncoding() (string, error) { hr, _, _ := i.Vtbl.ToPemEncoding.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_pemEncodedData)), + uintptr(unsafe.Pointer(&_pemEncodedData)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ClientCertificate.go b/pkg/webview2/ICoreWebView2ClientCertificate.go index 6d2dc6b..ea37f84 100644 --- a/pkg/webview2/ICoreWebView2ClientCertificate.go +++ b/pkg/webview2/ICoreWebView2ClientCertificate.go @@ -30,13 +30,26 @@ func (i *ICoreWebView2ClientCertificate) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ClientCertificate) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ClientCertificate) GetSubject() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetSubject.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -53,7 +66,7 @@ func (i *ICoreWebView2ClientCertificate) GetIssuer() (string, error) { hr, _, _ := i.Vtbl.GetIssuer.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -98,7 +111,7 @@ func (i *ICoreWebView2ClientCertificate) GetDerEncodedSerialNumber() (string, er hr, _, _ := i.Vtbl.GetDerEncodedSerialNumber.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -115,7 +128,7 @@ func (i *ICoreWebView2ClientCertificate) GetDisplayName() (string, error) { hr, _, _ := i.Vtbl.GetDisplayName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -132,7 +145,7 @@ func (i *ICoreWebView2ClientCertificate) ToPemEncoding() (string, error) { hr, _, _ := i.Vtbl.ToPemEncoding.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_pemEncodedData)), + uintptr(unsafe.Pointer(&_pemEncodedData)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ClientCertificateCollection.go b/pkg/webview2/ICoreWebView2ClientCertificateCollection.go index d413394..53b506e 100644 --- a/pkg/webview2/ICoreWebView2ClientCertificateCollection.go +++ b/pkg/webview2/ICoreWebView2ClientCertificateCollection.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2ClientCertificateCollection) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ClientCertificateCollection) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ClientCertificateCollection) GetCount() (uint32, error) { var value uint32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2ClientCertificateCollection) GetValueAtIndex(index uint32) hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2ClientCertificateRequestedEventArgs.go b/pkg/webview2/ICoreWebView2ClientCertificateRequestedEventArgs.go index d0a2fde..c77b4fb 100644 --- a/pkg/webview2/ICoreWebView2ClientCertificateRequestedEventArgs.go +++ b/pkg/webview2/ICoreWebView2ClientCertificateRequestedEventArgs.go @@ -33,13 +33,26 @@ func (i *ICoreWebView2ClientCertificateRequestedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ClientCertificateRequestedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ClientCertificateRequestedEventArgs) GetHost() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetHost.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -50,13 +63,13 @@ func (i *ICoreWebView2ClientCertificateRequestedEventArgs) GetHost() (string, er return value, nil } -func (i *ICoreWebView2ClientCertificateRequestedEventArgs) GetPort() (int, error) { +func (i *ICoreWebView2ClientCertificateRequestedEventArgs) GetPort() (int32, error) { - var value int + var value int32 hr, _, _ := i.Vtbl.GetPort.Call( uintptr(unsafe.Pointer(i)), - uintptr(value), + uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { return 0, syscall.Errno(hr) @@ -154,7 +167,7 @@ func (i *ICoreWebView2ClientCertificateRequestedEventArgs) PutCancel(value bool) hr, _, _ := i.Vtbl.PutCancel.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -182,7 +195,7 @@ func (i *ICoreWebView2ClientCertificateRequestedEventArgs) PutHandled(value bool hr, _, _ := i.Vtbl.PutHandled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2CompositionController.go b/pkg/webview2/ICoreWebView2CompositionController.go index ff07e6b..53728f2 100644 --- a/pkg/webview2/ICoreWebView2CompositionController.go +++ b/pkg/webview2/ICoreWebView2CompositionController.go @@ -29,6 +29,19 @@ func (i *ICoreWebView2CompositionController) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2CompositionController) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2CompositionController) GetRootVisualTarget() (*IUnknown, error) { var target *IUnknown @@ -61,8 +74,8 @@ func (i *ICoreWebView2CompositionController) SendMouseInput(eventKind COREWEBVIE uintptr(unsafe.Pointer(i)), uintptr(eventKind), uintptr(virtualKeys), - uintptr(unsafe.Pointer(&mouseData)), - uintptr(unsafe.Pointer(&point)), + uintptr(mouseData), + uintptr(*(*uint64)(unsafe.Pointer(&point))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -130,7 +143,7 @@ func (i *ICoreWebView2CompositionController) RemoveCursorChanged(token EventRegi hr, _, _ := i.Vtbl.RemoveCursorChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2CompositionController2.go b/pkg/webview2/ICoreWebView2CompositionController2.go index dadefc5..10dd6bc 100644 --- a/pkg/webview2/ICoreWebView2CompositionController2.go +++ b/pkg/webview2/ICoreWebView2CompositionController2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2CompositionController2Vtbl struct { - IUnknownVtbl + ICoreWebView2CompositionControllerVtbl GetAutomationProvider ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2CompositionController2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2CompositionController2() *ICoreWebView2CompositionController2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2CompositionController2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2CompositionController) GetICoreWebView2CompositionController2() *ICoreWebView2CompositionController2 { var result *ICoreWebView2CompositionController2 iidICoreWebView2CompositionController2 := NewGUID("{0b6a3d24-49cb-4806-ba20-b5e0734a7b26}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2CompositionController2)), diff --git a/pkg/webview2/ICoreWebView2CompositionController3.go b/pkg/webview2/ICoreWebView2CompositionController3.go index 713e89d..91d5f45 100644 --- a/pkg/webview2/ICoreWebView2CompositionController3.go +++ b/pkg/webview2/ICoreWebView2CompositionController3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2CompositionController3Vtbl struct { - IUnknownVtbl + ICoreWebView2CompositionController2Vtbl DragEnter ComProc DragLeave ComProc DragOver ComProc @@ -25,10 +25,30 @@ func (i *ICoreWebView2CompositionController3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2CompositionController3() *ICoreWebView2CompositionController3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2CompositionController3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2CompositionController) GetICoreWebView2CompositionController3() *ICoreWebView2CompositionController3 { var result *ICoreWebView2CompositionController3 iidICoreWebView2CompositionController3 := NewGUID("{9570570e-4d76-4361-9ee1-f04d0dbdfb1e}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2CompositionController3)), @@ -44,8 +64,8 @@ func (i *ICoreWebView2CompositionController3) DragEnter(dataObject *IDataObject, hr, _, _ := i.Vtbl.DragEnter.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(dataObject)), - uintptr(unsafe.Pointer(&keyState)), - uintptr(unsafe.Pointer(&point)), + uintptr(keyState), + uintptr(*(*uint64)(unsafe.Pointer(&point))), uintptr(unsafe.Pointer(&effect)), ) if windows.Handle(hr) != windows.S_OK { @@ -71,8 +91,8 @@ func (i *ICoreWebView2CompositionController3) DragOver(keyState uint32, point PO hr, _, _ := i.Vtbl.DragOver.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&keyState)), - uintptr(unsafe.Pointer(&point)), + uintptr(keyState), + uintptr(*(*uint64)(unsafe.Pointer(&point))), uintptr(unsafe.Pointer(&effect)), ) if windows.Handle(hr) != windows.S_OK { @@ -88,8 +108,8 @@ func (i *ICoreWebView2CompositionController3) Drop(dataObject *IDataObject, keyS hr, _, _ := i.Vtbl.Drop.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(dataObject)), - uintptr(unsafe.Pointer(&keyState)), - uintptr(unsafe.Pointer(&point)), + uintptr(keyState), + uintptr(*(*uint64)(unsafe.Pointer(&point))), uintptr(unsafe.Pointer(&effect)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2CompositionController4.go b/pkg/webview2/ICoreWebView2CompositionController4.go index 6853145..5b9e693 100644 --- a/pkg/webview2/ICoreWebView2CompositionController4.go +++ b/pkg/webview2/ICoreWebView2CompositionController4.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2CompositionController4Vtbl struct { - IUnknownVtbl + ICoreWebView2CompositionController3Vtbl GetNonClientRegionAtPoint ComProc QueryNonClientRegion ComProc AddNonClientRegionChanged ComProc @@ -25,10 +25,30 @@ func (i *ICoreWebView2CompositionController4) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2CompositionController4() *ICoreWebView2CompositionController4 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2CompositionController4) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2CompositionController) GetICoreWebView2CompositionController4() *ICoreWebView2CompositionController4 { var result *ICoreWebView2CompositionController4 iidICoreWebView2CompositionController4 := NewGUID("{7C367B9B-3D2B-450F-9E58-D61A20F486AA}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2CompositionController4)), @@ -43,7 +63,7 @@ func (i *ICoreWebView2CompositionController4) GetNonClientRegionAtPoint(point PO hr, _, _ := i.Vtbl.GetNonClientRegionAtPoint.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&point)), + uintptr(*(*uint64)(unsafe.Pointer(&point))), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { @@ -86,7 +106,7 @@ func (i *ICoreWebView2CompositionController4) RemoveNonClientRegionChanged(token hr, _, _ := i.Vtbl.RemoveNonClientRegionChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ContentLoadingEventArgs.go b/pkg/webview2/ICoreWebView2ContentLoadingEventArgs.go index 44f0326..37b7c5c 100644 --- a/pkg/webview2/ICoreWebView2ContentLoadingEventArgs.go +++ b/pkg/webview2/ICoreWebView2ContentLoadingEventArgs.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2ContentLoadingEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ContentLoadingEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ContentLoadingEventArgs) GetIsErrorPage() (bool, error) { // Create int32 to hold bool result var _value int32 diff --git a/pkg/webview2/ICoreWebView2ContextMenuItem.go b/pkg/webview2/ICoreWebView2ContextMenuItem.go index 525c6b6..a829317 100644 --- a/pkg/webview2/ICoreWebView2ContextMenuItem.go +++ b/pkg/webview2/ICoreWebView2ContextMenuItem.go @@ -34,13 +34,26 @@ func (i *ICoreWebView2ContextMenuItem) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ContextMenuItem) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ContextMenuItem) GetName() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -57,7 +70,7 @@ func (i *ICoreWebView2ContextMenuItem) GetLabel() (string, error) { hr, _, _ := i.Vtbl.GetLabel.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -88,7 +101,7 @@ func (i *ICoreWebView2ContextMenuItem) GetShortcutKeyDescription() (string, erro hr, _, _ := i.Vtbl.GetShortcutKeyDescription.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -131,7 +144,7 @@ func (i *ICoreWebView2ContextMenuItem) PutIsEnabled(value bool) error { hr, _, _ := i.Vtbl.PutIsEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -159,7 +172,7 @@ func (i *ICoreWebView2ContextMenuItem) PutIsChecked(value bool) error { hr, _, _ := i.Vtbl.PutIsChecked.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -216,7 +229,7 @@ func (i *ICoreWebView2ContextMenuItem) RemoveCustomItemSelected(token EventRegis hr, _, _ := i.Vtbl.RemoveCustomItemSelected.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ContextMenuItemCollection.go b/pkg/webview2/ICoreWebView2ContextMenuItemCollection.go index 2759ce7..2061dd6 100644 --- a/pkg/webview2/ICoreWebView2ContextMenuItemCollection.go +++ b/pkg/webview2/ICoreWebView2ContextMenuItemCollection.go @@ -25,6 +25,19 @@ func (i *ICoreWebView2ContextMenuItemCollection) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ContextMenuItemCollection) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ContextMenuItemCollection) GetCount() (uint32, error) { var value uint32 @@ -45,7 +58,7 @@ func (i *ICoreWebView2ContextMenuItemCollection) GetValueAtIndex(index uint32) ( hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { @@ -58,7 +71,7 @@ func (i *ICoreWebView2ContextMenuItemCollection) RemoveValueAtIndex(index uint32 hr, _, _ := i.Vtbl.RemoveValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -70,7 +83,7 @@ func (i *ICoreWebView2ContextMenuItemCollection) InsertValueAtIndex(index uint32 hr, _, _ := i.Vtbl.InsertValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2ContextMenuRequestedEventArgs.go b/pkg/webview2/ICoreWebView2ContextMenuRequestedEventArgs.go index 46f6c3f..d8399f5 100644 --- a/pkg/webview2/ICoreWebView2ContextMenuRequestedEventArgs.go +++ b/pkg/webview2/ICoreWebView2ContextMenuRequestedEventArgs.go @@ -29,6 +29,19 @@ func (i *ICoreWebView2ContextMenuRequestedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ContextMenuRequestedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ContextMenuRequestedEventArgs) GetMenuItems() (*ICoreWebView2ContextMenuItemCollection, error) { var value *ICoreWebView2ContextMenuItemCollection @@ -75,7 +88,7 @@ func (i *ICoreWebView2ContextMenuRequestedEventArgs) PutSelectedCommandId(value hr, _, _ := i.Vtbl.PutSelectedCommandId.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + uintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -101,7 +114,7 @@ func (i *ICoreWebView2ContextMenuRequestedEventArgs) PutHandled(value bool) erro hr, _, _ := i.Vtbl.PutHandled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ContextMenuTarget.go b/pkg/webview2/ICoreWebView2ContextMenuTarget.go index 58eaf0f..d381d7a 100644 --- a/pkg/webview2/ICoreWebView2ContextMenuTarget.go +++ b/pkg/webview2/ICoreWebView2ContextMenuTarget.go @@ -34,6 +34,19 @@ func (i *ICoreWebView2ContextMenuTarget) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ContextMenuTarget) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ContextMenuTarget) GetKind() (COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND, error) { var value COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND @@ -86,7 +99,7 @@ func (i *ICoreWebView2ContextMenuTarget) GetPageUri() (string, error) { hr, _, _ := i.Vtbl.GetPageUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -103,7 +116,7 @@ func (i *ICoreWebView2ContextMenuTarget) GetFrameUri() (string, error) { hr, _, _ := i.Vtbl.GetFrameUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -136,7 +149,7 @@ func (i *ICoreWebView2ContextMenuTarget) GetLinkUri() (string, error) { hr, _, _ := i.Vtbl.GetLinkUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -169,7 +182,7 @@ func (i *ICoreWebView2ContextMenuTarget) GetLinkText() (string, error) { hr, _, _ := i.Vtbl.GetLinkText.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -202,7 +215,7 @@ func (i *ICoreWebView2ContextMenuTarget) GetSourceUri() (string, error) { hr, _, _ := i.Vtbl.GetSourceUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -235,7 +248,7 @@ func (i *ICoreWebView2ContextMenuTarget) GetSelectionText() (string, error) { hr, _, _ := i.Vtbl.GetSelectionText.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Controller.go b/pkg/webview2/ICoreWebView2Controller.go index 18347d6..46273df 100644 --- a/pkg/webview2/ICoreWebView2Controller.go +++ b/pkg/webview2/ICoreWebView2Controller.go @@ -4,6 +4,7 @@ package webview2 import ( "golang.org/x/sys/windows" + "math" "syscall" "unsafe" ) @@ -44,6 +45,19 @@ func (i *ICoreWebView2Controller) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Controller) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2Controller) GetIsVisible() (bool, error) { // Create int32 to hold bool result var _isVisible int32 @@ -64,7 +78,7 @@ func (i *ICoreWebView2Controller) PutIsVisible(isVisible bool) error { hr, _, _ := i.Vtbl.PutIsVisible.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isVisible)), + boolToUintptr(isVisible), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -116,7 +130,7 @@ func (i *ICoreWebView2Controller) PutZoomFactor(zoomFactor float64) error { hr, _, _ := i.Vtbl.PutZoomFactor.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&zoomFactor)), + uintptr(math.Float64bits(zoomFactor)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -143,7 +157,7 @@ func (i *ICoreWebView2Controller) RemoveZoomFactorChanged(token EventRegistratio hr, _, _ := i.Vtbl.RemoveZoomFactorChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -156,7 +170,7 @@ func (i *ICoreWebView2Controller) SetBoundsAndZoomFactor(bounds RECT, zoomFactor hr, _, _ := i.Vtbl.SetBoundsAndZoomFactor.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&bounds)), - uintptr(unsafe.Pointer(&zoomFactor)), + uintptr(math.Float64bits(zoomFactor)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -195,7 +209,7 @@ func (i *ICoreWebView2Controller) RemoveMoveFocusRequested(token EventRegistrati hr, _, _ := i.Vtbl.RemoveMoveFocusRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -222,7 +236,7 @@ func (i *ICoreWebView2Controller) RemoveGotFocus(token EventRegistrationToken) e hr, _, _ := i.Vtbl.RemoveGotFocus.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -249,7 +263,7 @@ func (i *ICoreWebView2Controller) RemoveLostFocus(token EventRegistrationToken) hr, _, _ := i.Vtbl.RemoveLostFocus.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -276,7 +290,7 @@ func (i *ICoreWebView2Controller) RemoveAcceleratorKeyPressed(token EventRegistr hr, _, _ := i.Vtbl.RemoveAcceleratorKeyPressed.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -302,7 +316,7 @@ func (i *ICoreWebView2Controller) PutParentWindow(parentWindow HWND) error { hr, _, _ := i.Vtbl.PutParentWindow.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&parentWindow)), + uintptr(parentWindow), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Controller2.go b/pkg/webview2/ICoreWebView2Controller2.go index e4891c4..a168d35 100644 --- a/pkg/webview2/ICoreWebView2Controller2.go +++ b/pkg/webview2/ICoreWebView2Controller2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Controller2Vtbl struct { - IUnknownVtbl + ICoreWebView2ControllerVtbl GetDefaultBackgroundColor ComProc PutDefaultBackgroundColor ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Controller2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Controller2() *ICoreWebView2Controller2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Controller2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Controller) GetICoreWebView2Controller2() *ICoreWebView2Controller2 { var result *ICoreWebView2Controller2 iidICoreWebView2Controller2 := NewGUID("{c979903e-d4ca-4228-92eb-47ee3fa96eab}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Controller2)), @@ -53,7 +73,7 @@ func (i *ICoreWebView2Controller2) PutDefaultBackgroundColor(value COREWEBVIEW2_ hr, _, _ := i.Vtbl.PutDefaultBackgroundColor.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + uintptr(*(*uint32)(unsafe.Pointer(&value))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Controller3.go b/pkg/webview2/ICoreWebView2Controller3.go index 8dd5b03..1dd947f 100644 --- a/pkg/webview2/ICoreWebView2Controller3.go +++ b/pkg/webview2/ICoreWebView2Controller3.go @@ -4,12 +4,13 @@ package webview2 import ( "golang.org/x/sys/windows" + "math" "syscall" "unsafe" ) type ICoreWebView2Controller3Vtbl struct { - IUnknownVtbl + ICoreWebView2Controller2Vtbl GetRasterizationScale ComProc PutRasterizationScale ComProc GetShouldDetectMonitorScaleChanges ComProc @@ -29,10 +30,30 @@ func (i *ICoreWebView2Controller3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Controller3() *ICoreWebView2Controller3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Controller3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Controller) GetICoreWebView2Controller3() *ICoreWebView2Controller3 { var result *ICoreWebView2Controller3 iidICoreWebView2Controller3 := NewGUID("{f9614724-5d2b-41dc-aef7-73d62b51543b}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Controller3)), @@ -59,7 +80,7 @@ func (i *ICoreWebView2Controller3) PutRasterizationScale(scale float64) error { hr, _, _ := i.Vtbl.PutRasterizationScale.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&scale)), + uintptr(math.Float64bits(scale)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -84,16 +105,10 @@ func (i *ICoreWebView2Controller3) GetShouldDetectMonitorScaleChanges() (bool, e } func (i *ICoreWebView2Controller3) PutShouldDetectMonitorScaleChanges(value bool) error { - var intValue uintptr - if value { - intValue = 1 - } else { - intValue = 0 - } hr, _, _ := i.Vtbl.PutShouldDetectMonitorScaleChanges.Call( uintptr(unsafe.Pointer(i)), - intValue, + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -120,7 +135,7 @@ func (i *ICoreWebView2Controller3) RemoveRasterizationScaleChanged(token EventRe hr, _, _ := i.Vtbl.RemoveRasterizationScaleChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Controller4.go b/pkg/webview2/ICoreWebView2Controller4.go index eccc0ea..27f7f17 100644 --- a/pkg/webview2/ICoreWebView2Controller4.go +++ b/pkg/webview2/ICoreWebView2Controller4.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Controller4Vtbl struct { - IUnknownVtbl + ICoreWebView2Controller3Vtbl GetAllowExternalDrop ComProc PutAllowExternalDrop ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Controller4) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Controller4() *ICoreWebView2Controller4 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Controller4) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Controller) GetICoreWebView2Controller4() *ICoreWebView2Controller4 { var result *ICoreWebView2Controller4 iidICoreWebView2Controller4 := NewGUID("{97d418d5-a426-4e49-a151-e1a10f327d9e}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Controller4)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2Controller4) PutAllowExternalDrop(value bool) error { hr, _, _ := i.Vtbl.PutAllowExternalDrop.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ControllerOptions.go b/pkg/webview2/ICoreWebView2ControllerOptions.go index fb6cc2f..4beec17 100644 --- a/pkg/webview2/ICoreWebView2ControllerOptions.go +++ b/pkg/webview2/ICoreWebView2ControllerOptions.go @@ -25,13 +25,26 @@ func (i *ICoreWebView2ControllerOptions) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ControllerOptions) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ControllerOptions) GetProfileName() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetProfileName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -80,7 +93,7 @@ func (i *ICoreWebView2ControllerOptions) PutIsInPrivateModeEnabled(value bool) e hr, _, _ := i.Vtbl.PutIsInPrivateModeEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ControllerOptions2.go b/pkg/webview2/ICoreWebView2ControllerOptions2.go index 41aef9b..f999966 100644 --- a/pkg/webview2/ICoreWebView2ControllerOptions2.go +++ b/pkg/webview2/ICoreWebView2ControllerOptions2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2ControllerOptions2Vtbl struct { - IUnknownVtbl + ICoreWebView2ControllerOptionsVtbl GetScriptLocale ComProc PutScriptLocale ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2ControllerOptions2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2ControllerOptions2() *ICoreWebView2ControllerOptions2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ControllerOptions2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2ControllerOptions) GetICoreWebView2ControllerOptions2() *ICoreWebView2ControllerOptions2 { var result *ICoreWebView2ControllerOptions2 iidICoreWebView2ControllerOptions2 := NewGUID("{06c991d8-9e7e-11ed-a8fc-0242ac120002}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2ControllerOptions2)), @@ -41,7 +61,7 @@ func (i *ICoreWebView2ControllerOptions2) GetScriptLocale() (string, error) { hr, _, _ := i.Vtbl.GetScriptLocale.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Cookie.go b/pkg/webview2/ICoreWebView2Cookie.go index 8dd2dae..4d4a91a 100644 --- a/pkg/webview2/ICoreWebView2Cookie.go +++ b/pkg/webview2/ICoreWebView2Cookie.go @@ -4,6 +4,7 @@ package webview2 import ( "golang.org/x/sys/windows" + "math" "syscall" "unsafe" ) @@ -35,13 +36,26 @@ func (i *ICoreWebView2Cookie) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Cookie) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2Cookie) GetName() (string, error) { // Create *uint16 to hold result var _name *uint16 hr, _, _ := i.Vtbl.GetName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_name)), + uintptr(unsafe.Pointer(&_name)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -58,7 +72,7 @@ func (i *ICoreWebView2Cookie) GetValue() (string, error) { hr, _, _ := i.Vtbl.GetValue.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -93,7 +107,7 @@ func (i *ICoreWebView2Cookie) GetDomain() (string, error) { hr, _, _ := i.Vtbl.GetDomain.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_domain)), + uintptr(unsafe.Pointer(&_domain)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -110,7 +124,7 @@ func (i *ICoreWebView2Cookie) GetPath() (string, error) { hr, _, _ := i.Vtbl.GetPath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_path)), + uintptr(unsafe.Pointer(&_path)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -139,7 +153,7 @@ func (i *ICoreWebView2Cookie) PutExpires(expires float64) error { hr, _, _ := i.Vtbl.PutExpires.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&expires)), + uintptr(math.Float64bits(expires)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -167,7 +181,7 @@ func (i *ICoreWebView2Cookie) PutIsHttpOnly(isHttpOnly bool) error { hr, _, _ := i.Vtbl.PutIsHttpOnly.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isHttpOnly)), + boolToUintptr(isHttpOnly), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -221,7 +235,7 @@ func (i *ICoreWebView2Cookie) PutIsSecure(isSecure bool) error { hr, _, _ := i.Vtbl.PutIsSecure.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isSecure)), + boolToUintptr(isSecure), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2CookieList.go b/pkg/webview2/ICoreWebView2CookieList.go index 69a7318..6f1e830 100644 --- a/pkg/webview2/ICoreWebView2CookieList.go +++ b/pkg/webview2/ICoreWebView2CookieList.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2CookieList) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2CookieList) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2CookieList) GetCount() (uint32, error) { var value uint32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2CookieList) GetValueAtIndex(index uint32) (*ICoreWebView2C hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2CookieManager.go b/pkg/webview2/ICoreWebView2CookieManager.go index b7fd879..10195a0 100644 --- a/pkg/webview2/ICoreWebView2CookieManager.go +++ b/pkg/webview2/ICoreWebView2CookieManager.go @@ -29,6 +29,19 @@ func (i *ICoreWebView2CookieManager) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2CookieManager) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2CookieManager) CreateCookie(name string, value string, domain string, path string) (*ICoreWebView2Cookie, error) { // Convert string 'name' to *uint16 diff --git a/pkg/webview2/ICoreWebView2CustomSchemeRegistration.go b/pkg/webview2/ICoreWebView2CustomSchemeRegistration.go index 034024a..711a0ba 100644 --- a/pkg/webview2/ICoreWebView2CustomSchemeRegistration.go +++ b/pkg/webview2/ICoreWebView2CustomSchemeRegistration.go @@ -28,13 +28,26 @@ func (i *ICoreWebView2CustomSchemeRegistration) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2CustomSchemeRegistration) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2CustomSchemeRegistration) GetSchemeName() (string, error) { // Create *uint16 to hold result var _schemeName *uint16 hr, _, _ := i.Vtbl.GetSchemeName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_schemeName)), + uintptr(unsafe.Pointer(&_schemeName)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -65,7 +78,7 @@ func (i *ICoreWebView2CustomSchemeRegistration) PutTreatAsSecure(value bool) err hr, _, _ := i.Vtbl.PutTreatAsSecure.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -81,7 +94,7 @@ func (i *ICoreWebView2CustomSchemeRegistration) GetAllowedOrigins() (uint32, *st hr, _, _ := i.Vtbl.GetAllowedOrigins.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&allowedOriginsCount)), - uintptr(unsafe.Pointer(allowedOrigins)), + uintptr(unsafe.Pointer(&allowedOrigins)), ) if windows.Handle(hr) != windows.S_OK { return 0, nil, syscall.Errno(hr) @@ -99,7 +112,7 @@ func (i *ICoreWebView2CustomSchemeRegistration) SetAllowedOrigins(allowedOrigins hr, _, _ := i.Vtbl.SetAllowedOrigins.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&allowedOriginsCount)), + uintptr(allowedOriginsCount), uintptr(unsafe.Pointer(_allowedOrigins)), ) if windows.Handle(hr) != windows.S_OK { @@ -128,7 +141,7 @@ func (i *ICoreWebView2CustomSchemeRegistration) PutHasAuthorityComponent(hasAuth hr, _, _ := i.Vtbl.PutHasAuthorityComponent.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&hasAuthorityComponent)), + boolToUintptr(hasAuthorityComponent), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2DOMContentLoadedEventArgs.go b/pkg/webview2/ICoreWebView2DOMContentLoadedEventArgs.go index d2b3b34..2a96e56 100644 --- a/pkg/webview2/ICoreWebView2DOMContentLoadedEventArgs.go +++ b/pkg/webview2/ICoreWebView2DOMContentLoadedEventArgs.go @@ -22,6 +22,19 @@ func (i *ICoreWebView2DOMContentLoadedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2DOMContentLoadedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2DOMContentLoadedEventArgs) GetNavigationId() (uint64, error) { var value uint64 diff --git a/pkg/webview2/ICoreWebView2Deferral.go b/pkg/webview2/ICoreWebView2Deferral.go index efe5775..0898ad3 100644 --- a/pkg/webview2/ICoreWebView2Deferral.go +++ b/pkg/webview2/ICoreWebView2Deferral.go @@ -22,6 +22,19 @@ func (i *ICoreWebView2Deferral) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Deferral) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2Deferral) Complete() error { hr, _, _ := i.Vtbl.Complete.Call( diff --git a/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceivedEventArgs.go b/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceivedEventArgs.go index 7225340..4e7d7e7 100644 --- a/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceivedEventArgs.go +++ b/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceivedEventArgs.go @@ -22,13 +22,26 @@ func (i *ICoreWebView2DevToolsProtocolEventReceivedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2DevToolsProtocolEventReceivedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2DevToolsProtocolEventReceivedEventArgs) GetParameterObjectAsJson() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetParameterObjectAsJson.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceivedEventArgs2.go b/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceivedEventArgs2.go index 2a85d90..c9e324c 100644 --- a/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceivedEventArgs2.go +++ b/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceivedEventArgs2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2DevToolsProtocolEventReceivedEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2DevToolsProtocolEventReceivedEventArgsVtbl GetSessionId ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2DevToolsProtocolEventReceivedEventArgs2) AddRef() uintptr return refCounter } -func (i *ICoreWebView2) GetICoreWebView2DevToolsProtocolEventReceivedEventArgs2() *ICoreWebView2DevToolsProtocolEventReceivedEventArgs2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2DevToolsProtocolEventReceivedEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2DevToolsProtocolEventReceivedEventArgs) GetICoreWebView2DevToolsProtocolEventReceivedEventArgs2() *ICoreWebView2DevToolsProtocolEventReceivedEventArgs2 { var result *ICoreWebView2DevToolsProtocolEventReceivedEventArgs2 iidICoreWebView2DevToolsProtocolEventReceivedEventArgs2 := NewGUID("{2dc4959d-1494-4393-95ba-bea4cb9ebd1b}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2DevToolsProtocolEventReceivedEventArgs2)), @@ -40,7 +60,7 @@ func (i *ICoreWebView2DevToolsProtocolEventReceivedEventArgs2) GetSessionId() (s hr, _, _ := i.Vtbl.GetSessionId.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceiver.go b/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceiver.go index 0750648..e0376bb 100644 --- a/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceiver.go +++ b/pkg/webview2/ICoreWebView2DevToolsProtocolEventReceiver.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2DevToolsProtocolEventReceiver) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2DevToolsProtocolEventReceiver) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2DevToolsProtocolEventReceiver) AddDevToolsProtocolEventReceived(eventHandler *ICoreWebView2DevToolsProtocolEventReceivedEventHandler) (EventRegistrationToken, error) { var token EventRegistrationToken @@ -42,7 +55,7 @@ func (i *ICoreWebView2DevToolsProtocolEventReceiver) RemoveDevToolsProtocolEvent hr, _, _ := i.Vtbl.RemoveDevToolsProtocolEventReceived.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2DownloadOperation.go b/pkg/webview2/ICoreWebView2DownloadOperation.go index c26339b..1d53359 100644 --- a/pkg/webview2/ICoreWebView2DownloadOperation.go +++ b/pkg/webview2/ICoreWebView2DownloadOperation.go @@ -40,6 +40,19 @@ func (i *ICoreWebView2DownloadOperation) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2DownloadOperation) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2DownloadOperation) AddBytesReceivedChanged(eventHandler *ICoreWebView2BytesReceivedChangedEventHandler) (EventRegistrationToken, error) { var token EventRegistrationToken @@ -59,7 +72,7 @@ func (i *ICoreWebView2DownloadOperation) RemoveBytesReceivedChanged(token EventR hr, _, _ := i.Vtbl.RemoveBytesReceivedChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -86,7 +99,7 @@ func (i *ICoreWebView2DownloadOperation) RemoveEstimatedEndTimeChanged(token Eve hr, _, _ := i.Vtbl.RemoveEstimatedEndTimeChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -113,7 +126,7 @@ func (i *ICoreWebView2DownloadOperation) RemoveStateChanged(token EventRegistrat hr, _, _ := i.Vtbl.RemoveStateChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -127,7 +140,7 @@ func (i *ICoreWebView2DownloadOperation) GetUri() (string, error) { hr, _, _ := i.Vtbl.GetUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_uri)), + uintptr(unsafe.Pointer(&_uri)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -144,7 +157,7 @@ func (i *ICoreWebView2DownloadOperation) GetContentDisposition() (string, error) hr, _, _ := i.Vtbl.GetContentDisposition.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_contentDisposition)), + uintptr(unsafe.Pointer(&_contentDisposition)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -161,7 +174,7 @@ func (i *ICoreWebView2DownloadOperation) GetMimeType() (string, error) { hr, _, _ := i.Vtbl.GetMimeType.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_mimeType)), + uintptr(unsafe.Pointer(&_mimeType)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -206,7 +219,7 @@ func (i *ICoreWebView2DownloadOperation) GetEstimatedEndTime() (string, error) { hr, _, _ := i.Vtbl.GetEstimatedEndTime.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_estimatedEndTime)), + uintptr(unsafe.Pointer(&_estimatedEndTime)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -223,7 +236,7 @@ func (i *ICoreWebView2DownloadOperation) GetResultFilePath() (string, error) { hr, _, _ := i.Vtbl.GetResultFilePath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_resultFilePath)), + uintptr(unsafe.Pointer(&_resultFilePath)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2DownloadStartingEventArgs.go b/pkg/webview2/ICoreWebView2DownloadStartingEventArgs.go index ac63d86..ce6d706 100644 --- a/pkg/webview2/ICoreWebView2DownloadStartingEventArgs.go +++ b/pkg/webview2/ICoreWebView2DownloadStartingEventArgs.go @@ -29,6 +29,19 @@ func (i *ICoreWebView2DownloadStartingEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2DownloadStartingEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2DownloadStartingEventArgs) GetDownloadOperation() (*ICoreWebView2DownloadOperation, error) { var downloadOperation *ICoreWebView2DownloadOperation @@ -63,7 +76,7 @@ func (i *ICoreWebView2DownloadStartingEventArgs) PutCancel(cancel bool) error { hr, _, _ := i.Vtbl.PutCancel.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&cancel)), + boolToUintptr(cancel), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -77,7 +90,7 @@ func (i *ICoreWebView2DownloadStartingEventArgs) GetResultFilePath() (string, er hr, _, _ := i.Vtbl.GetResultFilePath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_resultFilePath)), + uintptr(unsafe.Pointer(&_resultFilePath)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -126,7 +139,7 @@ func (i *ICoreWebView2DownloadStartingEventArgs) PutHandled(handled bool) error hr, _, _ := i.Vtbl.PutHandled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&handled)), + boolToUintptr(handled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Environment.go b/pkg/webview2/ICoreWebView2Environment.go index 91aae99..0ccf0c1 100644 --- a/pkg/webview2/ICoreWebView2Environment.go +++ b/pkg/webview2/ICoreWebView2Environment.go @@ -26,11 +26,24 @@ func (i *ICoreWebView2Environment) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2Environment) CreateCoreWebView2Controller(parentWindow HWND, handler *ICoreWebView2CreateCoreWebView2ControllerCompletedHandler) error { hr, _, _ := i.Vtbl.CreateCoreWebView2Controller.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&parentWindow)), + uintptr(parentWindow), uintptr(unsafe.Pointer(handler)), ) if windows.Handle(hr) != windows.S_OK { @@ -39,7 +52,7 @@ func (i *ICoreWebView2Environment) CreateCoreWebView2Controller(parentWindow HWN return nil } -func (i *ICoreWebView2Environment) CreateWebResourceResponse(content *IStream, statusCode int, reasonPhrase string, headers string) (*ICoreWebView2WebResourceResponse, error) { +func (i *ICoreWebView2Environment) CreateWebResourceResponse(content *IStream, statusCode int32, reasonPhrase string, headers string) (*ICoreWebView2WebResourceResponse, error) { // Convert string 'reasonPhrase' to *uint16 _reasonPhrase, err := UTF16PtrFromString(reasonPhrase) @@ -73,7 +86,7 @@ func (i *ICoreWebView2Environment) GetBrowserVersionString() (string, error) { hr, _, _ := i.Vtbl.GetBrowserVersionString.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_versionInfo)), + uintptr(unsafe.Pointer(&_versionInfo)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -103,7 +116,7 @@ func (i *ICoreWebView2Environment) RemoveNewBrowserVersionAvailable(token EventR hr, _, _ := i.Vtbl.RemoveNewBrowserVersionAvailable.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Environment10.go b/pkg/webview2/ICoreWebView2Environment10.go index a763a97..0b0c8a8 100644 --- a/pkg/webview2/ICoreWebView2Environment10.go +++ b/pkg/webview2/ICoreWebView2Environment10.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment10Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment9Vtbl CreateCoreWebView2ControllerOptions ComProc CreateCoreWebView2ControllerWithOptions ComProc CreateCoreWebView2CompositionControllerWithOptions ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2Environment10) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment10() *ICoreWebView2Environment10 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment10) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment10() *ICoreWebView2Environment10 { var result *ICoreWebView2Environment10 iidICoreWebView2Environment10 := NewGUID("{ee0eb9df-6f12-46ce-b53f-3f47b9c928e0}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment10)), @@ -54,7 +74,7 @@ func (i *ICoreWebView2Environment10) CreateCoreWebView2ControllerWithOptions(Par hr, _, _ := i.Vtbl.CreateCoreWebView2ControllerWithOptions.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&ParentWindow)), + uintptr(ParentWindow), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(handler)), ) @@ -68,7 +88,7 @@ func (i *ICoreWebView2Environment10) CreateCoreWebView2CompositionControllerWith hr, _, _ := i.Vtbl.CreateCoreWebView2CompositionControllerWithOptions.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&ParentWindow)), + uintptr(ParentWindow), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(handler)), ) diff --git a/pkg/webview2/ICoreWebView2Environment11.go b/pkg/webview2/ICoreWebView2Environment11.go index 01c1750..f9b4534 100644 --- a/pkg/webview2/ICoreWebView2Environment11.go +++ b/pkg/webview2/ICoreWebView2Environment11.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment11Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment10Vtbl GetFailureReportFolderPath ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Environment11) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment11() *ICoreWebView2Environment11 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment11) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment11() *ICoreWebView2Environment11 { var result *ICoreWebView2Environment11 iidICoreWebView2Environment11 := NewGUID("{f0913dc6-a0ec-42ef-9805-91dff3a2966a}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment11)), @@ -40,7 +60,7 @@ func (i *ICoreWebView2Environment11) GetFailureReportFolderPath() (string, error hr, _, _ := i.Vtbl.GetFailureReportFolderPath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Environment12.go b/pkg/webview2/ICoreWebView2Environment12.go index f90c8d1..105eb07 100644 --- a/pkg/webview2/ICoreWebView2Environment12.go +++ b/pkg/webview2/ICoreWebView2Environment12.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment12Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment11Vtbl CreateSharedBuffer ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Environment12) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment12() *ICoreWebView2Environment12 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment12) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment12() *ICoreWebView2Environment12 { var result *ICoreWebView2Environment12 iidICoreWebView2Environment12 := NewGUID("{f503db9b-739f-48dd-b151-fdfcf253f54e}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment12)), @@ -40,7 +60,7 @@ func (i *ICoreWebView2Environment12) CreateSharedBuffer(Size uint64) (*ICoreWebV hr, _, _ := i.Vtbl.CreateSharedBuffer.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&Size)), + uintptr(Size), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2Environment13.go b/pkg/webview2/ICoreWebView2Environment13.go index 827acfc..f3c1b9e 100644 --- a/pkg/webview2/ICoreWebView2Environment13.go +++ b/pkg/webview2/ICoreWebView2Environment13.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment13Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment12Vtbl GetProcessExtendedInfos ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Environment13) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment13() *ICoreWebView2Environment13 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment13) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment13() *ICoreWebView2Environment13 { var result *ICoreWebView2Environment13 iidICoreWebView2Environment13 := NewGUID("{af641f58-72b2-11ee-b962-0242ac120002}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment13)), diff --git a/pkg/webview2/ICoreWebView2Environment14.go b/pkg/webview2/ICoreWebView2Environment14.go index ec7605d..e03d5c2 100644 --- a/pkg/webview2/ICoreWebView2Environment14.go +++ b/pkg/webview2/ICoreWebView2Environment14.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment14Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment13Vtbl CreateWebFileSystemFileHandle ComProc CreateWebFileSystemDirectoryHandle ComProc CreateObjectCollection ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2Environment14) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment14() *ICoreWebView2Environment14 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment14) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment14() *ICoreWebView2Environment14 { var result *ICoreWebView2Environment14 iidICoreWebView2Environment14 := NewGUID("{a5e9fad9-c875-59da-9bd7-473aa5ca1cef}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment14)), @@ -84,8 +104,8 @@ func (i *ICoreWebView2Environment14) CreateObjectCollection(length uint32, items hr, _, _ := i.Vtbl.CreateObjectCollection.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&length)), - uintptr(unsafe.Pointer(&items)), + uintptr(length), + uintptr(unsafe.Pointer(items)), uintptr(unsafe.Pointer(&objectCollection)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2Environment2.go b/pkg/webview2/ICoreWebView2Environment2.go index 914cce3..d24981e 100644 --- a/pkg/webview2/ICoreWebView2Environment2.go +++ b/pkg/webview2/ICoreWebView2Environment2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment2Vtbl struct { - IUnknownVtbl + ICoreWebView2EnvironmentVtbl CreateWebResourceRequest ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Environment2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment2() *ICoreWebView2Environment2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment2() *ICoreWebView2Environment2 { var result *ICoreWebView2Environment2 iidICoreWebView2Environment2 := NewGUID("{41f3632b-5ef4-404f-ad82-2d606c5a9a21}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment2)), diff --git a/pkg/webview2/ICoreWebView2Environment3.go b/pkg/webview2/ICoreWebView2Environment3.go index 58fbec8..302e845 100644 --- a/pkg/webview2/ICoreWebView2Environment3.go +++ b/pkg/webview2/ICoreWebView2Environment3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment3Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment2Vtbl CreateCoreWebView2CompositionController ComProc CreateCoreWebView2PointerInfo ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Environment3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment3() *ICoreWebView2Environment3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment3() *ICoreWebView2Environment3 { var result *ICoreWebView2Environment3 iidICoreWebView2Environment3 := NewGUID("{80a22ae3-be7c-4ce2-afe1-5a50056cdeeb}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment3)), @@ -39,7 +59,7 @@ func (i *ICoreWebView2Environment3) CreateCoreWebView2CompositionController(Pare hr, _, _ := i.Vtbl.CreateCoreWebView2CompositionController.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&ParentWindow)), + uintptr(ParentWindow), uintptr(unsafe.Pointer(handler)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2Environment4.go b/pkg/webview2/ICoreWebView2Environment4.go index 3be765f..fd6b264 100644 --- a/pkg/webview2/ICoreWebView2Environment4.go +++ b/pkg/webview2/ICoreWebView2Environment4.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment4Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment3Vtbl GetAutomationProviderForWindow ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Environment4) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment4() *ICoreWebView2Environment4 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment4) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment4() *ICoreWebView2Environment4 { var result *ICoreWebView2Environment4 iidICoreWebView2Environment4 := NewGUID("{20944379-6dcf-41d6-a0a0-abc0fc50de0d}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment4)), @@ -40,7 +60,7 @@ func (i *ICoreWebView2Environment4) GetAutomationProviderForWindow(hwnd HWND) (* hr, _, _ := i.Vtbl.GetAutomationProviderForWindow.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&hwnd)), + uintptr(hwnd), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2Environment5.go b/pkg/webview2/ICoreWebView2Environment5.go index cd7060f..2a11380 100644 --- a/pkg/webview2/ICoreWebView2Environment5.go +++ b/pkg/webview2/ICoreWebView2Environment5.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment5Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment4Vtbl AddBrowserProcessExited ComProc RemoveBrowserProcessExited ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Environment5) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment5() *ICoreWebView2Environment5 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment5) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment5() *ICoreWebView2Environment5 { var result *ICoreWebView2Environment5 iidICoreWebView2Environment5 := NewGUID("{319e423d-e0d7-4b8d-9254-ae9475de9b17}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment5)), @@ -54,7 +74,7 @@ func (i *ICoreWebView2Environment5) RemoveBrowserProcessExited(token EventRegist hr, _, _ := i.Vtbl.RemoveBrowserProcessExited.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Environment6.go b/pkg/webview2/ICoreWebView2Environment6.go index 5265f7d..598b20c 100644 --- a/pkg/webview2/ICoreWebView2Environment6.go +++ b/pkg/webview2/ICoreWebView2Environment6.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment6Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment5Vtbl CreatePrintSettings ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Environment6) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment6() *ICoreWebView2Environment6 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment6) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment6() *ICoreWebView2Environment6 { var result *ICoreWebView2Environment6 iidICoreWebView2Environment6 := NewGUID("{e59ee362-acbd-4857-9a8e-d3644d9459a9}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment6)), diff --git a/pkg/webview2/ICoreWebView2Environment7.go b/pkg/webview2/ICoreWebView2Environment7.go index e4a652f..c55d009 100644 --- a/pkg/webview2/ICoreWebView2Environment7.go +++ b/pkg/webview2/ICoreWebView2Environment7.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment7Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment6Vtbl GetUserDataFolder ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Environment7) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment7() *ICoreWebView2Environment7 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment7) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment7() *ICoreWebView2Environment7 { var result *ICoreWebView2Environment7 iidICoreWebView2Environment7 := NewGUID("{43c22296-3bbd-43a4-9c00-5c0df6dd29a2}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment7)), @@ -40,7 +60,7 @@ func (i *ICoreWebView2Environment7) GetUserDataFolder() (string, error) { hr, _, _ := i.Vtbl.GetUserDataFolder.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Environment8.go b/pkg/webview2/ICoreWebView2Environment8.go index 9894aef..3437342 100644 --- a/pkg/webview2/ICoreWebView2Environment8.go +++ b/pkg/webview2/ICoreWebView2Environment8.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment8Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment7Vtbl AddProcessInfosChanged ComProc RemoveProcessInfosChanged ComProc GetProcessInfos ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2Environment8) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment8() *ICoreWebView2Environment8 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment8) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment8() *ICoreWebView2Environment8 { var result *ICoreWebView2Environment8 iidICoreWebView2Environment8 := NewGUID("{d6eb91dd-c3d2-45e5-bd29-6dc2bc4de9cf}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment8)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2Environment8) RemoveProcessInfosChanged(token EventRegistr hr, _, _ := i.Vtbl.RemoveProcessInfosChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Environment9.go b/pkg/webview2/ICoreWebView2Environment9.go index e324c44..b79bc67 100644 --- a/pkg/webview2/ICoreWebView2Environment9.go +++ b/pkg/webview2/ICoreWebView2Environment9.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Environment9Vtbl struct { - IUnknownVtbl + ICoreWebView2Environment8Vtbl CreateContextMenuItem ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Environment9) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Environment9() *ICoreWebView2Environment9 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Environment9) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Environment) GetICoreWebView2Environment9() *ICoreWebView2Environment9 { var result *ICoreWebView2Environment9 iidICoreWebView2Environment9 := NewGUID("{f06f41bf-4b5a-49d8-b9f6-fa16cd29f274}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Environment9)), diff --git a/pkg/webview2/ICoreWebView2EnvironmentOptions.go b/pkg/webview2/ICoreWebView2EnvironmentOptions.go index 061f78e..f6f7c9e 100644 --- a/pkg/webview2/ICoreWebView2EnvironmentOptions.go +++ b/pkg/webview2/ICoreWebView2EnvironmentOptions.go @@ -29,13 +29,26 @@ func (i *ICoreWebView2EnvironmentOptions) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2EnvironmentOptions) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2EnvironmentOptions) GetAdditionalBrowserArguments() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetAdditionalBrowserArguments.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -70,7 +83,7 @@ func (i *ICoreWebView2EnvironmentOptions) GetLanguage() (string, error) { hr, _, _ := i.Vtbl.GetLanguage.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -105,7 +118,7 @@ func (i *ICoreWebView2EnvironmentOptions) GetTargetCompatibleBrowserVersion() (s hr, _, _ := i.Vtbl.GetTargetCompatibleBrowserVersion.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -154,7 +167,7 @@ func (i *ICoreWebView2EnvironmentOptions) PutAllowSingleSignOnUsingOSPrimaryAcco hr, _, _ := i.Vtbl.PutAllowSingleSignOnUsingOSPrimaryAccount.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&allow)), + boolToUintptr(allow), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2EnvironmentOptions2.go b/pkg/webview2/ICoreWebView2EnvironmentOptions2.go index 4acef94..44e9527 100644 --- a/pkg/webview2/ICoreWebView2EnvironmentOptions2.go +++ b/pkg/webview2/ICoreWebView2EnvironmentOptions2.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2EnvironmentOptions2) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2EnvironmentOptions2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2EnvironmentOptions2) GetExclusiveUserDataFolderAccess() (bool, error) { // Create int32 to hold bool result var _value int32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2EnvironmentOptions2) PutExclusiveUserDataFolderAccess(valu hr, _, _ := i.Vtbl.PutExclusiveUserDataFolderAccess.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2EnvironmentOptions3.go b/pkg/webview2/ICoreWebView2EnvironmentOptions3.go index 9e1aad3..90022d3 100644 --- a/pkg/webview2/ICoreWebView2EnvironmentOptions3.go +++ b/pkg/webview2/ICoreWebView2EnvironmentOptions3.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2EnvironmentOptions3) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2EnvironmentOptions3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2EnvironmentOptions3) GetIsCustomCrashReportingEnabled() (bool, error) { // Create int32 to hold bool result var _value int32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2EnvironmentOptions3) PutIsCustomCrashReportingEnabled(valu hr, _, _ := i.Vtbl.PutIsCustomCrashReportingEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2EnvironmentOptions4.go b/pkg/webview2/ICoreWebView2EnvironmentOptions4.go index b675342..6bd5f62 100644 --- a/pkg/webview2/ICoreWebView2EnvironmentOptions4.go +++ b/pkg/webview2/ICoreWebView2EnvironmentOptions4.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2EnvironmentOptions4) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2EnvironmentOptions4) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2EnvironmentOptions4) GetCustomSchemeRegistrations() (uint32, ICoreWebView2CustomSchemeRegistration, error) { var count uint32 @@ -43,8 +56,8 @@ func (i *ICoreWebView2EnvironmentOptions4) SetCustomSchemeRegistrations(count ui hr, _, _ := i.Vtbl.SetCustomSchemeRegistrations.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&count)), - uintptr(unsafe.Pointer(&schemeRegistrations)), + uintptr(count), + uintptr(unsafe.Pointer(schemeRegistrations)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2EnvironmentOptions5.go b/pkg/webview2/ICoreWebView2EnvironmentOptions5.go index b213fc6..b3050a0 100644 --- a/pkg/webview2/ICoreWebView2EnvironmentOptions5.go +++ b/pkg/webview2/ICoreWebView2EnvironmentOptions5.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2EnvironmentOptions5) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2EnvironmentOptions5) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2EnvironmentOptions5) GetEnableTrackingPrevention() (bool, error) { // Create int32 to hold bool result var _value int32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2EnvironmentOptions5) PutEnableTrackingPrevention(value boo hr, _, _ := i.Vtbl.PutEnableTrackingPrevention.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2EnvironmentOptions6.go b/pkg/webview2/ICoreWebView2EnvironmentOptions6.go index 602fc37..a550786 100644 --- a/pkg/webview2/ICoreWebView2EnvironmentOptions6.go +++ b/pkg/webview2/ICoreWebView2EnvironmentOptions6.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2EnvironmentOptions6) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2EnvironmentOptions6) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2EnvironmentOptions6) GetAreBrowserExtensionsEnabled() (bool, error) { // Create int32 to hold bool result var _value int32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2EnvironmentOptions6) PutAreBrowserExtensionsEnabled(value hr, _, _ := i.Vtbl.PutAreBrowserExtensionsEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2EnvironmentOptions7.go b/pkg/webview2/ICoreWebView2EnvironmentOptions7.go index c6ebda0..ce7d960 100644 --- a/pkg/webview2/ICoreWebView2EnvironmentOptions7.go +++ b/pkg/webview2/ICoreWebView2EnvironmentOptions7.go @@ -25,6 +25,19 @@ func (i *ICoreWebView2EnvironmentOptions7) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2EnvironmentOptions7) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2EnvironmentOptions7) GetChannelSearchKind() (COREWEBVIEW2_CHANNEL_SEARCH_KIND, error) { var value COREWEBVIEW2_CHANNEL_SEARCH_KIND diff --git a/pkg/webview2/ICoreWebView2EnvironmentOptions8.go b/pkg/webview2/ICoreWebView2EnvironmentOptions8.go index 5d666ca..f716d77 100644 --- a/pkg/webview2/ICoreWebView2EnvironmentOptions8.go +++ b/pkg/webview2/ICoreWebView2EnvironmentOptions8.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2EnvironmentOptions8) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2EnvironmentOptions8) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2EnvironmentOptions8) GetScrollBarStyle() (COREWEBVIEW2_SCROLLBAR_STYLE, error) { var value COREWEBVIEW2_SCROLLBAR_STYLE diff --git a/pkg/webview2/ICoreWebView2ExecuteScriptCompletedHandler.go b/pkg/webview2/ICoreWebView2ExecuteScriptCompletedHandler.go index 160b520..e2f4f98 100644 --- a/pkg/webview2/ICoreWebView2ExecuteScriptCompletedHandler.go +++ b/pkg/webview2/ICoreWebView2ExecuteScriptCompletedHandler.go @@ -33,13 +33,13 @@ func ICoreWebView2ExecuteScriptCompletedHandlerIUnknownRelease(this *ICoreWebVie return this.impl.Release() } -func ICoreWebView2ExecuteScriptCompletedHandlerInvoke(this *ICoreWebView2ExecuteScriptCompletedHandler, errorCode uintptr, result string) uintptr { +func ICoreWebView2ExecuteScriptCompletedHandlerInvoke(this *ICoreWebView2ExecuteScriptCompletedHandler, errorCode uintptr, result *uint16) uintptr { return this.impl.ExecuteScriptCompleted(errorCode, result) } type ICoreWebView2ExecuteScriptCompletedHandlerImpl interface { IUnknownImpl - ExecuteScriptCompleted(errorCode uintptr, result string) uintptr + ExecuteScriptCompleted(errorCode uintptr, result *uint16) uintptr } var ICoreWebView2ExecuteScriptCompletedHandlerFn = ICoreWebView2ExecuteScriptCompletedHandlerVtbl{ diff --git a/pkg/webview2/ICoreWebView2ExecuteScriptResult.go b/pkg/webview2/ICoreWebView2ExecuteScriptResult.go index 73c5693..159e3c4 100644 --- a/pkg/webview2/ICoreWebView2ExecuteScriptResult.go +++ b/pkg/webview2/ICoreWebView2ExecuteScriptResult.go @@ -25,6 +25,19 @@ func (i *ICoreWebView2ExecuteScriptResult) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ExecuteScriptResult) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ExecuteScriptResult) GetSucceeded() (bool, error) { // Create int32 to hold bool result var _value int32 @@ -47,7 +60,7 @@ func (i *ICoreWebView2ExecuteScriptResult) GetResultAsJson() (string, error) { hr, _, _ := i.Vtbl.GetResultAsJson.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_jsonResult)), + uintptr(unsafe.Pointer(&_jsonResult)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -66,7 +79,7 @@ func (i *ICoreWebView2ExecuteScriptResult) TryGetResultAsString() (string, bool, hr, _, _ := i.Vtbl.TryGetResultAsString.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_stringResult)), + uintptr(unsafe.Pointer(&_stringResult)), uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2File.go b/pkg/webview2/ICoreWebView2File.go index 90089d9..a94d8fb 100644 --- a/pkg/webview2/ICoreWebView2File.go +++ b/pkg/webview2/ICoreWebView2File.go @@ -22,13 +22,26 @@ func (i *ICoreWebView2File) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2File) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2File) GetPath() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetPath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2FileSystemHandle.go b/pkg/webview2/ICoreWebView2FileSystemHandle.go index 1ae6cf3..ead48c0 100644 --- a/pkg/webview2/ICoreWebView2FileSystemHandle.go +++ b/pkg/webview2/ICoreWebView2FileSystemHandle.go @@ -24,6 +24,19 @@ func (i *ICoreWebView2FileSystemHandle) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2FileSystemHandle) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2FileSystemHandle) GetKind() (COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND, error) { var value COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND @@ -44,7 +57,7 @@ func (i *ICoreWebView2FileSystemHandle) GetPath() (string, error) { hr, _, _ := i.Vtbl.GetPath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Frame.go b/pkg/webview2/ICoreWebView2Frame.go index 3c08c98..ee02d77 100644 --- a/pkg/webview2/ICoreWebView2Frame.go +++ b/pkg/webview2/ICoreWebView2Frame.go @@ -29,13 +29,26 @@ func (i *ICoreWebView2Frame) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Frame) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2Frame) GetName() (string, error) { // Create *uint16 to hold result var _name *uint16 hr, _, _ := i.Vtbl.GetName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_name)), + uintptr(unsafe.Pointer(&_name)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -65,7 +78,7 @@ func (i *ICoreWebView2Frame) RemoveNameChanged(token EventRegistrationToken) err hr, _, _ := i.Vtbl.RemoveNameChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -90,7 +103,7 @@ func (i *ICoreWebView2Frame) AddHostObjectToScriptWithOrigins(name string, objec uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(_name)), uintptr(unsafe.Pointer(object)), - uintptr(unsafe.Pointer(&originsCount)), + uintptr(originsCount), uintptr(unsafe.Pointer(_origins)), ) if windows.Handle(hr) != windows.S_OK { @@ -136,7 +149,7 @@ func (i *ICoreWebView2Frame) RemoveDestroyed(token EventRegistrationToken) error hr, _, _ := i.Vtbl.RemoveDestroyed.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Frame2.go b/pkg/webview2/ICoreWebView2Frame2.go index 3a38dff..1390f87 100644 --- a/pkg/webview2/ICoreWebView2Frame2.go +++ b/pkg/webview2/ICoreWebView2Frame2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Frame2Vtbl struct { - IUnknownVtbl + ICoreWebView2FrameVtbl AddNavigationStarting ComProc RemoveNavigationStarting ComProc AddContentLoading ComProc @@ -34,10 +34,30 @@ func (i *ICoreWebView2Frame2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Frame2() *ICoreWebView2Frame2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Frame2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Frame) GetICoreWebView2Frame2() *ICoreWebView2Frame2 { var result *ICoreWebView2Frame2 iidICoreWebView2Frame2 := NewGUID("{7a6a5834-d185-4dbf-b63f-4a9bc43107d4}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Frame2)), @@ -65,7 +85,7 @@ func (i *ICoreWebView2Frame2) RemoveNavigationStarting(token EventRegistrationTo hr, _, _ := i.Vtbl.RemoveNavigationStarting.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -92,7 +112,7 @@ func (i *ICoreWebView2Frame2) RemoveContentLoading(token EventRegistrationToken) hr, _, _ := i.Vtbl.RemoveContentLoading.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -119,7 +139,7 @@ func (i *ICoreWebView2Frame2) RemoveNavigationCompleted(token EventRegistrationT hr, _, _ := i.Vtbl.RemoveNavigationCompleted.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -146,7 +166,7 @@ func (i *ICoreWebView2Frame2) RemoveDOMContentLoaded(token EventRegistrationToke hr, _, _ := i.Vtbl.RemoveDOMContentLoaded.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -228,7 +248,7 @@ func (i *ICoreWebView2Frame2) RemoveWebMessageReceived(token EventRegistrationTo hr, _, _ := i.Vtbl.RemoveWebMessageReceived.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Frame3.go b/pkg/webview2/ICoreWebView2Frame3.go index e386c68..74c6301 100644 --- a/pkg/webview2/ICoreWebView2Frame3.go +++ b/pkg/webview2/ICoreWebView2Frame3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Frame3Vtbl struct { - IUnknownVtbl + ICoreWebView2Frame2Vtbl AddPermissionRequested ComProc RemovePermissionRequested ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Frame3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Frame3() *ICoreWebView2Frame3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Frame3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Frame) GetICoreWebView2Frame3() *ICoreWebView2Frame3 { var result *ICoreWebView2Frame3 iidICoreWebView2Frame3 := NewGUID("{b50d82cc-cc28-481d-9614-cb048895e6a0}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Frame3)), @@ -54,7 +74,7 @@ func (i *ICoreWebView2Frame3) RemovePermissionRequested(token EventRegistrationT hr, _, _ := i.Vtbl.RemovePermissionRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Frame4.go b/pkg/webview2/ICoreWebView2Frame4.go index fb86908..8c2f152 100644 --- a/pkg/webview2/ICoreWebView2Frame4.go +++ b/pkg/webview2/ICoreWebView2Frame4.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Frame4Vtbl struct { - IUnknownVtbl + ICoreWebView2Frame3Vtbl PostSharedBufferToScript ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Frame4) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Frame4() *ICoreWebView2Frame4 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Frame4) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Frame) GetICoreWebView2Frame4() *ICoreWebView2Frame4 { var result *ICoreWebView2Frame4 iidICoreWebView2Frame4 := NewGUID("{188782dc-92aa-4732-ab3c-fcc59f6f68b9}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Frame4)), diff --git a/pkg/webview2/ICoreWebView2Frame5.go b/pkg/webview2/ICoreWebView2Frame5.go index ea37d81..5b49614 100644 --- a/pkg/webview2/ICoreWebView2Frame5.go +++ b/pkg/webview2/ICoreWebView2Frame5.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Frame5Vtbl struct { - IUnknownVtbl + ICoreWebView2Frame4Vtbl GetFrameId ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Frame5) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Frame5() *ICoreWebView2Frame5 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Frame5) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Frame) GetICoreWebView2Frame5() *ICoreWebView2Frame5 { var result *ICoreWebView2Frame5 iidICoreWebView2Frame5 := NewGUID("{99d199c4-7305-11ee-b962-0242ac120002}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Frame5)), diff --git a/pkg/webview2/ICoreWebView2Frame6.go b/pkg/webview2/ICoreWebView2Frame6.go index bf50a86..a8d27fe 100644 --- a/pkg/webview2/ICoreWebView2Frame6.go +++ b/pkg/webview2/ICoreWebView2Frame6.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Frame6Vtbl struct { - IUnknownVtbl + ICoreWebView2Frame5Vtbl AddScreenCaptureStarting ComProc RemoveScreenCaptureStarting ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Frame6) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Frame6() *ICoreWebView2Frame6 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Frame6) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Frame) GetICoreWebView2Frame6() *ICoreWebView2Frame6 { var result *ICoreWebView2Frame6 iidICoreWebView2Frame6 := NewGUID("{0de611fd-31e9-5ddc-9d71-95eda26eff32}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Frame6)), @@ -54,7 +74,7 @@ func (i *ICoreWebView2Frame6) RemoveScreenCaptureStarting(token EventRegistratio hr, _, _ := i.Vtbl.RemoveScreenCaptureStarting.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2FrameCreatedEventArgs.go b/pkg/webview2/ICoreWebView2FrameCreatedEventArgs.go index e8a1f16..66b52a4 100644 --- a/pkg/webview2/ICoreWebView2FrameCreatedEventArgs.go +++ b/pkg/webview2/ICoreWebView2FrameCreatedEventArgs.go @@ -22,6 +22,19 @@ func (i *ICoreWebView2FrameCreatedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2FrameCreatedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2FrameCreatedEventArgs) GetFrame() (*ICoreWebView2Frame, error) { var value *ICoreWebView2Frame diff --git a/pkg/webview2/ICoreWebView2FrameInfo.go b/pkg/webview2/ICoreWebView2FrameInfo.go index 8f8defd..05fe28a 100644 --- a/pkg/webview2/ICoreWebView2FrameInfo.go +++ b/pkg/webview2/ICoreWebView2FrameInfo.go @@ -23,13 +23,26 @@ func (i *ICoreWebView2FrameInfo) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2FrameInfo) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2FrameInfo) GetName() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -46,7 +59,7 @@ func (i *ICoreWebView2FrameInfo) GetSource() (string, error) { hr, _, _ := i.Vtbl.GetSource.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2FrameInfo2.go b/pkg/webview2/ICoreWebView2FrameInfo2.go index 3991d11..fc8ac5e 100644 --- a/pkg/webview2/ICoreWebView2FrameInfo2.go +++ b/pkg/webview2/ICoreWebView2FrameInfo2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2FrameInfo2Vtbl struct { - IUnknownVtbl + ICoreWebView2FrameInfoVtbl GetParentFrameInfo ComProc GetFrameId ComProc GetFrameKind ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2FrameInfo2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2FrameInfo2() *ICoreWebView2FrameInfo2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2FrameInfo2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2FrameInfo) GetICoreWebView2FrameInfo2() *ICoreWebView2FrameInfo2 { var result *ICoreWebView2FrameInfo2 iidICoreWebView2FrameInfo2 := NewGUID("{56f85cfa-72c4-11ee-b962-0242ac120002}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2FrameInfo2)), diff --git a/pkg/webview2/ICoreWebView2FrameInfoCollection.go b/pkg/webview2/ICoreWebView2FrameInfoCollection.go index c23462e..32a386f 100644 --- a/pkg/webview2/ICoreWebView2FrameInfoCollection.go +++ b/pkg/webview2/ICoreWebView2FrameInfoCollection.go @@ -22,6 +22,19 @@ func (i *ICoreWebView2FrameInfoCollection) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2FrameInfoCollection) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2FrameInfoCollection) GetIterator() (*ICoreWebView2FrameInfoCollectionIterator, error) { var value *ICoreWebView2FrameInfoCollectionIterator diff --git a/pkg/webview2/ICoreWebView2FrameInfoCollectionIterator.go b/pkg/webview2/ICoreWebView2FrameInfoCollectionIterator.go index 9651543..5d8c8d3 100644 --- a/pkg/webview2/ICoreWebView2FrameInfoCollectionIterator.go +++ b/pkg/webview2/ICoreWebView2FrameInfoCollectionIterator.go @@ -24,6 +24,19 @@ func (i *ICoreWebView2FrameInfoCollectionIterator) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2FrameInfoCollectionIterator) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2FrameInfoCollectionIterator) GetHasCurrent() (bool, error) { // Create int32 to hold bool result var _value int32 diff --git a/pkg/webview2/ICoreWebView2HttpHeadersCollectionIterator.go b/pkg/webview2/ICoreWebView2HttpHeadersCollectionIterator.go index c27457a..ed76d4e 100644 --- a/pkg/webview2/ICoreWebView2HttpHeadersCollectionIterator.go +++ b/pkg/webview2/ICoreWebView2HttpHeadersCollectionIterator.go @@ -24,6 +24,19 @@ func (i *ICoreWebView2HttpHeadersCollectionIterator) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2HttpHeadersCollectionIterator) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2HttpHeadersCollectionIterator) GetCurrentHeader() (string, string, error) { // Create *uint16 to hold result var _name *uint16 @@ -32,8 +45,8 @@ func (i *ICoreWebView2HttpHeadersCollectionIterator) GetCurrentHeader() (string, hr, _, _ := i.Vtbl.GetCurrentHeader.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_name)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_name)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2HttpRequestHeaders.go b/pkg/webview2/ICoreWebView2HttpRequestHeaders.go index 12e7bac..7ad5be0 100644 --- a/pkg/webview2/ICoreWebView2HttpRequestHeaders.go +++ b/pkg/webview2/ICoreWebView2HttpRequestHeaders.go @@ -27,19 +27,32 @@ func (i *ICoreWebView2HttpRequestHeaders) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2HttpRequestHeaders) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2HttpRequestHeaders) GetHeader(name string) (string, error) { // Convert string 'name' to *uint16 _name, err := UTF16PtrFromString(name) if err != nil { - return "", nil + return "", err } // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetHeader.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(_name)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -75,7 +88,7 @@ func (i *ICoreWebView2HttpRequestHeaders) Contains(name string) (bool, error) { // Convert string 'name' to *uint16 _name, err := UTF16PtrFromString(name) if err != nil { - return false, nil + return false, err } // Create int32 to hold bool result var _value int32 diff --git a/pkg/webview2/ICoreWebView2HttpResponseHeaders.go b/pkg/webview2/ICoreWebView2HttpResponseHeaders.go index 819a480..86e907d 100644 --- a/pkg/webview2/ICoreWebView2HttpResponseHeaders.go +++ b/pkg/webview2/ICoreWebView2HttpResponseHeaders.go @@ -26,6 +26,19 @@ func (i *ICoreWebView2HttpResponseHeaders) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2HttpResponseHeaders) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2HttpResponseHeaders) AppendHeader(name string, value string) error { // Convert string 'name' to *uint16 @@ -47,7 +60,7 @@ func (i *ICoreWebView2HttpResponseHeaders) AppendHeader(name string, value strin if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) } - return err + return nil } func (i *ICoreWebView2HttpResponseHeaders) Contains(name string) (bool, error) { @@ -55,7 +68,7 @@ func (i *ICoreWebView2HttpResponseHeaders) Contains(name string) (bool, error) { // Convert string 'name' to *uint16 _name, err := UTF16PtrFromString(name) if err != nil { - return false, nil + return false, err } // Create int32 to hold bool result var _value int32 @@ -77,14 +90,14 @@ func (i *ICoreWebView2HttpResponseHeaders) GetHeader(name string) (string, error // Convert string 'name' to *uint16 _name, err := UTF16PtrFromString(name) if err != nil { - return "", nil + return "", err } // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetHeader.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(_name)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2LaunchingExternalUriSchemeEventArgs.go b/pkg/webview2/ICoreWebView2LaunchingExternalUriSchemeEventArgs.go index e710652..b201c63 100644 --- a/pkg/webview2/ICoreWebView2LaunchingExternalUriSchemeEventArgs.go +++ b/pkg/webview2/ICoreWebView2LaunchingExternalUriSchemeEventArgs.go @@ -27,13 +27,26 @@ func (i *ICoreWebView2LaunchingExternalUriSchemeEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2LaunchingExternalUriSchemeEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2LaunchingExternalUriSchemeEventArgs) GetUri() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -50,7 +63,7 @@ func (i *ICoreWebView2LaunchingExternalUriSchemeEventArgs) GetInitiatingOrigin() hr, _, _ := i.Vtbl.GetInitiatingOrigin.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -97,7 +110,7 @@ func (i *ICoreWebView2LaunchingExternalUriSchemeEventArgs) PutCancel(value bool) hr, _, _ := i.Vtbl.PutCancel.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2MoveFocusRequestedEventArgs.go b/pkg/webview2/ICoreWebView2MoveFocusRequestedEventArgs.go index 0f4a5c0..1910d12 100644 --- a/pkg/webview2/ICoreWebView2MoveFocusRequestedEventArgs.go +++ b/pkg/webview2/ICoreWebView2MoveFocusRequestedEventArgs.go @@ -24,6 +24,19 @@ func (i *ICoreWebView2MoveFocusRequestedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2MoveFocusRequestedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2MoveFocusRequestedEventArgs) GetReason() (COREWEBVIEW2_MOVE_FOCUS_REASON, error) { var reason COREWEBVIEW2_MOVE_FOCUS_REASON @@ -58,7 +71,7 @@ func (i *ICoreWebView2MoveFocusRequestedEventArgs) PutHandled(value bool) error hr, _, _ := i.Vtbl.PutHandled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2NavigationCompletedEventArgs.go b/pkg/webview2/ICoreWebView2NavigationCompletedEventArgs.go index 7c42f37..5720d69 100644 --- a/pkg/webview2/ICoreWebView2NavigationCompletedEventArgs.go +++ b/pkg/webview2/ICoreWebView2NavigationCompletedEventArgs.go @@ -24,6 +24,19 @@ func (i *ICoreWebView2NavigationCompletedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NavigationCompletedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2NavigationCompletedEventArgs) GetIsSuccess() (bool, error) { // Create int32 to hold bool result var _isSuccess int32 diff --git a/pkg/webview2/ICoreWebView2NavigationCompletedEventArgs2.go b/pkg/webview2/ICoreWebView2NavigationCompletedEventArgs2.go index e0db30a..308a36e 100644 --- a/pkg/webview2/ICoreWebView2NavigationCompletedEventArgs2.go +++ b/pkg/webview2/ICoreWebView2NavigationCompletedEventArgs2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2NavigationCompletedEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2NavigationCompletedEventArgsVtbl GetHttpStatusCode ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2NavigationCompletedEventArgs2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2NavigationCompletedEventArgs2() *ICoreWebView2NavigationCompletedEventArgs2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NavigationCompletedEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2NavigationCompletedEventArgs) GetICoreWebView2NavigationCompletedEventArgs2() *ICoreWebView2NavigationCompletedEventArgs2 { var result *ICoreWebView2NavigationCompletedEventArgs2 iidICoreWebView2NavigationCompletedEventArgs2 := NewGUID("{fdf8b738-ee1e-4db2-a329-8d7d7b74d792}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2NavigationCompletedEventArgs2)), @@ -34,13 +54,13 @@ func (i *ICoreWebView2) GetICoreWebView2NavigationCompletedEventArgs2() *ICoreWe return result } -func (i *ICoreWebView2NavigationCompletedEventArgs2) GetHttpStatusCode() (int, error) { +func (i *ICoreWebView2NavigationCompletedEventArgs2) GetHttpStatusCode() (int32, error) { - var value int + var value int32 hr, _, _ := i.Vtbl.GetHttpStatusCode.Call( uintptr(unsafe.Pointer(i)), - uintptr(value), + uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { return 0, syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2NavigationStartingEventArgs.go b/pkg/webview2/ICoreWebView2NavigationStartingEventArgs.go index 34e6b25..c0e276a 100644 --- a/pkg/webview2/ICoreWebView2NavigationStartingEventArgs.go +++ b/pkg/webview2/ICoreWebView2NavigationStartingEventArgs.go @@ -28,13 +28,26 @@ func (i *ICoreWebView2NavigationStartingEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NavigationStartingEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2NavigationStartingEventArgs) GetUri() (string, error) { // Create *uint16 to hold result var _uri *uint16 hr, _, _ := i.Vtbl.GetUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_uri)), + uintptr(unsafe.Pointer(&_uri)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -111,7 +124,7 @@ func (i *ICoreWebView2NavigationStartingEventArgs) PutCancel(cancel bool) error hr, _, _ := i.Vtbl.PutCancel.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&cancel)), + boolToUintptr(cancel), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2NavigationStartingEventArgs2.go b/pkg/webview2/ICoreWebView2NavigationStartingEventArgs2.go index 16d2e3e..01bb863 100644 --- a/pkg/webview2/ICoreWebView2NavigationStartingEventArgs2.go +++ b/pkg/webview2/ICoreWebView2NavigationStartingEventArgs2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2NavigationStartingEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2NavigationStartingEventArgsVtbl GetAdditionalAllowedFrameAncestors ComProc PutAdditionalAllowedFrameAncestors ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2NavigationStartingEventArgs2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2NavigationStartingEventArgs2() *ICoreWebView2NavigationStartingEventArgs2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NavigationStartingEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2NavigationStartingEventArgs) GetICoreWebView2NavigationStartingEventArgs2() *ICoreWebView2NavigationStartingEventArgs2 { var result *ICoreWebView2NavigationStartingEventArgs2 iidICoreWebView2NavigationStartingEventArgs2 := NewGUID("{9086be93-91aa-472d-a7e0-579f2ba006ad}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2NavigationStartingEventArgs2)), @@ -41,7 +61,7 @@ func (i *ICoreWebView2NavigationStartingEventArgs2) GetAdditionalAllowedFrameAnc hr, _, _ := i.Vtbl.GetAdditionalAllowedFrameAncestors.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2NavigationStartingEventArgs3.go b/pkg/webview2/ICoreWebView2NavigationStartingEventArgs3.go index c04120e..048fd82 100644 --- a/pkg/webview2/ICoreWebView2NavigationStartingEventArgs3.go +++ b/pkg/webview2/ICoreWebView2NavigationStartingEventArgs3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2NavigationStartingEventArgs3Vtbl struct { - IUnknownVtbl + ICoreWebView2NavigationStartingEventArgs2Vtbl GetNavigationKind ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2NavigationStartingEventArgs3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2NavigationStartingEventArgs3() *ICoreWebView2NavigationStartingEventArgs3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NavigationStartingEventArgs3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2NavigationStartingEventArgs) GetICoreWebView2NavigationStartingEventArgs3() *ICoreWebView2NavigationStartingEventArgs3 { var result *ICoreWebView2NavigationStartingEventArgs3 iidICoreWebView2NavigationStartingEventArgs3 := NewGUID("{ddffe494-4942-4bd2-ab73-35b8ff40e19f}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2NavigationStartingEventArgs3)), diff --git a/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs.go b/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs.go index c47edc7..973bb0b 100644 --- a/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs.go +++ b/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs.go @@ -29,13 +29,26 @@ func (i *ICoreWebView2NewWindowRequestedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NewWindowRequestedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2NewWindowRequestedEventArgs) GetUri() (string, error) { // Create *uint16 to hold result var _uri *uint16 hr, _, _ := i.Vtbl.GetUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_uri)), + uintptr(unsafe.Pointer(&_uri)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -76,7 +89,7 @@ func (i *ICoreWebView2NewWindowRequestedEventArgs) PutHandled(handled bool) erro hr, _, _ := i.Vtbl.PutHandled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&handled)), + boolToUintptr(handled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs2.go b/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs2.go index 727437c..1744b58 100644 --- a/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs2.go +++ b/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2NewWindowRequestedEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2NewWindowRequestedEventArgsVtbl GetName ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2NewWindowRequestedEventArgs2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2NewWindowRequestedEventArgs2() *ICoreWebView2NewWindowRequestedEventArgs2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NewWindowRequestedEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2NewWindowRequestedEventArgs) GetICoreWebView2NewWindowRequestedEventArgs2() *ICoreWebView2NewWindowRequestedEventArgs2 { var result *ICoreWebView2NewWindowRequestedEventArgs2 iidICoreWebView2NewWindowRequestedEventArgs2 := NewGUID("{bbc7baed-74c6-4c92-b63a-7f5aeae03de3}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2NewWindowRequestedEventArgs2)), @@ -40,7 +60,7 @@ func (i *ICoreWebView2NewWindowRequestedEventArgs2) GetName() (string, error) { hr, _, _ := i.Vtbl.GetName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs3.go b/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs3.go index 99cc223..df828a5 100644 --- a/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs3.go +++ b/pkg/webview2/ICoreWebView2NewWindowRequestedEventArgs3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2NewWindowRequestedEventArgs3Vtbl struct { - IUnknownVtbl + ICoreWebView2NewWindowRequestedEventArgs2Vtbl GetOriginalSourceFrameInfo ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2NewWindowRequestedEventArgs3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2NewWindowRequestedEventArgs3() *ICoreWebView2NewWindowRequestedEventArgs3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NewWindowRequestedEventArgs3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2NewWindowRequestedEventArgs) GetICoreWebView2NewWindowRequestedEventArgs3() *ICoreWebView2NewWindowRequestedEventArgs3 { var result *ICoreWebView2NewWindowRequestedEventArgs3 iidICoreWebView2NewWindowRequestedEventArgs3 := NewGUID("{842bed3c-6ad6-4dd9-b938-28c96667ad66}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2NewWindowRequestedEventArgs3)), diff --git a/pkg/webview2/ICoreWebView2NonClientRegionChangedEventArgs.go b/pkg/webview2/ICoreWebView2NonClientRegionChangedEventArgs.go index 9fa76a5..1eb37da 100644 --- a/pkg/webview2/ICoreWebView2NonClientRegionChangedEventArgs.go +++ b/pkg/webview2/ICoreWebView2NonClientRegionChangedEventArgs.go @@ -22,6 +22,19 @@ func (i *ICoreWebView2NonClientRegionChangedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NonClientRegionChangedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2NonClientRegionChangedEventArgs) GetRegionKind() (COREWEBVIEW2_NON_CLIENT_REGION_KIND, error) { var value COREWEBVIEW2_NON_CLIENT_REGION_KIND diff --git a/pkg/webview2/ICoreWebView2Notification.go b/pkg/webview2/ICoreWebView2Notification.go index 29e2996..8c669f2 100644 --- a/pkg/webview2/ICoreWebView2Notification.go +++ b/pkg/webview2/ICoreWebView2Notification.go @@ -39,6 +39,19 @@ func (i *ICoreWebView2Notification) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Notification) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2Notification) AddCloseRequested(eventHandler *ICoreWebView2NotificationCloseRequestedEventHandler) (EventRegistrationToken, error) { var token EventRegistrationToken @@ -58,7 +71,7 @@ func (i *ICoreWebView2Notification) RemoveCloseRequested(token EventRegistration hr, _, _ := i.Vtbl.RemoveCloseRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -105,7 +118,7 @@ func (i *ICoreWebView2Notification) GetBody() (string, error) { hr, _, _ := i.Vtbl.GetBody.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -136,7 +149,7 @@ func (i *ICoreWebView2Notification) GetLanguage() (string, error) { hr, _, _ := i.Vtbl.GetLanguage.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -153,7 +166,7 @@ func (i *ICoreWebView2Notification) GetTag() (string, error) { hr, _, _ := i.Vtbl.GetTag.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -170,7 +183,7 @@ func (i *ICoreWebView2Notification) GetIconUri() (string, error) { hr, _, _ := i.Vtbl.GetIconUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -187,7 +200,7 @@ func (i *ICoreWebView2Notification) GetTitle() (string, error) { hr, _, _ := i.Vtbl.GetTitle.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -204,7 +217,7 @@ func (i *ICoreWebView2Notification) GetBadgeUri() (string, error) { hr, _, _ := i.Vtbl.GetBadgeUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -221,7 +234,7 @@ func (i *ICoreWebView2Notification) GetBodyImageUri() (string, error) { hr, _, _ := i.Vtbl.GetBodyImageUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2NotificationReceivedEventArgs.go b/pkg/webview2/ICoreWebView2NotificationReceivedEventArgs.go index 304802c..dc3c4e0 100644 --- a/pkg/webview2/ICoreWebView2NotificationReceivedEventArgs.go +++ b/pkg/webview2/ICoreWebView2NotificationReceivedEventArgs.go @@ -26,13 +26,26 @@ func (i *ICoreWebView2NotificationReceivedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2NotificationReceivedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2NotificationReceivedEventArgs) GetSenderOrigin() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetSenderOrigin.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -61,7 +74,7 @@ func (i *ICoreWebView2NotificationReceivedEventArgs) PutHandled(value bool) erro hr, _, _ := i.Vtbl.PutHandled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ObjectCollection.go b/pkg/webview2/ICoreWebView2ObjectCollection.go index 0c87011..80e8765 100644 --- a/pkg/webview2/ICoreWebView2ObjectCollection.go +++ b/pkg/webview2/ICoreWebView2ObjectCollection.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2ObjectCollectionVtbl struct { - IUnknownVtbl + ICoreWebView2ObjectCollectionViewVtbl RemoveValueAtIndex ComProc InsertValueAtIndex ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2ObjectCollection) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2ObjectCollection() *ICoreWebView2ObjectCollection { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ObjectCollection) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2ObjectCollectionView) GetICoreWebView2ObjectCollection() *ICoreWebView2ObjectCollection { var result *ICoreWebView2ObjectCollection iidICoreWebView2ObjectCollection := NewGUID("{5cfec11c-25bd-4e8d-9e1a-7acdaeeec047}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2ObjectCollection)), @@ -39,7 +59,7 @@ func (i *ICoreWebView2ObjectCollection) RemoveValueAtIndex(index uint32) error { hr, _, _ := i.Vtbl.RemoveValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -51,7 +71,7 @@ func (i *ICoreWebView2ObjectCollection) InsertValueAtIndex(index uint32, value * hr, _, _ := i.Vtbl.InsertValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2ObjectCollectionView.go b/pkg/webview2/ICoreWebView2ObjectCollectionView.go index cdad6e7..73456c9 100644 --- a/pkg/webview2/ICoreWebView2ObjectCollectionView.go +++ b/pkg/webview2/ICoreWebView2ObjectCollectionView.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2ObjectCollectionView) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ObjectCollectionView) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ObjectCollectionView) GetCount() (uint32, error) { var value uint32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2ObjectCollectionView) GetValueAtIndex(index uint32) (*IUnk hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs.go b/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs.go index 832a4c6..688190e 100644 --- a/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs.go +++ b/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs.go @@ -27,13 +27,26 @@ func (i *ICoreWebView2PermissionRequestedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2PermissionRequestedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2PermissionRequestedEventArgs) GetUri() (string, error) { // Create *uint16 to hold result var _uri *uint16 hr, _, _ := i.Vtbl.GetUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_uri)), + uintptr(unsafe.Pointer(&_uri)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs2.go b/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs2.go index 0093325..c2e8537 100644 --- a/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs2.go +++ b/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2PermissionRequestedEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2PermissionRequestedEventArgsVtbl GetHandled ComProc PutHandled ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2PermissionRequestedEventArgs2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2PermissionRequestedEventArgs2() *ICoreWebView2PermissionRequestedEventArgs2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2PermissionRequestedEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2PermissionRequestedEventArgs) GetICoreWebView2PermissionRequestedEventArgs2() *ICoreWebView2PermissionRequestedEventArgs2 { var result *ICoreWebView2PermissionRequestedEventArgs2 iidICoreWebView2PermissionRequestedEventArgs2 := NewGUID("{74d7127f-9de6-4200-8734-42d6fb4ff741}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2PermissionRequestedEventArgs2)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2PermissionRequestedEventArgs2) PutHandled(value bool) erro hr, _, _ := i.Vtbl.PutHandled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs3.go b/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs3.go index 99fc5d3..a3dc780 100644 --- a/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs3.go +++ b/pkg/webview2/ICoreWebView2PermissionRequestedEventArgs3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2PermissionRequestedEventArgs3Vtbl struct { - IUnknownVtbl + ICoreWebView2PermissionRequestedEventArgs2Vtbl GetSavesInProfile ComProc PutSavesInProfile ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2PermissionRequestedEventArgs3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2PermissionRequestedEventArgs3() *ICoreWebView2PermissionRequestedEventArgs3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2PermissionRequestedEventArgs3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2PermissionRequestedEventArgs) GetICoreWebView2PermissionRequestedEventArgs3() *ICoreWebView2PermissionRequestedEventArgs3 { var result *ICoreWebView2PermissionRequestedEventArgs3 iidICoreWebView2PermissionRequestedEventArgs3 := NewGUID("{e61670bc-3dce-4177-86d2-c629ae3cb6ac}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2PermissionRequestedEventArgs3)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2PermissionRequestedEventArgs3) PutSavesInProfile(value boo hr, _, _ := i.Vtbl.PutSavesInProfile.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2PermissionSetting.go b/pkg/webview2/ICoreWebView2PermissionSetting.go index 7bcbdd7..ae594e5 100644 --- a/pkg/webview2/ICoreWebView2PermissionSetting.go +++ b/pkg/webview2/ICoreWebView2PermissionSetting.go @@ -24,6 +24,19 @@ func (i *ICoreWebView2PermissionSetting) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2PermissionSetting) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2PermissionSetting) GetPermissionKind() (COREWEBVIEW2_PERMISSION_KIND, error) { var value COREWEBVIEW2_PERMISSION_KIND @@ -44,7 +57,7 @@ func (i *ICoreWebView2PermissionSetting) GetPermissionOrigin() (string, error) { hr, _, _ := i.Vtbl.GetPermissionOrigin.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2PermissionSettingCollectionView.go b/pkg/webview2/ICoreWebView2PermissionSettingCollectionView.go index bd9a4b7..f8579d8 100644 --- a/pkg/webview2/ICoreWebView2PermissionSettingCollectionView.go +++ b/pkg/webview2/ICoreWebView2PermissionSettingCollectionView.go @@ -23,13 +23,26 @@ func (i *ICoreWebView2PermissionSettingCollectionView) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2PermissionSettingCollectionView) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2PermissionSettingCollectionView) GetValueAtIndex(index uint32) (*ICoreWebView2PermissionSetting, error) { var permissionSetting *ICoreWebView2PermissionSetting hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(&permissionSetting)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2PointerInfo.go b/pkg/webview2/ICoreWebView2PointerInfo.go index 240ce64..ad82b30 100644 --- a/pkg/webview2/ICoreWebView2PointerInfo.go +++ b/pkg/webview2/ICoreWebView2PointerInfo.go @@ -77,6 +77,19 @@ func (i *ICoreWebView2PointerInfo) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2PointerInfo) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2PointerInfo) GetPointerKind() (uint32, error) { var pointerKind uint32 @@ -95,7 +108,7 @@ func (i *ICoreWebView2PointerInfo) PutPointerKind(pointerKind uint32) error { hr, _, _ := i.Vtbl.PutPointerKind.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&pointerKind)), + uintptr(pointerKind), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -121,7 +134,7 @@ func (i *ICoreWebView2PointerInfo) PutPointerId(pointerId uint32) error { hr, _, _ := i.Vtbl.PutPointerId.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&pointerId)), + uintptr(pointerId), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -147,7 +160,7 @@ func (i *ICoreWebView2PointerInfo) PutFrameId(frameId uint32) error { hr, _, _ := i.Vtbl.PutFrameId.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&frameId)), + uintptr(frameId), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -173,7 +186,7 @@ func (i *ICoreWebView2PointerInfo) PutPointerFlags(pointerFlags uint32) error { hr, _, _ := i.Vtbl.PutPointerFlags.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&pointerFlags)), + uintptr(pointerFlags), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -251,7 +264,7 @@ func (i *ICoreWebView2PointerInfo) PutPixelLocation(pixelLocation POINT) error { hr, _, _ := i.Vtbl.PutPixelLocation.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&pixelLocation)), + uintptr(*(*uint64)(unsafe.Pointer(&pixelLocation))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -277,7 +290,7 @@ func (i *ICoreWebView2PointerInfo) PutHimetricLocation(himetricLocation POINT) e hr, _, _ := i.Vtbl.PutHimetricLocation.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&himetricLocation)), + uintptr(*(*uint64)(unsafe.Pointer(&himetricLocation))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -303,7 +316,7 @@ func (i *ICoreWebView2PointerInfo) PutPixelLocationRaw(pixelLocationRaw POINT) e hr, _, _ := i.Vtbl.PutPixelLocationRaw.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&pixelLocationRaw)), + uintptr(*(*uint64)(unsafe.Pointer(&pixelLocationRaw))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -329,7 +342,7 @@ func (i *ICoreWebView2PointerInfo) PutHimetricLocationRaw(himetricLocationRaw PO hr, _, _ := i.Vtbl.PutHimetricLocationRaw.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&himetricLocationRaw)), + uintptr(*(*uint64)(unsafe.Pointer(&himetricLocationRaw))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -355,7 +368,7 @@ func (i *ICoreWebView2PointerInfo) PutTime(time uint32) error { hr, _, _ := i.Vtbl.PutTime.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&time)), + uintptr(time), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -381,7 +394,7 @@ func (i *ICoreWebView2PointerInfo) PutHistoryCount(historyCount uint32) error { hr, _, _ := i.Vtbl.PutHistoryCount.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&historyCount)), + uintptr(historyCount), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -407,7 +420,7 @@ func (i *ICoreWebView2PointerInfo) PutInputData(inputData int32) error { hr, _, _ := i.Vtbl.PutInputData.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&inputData)), + uintptr(inputData), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -433,7 +446,7 @@ func (i *ICoreWebView2PointerInfo) PutKeyStates(keyStates uint32) error { hr, _, _ := i.Vtbl.PutKeyStates.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&keyStates)), + uintptr(keyStates), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -459,7 +472,7 @@ func (i *ICoreWebView2PointerInfo) PutPerformanceCount(performanceCount uint64) hr, _, _ := i.Vtbl.PutPerformanceCount.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&performanceCount)), + uintptr(performanceCount), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -485,7 +498,7 @@ func (i *ICoreWebView2PointerInfo) PutButtonChangeKind(buttonChangeKind int32) e hr, _, _ := i.Vtbl.PutButtonChangeKind.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&buttonChangeKind)), + uintptr(buttonChangeKind), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -511,7 +524,7 @@ func (i *ICoreWebView2PointerInfo) PutPenFlags(penFLags uint32) error { hr, _, _ := i.Vtbl.PutPenFlags.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&penFLags)), + uintptr(penFLags), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -537,7 +550,7 @@ func (i *ICoreWebView2PointerInfo) PutPenMask(penMask uint32) error { hr, _, _ := i.Vtbl.PutPenMask.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&penMask)), + uintptr(penMask), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -563,7 +576,7 @@ func (i *ICoreWebView2PointerInfo) PutPenPressure(penPressure uint32) error { hr, _, _ := i.Vtbl.PutPenPressure.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&penPressure)), + uintptr(penPressure), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -589,7 +602,7 @@ func (i *ICoreWebView2PointerInfo) PutPenRotation(penRotation uint32) error { hr, _, _ := i.Vtbl.PutPenRotation.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&penRotation)), + uintptr(penRotation), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -615,7 +628,7 @@ func (i *ICoreWebView2PointerInfo) PutPenTiltX(penTiltX int32) error { hr, _, _ := i.Vtbl.PutPenTiltX.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&penTiltX)), + uintptr(penTiltX), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -641,7 +654,7 @@ func (i *ICoreWebView2PointerInfo) PutPenTiltY(penTiltY int32) error { hr, _, _ := i.Vtbl.PutPenTiltY.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&penTiltY)), + uintptr(penTiltY), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -667,7 +680,7 @@ func (i *ICoreWebView2PointerInfo) PutTouchFlags(touchFlags uint32) error { hr, _, _ := i.Vtbl.PutTouchFlags.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&touchFlags)), + uintptr(touchFlags), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -693,7 +706,7 @@ func (i *ICoreWebView2PointerInfo) PutTouchMask(touchMask uint32) error { hr, _, _ := i.Vtbl.PutTouchMask.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&touchMask)), + uintptr(touchMask), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -771,7 +784,7 @@ func (i *ICoreWebView2PointerInfo) PutTouchOrientation(touchOrientation uint32) hr, _, _ := i.Vtbl.PutTouchOrientation.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&touchOrientation)), + uintptr(touchOrientation), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -797,7 +810,7 @@ func (i *ICoreWebView2PointerInfo) PutTouchPressure(touchPressure uint32) error hr, _, _ := i.Vtbl.PutTouchPressure.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&touchPressure)), + uintptr(touchPressure), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2PrintSettings.go b/pkg/webview2/ICoreWebView2PrintSettings.go index 3841e6a..0c57387 100644 --- a/pkg/webview2/ICoreWebView2PrintSettings.go +++ b/pkg/webview2/ICoreWebView2PrintSettings.go @@ -4,6 +4,7 @@ package webview2 import ( "golang.org/x/sys/windows" + "math" "syscall" "unsafe" ) @@ -47,6 +48,19 @@ func (i *ICoreWebView2PrintSettings) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2PrintSettings) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2PrintSettings) GetOrientation() (COREWEBVIEW2_PRINT_ORIENTATION, error) { var orientation COREWEBVIEW2_PRINT_ORIENTATION @@ -91,7 +105,7 @@ func (i *ICoreWebView2PrintSettings) PutScaleFactor(scaleFactor float64) error { hr, _, _ := i.Vtbl.PutScaleFactor.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&scaleFactor)), + uintptr(math.Float64bits(scaleFactor)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -117,7 +131,7 @@ func (i *ICoreWebView2PrintSettings) PutPageWidth(pageWidth float64) error { hr, _, _ := i.Vtbl.PutPageWidth.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&pageWidth)), + uintptr(math.Float64bits(pageWidth)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -143,7 +157,7 @@ func (i *ICoreWebView2PrintSettings) PutPageHeight(pageHeight float64) error { hr, _, _ := i.Vtbl.PutPageHeight.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&pageHeight)), + uintptr(math.Float64bits(pageHeight)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -169,7 +183,7 @@ func (i *ICoreWebView2PrintSettings) PutMarginTop(marginTop float64) error { hr, _, _ := i.Vtbl.PutMarginTop.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&marginTop)), + uintptr(math.Float64bits(marginTop)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -195,7 +209,7 @@ func (i *ICoreWebView2PrintSettings) PutMarginBottom(marginBottom float64) error hr, _, _ := i.Vtbl.PutMarginBottom.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&marginBottom)), + uintptr(math.Float64bits(marginBottom)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -221,7 +235,7 @@ func (i *ICoreWebView2PrintSettings) PutMarginLeft(marginLeft float64) error { hr, _, _ := i.Vtbl.PutMarginLeft.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&marginLeft)), + uintptr(math.Float64bits(marginLeft)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -247,7 +261,7 @@ func (i *ICoreWebView2PrintSettings) PutMarginRight(marginRight float64) error { hr, _, _ := i.Vtbl.PutMarginRight.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&marginRight)), + uintptr(math.Float64bits(marginRight)), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -275,7 +289,7 @@ func (i *ICoreWebView2PrintSettings) PutShouldPrintBackgrounds(shouldPrintBackgr hr, _, _ := i.Vtbl.PutShouldPrintBackgrounds.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&shouldPrintBackgrounds)), + boolToUintptr(shouldPrintBackgrounds), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -303,7 +317,7 @@ func (i *ICoreWebView2PrintSettings) PutShouldPrintSelectionOnly(shouldPrintSele hr, _, _ := i.Vtbl.PutShouldPrintSelectionOnly.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&shouldPrintSelectionOnly)), + boolToUintptr(shouldPrintSelectionOnly), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -331,7 +345,7 @@ func (i *ICoreWebView2PrintSettings) PutShouldPrintHeaderAndFooter(shouldPrintHe hr, _, _ := i.Vtbl.PutShouldPrintHeaderAndFooter.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&shouldPrintHeaderAndFooter)), + boolToUintptr(shouldPrintHeaderAndFooter), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -345,7 +359,7 @@ func (i *ICoreWebView2PrintSettings) GetHeaderTitle() (string, error) { hr, _, _ := i.Vtbl.GetHeaderTitle.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_headerTitle)), + uintptr(unsafe.Pointer(&_headerTitle)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -380,7 +394,7 @@ func (i *ICoreWebView2PrintSettings) GetFooterUri() (string, error) { hr, _, _ := i.Vtbl.GetFooterUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_footerUri)), + uintptr(unsafe.Pointer(&_footerUri)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2PrintSettings2.go b/pkg/webview2/ICoreWebView2PrintSettings2.go index 616f44d..80c259e 100644 --- a/pkg/webview2/ICoreWebView2PrintSettings2.go +++ b/pkg/webview2/ICoreWebView2PrintSettings2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2PrintSettings2Vtbl struct { - IUnknownVtbl + ICoreWebView2PrintSettingsVtbl GetPageRanges ComProc PutPageRanges ComProc GetPagesPerSide ComProc @@ -37,10 +37,30 @@ func (i *ICoreWebView2PrintSettings2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2PrintSettings2() *ICoreWebView2PrintSettings2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2PrintSettings2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2PrintSettings) GetICoreWebView2PrintSettings2() *ICoreWebView2PrintSettings2 { var result *ICoreWebView2PrintSettings2 iidICoreWebView2PrintSettings2 := NewGUID("{CA7F0E1F-3484-41D1-8C1A-65CD44A63F8D}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2PrintSettings2)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2PrintSettings2) GetPageRanges() (string, error) { hr, _, _ := i.Vtbl.GetPageRanges.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -102,7 +122,7 @@ func (i *ICoreWebView2PrintSettings2) PutPagesPerSide(value int32) error { hr, _, _ := i.Vtbl.PutPagesPerSide.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + uintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -128,7 +148,7 @@ func (i *ICoreWebView2PrintSettings2) PutCopies(value int32) error { hr, _, _ := i.Vtbl.PutCopies.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + uintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -246,7 +266,7 @@ func (i *ICoreWebView2PrintSettings2) GetPrinterName() (string, error) { hr, _, _ := i.Vtbl.GetPrinterName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ProcessExtendedInfo.go b/pkg/webview2/ICoreWebView2ProcessExtendedInfo.go index 55d4ba9..66e0a63 100644 --- a/pkg/webview2/ICoreWebView2ProcessExtendedInfo.go +++ b/pkg/webview2/ICoreWebView2ProcessExtendedInfo.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2ProcessExtendedInfo) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ProcessExtendedInfo) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ProcessExtendedInfo) GetProcessInfo() (*ICoreWebView2ProcessInfo, error) { var processInfo *ICoreWebView2ProcessInfo diff --git a/pkg/webview2/ICoreWebView2ProcessExtendedInfoCollection.go b/pkg/webview2/ICoreWebView2ProcessExtendedInfoCollection.go index 48a4a19..5a10376 100644 --- a/pkg/webview2/ICoreWebView2ProcessExtendedInfoCollection.go +++ b/pkg/webview2/ICoreWebView2ProcessExtendedInfoCollection.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2ProcessExtendedInfoCollection) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ProcessExtendedInfoCollection) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ProcessExtendedInfoCollection) GetCount() (uint32, error) { var value uint32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2ProcessExtendedInfoCollection) GetValueAtIndex(index uint3 hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2ProcessFailedEventArgs.go b/pkg/webview2/ICoreWebView2ProcessFailedEventArgs.go index 1f6aad6..8e0b576 100644 --- a/pkg/webview2/ICoreWebView2ProcessFailedEventArgs.go +++ b/pkg/webview2/ICoreWebView2ProcessFailedEventArgs.go @@ -22,6 +22,19 @@ func (i *ICoreWebView2ProcessFailedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ProcessFailedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ProcessFailedEventArgs) GetProcessFailedKind() (COREWEBVIEW2_PROCESS_FAILED_KIND, error) { var value COREWEBVIEW2_PROCESS_FAILED_KIND diff --git a/pkg/webview2/ICoreWebView2ProcessFailedEventArgs2.go b/pkg/webview2/ICoreWebView2ProcessFailedEventArgs2.go index 3a85b42..707847a 100644 --- a/pkg/webview2/ICoreWebView2ProcessFailedEventArgs2.go +++ b/pkg/webview2/ICoreWebView2ProcessFailedEventArgs2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2ProcessFailedEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2ProcessFailedEventArgsVtbl GetReason ComProc GetExitCode ComProc GetProcessDescription ComProc @@ -25,10 +25,30 @@ func (i *ICoreWebView2ProcessFailedEventArgs2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2ProcessFailedEventArgs2() *ICoreWebView2ProcessFailedEventArgs2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ProcessFailedEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2ProcessFailedEventArgs) GetICoreWebView2ProcessFailedEventArgs2() *ICoreWebView2ProcessFailedEventArgs2 { var result *ICoreWebView2ProcessFailedEventArgs2 iidICoreWebView2ProcessFailedEventArgs2 := NewGUID("{4dab9422-46fa-4c3e-a5d2-41d2071d3680}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2ProcessFailedEventArgs2)), @@ -51,13 +71,13 @@ func (i *ICoreWebView2ProcessFailedEventArgs2) GetReason() (COREWEBVIEW2_PROCESS return reason, nil } -func (i *ICoreWebView2ProcessFailedEventArgs2) GetExitCode() (int, error) { +func (i *ICoreWebView2ProcessFailedEventArgs2) GetExitCode() (int32, error) { - var exitCode int + var exitCode int32 hr, _, _ := i.Vtbl.GetExitCode.Call( uintptr(unsafe.Pointer(i)), - uintptr(exitCode), + uintptr(unsafe.Pointer(&exitCode)), ) if windows.Handle(hr) != windows.S_OK { return 0, syscall.Errno(hr) @@ -71,7 +91,7 @@ func (i *ICoreWebView2ProcessFailedEventArgs2) GetProcessDescription() (string, hr, _, _ := i.Vtbl.GetProcessDescription.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_processDescription)), + uintptr(unsafe.Pointer(&_processDescription)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ProcessFailedEventArgs3.go b/pkg/webview2/ICoreWebView2ProcessFailedEventArgs3.go index bd13dd3..8ed5f4a 100644 --- a/pkg/webview2/ICoreWebView2ProcessFailedEventArgs3.go +++ b/pkg/webview2/ICoreWebView2ProcessFailedEventArgs3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2ProcessFailedEventArgs3Vtbl struct { - IUnknownVtbl + ICoreWebView2ProcessFailedEventArgs2Vtbl GetFailureSourceModulePath ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2ProcessFailedEventArgs3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2ProcessFailedEventArgs3() *ICoreWebView2ProcessFailedEventArgs3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ProcessFailedEventArgs3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2ProcessFailedEventArgs) GetICoreWebView2ProcessFailedEventArgs3() *ICoreWebView2ProcessFailedEventArgs3 { var result *ICoreWebView2ProcessFailedEventArgs3 iidICoreWebView2ProcessFailedEventArgs3 := NewGUID("{ab667428-094d-5fd1-b480-8b4c0fdbdf2f}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2ProcessFailedEventArgs3)), @@ -40,7 +60,7 @@ func (i *ICoreWebView2ProcessFailedEventArgs3) GetFailureSourceModulePath() (str hr, _, _ := i.Vtbl.GetFailureSourceModulePath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ProcessInfo.go b/pkg/webview2/ICoreWebView2ProcessInfo.go index 8b52898..ff6c108 100644 --- a/pkg/webview2/ICoreWebView2ProcessInfo.go +++ b/pkg/webview2/ICoreWebView2ProcessInfo.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2ProcessInfo) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ProcessInfo) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ProcessInfo) GetProcessId() (int32, error) { var value int32 diff --git a/pkg/webview2/ICoreWebView2ProcessInfoCollection.go b/pkg/webview2/ICoreWebView2ProcessInfoCollection.go index 10707c4..a034e35 100644 --- a/pkg/webview2/ICoreWebView2ProcessInfoCollection.go +++ b/pkg/webview2/ICoreWebView2ProcessInfoCollection.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2ProcessInfoCollection) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ProcessInfoCollection) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ProcessInfoCollection) GetCount() (uint32, error) { var value uint32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2ProcessInfoCollection) GetValueAtIndex(index uint32) (*ICo hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2Profile.go b/pkg/webview2/ICoreWebView2Profile.go index 6c4568e..082bf61 100644 --- a/pkg/webview2/ICoreWebView2Profile.go +++ b/pkg/webview2/ICoreWebView2Profile.go @@ -28,13 +28,26 @@ func (i *ICoreWebView2Profile) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Profile) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2Profile) GetProfileName() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetProfileName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -67,7 +80,7 @@ func (i *ICoreWebView2Profile) GetProfilePath() (string, error) { hr, _, _ := i.Vtbl.GetProfilePath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -84,7 +97,7 @@ func (i *ICoreWebView2Profile) GetDefaultDownloadFolderPath() (string, error) { hr, _, _ := i.Vtbl.GetDefaultDownloadFolderPath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Profile2.go b/pkg/webview2/ICoreWebView2Profile2.go index cef10dd..802e875 100644 --- a/pkg/webview2/ICoreWebView2Profile2.go +++ b/pkg/webview2/ICoreWebView2Profile2.go @@ -4,12 +4,13 @@ package webview2 import ( "golang.org/x/sys/windows" + "math" "syscall" "unsafe" ) type ICoreWebView2Profile2Vtbl struct { - IUnknownVtbl + ICoreWebView2ProfileVtbl ClearBrowsingData ComProc ClearBrowsingDataInTimeRange ComProc ClearBrowsingDataAll ComProc @@ -24,10 +25,30 @@ func (i *ICoreWebView2Profile2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Profile2() *ICoreWebView2Profile2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Profile2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Profile) GetICoreWebView2Profile2() *ICoreWebView2Profile2 { var result *ICoreWebView2Profile2 iidICoreWebView2Profile2 := NewGUID("{fa740d4b-5eae-4344-a8ad-74be31925397}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Profile2)), @@ -54,8 +75,8 @@ func (i *ICoreWebView2Profile2) ClearBrowsingDataInTimeRange(dataKinds COREWEBVI hr, _, _ := i.Vtbl.ClearBrowsingDataInTimeRange.Call( uintptr(unsafe.Pointer(i)), uintptr(dataKinds), - uintptr(unsafe.Pointer(&startTime)), - uintptr(unsafe.Pointer(&endTime)), + uintptr(math.Float64bits(startTime)), + uintptr(math.Float64bits(endTime)), uintptr(unsafe.Pointer(handler)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2Profile3.go b/pkg/webview2/ICoreWebView2Profile3.go index da5ccc4..4a24e67 100644 --- a/pkg/webview2/ICoreWebView2Profile3.go +++ b/pkg/webview2/ICoreWebView2Profile3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Profile3Vtbl struct { - IUnknownVtbl + ICoreWebView2Profile2Vtbl GetPreferredTrackingPreventionLevel ComProc PutPreferredTrackingPreventionLevel ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Profile3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Profile3() *ICoreWebView2Profile3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Profile3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Profile) GetICoreWebView2Profile3() *ICoreWebView2Profile3 { var result *ICoreWebView2Profile3 iidICoreWebView2Profile3 := NewGUID("{b188e659-5685-4e05-bdba-fc640e0f1992}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Profile3)), diff --git a/pkg/webview2/ICoreWebView2Profile4.go b/pkg/webview2/ICoreWebView2Profile4.go index 92e36e3..e31498a 100644 --- a/pkg/webview2/ICoreWebView2Profile4.go +++ b/pkg/webview2/ICoreWebView2Profile4.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Profile4Vtbl struct { - IUnknownVtbl + ICoreWebView2Profile3Vtbl SetPermissionState ComProc GetNonDefaultPermissionSettings ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Profile4) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Profile4() *ICoreWebView2Profile4 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Profile4) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Profile) GetICoreWebView2Profile4() *ICoreWebView2Profile4 { var result *ICoreWebView2Profile4 iidICoreWebView2Profile4 := NewGUID("{8f4ae680-192e-4ec8-833a-21cfadaef628}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Profile4)), diff --git a/pkg/webview2/ICoreWebView2Profile5.go b/pkg/webview2/ICoreWebView2Profile5.go index ecff06d..2d2174a 100644 --- a/pkg/webview2/ICoreWebView2Profile5.go +++ b/pkg/webview2/ICoreWebView2Profile5.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Profile5Vtbl struct { - IUnknownVtbl + ICoreWebView2Profile4Vtbl GetCookieManager ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2Profile5) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Profile5() *ICoreWebView2Profile5 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Profile5) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Profile) GetICoreWebView2Profile5() *ICoreWebView2Profile5 { var result *ICoreWebView2Profile5 iidICoreWebView2Profile5 := NewGUID("{2ee5b76e-6e80-4df2-bcd3-d4ec3340a01b}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Profile5)), diff --git a/pkg/webview2/ICoreWebView2Profile6.go b/pkg/webview2/ICoreWebView2Profile6.go index 1223998..e590a2d 100644 --- a/pkg/webview2/ICoreWebView2Profile6.go +++ b/pkg/webview2/ICoreWebView2Profile6.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Profile6Vtbl struct { - IUnknownVtbl + ICoreWebView2Profile5Vtbl GetIsPasswordAutosaveEnabled ComProc PutIsPasswordAutosaveEnabled ComProc GetIsGeneralAutofillEnabled ComProc @@ -25,10 +25,30 @@ func (i *ICoreWebView2Profile6) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Profile6() *ICoreWebView2Profile6 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Profile6) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Profile) GetICoreWebView2Profile6() *ICoreWebView2Profile6 { var result *ICoreWebView2Profile6 iidICoreWebView2Profile6 := NewGUID("{BD82FA6A-1D65-4C33-B2B4-0393020CC61B}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Profile6)), @@ -57,7 +77,7 @@ func (i *ICoreWebView2Profile6) PutIsPasswordAutosaveEnabled(value bool) error { hr, _, _ := i.Vtbl.PutIsPasswordAutosaveEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -85,7 +105,7 @@ func (i *ICoreWebView2Profile6) PutIsGeneralAutofillEnabled(value bool) error { hr, _, _ := i.Vtbl.PutIsGeneralAutofillEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Profile7.go b/pkg/webview2/ICoreWebView2Profile7.go index 4bc784b..b5903ce 100644 --- a/pkg/webview2/ICoreWebView2Profile7.go +++ b/pkg/webview2/ICoreWebView2Profile7.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Profile7Vtbl struct { - IUnknownVtbl + ICoreWebView2Profile6Vtbl AddBrowserExtension ComProc GetBrowserExtensions ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Profile7) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Profile7() *ICoreWebView2Profile7 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Profile7) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Profile) GetICoreWebView2Profile7() *ICoreWebView2Profile7 { var result *ICoreWebView2Profile7 iidICoreWebView2Profile7 := NewGUID("{7b4c7906-a1aa-4cb4-b723-db09f813d541}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Profile7)), diff --git a/pkg/webview2/ICoreWebView2Profile8.go b/pkg/webview2/ICoreWebView2Profile8.go index 151cce8..c489012 100644 --- a/pkg/webview2/ICoreWebView2Profile8.go +++ b/pkg/webview2/ICoreWebView2Profile8.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Profile8Vtbl struct { - IUnknownVtbl + ICoreWebView2Profile7Vtbl Delete ComProc AddDeleted ComProc RemoveDeleted ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2Profile8) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Profile8() *ICoreWebView2Profile8 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Profile8) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Profile) GetICoreWebView2Profile8() *ICoreWebView2Profile8 { var result *ICoreWebView2Profile8 iidICoreWebView2Profile8 := NewGUID("{fbf70c2f-eb1f-4383-85a0-163e92044011}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Profile8)), @@ -66,7 +86,7 @@ func (i *ICoreWebView2Profile8) RemoveDeleted(token EventRegistrationToken) erro hr, _, _ := i.Vtbl.RemoveDeleted.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2RegionRectCollectionView.go b/pkg/webview2/ICoreWebView2RegionRectCollectionView.go index bb25fec..7296baa 100644 --- a/pkg/webview2/ICoreWebView2RegionRectCollectionView.go +++ b/pkg/webview2/ICoreWebView2RegionRectCollectionView.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2RegionRectCollectionView) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2RegionRectCollectionView) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2RegionRectCollectionView) GetCount() (uint32, error) { var value uint32 @@ -43,7 +56,7 @@ func (i *ICoreWebView2RegionRectCollectionView) GetValueAtIndex(index uint32) (R hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), + uintptr(index), uintptr(unsafe.Pointer(&value)), ) if windows.Handle(hr) != windows.S_OK { diff --git a/pkg/webview2/ICoreWebView2SaveAsUIShowingEventArgs.go b/pkg/webview2/ICoreWebView2SaveAsUIShowingEventArgs.go index 0034ebc..15e76ff 100644 --- a/pkg/webview2/ICoreWebView2SaveAsUIShowingEventArgs.go +++ b/pkg/webview2/ICoreWebView2SaveAsUIShowingEventArgs.go @@ -33,13 +33,26 @@ func (i *ICoreWebView2SaveAsUIShowingEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2SaveAsUIShowingEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2SaveAsUIShowingEventArgs) GetContentMimeType() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetContentMimeType.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -54,7 +67,7 @@ func (i *ICoreWebView2SaveAsUIShowingEventArgs) PutCancel(value bool) error { hr, _, _ := i.Vtbl.PutCancel.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -82,7 +95,7 @@ func (i *ICoreWebView2SaveAsUIShowingEventArgs) PutSuppressDefaultDialog(value b hr, _, _ := i.Vtbl.PutSuppressDefaultDialog.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -144,7 +157,7 @@ func (i *ICoreWebView2SaveAsUIShowingEventArgs) GetSaveAsFilePath() (string, err hr, _, _ := i.Vtbl.GetSaveAsFilePath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -159,7 +172,7 @@ func (i *ICoreWebView2SaveAsUIShowingEventArgs) PutAllowReplace(value bool) erro hr, _, _ := i.Vtbl.PutAllowReplace.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2SaveFileSecurityCheckStartingEventArgs.go b/pkg/webview2/ICoreWebView2SaveFileSecurityCheckStartingEventArgs.go index 98990b5..cbf4bb9 100644 --- a/pkg/webview2/ICoreWebView2SaveFileSecurityCheckStartingEventArgs.go +++ b/pkg/webview2/ICoreWebView2SaveFileSecurityCheckStartingEventArgs.go @@ -29,6 +29,19 @@ func (i *ICoreWebView2SaveFileSecurityCheckStartingEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2SaveFileSecurityCheckStartingEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2SaveFileSecurityCheckStartingEventArgs) GetCancelSave() (bool, error) { // Create int32 to hold bool result var _value int32 @@ -49,7 +62,7 @@ func (i *ICoreWebView2SaveFileSecurityCheckStartingEventArgs) PutCancelSave(valu hr, _, _ := i.Vtbl.PutCancelSave.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -63,7 +76,7 @@ func (i *ICoreWebView2SaveFileSecurityCheckStartingEventArgs) GetDocumentOriginU hr, _, _ := i.Vtbl.GetDocumentOriginUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -80,7 +93,7 @@ func (i *ICoreWebView2SaveFileSecurityCheckStartingEventArgs) GetFileExtension() hr, _, _ := i.Vtbl.GetFileExtension.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -97,7 +110,7 @@ func (i *ICoreWebView2SaveFileSecurityCheckStartingEventArgs) GetFilePath() (str hr, _, _ := i.Vtbl.GetFilePath.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -128,7 +141,7 @@ func (i *ICoreWebView2SaveFileSecurityCheckStartingEventArgs) PutSuppressDefault hr, _, _ := i.Vtbl.PutSuppressDefaultPolicy.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ScreenCaptureStartingEventArgs.go b/pkg/webview2/ICoreWebView2ScreenCaptureStartingEventArgs.go index c276af4..da6f8cb 100644 --- a/pkg/webview2/ICoreWebView2ScreenCaptureStartingEventArgs.go +++ b/pkg/webview2/ICoreWebView2ScreenCaptureStartingEventArgs.go @@ -27,6 +27,19 @@ func (i *ICoreWebView2ScreenCaptureStartingEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ScreenCaptureStartingEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ScreenCaptureStartingEventArgs) GetCancel() (bool, error) { // Create int32 to hold bool result var _value int32 @@ -47,7 +60,7 @@ func (i *ICoreWebView2ScreenCaptureStartingEventArgs) PutCancel(value bool) erro hr, _, _ := i.Vtbl.PutCancel.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -75,7 +88,7 @@ func (i *ICoreWebView2ScreenCaptureStartingEventArgs) PutHandled(value bool) err hr, _, _ := i.Vtbl.PutHandled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ScriptDialogOpeningEventArgs.go b/pkg/webview2/ICoreWebView2ScriptDialogOpeningEventArgs.go index 30de940..1245b6d 100644 --- a/pkg/webview2/ICoreWebView2ScriptDialogOpeningEventArgs.go +++ b/pkg/webview2/ICoreWebView2ScriptDialogOpeningEventArgs.go @@ -29,13 +29,26 @@ func (i *ICoreWebView2ScriptDialogOpeningEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ScriptDialogOpeningEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ScriptDialogOpeningEventArgs) GetUri() (string, error) { // Create *uint16 to hold result var _uri *uint16 hr, _, _ := i.Vtbl.GetUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_uri)), + uintptr(unsafe.Pointer(&_uri)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -66,7 +79,7 @@ func (i *ICoreWebView2ScriptDialogOpeningEventArgs) GetMessage() (string, error) hr, _, _ := i.Vtbl.GetMessage.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_message)), + uintptr(unsafe.Pointer(&_message)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -94,7 +107,7 @@ func (i *ICoreWebView2ScriptDialogOpeningEventArgs) GetDefaultText() (string, er hr, _, _ := i.Vtbl.GetDefaultText.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_defaultText)), + uintptr(unsafe.Pointer(&_defaultText)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -111,7 +124,7 @@ func (i *ICoreWebView2ScriptDialogOpeningEventArgs) GetResultText() (string, err hr, _, _ := i.Vtbl.GetResultText.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_resultText)), + uintptr(unsafe.Pointer(&_resultText)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ScriptException.go b/pkg/webview2/ICoreWebView2ScriptException.go index 087dd6a..bf9781e 100644 --- a/pkg/webview2/ICoreWebView2ScriptException.go +++ b/pkg/webview2/ICoreWebView2ScriptException.go @@ -26,6 +26,19 @@ func (i *ICoreWebView2ScriptException) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ScriptException) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ScriptException) GetLineNumber() (uint32, error) { var value uint32 @@ -60,7 +73,7 @@ func (i *ICoreWebView2ScriptException) GetName() (string, error) { hr, _, _ := i.Vtbl.GetName.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -77,7 +90,7 @@ func (i *ICoreWebView2ScriptException) GetMessage() (string, error) { hr, _, _ := i.Vtbl.GetMessage.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -94,7 +107,7 @@ func (i *ICoreWebView2ScriptException) GetToJson() (string, error) { hr, _, _ := i.Vtbl.GetToJson.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2ServerCertificateErrorDetectedEventArgs.go b/pkg/webview2/ICoreWebView2ServerCertificateErrorDetectedEventArgs.go index 1ff59d0..c146408 100644 --- a/pkg/webview2/ICoreWebView2ServerCertificateErrorDetectedEventArgs.go +++ b/pkg/webview2/ICoreWebView2ServerCertificateErrorDetectedEventArgs.go @@ -27,6 +27,19 @@ func (i *ICoreWebView2ServerCertificateErrorDetectedEventArgs) AddRef() uintptr return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2ServerCertificateErrorDetectedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2ServerCertificateErrorDetectedEventArgs) GetErrorStatus() (COREWEBVIEW2_WEB_ERROR_STATUS, error) { var value COREWEBVIEW2_WEB_ERROR_STATUS @@ -47,7 +60,7 @@ func (i *ICoreWebView2ServerCertificateErrorDetectedEventArgs) GetRequestUri() ( hr, _, _ := i.Vtbl.GetRequestUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Settings.go b/pkg/webview2/ICoreWebView2Settings.go index c86a892..2cc9c09 100644 --- a/pkg/webview2/ICoreWebView2Settings.go +++ b/pkg/webview2/ICoreWebView2Settings.go @@ -39,6 +39,19 @@ func (i *ICoreWebView2Settings) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Settings) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2Settings) GetIsScriptEnabled() (bool, error) { // Create int32 to hold bool result var _isScriptEnabled int32 @@ -59,7 +72,7 @@ func (i *ICoreWebView2Settings) PutIsScriptEnabled(isScriptEnabled bool) error { hr, _, _ := i.Vtbl.PutIsScriptEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isScriptEnabled)), + boolToUintptr(isScriptEnabled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -87,7 +100,7 @@ func (i *ICoreWebView2Settings) PutIsWebMessageEnabled(isWebMessageEnabled bool) hr, _, _ := i.Vtbl.PutIsWebMessageEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isWebMessageEnabled)), + boolToUintptr(isWebMessageEnabled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -115,7 +128,7 @@ func (i *ICoreWebView2Settings) PutAreDefaultScriptDialogsEnabled(areDefaultScri hr, _, _ := i.Vtbl.PutAreDefaultScriptDialogsEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDefaultScriptDialogsEnabled)), + boolToUintptr(areDefaultScriptDialogsEnabled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -143,7 +156,7 @@ func (i *ICoreWebView2Settings) PutIsStatusBarEnabled(isStatusBarEnabled bool) e hr, _, _ := i.Vtbl.PutIsStatusBarEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isStatusBarEnabled)), + boolToUintptr(isStatusBarEnabled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -171,7 +184,7 @@ func (i *ICoreWebView2Settings) PutAreDevToolsEnabled(areDevToolsEnabled bool) e hr, _, _ := i.Vtbl.PutAreDevToolsEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDevToolsEnabled)), + boolToUintptr(areDevToolsEnabled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -199,7 +212,7 @@ func (i *ICoreWebView2Settings) PutAreDefaultContextMenusEnabled(enabled bool) e hr, _, _ := i.Vtbl.PutAreDefaultContextMenusEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), + boolToUintptr(enabled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -227,7 +240,7 @@ func (i *ICoreWebView2Settings) PutAreHostObjectsAllowed(allowed bool) error { hr, _, _ := i.Vtbl.PutAreHostObjectsAllowed.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&allowed)), + boolToUintptr(allowed), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -255,7 +268,7 @@ func (i *ICoreWebView2Settings) PutIsZoomControlEnabled(enabled bool) error { hr, _, _ := i.Vtbl.PutIsZoomControlEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), + boolToUintptr(enabled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -283,7 +296,7 @@ func (i *ICoreWebView2Settings) PutIsBuiltInErrorPageEnabled(enabled bool) error hr, _, _ := i.Vtbl.PutIsBuiltInErrorPageEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), + boolToUintptr(enabled), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Settings2.go b/pkg/webview2/ICoreWebView2Settings2.go index 4151843..c02772c 100644 --- a/pkg/webview2/ICoreWebView2Settings2.go +++ b/pkg/webview2/ICoreWebView2Settings2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Settings2Vtbl struct { - IUnknownVtbl + ICoreWebView2SettingsVtbl GetUserAgent ComProc PutUserAgent ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Settings2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Settings2() *ICoreWebView2Settings2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Settings2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Settings) GetICoreWebView2Settings2() *ICoreWebView2Settings2 { var result *ICoreWebView2Settings2 iidICoreWebView2Settings2 := NewGUID("{ee9a0f68-f46c-4e32-ac23-ef8cac224d2a}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Settings2)), @@ -41,7 +61,7 @@ func (i *ICoreWebView2Settings2) GetUserAgent() (string, error) { hr, _, _ := i.Vtbl.GetUserAgent.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Settings3.go b/pkg/webview2/ICoreWebView2Settings3.go index 71c74ef..c1f52e4 100644 --- a/pkg/webview2/ICoreWebView2Settings3.go +++ b/pkg/webview2/ICoreWebView2Settings3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Settings3Vtbl struct { - IUnknownVtbl + ICoreWebView2Settings2Vtbl GetAreBrowserAcceleratorKeysEnabled ComProc PutAreBrowserAcceleratorKeysEnabled ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Settings3) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Settings3() *ICoreWebView2Settings3 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Settings3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Settings) GetICoreWebView2Settings3() *ICoreWebView2Settings3 { var result *ICoreWebView2Settings3 iidICoreWebView2Settings3 := NewGUID("{fdb5ab74-af33-4854-84f0-0a631deb5eba}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Settings3)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2Settings3) PutAreBrowserAcceleratorKeysEnabled(value bool) hr, _, _ := i.Vtbl.PutAreBrowserAcceleratorKeysEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Settings4.go b/pkg/webview2/ICoreWebView2Settings4.go index 0d81a6e..86263ce 100644 --- a/pkg/webview2/ICoreWebView2Settings4.go +++ b/pkg/webview2/ICoreWebView2Settings4.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Settings4Vtbl struct { - IUnknownVtbl + ICoreWebView2Settings3Vtbl GetIsPasswordAutosaveEnabled ComProc PutIsPasswordAutosaveEnabled ComProc GetIsGeneralAutofillEnabled ComProc @@ -25,10 +25,30 @@ func (i *ICoreWebView2Settings4) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Settings4() *ICoreWebView2Settings4 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Settings4) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Settings) GetICoreWebView2Settings4() *ICoreWebView2Settings4 { var result *ICoreWebView2Settings4 iidICoreWebView2Settings4 := NewGUID("{cb56846c-4168-4d53-b04f-03b6d6796ff2}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Settings4)), @@ -57,7 +77,7 @@ func (i *ICoreWebView2Settings4) PutIsPasswordAutosaveEnabled(value bool) error hr, _, _ := i.Vtbl.PutIsPasswordAutosaveEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -85,7 +105,7 @@ func (i *ICoreWebView2Settings4) PutIsGeneralAutofillEnabled(value bool) error { hr, _, _ := i.Vtbl.PutIsGeneralAutofillEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Settings5.go b/pkg/webview2/ICoreWebView2Settings5.go index 88db9de..f13b524 100644 --- a/pkg/webview2/ICoreWebView2Settings5.go +++ b/pkg/webview2/ICoreWebView2Settings5.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Settings5Vtbl struct { - IUnknownVtbl + ICoreWebView2Settings4Vtbl GetIsPinchZoomEnabled ComProc PutIsPinchZoomEnabled ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Settings5) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Settings5() *ICoreWebView2Settings5 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Settings5) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Settings) GetICoreWebView2Settings5() *ICoreWebView2Settings5 { var result *ICoreWebView2Settings5 iidICoreWebView2Settings5 := NewGUID("{183e7052-1d03-43a0-ab99-98e043b66b39}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Settings5)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2Settings5) PutIsPinchZoomEnabled(value bool) error { hr, _, _ := i.Vtbl.PutIsPinchZoomEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Settings6.go b/pkg/webview2/ICoreWebView2Settings6.go index 8e91efc..7bec758 100644 --- a/pkg/webview2/ICoreWebView2Settings6.go +++ b/pkg/webview2/ICoreWebView2Settings6.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Settings6Vtbl struct { - IUnknownVtbl + ICoreWebView2Settings5Vtbl GetIsSwipeNavigationEnabled ComProc PutIsSwipeNavigationEnabled ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Settings6) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Settings6() *ICoreWebView2Settings6 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Settings6) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Settings) GetICoreWebView2Settings6() *ICoreWebView2Settings6 { var result *ICoreWebView2Settings6 iidICoreWebView2Settings6 := NewGUID("{11cb3acd-9bc8-43b8-83bf-f40753714f87}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Settings6)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2Settings6) PutIsSwipeNavigationEnabled(value bool) error { hr, _, _ := i.Vtbl.PutIsSwipeNavigationEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Settings7.go b/pkg/webview2/ICoreWebView2Settings7.go index 1d1a6fe..5cd80ef 100644 --- a/pkg/webview2/ICoreWebView2Settings7.go +++ b/pkg/webview2/ICoreWebView2Settings7.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Settings7Vtbl struct { - IUnknownVtbl + ICoreWebView2Settings6Vtbl GetHiddenPdfToolbarItems ComProc PutHiddenPdfToolbarItems ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Settings7) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Settings7() *ICoreWebView2Settings7 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Settings7) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Settings) GetICoreWebView2Settings7() *ICoreWebView2Settings7 { var result *ICoreWebView2Settings7 iidICoreWebView2Settings7 := NewGUID("{488dc902-35ef-42d2-bc7d-94b65c4bc49c}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Settings7)), diff --git a/pkg/webview2/ICoreWebView2Settings8.go b/pkg/webview2/ICoreWebView2Settings8.go index d4697a3..830cb1b 100644 --- a/pkg/webview2/ICoreWebView2Settings8.go +++ b/pkg/webview2/ICoreWebView2Settings8.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Settings8Vtbl struct { - IUnknownVtbl + ICoreWebView2Settings7Vtbl GetIsReputationCheckingRequired ComProc PutIsReputationCheckingRequired ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Settings8) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Settings8() *ICoreWebView2Settings8 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Settings8) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Settings) GetICoreWebView2Settings8() *ICoreWebView2Settings8 { var result *ICoreWebView2Settings8 iidICoreWebView2Settings8 := NewGUID("{9e6b0e8f-86ad-4e81-8147-a9b5edb68650}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Settings8)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2Settings8) PutIsReputationCheckingRequired(value bool) err hr, _, _ := i.Vtbl.PutIsReputationCheckingRequired.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2Settings9.go b/pkg/webview2/ICoreWebView2Settings9.go index da9ac91..7d33b72 100644 --- a/pkg/webview2/ICoreWebView2Settings9.go +++ b/pkg/webview2/ICoreWebView2Settings9.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2Settings9Vtbl struct { - IUnknownVtbl + ICoreWebView2Settings8Vtbl GetIsNonClientRegionSupportEnabled ComProc PutIsNonClientRegionSupportEnabled ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2Settings9) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2Settings9() *ICoreWebView2Settings9 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2Settings9) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2Settings) GetICoreWebView2Settings9() *ICoreWebView2Settings9 { var result *ICoreWebView2Settings9 iidICoreWebView2Settings9 := NewGUID("{0528a73b-e92d-49f4-927a-e547dddaa37d}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2Settings9)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2Settings9) PutIsNonClientRegionSupportEnabled(value bool) hr, _, _ := i.Vtbl.PutIsNonClientRegionSupportEnabled.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2SharedBuffer.go b/pkg/webview2/ICoreWebView2SharedBuffer.go index dcc4945..1cba3d6 100644 --- a/pkg/webview2/ICoreWebView2SharedBuffer.go +++ b/pkg/webview2/ICoreWebView2SharedBuffer.go @@ -26,6 +26,19 @@ func (i *ICoreWebView2SharedBuffer) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2SharedBuffer) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2SharedBuffer) GetSize() (uint64, error) { var value uint64 diff --git a/pkg/webview2/ICoreWebView2SourceChangedEventArgs.go b/pkg/webview2/ICoreWebView2SourceChangedEventArgs.go index af64cb8..3f3e9e2 100644 --- a/pkg/webview2/ICoreWebView2SourceChangedEventArgs.go +++ b/pkg/webview2/ICoreWebView2SourceChangedEventArgs.go @@ -22,6 +22,19 @@ func (i *ICoreWebView2SourceChangedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2SourceChangedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2SourceChangedEventArgs) GetIsNewDocument() (bool, error) { // Create int32 to hold bool result var _value int32 diff --git a/pkg/webview2/ICoreWebView2StringCollection.go b/pkg/webview2/ICoreWebView2StringCollection.go index fb3afe4..ab1a2a7 100644 --- a/pkg/webview2/ICoreWebView2StringCollection.go +++ b/pkg/webview2/ICoreWebView2StringCollection.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2StringCollection) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2StringCollection) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2StringCollection) GetCount() (uint32, error) { var value uint32 @@ -43,8 +56,8 @@ func (i *ICoreWebView2StringCollection) GetValueAtIndex(index uint32) (string, e hr, _, _ := i.Vtbl.GetValueAtIndex.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&index)), - uintptr(unsafe.Pointer(_value)), + uintptr(index), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2WebMessageReceivedEventArgs.go b/pkg/webview2/ICoreWebView2WebMessageReceivedEventArgs.go index 3de78bb..7214b06 100644 --- a/pkg/webview2/ICoreWebView2WebMessageReceivedEventArgs.go +++ b/pkg/webview2/ICoreWebView2WebMessageReceivedEventArgs.go @@ -24,13 +24,26 @@ func (i *ICoreWebView2WebMessageReceivedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2WebMessageReceivedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2WebMessageReceivedEventArgs) GetSource() (string, error) { // Create *uint16 to hold result var _value *uint16 hr, _, _ := i.Vtbl.GetSource.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -47,7 +60,7 @@ func (i *ICoreWebView2WebMessageReceivedEventArgs) GetWebMessageAsJson() (string hr, _, _ := i.Vtbl.GetWebMessageAsJson.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -64,7 +77,7 @@ func (i *ICoreWebView2WebMessageReceivedEventArgs) TryGetWebMessageAsString() (s hr, _, _ := i.Vtbl.TryGetWebMessageAsString.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2WebMessageReceivedEventArgs2.go b/pkg/webview2/ICoreWebView2WebMessageReceivedEventArgs2.go index 19ae626..c5ca298 100644 --- a/pkg/webview2/ICoreWebView2WebMessageReceivedEventArgs2.go +++ b/pkg/webview2/ICoreWebView2WebMessageReceivedEventArgs2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2WebMessageReceivedEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2WebMessageReceivedEventArgsVtbl GetAdditionalObjects ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2WebMessageReceivedEventArgs2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2WebMessageReceivedEventArgs2() *ICoreWebView2WebMessageReceivedEventArgs2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2WebMessageReceivedEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2WebMessageReceivedEventArgs) GetICoreWebView2WebMessageReceivedEventArgs2() *ICoreWebView2WebMessageReceivedEventArgs2 { var result *ICoreWebView2WebMessageReceivedEventArgs2 iidICoreWebView2WebMessageReceivedEventArgs2 := NewGUID("{06fc7ab7-c90c-4297-9389-33ca01cf6d5e}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2WebMessageReceivedEventArgs2)), diff --git a/pkg/webview2/ICoreWebView2WebResourceRequest.go b/pkg/webview2/ICoreWebView2WebResourceRequest.go index e6f467f..c34e57d 100644 --- a/pkg/webview2/ICoreWebView2WebResourceRequest.go +++ b/pkg/webview2/ICoreWebView2WebResourceRequest.go @@ -28,13 +28,26 @@ func (i *ICoreWebView2WebResourceRequest) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2WebResourceRequest) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2WebResourceRequest) GetUri() (string, error) { // Create *uint16 to hold result var _uri *uint16 hr, _, _ := i.Vtbl.GetUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_uri)), + uintptr(unsafe.Pointer(&_uri)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) @@ -69,7 +82,7 @@ func (i *ICoreWebView2WebResourceRequest) GetMethod() (string, error) { hr, _, _ := i.Vtbl.GetMethod.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_method)), + uintptr(unsafe.Pointer(&_method)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2WebResourceRequestedEventArgs.go b/pkg/webview2/ICoreWebView2WebResourceRequestedEventArgs.go index 6438175..2fdb137 100644 --- a/pkg/webview2/ICoreWebView2WebResourceRequestedEventArgs.go +++ b/pkg/webview2/ICoreWebView2WebResourceRequestedEventArgs.go @@ -26,6 +26,19 @@ func (i *ICoreWebView2WebResourceRequestedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2WebResourceRequestedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2WebResourceRequestedEventArgs) GetRequest() (*ICoreWebView2WebResourceRequest, error) { var request *ICoreWebView2WebResourceRequest diff --git a/pkg/webview2/ICoreWebView2WebResourceRequestedEventArgs2.go b/pkg/webview2/ICoreWebView2WebResourceRequestedEventArgs2.go index 1a50c69..053dc15 100644 --- a/pkg/webview2/ICoreWebView2WebResourceRequestedEventArgs2.go +++ b/pkg/webview2/ICoreWebView2WebResourceRequestedEventArgs2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2WebResourceRequestedEventArgs2Vtbl struct { - IUnknownVtbl + ICoreWebView2WebResourceRequestedEventArgsVtbl GetRequestedSourceKind ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2WebResourceRequestedEventArgs2) AddRef() uintptr { return refCounter } -func (i *ICoreWebView2) GetICoreWebView2WebResourceRequestedEventArgs2() *ICoreWebView2WebResourceRequestedEventArgs2 { +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2WebResourceRequestedEventArgs2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + +func (i *ICoreWebView2WebResourceRequestedEventArgs) GetICoreWebView2WebResourceRequestedEventArgs2() *ICoreWebView2WebResourceRequestedEventArgs2 { var result *ICoreWebView2WebResourceRequestedEventArgs2 iidICoreWebView2WebResourceRequestedEventArgs2 := NewGUID("{9c562c24-b219-4d7f-92f6-b187fbbadd56}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2WebResourceRequestedEventArgs2)), diff --git a/pkg/webview2/ICoreWebView2WebResourceResponse.go b/pkg/webview2/ICoreWebView2WebResourceResponse.go index acb5639..60489bf 100644 --- a/pkg/webview2/ICoreWebView2WebResourceResponse.go +++ b/pkg/webview2/ICoreWebView2WebResourceResponse.go @@ -28,6 +28,19 @@ func (i *ICoreWebView2WebResourceResponse) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2WebResourceResponse) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2WebResourceResponse) GetContent() (*IStream, error) { var content *IStream @@ -68,13 +81,13 @@ func (i *ICoreWebView2WebResourceResponse) GetHeaders() (*ICoreWebView2HttpRespo return headers, nil } -func (i *ICoreWebView2WebResourceResponse) GetStatusCode() (int, error) { +func (i *ICoreWebView2WebResourceResponse) GetStatusCode() (int32, error) { - var statusCode int + var statusCode int32 hr, _, _ := i.Vtbl.GetStatusCode.Call( uintptr(unsafe.Pointer(i)), - uintptr(statusCode), + uintptr(unsafe.Pointer(&statusCode)), ) if windows.Handle(hr) != windows.S_OK { return 0, syscall.Errno(hr) @@ -82,7 +95,7 @@ func (i *ICoreWebView2WebResourceResponse) GetStatusCode() (int, error) { return statusCode, nil } -func (i *ICoreWebView2WebResourceResponse) PutStatusCode(statusCode int) error { +func (i *ICoreWebView2WebResourceResponse) PutStatusCode(statusCode int32) error { hr, _, _ := i.Vtbl.PutStatusCode.Call( uintptr(unsafe.Pointer(i)), @@ -100,7 +113,7 @@ func (i *ICoreWebView2WebResourceResponse) GetReasonPhrase() (string, error) { hr, _, _ := i.Vtbl.GetReasonPhrase.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_reasonPhrase)), + uintptr(unsafe.Pointer(&_reasonPhrase)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2WebResourceResponseReceivedEventArgs.go b/pkg/webview2/ICoreWebView2WebResourceResponseReceivedEventArgs.go index a4fbcf9..ba6daf1 100644 --- a/pkg/webview2/ICoreWebView2WebResourceResponseReceivedEventArgs.go +++ b/pkg/webview2/ICoreWebView2WebResourceResponseReceivedEventArgs.go @@ -23,6 +23,19 @@ func (i *ICoreWebView2WebResourceResponseReceivedEventArgs) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2WebResourceResponseReceivedEventArgs) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2WebResourceResponseReceivedEventArgs) GetRequest() (*ICoreWebView2WebResourceRequest, error) { var value *ICoreWebView2WebResourceRequest diff --git a/pkg/webview2/ICoreWebView2WebResourceResponseView.go b/pkg/webview2/ICoreWebView2WebResourceResponseView.go index 92eff95..aa5a9df 100644 --- a/pkg/webview2/ICoreWebView2WebResourceResponseView.go +++ b/pkg/webview2/ICoreWebView2WebResourceResponseView.go @@ -25,6 +25,19 @@ func (i *ICoreWebView2WebResourceResponseView) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2WebResourceResponseView) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2WebResourceResponseView) GetHeaders() (*ICoreWebView2HttpResponseHeaders, error) { var headers *ICoreWebView2HttpResponseHeaders @@ -39,13 +52,13 @@ func (i *ICoreWebView2WebResourceResponseView) GetHeaders() (*ICoreWebView2HttpR return headers, nil } -func (i *ICoreWebView2WebResourceResponseView) GetStatusCode() (int, error) { +func (i *ICoreWebView2WebResourceResponseView) GetStatusCode() (int32, error) { - var statusCode int + var statusCode int32 hr, _, _ := i.Vtbl.GetStatusCode.Call( uintptr(unsafe.Pointer(i)), - uintptr(statusCode), + uintptr(unsafe.Pointer(&statusCode)), ) if windows.Handle(hr) != windows.S_OK { return 0, syscall.Errno(hr) @@ -59,7 +72,7 @@ func (i *ICoreWebView2WebResourceResponseView) GetReasonPhrase() (string, error) hr, _, _ := i.Vtbl.GetReasonPhrase.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_reasonPhrase)), + uintptr(unsafe.Pointer(&_reasonPhrase)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2WindowFeatures.go b/pkg/webview2/ICoreWebView2WindowFeatures.go index 9dac4b7..1bd776a 100644 --- a/pkg/webview2/ICoreWebView2WindowFeatures.go +++ b/pkg/webview2/ICoreWebView2WindowFeatures.go @@ -31,6 +31,19 @@ func (i *ICoreWebView2WindowFeatures) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2WindowFeatures) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2WindowFeatures) GetHasPosition() (bool, error) { // Create int32 to hold bool result var _value int32 diff --git a/pkg/webview2/ICoreWebView2_10.go b/pkg/webview2/ICoreWebView2_10.go index b30cff8..58799f9 100644 --- a/pkg/webview2/ICoreWebView2_10.go +++ b/pkg/webview2/ICoreWebView2_10.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_10Vtbl struct { - IUnknownVtbl + ICoreWebView2_9Vtbl AddBasicAuthenticationRequested ComProc RemoveBasicAuthenticationRequested ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2_10) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_10) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_10() *ICoreWebView2_10 { var result *ICoreWebView2_10 iidICoreWebView2_10 := NewGUID("{b1690564-6f5a-4983-8e48-31d1143fecdb}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_10)), @@ -54,7 +74,7 @@ func (i *ICoreWebView2_10) RemoveBasicAuthenticationRequested(token EventRegistr hr, _, _ := i.Vtbl.RemoveBasicAuthenticationRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_11.go b/pkg/webview2/ICoreWebView2_11.go index 1588de4..552fe37 100644 --- a/pkg/webview2/ICoreWebView2_11.go +++ b/pkg/webview2/ICoreWebView2_11.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_11Vtbl struct { - IUnknownVtbl + ICoreWebView2_10Vtbl CallDevToolsProtocolMethodForSession ComProc AddContextMenuRequested ComProc RemoveContextMenuRequested ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2_11) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_11) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_11() *ICoreWebView2_11 { var result *ICoreWebView2_11 iidICoreWebView2_11 := NewGUID("{0be78e56-c193-4051-b943-23b460c08bdb}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_11)), @@ -86,7 +106,7 @@ func (i *ICoreWebView2_11) RemoveContextMenuRequested(token EventRegistrationTok hr, _, _ := i.Vtbl.RemoveContextMenuRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_12.go b/pkg/webview2/ICoreWebView2_12.go index 93dd2de..69e6e93 100644 --- a/pkg/webview2/ICoreWebView2_12.go +++ b/pkg/webview2/ICoreWebView2_12.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_12Vtbl struct { - IUnknownVtbl + ICoreWebView2_11Vtbl AddStatusBarTextChanged ComProc RemoveStatusBarTextChanged ComProc GetStatusBarText ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2_12) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_12) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_12() *ICoreWebView2_12 { var result *ICoreWebView2_12 iidICoreWebView2_12 := NewGUID("{35D69927-BCFA-4566-9349-6B3E0D154CAC}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_12)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2_12) RemoveStatusBarTextChanged(token EventRegistrationTok hr, _, _ := i.Vtbl.RemoveStatusBarTextChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -69,7 +89,7 @@ func (i *ICoreWebView2_12) GetStatusBarText() (string, error) { hr, _, _ := i.Vtbl.GetStatusBarText.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_13.go b/pkg/webview2/ICoreWebView2_13.go index a7c973b..ba548c9 100644 --- a/pkg/webview2/ICoreWebView2_13.go +++ b/pkg/webview2/ICoreWebView2_13.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_13Vtbl struct { - IUnknownVtbl + ICoreWebView2_12Vtbl GetProfile ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2_13) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_13) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_13() *ICoreWebView2_13 { var result *ICoreWebView2_13 iidICoreWebView2_13 := NewGUID("{f75f09a8-667e-4983-88d6-c8773f315e84}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_13)), diff --git a/pkg/webview2/ICoreWebView2_14.go b/pkg/webview2/ICoreWebView2_14.go index 3b82850..5d5622a 100644 --- a/pkg/webview2/ICoreWebView2_14.go +++ b/pkg/webview2/ICoreWebView2_14.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_14Vtbl struct { - IUnknownVtbl + ICoreWebView2_13Vtbl AddServerCertificateErrorDetected ComProc RemoveServerCertificateErrorDetected ComProc ClearServerCertificateErrorActions ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2_14) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_14) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_14() *ICoreWebView2_14 { var result *ICoreWebView2_14 iidICoreWebView2_14 := NewGUID("{6daa4f10-4a90-4753-8898-77c5df534165}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_14)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2_14) RemoveServerCertificateErrorDetected(token EventRegis hr, _, _ := i.Vtbl.RemoveServerCertificateErrorDetected.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_15.go b/pkg/webview2/ICoreWebView2_15.go index e85a801..ac98114 100644 --- a/pkg/webview2/ICoreWebView2_15.go +++ b/pkg/webview2/ICoreWebView2_15.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_15Vtbl struct { - IUnknownVtbl + ICoreWebView2_14Vtbl AddFaviconChanged ComProc RemoveFaviconChanged ComProc GetFaviconUri ComProc @@ -25,10 +25,30 @@ func (i *ICoreWebView2_15) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_15) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_15() *ICoreWebView2_15 { var result *ICoreWebView2_15 iidICoreWebView2_15 := NewGUID("{517B2D1D-7DAE-4A66-A4F4-10352FFB9518}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_15)), @@ -56,7 +76,7 @@ func (i *ICoreWebView2_15) RemoveFaviconChanged(token EventRegistrationToken) er hr, _, _ := i.Vtbl.RemoveFaviconChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -70,7 +90,7 @@ func (i *ICoreWebView2_15) GetFaviconUri() (string, error) { hr, _, _ := i.Vtbl.GetFaviconUri.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_value)), + uintptr(unsafe.Pointer(&_value)), ) if windows.Handle(hr) != windows.S_OK { return "", syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_16.go b/pkg/webview2/ICoreWebView2_16.go index 855dedb..0c63fc5 100644 --- a/pkg/webview2/ICoreWebView2_16.go +++ b/pkg/webview2/ICoreWebView2_16.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_16Vtbl struct { - IUnknownVtbl + ICoreWebView2_15Vtbl Print ComProc ShowPrintUI ComProc PrintToPdfStream ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2_16) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_16) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_16() *ICoreWebView2_16 { var result *ICoreWebView2_16 iidICoreWebView2_16 := NewGUID("{0EB34DC9-9F91-41E1-8639-95CD5943906B}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_16)), diff --git a/pkg/webview2/ICoreWebView2_17.go b/pkg/webview2/ICoreWebView2_17.go index 71c5841..4b6eb13 100644 --- a/pkg/webview2/ICoreWebView2_17.go +++ b/pkg/webview2/ICoreWebView2_17.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_17Vtbl struct { - IUnknownVtbl + ICoreWebView2_16Vtbl PostSharedBufferToScript ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2_17) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_17) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_17() *ICoreWebView2_17 { var result *ICoreWebView2_17 iidICoreWebView2_17 := NewGUID("{702e75d4-fd44-434d-9d70-1a68a6b1192a}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_17)), diff --git a/pkg/webview2/ICoreWebView2_18.go b/pkg/webview2/ICoreWebView2_18.go index 7e61d04..b061236 100644 --- a/pkg/webview2/ICoreWebView2_18.go +++ b/pkg/webview2/ICoreWebView2_18.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_18Vtbl struct { - IUnknownVtbl + ICoreWebView2_17Vtbl AddLaunchingExternalUriScheme ComProc RemoveLaunchingExternalUriScheme ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2_18) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_18) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_18() *ICoreWebView2_18 { var result *ICoreWebView2_18 iidICoreWebView2_18 := NewGUID("{7a626017-28be-49b2-b865-3ba2b3522d90}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_18)), @@ -54,7 +74,7 @@ func (i *ICoreWebView2_18) RemoveLaunchingExternalUriScheme(token EventRegistrat hr, _, _ := i.Vtbl.RemoveLaunchingExternalUriScheme.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_19.go b/pkg/webview2/ICoreWebView2_19.go index 9b95eb0..4aea6bf 100644 --- a/pkg/webview2/ICoreWebView2_19.go +++ b/pkg/webview2/ICoreWebView2_19.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_19Vtbl struct { - IUnknownVtbl + ICoreWebView2_18Vtbl GetMemoryUsageTargetLevel ComProc PutMemoryUsageTargetLevel ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2_19) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_19) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_19() *ICoreWebView2_19 { var result *ICoreWebView2_19 iidICoreWebView2_19 := NewGUID("{6921f954-79b0-437f-a997-c85811897c68}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_19)), diff --git a/pkg/webview2/ICoreWebView2_2.go b/pkg/webview2/ICoreWebView2_2.go index 45a2b79..b2180a9 100644 --- a/pkg/webview2/ICoreWebView2_2.go +++ b/pkg/webview2/ICoreWebView2_2.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_2Vtbl struct { - IUnknownVtbl + ICoreWebView2Vtbl AddWebResourceResponseReceived ComProc RemoveWebResourceResponseReceived ComProc NavigateWithWebResourceRequest ComProc @@ -28,10 +28,30 @@ func (i *ICoreWebView2_2) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_2) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_2() *ICoreWebView2_2 { var result *ICoreWebView2_2 iidICoreWebView2_2 := NewGUID("{9E8F0CF8-E670-4B5E-B2BC-73E061E3184C}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_2)), @@ -59,7 +79,7 @@ func (i *ICoreWebView2_2) RemoveWebResourceResponseReceived(token EventRegistrat hr, _, _ := i.Vtbl.RemoveWebResourceResponseReceived.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -98,7 +118,7 @@ func (i *ICoreWebView2_2) RemoveDOMContentLoaded(token EventRegistrationToken) e hr, _, _ := i.Vtbl.RemoveDOMContentLoaded.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_20.go b/pkg/webview2/ICoreWebView2_20.go index fbf69ff..db1e405 100644 --- a/pkg/webview2/ICoreWebView2_20.go +++ b/pkg/webview2/ICoreWebView2_20.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_20Vtbl struct { - IUnknownVtbl + ICoreWebView2_19Vtbl GetFrameId ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2_20) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_20) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_20() *ICoreWebView2_20 { var result *ICoreWebView2_20 iidICoreWebView2_20 := NewGUID("{b4bc1926-7305-11ee-b962-0242ac120002}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_20)), diff --git a/pkg/webview2/ICoreWebView2_21.go b/pkg/webview2/ICoreWebView2_21.go index 54a52d3..9c249c8 100644 --- a/pkg/webview2/ICoreWebView2_21.go +++ b/pkg/webview2/ICoreWebView2_21.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_21Vtbl struct { - IUnknownVtbl + ICoreWebView2_20Vtbl ExecuteScriptWithResult ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2_21) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_21) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_21() *ICoreWebView2_21 { var result *ICoreWebView2_21 iidICoreWebView2_21 := NewGUID("{c4980dea-587b-43b9-8143-3ef3bf552d95}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_21)), diff --git a/pkg/webview2/ICoreWebView2_22.go b/pkg/webview2/ICoreWebView2_22.go index 9107307..3cc7c10 100644 --- a/pkg/webview2/ICoreWebView2_22.go +++ b/pkg/webview2/ICoreWebView2_22.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_22Vtbl struct { - IUnknownVtbl + ICoreWebView2_21Vtbl AddWebResourceRequestedFilterWithRequestSourceKinds ComProc RemoveWebResourceRequestedFilterWithRequestSourceKinds ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2_22) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_22) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_22() *ICoreWebView2_22 { var result *ICoreWebView2_22 iidICoreWebView2_22 := NewGUID("{db75dfc7-a857-4632-a398-6969dde26c0a}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_22)), diff --git a/pkg/webview2/ICoreWebView2_23.go b/pkg/webview2/ICoreWebView2_23.go index 6696cfc..08d75f0 100644 --- a/pkg/webview2/ICoreWebView2_23.go +++ b/pkg/webview2/ICoreWebView2_23.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_23Vtbl struct { - IUnknownVtbl + ICoreWebView2_22Vtbl PostWebMessageAsJsonWithAdditionalObjects ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2_23) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_23) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_23() *ICoreWebView2_23 { var result *ICoreWebView2_23 iidICoreWebView2_23 := NewGUID("{508f0db5-90c4-5872-90a7-267a91377502}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_23)), diff --git a/pkg/webview2/ICoreWebView2_24.go b/pkg/webview2/ICoreWebView2_24.go index 88ca87a..0dd78a8 100644 --- a/pkg/webview2/ICoreWebView2_24.go +++ b/pkg/webview2/ICoreWebView2_24.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_24Vtbl struct { - IUnknownVtbl + ICoreWebView2_23Vtbl AddNotificationReceived ComProc RemoveNotificationReceived ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2_24) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_24) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_24() *ICoreWebView2_24 { var result *ICoreWebView2_24 iidICoreWebView2_24 := NewGUID("{39a7ad55-4287-5cc1-88a1-c6f458593824}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_24)), @@ -54,7 +74,7 @@ func (i *ICoreWebView2_24) RemoveNotificationReceived(token EventRegistrationTok hr, _, _ := i.Vtbl.RemoveNotificationReceived.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_25.go b/pkg/webview2/ICoreWebView2_25.go index 8bff273..b0576d5 100644 --- a/pkg/webview2/ICoreWebView2_25.go +++ b/pkg/webview2/ICoreWebView2_25.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_25Vtbl struct { - IUnknownVtbl + ICoreWebView2_24Vtbl AddSaveAsUIShowing ComProc RemoveSaveAsUIShowing ComProc ShowSaveAsUI ComProc @@ -24,10 +24,30 @@ func (i *ICoreWebView2_25) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_25) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_25() *ICoreWebView2_25 { var result *ICoreWebView2_25 iidICoreWebView2_25 := NewGUID("{b5a86092-df50-5b4f-a17b-6c8f8b40b771}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_25)), @@ -55,7 +75,7 @@ func (i *ICoreWebView2_25) RemoveSaveAsUIShowing(token EventRegistrationToken) e hr, _, _ := i.Vtbl.RemoveSaveAsUIShowing.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_26.go b/pkg/webview2/ICoreWebView2_26.go index e8bf63f..5f80ece 100644 --- a/pkg/webview2/ICoreWebView2_26.go +++ b/pkg/webview2/ICoreWebView2_26.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_26Vtbl struct { - IUnknownVtbl + ICoreWebView2_25Vtbl AddSaveFileSecurityCheckStarting ComProc RemoveSaveFileSecurityCheckStarting ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2_26) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_26) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_26() *ICoreWebView2_26 { var result *ICoreWebView2_26 iidICoreWebView2_26 := NewGUID("{806268b8-f897-5685-88e5-c45fca0b1a48}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_26)), @@ -36,6 +56,7 @@ func (i *ICoreWebView2) GetICoreWebView2_26() *ICoreWebView2_26 { } func (i *ICoreWebView2_26) AddSaveFileSecurityCheckStarting(eventHandler *ICoreWebView2SaveFileSecurityCheckStartingEventHandler) (EventRegistrationToken, error) { + var token EventRegistrationToken hr, _, _ := i.Vtbl.AddSaveFileSecurityCheckStarting.Call( @@ -50,9 +71,10 @@ func (i *ICoreWebView2_26) AddSaveFileSecurityCheckStarting(eventHandler *ICoreW } func (i *ICoreWebView2_26) RemoveSaveFileSecurityCheckStarting(token EventRegistrationToken) error { + hr, _, _ := i.Vtbl.RemoveSaveFileSecurityCheckStarting.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_27.go b/pkg/webview2/ICoreWebView2_27.go index 09e1923..c4332f6 100644 --- a/pkg/webview2/ICoreWebView2_27.go +++ b/pkg/webview2/ICoreWebView2_27.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_27Vtbl struct { - IUnknownVtbl + ICoreWebView2_26Vtbl AddScreenCaptureStarting ComProc RemoveScreenCaptureStarting ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2_27) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_27) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_27() *ICoreWebView2_27 { var result *ICoreWebView2_27 iidICoreWebView2_27 := NewGUID("{00fbe33b-8c07-517c-aa23-0ddd4b5f6fa0}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_27)), @@ -54,7 +74,7 @@ func (i *ICoreWebView2_27) RemoveScreenCaptureStarting(token EventRegistrationTo hr, _, _ := i.Vtbl.RemoveScreenCaptureStarting.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_3.go b/pkg/webview2/ICoreWebView2_3.go index f08d23f..6f555dc 100644 --- a/pkg/webview2/ICoreWebView2_3.go +++ b/pkg/webview2/ICoreWebView2_3.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_3Vtbl struct { - IUnknownVtbl + ICoreWebView2_2Vtbl TrySuspend ComProc Resume ComProc GetIsSuspended ComProc @@ -26,10 +26,30 @@ func (i *ICoreWebView2_3) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_3) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_3() *ICoreWebView2_3 { var result *ICoreWebView2_3 iidICoreWebView2_3 := NewGUID("{A0D6DF20-3B92-416D-AA0C-437A9C727857}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_3)), diff --git a/pkg/webview2/ICoreWebView2_4.go b/pkg/webview2/ICoreWebView2_4.go index e513d4f..c5504ad 100644 --- a/pkg/webview2/ICoreWebView2_4.go +++ b/pkg/webview2/ICoreWebView2_4.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_4Vtbl struct { - IUnknownVtbl + ICoreWebView2_3Vtbl AddFrameCreated ComProc RemoveFrameCreated ComProc AddDownloadStarting ComProc @@ -25,10 +25,30 @@ func (i *ICoreWebView2_4) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_4) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_4() *ICoreWebView2_4 { var result *ICoreWebView2_4 iidICoreWebView2_4 := NewGUID("{20d02d59-6df2-42dc-bd06-f98a694b1302}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_4)), @@ -56,7 +76,7 @@ func (i *ICoreWebView2_4) RemoveFrameCreated(token EventRegistrationToken) error hr, _, _ := i.Vtbl.RemoveFrameCreated.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -83,7 +103,7 @@ func (i *ICoreWebView2_4) RemoveDownloadStarting(token EventRegistrationToken) e hr, _, _ := i.Vtbl.RemoveDownloadStarting.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_5.go b/pkg/webview2/ICoreWebView2_5.go index 6c0b39d..1ad7055 100644 --- a/pkg/webview2/ICoreWebView2_5.go +++ b/pkg/webview2/ICoreWebView2_5.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_5Vtbl struct { - IUnknownVtbl + ICoreWebView2_4Vtbl AddClientCertificateRequested ComProc RemoveClientCertificateRequested ComProc } @@ -23,10 +23,30 @@ func (i *ICoreWebView2_5) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_5) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_5() *ICoreWebView2_5 { var result *ICoreWebView2_5 iidICoreWebView2_5 := NewGUID("{bedb11b8-d63c-11eb-b8bc-0242ac130003}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_5)), @@ -54,7 +74,7 @@ func (i *ICoreWebView2_5) RemoveClientCertificateRequested(token EventRegistrati hr, _, _ := i.Vtbl.RemoveClientCertificateRequested.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_6.go b/pkg/webview2/ICoreWebView2_6.go index 1b93eb1..47a216f 100644 --- a/pkg/webview2/ICoreWebView2_6.go +++ b/pkg/webview2/ICoreWebView2_6.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_6Vtbl struct { - IUnknownVtbl + ICoreWebView2_5Vtbl OpenTaskManagerWindow ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2_6) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_6) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_6() *ICoreWebView2_6 { var result *ICoreWebView2_6 iidICoreWebView2_6 := NewGUID("{499aadac-d92c-4589-8a75-111bfc167795}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_6)), diff --git a/pkg/webview2/ICoreWebView2_7.go b/pkg/webview2/ICoreWebView2_7.go index 19b012b..8a3d4f0 100644 --- a/pkg/webview2/ICoreWebView2_7.go +++ b/pkg/webview2/ICoreWebView2_7.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_7Vtbl struct { - IUnknownVtbl + ICoreWebView2_6Vtbl PrintToPdf ComProc } @@ -22,10 +22,30 @@ func (i *ICoreWebView2_7) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_7) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_7() *ICoreWebView2_7 { var result *ICoreWebView2_7 iidICoreWebView2_7 := NewGUID("{79c24d83-09a3-45ae-9418-487f32a58740}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_7)), diff --git a/pkg/webview2/ICoreWebView2_8.go b/pkg/webview2/ICoreWebView2_8.go index a52aa66..c372d14 100644 --- a/pkg/webview2/ICoreWebView2_8.go +++ b/pkg/webview2/ICoreWebView2_8.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_8Vtbl struct { - IUnknownVtbl + ICoreWebView2_7Vtbl AddIsMutedChanged ComProc RemoveIsMutedChanged ComProc GetIsMuted ComProc @@ -28,10 +28,30 @@ func (i *ICoreWebView2_8) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_8) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_8() *ICoreWebView2_8 { var result *ICoreWebView2_8 iidICoreWebView2_8 := NewGUID("{E9632730-6E1E-43AB-B7B8-7B2C9E62E094}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_8)), @@ -59,7 +79,7 @@ func (i *ICoreWebView2_8) RemoveIsMutedChanged(token EventRegistrationToken) err hr, _, _ := i.Vtbl.RemoveIsMutedChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -87,7 +107,7 @@ func (i *ICoreWebView2_8) PutIsMuted(value bool) error { hr, _, _ := i.Vtbl.PutIsMuted.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + boolToUintptr(value), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -114,7 +134,7 @@ func (i *ICoreWebView2_8) RemoveIsDocumentPlayingAudioChanged(token EventRegistr hr, _, _ := i.Vtbl.RemoveIsDocumentPlayingAudioChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/ICoreWebView2_9.go b/pkg/webview2/ICoreWebView2_9.go index c93fee5..7d121c8 100644 --- a/pkg/webview2/ICoreWebView2_9.go +++ b/pkg/webview2/ICoreWebView2_9.go @@ -9,7 +9,7 @@ import ( ) type ICoreWebView2_9Vtbl struct { - IUnknownVtbl + ICoreWebView2_8Vtbl AddIsDefaultDownloadDialogOpenChanged ComProc RemoveIsDefaultDownloadDialogOpenChanged ComProc GetIsDefaultDownloadDialogOpen ComProc @@ -30,10 +30,30 @@ func (i *ICoreWebView2_9) AddRef() uintptr { return refCounter } +// Release drops one reference and returns the new count. +// +// AddRef was generated for all 252 interfaces and Release for none, which left every caller of a +// Get() accessor leaking: QueryInterface AddRefs on success and there was no matching +// call to make, short of reaching through the embedded IUnknownVtbl for CallRelease. Additive, so +// no existing caller changes. +// +// Not generated for handler interfaces: those are objects WE implement and hand to WebView2, so +// their lifetime is the Go object's, and calling through the vtable would re-enter our own impl. +func (i *ICoreWebView2_9) Release() uint32 { + return i.Vtbl.CallRelease(unsafe.Pointer(i)) +} + func (i *ICoreWebView2) GetICoreWebView2_9() *ICoreWebView2_9 { var result *ICoreWebView2_9 iidICoreWebView2_9 := NewGUID("{4d7b2eab-9fdc-468d-b998-a9260b5ed651}") + // The HRESULT is deliberately not returned, because changing the signature of all 82 of these + // accessors is an API break. It is E_NOINTERFACE whenever the installed WebView2 Runtime is + // older than this interface, which is the normal case rather than an exotic one -- and then + // result stays nil and the CALLER's next method call dereferences it. Callers must nil-check. + // + // This also leaks a reference on success: QueryInterface AddRefs, and no Release is generated. + // Use Vtbl.CallRelease(unsafe.Pointer(x)) via the embedded IUnknownVtbl when finished. _, _, _ = i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_9)), @@ -61,7 +81,7 @@ func (i *ICoreWebView2_9) RemoveIsDefaultDownloadDialogOpenChanged(token EventRe hr, _, _ := i.Vtbl.RemoveIsDefaultDownloadDialogOpenChanged.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&token)), + uintptr(*(*uint64)(unsafe.Pointer(&token))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) @@ -151,7 +171,7 @@ func (i *ICoreWebView2_9) PutDefaultDownloadDialogMargin(value POINT) error { hr, _, _ := i.Vtbl.PutDefaultDownloadDialogMargin.Call( uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&value)), + uintptr(*(*uint64)(unsafe.Pointer(&value))), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/pkg/webview2/com.go b/pkg/webview2/com.go index 125ba21..c3083e3 100644 --- a/pkg/webview2/com.go +++ b/pkg/webview2/com.go @@ -32,6 +32,12 @@ type IUnknownVtbl struct { Release ComProc } +// CallRelease returns the new reference count, which is what IUnknown::Release returns. +// +// This used to return error, built from the Errno that LazyProc.Call yields -- which is +// non-nil on success, so `err != windows.ERROR_SUCCESS` was true for every successful +// Release and the refcount was thrown away. pkg/edge/com.go and the committed +// pkg/webview2/com.go both already carry this corrected form; only the template did not. func (i *IUnknownVtbl) CallRelease(this unsafe.Pointer) uint32 { ret, _, _ := i.Release.Call( uintptr(this), @@ -360,3 +366,16 @@ func (i *IStream) Read(p []byte) (int, error) { return 0, syscall.Errno(res) } } + +// boolToUintptr converts a Go bool to a Win32 BOOL passed by value. +// +// A COM in-parameter declared BOOL is a 4-byte integer passed BY VALUE. Handing over the +// address of a Go bool instead makes the callee read a pointer as an integer -- wrong, and +// wrong differently on each call. uintptr(b) is not a legal Go conversion, so the branch in +// Param.processVtableCallInput emits a call to this instead. +func boolToUintptr(b bool) uintptr { + if b { + return 1 + } + return 0 +}