aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-ole/go-ole/com.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/go-ole/go-ole/com.go')
-rw-r--r--vendor/github.com/go-ole/go-ole/com.go329
1 files changed, 329 insertions, 0 deletions
diff --git a/vendor/github.com/go-ole/go-ole/com.go b/vendor/github.com/go-ole/go-ole/com.go
new file mode 100644
index 000000000..75ebbf13f
--- /dev/null
+++ b/vendor/github.com/go-ole/go-ole/com.go
@@ -0,0 +1,329 @@
+// +build windows
+
+package ole
+
+import (
+ "errors"
+ "syscall"
+ "time"
+ "unicode/utf16"
+ "unsafe"
+)
+
+var (
+ procCoInitialize, _ = modole32.FindProc("CoInitialize")
+ procCoInitializeEx, _ = modole32.FindProc("CoInitializeEx")
+ procCoUninitialize, _ = modole32.FindProc("CoUninitialize")
+ procCoCreateInstance, _ = modole32.FindProc("CoCreateInstance")
+ procCoTaskMemFree, _ = modole32.FindProc("CoTaskMemFree")
+ procCLSIDFromProgID, _ = modole32.FindProc("CLSIDFromProgID")
+ procCLSIDFromString, _ = modole32.FindProc("CLSIDFromString")
+ procStringFromCLSID, _ = modole32.FindProc("StringFromCLSID")
+ procStringFromIID, _ = modole32.FindProc("StringFromIID")
+ procIIDFromString, _ = modole32.FindProc("IIDFromString")
+ procGetUserDefaultLCID, _ = modkernel32.FindProc("GetUserDefaultLCID")
+ procCopyMemory, _ = modkernel32.FindProc("RtlMoveMemory")
+ procVariantInit, _ = modoleaut32.FindProc("VariantInit")
+ procVariantClear, _ = modoleaut32.FindProc("VariantClear")
+ procVariantTimeToSystemTime, _ = modoleaut32.FindProc("VariantTimeToSystemTime")
+ procSysAllocString, _ = modoleaut32.FindProc("SysAllocString")
+ procSysAllocStringLen, _ = modoleaut32.FindProc("SysAllocStringLen")
+ procSysFreeString, _ = modoleaut32.FindProc("SysFreeString")
+ procSysStringLen, _ = modoleaut32.FindProc("SysStringLen")
+ procCreateDispTypeInfo, _ = modoleaut32.FindProc("CreateDispTypeInfo")
+ procCreateStdDispatch, _ = modoleaut32.FindProc("CreateStdDispatch")
+ procGetActiveObject, _ = modoleaut32.FindProc("GetActiveObject")
+
+ procGetMessageW, _ = moduser32.FindProc("GetMessageW")
+ procDispatchMessageW, _ = moduser32.FindProc("DispatchMessageW")
+)
+
+// coInitialize initializes COM library on current thread.
+//
+// MSDN documentation suggests that this function should not be called. Call
+// CoInitializeEx() instead. The reason has to do with threading and this
+// function is only for single-threaded apartments.
+//
+// That said, most users of the library have gotten away with just this
+// function. If you are experiencing threading issues, then use
+// CoInitializeEx().
+func coInitialize() (err error) {
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/ms678543(v=vs.85).aspx
+ // Suggests that no value should be passed to CoInitialized.
+ // Could just be Call() since the parameter is optional. <-- Needs testing to be sure.
+ hr, _, _ := procCoInitialize.Call(uintptr(0))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ return
+}
+
+// coInitializeEx initializes COM library with concurrency model.
+func coInitializeEx(coinit uint32) (err error) {
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/ms695279(v=vs.85).aspx
+ // Suggests that the first parameter is not only optional but should always be NULL.
+ hr, _, _ := procCoInitializeEx.Call(uintptr(0), uintptr(coinit))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ return
+}
+
+// CoInitialize initializes COM library on current thread.
+//
+// MSDN documentation suggests that this function should not be called. Call
+// CoInitializeEx() instead. The reason has to do with threading and this
+// function is only for single-threaded apartments.
+//
+// That said, most users of the library have gotten away with just this
+// function. If you are experiencing threading issues, then use
+// CoInitializeEx().
+func CoInitialize(p uintptr) (err error) {
+ // p is ignored and won't be used.
+ // Avoid any variable not used errors.
+ p = uintptr(0)
+ return coInitialize()
+}
+
+// CoInitializeEx initializes COM library with concurrency model.
+func CoInitializeEx(p uintptr, coinit uint32) (err error) {
+ // Avoid any variable not used errors.
+ p = uintptr(0)
+ return coInitializeEx(coinit)
+}
+
+// CoUninitialize uninitializes COM Library.
+func CoUninitialize() {
+ procCoUninitialize.Call()
+}
+
+// CoTaskMemFree frees memory pointer.
+func CoTaskMemFree(memptr uintptr) {
+ procCoTaskMemFree.Call(memptr)
+}
+
+// CLSIDFromProgID retrieves Class Identifier with the given Program Identifier.
+//
+// The Programmatic Identifier must be registered, because it will be looked up
+// in the Windows Registry. The registry entry has the following keys: CLSID,
+// Insertable, Protocol and Shell
+// (https://msdn.microsoft.com/en-us/library/dd542719(v=vs.85).aspx).
+//
+// programID identifies the class id with less precision and is not guaranteed
+// to be unique. These are usually found in the registry under
+// HKEY_LOCAL_MACHINE\SOFTWARE\Classes, usually with the format of
+// "Program.Component.Version" with version being optional.
+//
+// CLSIDFromProgID in Windows API.
+func CLSIDFromProgID(progId string) (clsid *GUID, err error) {
+ var guid GUID
+ lpszProgID := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(progId)))
+ hr, _, _ := procCLSIDFromProgID.Call(lpszProgID, uintptr(unsafe.Pointer(&guid)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ clsid = &guid
+ return
+}
+
+// CLSIDFromString retrieves Class ID from string representation.
+//
+// This is technically the string version of the GUID and will convert the
+// string to object.
+//
+// CLSIDFromString in Windows API.
+func CLSIDFromString(str string) (clsid *GUID, err error) {
+ var guid GUID
+ lpsz := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str)))
+ hr, _, _ := procCLSIDFromString.Call(lpsz, uintptr(unsafe.Pointer(&guid)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ clsid = &guid
+ return
+}
+
+// StringFromCLSID returns GUID formated string from GUID object.
+func StringFromCLSID(clsid *GUID) (str string, err error) {
+ var p *uint16
+ hr, _, _ := procStringFromCLSID.Call(uintptr(unsafe.Pointer(clsid)), uintptr(unsafe.Pointer(&p)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ str = LpOleStrToString(p)
+ return
+}
+
+// IIDFromString returns GUID from program ID.
+func IIDFromString(progId string) (clsid *GUID, err error) {
+ var guid GUID
+ lpsz := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(progId)))
+ hr, _, _ := procIIDFromString.Call(lpsz, uintptr(unsafe.Pointer(&guid)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ clsid = &guid
+ return
+}
+
+// StringFromIID returns GUID formatted string from GUID object.
+func StringFromIID(iid *GUID) (str string, err error) {
+ var p *uint16
+ hr, _, _ := procStringFromIID.Call(uintptr(unsafe.Pointer(iid)), uintptr(unsafe.Pointer(&p)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ str = LpOleStrToString(p)
+ return
+}
+
+// CreateInstance of single uninitialized object with GUID.
+func CreateInstance(clsid *GUID, iid *GUID) (unk *IUnknown, err error) {
+ if iid == nil {
+ iid = IID_IUnknown
+ }
+ hr, _, _ := procCoCreateInstance.Call(
+ uintptr(unsafe.Pointer(clsid)),
+ 0,
+ CLSCTX_SERVER,
+ uintptr(unsafe.Pointer(iid)),
+ uintptr(unsafe.Pointer(&unk)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ return
+}
+
+// GetActiveObject retrieves pointer to active object.
+func GetActiveObject(clsid *GUID, iid *GUID) (unk *IUnknown, err error) {
+ if iid == nil {
+ iid = IID_IUnknown
+ }
+ hr, _, _ := procGetActiveObject.Call(
+ uintptr(unsafe.Pointer(clsid)),
+ uintptr(unsafe.Pointer(iid)),
+ uintptr(unsafe.Pointer(&unk)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ return
+}
+
+// VariantInit initializes variant.
+func VariantInit(v *VARIANT) (err error) {
+ hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ return
+}
+
+// VariantClear clears value in Variant settings to VT_EMPTY.
+func VariantClear(v *VARIANT) (err error) {
+ hr, _, _ := procVariantClear.Call(uintptr(unsafe.Pointer(v)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ return
+}
+
+// SysAllocString allocates memory for string and copies string into memory.
+func SysAllocString(v string) (ss *int16) {
+ pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v))))
+ ss = (*int16)(unsafe.Pointer(pss))
+ return
+}
+
+// SysAllocStringLen copies up to length of given string returning pointer.
+func SysAllocStringLen(v string) (ss *int16) {
+ utf16 := utf16.Encode([]rune(v + "\x00"))
+ ptr := &utf16[0]
+
+ pss, _, _ := procSysAllocStringLen.Call(uintptr(unsafe.Pointer(ptr)), uintptr(len(utf16)-1))
+ ss = (*int16)(unsafe.Pointer(pss))
+ return
+}
+
+// SysFreeString frees string system memory. This must be called with SysAllocString.
+func SysFreeString(v *int16) (err error) {
+ hr, _, _ := procSysFreeString.Call(uintptr(unsafe.Pointer(v)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ return
+}
+
+// SysStringLen is the length of the system allocated string.
+func SysStringLen(v *int16) uint32 {
+ l, _, _ := procSysStringLen.Call(uintptr(unsafe.Pointer(v)))
+ return uint32(l)
+}
+
+// CreateStdDispatch provides default IDispatch implementation for IUnknown.
+//
+// This handles default IDispatch implementation for objects. It haves a few
+// limitations with only supporting one language. It will also only return
+// default exception codes.
+func CreateStdDispatch(unk *IUnknown, v uintptr, ptinfo *IUnknown) (disp *IDispatch, err error) {
+ hr, _, _ := procCreateStdDispatch.Call(
+ uintptr(unsafe.Pointer(unk)),
+ v,
+ uintptr(unsafe.Pointer(ptinfo)),
+ uintptr(unsafe.Pointer(&disp)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ return
+}
+
+// CreateDispTypeInfo provides default ITypeInfo implementation for IDispatch.
+//
+// This will not handle the full implementation of the interface.
+func CreateDispTypeInfo(idata *INTERFACEDATA) (pptinfo *IUnknown, err error) {
+ hr, _, _ := procCreateDispTypeInfo.Call(
+ uintptr(unsafe.Pointer(idata)),
+ uintptr(GetUserDefaultLCID()),
+ uintptr(unsafe.Pointer(&pptinfo)))
+ if hr != 0 {
+ err = NewError(hr)
+ }
+ return
+}
+
+// copyMemory moves location of a block of memory.
+func copyMemory(dest unsafe.Pointer, src unsafe.Pointer, length uint32) {
+ procCopyMemory.Call(uintptr(dest), uintptr(src), uintptr(length))
+}
+
+// GetUserDefaultLCID retrieves current user default locale.
+func GetUserDefaultLCID() (lcid uint32) {
+ ret, _, _ := procGetUserDefaultLCID.Call()
+ lcid = uint32(ret)
+ return
+}
+
+// GetMessage in message queue from runtime.
+//
+// This function appears to block. PeekMessage does not block.
+func GetMessage(msg *Msg, hwnd uint32, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) {
+ r0, _, err := procGetMessageW.Call(uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax))
+ ret = int32(r0)
+ return
+}
+
+// DispatchMessage to window procedure.
+func DispatchMessage(msg *Msg) (ret int32) {
+ r0, _, _ := procDispatchMessageW.Call(uintptr(unsafe.Pointer(msg)))
+ ret = int32(r0)
+ return
+}
+
+// GetVariantDate converts COM Variant Time value to Go time.Time.
+func GetVariantDate(value float64) (time.Time, error) {
+ var st syscall.Systemtime
+ r, _, _ := procVariantTimeToSystemTime.Call(uintptr(value), uintptr(unsafe.Pointer(&st)))
+ if r != 0 {
+ return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil
+ }
+ return time.Now(), errors.New("Could not convert to time, passing current time.")
+}