| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- //go:build windows
- package ole
- import (
- "math/big"
- "syscall"
- "time"
- "unsafe"
- )
- func getIDsOfName(disp *IDispatch, names []string) (dispid []int32, err error) {
- wnames := make([]*uint16, len(names))
- for i := 0; i < len(names); i++ {
- wnames[i] = syscall.StringToUTF16Ptr(names[i])
- }
- dispid = make([]int32, len(names))
- namelen := uint32(len(names))
- hr, _, _ := syscall.Syscall6(
- disp.VTable().GetIDsOfNames,
- 6,
- uintptr(unsafe.Pointer(disp)),
- uintptr(unsafe.Pointer(IID_NULL)),
- uintptr(unsafe.Pointer(&wnames[0])),
- uintptr(namelen),
- uintptr(GetUserDefaultLCID()),
- uintptr(unsafe.Pointer(&dispid[0])))
- if hr != 0 {
- err = NewError(hr)
- }
- return
- }
- func getTypeInfoCount(disp *IDispatch) (c uint32, err error) {
- hr, _, _ := syscall.Syscall(
- disp.VTable().GetTypeInfoCount,
- 2,
- uintptr(unsafe.Pointer(disp)),
- uintptr(unsafe.Pointer(&c)),
- 0)
- if hr != 0 {
- err = NewError(hr)
- }
- return
- }
- func getTypeInfo(disp *IDispatch) (tinfo *ITypeInfo, err error) {
- hr, _, _ := syscall.Syscall(
- disp.VTable().GetTypeInfo,
- 3,
- uintptr(unsafe.Pointer(disp)),
- uintptr(GetUserDefaultLCID()),
- uintptr(unsafe.Pointer(&tinfo)))
- if hr != 0 {
- err = NewError(hr)
- }
- return
- }
- func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (result *VARIANT, err error) {
- var dispparams DISPPARAMS
- if dispatch&DISPATCH_PROPERTYPUT != 0 {
- dispnames := [1]int32{DISPID_PROPERTYPUT}
- dispparams.rgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0]))
- dispparams.cNamedArgs = 1
- } else if dispatch&DISPATCH_PROPERTYPUTREF != 0 {
- dispnames := [1]int32{DISPID_PROPERTYPUT}
- dispparams.rgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0]))
- dispparams.cNamedArgs = 1
- }
- var vargs []VARIANT
- if len(params) > 0 {
- vargs = make([]VARIANT, len(params))
- for i, v := range params {
- // n := len(params)-i-1
- n := len(params) - i - 1
- VariantInit(&vargs[n])
- switch vv := v.(type) {
- case bool:
- if vv {
- vargs[n] = NewVariant(VT_BOOL, 0xffff)
- } else {
- vargs[n] = NewVariant(VT_BOOL, 0)
- }
- case *bool:
- vargs[n] = NewVariant(VT_BOOL|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*bool)))))
- case uint8:
- vargs[n] = NewVariant(VT_I1, int64(v.(uint8)))
- case *uint8:
- vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint8)))))
- case int8:
- vargs[n] = NewVariant(VT_I1, int64(v.(int8)))
- case *int8:
- vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint8)))))
- case int16:
- vargs[n] = NewVariant(VT_I2, int64(v.(int16)))
- case *int16:
- vargs[n] = NewVariant(VT_I2|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int16)))))
- case uint16:
- vargs[n] = NewVariant(VT_UI2, int64(v.(uint16)))
- case *uint16:
- vargs[n] = NewVariant(VT_UI2|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint16)))))
- case int32:
- vargs[n] = NewVariant(VT_I4, int64(v.(int32)))
- case *int32:
- vargs[n] = NewVariant(VT_I4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int32)))))
- case uint32:
- vargs[n] = NewVariant(VT_UI4, int64(v.(uint32)))
- case *uint32:
- vargs[n] = NewVariant(VT_UI4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint32)))))
- case int64:
- vargs[n] = NewVariant(VT_I8, int64(v.(int64)))
- case *int64:
- vargs[n] = NewVariant(VT_I8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int64)))))
- case uint64:
- vargs[n] = NewVariant(VT_UI8, int64(uintptr(v.(uint64))))
- case *uint64:
- vargs[n] = NewVariant(VT_UI8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint64)))))
- case int:
- vargs[n] = NewVariant(VT_I4, int64(v.(int)))
- case *int:
- vargs[n] = NewVariant(VT_I4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int)))))
- case uint:
- vargs[n] = NewVariant(VT_UI4, int64(v.(uint)))
- case *uint:
- vargs[n] = NewVariant(VT_UI4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint)))))
- case float32:
- vargs[n] = NewVariant(VT_R4, *(*int64)(unsafe.Pointer(&vv)))
- case *float32:
- vargs[n] = NewVariant(VT_R4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*float32)))))
- case float64:
- vargs[n] = NewVariant(VT_R8, *(*int64)(unsafe.Pointer(&vv)))
- case *float64:
- vargs[n] = NewVariant(VT_R8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*float64)))))
- case *big.Int:
- vargs[n] = NewVariant(VT_DECIMAL, v.(*big.Int).Int64())
- case string:
- vargs[n] = NewVariant(VT_BSTR, int64(uintptr(unsafe.Pointer(SysAllocStringLen(v.(string))))))
- case *string:
- vargs[n] = NewVariant(VT_BSTR|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*string)))))
- case time.Time:
- s := vv.Format("2006-01-02 15:04:05")
- vargs[n] = NewVariant(VT_BSTR, int64(uintptr(unsafe.Pointer(SysAllocStringLen(s)))))
- case *time.Time:
- s := vv.Format("2006-01-02 15:04:05")
- vargs[n] = NewVariant(VT_BSTR|VT_BYREF, int64(uintptr(unsafe.Pointer(&s))))
- case *IDispatch:
- vargs[n] = NewVariant(VT_DISPATCH, int64(uintptr(unsafe.Pointer(v.(*IDispatch)))))
- case **IDispatch:
- vargs[n] = NewVariant(VT_DISPATCH|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(**IDispatch)))))
- case nil:
- vargs[n] = NewVariant(VT_NULL, 0)
- case *VARIANT:
- vargs[n] = NewVariant(VT_VARIANT|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*VARIANT)))))
- case []byte:
- safeByteArray := safeArrayFromByteSlice(v.([]byte))
- vargs[n] = NewVariant(VT_ARRAY|VT_UI1, int64(uintptr(unsafe.Pointer(safeByteArray))))
- defer VariantClear(&vargs[n])
- case []string:
- safeByteArray := safeArrayFromStringSlice(v.([]string))
- vargs[n] = NewVariant(VT_ARRAY|VT_BSTR, int64(uintptr(unsafe.Pointer(safeByteArray))))
- defer VariantClear(&vargs[n])
- default:
- panic("unknown type")
- }
- }
- dispparams.rgvarg = uintptr(unsafe.Pointer(&vargs[0]))
- dispparams.cArgs = uint32(len(params))
- }
- result = new(VARIANT)
- var excepInfo EXCEPINFO
- VariantInit(result)
- hr, _, _ := syscall.Syscall9(
- disp.VTable().Invoke,
- 9,
- uintptr(unsafe.Pointer(disp)),
- uintptr(dispid),
- uintptr(unsafe.Pointer(IID_NULL)),
- uintptr(GetUserDefaultLCID()),
- uintptr(dispatch),
- uintptr(unsafe.Pointer(&dispparams)),
- uintptr(unsafe.Pointer(result)),
- uintptr(unsafe.Pointer(&excepInfo)),
- 0)
- if hr != 0 {
- err = NewErrorWithSubError(hr, BstrToString(excepInfo.bstrDescription), excepInfo)
- }
- for i, varg := range vargs {
- n := len(params) - i - 1
- if varg.VT == VT_BSTR && varg.Val != 0 {
- SysFreeString(((*int16)(unsafe.Pointer(uintptr(varg.Val)))))
- }
- if varg.VT == (VT_BSTR|VT_BYREF) && varg.Val != 0 {
- *(params[n].(*string)) = LpOleStrToString(*(**uint16)(unsafe.Pointer(uintptr(varg.Val))))
- }
- }
- return
- }
|