github.com/go-ole/go-ole@v1.2.6/_example/winsock/winsock.go (about) 1 // +build windows 2 3 package main 4 5 import ( 6 "log" 7 "syscall" 8 "unsafe" 9 10 ole "github.com/go-ole/go-ole" 11 "github.com/go-ole/go-ole/oleutil" 12 ) 13 14 type EventReceiver struct { 15 lpVtbl *EventReceiverVtbl 16 ref int32 17 host *ole.IDispatch 18 } 19 20 type EventReceiverVtbl 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 QueryInterface(this *ole.IUnknown, iid *ole.GUID, punk **ole.IUnknown) uint32 { 31 s, _ := ole.StringFromCLSID(iid) 32 *punk = nil 33 if ole.IsEqualGUID(iid, ole.IID_IUnknown) || 34 ole.IsEqualGUID(iid, ole.IID_IDispatch) { 35 AddRef(this) 36 *punk = this 37 return ole.S_OK 38 } 39 if s == "{248DD893-BB45-11CF-9ABC-0080C7E7B78D}" { 40 AddRef(this) 41 *punk = this 42 return ole.S_OK 43 } 44 return ole.E_NOINTERFACE 45 } 46 47 func AddRef(this *ole.IUnknown) int32 { 48 pthis := (*EventReceiver)(unsafe.Pointer(this)) 49 pthis.ref++ 50 return pthis.ref 51 } 52 53 func Release(this *ole.IUnknown) int32 { 54 pthis := (*EventReceiver)(unsafe.Pointer(this)) 55 pthis.ref-- 56 return pthis.ref 57 } 58 59 func GetIDsOfNames(this *ole.IUnknown, iid *ole.GUID, wnames []*uint16, namelen int, lcid int, pdisp []int32) uintptr { 60 for n := 0; n < namelen; n++ { 61 pdisp[n] = int32(n) 62 } 63 return uintptr(ole.S_OK) 64 } 65 66 func GetTypeInfoCount(pcount *int) uintptr { 67 if pcount != nil { 68 *pcount = 0 69 } 70 return uintptr(ole.S_OK) 71 } 72 73 func GetTypeInfo(ptypeif *uintptr) uintptr { 74 return uintptr(ole.E_NOTIMPL) 75 } 76 77 func Invoke(this *ole.IDispatch, dispid int, riid *ole.GUID, lcid int, flags int16, dispparams *ole.DISPPARAMS, result *ole.VARIANT, pexcepinfo *ole.EXCEPINFO, nerr *uint) uintptr { 78 switch dispid { 79 case 0: 80 log.Println("DataArrival") 81 winsock := (*EventReceiver)(unsafe.Pointer(this)).host 82 var data ole.VARIANT 83 ole.VariantInit(&data) 84 oleutil.CallMethod(winsock, "GetData", &data) 85 s := string(data.ToArray().ToByteArray()) 86 println() 87 println(s) 88 println() 89 case 1: 90 log.Println("Connected") 91 winsock := (*EventReceiver)(unsafe.Pointer(this)).host 92 oleutil.CallMethod(winsock, "SendData", "GET / HTTP/1.0\r\n\r\n") 93 case 3: 94 log.Println("SendProgress") 95 case 4: 96 log.Println("SendComplete") 97 case 5: 98 log.Println("Close") 99 this.Release() 100 case 6: 101 log.Fatal("Error") 102 default: 103 log.Println(dispid) 104 } 105 return ole.E_NOTIMPL 106 } 107 108 func main() { 109 ole.CoInitialize(0) 110 111 unknown, err := oleutil.CreateObject("{248DD896-BB45-11CF-9ABC-0080C7E7B78D}") 112 if err != nil { 113 panic(err.Error()) 114 } 115 winsock, _ := unknown.QueryInterface(ole.IID_IDispatch) 116 iid, _ := ole.CLSIDFromString("{248DD893-BB45-11CF-9ABC-0080C7E7B78D}") 117 118 dest := &EventReceiver{} 119 dest.lpVtbl = &EventReceiverVtbl{} 120 dest.lpVtbl.pQueryInterface = syscall.NewCallback(QueryInterface) 121 dest.lpVtbl.pAddRef = syscall.NewCallback(AddRef) 122 dest.lpVtbl.pRelease = syscall.NewCallback(Release) 123 dest.lpVtbl.pGetTypeInfoCount = syscall.NewCallback(GetTypeInfoCount) 124 dest.lpVtbl.pGetTypeInfo = syscall.NewCallback(GetTypeInfo) 125 dest.lpVtbl.pGetIDsOfNames = syscall.NewCallback(GetIDsOfNames) 126 dest.lpVtbl.pInvoke = syscall.NewCallback(Invoke) 127 dest.host = winsock 128 129 oleutil.ConnectObject(winsock, iid, (*ole.IUnknown)(unsafe.Pointer(dest))) 130 _, err = oleutil.CallMethod(winsock, "Connect", "127.0.0.1", 80) 131 if err != nil { 132 log.Fatal(err) 133 } 134 135 var m ole.Msg 136 for dest.ref != 0 { 137 ole.GetMessage(&m, 0, 0, 0) 138 ole.DispatchMessage(&m) 139 } 140 }