You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
653 lines
16 KiB
653 lines
16 KiB
/*++
|
|
* File name:
|
|
* tclientaxobj.h
|
|
* Contents:
|
|
* This module contains the header for the CTClientApi class.
|
|
*
|
|
* Copyright (C) 2002 Microsoft Corp.
|
|
--*/
|
|
|
|
#include "resource.h"
|
|
#include <atlctl.h>
|
|
|
|
#include "gdata.h"
|
|
|
|
//
|
|
// VOID
|
|
// SaveError (
|
|
// IN PCSTR Error,
|
|
// IN DWORD TlsIndex,
|
|
// OUT HRESULT *Result
|
|
// );
|
|
//
|
|
|
|
#define SaveError(Error, TlsIndex, Result) \
|
|
{ \
|
|
\
|
|
/* \
|
|
* Set the result code. The presence of an error string indicates \
|
|
* failure. \
|
|
*/ \
|
|
\
|
|
*(Result) = (Error) == NULL ? S_OK : E_FAIL; \
|
|
\
|
|
/* \
|
|
* Update the current thread's error string. If a TLS index could not \
|
|
* be allocated for the current instance, error strings cannot be used. \
|
|
*/ \
|
|
\
|
|
if ((TlsIndex) != TLS_OUT_OF_INDEXES) \
|
|
{ \
|
|
\
|
|
/* \
|
|
/ If a TLS index was allocated, setting the value should not fail. \
|
|
*/ \
|
|
\
|
|
if (!RTL_VERIFY(TlsSetValue((TlsIndex), (PVOID)(Error)))) \
|
|
{ \
|
|
*(Result) = HRESULT_FROM_WIN32(GetLastError()); \
|
|
} \
|
|
} \
|
|
} \
|
|
|
|
//
|
|
// CTClientApi class.
|
|
//
|
|
|
|
class CTClientApi :
|
|
public CComObjectRoot,
|
|
public CComCoClass<CTClientApi, &CLSID_CTClient>,
|
|
public CComControl<CTClientApi>,
|
|
public IDispatchImpl<ITClientApi, &IID_ITClientApi, &LIBID_TCLIENTAXLib>,
|
|
public IPersistStreamInitImpl<CTClientApi>,
|
|
public IPersistStorageImpl<CTClientApi>,
|
|
public IOleControlImpl<CTClientApi>,
|
|
public IOleObjectImpl<CTClientApi>,
|
|
public IOleInPlaceActiveObjectImpl<CTClientApi>,
|
|
public IOleInPlaceObjectWindowlessImpl<CTClientApi>,
|
|
public IViewObjectExImpl<CTClientApi> //,
|
|
// public IObjectSafetyImpl<CTClientApi, INTERFACESAFE_FOR_UNTRUSTED_CALLER>
|
|
{
|
|
public:
|
|
CTClientApi(
|
|
) :
|
|
m_pCI(NULL)
|
|
{
|
|
|
|
//
|
|
// Allocate the index for per-thread errors. If the allocation
|
|
// fails, error strings will not be available.
|
|
//
|
|
|
|
m_dwErrorIndex = TlsAlloc();
|
|
|
|
//
|
|
// Initialize the allocation lists.
|
|
//
|
|
|
|
#if 0
|
|
|
|
InitializeListHead(&m_HeapAllocations);
|
|
InitializeListHead(&m_SysStringAllocations);
|
|
InitializeListHead(&m_TClientAllocations);
|
|
|
|
#endif
|
|
|
|
//
|
|
// Initialize the global printing routine. It would be preferable to
|
|
// set it only if it is currently empty, but Windows 95 compatibility
|
|
// is required, and therefore InterlockedCompareExchange would have
|
|
// to be dynamically loaded with LoadLibrary.
|
|
//
|
|
|
|
InterlockedExchangePointer((PVOID *)&g_pfnPrintMessage,
|
|
CTClientApi::PrintMessage);
|
|
}
|
|
~CTClientApi(
|
|
)
|
|
{
|
|
|
|
#if 0
|
|
|
|
PLIST_ENTRY pNextEntry;
|
|
PALLOCATION pAllocation;
|
|
|
|
#endif
|
|
|
|
//
|
|
// If a connection exists, disconnect it.
|
|
//
|
|
|
|
if (m_pCI != NULL)
|
|
{
|
|
RTL_VERIFY(SCDisconnect(m_pCI) == NULL);
|
|
m_pCI = NULL;
|
|
}
|
|
|
|
//
|
|
// TODO: The lists aren't used at present, but if they are going to
|
|
// be used, an access count and rundown flag should be used to
|
|
// protect the following code.
|
|
//
|
|
|
|
#if 0
|
|
|
|
//
|
|
// Free any heap allocations.
|
|
//
|
|
|
|
while (!IsListEmpty(&m_HeapAllocations))
|
|
{
|
|
|
|
//
|
|
// Remove the entry from the list, free the allocated memory,
|
|
// then free the allocation structure.
|
|
//
|
|
|
|
pNextEntry = RemoveHeadList(&m_HeapAllocations);
|
|
ASSERT(pNextEntry != NULL);
|
|
pAllocation = CONTAINING_RECORD(pNextEntry,
|
|
ALLOCATION,
|
|
AllocationListEntry);
|
|
ASSERT(pAllocation != NULL && pAllocation->Address != NULL);
|
|
RTL_VERIFY(HeapFree(GetProcessHeap(), 0, pAllocation->Address));
|
|
RTL_VERIFY(HeapFree(GetProcessHeap(), 0, pAllocation));
|
|
}
|
|
|
|
//
|
|
// Free any COM strings that will not be freed by the caller.
|
|
//
|
|
|
|
while (!IsListEmpty(&m_SysStringAllocations))
|
|
{
|
|
|
|
//
|
|
// Remove the entry from the list, free the allocated memory,
|
|
// then free the allocation structure.
|
|
//
|
|
|
|
pNextEntry = RemoveHeadList(&m_SysStringAllocations);
|
|
ASSERT(pNextEntry != NULL);
|
|
pAllocation = CONTAINING_RECORD(pNextEntry,
|
|
ALLOCATION,
|
|
AllocationListEntry);
|
|
ASSERT(pAllocation != NULL && pAllocation->Address != NULL);
|
|
SysFreeString((BSTR)pAllocation->Address);
|
|
RTL_VERIFY(HeapFree(GetProcessHeap(), 0, pAllocation));
|
|
}
|
|
|
|
//
|
|
// Free any TClient-allocated memory.
|
|
//
|
|
|
|
while (!IsListEmpty(&m_TClientAllocations))
|
|
{
|
|
|
|
//
|
|
// Remove the entry from the list, free the allocated memory,
|
|
// then free the allocation structure.
|
|
//
|
|
|
|
pNextEntry = RemoveHeadList(&m_TClientAllocations);
|
|
ASSERT(pNextEntry != NULL);
|
|
pAllocation = CONTAINING_RECORD(pNextEntry,
|
|
ALLOCATION,
|
|
AllocationListEntry);
|
|
ASSERT(pAllocation != NULL && pAllocation->Address != NULL);
|
|
SCFreeMem(pAllocation->Address);
|
|
RTL_VERIFY(HeapFree(GetProcessHeap(), 0, pAllocation));
|
|
}
|
|
|
|
#endif
|
|
|
|
//
|
|
// If an error index was allocated, free it.
|
|
//
|
|
|
|
if (m_dwErrorIndex != TLS_OUT_OF_INDEXES)
|
|
{
|
|
RTL_VERIFY(TlsFree(m_dwErrorIndex));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Define message map which may be enabled later, if GUI support is added
|
|
// (e.g. for logging).
|
|
//
|
|
|
|
#if 0
|
|
|
|
BEGIN_MSG_MAP(CTClientApi)
|
|
MESSAGE_HANDLER(WM_PAINT, OnPaint)
|
|
MESSAGE_HANDLER(WM_CREATE, OnCreate)
|
|
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
|
|
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
|
|
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
|
|
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
|
|
MESSAGE_HANDLER(WM_TIMER, OnTimer)
|
|
MESSAGE_HANDLER(WM_SIZE, OnSize)
|
|
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
|
|
END_MSG_MAP()
|
|
|
|
#endif // 0
|
|
|
|
//
|
|
// Define COM map.
|
|
//
|
|
|
|
BEGIN_COM_MAP(CTClientApi)
|
|
COM_INTERFACE_ENTRY(IDispatch)
|
|
COM_INTERFACE_ENTRY(ITClientApi)
|
|
// COM_INTERFACE_ENTRY(IObjectSafety)
|
|
COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx)
|
|
COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)
|
|
COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)
|
|
COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)
|
|
COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless)
|
|
COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless)
|
|
COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)
|
|
COM_INTERFACE_ENTRY_IMPL(IOleControl)
|
|
COM_INTERFACE_ENTRY_IMPL(IOleObject)
|
|
COM_INTERFACE_ENTRY_IMPL(IPersistStorage)
|
|
COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit)
|
|
END_COM_MAP()
|
|
|
|
//
|
|
// Define connection-point map.
|
|
//
|
|
|
|
BEGIN_CONNECTION_POINT_MAP(CTClientApi)
|
|
END_CONNECTION_POINT_MAP()
|
|
|
|
//
|
|
// Define property map.
|
|
//
|
|
|
|
BEGIN_PROP_MAP(CTClientApi)
|
|
END_PROPERTY_MAP()
|
|
|
|
//
|
|
// COM declarations.
|
|
//
|
|
|
|
//DECLARE_NOT_AGGREGATABLE(CTClientApi)
|
|
DECLARE_GET_CONTROLLING_UNKNOWN()
|
|
//DECLARE_CONTROL_INFO(CLSID_CTClient)
|
|
DECLARE_REGISTRY_RESOURCEID(IDR_TClient)
|
|
|
|
protected:
|
|
|
|
//
|
|
// Define connection information and error index.
|
|
//
|
|
|
|
PCONNECTINFO m_pCI;
|
|
DWORD m_dwErrorIndex;
|
|
|
|
//
|
|
// The following lists are used to track allocations from the process and
|
|
// CRT heaps. The SysXxxString routines use the CRT heap, which is also
|
|
// used for the TClient allocations. General allocations use the process
|
|
// heap.
|
|
//
|
|
// Note: These lists are not currently used.
|
|
//
|
|
|
|
#if 0
|
|
|
|
LIST_ENTRY m_HeapAllocations;
|
|
LIST_ENTRY m_SysStringAllocations;
|
|
LIST_ENTRY m_TClientAllocations;
|
|
|
|
#endif
|
|
|
|
//
|
|
// ITClientApi interface.
|
|
//
|
|
|
|
public:
|
|
|
|
//
|
|
// Declare message handlers which may be enabled later.
|
|
//
|
|
|
|
#if 0
|
|
|
|
HRESULT
|
|
OnDraw (
|
|
ATL_DRAWINFO& di
|
|
);
|
|
|
|
LRESULT
|
|
OnCreate (
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL& bHandled
|
|
);
|
|
|
|
LRESULT
|
|
OnDestroy (
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL& bHandled
|
|
);
|
|
|
|
LRESULT
|
|
OnLButtonDown (
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL& bHandled
|
|
);
|
|
|
|
LRESULT
|
|
OnLButtonUp (
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL& bHandled
|
|
);
|
|
|
|
LRESULT
|
|
OnMouseMove (
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL& bHandled
|
|
);
|
|
|
|
LRESULT
|
|
OnSize (
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL& bHandled
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(uMsg);
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
UNREFERENCED_PARAMETER(bHandled);
|
|
return 0;
|
|
}
|
|
|
|
LRESULT
|
|
OnEraseBackground (
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL& bHandled
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(uMsg);
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
UNREFERENCED_PARAMETER(bHandled);
|
|
return 0;
|
|
}
|
|
|
|
LRESULT
|
|
OnTimer (
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL& bHandled
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(uMsg);
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
UNREFERENCED_PARAMETER(bHandled);
|
|
return 0;
|
|
}
|
|
|
|
#endif // 0
|
|
|
|
STDMETHODIMP
|
|
get_Error (
|
|
OUT BSTR *Message
|
|
)
|
|
{
|
|
|
|
PSTR szError;
|
|
BSTR bstrError;
|
|
HRESULT hrResult;
|
|
|
|
USES_CONVERSION;
|
|
ATLTRACE(_T("ITClientApi::get_Error\n"));
|
|
|
|
//
|
|
// Get the current thread's error string. If a TLS index could not be
|
|
// allocated, an error string cannot be returned.
|
|
//
|
|
|
|
if (m_dwErrorIndex != TLS_OUT_OF_INDEXES)
|
|
{
|
|
szError = (PSTR)TlsGetValue(m_dwErrorIndex);
|
|
}
|
|
else
|
|
{
|
|
szError = NULL;
|
|
}
|
|
|
|
//
|
|
// If the error string is NULL or empty, use NULL.
|
|
//
|
|
|
|
if (szError == NULL || *szError == '\0')
|
|
{
|
|
bstrError = NULL;
|
|
}
|
|
|
|
//
|
|
// Convert the current error string to a BSTR. This will allocate
|
|
// from the CRT heap, and the storage must be freed by the caller,
|
|
// using SysFreeString.
|
|
//
|
|
|
|
else
|
|
{
|
|
bstrError = A2BSTR(szError);
|
|
if (bstrError == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Copy the address of the error string to the message pointer.
|
|
//
|
|
|
|
hrResult = E_FAIL;
|
|
_try
|
|
{
|
|
_try
|
|
{
|
|
*Message = bstrError;
|
|
hrResult = S_OK;
|
|
}
|
|
|
|
//
|
|
// If the message pointer is invalid, set an appropriate return
|
|
// value.
|
|
//
|
|
|
|
_except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
|
|
{
|
|
hrResult = E_POINTER;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If the message pointer could not be set, the BSTR will not be
|
|
// returned, so free it.
|
|
//
|
|
|
|
_finally
|
|
{
|
|
if (FAILED(hrResult))
|
|
{
|
|
ASSERT(bstrError != NULL);
|
|
SysFreeString(bstrError);
|
|
}
|
|
}
|
|
|
|
return hrResult;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
SaveClipboard (
|
|
IN BSTR FormatName,
|
|
IN BSTR FileName
|
|
);
|
|
|
|
STDMETHODIMP
|
|
IsDead (
|
|
OUT BOOL *Dead
|
|
);
|
|
|
|
STDMETHODIMP
|
|
SendTextAsMessages (
|
|
IN BSTR Text
|
|
);
|
|
|
|
STDMETHODIMP
|
|
Connect2 (
|
|
IN BSTR ServerName,
|
|
IN BSTR UserName,
|
|
IN BSTR Password,
|
|
IN BSTR Domain,
|
|
IN BSTR Shell,
|
|
IN ULONG XResolution,
|
|
IN ULONG YResolution,
|
|
IN ULONG ConnectionFlags,
|
|
IN ULONG ColorDepth,
|
|
IN ULONG AudioOptions
|
|
);
|
|
|
|
STDMETHODIMP
|
|
GetFeedbackString (
|
|
OUT BSTR *FeedbackString
|
|
);
|
|
|
|
STDMETHODIMP
|
|
GetFeedback (
|
|
OUT SAFEARRAY **Feedback
|
|
);
|
|
|
|
STDMETHODIMP
|
|
ClientTerminate (
|
|
VOID
|
|
);
|
|
|
|
STDMETHODIMP
|
|
Check (
|
|
IN BSTR Command,
|
|
IN BSTR Parameter
|
|
);
|
|
|
|
STDMETHODIMP
|
|
Clipboard (
|
|
IN ULONG Command,
|
|
IN BSTR FileName
|
|
);
|
|
|
|
STDMETHODIMP
|
|
Connect (
|
|
IN BSTR ServerName,
|
|
IN BSTR UserName,
|
|
IN BSTR Password,
|
|
IN BSTR Domain,
|
|
IN ULONG XResolution,
|
|
IN ULONG YResolution
|
|
);
|
|
|
|
STDMETHODIMP
|
|
Disconnect (
|
|
VOID
|
|
);
|
|
|
|
STDMETHODIMP
|
|
Logoff (
|
|
VOID
|
|
);
|
|
|
|
STDMETHODIMP
|
|
SendData (
|
|
IN UINT Message,
|
|
IN UINT_PTR WParameter,
|
|
IN LONG_PTR LParameter
|
|
);
|
|
|
|
STDMETHODIMP
|
|
Start (
|
|
IN BSTR AppName
|
|
);
|
|
|
|
STDMETHODIMP
|
|
SwitchToProcess (
|
|
IN BSTR WindowTitle
|
|
);
|
|
|
|
STDMETHODIMP
|
|
SendMouseClick (
|
|
IN ULONG XPosition,
|
|
IN ULONG YPosition
|
|
);
|
|
|
|
STDMETHODIMP
|
|
GetSessionId (
|
|
OUT ULONG *SessionId
|
|
);
|
|
|
|
STDMETHODIMP
|
|
CloseClipboard (
|
|
VOID
|
|
);
|
|
|
|
STDMETHODIMP
|
|
OpenClipboard (
|
|
IN HWND Window
|
|
);
|
|
|
|
STDMETHODIMP
|
|
SetClientTopmost (
|
|
IN BOOL Enable
|
|
);
|
|
|
|
STDMETHODIMP
|
|
Attach (
|
|
IN HWND Window,
|
|
IN LONG_PTR Cookie
|
|
);
|
|
|
|
STDMETHODIMP
|
|
Detach (
|
|
VOID
|
|
);
|
|
|
|
STDMETHODIMP
|
|
GetIni (
|
|
OUT ITClientIni **Ini
|
|
);
|
|
|
|
STDMETHODIMP
|
|
GetClientWindowHandle (
|
|
OUT HWND *Window
|
|
);
|
|
|
|
//
|
|
// Utility routines.
|
|
//
|
|
|
|
static
|
|
VOID
|
|
CTClientApi::PrintMessage (
|
|
MESSAGETYPE MessageType,
|
|
LPCSTR Format,
|
|
...
|
|
);
|
|
};
|