github.com/hspan/go-ole@v0.0.0/oleutil/connection.go (about) 1 // +build windows 2 3 package oleutil 4 5 import ( 6 "reflect" 7 "unsafe" 8 9 ole "github.com/hspan/go-ole" 10 ) 11 12 type stdDispatch struct { 13 lpVtbl *stdDispatchVtbl 14 ref int32 15 iid *ole.GUID 16 iface interface{} 17 funcMap map[string]int32 18 } 19 20 type stdDispatchVtbl struct { 21 pQueryInterface uintptr 22 pAddRef uintptr 23 pRelease uintptr 24 pGetTypeInfoCount uintptr 25 pGetTypeInfo uintptr 26 pGetIDsOfNames uintptr 27 pInvoke uintptr 28 } 29 30 func dispQueryInterface(this *ole.IUnknown, iid *ole.GUID, punk **ole.IUnknown) uint32 { 31 pthis := (*stdDispatch)(unsafe.Pointer(this)) 32 *punk = nil 33 if ole.IsEqualGUID(iid, ole.IID_IUnknown) || 34 ole.IsEqualGUID(iid, ole.IID_IDispatch) { 35 dispAddRef(this) 36 *punk = this 37 return ole.S_OK 38 } 39 if ole.IsEqualGUID(iid, pthis.iid) { 40 dispAddRef(this) 41 *punk = this 42 return ole.S_OK 43 } 44 return ole.E_NOINTERFACE 45 } 46 47 func dispAddRef(this *ole.IUnknown) int32 { 48 pthis := (*stdDispatch)(unsafe.Pointer(this)) 49 pthis.ref++ 50 return pthis.ref 51 } 52 53 func dispRelease(this *ole.IUnknown) int32 { 54 pthis := (*stdDispatch)(unsafe.Pointer(this)) 55 pthis.ref-- 56 return pthis.ref 57 } 58 59 func dispGetIDsOfNames(this *ole.IUnknown, iid *ole.GUID, wnames []*uint16, namelen int, lcid int, pdisp []int32) uintptr { 60 pthis := (*stdDispatch)(unsafe.Pointer(this)) 61 names := make([]string, len(wnames)) 62 for i := 0; i < len(names); i++ { 63 names[i] = ole.LpOleStrToString(wnames[i]) 64 } 65 for n := 0; n < namelen; n++ { 66 if id, ok := pthis.funcMap[names[n]]; ok { 67 pdisp[n] = id 68 } 69 } 70 return ole.S_OK 71 } 72 73 func dispGetTypeInfoCount(pcount *int) uintptr { 74 if pcount != nil { 75 *pcount = 0 76 } 77 return ole.S_OK 78 } 79 80 func dispGetTypeInfo(ptypeif *uintptr) uintptr { 81 return ole.E_NOTIMPL 82 } 83 84 func dispInvoke(this *ole.IDispatch, dispid int32, riid *ole.GUID, lcid int, flags int16, dispparams *ole.DISPPARAMS, result *ole.VARIANT, pexcepinfo *ole.EXCEPINFO, nerr *uint) uintptr { 85 pthis := (*stdDispatch)(unsafe.Pointer(this)) 86 found := "" 87 for name, id := range pthis.funcMap { 88 if id == dispid { 89 found = name 90 } 91 } 92 if found != "" { 93 rv := reflect.ValueOf(pthis.iface).Elem() 94 rm := rv.MethodByName(found) 95 rr := rm.Call([]reflect.Value{}) 96 println(len(rr)) 97 return ole.S_OK 98 } 99 return ole.E_NOTIMPL 100 }