summaryrefslogtreecommitdiff
path: root/OSpiceX.h
diff options
context:
space:
mode:
Diffstat (limited to 'OSpiceX.h')
-rw-r--r--OSpiceX.h454
1 files changed, 454 insertions, 0 deletions
diff --git a/OSpiceX.h b/OSpiceX.h
new file mode 100644
index 0000000..406435b
--- /dev/null
+++ b/OSpiceX.h
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the GNU General Public License, version 2 or any
+ * later version. See the file COPYING in the top-level directory of
+ * this distribution or http://www.gnu.org/licenses/gpl-2.0.txt.
+ */
+// OSpiceX.h : Declaration of the COSpiceX
+
+#pragma once
+
+#include "resource.h" // main symbols
+
+// atl uses the deprecate function wsprintfA, disable the C4995 warning
+#pragma warning(disable : 4995)
+#include <atlctl.h>
+#include <map>
+#include "stdint.h"
+
+#include "SpiceX.h"
+#include "SpiceXCommon.h"
+#include "_IOSpiceXEvents_CP.h"
+
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
+#endif
+
+// All SpiceX Windows Messages constants are offsets from SPICEX_WM_BASE
+#define SPICEX_WM_BASE WM_USER + 0x1000 // 0x0400 + 0x1000 = 0x1400 = 5120
+#define SPICEX_ON_DISCONNECTED_MSG (SPICEX_WM_BASE+0) // 5120
+#define SPICEX_ON_MENU_ITEM_SELECTED_MSG (SPICEX_WM_BASE+1) // 5120
+
+// http://msdn.microsoft.com/en-us/library/aa911976.aspx
+#define RDP_ERROR_CODE_LOCAL_DISCONNECTION 1
+#define RDP_ERROR_CODE_DNS_LOOKUP_FAILED 260
+#define RDP_ERROR_CODE_OUT_OF_MEMORY 262
+#define RDP_ERROR_CODE_WINSOCK_CONNECT_FAILED 516
+#define RDP_ERROR_CODE_HOST_NOT_FOUND 520
+#define RDP_ERROR_CODE_INTERNAL_ERROR 1032
+#define RDP_ERROR_RECV_WINSOCK_FAILED 1028
+#define RDP_ERROR_SEND_WINSOCK_FAILED 772
+#define RDP_ERROR_CODE_TIMEOUT 1796
+
+#define SPICE_ERROR_BASE 100
+
+#define PIPE_BUF_SIZE 16384
+
+struct ControllerValue;
+
+// COSpiceX
+class ATL_NO_VTABLE COSpiceX :
+ public CComObjectRootEx<CComSingleThreadModel>,
+ public IDispatchImpl<IOSpiceX, &IID_IOSpiceX, &LIBID_SpiceXLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
+ public IPersistStreamInitImpl<COSpiceX>,
+ public IPersistPropertyBagImpl<COSpiceX>,
+ public IOleControlImpl<COSpiceX>,
+ public IOleObjectImpl<COSpiceX>,
+ public IOleInPlaceActiveObjectImpl<COSpiceX>,
+ public IViewObjectExImpl<COSpiceX>,
+ public IOleInPlaceObjectWindowlessImpl<COSpiceX>,
+ public ISupportErrorInfo,
+ public IConnectionPointContainerImpl<COSpiceX>,
+ public CProxy_IOSpiceXEvents<COSpiceX>,
+ public IPersistStorageImpl<COSpiceX>,
+ public ISpecifyPropertyPagesImpl<COSpiceX>,
+ public IQuickActivateImpl<COSpiceX>,
+#ifndef _WIN32_WCE
+ public IDataObjectImpl<COSpiceX>,
+#endif
+ public IProvideClassInfo2Impl<&CLSID_OSpiceX, &__uuidof(_IOSpiceXEvents), &LIBID_SpiceXLib>,
+#ifdef _WIN32_WCE // IObjectSafety is required on Windows CE for the control to be loaded correctly
+ public IObjectSafetyImpl<COSpiceX, INTERFACESAFE_FOR_UNTRUSTED_CALLER>,
+#endif
+ public CComCoClass<COSpiceX, &CLSID_OSpiceX>,
+ public CComControl<COSpiceX>,
+ // added by itai 10/07/07 (IObjectSafetyImpl implementation (suppress unsafe AX msg)
+ public IObjectSafetyImpl<COSpiceX, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA>
+{
+public:
+
+
+ COSpiceX()
+ {
+ // added by itai 01/07/07 (indicate the control should be windowed, used for calling html events
+ // from a non base thread using Windows Messages)
+ m_bWindowOnly = true;
+ m_hClientPipe = NULL;
+ m_hEventThread = NULL;
+ m_hClientProcess = NULL;
+ m_hUsbCtrlProcess = NULL;
+ m_hUsbCtrlLog = INVALID_HANDLE_VALUE;
+ m_pi.hProcess = NULL;
+ m_ulNumberOfMonitors = 1;
+ m_UsbListenPort = 32032;
+ m_AdminConsole = TRUE;
+ m_SendCtrlAltDelete = TRUE;
+ m_NoTaskMgrExecution = FALSE;
+ m_UsbAutoShare = FALSE;
+
+ ZeroMemory(&m_OverlappedRead, sizeof(m_OverlappedRead));
+ m_OverlappedRead.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ ZeroMemory(&m_OverlappedWrite, sizeof(m_OverlappedWrite));
+ m_OverlappedWrite.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ InitializeCriticalSection(&m_WriteLock);
+ m_WriteStart = m_WriteEnd = m_WriteBuffer;
+ m_WritePending = false;
+
+ // set object properties to their default values
+ StringCchCopyN(m_HostIP, MAX_PATH, L"255.255.255.255", MAX_PATH);
+ StringCchCopyN(m_GuestHostName, MAX_PATH, L"", MAX_PATH);
+ StringCchCopyN(m_AudioGuestIP, MAX_PATH, L"255.255.255.255", MAX_PATH);
+ StringCchCopyN(m_szCipherSuite, MAX_PATH, L"", MAX_PATH);
+ StringCchCopyN(m_szSSLChannels, MAX_PATH, L"", MAX_PATH);
+ m_bIsSSL = false;
+ m_Port = 0;
+ m_SecurePort = 0;
+ m_AudioPort = 0;
+ StringCchCopyN(m_Title, RED_CLIENT_MAX_TITLE_SIZE, RED_CLIENT_DEFAULT_TITLE,
+ RED_CLIENT_MAX_TITLE_SIZE);
+ StringCchCopyN(m_szPassword, RED_MAX_PASSWORD_LENGTH, L"", RED_MAX_PASSWORD_LENGTH);
+ StringCchCopyN(m_strMenuResource, RED_CLIENT_MAX_MENU_SIZE, L"", RED_CLIENT_MAX_MENU_SIZE);
+ }
+
+DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE |
+ OLEMISC_CANTLINKINSIDE |
+ OLEMISC_INSIDEOUT |
+ OLEMISC_ACTIVATEWHENVISIBLE |
+ OLEMISC_SETCLIENTSITEFIRST
+)
+
+DECLARE_REGISTRY_RESOURCEID(IDR_OSPICEX)
+
+
+BEGIN_COM_MAP(COSpiceX)
+ COM_INTERFACE_ENTRY(IOSpiceX)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(IViewObjectEx)
+ COM_INTERFACE_ENTRY(IViewObject2)
+ COM_INTERFACE_ENTRY(IViewObject)
+ COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
+ COM_INTERFACE_ENTRY(IOleInPlaceObject)
+ COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
+ COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
+ COM_INTERFACE_ENTRY(IOleControl)
+ COM_INTERFACE_ENTRY(IOleObject)
+ COM_INTERFACE_ENTRY(IPersistStreamInit)
+ COM_INTERFACE_ENTRY(IPersistPropertyBag)
+ COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+ COM_INTERFACE_ENTRY(IConnectionPointContainer)
+ COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
+ COM_INTERFACE_ENTRY(IQuickActivate)
+ COM_INTERFACE_ENTRY(IPersistStorage)
+#ifndef _WIN32_WCE
+ COM_INTERFACE_ENTRY(IDataObject)
+#endif
+ COM_INTERFACE_ENTRY(IProvideClassInfo)
+ COM_INTERFACE_ENTRY(IProvideClassInfo2)
+#ifdef _WIN32_WCE // IObjectSafety is required on Windows CE for the control to be loaded correctly
+ COM_INTERFACE_ENTRY_IID(IID_IObjectSafety, IObjectSafety)
+#endif
+ // added by itai 10/07/07 (IObjectSafetyImpl implementation (suppress unsafe AX msg)
+ COM_INTERFACE_ENTRY(IObjectSafety)
+END_COM_MAP()
+
+BEGIN_PROP_MAP(COSpiceX)
+ PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
+ PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
+ // Example entries
+ // PROP_ENTRY("Property Description", dispid, clsid)
+ // PROP_PAGE(CLSID_StockColorPage)
+END_PROP_MAP()
+
+BEGIN_CONNECTION_POINT_MAP(COSpiceX)
+ CONNECTION_POINT_ENTRY(__uuidof(_IOSpiceXEvents))
+END_CONNECTION_POINT_MAP()
+
+BEGIN_MSG_MAP(COSpiceX)
+ CHAIN_MSG_MAP(CComControl<COSpiceX>)
+ DEFAULT_REFLECTION_HANDLER()
+ // added by itai 01/07/07 (using windows messages to fire events)
+ MESSAGE_HANDLER(SPICEX_ON_DISCONNECTED_MSG, OnDisconnectedMsg)
+ MESSAGE_HANDLER(SPICEX_ON_MENU_ITEM_SELECTED_MSG, OnMenuItemSelected)
+END_MSG_MAP()
+// Handler prototypes:
+// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
+
+// ISupportsErrorInfo
+ STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
+ {
+ static const IID* arr[] =
+ {
+ &IID_IOSpiceX,
+ };
+
+ for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
+ {
+ if (InlineIsEqualGUID(*arr[i], riid))
+ return S_OK;
+ }
+ return S_FALSE;
+ }
+
+// IViewObjectEx
+ DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
+
+// IPersistPropertBag
+ STDMETHOD(Load)(IPropertyBag *pPropBag, IErrorLog* pErrorLog);
+
+ // IOSpiceX
+public:
+ HRESULT OnDraw(ATL_DRAWINFO& di)
+ {
+ RECT& rc = *(RECT*)di.prcBounds;
+ // Set Clip region to the rectangle specified by di.prcBounds
+ HRGN hRgnOld = NULL;
+ if (GetClipRgn(di.hdcDraw, hRgnOld) != 1)
+ hRgnOld = NULL;
+ bool bSelectOldRgn = false;
+
+ HRGN hRgnNew = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
+
+ if (hRgnNew != NULL)
+ {
+ bSelectOldRgn = (SelectClipRgn(di.hdcDraw, hRgnNew) != ERROR);
+ }
+
+ Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
+ SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE);
+ LPCTSTR pszText = _T("ATL 8.0 : OSpiceX");
+#ifndef _WIN32_WCE
+ TextOut(di.hdcDraw,
+ (rc.left + rc.right) / 2,
+ (rc.top + rc.bottom) / 2,
+ pszText,
+ lstrlen(pszText));
+#else
+ ExtTextOut(di.hdcDraw,
+ (rc.left + rc.right) / 2,
+ (rc.top + rc.bottom) / 2,
+ ETO_OPAQUE,
+ NULL,
+ pszText,
+ ATL::lstrlen(pszText),
+ NULL);
+#endif
+
+ if (bSelectOldRgn)
+ SelectClipRgn(di.hdcDraw, hRgnOld);
+
+ return S_OK;
+ }
+
+ LRESULT OnMenuItemSelected(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ Fire_OnMenuItemSelected((ULONG)wParam);
+ return ERROR_SUCCESS;
+ }
+
+ LRESULT OnDisconnectedMsg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ Fire_OnDisconnected((LONG)wParam);
+ return ERROR_SUCCESS;
+ }
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ HRESULT FinalConstruct()
+ {
+ return S_OK;
+ }
+
+ void FinalRelease()
+ {
+ }
+ STDMETHOD(Connect)(void);
+ STDMETHOD(Disconnect)(void);
+ STDMETHOD(SendCAD)(void);
+ STDMETHOD(Show)(void);
+ STDMETHOD(Hide)(void);
+ STDMETHOD(SetSecondaryAddress)(void);
+ STDMETHOD(get_HostIP)(BSTR* pVal);
+ STDMETHOD(put_HostIP)(BSTR newVal);
+ STDMETHOD(get_Port)(USHORT* pVal);
+ STDMETHOD(put_Port)(USHORT newVal);
+ STDMETHOD(get_SecurePort)(USHORT* pVal);
+ STDMETHOD(put_SecurePort)(USHORT newVal);
+ STDMETHOD(get_ScaleEnable)(ULONG* pVal);
+ STDMETHOD(put_ScaleEnable)(ULONG newVal);
+ STDMETHOD(get_ScaleNum)(ULONG* pVal);
+ STDMETHOD(put_ScaleNum)(ULONG newVal);
+ STDMETHOD(get_ScaleDen)(ULONG* pVal);
+ STDMETHOD(put_ScaleDen)(ULONG newVal);
+ STDMETHOD(get_FullScreen)(ULONG* pVal);
+ STDMETHOD(put_FullScreen)(ULONG newVal);
+ STDMETHOD(get_MsUser)(BSTR* pVal);
+ STDMETHOD(put_MsUser)(BSTR newVal);
+ STDMETHOD(get_MSDomain)(BSTR* pVal);
+ STDMETHOD(put_MSDomain)(BSTR newVal);
+ STDMETHOD(get_MSPassword)(BSTR* pVal);
+ STDMETHOD(put_MSPassword)(BSTR newVal);
+ STDMETHOD(get_StretchMode)(ULONG* pVal);
+ STDMETHOD(put_StretchMode)(ULONG newVal);
+ STDMETHOD(get_ScreenHeight)(ULONG* pVal);
+ STDMETHOD(put_ScreenHeight)(ULONG newVal);
+ STDMETHOD(get_ConnectingText)(BSTR* pVal);
+ STDMETHOD(put_ConnectingText)(BSTR newVal);
+ STDMETHOD(get_DisconnectingText)(BSTR* pVal);
+ STDMETHOD(put_DisconnectingText)(BSTR newVal);
+ STDMETHOD(get_SwapMouseButtons)(ULONG* pVal);
+ STDMETHOD(put_SwapMouseButtons)(ULONG newVal);
+ STDMETHOD(get_AudioRedirection)(ULONG* pVal);
+ STDMETHOD(put_AudioRedirection)(ULONG newVal);
+ STDMETHOD(get_SecondaryHostIP)(BSTR* pVal);
+ STDMETHOD(put_SecondaryHostIP)(BSTR newVal);
+ STDMETHOD(get_SecondaryPort)(USHORT* pVal);
+ STDMETHOD(put_SecondaryPort)(USHORT newVal);
+ STDMETHOD(get_PollingInterval)(ULONG* pVal);
+ STDMETHOD(put_PollingInterval)(ULONG newVal);
+ STDMETHOD(get_Title)(BSTR* pVal);
+ STDMETHOD(put_Title)(BSTR newVal);
+ // Audio interface
+ STDMETHOD(ConnectAudio)(void);
+ STDMETHOD(DisconnectAudio)(void);
+ STDMETHOD(get_AudioGuestIP)(BSTR* pVal);
+ STDMETHOD(put_AudioGuestIP)(BSTR newVal);
+ STDMETHOD(get_AudioGuestPort)(SHORT* pVal);
+ STDMETHOD(put_AudioGuestPort)(SHORT newVal);
+ STDMETHOD(get_Password)(BSTR* pVal);
+ STDMETHOD(put_Password)(BSTR newVal);
+ STDMETHOD(get_CipherSuite)(BSTR* pVal);
+ STDMETHOD(put_CipherSuite)(BSTR newVal);
+ STDMETHOD(get_SSLChannels)(BSTR* pVal);
+ STDMETHOD(put_SSLChannels)(BSTR newVal);
+ STDMETHOD(get_multimediaPorts)(BSTR* pVal);
+ STDMETHOD(put_multimediaPorts)(BSTR newVal);
+ STDMETHOD(get_DynamicMenu)(BSTR* pVal);
+ STDMETHOD(put_DynamicMenu)(BSTR newVal);
+ STDMETHOD(get_NumberOfMonitors)(ULONG* pVal);
+ STDMETHOD(put_NumberOfMonitors)(ULONG newVal);
+ STDMETHOD(CreateMenu)(BSTR MenuResourceString);
+ STDMETHOD(DeleteMenu)(void);
+ STDMETHOD(get_UsbListenPort)(USHORT* pVal);
+ STDMETHOD(put_UsbListenPort)(USHORT newVal);
+ STDMETHOD(get_AdminConsole)(BOOL* pVal);
+ STDMETHOD(put_AdminConsole)(BOOL newVal);
+ STDMETHOD(get_SendCtrlAltDelete)(BOOL* pVal);
+ STDMETHOD(put_SendCtrlAltDelete)(BOOL newVal);
+ STDMETHOD(get_NoTaskMgrExecution)(BOOL* pVal);
+ STDMETHOD(put_NoTaskMgrExecution)(BOOL newVal);
+ STDMETHOD(get_GuestHostName)(BSTR* pVal);
+ STDMETHOD(put_GuestHostName)(BSTR newVal);
+ STDMETHOD(get_HotKey)(BSTR* pVal);
+ STDMETHOD(put_HotKey)(BSTR newVal);
+ STDMETHOD(SetUsbFilter)(BSTR newVal);
+ STDMETHOD(get_Version)(BSTR* pVal);
+ STDMETHOD(get_UsbAutoShare)(BOOL* pVal);
+ STDMETHOD(put_UsbAutoShare)(BOOL newVal);
+ STDMETHOD(SetLanguageStrings)(BSTR bzSection, BSTR bzLangStr);
+ STDMETHOD(get_TrustStore)(BSTR* pVal);
+ STDMETHOD(put_TrustStore)(BSTR newVal);
+ STDMETHOD(get_HostSubject)(BSTR* pVal);
+ STDMETHOD(put_HostSubject)(BSTR newVal);
+ STDMETHOD(get_ColorDepth)(USHORT* pVal);
+ STDMETHOD(put_ColorDepth)(USHORT newVal);
+ STDMETHOD(get_DisableEffects)(BSTR* pVal);
+ STDMETHOD(put_DisableEffects)(BSTR newVal);
+ STDMETHOD(get_SmartCard)(BOOL* pVal);
+ STDMETHOD(put_SmartCard)(BOOL newVal);
+ STDMETHOD(get_Proxy)(BSTR* pVal);
+ STDMETHOD(put_Proxy)(BSTR newVal);
+
+private:
+ UINT m_CurrentExecuterState;
+ HANDLE m_hClientPipe;
+ HANDLE m_hEventThread;
+ HANDLE m_hClientProcess;
+ HANDLE m_hUsbCtrlProcess;
+ HANDLE m_hUsbCtrlLog;
+ PROCESS_INFORMATION m_pi;
+
+ OVERLAPPED m_OverlappedRead;
+ OVERLAPPED m_OverlappedWrite;
+ CRITICAL_SECTION m_WriteLock;
+ int8_t m_WriteBuffer[PIPE_BUF_SIZE];
+ int8_t* m_WriteStart;
+ int8_t* m_WriteEnd;
+ bool m_WritePending;
+
+ bool m_bIsSSL;
+ wchar_t m_szPassword[RED_MAX_PASSWORD_LENGTH];
+ wchar_t m_szCipherSuite[MAX_PATH];
+ wchar_t m_szSSLChannels[MAX_PATH];
+ wchar_t m_HostIP[MAX_PATH];
+ wchar_t m_GuestHostName[MAX_PATH];
+ wchar_t m_AudioGuestIP[MAX_PATH];
+ wchar_t m_AudioGuestPorts[MAX_PATH];
+ wchar_t m_Title[RED_CLIENT_MAX_TITLE_SIZE];
+ wchar_t m_strMenuResource[RED_CLIENT_MAX_MENU_SIZE];
+ std::wstring m_UsbFilter;
+ std::map<std::wstring, std::wstring> m_Language;
+ std::wstring m_HotKey;
+ std::wstring m_TrustStore;
+ std::wstring m_HostSubject;
+ USHORT m_Port;
+ USHORT m_SecurePort;
+ USHORT m_AudioPort;
+ ULONG m_ulNumberOfMonitors;
+ ULONG m_ScaleEnable;
+ ULONG m_ScaleNum;
+ ULONG m_ScaleDen;
+ ULONG m_FullScreen;
+ BSTR m_MsUser;
+ BSTR m_MSDomain;
+ BSTR m_MSPassword;
+ ULONG m_StretchMode;
+ ULONG m_ScreenHeight;
+ BSTR m_ConnectingText;
+ BSTR m_DisconnectingText;
+ ULONG m_SwapMouseButtons;
+ ULONG m_AudioRedirection;
+ BSTR m_SecondaryHostIP;
+ USHORT m_SecondaryPort;
+ ULONG m_PollingInterval;
+ USHORT m_UsbListenPort;
+ BOOL m_AdminConsole;
+ BOOL m_SendCtrlAltDelete;
+ BOOL m_NoTaskMgrExecution;
+ BOOL m_UsbAutoShare;
+ USHORT m_ColorDepth;
+ std::wstring m_DisableEffects;
+ BOOL m_SmartCard;
+ std::wstring m_Proxy;
+
+private:
+ static DWORD WINAPI event_thread(PVOID param);
+ bool handle_in_msg(ControllerValue& msg);
+ bool handle_out_msg();
+ HRESULT write_to_pipe(const void* data, uint32_t size);
+ HRESULT send_init();
+ HRESULT send_msg(uint32_t id);
+ HRESULT send_value(uint32_t id, uint32_t value);
+ HRESULT send_bool(uint32_t id, uint32_t value);
+ HRESULT send_wstr(uint32_t id, const wchar_t* str, bool use_mb_str = false);
+ void cleanup();
+
+ static DWORD WINAPI UsbCtrlWatchDog(PVOID param);
+ HRESULT ExecuteUsbCtrl();
+ HRESULT CreateCAFile(OUT LPWSTR szCAFileName, DWORD nSize);
+};
+
+OBJECT_ENTRY_AUTO(__uuidof(OSpiceX), COSpiceX)