diff --git a/webview2/scripts/generator/testfiles/ICoreWebView2.go.txt b/webview2/scripts/generator/testfiles/ICoreWebView2.go.txt index da352fbcebc..48cf9e7fc4f 100644 --- a/webview2/scripts/generator/testfiles/ICoreWebView2.go.txt +++ b/webview2/scripts/generator/testfiles/ICoreWebView2.go.txt @@ -17,9 +17,14 @@ type ICoreWebView2 struct { Vtbl *ICoreWebView2Vtbl } -func (i *ICoreWebView2) AddRef() uintptr { +func (i *ICoreWebView2) AddRef() uint32 { refCounter, _, _ := i.Vtbl.AddRef.Call(uintptr(unsafe.Pointer(i))) - return refCounter + return uint32(refCounter) +} + +func (i *ICoreWebView2) Release() uint32 { + refCounter, _, _ := i.Vtbl.Release.Call(uintptr(unsafe.Pointer(i))) + return uint32(refCounter) } diff --git a/webview2/scripts/generator/testfiles/ICoreWebView2AcceleratorKeyPressedEventArgs.go.txt b/webview2/scripts/generator/testfiles/ICoreWebView2AcceleratorKeyPressedEventArgs.go.txt index 9e05d6f388b..97e25484a2a 100644 --- a/webview2/scripts/generator/testfiles/ICoreWebView2AcceleratorKeyPressedEventArgs.go.txt +++ b/webview2/scripts/generator/testfiles/ICoreWebView2AcceleratorKeyPressedEventArgs.go.txt @@ -16,9 +16,14 @@ type ICoreWebView2AcceleratorKeyPressedEventArgs struct { Vtbl *ICoreWebView2AcceleratorKeyPressedEventArgsVtbl } -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) AddRef() uintptr { +func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) AddRef() uint32 { refCounter, _, _ := i.Vtbl.AddRef.Call(uintptr(unsafe.Pointer(i))) - return refCounter + return uint32(refCounter) +} + +func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) Release() uint32 { + refCounter, _, _ := i.Vtbl.Release.Call(uintptr(unsafe.Pointer(i))) + return uint32(refCounter) } diff --git a/webview2/scripts/generator/testfiles/ICoreWebView2CustomSchemeRegistration.go.txt b/webview2/scripts/generator/testfiles/ICoreWebView2CustomSchemeRegistration.go.txt index 5f84641027b..f4902eb6ce1 100644 --- a/webview2/scripts/generator/testfiles/ICoreWebView2CustomSchemeRegistration.go.txt +++ b/webview2/scripts/generator/testfiles/ICoreWebView2CustomSchemeRegistration.go.txt @@ -16,24 +16,40 @@ type ICoreWebView2CustomSchemeRegistration struct { Vtbl *ICoreWebView2CustomSchemeRegistrationVtbl } -func (i *ICoreWebView2CustomSchemeRegistration) AddRef() uintptr { +func (i *ICoreWebView2CustomSchemeRegistration) AddRef() uint32 { refCounter, _, _ := i.Vtbl.AddRef.Call(uintptr(unsafe.Pointer(i))) - return refCounter + return uint32(refCounter) } +func (i *ICoreWebView2CustomSchemeRegistration) Release() uint32 { + refCounter, _, _ := i.Vtbl.Release.Call(uintptr(unsafe.Pointer(i))) + return uint32(refCounter) +} -func (i *ICoreWebView2CustomSchemeRegistration) SetAllowedOrigins(allowedOriginsCount uint32, allowedOrigins string) error { - // Convert string 'allowedOrigins' to *uint16 - _allowedOrigins, err := UTF16PtrFromString(allowedOrigins) +func (i *ICoreWebView2CustomSchemeRegistration) SetAllowedOrigins(allowedOriginsCount uint32, allowedOrigins []string) error { + + // Convert []string 'allowedOrigins' to []*uint16 + _allowedOrigins, err := (func() ([]*uint16, error) { + result := make([]*uint16, len(allowedOrigins)) + for _i, _s := range allowedOrigins { + p, e := UTF16PtrFromString(_s) + if e != nil { + return nil, e + } + result[_i] = p + } + return result, nil + })() if err != nil { return err } + hr, _, err := i.Vtbl.SetAllowedOrigins.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&allowedOriginsCount)), - uintptr(unsafe.Pointer(_allowedOrigins)), + uintptr(unsafe.Pointer(&_allowedOrigins[0])), ) if windows.Handle(hr) != windows.S_OK { return syscall.Errno(hr) diff --git a/webview2/scripts/generator/testfiles/ICoreWebView2FrameInfo.go.txt b/webview2/scripts/generator/testfiles/ICoreWebView2FrameInfo.go.txt index 1d81a143643..da52141aa74 100644 --- a/webview2/scripts/generator/testfiles/ICoreWebView2FrameInfo.go.txt +++ b/webview2/scripts/generator/testfiles/ICoreWebView2FrameInfo.go.txt @@ -17,9 +17,14 @@ type ICoreWebView2FrameInfo struct { Vtbl *ICoreWebView2FrameInfoVtbl } -func (i *ICoreWebView2FrameInfo) AddRef() uintptr { +func (i *ICoreWebView2FrameInfo) AddRef() uint32 { refCounter, _, _ := i.Vtbl.AddRef.Call(uintptr(unsafe.Pointer(i))) - return refCounter + return uint32(refCounter) +} + +func (i *ICoreWebView2FrameInfo) Release() uint32 { + refCounter, _, _ := i.Vtbl.Release.Call(uintptr(unsafe.Pointer(i))) + return uint32(refCounter) } @@ -30,7 +35,7 @@ func (i *ICoreWebView2FrameInfo) GetName() (string, error) { hr, _, err := 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) @@ -48,7 +53,7 @@ func (i *ICoreWebView2FrameInfo) GetSource() (string, error) { hr, _, err := 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) diff --git a/webview2/scripts/generator/testfiles/ICoreWebView2ProcessFailedEventArgs2.go.txt b/webview2/scripts/generator/testfiles/ICoreWebView2ProcessFailedEventArgs2.go.txt index c16dd90606f..3620161757d 100644 --- a/webview2/scripts/generator/testfiles/ICoreWebView2ProcessFailedEventArgs2.go.txt +++ b/webview2/scripts/generator/testfiles/ICoreWebView2ProcessFailedEventArgs2.go.txt @@ -16,22 +16,29 @@ type ICoreWebView2ProcessFailedEventArgs2 struct { Vtbl *ICoreWebView2ProcessFailedEventArgs2Vtbl } -func (i *ICoreWebView2ProcessFailedEventArgs2) AddRef() uintptr { +func (i *ICoreWebView2ProcessFailedEventArgs2) AddRef() uint32 { refCounter, _, _ := i.Vtbl.AddRef.Call(uintptr(unsafe.Pointer(i))) - return refCounter + return uint32(refCounter) +} + +func (i *ICoreWebView2ProcessFailedEventArgs2) Release() uint32 { + refCounter, _, _ := i.Vtbl.Release.Call(uintptr(unsafe.Pointer(i))) + return uint32(refCounter) } -func (i *ICoreWebView2) GetICoreWebView2ProcessFailedEventArgs2() *ICoreWebView2ProcessFailedEventArgs2 { +func (i *ICoreWebView2) GetICoreWebView2ProcessFailedEventArgs2() (*ICoreWebView2ProcessFailedEventArgs2, error) { var result *ICoreWebView2ProcessFailedEventArgs2 iidICoreWebView2ProcessFailedEventArgs2 := NewGUID("{4dab9422-46fa-4c3e-a5d2-41d2071d3680}") - _, _, _ = i.Vtbl.QueryInterface.Call( + hr, _, _ := i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2ProcessFailedEventArgs2)), uintptr(unsafe.Pointer(&result))) - - return result + if windows.Handle(hr) != windows.S_OK { + return nil, syscall.Errno(hr) + } + return result, nil } diff --git a/webview2/scripts/generator/testfiles/ICoreWebView2_3.go.txt b/webview2/scripts/generator/testfiles/ICoreWebView2_3.go.txt index e6757908b5c..aea387cf462 100644 --- a/webview2/scripts/generator/testfiles/ICoreWebView2_3.go.txt +++ b/webview2/scripts/generator/testfiles/ICoreWebView2_3.go.txt @@ -16,22 +16,29 @@ type ICoreWebView2_3 struct { Vtbl *ICoreWebView2_3Vtbl } -func (i *ICoreWebView2_3) AddRef() uintptr { +func (i *ICoreWebView2_3) AddRef() uint32 { refCounter, _, _ := i.Vtbl.AddRef.Call(uintptr(unsafe.Pointer(i))) - return refCounter + return uint32(refCounter) +} + +func (i *ICoreWebView2_3) Release() uint32 { + refCounter, _, _ := i.Vtbl.Release.Call(uintptr(unsafe.Pointer(i))) + return uint32(refCounter) } -func (i *ICoreWebView2) GetICoreWebView2_3() *ICoreWebView2_3 { +func (i *ICoreWebView2) GetICoreWebView2_3() (*ICoreWebView2_3, error) { var result *ICoreWebView2_3 iidICoreWebView2_3 := NewGUID("{A0D6DF20-3B92-416D-AA0C-437A9C727857}") - _, _, _ = i.Vtbl.QueryInterface.Call( + hr, _, _ := i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iidICoreWebView2_3)), uintptr(unsafe.Pointer(&result))) - - return result + if windows.Handle(hr) != windows.S_OK { + return nil, syscall.Errno(hr) + } + return result, nil } diff --git a/webview2/scripts/generator/types/param.go b/webview2/scripts/generator/types/param.go index 8075c81a9c0..b625675d35f 100644 --- a/webview2/scripts/generator/types/param.go +++ b/webview2/scripts/generator/types/param.go @@ -45,6 +45,10 @@ func (p *Param) Process(decl *InterfaceMethod) { if p.isDoublePointer() { p.GoType = "*" + p.GoType } + // Bug 2: [in] LPWSTR* / [in] LPCWSTR* is an array of strings, not a single string + if p.IsInputParam() && p.isSinglePointer() && (p.Type == "LPWSTR" || p.Type == "LPCWSTR") { + p.GoType = "[]string" + } p.OutputGoType = p.GoType if p.IsOutputParam() && strings.HasPrefix(p.OutputGoType, "**") { p.OutputGoType = p.GoType[1:] @@ -65,7 +69,8 @@ func (p *Param) isDoublePointer() bool { } func (p *Param) AsInputType() string { - if p.isPointer() && p.GoType != "string" { + // For string slices ([]string from [in] LPWSTR*) and plain strings, pass as-is + if p.isPointer() && p.GoType != "string" && !strings.HasPrefix(p.GoType, "[]") { return "*" + p.GoType } return p.GoType @@ -109,7 +114,15 @@ func (p *Param) processVtableCallInput() { } switch p.Type { case "LPCWSTR", "LPWSTR": - p.VtableCallInput = "uintptr(unsafe.Pointer(" + variableName + "))" + if p.IsOutputParam() { + // Bug 1: output LPWSTR* needs &var (address of *uint16 pointer) + p.VtableCallInput = "uintptr(unsafe.Pointer(&" + variableName + "))" + } else if p.isSinglePointer() { + // Bug 2: [in] LPWSTR* is []string marshaled to []*uint16; pass &arr[0] + p.VtableCallInput = "uintptr(unsafe.Pointer(&" + variableName + "[0]))" + } else { + p.VtableCallInput = "uintptr(unsafe.Pointer(" + variableName + "))" + } return } if p.Pointer == "**" { @@ -165,6 +178,10 @@ func (p *Param) processSetupInputs() { // We need to convert to *uint16 p.setupTemplate = "inputStringSetup.tmpl" p.LocalName = "_" + p.Name + case "[]string": + // Bug 2: [in] LPWSTR* array — convert each element to *uint16 + p.setupTemplate = "inputStringArraySetup.tmpl" + p.LocalName = "_" + p.Name } } diff --git a/webview2/scripts/generator/types/templates/com.tmpl b/webview2/scripts/generator/types/templates/com.tmpl index d74edfa22ac..037a02fa527 100644 --- a/webview2/scripts/generator/types/templates/com.tmpl +++ b/webview2/scripts/generator/types/templates/com.tmpl @@ -44,8 +44,8 @@ func (i *IUnknownVtbl) CallRelease(this unsafe.Pointer) error { type IUnknownImpl interface { QueryInterface(refiid, object uintptr) uintptr - AddRef() uintptr - Release() uintptr + AddRef() uint32 + Release() uint32 } // Call calls a COM procedure. @@ -72,8 +72,15 @@ type HMENU uintptr type HMODULE uintptr type HWND uintptr -// NOTE: For sure, this is wrong! -type VARIANT uintptr +// VARIANT is a 16-byte Windows VARIANT type matching the Windows ABI. +// The Val field is a union; callers must interpret it based on VT. +type VARIANT struct { + VT uint16 + Reserved1 uint16 + Reserved2 uint16 + Reserved3 uint16 + Val [8]byte +} type IDataObject struct { IUnknown diff --git a/webview2/scripts/generator/types/templates/inputStringArraySetup.tmpl b/webview2/scripts/generator/types/templates/inputStringArraySetup.tmpl new file mode 100644 index 00000000000..ce46bfd0dab --- /dev/null +++ b/webview2/scripts/generator/types/templates/inputStringArraySetup.tmpl @@ -0,0 +1,16 @@ + + // Convert []string '{{.Param.Name}}' to []*uint16 + {{.Param.LocalName}}, err := (func() ([]*uint16, error) { + result := make([]*uint16, len({{.Param.Name}})) + for _i, _s := range {{.Param.Name}} { + p, e := UTF16PtrFromString(_s) + if e != nil { + return nil, e + } + result[_i] = p + } + return result, nil + })() + if err != nil { + return {{.ErrorValues}} + } diff --git a/webview2/scripts/generator/types/templates/interfaceInvoke.tmpl b/webview2/scripts/generator/types/templates/interfaceInvoke.tmpl index 316f83a30d7..e33b981860c 100644 --- a/webview2/scripts/generator/types/templates/interfaceInvoke.tmpl +++ b/webview2/scripts/generator/types/templates/interfaceInvoke.tmpl @@ -3,11 +3,11 @@ func {{.Name}}IUnknownQueryInterface(this *{{.Declaration.Name}}, refiid, object } func {{.Declaration.Name}}IUnknownAddRef(this *{{.Declaration.Name}}) uintptr { - return this.impl.AddRef() + return uintptr(this.impl.AddRef()) } func {{.Declaration.Name}}IUnknownRelease(this *{{.Declaration.Name}}) uintptr { - return this.impl.Release() + return uintptr(this.impl.Release()) } func {{.Declaration.Name}}Invoke(this *{{.Declaration.Name}}, {{.InvokeMethod.GoInputs}}) uintptr { diff --git a/webview2/scripts/generator/types/templates/interfacevtbl.tmpl b/webview2/scripts/generator/types/templates/interfacevtbl.tmpl index 19261498ec8..5e9eb858e00 100644 --- a/webview2/scripts/generator/types/templates/interfacevtbl.tmpl +++ b/webview2/scripts/generator/types/templates/interfacevtbl.tmpl @@ -24,22 +24,29 @@ type {{.Name}} struct { {{- end}} } -func (i *{{.Name}}) AddRef() uintptr { +func (i *{{.Name}}) AddRef() uint32 { refCounter, _, _ := i.Vtbl.AddRef.Call(uintptr(unsafe.Pointer(i))) - return refCounter + return uint32(refCounter) +} + +func (i *{{.Name}}) Release() uint32 { + refCounter, _, _ := i.Vtbl.Release.Call(uintptr(unsafe.Pointer(i))) + return uint32(refCounter) } {{if .BaseClass }} -func (i *ICoreWebView2) Get{{.Name}}() *{{.Name}} { +func (i *ICoreWebView2) Get{{.Name}}() (*{{.Name}}, error) { var result *{{.Name}} iid{{.Name}} := NewGUID({{.Header.AsString}}) - _, _, _ = i.Vtbl.QueryInterface.Call( + hr, _, _ := i.Vtbl.QueryInterface.Call( uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(iid{{.Name}})), uintptr(unsafe.Pointer(&result))) - - return result + if windows.Handle(hr) != windows.S_OK { + return nil, syscall.Errno(hr) + } + return result, nil } {{end}} \ No newline at end of file