You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
3.9 KiB
191 lines
3.9 KiB
package ole
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"unsafe"
|
|
)
|
|
|
|
// DISPPARAMS are the arguments that passed to methods or property.
|
|
type DISPPARAMS struct {
|
|
rgvarg uintptr
|
|
rgdispidNamedArgs uintptr
|
|
cArgs uint32
|
|
cNamedArgs uint32
|
|
}
|
|
|
|
// EXCEPINFO defines exception info.
|
|
type EXCEPINFO struct {
|
|
wCode uint16
|
|
wReserved uint16
|
|
bstrSource *uint16
|
|
bstrDescription *uint16
|
|
bstrHelpFile *uint16
|
|
dwHelpContext uint32
|
|
pvReserved uintptr
|
|
pfnDeferredFillIn uintptr
|
|
scode uint32
|
|
|
|
// Go-specific part. Don't move upper cos it'll break structure layout for native code.
|
|
rendered bool
|
|
source string
|
|
description string
|
|
helpFile string
|
|
}
|
|
|
|
// renderStrings translates BSTR strings to Go ones so `.Error` and `.String`
|
|
// could be safely called after `.Clear`. We need this when we can't rely on
|
|
// a caller to call `.Clear`.
|
|
func (e *EXCEPINFO) renderStrings() {
|
|
e.rendered = true
|
|
if e.bstrSource == nil {
|
|
e.source = "<nil>"
|
|
} else {
|
|
e.source = BstrToString(e.bstrSource)
|
|
}
|
|
if e.bstrDescription == nil {
|
|
e.description = "<nil>"
|
|
} else {
|
|
e.description = BstrToString(e.bstrDescription)
|
|
}
|
|
if e.bstrHelpFile == nil {
|
|
e.helpFile = "<nil>"
|
|
} else {
|
|
e.helpFile = BstrToString(e.bstrHelpFile)
|
|
}
|
|
}
|
|
|
|
// Clear frees BSTR strings inside an EXCEPINFO and set it to NULL.
|
|
func (e *EXCEPINFO) Clear() {
|
|
freeBSTR := func(s *uint16) {
|
|
// SysFreeString don't return errors and is safe for call's on NULL.
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysfreestring
|
|
_ = SysFreeString((*int16)(unsafe.Pointer(s)))
|
|
}
|
|
|
|
if e.bstrSource != nil {
|
|
freeBSTR(e.bstrSource)
|
|
e.bstrSource = nil
|
|
}
|
|
if e.bstrDescription != nil {
|
|
freeBSTR(e.bstrDescription)
|
|
e.bstrDescription = nil
|
|
}
|
|
if e.bstrHelpFile != nil {
|
|
freeBSTR(e.bstrHelpFile)
|
|
e.bstrHelpFile = nil
|
|
}
|
|
}
|
|
|
|
// WCode return wCode in EXCEPINFO.
|
|
func (e EXCEPINFO) WCode() uint16 {
|
|
return e.wCode
|
|
}
|
|
|
|
// SCODE return scode in EXCEPINFO.
|
|
func (e EXCEPINFO) SCODE() uint32 {
|
|
return e.scode
|
|
}
|
|
|
|
// String convert EXCEPINFO to string.
|
|
func (e EXCEPINFO) String() string {
|
|
if !e.rendered {
|
|
e.renderStrings()
|
|
}
|
|
return fmt.Sprintf(
|
|
"wCode: %#x, bstrSource: %v, bstrDescription: %v, bstrHelpFile: %v, dwHelpContext: %#x, scode: %#x",
|
|
e.wCode, e.source, e.description, e.helpFile, e.dwHelpContext, e.scode,
|
|
)
|
|
}
|
|
|
|
// Error implements error interface and returns error string.
|
|
func (e EXCEPINFO) Error() string {
|
|
if !e.rendered {
|
|
e.renderStrings()
|
|
}
|
|
|
|
if e.description != "<nil>" {
|
|
return strings.TrimSpace(e.description)
|
|
}
|
|
|
|
code := e.scode
|
|
if e.wCode != 0 {
|
|
code = uint32(e.wCode)
|
|
}
|
|
return fmt.Sprintf("%v: %#x", e.source, code)
|
|
}
|
|
|
|
// PARAMDATA defines parameter data type.
|
|
type PARAMDATA struct {
|
|
Name *int16
|
|
Vt uint16
|
|
}
|
|
|
|
// METHODDATA defines method info.
|
|
type METHODDATA struct {
|
|
Name *uint16
|
|
Data *PARAMDATA
|
|
Dispid int32
|
|
Meth uint32
|
|
CC int32
|
|
CArgs uint32
|
|
Flags uint16
|
|
VtReturn uint32
|
|
}
|
|
|
|
// INTERFACEDATA defines interface info.
|
|
type INTERFACEDATA struct {
|
|
MethodData *METHODDATA
|
|
CMembers uint32
|
|
}
|
|
|
|
// Point is 2D vector type.
|
|
type Point struct {
|
|
X int32
|
|
Y int32
|
|
}
|
|
|
|
// Msg is message between processes.
|
|
type Msg struct {
|
|
Hwnd uint32
|
|
Message uint32
|
|
Wparam int32
|
|
Lparam int32
|
|
Time uint32
|
|
Pt Point
|
|
}
|
|
|
|
// TYPEDESC defines data type.
|
|
type TYPEDESC struct {
|
|
Hreftype uint32
|
|
VT uint16
|
|
}
|
|
|
|
// IDLDESC defines IDL info.
|
|
type IDLDESC struct {
|
|
DwReserved uint32
|
|
WIDLFlags uint16
|
|
}
|
|
|
|
// TYPEATTR defines type info.
|
|
type TYPEATTR struct {
|
|
Guid GUID
|
|
Lcid uint32
|
|
dwReserved uint32
|
|
MemidConstructor int32
|
|
MemidDestructor int32
|
|
LpstrSchema *uint16
|
|
CbSizeInstance uint32
|
|
Typekind int32
|
|
CFuncs uint16
|
|
CVars uint16
|
|
CImplTypes uint16
|
|
CbSizeVft uint16
|
|
CbAlignment uint16
|
|
WTypeFlags uint16
|
|
WMajorVerNum uint16
|
|
WMinorVerNum uint16
|
|
TdescAlias TYPEDESC
|
|
IdldescType IDLDESC
|
|
}
|