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  }