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