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  }