connection.go 2.2 KB

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