| // +build windows |
| |
| package oleutil |
| |
| import ( |
| "reflect" |
| "unsafe" |
| |
| ole "github.com/go-ole/go-ole" |
| ) |
| |
| type stdDispatch struct { |
| lpVtbl *stdDispatchVtbl |
| ref int32 |
| iid *ole.GUID |
| iface interface{} |
| funcMap map[string]int32 |
| } |
| |
| type stdDispatchVtbl struct { |
| pQueryInterface uintptr |
| pAddRef uintptr |
| pRelease uintptr |
| pGetTypeInfoCount uintptr |
| pGetTypeInfo uintptr |
| pGetIDsOfNames uintptr |
| pInvoke uintptr |
| } |
| |
| func dispQueryInterface(this *ole.IUnknown, iid *ole.GUID, punk **ole.IUnknown) uint32 { |
| pthis := (*stdDispatch)(unsafe.Pointer(this)) |
| *punk = nil |
| if ole.IsEqualGUID(iid, ole.IID_IUnknown) || |
| ole.IsEqualGUID(iid, ole.IID_IDispatch) { |
| dispAddRef(this) |
| *punk = this |
| return ole.S_OK |
| } |
| if ole.IsEqualGUID(iid, pthis.iid) { |
| dispAddRef(this) |
| *punk = this |
| return ole.S_OK |
| } |
| return ole.E_NOINTERFACE |
| } |
| |
| func dispAddRef(this *ole.IUnknown) int32 { |
| pthis := (*stdDispatch)(unsafe.Pointer(this)) |
| pthis.ref++ |
| return pthis.ref |
| } |
| |
| func dispRelease(this *ole.IUnknown) int32 { |
| pthis := (*stdDispatch)(unsafe.Pointer(this)) |
| pthis.ref-- |
| return pthis.ref |
| } |
| |
| func dispGetIDsOfNames(this *ole.IUnknown, iid *ole.GUID, wnames []*uint16, namelen int, lcid int, pdisp []int32) uintptr { |
| pthis := (*stdDispatch)(unsafe.Pointer(this)) |
| names := make([]string, len(wnames)) |
| for i := 0; i < len(names); i++ { |
| names[i] = ole.LpOleStrToString(wnames[i]) |
| } |
| for n := 0; n < namelen; n++ { |
| if id, ok := pthis.funcMap[names[n]]; ok { |
| pdisp[n] = id |
| } |
| } |
| return ole.S_OK |
| } |
| |
| func dispGetTypeInfoCount(pcount *int) uintptr { |
| if pcount != nil { |
| *pcount = 0 |
| } |
| return ole.S_OK |
| } |
| |
| func dispGetTypeInfo(ptypeif *uintptr) uintptr { |
| return ole.E_NOTIMPL |
| } |
| |
| 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 { |
| pthis := (*stdDispatch)(unsafe.Pointer(this)) |
| found := "" |
| for name, id := range pthis.funcMap { |
| if id == dispid { |
| found = name |
| } |
| } |
| if found != "" { |
| rv := reflect.ValueOf(pthis.iface).Elem() |
| rm := rv.MethodByName(found) |
| rr := rm.Call([]reflect.Value{}) |
| println(len(rr)) |
| return ole.S_OK |
| } |
| return ole.E_NOTIMPL |
| } |