diff --git a/ddeml/ddeml.go b/ddeml/ddeml.go new file mode 100644 index 0000000..aeb0aa0 --- /dev/null +++ b/ddeml/ddeml.go @@ -0,0 +1,116 @@ +package ddeml + +import ( + . "go-dde/types" + "unsafe" +) + +var ( + DdeInitialize func( + Inst *DWORD, + Callback any, + Cmd DWORD, + Res DWORD) UINT + + DdeUninitialize func(Inst DWORD) BOOL + + DdeConnectList func( + Inst DWORD, + Service HSZ, + Topic HSZ, + ConvList HCONVLIST, + CC *CONVCONTEXT) HCONVLIST + + DdeQueryNextServer func( + ConvList HCONVLIST, ConvPrev HCONV) HCONV + + DdeDisconnectList func(ConvList HCONVLIST) BOOL + + DdeConnect func( + Inst DWORD, + Service HSZ, + Topic HSZ, + CC *CONVCONTEXT) HCONV + + DdeDisconnect func(Conv HCONV) BOOL + + DdeReconnect func(Conv HCONV) HCONV + + DdeQueryConvInfo func( + Conv HCONV, + Transaction DWORD, + ConvInfo *CONVINFO) UINT + + DdeSetUserHandle func( + Conv HCONV, Id DWORD, User DWORD_PTR) BOOL + + DdeAbandonTransaction func( + Inst DWORD, Conv HCONV, Transaction DWORD) BOOL + + DdePostAdvise func( + Inst DWORD, Topic HSZ, Item HSZ) BOOL + + DdeEnableCallback func( + Inst DWORD, Conv HCONV, Cmd UINT) BOOL + + DdeImpersonateClient func(Conv HCONV) BOOL + + DdeNameService func( + Inst DWORD, S1 HSZ, S2 HSZ, Cmd UINT) HDDEDATA + + DdeClientTransaction func( + Data unsafe.Pointer, //*BYTE + cData DWORD, + Conv HCONV, + Item HSZ, + Fmt UINT, + Type UINT, + Timeout DWORD, + Result *DWORD) HDDEDATA + + DdeCreateDataHandle func( + Inst DWORD, + Src *BYTE, + C DWORD, + Off DWORD, + Item HSZ, + Fmt UINT, + Cmd UINT) HDDEDATA + + DdeAddData func( + Data HDDEDATA, + Src *BYTE, + C DWORD, + Off DWORD) HDDEDATA + + DdeGetData func( + Data HDDEDATA, + Dst *BYTE, + Max DWORD, + Off DWORD) DWORD + + DdeAccessData func( + Data HDDEDATA, DataSize *DWORD) *BYTE + + DdeUnaccessData func(Data HDDEDATA) BOOL + + DdeFreeDataHandle func(Data HDDEDATA) BOOL + + DdeGetLastError func(Inst DWORD) UINT + + DdeCreateStringHandle func( + Inst DWORD, S VString, CodePage int) HSZ + + DdeQueryString func( + Inst DWORD, + S HSZ, + OS OVString, + hMax DWORD, + CodePage int) DWORD + + DdeFreeStringHandle func(Inst DWORD, S HSZ) BOOL + + DdeKeepStringHandle func(Inst DWORD, S HSZ) BOOL + + DdeCmpStringHandles func(S1 HSZ, S2 HSZ) int +) diff --git a/ddeml/ddeml_impl.go b/ddeml/ddeml_impl.go new file mode 100644 index 0000000..9d54f2b --- /dev/null +++ b/ddeml/ddeml_impl.go @@ -0,0 +1,279 @@ +package ddeml + +import ( + "fmt" + . "go-dde/types" + "syscall" + "unsafe" +) + +func init() { + user32 := syscall.MustLoadDLL("user32") + DdeInitialize = func( + Inst *DWORD, + Callback any, + Cmd DWORD, + Res DWORD) UINT { + proc := user32.MustFindProc("DdeInitializeW") + res, _, err := proc.Call( + uintptr(unsafe.Pointer(Inst)), + syscall.NewCallback(Callback), + uintptr(Cmd), + 0) + if err != nil { + fmt.Print(err.Error()) + } + return UINT(res) + } + DdeUninitialize = func(Inst DWORD) BOOL { + proc := user32.MustFindProc("DdeUninitialize") + res, _, _ := proc.Call(uintptr(Inst)) + return BOOL(res) + } + DdeConnectList = func( + Inst DWORD, + Service HSZ, + Topic HSZ, + ConvList HCONVLIST, + CC *CONVCONTEXT) HCONVLIST { + proc := user32.MustFindProc("DdeConnectList") + res, _, _ := proc.Call( + uintptr(Inst), + uintptr(Service), + uintptr(Topic), + uintptr(ConvList), + uintptr(unsafe.Pointer(CC))) + return HCONVLIST(res) + } + + DdeQueryNextServer = func( + ConvList HCONVLIST, ConvPrev HCONV) HCONV { + proc := user32.MustFindProc("DdeQueryNextServer") + res, _, _ := proc.Call(uintptr(ConvList), uintptr(ConvPrev)) + return HCONV(res) + } + + DdeDisconnectList = func(ConvList HCONVLIST) BOOL { + proc := user32.MustFindProc("DdeDisconnectList") + res, _, _ := proc.Call(uintptr(ConvList)) + return BOOL(res) + } + + DdeConnect = func( + Inst DWORD, + Service HSZ, + Topic HSZ, + CC *CONVCONTEXT) HCONV { + proc := user32.MustFindProc("DdeConnect") + res, _, _ := proc.Call( + uintptr(Inst), + uintptr(Service), + uintptr(Topic), + uintptr(unsafe.Pointer(CC)), + ) + return HCONV(res) + } + + DdeDisconnect = func(Conv HCONV) BOOL { + proc := user32.MustFindProc("DdeDisconnect") + res, _, _ := proc.Call(uintptr(Conv)) + return BOOL(res) + } + + DdeReconnect = func(Conv HCONV) HCONV { + proc := user32.MustFindProc("DdeReconnect") + res, _, _ := proc.Call(uintptr(Conv)) + return HCONV(res) + } + + DdeQueryConvInfo = func( + Conv HCONV, + Transaction DWORD, + ConvInfo *CONVINFO) UINT { + proc := user32.MustFindProc("DdeQueryConvInfo") + res, _, _ := proc.Call(uintptr(Conv), + uintptr(Transaction), + uintptr(unsafe.Pointer(ConvInfo))) + return UINT(res) + } + + DdeSetUserHandle = func( + Conv HCONV, Id DWORD, User DWORD_PTR) BOOL { + proc := user32.MustFindProc("DdeSetUserHandle") + res, _, _ := proc.Call(uintptr(Conv), uintptr(Id), uintptr(User)) + return BOOL(res) + } + + DdeAbandonTransaction = func( + Inst DWORD, Conv HCONV, Transaction DWORD) BOOL { + proc := user32.MustFindProc("DdeAbandonTransaction") + res, _, _ := proc.Call(uintptr(Inst), uintptr(Conv), uintptr(Transaction)) + return BOOL(res) + } + + DdePostAdvise = func( + Inst DWORD, Topic HSZ, Item HSZ) BOOL { + proc := user32.MustFindProc("DdePostAdvise") + res, _, _ := proc.Call(uintptr(Inst), uintptr(Topic), uintptr(Item)) + return BOOL(res) + } + + DdeEnableCallback = func( + Inst DWORD, Conv HCONV, Cmd UINT) BOOL { + proc := user32.MustFindProc("DdeEnableCallback") + res, _, _ := proc.Call(uintptr(Inst), uintptr(Conv), uintptr(Cmd)) + return BOOL(res) + } + + DdeImpersonateClient = func(Conv HCONV) BOOL { + proc := user32.MustFindProc("DdeImpersonateClient") + res, _, _ := proc.Call(uintptr(Conv)) + return BOOL(res) + } + + DdeNameService = func( + Inst DWORD, S1 HSZ, S2 HSZ, Cmd UINT) HDDEDATA { + proc := user32.MustFindProc("DdeNameService") + res, _, _ := proc.Call(uintptr(Inst), uintptr(S1), uintptr(S2), uintptr(Cmd)) + return HDDEDATA(res) + } + + DdeClientTransaction = func( + Data unsafe.Pointer, //*BYTE + cData DWORD, + Conv HCONV, + Item HSZ, + Fmt UINT, + Type UINT, + Timeout DWORD, + Result *DWORD) HDDEDATA { + proc := user32.MustFindProc("DdeClientTransaction") + res, _, _ := proc.Call( + uintptr(Data), + uintptr(cData), + uintptr(Conv), + uintptr(Item), + uintptr(Fmt), + uintptr(Type), + uintptr(Timeout), + uintptr(unsafe.Pointer(Result))) + return HDDEDATA(res) + } + + DdeCreateDataHandle = func( + Inst DWORD, + Src *BYTE, + C DWORD, + Off DWORD, + Item HSZ, + Fmt UINT, + Cmd UINT) HDDEDATA { + proc := user32.MustFindProc("DdeCreateDataHandle") + res, _, _ := proc.Call( + uintptr(Inst), + uintptr(unsafe.Pointer(Src)), + uintptr(C), + uintptr(Off), + uintptr(Item), + uintptr(Fmt), + uintptr(Cmd)) + return HDDEDATA(res) + } + + DdeAddData = func( + Data HDDEDATA, + Src *BYTE, + C DWORD, + Off DWORD) HDDEDATA { + proc := user32.MustFindProc("DdeAddData") + res, _, _ := proc.Call(uintptr(Data), + uintptr(unsafe.Pointer(Src)), + uintptr(C), + uintptr(Off)) + return HDDEDATA(res) + } + + DdeGetData = func( + Data HDDEDATA, + Dst *BYTE, + Max DWORD, + Off DWORD) DWORD { + proc := user32.MustFindProc("DdeGetData") + res, _, _ := proc.Call(uintptr(Data), + uintptr(unsafe.Pointer(Dst)), + uintptr(Max), + uintptr(Off)) + return DWORD(res) + } + + DdeAccessData = func( + Data HDDEDATA, DataSize *DWORD) *BYTE { + proc := user32.MustFindProc("DdeAccessData") + res, _, _ := proc.Call(uintptr(Data), + uintptr(unsafe.Pointer(DataSize))) + return (*BYTE)(unsafe.Pointer(res)) + } + + DdeUnaccessData = func(Data HDDEDATA) BOOL { + proc := user32.MustFindProc("DdeUnaccessData") + res, _, _ := proc.Call(uintptr(Data)) + return BOOL(res) + } + + DdeFreeDataHandle = func(Data HDDEDATA) BOOL { + proc := user32.MustFindProc("DdeFreeDataHandle") + res, _, _ := proc.Call(uintptr(Data)) + return BOOL(res) + } + + DdeGetLastError = func(Inst DWORD) UINT { + proc := user32.MustFindProc("DdeGetLastError") + res, _, _ := proc.Call(uintptr(Inst)) + return UINT(res) + } + + DdeCreateStringHandle = func( + Inst DWORD, S VString, CodePage int) HSZ { + u, _ := syscall.UTF16PtrFromString(string(S)) + proc := user32.MustFindProc("DdeCreateStringHandleW") + res, _, _ := proc.Call(uintptr(Inst), uintptr(unsafe.Pointer(u)), uintptr(CodePage)) + return HSZ(res) + } + + DdeQueryString = func( + Inst DWORD, + S HSZ, + OS OVString, + hMax DWORD, + CodePage int) DWORD { + proc := user32.MustFindProc("DdeQueryStringW") + res, _, _ := proc.Call( + uintptr(Inst), + uintptr(S), + uintptr(unsafe.Pointer(&OS)), + uintptr(hMax), + uintptr(CodePage)) + return DWORD(res) + } + + DdeFreeStringHandle = func(Inst DWORD, S HSZ) BOOL { + proc := user32.MustFindProc("DdeFreeStringHandle") + res, _, _ := proc.Call(uintptr(Inst), + uintptr(S)) + return BOOL(res) + } + + DdeKeepStringHandle = func(Inst DWORD, S HSZ) BOOL { + proc := user32.MustFindProc("DdeKeepStringHandle") + res, _, _ := proc.Call(uintptr(Inst), + uintptr(S)) + return BOOL(res) + } + + DdeCmpStringHandles = func(S1 HSZ, S2 HSZ) int { + proc := user32.MustFindProc("DdeCmpStringHandles") + res, _, _ := proc.Call(uintptr(S1), + uintptr(S2)) + return int(res) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5e4236d --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module go-dde + +go 1.18 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/main.go b/main.go new file mode 100644 index 0000000..db9bab6 --- /dev/null +++ b/main.go @@ -0,0 +1,115 @@ +package main + +import ( + "fmt" + dde "go-dde/ddeml" + . "go-dde/types" + "time" + "unsafe" +) + +const ( + MAX_BUFFER_SIZE = 16 +) + +func DdeCallback(wType int, wFmt int, hConv uintptr, hsz1 uintptr, hsz2 uintptr, hData uintptr, dwData1 int64, dwData2 int64) int { + switch wType { + case XTYP_CONNECT: + //接受客户端链接; + return 0 //接受客户端链接 + case XTYP_ADVSTART: + //客户端启动咨询循环。 + return 0 //接受客户端链接 + case XTYP_ADVREQ: + //广播数据; + case XTYP_REQUEST: + //数据请求; + case XTYP_POKE: + //接受客户端发送的数据; + default: + return 0 + } + return 0 +} + +var callbacks FNCALLBACK = func( + Type UINT, + Fmt UINT, + Conv HCONV, + Sz1 HSZ, + Sz2 HSZ, + Data HDDEDATA, + Data1 ULONG_PTR, + Data2 ULONG_PTR) HDDEDATA { + return 0 +} + +func DDERequest(idInst DWORD, hConv HCONV, hszItem HSZ, sDesc string) string { + hData := dde.DdeClientTransaction(nil, 0, hConv, hszItem, UINT(CF_TEXT), + UINT(XTYP_REQUEST), 5000, nil) + if hData == 0 { + return "Request failed" + } else { + size := dde.DdeGetData(hData, nil, 0, 0) + var str BYTE + dde.DdeGetData(hData, &str, size, 0) + buffer := (*[MAX_BUFFER_SIZE]byte)(unsafe.Pointer(&str))[:size-1] + //szResult := *(*[]byte)(unsafe.Pointer(&str)) + return string(buffer) + } +} +func DDEPoke(idInst DWORD, hConv HCONV, hszItem HSZ, szData string) { + var data []byte = []byte(szData) + dde.DdeClientTransaction((unsafe.Pointer(&data)), + DWORD(len(data)+1), + hConv, hszItem, UINT(CF_TEXT), + UINT(XTYP_POKE), 3000, nil) +} + +var idInst DWORD = 0 +var szApp VString = "Server" +var szTopic VString = "MyTopic" +var items []VString = []VString{"MyItem0", "MyItem1", "MyItem2", "MyItem3", "MyItem4", "MyItem5", "MyItem6"} +var hszItem []HSZ = make([]HSZ, len(items)) + +func runClient() { + // AddApis(dde.DdeApis) + // AddApis(dde.DdeANSIApis) + // AddApis(dde.DdeUnicodeApis) + var cmd DWORD = DWORD(APPCLASS_STANDARD | APPCMD_CLIENTONLY) + var res DWORD = 0 + iReturn := dde.DdeInitialize(&idInst, DdeCallback, cmd, res) + if iReturn != UINT(DMLERR_NO_ERROR) { + + } + if int(iReturn) != DMLERR_NO_ERROR { + fmt.Printf("DDE Initialization Failed") + } + var hConv HCONV // 会话句柄 + hszApp := dde.DdeCreateStringHandle(idInst, szApp, 0) + hszTopic := dde.DdeCreateStringHandle(idInst, szTopic, 0) + for i := 0; i < len(items); i++ { + hszItem[i] = dde.DdeCreateStringHandle(idInst, items[i], 0) + } + hConv = dde.DdeConnect(idInst, hszApp, hszTopic, nil) + dde.DdeFreeStringHandle(idInst, hszApp) + dde.DdeFreeStringHandle(idInst, hszTopic) + if hConv == 0 { + fmt.Printf("DDE Connection Failed.\n") + time.Sleep(2e9) //2e9 相当于2秒 + dde.DdeUninitialize(idInst) + } + for i := 0; i < len(items); i++ { + data := DDERequest(idInst, hConv, hszItem[i], "请求到服务端数据: ") + fmt.Printf("data: %v\n", data) + DDEPoke(idInst, hConv, hszItem[i], data) + time.Sleep(1e9) + } + fmt.Printf("客户端关闭") + dde.DdeDisconnect(hConv) + dde.DdeUninitialize(idInst) +} + +func main() { + runClient() +} diff --git a/types/types.go b/types/types.go new file mode 100644 index 0000000..69725e3 --- /dev/null +++ b/types/types.go @@ -0,0 +1,335 @@ +package types + +var ( + DMLERR_NO_ERROR = 0x0000 + DMLERR_ADVACKTIMEOUT = 0x4000 + DMLERR_DATAACKTIMEOUT = 0x4002 + DMLERR_DLL_NOT_INITIALIZED = 0x4003 + DMLERR_EXECACKTIMEOUT = 0x4006 + DMLERR_NO_CONV_ESTABLISHED = 0x400A // (0x400A) + DMLERR_POKEACKTIMEOUT = 0x400B + DMLERR_POSTMSG_FAILED = 0x400C + DMLERR_SERVER_DIED = 0x400E + + CF_TEXT = 1 + CF_BITMAP = 2 + CF_METAFILEPICT = 3 + CF_SYLK = 4 + CF_DIF = 5 + CF_TIFF = 6 + CF_OEMTEXT = 7 + CF_DIB = 8 + CF_PALETTE = 9 + CF_PENDATA = 10 + CF_RIFF = 11 + CF_WAVE = 12 + CF_UNICODETEXT = 13 + CF_ENHMETAFILE = 14 + CF_HDROP = 15 + CF_LOCALE = 16 + CF_DIBV5 = 17 + CF_MAX = 18 + + DDE_FACK = 0x8000 + DDE_FBUSY = 0x4000 + DDE_FDEFERUPD = 0x4000 + DDE_FACKREQ = 0x8000 + DDE_FRELEASE = 0x2000 + DDE_FREQUESTED = 0x1000 + DDE_FAPPSTATUS = 0x00FF + DDE_FNOTPROCESSED = 0x0000 + + //DDE_FACKRESERVED = ~(DDE_FACK | DDE_FBUSY | DDE_FAPPSTATUS) + //DDE_FADVRESERVED = ~(DDE_FACKREQ | DDE_FDEFERUPD) + //DDE_FDATRESERVED = ~(DDE_FACKREQ | DDE_FRELEASE | DDE_FREQUESTED) + //DDE_FPOKRESERVED = ~(DDE_FRELEASE) + + XTYPF_NOBLOCK = 0x0002 + XTYPF_NODATA = 0x0004 + XTYPF_ACKREQ = 0x0008 + + XCLASS_MASK = 0xFC00 + XCLASS_BOOL = 0x1000 + XCLASS_DATA = 0x2000 + XCLASS_FLAGS = 0x4000 + XCLASS_NOTIFICATION = 0x8000 + + XTYP_ERROR = 0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_ADVDATA = 0x0010 | XCLASS_FLAGS + XTYP_ADVREQ = 0x0020 | XCLASS_DATA | XTYPF_NOBLOCK + XTYP_ADVSTART = 0x0030 | XCLASS_BOOL + XTYP_ADVSTOP = 0x0040 | XCLASS_NOTIFICATION + XTYP_EXECUTE = 0x0050 | XCLASS_FLAGS + XTYP_CONNECT = 0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK + XTYP_CONNECT_CONFIRM = 0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_XACT_COMPLETE = 0x0080 | XCLASS_NOTIFICATION + XTYP_POKE = 0x0090 | XCLASS_FLAGS + XTYP_REGISTER = 0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_REQUEST = 0x00B0 | XCLASS_DATA + XTYP_DISCONNECT = 0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_UNREGISTER = 0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_WILDCONNECT = 0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK + XTYP_MONITOR = 0x00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + + XTYP_MASK = 0x00F0 + XTYP_SHIFT = 4 + + TIMEOUT_ASYNC = 0xFFFFFFFF + + APPCLASS_STANDARD = 0x00000000 + APPCMD_CLIENTONLY = 0x00000010 + + CP_WINANSI = 1004 + CP_WINUNICODE = 1200 +) + +type ( + CString byte + UString uint16 + OVString string + VString string + Fake_type_Fix_me uintptr + enum int + ACCESS_MASK DWORD + AChar Char + ALG_ID Unsigned_int + AString *string + ATOM WORD + BOOL int + BOOLEAN byte + BSTR *OLECHAR + BYTE byte + CALID DWORD + CALTYPE DWORD + CH AChar + CLIPFORMAT WORD + COLOR16 USHORT + COLORREF DWORD + Char uint8 + DATE DOUBLE + DISPID int32 + DOUBLE float64 + DWORD uint32 //TODO(t):True w32/w64? + DWORDLONG uint64 //TODO(t):True w32/w64? + DWORD_PTR ULONG_PTR + EXECUTION_STATE DWORD + FARPROC uintptr //TODO(t):unsafe.Pointer? + FLOAT float32 + FOURCC DWORD + FXPT2DOT30 LONG + GEOCLASS DWORD + GEOID LONG + GEOTYPE DWORD + GROUP uint + HACCEL HANDLE + HANDLE DWORD //TODO(t):Actually strict -> struct but go does not do coercion + HBITMAP int //TODO(t):HANDLE but go does not do coercion + HBRUSH HANDLE + HCOLORSPACE HANDLE + HCONV HANDLE + HCONVLIST HANDLE + HCRYPTHASH ULONG_PTR + HCRYPTKEY ULONG_PTR + HCRYPTPROV ULONG_PTR + HCURSOR HANDLE + HDC HANDLE + HDDEDATA HANDLE + HDESK HANDLE + HDEVNOTIFY HANDLE + HDPA HANDLE + HDROP HANDLE + HDRVR HANDLE + HDSA HANDLE + HDWP HANDLE + HENHMETAFILE HANDLE + HFILE HANDLE + HFONT HANDLE + HGDIOBJ HANDLE + HGLOBAL HANDLE + HGLRC HANDLE + HHOOK HANDLE + HICON HANDLE + HIMAGELIST HANDLE + HINSTANCE HANDLE + HKEY HANDLE + HKL HANDLE + HLOCAL HANDLE + HMENU HANDLE + HMETAFILE HANDLE + HMIDI HANDLE + HMIDIIN HANDLE + HMIDIOUT HANDLE + HMIDISTRM HANDLE + HMIXER HANDLE + HMIXEROBJ HANDLE + HMMIO HANDLE + HMODULE HINSTANCE + HMONITOR HANDLE + HOLEMENU HANDLE + HPALETTE HANDLE + HPEN HANDLE + HRAWINPUT HANDLE + HRESULT HANDLE + HRGN HANDLE + HRSRC HANDLE + HSZ HANDLE + HTASK HANDLE + HWAVEIN HANDLE + HWAVEOUT HANDLE + HWINEVENTHOOK HANDLE + HWINSTA HANDLE + HWND HANDLE + IAdviseSink struct{} + IBindCtx struct{} + IBindStatusCallback struct{} + IChannelHook struct{} + IClassFactory struct{} + ICreateErrorInfo struct{} + ICreateTypeLib struct{} + ICreateTypeLib2 struct{} + IDataAdviseHolder struct{} + IDataObject struct{} + IDispatch struct{} + IDropSource struct{} + IDropTarget struct{} + IEnumFORMATETC struct{} + IEnumOLEVERB struct{} + IErrorInfo struct{} + IFillLockBytes struct{} + IInitializeSpy struct{} + ILockBytes struct{} + IMalloc struct{} + IMallocSpy struct{} + IMarshal struct{} + IMessageFilter struct{} + IMoniker struct{} + INT int + INT_PTR INT + IOAString *string + IOleAdviseHolder struct{} + IOleClientSite struct{} + IOleInPlaceActiveObject struct{} + IOleInPlaceFrame struct{} + IOleObject struct{} + IPersistStorage struct{} + IPersistStream struct{} + IRecordInfo struct{} + IRunningObjectTable struct{} + IStorage struct{} + IStream struct{} + ISurrogate struct{} + ITypeInfo struct{} + ITypeLib struct{} + IUnknown struct{} + LANGID USHORT + LCID DWORD + LCSCSTYPE LONG + LCSGAMUTMATCH LONG + LCTYPE DWORD + LGRPID DWORD + LONG int32 //TODO(t):?SIZE __3264 + LONG64 int64 + LONGLONG int64 //TODO(t):Win64=128 + LONG_PTR LONG + LPARAM LONG_PTR + LRESULT LONG_PTR + MCIDEVICEID UINT + MCIERROR DWORD + MENUTEMPLATE *VOID + MMRESULT UINT + MMVERSION UINT + MVString *string //TODO(t):*[]string? + NLS_FUNCTION DWORD + OAString *string + OLECHAR WChar + OLESTR WString + OLESTREAM struct{} + OMVString *string //TODO(t):*[]string ? + OWString *string + REGSAM ACCESS_MASK + RPC_AUTHZ_HANDLE *VOID + RPC_AUTH_IDENTITY_HANDLE *VOID + SCODE int32 + SC_HANDLE HANDLE + SC_LOCK *VOID + SECURITY_CONTEXT_TRACKING_MODE BOOLEAN + SECURITY_DESCRIPTOR_CONTROL USHORT + SECURITY_INFORMATION DWORD + SERVICETYPE ULONG + SERVICE_STATUS_HANDLE HANDLE + SHORT int16 + SIZE_T ULONG_PTR + SNB **OLECHAR + SOCKET UINT_PTR + STREAM IStream + UCHAR byte + UINT uint + UINT_PTR UINT + ULONG DWORD //TODO(t):size + ULONG64 uint64 + ULONGLONG uint64 //TODO(t):Win64=128? + ULONG_PTR uintptr //TODO(t):true def + USHORT uint16 //TODO(t):size + U_int uint + U_long uint32 + U_short uint16 + Unsigned_int uint + Unsigned_long uint32 + Unsigned_short uint16 + VARIANT_BOOL int16 + VARTYPE uint16 + VChar *uint16 //TODO(t): uint8/uint16 + VOID struct{} // //TODO(t):Go does not do coercion; Any side-effects? + VOID64 struct{} //TODO(t):__ptr64 //TODO(t):Go does not do coercion; Any side-effects? + WChar uint16 + WORD uint16 //TODO(t):True 32/64? signed? + WPARAM LONG_PTR + WSAEVENT HANDLE + WString *string +) + +type FNCALLBACK func( + Type UINT, + Fmt UINT, + Conv HCONV, + Sz1 HSZ, + Sz2 HSZ, + Data HDDEDATA, + Data1 ULONG_PTR, + Data2 ULONG_PTR) HDDEDATA + +type SECURITY_IMPERSONATION_LEVEL enum + +type SECURITY_QUALITY_OF_SERVICE struct { + Length DWORD + ImpersonationLevel SECURITY_IMPERSONATION_LEVEL + ContextTrackingMode SECURITY_CONTEXT_TRACKING_MODE + EffectiveOnly BOOLEAN +} +type CONVCONTEXT struct { + Size UINT + Flags UINT + CountryID UINT + CodePage int + LangID DWORD + Security DWORD + QoS SECURITY_QUALITY_OF_SERVICE +} +type CONVINFO struct { + Size DWORD + User DWORD_PTR + ConvPartner HCONV + SvcPartner HSZ + ServiceReq HSZ + Topic HSZ + Item HSZ + Fmt UINT + Type UINT + Status UINT + Convst UINT + LastError UINT + ConvList HCONVLIST + ConvCtxt CONVCONTEXT + Wnd HWND + WndPartner HWND +} diff --git a/util/ddeml.go b/util/ddeml.go new file mode 100644 index 0000000..10540cc --- /dev/null +++ b/util/ddeml.go @@ -0,0 +1,84 @@ +package util + +var ( + DMLERR_NO_ERROR = 0x0000 + DMLERR_ADVACKTIMEOUT = 0x4000 + DMLERR_DATAACKTIMEOUT = 0x4002 + DMLERR_DLL_NOT_INITIALIZED = 0x4003 + DMLERR_EXECACKTIMEOUT = 0x4006 + DMLERR_NO_CONV_ESTABLISHED = 0x400A // (0x400A) + DMLERR_POKEACKTIMEOUT = 0x400B + DMLERR_POSTMSG_FAILED = 0x400C + DMLERR_SERVER_DIED = 0x400E + + CF_TEXT = 1 + CF_BITMAP = 2 + CF_METAFILEPICT = 3 + CF_SYLK = 4 + CF_DIF = 5 + CF_TIFF = 6 + CF_OEMTEXT = 7 + CF_DIB = 8 + CF_PALETTE = 9 + CF_PENDATA = 10 + CF_RIFF = 11 + CF_WAVE = 12 + CF_UNICODETEXT = 13 + CF_ENHMETAFILE = 14 + CF_HDROP = 15 + CF_LOCALE = 16 + CF_DIBV5 = 17 + CF_MAX = 18 + + DDE_FACK = 0x8000 + DDE_FBUSY = 0x4000 + DDE_FDEFERUPD = 0x4000 + DDE_FACKREQ = 0x8000 + DDE_FRELEASE = 0x2000 + DDE_FREQUESTED = 0x1000 + DDE_FAPPSTATUS = 0x00FF + DDE_FNOTPROCESSED = 0x0000 + + //DDE_FACKRESERVED = ~(DDE_FACK | DDE_FBUSY | DDE_FAPPSTATUS) + //DDE_FADVRESERVED = ~(DDE_FACKREQ | DDE_FDEFERUPD) + //DDE_FDATRESERVED = ~(DDE_FACKREQ | DDE_FRELEASE | DDE_FREQUESTED) + //DDE_FPOKRESERVED = ~(DDE_FRELEASE) + + XTYPF_NOBLOCK = 0x0002 + XTYPF_NODATA = 0x0004 + XTYPF_ACKREQ = 0x0008 + + XCLASS_MASK = 0xFC00 + XCLASS_BOOL = 0x1000 + XCLASS_DATA = 0x2000 + XCLASS_FLAGS = 0x4000 + XCLASS_NOTIFICATION = 0x8000 + + XTYP_ERROR = 0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_ADVDATA = 0x0010 | XCLASS_FLAGS + XTYP_ADVREQ = 0x0020 | XCLASS_DATA | XTYPF_NOBLOCK + XTYP_ADVSTART = 0x0030 | XCLASS_BOOL + XTYP_ADVSTOP = 0x0040 | XCLASS_NOTIFICATION + XTYP_EXECUTE = 0x0050 | XCLASS_FLAGS + XTYP_CONNECT = 0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK + XTYP_CONNECT_CONFIRM = 0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_XACT_COMPLETE = 0x0080 | XCLASS_NOTIFICATION + XTYP_POKE = 0x0090 | XCLASS_FLAGS + XTYP_REGISTER = 0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_REQUEST = 0x00B0 | XCLASS_DATA + XTYP_DISCONNECT = 0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_UNREGISTER = 0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + XTYP_WILDCONNECT = 0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK + XTYP_MONITOR = 0x00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK + + XTYP_MASK = 0x00F0 + XTYP_SHIFT = 4 + + TIMEOUT_ASYNC = 0xFFFFFFFF + + APPCLASS_STANDARD = 0x00000000 + APPCMD_CLIENTONLY = 0x00000010 + + CP_WINANSI = 1004 + CP_WINUNICODE = 1200 +)