github.com/remoteit/go-ole@v1.2.7/ole.go (about)

     1  package ole
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"unsafe"
     7  )
     8  
     9  // DISPPARAMS are the arguments that passed to methods or property.
    10  type DISPPARAMS struct {
    11  	rgvarg            uintptr
    12  	rgdispidNamedArgs uintptr
    13  	cArgs             uint32
    14  	cNamedArgs        uint32
    15  }
    16  
    17  // EXCEPINFO defines exception info.
    18  type EXCEPINFO struct {
    19  	wCode             uint16
    20  	wReserved         uint16
    21  	bstrSource        *uint16
    22  	bstrDescription   *uint16
    23  	bstrHelpFile      *uint16
    24  	dwHelpContext     uint32
    25  	pvReserved        uintptr
    26  	pfnDeferredFillIn uintptr
    27  	scode             uint32
    28  
    29  	// Go-specific part. Don't move upper cos it'll break structure layout for native code.
    30  	rendered    bool
    31  	source      string
    32  	description string
    33  	helpFile    string
    34  }
    35  
    36  // renderStrings translates BSTR strings to Go ones so `.Error` and `.String`
    37  // could be safely called after `.Clear`. We need this when we can't rely on
    38  // a caller to call `.Clear`.
    39  func (e *EXCEPINFO) renderStrings() {
    40  	e.rendered = true
    41  	if e.bstrSource == nil {
    42  		e.source = "<nil>"
    43  	} else {
    44  		e.source = BstrToString(e.bstrSource)
    45  	}
    46  	if e.bstrDescription == nil {
    47  		e.description = "<nil>"
    48  	} else {
    49  		e.description = BstrToString(e.bstrDescription)
    50  	}
    51  	if e.bstrHelpFile == nil {
    52  		e.helpFile = "<nil>"
    53  	} else {
    54  		e.helpFile = BstrToString(e.bstrHelpFile)
    55  	}
    56  }
    57  
    58  // Clear frees BSTR strings inside an EXCEPINFO and set it to NULL.
    59  func (e *EXCEPINFO) Clear() {
    60  	freeBSTR := func(s *uint16) {
    61  		// SysFreeString don't return errors and is safe for call's on NULL.
    62  		// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysfreestring
    63  		_ = SysFreeString((*int16)(unsafe.Pointer(s)))
    64  	}
    65  
    66  	if e.bstrSource != nil {
    67  		freeBSTR(e.bstrSource)
    68  		e.bstrSource = nil
    69  	}
    70  	if e.bstrDescription != nil {
    71  		freeBSTR(e.bstrDescription)
    72  		e.bstrDescription = nil
    73  	}
    74  	if e.bstrHelpFile != nil {
    75  		freeBSTR(e.bstrHelpFile)
    76  		e.bstrHelpFile = nil
    77  	}
    78  }
    79  
    80  // WCode return wCode in EXCEPINFO.
    81  func (e EXCEPINFO) WCode() uint16 {
    82  	return e.wCode
    83  }
    84  
    85  // SCODE return scode in EXCEPINFO.
    86  func (e EXCEPINFO) SCODE() uint32 {
    87  	return e.scode
    88  }
    89  
    90  // String convert EXCEPINFO to string.
    91  func (e EXCEPINFO) String() string {
    92  	if !e.rendered {
    93  		e.renderStrings()
    94  	}
    95  	return fmt.Sprintf(
    96  		"wCode: %#x, bstrSource: %v, bstrDescription: %v, bstrHelpFile: %v, dwHelpContext: %#x, scode: %#x",
    97  		e.wCode, e.source, e.description, e.helpFile, e.dwHelpContext, e.scode,
    98  	)
    99  }
   100  
   101  // Error implements error interface and returns error string.
   102  func (e EXCEPINFO) Error() string {
   103  	if !e.rendered {
   104  		e.renderStrings()
   105  	}
   106  
   107  	if e.description != "<nil>" {
   108  		return strings.TrimSpace(e.description)
   109  	}
   110  
   111  	code := e.scode
   112  	if e.wCode != 0 {
   113  		code = uint32(e.wCode)
   114  	}
   115  	return fmt.Sprintf("%v: %#x", e.source, code)
   116  }
   117  
   118  // PARAMDATA defines parameter data type.
   119  type PARAMDATA struct {
   120  	Name *int16
   121  	Vt   uint16
   122  }
   123  
   124  // METHODDATA defines method info.
   125  type METHODDATA struct {
   126  	Name     *uint16
   127  	Data     *PARAMDATA
   128  	Dispid   int32
   129  	Meth     uint32
   130  	CC       int32
   131  	CArgs    uint32
   132  	Flags    uint16
   133  	VtReturn uint32
   134  }
   135  
   136  // INTERFACEDATA defines interface info.
   137  type INTERFACEDATA struct {
   138  	MethodData *METHODDATA
   139  	CMembers   uint32
   140  }
   141  
   142  // Point is 2D vector type.
   143  type Point struct {
   144  	X int32
   145  	Y int32
   146  }
   147  
   148  // Msg is message between processes.
   149  type Msg struct {
   150  	Hwnd    uint32
   151  	Message uint32
   152  	Wparam  int32
   153  	Lparam  int32
   154  	Time    uint32
   155  	Pt      Point
   156  }
   157  
   158  // TYPEDESC defines data type.
   159  type TYPEDESC struct {
   160  	Hreftype uint32
   161  	VT       uint16
   162  }
   163  
   164  // IDLDESC defines IDL info.
   165  type IDLDESC struct {
   166  	DwReserved uint32
   167  	WIDLFlags  uint16
   168  }
   169  
   170  // TYPEATTR defines type info.
   171  type TYPEATTR struct {
   172  	Guid             GUID
   173  	Lcid             uint32
   174  	dwReserved       uint32
   175  	MemidConstructor int32
   176  	MemidDestructor  int32
   177  	LpstrSchema      *uint16
   178  	CbSizeInstance   uint32
   179  	Typekind         int32
   180  	CFuncs           uint16
   181  	CVars            uint16
   182  	CImplTypes       uint16
   183  	CbSizeVft        uint16
   184  	CbAlignment      uint16
   185  	WTypeFlags       uint16
   186  	WMajorVerNum     uint16
   187  	WMinorVerNum     uint16
   188  	TdescAlias       TYPEDESC
   189  	IdldescType      IDLDESC
   190  }