From efcb331e18802819661fbb9d400c8c90e7af0597 Mon Sep 17 00:00:00 2001 From: Michele Cicciotti Date: Sat, 19 Aug 2006 18:40:53 +0000 Subject: [PATCH] modified porting-tools/rdesktop-core-tester/activex.cpp Getting closer and closer and closer yet... modified porting-tools/rdesktop-core-tester/mstsclib_h.h modified porting-tools/rdesktop-core-tester/mstsclib_i.c modified porting-tools/rdesktop-core-tester/mstsclib_redist_h.h modified porting-tools/rdesktop-core-tester/mstsclib_redist_i.c Regenerated, no code changes modified porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp modified rdesktop/cache.c modified rdesktop/iso.c modified rdesktop/licence.c modified rdesktop/mcs.c modified rdesktop/orders.c modified rdesktop/parse.h modified rdesktop/proto.h modified rdesktop/pstcache.c modified rdesktop/rdesktop.h modified rdesktop/rdp.c modified rdesktop/rdp5.c modified rdesktop/secure.c modified rdesktop/tcp.c Trimmed down rdesktop-core library to the maximum extent possible Handle errors gracefully Use actual Unicode strings Fixed most warnings Added hooks for events happening inside the protocol's main loop modified porting-tools/rdesktop-core-tester/stdafx.cpp Clean-up svn path=/trunk/; revision=23612 --- .../rdesktop-core-tester/activex.cpp | 1013 +++++++++++++---- .../rdesktop-core-tester/mstsclib_h.h | 4 +- .../rdesktop-core-tester/mstsclib_i.c | 4 +- .../rdesktop-core-tester/mstsclib_redist_h.h | 4 +- .../rdesktop-core-tester/mstsclib_redist_i.c | 4 +- .../rdesktop-core-tester.cpp | 202 +--- .../rdesktop-core-tester/stdafx.cpp | 7 +- .../applications/tsclient/rdesktop/cache.c | 8 +- .../base/applications/tsclient/rdesktop/iso.c | 53 +- .../applications/tsclient/rdesktop/licence.c | 39 +- .../base/applications/tsclient/rdesktop/mcs.c | 88 +- .../applications/tsclient/rdesktop/orders.c | 54 +- .../applications/tsclient/rdesktop/parse.h | 4 +- .../applications/tsclient/rdesktop/proto.h | 58 +- .../applications/tsclient/rdesktop/pstcache.c | 8 +- .../applications/tsclient/rdesktop/rdesktop.h | 309 +---- .../base/applications/tsclient/rdesktop/rdp.c | 230 ++-- .../applications/tsclient/rdesktop/rdp5.c | 15 +- .../applications/tsclient/rdesktop/secure.c | 66 +- .../base/applications/tsclient/rdesktop/tcp.c | 83 +- 20 files changed, 1358 insertions(+), 895 deletions(-) diff --git a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/activex.cpp b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/activex.cpp index b1aab6a0ffa..7b9dab73574 100644 --- a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/activex.cpp +++ b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/activex.cpp @@ -78,10 +78,7 @@ class RdpClient sealed: // FIXME: wrap "sealed" in a macro /* RDP client interface */ public MSTSCLib::IMsRdpClient4, - public MSTSCLib::IMsRdpClientNonScriptable2, - - /* RDP client context */ - public RDPCLIENT + public MSTSCLib::IMsRdpClientNonScriptable2 { private: /* An endless amount of COM glue */ @@ -137,6 +134,10 @@ private: // OLE control glue HWND m_controlWindow; IOleClientSite * m_clientSite; + IOleInPlaceSite * m_inPlaceSite; + IOleAdviseHolder * m_adviseHolder; + LONG m_freezeEvents; + bool m_uiActive; // UrlMon security DWORD m_SafetyOptions; @@ -146,6 +147,10 @@ private: return m_SafetyOptions & INTERFACESAFE_FOR_UNTRUSTED_CALLER; } + /* Glue to interface to rdesktop-core */ + RDPCLIENT m_protocolState; + HANDLE m_protocolThread; + /* Properties */ // Storage fields // NOTE: keep sorted by alignment (pointers and handles, integers, enumerations, booleans) @@ -217,7 +222,6 @@ private: bool m_ShadowBitmap; bool m_EncryptionEnabled; bool m_DedicatedTerminal; - bool m_EnableMouse; bool m_DisableCtrlAltDel; bool m_EnableWindowsKey; bool m_DoubleClickDetect; @@ -316,16 +320,22 @@ private: } /* Events */ - MSTSCLib::IMsTscAxEvents * const * GetSinks() const + MSTSCLib::IMsTscAxEvents ** GetSinks() const { if(m_EventSinksCount > 1) return m_EventSinks; else - return m_EventSinksStatic; + return const_cast(m_EventSinksStatic); + } + + // Event freezing + void UnfreezeEvents() + { + // Just in case } // Generic event riser & helpers - void FireEvent(DISPID eventId, VARIANTARG rgvarg[], unsigned int cArgs, VARIANTARG * retval) + void InvokeSinks(DISPID eventId, VARIANTARG rgvarg[], unsigned int cArgs, VARIANTARG * retval) { DISPPARAMS params; @@ -334,45 +344,154 @@ private: params.cArgs = cArgs; params.cNamedArgs = 0; - MSTSCLib::IMsTscAxEvents * const * sinks = GetSinks(); + MSTSCLib::IMsTscAxEvents ** sinks = GetSinks(); for(size_t i = 0; i < m_EventSinksCount; ++ i) - { sinks[i]->Invoke(eventId, IID_NULL, 0, DISPATCH_METHOD, ¶ms, retval, NULL, NULL); + } - // BUGBUG: should we keep looping if the event has a return value? + typedef void (RdpClient::* AsyncEventCallback) + ( + DISPID eventId, + VARIANTARG * rgvarg, + unsigned int cArgs, + VARIANTARG * retVal + ); + + void CleanupEventArgumentsCallback + ( + DISPID eventId, + VARIANTARG * rgvarg, + unsigned int cArgs, + VARIANTARG * retVal + ) + { + assert((rgvarg == NULL) == (cArgs == 0)); + + for(unsigned int i = 0; i < cArgs; ++ i) + VariantClear(&rgvarg[i]); + + if(retVal) + VariantClear(retVal); + } + + // synchronous call from inside the apartment that owns the object + void FireEventInsideApartment + ( + DISPID eventId, + VARIANTARG * rgvarg = NULL, + unsigned int cArgs = 0, + VARIANTARG * retval = NULL, + AsyncEventCallback callback = NULL + ) + { + if(retval == NULL && callback) + { + VARIANTARG localRetval = { }; + retval = &localRetval; } + + InvokeSinks(eventId, rgvarg, cArgs, retval); + + if(callback) + (this->*callback)(eventId, rgvarg, cArgs, retval); } - void FireEvent(DISPID eventId, VARIANTARG * retval = NULL) + struct EventArguments { - return FireEvent(eventId, NULL, 0, retval); + DISPID eventId; + VARIANTARG * rgvarg; + unsigned int cArgs; + VARIANTARG * retval; + AsyncEventCallback callback; + }; + + static const UINT RDPC_WM_SYNC_EVENT = WM_USER + 1; + static const UINT RDPC_WM_ASYNC_EVENT = WM_USER + 2; + + bool HandleEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& result) + { + switch(uMsg) + { + case RDPC_WM_SYNC_EVENT: + case RDPC_WM_ASYNC_EVENT: + break; + + default: + return false; + } + + const EventArguments * eventArgs = reinterpret_cast(lParam); + assert(eventArgs); + + FireEventInsideApartment(eventArgs->eventId, eventArgs->rgvarg, eventArgs->cArgs, eventArgs->retval, eventArgs->callback); + + if(uMsg == RDPC_WM_ASYNC_EVENT) + delete eventArgs; + + return true; } - void FireEvent(DISPID eventId, VARIANTARG& arg, VARIANTARG * retval = NULL) + // synchronous call from outside the apartment + void FireEventOutsideApartment + ( + DISPID eventId, + VARIANTARG * rgvarg = NULL, + unsigned int cArgs = 0, + VARIANTARG * retval = NULL, + AsyncEventCallback callback = NULL + ) { - return FireEvent(eventId, &arg, 1, retval); + EventArguments syncEvent = { eventId, rgvarg, cArgs, retval, callback }; + SendMessage(m_controlWindow, RDPC_WM_SYNC_EVENT, 0, reinterpret_cast(&syncEvent)); } - template void FireEvent(DISPID eventId, VARIANTARG (& args)[N], VARIANTARG * retval = NULL) + // asynchronous call from outside the apartment + HRESULT FireEventOutsideApartmentAsync + ( + DISPID eventId, + VARIANTARG * rgvarg = NULL, + unsigned int cArgs = 0, + VARIANTARG * retval = NULL, + AsyncEventCallback callback = NULL + ) { - return FireEvent(eventId, args, (N), retval); + EventArguments * asyncEvent = new EventArguments(); + + if(asyncEvent == NULL) + return E_OUTOFMEMORY; + + asyncEvent->eventId = eventId; + asyncEvent->rgvarg = rgvarg; + asyncEvent->cArgs = cArgs; + asyncEvent->retval = NULL; + + if(!PostMessage(m_controlWindow, RDPC_WM_ASYNC_EVENT, 0, reinterpret_cast(asyncEvent))) + { + delete asyncEvent; + return HRESULT_FROM_WIN32(GetLastError()); + } + + return S_OK; } // Specific events void FireConnecting() { - FireEvent(1); + // Source: protocol + FireEventOutsideApartment(1); } void FireConnected() { - FireEvent(2); + // Source: protocol + FireEventOutsideApartment(2); } void FireLoginComplete() { - FireEvent(3); + // Source: protocol + FireEventOutsideApartment(3); } void FireDisconnected(long reason) @@ -382,40 +501,71 @@ private: arg.vt = VT_I4; arg.lVal = reason; - FireEvent(4, arg); + // Source: protocol + FireEventOutsideApartment(4, &arg, 1); } void FireEnterFullScreenMode() { - FireEvent(5); + // Source: UI window + FireEventInsideApartment(5); } void FireLeaveFullScreenMode() { - FireEvent(6); + // Source: UI window + FireEventInsideApartment(6); } - void FireChannelReceivedData(BSTR chanName, BSTR chanData) + HRESULT FireChannelReceivedData(char (& chanName)[CHANNEL_NAME_LEN + 1], void * chanData, unsigned int chanDataSize) { + // BUGBUG: what to do when we run outside of memory? + + OLECHAR wchanName[ARRAYSIZE(chanName)]; + std::copy(chanName + 0, chanName + ARRAYSIZE(chanName), wchanName); + + BSTR bstrChanName = SysAllocString(wchanName); + + if(bstrChanName == NULL) + return E_OUTOFMEMORY; + + BSTR bstrChanData = SysAllocStringByteLen(NULL, chanDataSize); + + if(bstrChanData == NULL) + { + SysFreeString(bstrChanName); + return E_OUTOFMEMORY; + } + + CopyMemory(bstrChanData, chanData, chanDataSize); + VARIANTARG args[2] = { }; args[1].vt = VT_BSTR; - args[1].bstrVal = chanName; + args[1].bstrVal = bstrChanName; args[0].vt = VT_BSTR; - args[0].bstrVal = chanData; + args[0].bstrVal = bstrChanData; - FireEvent(7, args); + // Source: protocol + HRESULT hr = FireEventOutsideApartmentAsync(7, args, ARRAYSIZE(args), NULL, &RdpClient::CleanupEventArgumentsCallback); + + if(FAILED(hr)) + CleanupEventArgumentsCallback(7, args, ARRAYSIZE(args), NULL); + + return hr; } void FireRequestGoFullScreen() { - FireEvent(8); + // Source: UI window + FireEventInsideApartment(8); } void FireRequestLeaveFullScreen() { - FireEvent(9); + // Source: UI window + FireEventInsideApartment(9); } void FireFatalError(long errorCode) @@ -425,7 +575,8 @@ private: arg.vt = VT_I4; arg.lVal = errorCode; - FireEvent(10, arg); + // Source: protocol + FireEventOutsideApartment(10, &arg, 1); } void FireWarning(long warningCode) @@ -435,7 +586,8 @@ private: arg.vt = VT_I4; arg.lVal = warningCode; - FireEvent(11); + // Source: protocol + FireEventOutsideApartment(11, &arg, 1); } void FireRemoteDesktopSizeChange(long width, long height) @@ -448,45 +600,64 @@ private: args[0].vt = VT_I4; args[0].lVal = height; - FireEvent(12, args); + // Source: UI window + FireEventInsideApartment(12, args, ARRAYSIZE(args)); } void FireIdleTimeoutNotification() { - FireEvent(13); + // Source: input thread + FireEventOutsideApartment(13); } void FireRequestContainerMinimize() { - FireEvent(14); + // Source: UI window + FireEventInsideApartment(14); } - void FireConfirmClose(VARIANT_BOOL * pfAllowClose) + bool FireConfirmClose() { VARIANTARG retval = { }; + VARIANT_BOOL allowClose = VARIANT_TRUE; retval.vt = VT_BYREF | VT_BOOL; - retval.pboolVal = pfAllowClose; + retval.pboolVal = &allowClose; - FireEvent(15, &retval); + // Source: ??? // BUGBUG: fix this! + FireEventOutsideApartment(15, NULL, 0, &retval); + + return allowClose != VARIANT_FALSE; } - void FireReceivedTSPublicKey(BSTR publicKey, VARIANT_BOOL * pfContinueLogon) + HRESULT FireReceivedTSPublicKey(void * publicKey, unsigned int publicKeyLength) { + BSTR bstrPublicKey = SysAllocStringByteLen(NULL, publicKeyLength); + + if(bstrPublicKey == NULL) + return E_OUTOFMEMORY; + + CopyMemory(bstrPublicKey, publicKey, publicKeyLength); + + VARIANT_BOOL continueLogon = VARIANT_TRUE; VARIANTARG arg = { }; VARIANTARG retval = { }; arg.vt = VT_BSTR; - arg.bstrVal = publicKey; + arg.bstrVal = bstrPublicKey; retval.vt = VT_BYREF | VT_BOOL; - retval.pboolVal = pfContinueLogon; + retval.pboolVal = &continueLogon; - FireEvent(16, arg, &retval); + // Source: protocol + FireEventOutsideApartment(16, &arg, 1, &retval); + + return continueLogon ? S_OK : S_FALSE; } - void FireAutoReconnecting(long disconnectReason, long attemptCount, MSTSCLib::AutoReconnectContinueState * pArcContinueStatus) + LONG FireAutoReconnecting(long disconnectReason, long attemptCount) { + LONG continueStatus = MSTSCLib::autoReconnectContinueAutomatic; VARIANTARG args[2] = { }; VARIANTARG retval = { }; @@ -497,19 +668,24 @@ private: args[0].lVal = attemptCount; retval.vt = VT_BYREF | VT_I4; - retval.plVal = (LONG *)pArcContinueStatus; + retval.plVal = &continueStatus; - FireEvent(17, args, &retval); + // Source: protocol + FireEventOutsideApartment(17, args, ARRAYSIZE(args), &retval); + + return continueStatus; } void FireAuthenticationWarningDisplayed() { - FireEvent(18); + // Source: protocol + FireEventOutsideApartment(18); } void FireAuthenticationWarningDismissed() { - FireEvent(19); + // Source: protocol + FireEventOutsideApartment(19); } /* Actual IUnknown implementation */ @@ -602,9 +778,18 @@ private: m_classId(classId), m_typeLib(), m_dispTypeInfo(), + m_controlWindow(NULL), m_clientSite(), + m_inPlaceSite(), + m_adviseHolder(), + m_freezeEvents(0), + m_uiActive(false), m_SafetyOptions(), + // rdesktop-core interface + m_protocolState(), + m_protocolThread(), + // Properties m_Server(), m_Domain(), @@ -642,7 +827,6 @@ private: m_orderDrawThresold(0), m_BitmapCacheSize(1500), m_BitmapVirtualCacheSize(10), - m_NumBitmapCaches(), m_brushSupportLevel(), m_minInputSendInterval(), m_InputEventsAtOnce(), @@ -670,7 +854,6 @@ private: m_ShadowBitmap(true), m_EncryptionEnabled(true), m_DedicatedTerminal(false), - m_EnableMouse(true), m_DisableCtrlAltDel(true), m_EnableWindowsKey(true), m_DoubleClickDetect(false), @@ -703,23 +886,33 @@ private: { assert(m_refCount == 0); + // TODO: if connected, disconnect + + DestroyControlWindow(); + if(m_typeLib) m_typeLib->Release(); if(m_dispTypeInfo) m_dispTypeInfo->Release(); - MSTSCLib::IMsTscAxEvents * const * sinks = GetSinks(); + MSTSCLib::IMsTscAxEvents ** sinks = GetSinks(); for(size_t i = 0; i < m_EventSinksCount; ++ i) sinks[i]->Release(); if(m_EventSinksCount > 1) - CoTaskMemFree(m_EventSinks); + delete[] m_EventSinks; if(m_clientSite) m_clientSite->Release(); + if(m_inPlaceSite) + m_inPlaceSite->Release(); + + if(m_adviseHolder) + m_adviseHolder->Release(); + SysFreeString(m_Server); SysFreeString(m_Domain); SysFreeString(m_UserName); @@ -1177,16 +1370,23 @@ private: virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapCacheSize(long pbitmapCacheSize) { - return S_FALSE; + // NOTE: the upper bound of "32" for a field with a default value of 1500 seems to be a bug + if(pbitmapCacheSize < 0 || pbitmapCacheSize > 32) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_BitmapCacheSize, pbitmapCacheSize); } virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapCacheSize(long * pbitmapCacheSize) { - return S_FALSE; + return Outer()->GetProperty(Outer()->m_BitmapCacheSize, pbitmapCacheSize); } virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapVirtualCacheSize(long pbitmapVirtualCacheSize) { + if(pbitmapVirtualCacheSize < 0 || pbitmapVirtualCacheSize > 32) + return E_INVALIDARG; + return Outer()->SetProperty(Outer()->m_BitmapVirtualCacheSize, pbitmapVirtualCacheSize); } @@ -1207,12 +1407,12 @@ private: virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_NumBitmapCaches(long pnumBitmapCaches) { - return S_FALSE; + return Outer()->SetProperty(Outer()->m_NumBitmapCaches, pnumBitmapCaches); } virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_NumBitmapCaches(long * pnumBitmapCaches) { - return S_FALSE; + return Outer()->GetProperty(Outer()->m_NumBitmapCaches, pnumBitmapCaches); } virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_CachePersistenceActive(long pcachePersistenceActive) @@ -1242,31 +1442,37 @@ private: virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_minInputSendInterval(long pminInputSendInterval) { + // TODO return S_FALSE; } virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_minInputSendInterval(long * pminInputSendInterval) { + // TODO return S_FALSE; } virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_InputEventsAtOnce(long pinputEventsAtOnce) { + // TODO return S_FALSE; } virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_InputEventsAtOnce(long * pinputEventsAtOnce) { + // TODO return S_FALSE; } virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_maxEventCount(long pmaxEventCount) { + // TODO return S_FALSE; } virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_maxEventCount(long * pmaxEventCount) { + // TODO return S_FALSE; } @@ -1933,6 +2139,130 @@ public: return CONTAINING_RECORD(innerThis, RdpClient, m_securedSettings); } +private: + /* Thread that hosts rdesktop-core */ + static DWORD WINAPI ProtocolLoopThreadProc(LPVOID lpParam) + { + static_cast(lpParam)->ProtocolLoop(); + return 0; + } + + void ProtocolLoop() + { + FireConnecting(); + + uint32 flags = 0; // TODO + + // Initial connection + rdp_connect + ( + &m_protocolState, + NULL, // TODO server + flags, + m_UserName, + m_Domain, + m_ClearTextPassword, + m_StartProgram, + m_WorkDir, + NULL, // TODO hostname + NULL // TODO cookie + ); + + BOOL disconnected = False; + + do + { + BOOL deactivated = False; + uint32 extendedDisconnectReason = 0; + + // The main protocol loop + rdp_main_loop(&m_protocolState, &deactivated, &extendedDisconnectReason); + + // Redirection + if(m_protocolState.redirect) + { + m_protocolState.redirect = False; + rdp_reset_state(&m_protocolState); + + // TODO: reset connection parameters + // This has to be done in the main thread, so use SendMessage on the control window + + flags |= RDP_LOGON_AUTO; + + // retry + continue; + } + + // Disconnection + m_ExtendedDisconnectReason = static_cast(extendedDisconnectReason); + + // Clean disconnection + if(deactivated) + break; + + BOOL success; + + long autoReconnections = 0; + long totalReconnections = 0; + + // Reconnection + do + { + ++ totalReconnections; + + // ask the container whether we should reconnect + long reconnectMode = FireAutoReconnecting(m_protocolState.disconnect_reason, totalReconnections); + + // do not reconnect + if(reconnectMode == MSTSCLib::autoReconnectContinueStop) + { + disconnected = True; + break; + } + + // the container will reconnect manually with Connect or abort with Disconnect + if(reconnectMode == MSTSCLib::autoReconnectContinueManual) + { + // TODO: wait for a call to Connect or Disconnect + } + // reconnect automatically + else + { + // automatic reconnection is disabled + if(m_EnableAutoReconnect) + break; + + // too many consecutive automatic reconnections + if(autoReconnections == m_MaxReconnectAttempts) + break; + + ++ autoReconnections; + } + + // Reconnection + success = rdp_reconnect + ( + &m_protocolState, + NULL, // TODO + flags, + m_UserName, + m_Domain, + m_ClearTextPassword, + m_StartProgram, + m_WorkDir, + NULL, // TODO + NULL // TODO + ); + } + while(!success); + } + while(!disconnected); + + // Disconnected + // TODO: clean up protocol state, clear "connected" flag + FireDisconnected(m_protocolState.disconnect_reason); + } + public: /* Class factory */ static HRESULT CreateInstance(REFCLSID rclsid, IUnknown * punkOuter, REFIID riid, void ** ppObj) @@ -1956,120 +2286,8 @@ public: return S_OK; } - /* IUnknown */ // DONE - /* - NOTE: this is the delegating implementation, to support aggregation. The actual - implementation is RdpClientInner, above - */ - virtual STDMETHODIMP IUnknown::QueryInterface(REFIID riid, void ** ppvObject) - { - return m_punkOuter->QueryInterface(riid, ppvObject); - } - - virtual STDMETHODIMP_(ULONG) IUnknown::AddRef() - { - return m_punkOuter->AddRef(); - } - - virtual STDMETHODIMP_(ULONG) IUnknown::Release() - { - return m_punkOuter->Release(); - } - - /* IDispatch */ // DONE - virtual STDMETHODIMP IDispatch::GetTypeInfoCount(UINT * pctinfo) - { - *pctinfo = 1; - return S_OK; - } - - virtual STDMETHODIMP IDispatch::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) - { - if(iTInfo != 0) - return DISP_E_BADINDEX; - - return AcquireDispTypeInfo(ppTInfo); - } - - virtual STDMETHODIMP IDispatch::GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) - { - HRESULT hr = LoadDispTypeInfo(); - - if(FAILED(hr)) - return hr; - - return m_dispTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId); - } - - virtual STDMETHODIMP IDispatch::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) - { - HRESULT hr = LoadDispTypeInfo(); - - if(FAILED(hr)) - return hr; - - return m_dispTypeInfo->Invoke - ( - static_cast(this), - dispIdMember, - wFlags, - pDispParams, - pVarResult, - pExcepInfo, - puArgErr - ); - } - - /* IConnectionPoint */ // DONE // FIXME! support more than one connection! - virtual STDMETHODIMP GetConnectionInterface(IID * pIID) - { - assert(pIID); - *pIID = MSTSCLib::DIID_IMsTscAxEvents; - return S_OK; - } - - virtual STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer ** ppCPC) - { - assert(ppCPC); - addRef(); - *ppCPC = this; - return S_OK; - } - - virtual STDMETHODIMP Advise(IUnknown * pUnkSink, DWORD * pdwCookie) - { - if(m_EventSinksCount == 0) - { - if(FAILED(pUnkSink->QueryInterface(&m_EventSinksStatic[0]))) - return CONNECT_E_CANNOTCONNECT; - - ++ m_EventSinksCount; - - *pdwCookie = 1; - return S_OK; - } - - return CONNECT_E_ADVISELIMIT; - } - - virtual STDMETHODIMP Unadvise(DWORD dwCookie) - { - if(dwCookie != 1 || m_EventSinksCount == 0) - return CONNECT_E_NOCONNECTION; - - m_EventSinksStatic[0]->Release(); - m_EventSinksStatic[0] = NULL; - m_EventSinksCount = 0; - return S_OK; - } - - virtual STDMETHODIMP EnumConnections(IEnumConnections ** ppEnum) - { - // I see no real value in this - return E_NOTIMPL; - } - - /* IConnectionPointContainer */ // DONE +private: + /* Connection point enumerator */ class CEnumConnectionPoints: public IEnumConnectionPoints { private: @@ -2162,6 +2380,9 @@ public: virtual STDMETHODIMP Clone(IEnumConnectionPoints ** ppEnum) { + if(ppEnum == NULL) + return E_POINTER; + *ppEnum = new CEnumConnectionPoints(*this); if(*ppEnum == NULL) @@ -2171,6 +2392,284 @@ public: } }; + /* Pay no attention, ActiveX glue... */ + HRESULT CreateControlWindow() + { + // TODO + m_UIParentWindowHandle = m_controlWindow; + return E_FAIL; + } + + HRESULT DestroyControlWindow() + { + if(m_controlWindow == NULL) + return S_FALSE; + + HWND controlWindow = NULL; + std::swap(controlWindow, m_controlWindow); + DestroyWindow(controlWindow); + return S_OK; + } + + HRESULT Activate(LONG iVerb, IOleClientSite * pActiveSite, HWND hwndParent, LPCRECT lprcPosRect) + { + if(pActiveSite == NULL) + pActiveSite = m_clientSite; + + if(pActiveSite == NULL) + return E_FAIL; + + // TODO: store this until we are closed or deactivated + IOleInPlaceSite * site; + + HRESULT hr = pActiveSite->QueryInterface(&site); + + if(FAILED(hr)) + return hr; + + IOleInPlaceFrame * frame = NULL; + IOleInPlaceUIWindow * uiWindow = NULL; + + for(;;) + { + hr = site->CanInPlaceActivate(); + + if(hr == S_FALSE) + hr = E_FAIL; + + if(FAILED(hr)) + break; + + site->OnInPlaceActivate(); + + if(hwndParent == NULL) + { + hr = site->GetWindow(&hwndParent); + + if(FAILED(hr)) + break; + } + + RECT rcPos; + RECT rcClip; + OLEINPLACEFRAMEINFO frameInfo = { sizeof(frameInfo) }; + + site->GetWindowContext(&frame, &uiWindow, &rcPos, &rcClip, &frameInfo); + + if(lprcPosRect == NULL) + lprcPosRect = &rcPos; + + if(m_controlWindow) + ShowWindow(m_controlWindow, SW_SHOW); + else + { + hr = CreateControlWindow(); + + if(FAILED(hr)) + break; + } + + SetObjectRects(lprcPosRect, &rcClip); + + // UI activation + if((iVerb == OLEIVERB_PRIMARY || iVerb == OLEIVERB_UIACTIVATE) && !m_uiActive) + { + m_uiActive = true; + + hr = site->OnUIActivate(); + + if(FAILED(hr)) + break; + + // TODO: focus the control window + + if(frame) + { + frame->SetActiveObject(this, NULL); + frame->SetBorderSpace(NULL); + } + + if(uiWindow) + { + uiWindow->SetActiveObject(this, NULL); + uiWindow->SetBorderSpace(NULL); + } + } + + break; + } + + if(uiWindow) + uiWindow->Release(); + + if(frame) + frame->Release(); + + site->Release(); + + if(SUCCEEDED(hr)) + pActiveSite->ShowObject(); + + return hr; + } + +public: + /* IUnknown */ + /* + NOTE: this is the delegating implementation, to support aggregation. The actual + implementation is RdpClientInner, above + */ + virtual STDMETHODIMP IUnknown::QueryInterface(REFIID riid, void ** ppvObject) + { + return m_punkOuter->QueryInterface(riid, ppvObject); + } + + virtual STDMETHODIMP_(ULONG) IUnknown::AddRef() + { + return m_punkOuter->AddRef(); + } + + virtual STDMETHODIMP_(ULONG) IUnknown::Release() + { + return m_punkOuter->Release(); + } + + /* IDispatch */ + virtual STDMETHODIMP IDispatch::GetTypeInfoCount(UINT * pctinfo) + { + *pctinfo = 1; + return S_OK; + } + + virtual STDMETHODIMP IDispatch::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) + { + if(iTInfo != 0) + return DISP_E_BADINDEX; + + return AcquireDispTypeInfo(ppTInfo); + } + + virtual STDMETHODIMP IDispatch::GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) + { + HRESULT hr = LoadDispTypeInfo(); + + if(FAILED(hr)) + return hr; + + return m_dispTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId); + } + + virtual STDMETHODIMP IDispatch::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) + { + HRESULT hr = LoadDispTypeInfo(); + + if(FAILED(hr)) + return hr; + + return m_dispTypeInfo->Invoke + ( + static_cast(this), + dispIdMember, + wFlags, + pDispParams, + pVarResult, + pExcepInfo, + puArgErr + ); + } + + /* IConnectionPoint */ + virtual STDMETHODIMP GetConnectionInterface(IID * pIID) + { + if(pIID == NULL) + return E_POINTER; + + *pIID = MSTSCLib::DIID_IMsTscAxEvents; + return S_OK; + } + + virtual STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer ** ppCPC) + { + if(ppCPC == NULL) + return E_POINTER; + + addRef(); + *ppCPC = this; + return S_OK; + } + + virtual STDMETHODIMP Advise(IUnknown * pUnkSink, DWORD * pdwCookie) + { + MSTSCLib::IMsTscAxEvents * sink; + + if(FAILED(pUnkSink->QueryInterface(&sink))) + return CONNECT_E_CANNOTCONNECT; + + MSTSCLib::IMsTscAxEvents ** sinks = GetSinks(); + DWORD cookie = 0; + + if(m_EventSinksCount) + { + bool found = false; + + for(size_t i = 0; i < m_EventSinksCount; ++ i) + { + found = (sinks[i] == NULL); + + if(found) + { + cookie = static_cast(i); + break; + } + } + + if(!found) + { + MSTSCLib::IMsTscAxEvents ** newSinks = new MSTSCLib::IMsTscAxEvents *[m_EventSinksCount + 1]; + + if(newSinks == NULL) + { + sink->Release(); + return E_OUTOFMEMORY; + } + + std::copy(sinks, sinks + m_EventSinksCount, newSinks); + + m_EventSinks = newSinks; + sinks = newSinks; + + cookie = static_cast(m_EventSinksCount); + } + } + + sinks[cookie] = sink; + *pdwCookie = cookie; + + return S_OK; + } + + virtual STDMETHODIMP Unadvise(DWORD dwCookie) + { + MSTSCLib::IMsTscAxEvents ** sinks = GetSinks(); + + if(dwCookie >= m_EventSinksCount || sinks[dwCookie] == NULL) + return CONNECT_E_NOCONNECTION; + + sinks[dwCookie]->Release(); + sinks[dwCookie] = NULL; + + // BUGBUG: the array currently grows forever. Trim it whenever possible + + return S_OK; + } + + virtual STDMETHODIMP EnumConnections(IEnumConnections ** ppEnum) + { + // I see no real value in this + return E_NOTIMPL; + } + + /* IConnectionPointContainer */ virtual STDMETHODIMP IConnectionPointContainer::EnumConnectionPoints(IEnumConnectionPoints ** ppEnum) { *ppEnum = new CEnumConnectionPoints(this); @@ -2238,7 +2737,7 @@ public: return E_NOTIMPL; } - /* IObjectSafety */ // DONE + /* IObjectSafety */ virtual STDMETHODIMP IObjectSafety::GetInterfaceSafetyOptions(REFIID riid, DWORD * pdwSupportedOptions, DWORD * pdwEnabledOptions) { if(pdwSupportedOptions == NULL || pdwEnabledOptions == NULL) @@ -2261,7 +2760,7 @@ public: return S_OK; } - /* IOleControl */ // DONE + /* IOleControl */ // 3/4 virtual STDMETHODIMP IOleControl::GetControlInfo(CONTROLINFO * pCI) { return E_NOTIMPL; @@ -2279,7 +2778,11 @@ public: virtual STDMETHODIMP IOleControl::FreezeEvents(BOOL bFreeze) { - // TODO? do we need special processing for this? + if(bFreeze) + InterlockedIncrement(&m_freezeEvents); + else if(InterlockedDecrement(&m_freezeEvents) == 0) + UnfreezeEvents(); + return S_OK; } @@ -2291,13 +2794,13 @@ public: virtual STDMETHODIMP IOleInPlaceActiveObject::OnFrameWindowActivate(BOOL fActivate) { - // TODO? + // TODO return E_NOTIMPL; } virtual STDMETHODIMP IOleInPlaceActiveObject::OnDocWindowActivate(BOOL fActivate) { - // TODO? + // TODO return E_NOTIMPL; } @@ -2311,19 +2814,22 @@ public: return S_OK; } - /* IOleInPlaceObject */ // 0/4 + /* IOleInPlaceObject */ // 1/4 virtual STDMETHODIMP IOleInPlaceObject::InPlaceDeactivate() { + // TODO: UIDeactivate, destroy window, inplacesite->OnInPlaceDeactivate return E_NOTIMPL; } virtual STDMETHODIMP IOleInPlaceObject::UIDeactivate() { + // TODO return E_NOTIMPL; } virtual STDMETHODIMP IOleInPlaceObject::SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect) { + // TODO: reposition the control window and set its region here return E_NOTIMPL; } @@ -2332,7 +2838,7 @@ public: return E_NOTIMPL; } - /* IOleObject */ // 14/21 + /* IOleObject */ // 18/21 virtual STDMETHODIMP IOleObject::SetClientSite(IOleClientSite * pClientSite) { if(m_clientSite) @@ -2365,6 +2871,7 @@ public: virtual STDMETHODIMP IOleObject::Close(DWORD dwSaveOption) { + // TODO: deactivate, destroy window, release in-place site, release advise sink return E_NOTIMPL; // TODO } @@ -2390,7 +2897,33 @@ public: virtual STDMETHODIMP IOleObject::DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite * pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect) { - return E_NOTIMPL; // TODO + HRESULT hr; + + switch(iVerb) + { + case OLEIVERB_PRIMARY: + case OLEIVERB_SHOW: + case OLEIVERB_UIACTIVATE: + case OLEIVERB_INPLACEACTIVATE: + hr = S_OK; + break; + + default: + if(iVerb > 0) + hr = OLEOBJ_S_INVALIDVERB; + else + hr = E_NOTIMPL; + } + + if(FAILED(hr)) + return hr; + + HRESULT hrActivate = Activate(iVerb, pActiveSite, hwndParent, lprcPosRect); + + if(FAILED(hrActivate)) + hr = hrActivate; + + return hr; } virtual STDMETHODIMP IOleObject::EnumVerbs(IEnumOLEVERB ** ppEnumOleVerb) @@ -2421,27 +2954,52 @@ public: virtual STDMETHODIMP IOleObject::SetExtent(DWORD dwDrawAspect, SIZEL * psizel) { - return E_NOTIMPL; // TODO + // TODO: resize + return E_NOTIMPL; } virtual STDMETHODIMP IOleObject::GetExtent(DWORD dwDrawAspect, SIZEL * psizel) { - return E_NOTIMPL; // TODO + // TODO: return size + return E_NOTIMPL; + } + + HRESULT NeedAdviseHolder() + { + if(m_adviseHolder) + return S_OK; + + return CreateOleAdviseHolder(&m_adviseHolder); } virtual STDMETHODIMP IOleObject::Advise(IAdviseSink * pAdvSink, DWORD * pdwConnection) { - return E_NOTIMPL; // TODO + HRESULT hr = NeedAdviseHolder(); + + if(FAILED(hr)) + return hr; + + return m_adviseHolder->Advise(pAdvSink, pdwConnection); } virtual STDMETHODIMP IOleObject::Unadvise(DWORD dwConnection) { - return E_NOTIMPL; // TODO + HRESULT hr = NeedAdviseHolder(); + + if(FAILED(hr)) + return hr; + + return m_adviseHolder->Unadvise(dwConnection); } virtual STDMETHODIMP IOleObject::EnumAdvise(IEnumSTATDATA ** ppenumAdvise) { - return E_NOTIMPL; // TODO + HRESULT hr = NeedAdviseHolder(); + + if(FAILED(hr)) + return hr; + + return m_adviseHolder->EnumAdvise(ppenumAdvise); } virtual STDMETHODIMP IOleObject::GetMiscStatus(DWORD dwAspect, DWORD * pdwStatus) @@ -2454,7 +3012,7 @@ public: return E_NOTIMPL; } - /* IOleWindow */ // DONE + /* IOleWindow */ virtual STDMETHODIMP IOleWindow::GetWindow(HWND * phwnd) { if(phwnd == NULL) @@ -2472,7 +3030,7 @@ public: return E_NOTIMPL; } - /* IPersist */ // DONE + /* IPersist */ virtual STDMETHODIMP IPersist::GetClassID(CLSID * pClassID) { *pClassID = m_classId; @@ -2552,7 +3110,7 @@ public: return E_NOTIMPL; } - /* IProvideClassInfo */ // DONE + /* IProvideClassInfo */ virtual STDMETHODIMP IProvideClassInfo::GetClassInfo(ITypeInfo ** ppTI) { HRESULT hr = LoadTypeLibrary(); @@ -2563,7 +3121,7 @@ public: return m_typeLib->GetTypeInfoOfGuid(m_classId, ppTI); } - /* IProvideClassInfo2 */ // DONE + /* IProvideClassInfo2 */ virtual STDMETHODIMP IProvideClassInfo2::GetGUID(DWORD dwGuidKind, GUID * pGUID) { if(dwGuidKind != GUIDKIND_DEFAULT_SOURCE_DISP_IID) @@ -2573,10 +3131,30 @@ public: return S_OK; } - /* IQuickActivate */ // 2/3 + /* IQuickActivate */ virtual STDMETHODIMP IQuickActivate::QuickActivate(QACONTAINER * pQaContainer, QACONTROL * pQaControl) { - return E_NOTIMPL; // TODO + if(pQaContainer == NULL || pQaControl == NULL) + return E_POINTER; + + if(pQaContainer->cbSize < sizeof(*pQaContainer) || pQaControl->cbSize < sizeof(*pQaControl)) + return E_INVALIDARG; + + ULONG cb = pQaControl->cbSize; + ZeroMemory(pQaControl, cb); + pQaControl->cbSize = cb; + + SetClientSite(pQaContainer->pClientSite); + + if(pQaContainer->pAdviseSink) + SetAdvise(DVASPECT_CONTENT, 0, pQaContainer->pAdviseSink); + + if(pQaContainer->pUnkEventSink) + Advise(pQaContainer->pUnkEventSink, &pQaControl->dwEventCookie); + + GetMiscStatus(DVASPECT_CONTENT, &pQaControl->dwMiscStatus); + + return E_NOTIMPL; } virtual STDMETHODIMP IQuickActivate::SetContentExtent(LPSIZEL pSizel) @@ -2780,16 +3358,59 @@ public: virtual STDMETHODIMP IMsTscAx::Connect() { - return E_NOTIMPL; // TODO + if(m_Connected) + return E_FAIL; + + m_Connected = true; + + // TODO: if the protocol thread is waiting to reconnect, wake it up + + // TODO: initialize plugin DLLs/channels + + HRESULT hr; + + if(m_controlWindow == NULL) + { + hr = CreateControlWindow(); + + if(FAILED(hr)) + return hr; + } + + for(;;) + { + // TODO: initialize m_protocolState + + DWORD dwIgnore; + m_protocolThread = CreateThread(NULL, 0, ProtocolLoopThreadProc, this, 0, &dwIgnore); + + hr = S_OK; + break; + } + + if(FAILED(hr)) + m_Connected = false; + + return hr; } virtual STDMETHODIMP IMsTscAx::Disconnect() { + if(!m_Connected) + return E_FAIL; + + // TODO: if the protocol thread is waiting to reconnect, wake it up + return E_NOTIMPL; // TODO } virtual STDMETHODIMP IMsTscAx::CreateVirtualChannels(BSTR newVal) { + UINT strLength = SysStringLen(newVal); + + if(strLength < 1 || strLength > 300) + return E_INVALIDARG; + return E_NOTIMPL; // TODO } @@ -2869,7 +3490,7 @@ public: return E_NOTIMPL; // TODO } - /* IMsRdpClient2 */ // DONE + /* IMsRdpClient2 */ virtual STDMETHODIMP IMsRdpClient2::get_AdvancedSettings3(MSTSCLib::IMsRdpClientAdvancedSettings2 ** ppAdvSettings) { return GetAdvancedSettings(ppAdvSettings); @@ -2885,19 +3506,19 @@ public: return GetProperty(m_ConnectedStatusText, pConnectedStatusText); } - /* IMsRdpClient3 */ // DONE + /* IMsRdpClient3 */ virtual STDMETHODIMP IMsRdpClient3::get_AdvancedSettings4(MSTSCLib::IMsRdpClientAdvancedSettings3 ** ppAdvSettings) { return GetAdvancedSettings(ppAdvSettings); } - /* IMsRdpClient4 */ // DONE + /* IMsRdpClient4 */ virtual STDMETHODIMP IMsRdpClient4::get_AdvancedSettings5(MSTSCLib::IMsRdpClientAdvancedSettings4 ** ppAdvSettings5) { return GetAdvancedSettings(ppAdvSettings5); } - /* IMsTscNonScriptable */ // DONE + /* IMsTscNonScriptable */ virtual STDMETHODIMP IMsTscNonScriptable::put_ClearTextPassword(BSTR rhs) { return SetProperty(m_ClearTextPassword, rhs); @@ -2961,7 +3582,7 @@ public: return E_NOTIMPL; // TODO } - /* IMsRdpClientNonScriptable2 */ // DONE + /* IMsRdpClientNonScriptable2 */ virtual STDMETHODIMP IMsRdpClientNonScriptable2::put_UIParentWindowHandle(HWND phwndUIParentWindowHandle) { return SetProperty(m_UIParentWindowHandle, phwndUIParentWindowHandle); @@ -3077,6 +3698,12 @@ STDAPI DllCanUnloadNow(void) return canUnloadServer() ? S_OK : S_FALSE; } +STDAPI_(ULONG) DllGetTscCtlVer(void) +{ + // BUGBUG: don't hardcode this + return 0x05020ECE; // 5.2.3790 +} + } // EOF diff --git a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_h.h b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_h.h index 4e556bc2c79..c49476ba32f 100644 --- a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_h.h +++ b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_h.h @@ -4,10 +4,10 @@ /* File created by MIDL compiler version 7.00.0493 */ -/* at Sat Aug 12 22:21:54 2006 +/* at Sun Aug 13 16:46:06 2006 */ /* Compiler settings for .\mstsclib.idl: - Oicf, W2, Zp8, env=Win32 (32b run) + Oicf, W1, Zp8, env=Win32 (32b run) protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data VC __declspec() decoration level: diff --git a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_i.c b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_i.c index e71e6ab224c..60a812a56c1 100644 --- a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_i.c +++ b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_i.c @@ -6,10 +6,10 @@ /* File created by MIDL compiler version 7.00.0493 */ -/* at Sat Aug 12 22:21:54 2006 +/* at Sun Aug 13 16:46:06 2006 */ /* Compiler settings for .\mstsclib.idl: - Oicf, W2, Zp8, env=Win32 (32b run) + Oicf, W1, Zp8, env=Win32 (32b run) protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data VC __declspec() decoration level: diff --git a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_h.h b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_h.h index b16c0344785..dc1bc2da754 100644 --- a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_h.h +++ b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_h.h @@ -4,10 +4,10 @@ /* File created by MIDL compiler version 7.00.0493 */ -/* at Sat Aug 12 22:21:53 2006 +/* at Sun Aug 13 16:46:05 2006 */ /* Compiler settings for .\mstsclib_redist.idl: - Oicf, W2, Zp8, env=Win32 (32b run) + Oicf, W1, Zp8, env=Win32 (32b run) protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data VC __declspec() decoration level: diff --git a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_i.c b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_i.c index dfeb95f53e0..5930c974073 100644 --- a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_i.c +++ b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_i.c @@ -6,10 +6,10 @@ /* File created by MIDL compiler version 7.00.0493 */ -/* at Sat Aug 12 22:21:53 2006 +/* at Sun Aug 13 16:46:05 2006 */ /* Compiler settings for .\mstsclib_redist.idl: - Oicf, W2, Zp8, env=Win32 (32b run) + Oicf, W1, Zp8, env=Win32 (32b run) protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data VC __declspec() decoration level: diff --git a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp index 3827e176904..045b261a88d 100644 --- a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp +++ b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp @@ -7,7 +7,7 @@ template T aligndown(const T& X, const U& align) { - return X & ~(T(align) - 1); + return X & ~(T(align) - 1); } template T alignup(const T& X, const U& align) @@ -93,56 +93,6 @@ extern "C" va_end(ap); } - /* malloc; exit if out of memory */ - void * - xmalloc(size_t size) - { - void *mem = malloc(size); - if (mem == NULL) - { - error("xmalloc %d\n", size); - exit(1); - } - return mem; - } - - /* strdup */ - char * - xstrdup(const char *s) - { - char *mem = _strdup(s); - if (mem == NULL) - { - perror("strdup"); - exit(1); - } - return mem; - } - - /* realloc; exit if out of memory */ - void * - xrealloc(void *oldmem, size_t size) - { - void *mem; - - if (size < 1) - size = 1; - mem = realloc(oldmem, size); - if (mem == NULL) - { - error("xrealloc %d\n", size); - exit(1); - } - return mem; - } - - /* free */ - void - xfree(void *mem) - { - free(mem); - } - /* Create the bitmap cache directory */ BOOL rd_pstcache_mkdir(void) @@ -231,78 +181,12 @@ extern "C" int load_licence(RDPCLIENT * This, unsigned char **data) { - char *home, *path; - struct stat st; - int fd, length; - - home = getenv("HOME"); - if (home == NULL) - return -1; - - path = (char *) xmalloc(strlen(home) + strlen(This->hostname) + sizeof("/.rdesktop/licence.")); - sprintf(path, "%s/.rdesktop/licence.%s", home, This->hostname); - - fd = _open(path, O_RDONLY); - if (fd == -1) - return -1; - - if (fstat(fd, &st)) - return -1; - - *data = (uint8 *) xmalloc(st.st_size); - length = _read(fd, *data, st.st_size); - _close(fd); - xfree(path); - return length; + return -1; } void save_licence(RDPCLIENT * This, unsigned char *data, int length) { - char *home, *path, *tmppath; - int fd; - - home = getenv("HOME"); - if (home == NULL) - return; - - path = (char *) xmalloc(strlen(home) + strlen(This->hostname) + sizeof("/.rdesktop/licence.")); - - sprintf(path, "%s/.rdesktop", home); - if ((_mkdir(path) == -1) && errno != EEXIST) - { - perror(path); - return; - } - - /* write licence to licence.hostname.new, then atomically rename to licence.hostname */ - - sprintf(path, "%s/.rdesktop/licence.%s", home, This->hostname); - tmppath = (char *) xmalloc(strlen(path) + sizeof(".new")); - strcpy(tmppath, path); - strcat(tmppath, ".new"); - - fd = _open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd == -1) - { - perror(tmppath); - return; - } - - if (_write(fd, data, length) != length) - { - perror(tmppath); - _unlink(tmppath); - } - else if (rename(tmppath, path) == -1) - { - perror(path); - _unlink(tmppath); - } - - _close(fd); - xfree(tmppath); - xfree(path); } /* ==== END POOP ==== */ @@ -381,7 +265,10 @@ extern "C" int datasize = tostride * height; - uint8 * dibits = new(xmalloc(datasize)) uint8; + uint8 * dibits = new(malloc(datasize)) uint8; + + if(dibits == NULL) + return NULL; const uint8 * src = data; uint8 * dest = dibits; @@ -412,11 +299,13 @@ extern "C" void ui_resize_window(RDPCLIENT * This) { + // EVENT: OnRemoteDesktopSizeChange + // TODO: resize buffer SetWindowPos(hwnd, NULL, 0, 0, This->width, This->height, SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE); } int - ui_select(RDPCLIENT * This, int rdp_socket) + ui_select(RDPCLIENT * This, SOCKET rdp_socket) { return 1; // TODO: return 0 for user quit. Or just kill this silly function } @@ -451,11 +340,14 @@ extern "C" { uint8 * databuf = NULL; uint8 * databits = win32_convert_scanlines(width, height, 1, 1, 2, data, &databuf); - + + if(databits == NULL) + return NULL; + HBITMAP hbm = CreateBitmap(width, height, 1, 1, databits); if(databuf) - xfree(databuf); + free(databuf); const uint8 * p = data; int stride = alignup(alignup(width, 8) / 8, 1); @@ -497,8 +389,18 @@ extern "C" uint8 * xorbuf = NULL; uint8 * andbits = win32_convert_scanlines(width, - height, 1, 2, 4, andmask, &andbuf); + + if(andbits == NULL) + return NULL; + uint8 * xorbits = win32_convert_scanlines(width, height, 24, 2, 4, xormask, &xorbuf); + if(xorbits == NULL) + { + free(andbits); + return NULL; + } + HBITMAP hbmMask = CreateBitmap(width, height, 1, 1, andbits); HBITMAP hbmColor = win32_create_dib(width, height, 24, xorbits); @@ -508,17 +410,17 @@ extern "C" iconinfo.yHotspot = y; iconinfo.hbmMask = hbmMask; iconinfo.hbmColor = hbmColor; - + HICON icon = CreateIconIndirect(&iconinfo); if(icon == NULL) error("CreateIconIndirect %dx%d failed\n", width, height); if(andbuf) - xfree(andbuf); + free(andbuf); if(xorbuf) - xfree(xorbuf); + free(xorbuf); DeleteObject(hbmMask); DeleteObject(hbmColor); @@ -763,7 +665,7 @@ extern "C" SetBkColor(hdcBuffer, bgcolour); SetTextColor(hdcBuffer, fgcolour); SetBrushOrgEx(hdcBuffer, brush->xorigin, brush->yorigin, NULL); - SelectObject(hdcBuffer, hbr); + SelectObject(hdcBuffer, hbr); PatBlt(hdcBuffer, x, y, cx, cy, MAKELONG(0, opcode)); @@ -841,7 +743,7 @@ extern "C" DeleteObject(hpen); RECT rcDamage; - + if(startx < endx) { rcDamage.left = startx; @@ -1058,7 +960,7 @@ extern "C" SelectObject(hdcBuffer, holdpen); SelectObject(hdcBuffer, holdbrush); - + DeleteObject(hbr); if(boxcx > 1) @@ -1179,6 +1081,15 @@ extern "C" { RestoreDC(hdcBuffer, nSavedDC); } + + int event_pubkey(RDPCLIENT * This, const unsigned char * key, size_t key_size) + { + return True; + } + + void event_logon(RDPCLIENT * This) + { + } }; static @@ -1268,7 +1179,7 @@ mstsc_WndProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam) /* Keyboard stuff */ case WM_SYSKEYDOWN: - case WM_KEYDOWN: + case WM_KEYDOWN: rdp_send_input(This, GetMessageTime(), RDP_INPUT_SCANCODE, RDP_KEYPRESS | (lparam & 0x1000000 ? KBD_FLAG_EXT : 0), LOBYTE(HIWORD(lparam)), 0); break; @@ -1290,7 +1201,7 @@ mstsc_WndProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam) // Movement case WM_MOUSEMOVE: - if(This->sendmotion || wparam & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON | MK_XBUTTON1 | MK_XBUTTON2)) + //if(This->sendmotion || wparam & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON | MK_XBUTTON1 | MK_XBUTTON2)) rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, LOWORD(lparam), HIWORD(lparam)); break; @@ -1352,14 +1263,13 @@ mstsc_ProtocolIOThread { RDPCLIENT * This = static_cast(lpArgument); - strcpy(This->username, "Administrator"); - - DWORD dw = sizeof(This->hostname); - GetComputerNameA(This->hostname, &dw); + WCHAR hostname[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD dw = ARRAYSIZE(hostname); + GetComputerNameW(hostname, &dw); uint32 flags = RDP_LOGON_NORMAL | RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2; - rdp_connect(This, "10.0.0.3", flags, "", "", "", ""); + rdp_connect(This, "10.0.0.3", flags, L"Administrator", L"", L"", L"", L"", hostname, ""); //rdp_connect(This, "192.168.7.232", flags, "", "", "", ""); hdcBuffer = CreateCompatibleDC(NULL); @@ -1390,6 +1300,8 @@ mstsc_ProtocolIOThread uint32 ext_disc_reason; rdp_main_loop(This, &deactivated, &ext_disc_reason); + // TODO: handle redirection + // EVENT: OnDisconnect SendMessage(hwnd, WM_CLOSE, 0, 0); @@ -1450,6 +1362,7 @@ VirtualChannelInit memcpy(This->channel_defs + This->num_channels, pChannel, sizeof(*pChannel) * channelCount); +#if 0 // TODO for(INT i = 0; i < channelCount; ++ i) { pChannel[i].options |= CHANNEL_OPTION_INITIALIZED; @@ -1459,6 +1372,7 @@ VirtualChannelInit This->channel_data[j].pChannelInitEventProc = pChannelInitEventProc; This->channel_data[j].pChannelOpenEventProc = NULL; } +#endif This->num_channels += channelCount; @@ -1491,6 +1405,7 @@ VirtualChannelOpen RDPCLIENT * This = (RDPCLIENT *)pInitHandle; +#if 0 // TODO for(unsigned i = 0; i < This->num_channels; ++ i) { if(strcmp(pChannelName, This->channel_defs[i].name) == 0) @@ -1507,6 +1422,7 @@ VirtualChannelOpen break; } } +#endif return CHANNEL_RC_OK; } @@ -1562,7 +1478,7 @@ int wmain() This->height = 600; This->server_depth = 24; This->bitmap_compression = True; - This->sendmotion = True; + //This->sendmotion = True; This->bitmap_cache = True; This->bitmap_cache_persist_enable = False; This->bitmap_cache_precache = True; @@ -1570,14 +1486,14 @@ int wmain() This->packet_encryption = True; This->desktop_save = True; This->polygon_ellipse_orders = False; // = True; - This->fullscreen = False; - This->grab_keyboard = True; - This->hide_decorations = False; + //This->fullscreen = False; + //This->grab_keyboard = True; + //This->hide_decorations = False; This->use_rdp5 = True; - This->rdpclip = True; + //This->rdpclip = True; This->console_session = False; - This->numlock_sync = False; - This->seamless_rdp = False; + //This->numlock_sync = False; + //This->seamless_rdp = False; This->rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS; This->tcp_port_rdp = TCP_PORT_RDP; @@ -1589,6 +1505,8 @@ int wmain() This->cache.bmpcache_mru[1] = NOT_SET; This->cache.bmpcache_mru[2] = NOT_SET; + This->rdp.current_status = 1; + hcursor = NULL; WNDCLASS wc; diff --git a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/stdafx.cpp b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/stdafx.cpp index ed86f05d826..0bc452e65b3 100644 --- a/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/stdafx.cpp +++ b/reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/stdafx.cpp @@ -1,8 +1,3 @@ -// stdafx.cpp : source file that includes just the standard includes -// rdesktop-core-tester.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - #include "stdafx.h" -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file +// EOF diff --git a/reactos/base/applications/tsclient/rdesktop/cache.c b/reactos/base/applications/tsclient/rdesktop/cache.c index b2f4078233e..1240be83117 100644 --- a/reactos/base/applications/tsclient/rdesktop/cache.c +++ b/reactos/base/applications/tsclient/rdesktop/cache.c @@ -316,11 +316,15 @@ void cache_put_text(RDPCLIENT * This, uint8 cache_id, void *data, int length) { DATABLOB *text; + void * p = malloc(length); + + if(p == NULL) + return; text = &This->cache.textcache[cache_id]; if (text->data != NULL) - xfree(text->data); - text->data = xmalloc(length); + free(text->data); + text->data = p; text->size = length; memcpy(text->data, data, length); } diff --git a/reactos/base/applications/tsclient/rdesktop/iso.c b/reactos/base/applications/tsclient/rdesktop/iso.c index 891dce5fe5c..98700027743 100644 --- a/reactos/base/applications/tsclient/rdesktop/iso.c +++ b/reactos/base/applications/tsclient/rdesktop/iso.c @@ -21,13 +21,16 @@ #include "rdesktop.h" /* Send a self-contained ISO PDU */ -static void +static BOOL iso_send_msg(RDPCLIENT * This, uint8 code) { STREAM s; s = tcp_init(This, 11); + if(s == NULL) + return False; + out_uint8(s, 3); /* version */ out_uint8(s, 0); /* reserved */ out_uint16_be(s, 11); /* length */ @@ -39,17 +42,21 @@ iso_send_msg(RDPCLIENT * This, uint8 code) out_uint8(s, 0); /* class */ s_mark_end(s); - tcp_send(This, s); + return tcp_send(This, s); } -static void -iso_send_connection_request(RDPCLIENT * This, char *username) +static BOOL +iso_send_connection_request(RDPCLIENT * This, char *cookie) { STREAM s; - int length = 30 + strlen(username); + int cookielen = (int)strlen(cookie); + int length = 11 + cookielen; s = tcp_init(This, length); + if(s == NULL) + return False; + out_uint8(s, 3); /* version */ out_uint8(s, 0); /* reserved */ out_uint16_be(s, length); /* length */ @@ -60,14 +67,10 @@ iso_send_connection_request(RDPCLIENT * This, char *username) out_uint16(s, 0); /* src_ref */ out_uint8(s, 0); /* class */ - out_uint8p(s, "Cookie: mstshash=", strlen("Cookie: mstshash=")); - out_uint8p(s, username, strlen(username)); - - out_uint8(s, 0x0d); /* Unknown */ - out_uint8(s, 0x0a); /* Unknown */ + out_uint8p(s, cookie, cookielen); s_mark_end(s); - tcp_send(This, s); + return tcp_send(This, s); } /* Receive a message on the ISO layer, return code */ @@ -121,19 +124,23 @@ iso_init(RDPCLIENT * This, int length) STREAM s; s = tcp_init(This, length + 7); + + if(s == NULL) + return NULL; + s_push_layer(s, iso_hdr, 7); return s; } /* Send an ISO data PDU */ -void +BOOL iso_send(RDPCLIENT * This, STREAM s) { uint16 length; s_pop_layer(s, iso_hdr); - length = s->end - s->p; + length = (uint16)(s->end - s->p); out_uint8(s, 3); /* version */ out_uint8(s, 0); /* reserved */ @@ -143,7 +150,7 @@ iso_send(RDPCLIENT * This, STREAM s) out_uint8(s, ISO_PDU_DT); /* code */ out_uint8(s, 0x80); /* eot */ - tcp_send(This, s); + return tcp_send(This, s); } /* Receive ISO transport data packet */ @@ -169,14 +176,15 @@ iso_recv(RDPCLIENT * This, uint8 * rdpver) /* Establish a connection up to the ISO layer */ BOOL -iso_connect(RDPCLIENT * This, char *server, char *username) +iso_connect(RDPCLIENT * This, char *server, char *cookie) { uint8 code = 0; if (!tcp_connect(This, server)) return False; - iso_send_connection_request(This, username); + if (!iso_send_connection_request(This, cookie)) + return False; if (iso_recv_msg(This, &code, NULL) == NULL) return False; @@ -193,14 +201,15 @@ iso_connect(RDPCLIENT * This, char *server, char *username) /* Establish a reconnection up to the ISO layer */ BOOL -iso_reconnect(RDPCLIENT * This, char *server) +iso_reconnect(RDPCLIENT * This, char *server, char *cookie) { uint8 code = 0; if (!tcp_connect(This, server)) return False; - iso_send_msg(This, ISO_PDU_CR); + if (!iso_send_connection_request(This, cookie)) // BUGBUG should we really pass the cookie here? + return False; if (iso_recv_msg(This, &code, NULL) == NULL) return False; @@ -216,11 +225,13 @@ iso_reconnect(RDPCLIENT * This, char *server) } /* Disconnect from the ISO layer */ -void +BOOL iso_disconnect(RDPCLIENT * This) { - iso_send_msg(This, ISO_PDU_DR); - tcp_disconnect(This); + if(!iso_send_msg(This, ISO_PDU_DR)) + return False; + + return tcp_disconnect(This); } /* reset the state to support reconnecting */ diff --git a/reactos/base/applications/tsclient/rdesktop/licence.c b/reactos/base/applications/tsclient/rdesktop/licence.c index d60d45f3fbd..c662cd90cfd 100644 --- a/reactos/base/applications/tsclient/rdesktop/licence.c +++ b/reactos/base/applications/tsclient/rdesktop/licence.c @@ -43,11 +43,11 @@ static void licence_generate_hwid(RDPCLIENT * This, uint8 * hwid) { buf_out_uint32(hwid, 2); - strncpy((char *) (hwid + 4), This->hostname, LICENCE_HWID_SIZE - 4); + strncpy((char *) (hwid + 4), This->licence_hostname, LICENCE_HWID_SIZE - 4); } /* Present an existing licence to the server */ -static void +static BOOL licence_present(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data, uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature) { @@ -59,6 +59,9 @@ licence_present(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data, s = sec_init(This, sec_flags, length + 4); + if(s == NULL) + return False; + out_uint8(s, LICENCE_TAG_PRESENT); out_uint8(s, 2); /* version */ out_uint16_le(s, length); @@ -84,21 +87,24 @@ licence_present(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data, out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); s_mark_end(s); - sec_send(This, s, sec_flags); + return sec_send(This, s, sec_flags); } /* Send a licence request packet */ -static void +static BOOL licence_send_request(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data, char *user, char *host) { uint32 sec_flags = SEC_LICENCE_NEG; - uint16 userlen = strlen(user) + 1; - uint16 hostlen = strlen(host) + 1; + uint16 userlen = (uint16)strlen(user) + 1; + uint16 hostlen = (uint16)strlen(host) + 1; uint16 length = 128 + userlen + hostlen; STREAM s; s = sec_init(This, sec_flags, length + 2); + if(s == NULL) + return False; + out_uint8(s, LICENCE_TAG_REQUEST); out_uint8(s, 2); /* version */ out_uint16_le(s, length); @@ -122,11 +128,11 @@ licence_send_request(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data, out_uint8p(s, host, hostlen); s_mark_end(s); - sec_send(This, s, sec_flags); + return sec_send(This, s, sec_flags); } /* Process a licence demand packet */ -static void +static BOOL licence_process_demand(RDPCLIENT * This, STREAM s) { uint8 null_data[SEC_MODULUS_SIZE]; @@ -156,16 +162,18 @@ licence_process_demand(RDPCLIENT * This, STREAM s) RC4_set_key(&crypt_key, 16, This->licence.key); RC4(&crypt_key, sizeof(hwid), hwid, hwid); - licence_present(This, null_data, null_data, licence_data, licence_size, hwid, signature); - xfree(licence_data); - return; + if(!licence_present(This, null_data, null_data, licence_data, licence_size, hwid, signature)) + return False; + + free(licence_data); + return True; } - licence_send_request(This, null_data, null_data, This->username, This->hostname); + return licence_send_request(This, null_data, null_data, This->licence_username, This->licence_hostname); } /* Send an authentication response packet */ -static void +static BOOL licence_send_authresp(RDPCLIENT * This, uint8 * token, uint8 * crypt_hwid, uint8 * signature) { uint32 sec_flags = SEC_LICENCE_NEG; @@ -174,6 +182,9 @@ licence_send_authresp(RDPCLIENT * This, uint8 * token, uint8 * crypt_hwid, uint8 s = sec_init(This, sec_flags, length + 2); + if(s == NULL) + return False; + out_uint8(s, LICENCE_TAG_AUTHRESP); out_uint8(s, 2); /* version */ out_uint16_le(s, length); @@ -189,7 +200,7 @@ licence_send_authresp(RDPCLIENT * This, uint8 * token, uint8 * crypt_hwid, uint8 out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); s_mark_end(s); - sec_send(This, s, sec_flags); + return sec_send(This, s, sec_flags); } /* Parse an authentication request packet */ diff --git a/reactos/base/applications/tsclient/rdesktop/mcs.c b/reactos/base/applications/tsclient/rdesktop/mcs.c index aadb5b1751a..3b7d2f20fb7 100644 --- a/reactos/base/applications/tsclient/rdesktop/mcs.c +++ b/reactos/base/applications/tsclient/rdesktop/mcs.c @@ -113,15 +113,18 @@ mcs_parse_domain_params(STREAM s) } /* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */ -static void +static BOOL mcs_send_connect_initial(RDPCLIENT * This, STREAM mcs_data) { - int datalen = mcs_data->end - mcs_data->data; + int datalen = (uint16)(mcs_data->end - mcs_data->data); int length = 9 + 3 * 34 + 4 + datalen; STREAM s; s = iso_init(This, length + 5); + if(s == NULL) + return False; + ber_out_header(s, MCS_CONNECT_INITIAL, length); ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* calling domain */ out_uint8(s, 1); @@ -139,7 +142,7 @@ mcs_send_connect_initial(RDPCLIENT * This, STREAM mcs_data) out_uint8p(s, mcs_data->data, datalen); s_mark_end(s); - iso_send(This, s); + return iso_send(This, s); } /* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */ @@ -187,33 +190,39 @@ mcs_recv_connect_response(RDPCLIENT * This, STREAM mcs_data) } /* Send an EDrq message (ASN.1 PER) */ -static void +static BOOL mcs_send_edrq(RDPCLIENT * This) { STREAM s; s = iso_init(This, 5); + if(s == NULL) + return False; + out_uint8(s, (MCS_EDRQ << 2)); out_uint16_be(s, 1); /* height */ out_uint16_be(s, 1); /* interval */ s_mark_end(s); - iso_send(This, s); + return iso_send(This, s); } /* Send an AUrq message (ASN.1 PER) */ -static void +static BOOL mcs_send_aurq(RDPCLIENT * This) { STREAM s; s = iso_init(This, 1); + if(s == NULL) + return False; + out_uint8(s, (MCS_AURQ << 2)); s_mark_end(s); - iso_send(This, s); + return iso_send(This, s); } /* Expect a AUcf message (ASN.1 PER) */ @@ -248,7 +257,7 @@ mcs_recv_aucf(RDPCLIENT * This, uint16 * mcs_userid) } /* Send a CJrq message (ASN.1 PER) */ -static void +static BOOL mcs_send_cjrq(RDPCLIENT * This, uint16 chanid) { STREAM s; @@ -257,12 +266,15 @@ mcs_send_cjrq(RDPCLIENT * This, uint16 chanid) s = iso_init(This, 5); + if(s == NULL) + return False; + out_uint8(s, (MCS_CJRQ << 2)); out_uint16_be(s, This->mcs_userid); out_uint16_be(s, chanid); s_mark_end(s); - iso_send(This, s); + return iso_send(This, s); } /* Expect a CJcf message (ASN.1 PER) */ @@ -304,19 +316,23 @@ mcs_init(RDPCLIENT * This, int length) STREAM s; s = iso_init(This, length + 8); + + if(s == NULL) + return NULL; + s_push_layer(s, mcs_hdr, 8); return s; } /* Send an MCS transport data packet to a specific channel */ -void +BOOL mcs_send_to_channel(RDPCLIENT * This, STREAM s, uint16 channel) { uint16 length; s_pop_layer(s, mcs_hdr); - length = s->end - s->p - 8; + length = (uint16)(s->end - s->p - 8); length |= 0x8000; out_uint8(s, (MCS_SDRQ << 2)); @@ -325,14 +341,14 @@ mcs_send_to_channel(RDPCLIENT * This, STREAM s, uint16 channel) out_uint8(s, 0x70); /* flags */ out_uint16_be(s, length); - iso_send(This, s); + return iso_send(This, s); } /* Send an MCS transport data packet to the global channel */ -void +BOOL mcs_send(RDPCLIENT * This, STREAM s) { - mcs_send_to_channel(This, s, MCS_GLOBAL_CHANNEL); + return mcs_send_to_channel(This, s, MCS_GLOBAL_CHANNEL); } /* Receive an MCS transport data packet */ @@ -369,77 +385,67 @@ mcs_recv(RDPCLIENT * This, uint16 * channel, uint8 * rdpver) /* Establish a connection up to the MCS layer */ BOOL -mcs_connect(RDPCLIENT * This, char *server, STREAM mcs_data, char *username) +mcs_connect(RDPCLIENT * This, char *server, char * cookie, STREAM mcs_data) { unsigned int i; - if (!iso_connect(This, server, username)) + if (!iso_connect(This, server, cookie)) return False; - mcs_send_connect_initial(This, mcs_data); - if (!mcs_recv_connect_response(This, mcs_data)) + if (!mcs_send_connect_initial(This, mcs_data) || !mcs_recv_connect_response(This, mcs_data)) goto error; - mcs_send_edrq(This); + if (!mcs_send_edrq(This) || !mcs_send_aurq(This)) + goto error; - mcs_send_aurq(This); if (!mcs_recv_aucf(This, &This->mcs_userid)) goto error; - mcs_send_cjrq(This, This->mcs_userid + MCS_USERCHANNEL_BASE); - - if (!mcs_recv_cjcf(This)) + if (!mcs_send_cjrq(This, This->mcs_userid + MCS_USERCHANNEL_BASE) || !mcs_recv_cjcf(This)) goto error; - mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL); - if (!mcs_recv_cjcf(This)) + if (!mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL) || !mcs_recv_cjcf(This)) goto error; for (i = 0; i < This->num_channels; i++) { - mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL + 1 + i); - if (!mcs_recv_cjcf(This)) + if (!mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL + 1 + i) || !mcs_recv_cjcf(This)) goto error; } return True; - error: + error: iso_disconnect(This); return False; } /* Establish a connection up to the MCS layer */ BOOL -mcs_reconnect(RDPCLIENT * This, char *server, STREAM mcs_data) +mcs_reconnect(RDPCLIENT * This, char *server, char *cookie, STREAM mcs_data) { unsigned int i; - if (!iso_reconnect(This, server)) + if (!iso_reconnect(This, server, cookie)) return False; - mcs_send_connect_initial(This, mcs_data); - if (!mcs_recv_connect_response(This, mcs_data)) + if (!mcs_send_connect_initial(This, mcs_data) || !mcs_recv_connect_response(This, mcs_data)) goto error; - mcs_send_edrq(This); + if (!mcs_send_edrq(This) || !mcs_send_aurq(This)) + goto error; - mcs_send_aurq(This); if (!mcs_recv_aucf(This, &This->mcs_userid)) goto error; - mcs_send_cjrq(This, This->mcs_userid + MCS_USERCHANNEL_BASE); - - if (!mcs_recv_cjcf(This)) + if (!mcs_send_cjrq(This, This->mcs_userid + MCS_USERCHANNEL_BASE) || !mcs_recv_cjcf(This)) goto error; - mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL); - if (!mcs_recv_cjcf(This)) + if (!mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL) || !mcs_recv_cjcf(This)) goto error; for (i = 0; i < This->num_channels; i++) { - mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL + 1 + i); - if (!mcs_recv_cjcf(This)) + if (!mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL + 1 + i) || !mcs_recv_cjcf(This)) goto error; } return True; diff --git a/reactos/base/applications/tsclient/rdesktop/orders.c b/reactos/base/applications/tsclient/rdesktop/orders.c index 517633a6662..2c336498d4e 100644 --- a/reactos/base/applications/tsclient/rdesktop/orders.c +++ b/reactos/base/applications/tsclient/rdesktop/orders.c @@ -545,7 +545,11 @@ process_polygon(RDPCLIENT * This, STREAM s, POLYGON_ORDER * os, uint32 present, return; } - points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT)); + points = (POINT *) malloc((os->npoints + 1) * sizeof(POINT)); + + if(points == NULL) + return; + memset(points, 0, (os->npoints + 1) * sizeof(POINT)); points[0].x = os->x; @@ -578,7 +582,7 @@ process_polygon(RDPCLIENT * This, STREAM s, POLYGON_ORDER * os, uint32 present, else error("polygon parse error\n"); - xfree(points); + free(points); } /* Process a polygon2 order */ @@ -635,7 +639,11 @@ process_polygon2(RDPCLIENT * This, STREAM s, POLYGON2_ORDER * os, uint32 present return; } - points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT)); + points = (POINT *) malloc((os->npoints + 1) * sizeof(POINT)); + + if(points == NULL) + return; + memset(points, 0, (os->npoints + 1) * sizeof(POINT)); points[0].x = os->x; @@ -668,7 +676,7 @@ process_polygon2(RDPCLIENT * This, STREAM s, POLYGON2_ORDER * os, uint32 present else error("polygon2 parse error\n"); - xfree(points); + free(points); } /* Process a polyline order */ @@ -717,7 +725,11 @@ process_polyline(RDPCLIENT * This, STREAM s, POLYLINE_ORDER * os, uint32 present return; } - points = (POINT *) xmalloc((os->lines + 1) * sizeof(POINT)); + points = (POINT *) malloc((os->lines + 1) * sizeof(POINT)); + + if(points == NULL) + return; + memset(points, 0, (os->lines + 1) * sizeof(POINT)); points[0].x = os->x; @@ -750,7 +762,7 @@ process_polyline(RDPCLIENT * This, STREAM s, POLYLINE_ORDER * os, uint32 present else error("polyline parse error\n"); - xfree(points); + free(points); } /* Process an ellipse order */ @@ -926,8 +938,7 @@ process_raw_bmpcache(RDPCLIENT * This, STREAM s) HBITMAP bitmap; uint16 cache_idx, bufsize; uint8 cache_id, width, height, bpp, Bpp; - uint8 *data, *inverted; - int y; + uint8 *data; in_uint8(s, cache_id); in_uint8s(s, 1); /* pad */ @@ -1000,7 +1011,10 @@ process_bmpcache(RDPCLIENT * This, STREAM s) DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d,bpp=%d,size=%d,pad1=%d,bufsize=%d,pad2=%d,rs=%d,fs=%d)\n", width, height, cache_id, cache_idx, bpp, size, pad1, bufsize, pad2, row_size, final_size)); - bmpdata = (uint8 *) xmalloc(width * height * Bpp); + bmpdata = (uint8 *) malloc(width * height * Bpp); + + if(bmpdata == NULL) + return; if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) { @@ -1012,7 +1026,7 @@ process_bmpcache(RDPCLIENT * This, STREAM s) DEBUG(("Failed to decompress bitmap data\n")); } - xfree(bmpdata); + free(bmpdata); } /* Process a bitmap cache v2 order */ @@ -1020,7 +1034,6 @@ static void process_bmpcache2(RDPCLIENT * This, STREAM s, uint16 flags, BOOL compressed) { HBITMAP bitmap; - int y; uint8 cache_id, cache_idx_low, width, height, Bpp; uint16 cache_idx, bufsize; uint8 *data, *bmpdata, *bitmap_id; @@ -1062,12 +1075,15 @@ process_bmpcache2(RDPCLIENT * This, STREAM s, uint16 flags, BOOL compressed) if (compressed) { - bmpdata = (uint8 *) xmalloc(width * height * Bpp); + bmpdata = (uint8 *) malloc(width * height * Bpp); + + if(bmpdata == NULL) + return; if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp)) { DEBUG(("Failed to decompress bitmap data\n")); - xfree(bmpdata); + free(bmpdata); return; } } @@ -1097,7 +1113,7 @@ process_bmpcache2(RDPCLIENT * This, STREAM s, uint16 flags, BOOL compressed) } if (compressed) - xfree(bmpdata); + free(bmpdata); } /* Process a colourmap cache order */ @@ -1113,7 +1129,13 @@ process_colcache(RDPCLIENT * This, STREAM s) in_uint8(s, cache_id); in_uint16_le(s, map.ncolours); - map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours); + map.colours = (COLOURENTRY *) malloc(sizeof(COLOURENTRY) * map.ncolours); + + if(map.colours == NULL) + { + in_uint8s(s, map.ncolours * 4); + return; + } for (i = 0; i < map.ncolours; i++) { @@ -1131,7 +1153,7 @@ process_colcache(RDPCLIENT * This, STREAM s) if (cache_id) ui_set_colourmap(This, hmap); - xfree(map.colours); + free(map.colours); } /* Process a font cache order */ diff --git a/reactos/base/applications/tsclient/rdesktop/parse.h b/reactos/base/applications/tsclient/rdesktop/parse.h index b7e4efedc24..68d189c68bb 100644 --- a/reactos/base/applications/tsclient/rdesktop/parse.h +++ b/reactos/base/applications/tsclient/rdesktop/parse.h @@ -72,8 +72,8 @@ typedef struct stream #else #define in_uint16_be(s,v) { v = *((s)->p++); next_be(s,v); } #define in_uint32_be(s,v) { in_uint16_be(s,v); next_be(s,v); next_be(s,v); } -#define out_uint16_be(s,v) { *((s)->p++) = ((v) >> 8) & 0xff; *((s)->p++) = (v) & 0xff; } -#define out_uint32_be(s,v) { out_uint16_be(s, ((v) >> 16) & 0xffff); out_uint16_be(s, (v) & 0xffff); } +#define out_uint16_be(s,v) { *((s)->p++) = (uint8)((v) >> 8) & 0xff; *((s)->p++) = (uint8)((v) & 0xff); } +#define out_uint32_be(s,v) { out_uint16_be(s, (uint16)(((v) >> 16) & 0xffff)); out_uint16_be(s, (uint16)((v) & 0xffff)); } #endif #ifndef B_ENDIAN_PREFERRED diff --git a/reactos/base/applications/tsclient/rdesktop/proto.h b/reactos/base/applications/tsclient/rdesktop/proto.h index 952f187194f..9cb37a59cb6 100644 --- a/reactos/base/applications/tsclient/rdesktop/proto.h +++ b/reactos/base/applications/tsclient/rdesktop/proto.h @@ -73,21 +73,21 @@ int get_current_workarea(RDPCLIENT * This, uint32 * x, uint32 * y, uint32 * widt void ewmh_init(RDPCLIENT * This); /* iso.c */ STREAM iso_init(RDPCLIENT * This, int length); -void iso_send(RDPCLIENT * This, STREAM s); +BOOL iso_send(RDPCLIENT * This, STREAM s); STREAM iso_recv(RDPCLIENT * This, uint8 * rdpver); -BOOL iso_connect(RDPCLIENT * This, char *server, char *username); -BOOL iso_reconnect(RDPCLIENT * This, char *server); -void iso_disconnect(RDPCLIENT * This); +BOOL iso_connect(RDPCLIENT * This, char *server, char *cookie); +BOOL iso_reconnect(RDPCLIENT * This, char *server, char *cookie); +BOOL iso_disconnect(RDPCLIENT * This); void iso_reset_state(RDPCLIENT * This); /* licence.c */ void licence_process(RDPCLIENT * This, STREAM s); /* mcs.c */ STREAM mcs_init(RDPCLIENT * This, int length); -void mcs_send_to_channel(RDPCLIENT * This, STREAM s, uint16 channel); -void mcs_send(RDPCLIENT * This, STREAM s); +BOOL mcs_send_to_channel(RDPCLIENT * This, STREAM s, uint16 channel); +BOOL mcs_send(RDPCLIENT * This, STREAM s); STREAM mcs_recv(RDPCLIENT * This, uint16 * channel, uint8 * rdpver); -BOOL mcs_connect(RDPCLIENT * This, char *server, STREAM mcs_data, char *username); -BOOL mcs_reconnect(RDPCLIENT * This, char *server, STREAM mcs_data); +BOOL mcs_connect(RDPCLIENT * This, char *server, char *cookie, STREAM mcs_data); +BOOL mcs_reconnect(RDPCLIENT * This, char *server, char *cookie, STREAM mcs_data); void mcs_disconnect(RDPCLIENT * This); void mcs_reset_state(RDPCLIENT * This); /* orders.c */ @@ -110,10 +110,6 @@ BOOL pstcache_init(RDPCLIENT * This, uint8 cache_id); /* rdesktop.c */ int main(int argc, char *argv[]); void generate_random(uint8 * random); -void *xmalloc(size_t size); -char *xstrdup(const char *s); -void *xrealloc(void *oldmem, size_t size); -void xfree(void *mem); void error(char *format, ...); void warning(char *format, ...); void unimpl(char *format, ...); @@ -134,13 +130,13 @@ int rd_write_file(int fd, void *ptr, int len); int rd_lseek_file(int fd, int offset); BOOL rd_lock_file(int fd, int start, int len); /* rdp5.c */ -void rdp5_process(RDPCLIENT * This, STREAM s); +BOOL rdp5_process(RDPCLIENT * This, STREAM s); /* rdp.c */ -void rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len); -int rdp_in_unistr(RDPCLIENT * This, STREAM s, char *string, int uni_len); -void rdp_send_input(RDPCLIENT * This, uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, +void rdp_out_unistr(RDPCLIENT * This, STREAM s, wchar_t *string, int len); +int rdp_in_unistr(RDPCLIENT * This, STREAM s, wchar_t *string, int uni_len); +BOOL rdp_send_input(RDPCLIENT * This, uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2); -void rdp_send_client_window_status(RDPCLIENT * This, int status); +BOOL rdp_send_client_window_status(RDPCLIENT * This, int status); void process_colour_pointer_pdu(RDPCLIENT * This, STREAM s); void process_cached_pointer_pdu(RDPCLIENT * This, STREAM s); void process_system_pointer_pdu(RDPCLIENT * This, STREAM s); @@ -149,10 +145,10 @@ void process_palette(RDPCLIENT * This, STREAM s); void process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason); void rdp_main_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason); BOOL rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason); -BOOL rdp_connect(RDPCLIENT * This, char *server, uint32 flags, char *domain, char *password, char *command, - char *directory); -BOOL rdp_reconnect(RDPCLIENT * This, char *server, uint32 flags, char *domain, char *password, char *command, - char *directory, char *cookie); +BOOL rdp_connect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password, wchar_t *command, + wchar_t *directory, wchar_t *hostname, char *cookie); +BOOL rdp_reconnect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password, wchar_t *command, + wchar_t *directory, wchar_t *hostname, char *cookie); void rdp_reset_state(RDPCLIENT * This); void rdp_disconnect(RDPCLIENT * This); #if 0 @@ -187,12 +183,12 @@ void sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, ui int datalen); void sec_decrypt(RDPCLIENT * This, uint8 * data, int length); STREAM sec_init(RDPCLIENT * This, uint32 flags, int maxlen); -void sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel); -void sec_send(RDPCLIENT * This, STREAM s, uint32 flags); +BOOL sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel); +BOOL sec_send(RDPCLIENT * This, STREAM s, uint32 flags); void sec_process_mcs_data(RDPCLIENT * This, STREAM s); STREAM sec_recv(RDPCLIENT * This, uint8 * rdpver); -BOOL sec_connect(RDPCLIENT * This, char *server, char *username); -BOOL sec_reconnect(RDPCLIENT * This, char *server); +BOOL sec_connect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie); +BOOL sec_reconnect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie); void sec_disconnect(RDPCLIENT * This); void sec_reset_state(RDPCLIENT * This); #if 0 @@ -203,11 +199,11 @@ BOOL serial_get_timeout(RDPCLIENT * This, NTHANDLE handle, uint32 length, uint32 #endif /* tcp.c */ STREAM tcp_init(RDPCLIENT * This, uint32 maxlen); -void tcp_send(RDPCLIENT * This, STREAM s); +BOOL tcp_send(RDPCLIENT * This, STREAM s); STREAM tcp_recv(RDPCLIENT * This, STREAM s, uint32 length); BOOL tcp_connect(RDPCLIENT * This, char *server); -void tcp_disconnect(RDPCLIENT * This); -char *tcp_get_address(RDPCLIENT * This); +BOOL tcp_disconnect(RDPCLIENT * This); +wchar_t *tcp_get_address(RDPCLIENT * This); void tcp_reset_state(RDPCLIENT * This); /* xclip.c */ void ui_clip_format_announce(RDPCLIENT * This, uint8 * data, uint32 length); @@ -245,7 +241,7 @@ BOOL ui_create_window(RDPCLIENT * This); void ui_resize_window(RDPCLIENT * This); void ui_destroy_window(RDPCLIENT * This); void xwin_toggle_fullscreen(RDPCLIENT * This); -int ui_select(RDPCLIENT * This, int rdp_socket); +int ui_select(RDPCLIENT * This, SOCKET rdp_socket); void ui_move_pointer(RDPCLIENT * This, int x, int y); HBITMAP ui_create_bitmap(RDPCLIENT * This, int width, int height, uint8 * data); void ui_paint_bitmap(RDPCLIENT * This, int x, int y, int cx, int cy, int width, int height, uint8 * data); @@ -313,6 +309,10 @@ void seamless_select_timeout(RDPCLIENT * This, struct timeval *tv); unsigned int seamless_send_zchange(RDPCLIENT * This, unsigned long id, unsigned long below, unsigned long flags); unsigned int seamless_send_focus(RDPCLIENT * This, unsigned long id, unsigned long flags); +/* events */ +int event_pubkey(RDPCLIENT * This, const unsigned char * key, size_t key_size); +void event_logon(RDPCLIENT * This); + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/reactos/base/applications/tsclient/rdesktop/pstcache.c b/reactos/base/applications/tsclient/rdesktop/pstcache.c index d0ed9626450..18b7fbd94fa 100644 --- a/reactos/base/applications/tsclient/rdesktop/pstcache.c +++ b/reactos/base/applications/tsclient/rdesktop/pstcache.c @@ -59,14 +59,18 @@ pstcache_load_bitmap(RDPCLIENT * This, uint8 cache_id, uint16 cache_idx) fd = This->pstcache_fd[cache_id]; rd_lseek_file(fd, cache_idx * (This->pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)); - celldata = (uint8 *) xmalloc(cellhdr.length); + celldata = (uint8 *) malloc(cellhdr.length); + + if(celldata == NULL) + return False; + rd_read_file(fd, celldata, cellhdr.length); bitmap = ui_create_bitmap(This, cellhdr.width, cellhdr.height, celldata); DEBUG(("Load bitmap from disk: id=%d, idx=%d, bmp=0x%x)\n", cache_id, cache_idx, bitmap)); cache_put_bitmap(This, cache_id, cache_idx, bitmap); - xfree(celldata); + free(celldata); return True; } diff --git a/reactos/base/applications/tsclient/rdesktop/rdesktop.h b/reactos/base/applications/tsclient/rdesktop/rdesktop.h index ce4ceb38b06..e173a669225 100644 --- a/reactos/base/applications/tsclient/rdesktop/rdesktop.h +++ b/reactos/base/applications/tsclient/rdesktop/rdesktop.h @@ -23,6 +23,7 @@ #endif #include +#include #include #if 0 @@ -191,23 +192,16 @@ typedef struct _seamless_window } seamless_window; #endif -typedef struct CHANNEL_PRIVATE_ -{ - int opened; - PCHANNEL_INIT_EVENT_FN pChannelInitEventProc; - PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc; -} -CHANNEL_PRIVATE; - /* holds the whole state of the RDP client */ struct rdpclient { /* channels.c */ CHANNEL_DEF channel_defs[CHANNEL_MAX_COUNT]; - CHANNEL_PRIVATE channel_data[CHANNEL_MAX_COUNT]; unsigned int num_channels; /* licence.c */ + char * licence_username; + char licence_hostname[MAX_COMPUTERNAME_LENGTH + 1]; BOOL licence_issued; /* mcs.c */ @@ -222,10 +216,7 @@ struct rdpclient BOOL pstcache_enumerated; /* rdesktop.c */ - char title[64]; - char username[64]; - char hostname[16]; - char keymapname[MAX_PATH]; + int disconnect_reason; unsigned int keylayout; int keyboard_type; int keyboard_subtype; @@ -233,17 +224,8 @@ struct rdpclient int width; int height; - int xpos; - int ypos; - int pos; /* 0 position unspecified, - 1 specified, - 2 xpos neg, - 4 ypos neg */ - int server_depth; - int win_button_size; /* If zero, disable single app mode */ BOOL bitmap_compression; - BOOL sendmotion; BOOL bitmap_cache; BOOL bitmap_cache_persist_enable; BOOL bitmap_cache_precache; @@ -251,27 +233,17 @@ struct rdpclient BOOL packet_encryption; BOOL desktop_save; /* desktop save order */ BOOL polygon_ellipse_orders; /* polygon / ellipse orders */ - BOOL fullscreen; - BOOL grab_keyboard; - BOOL hide_decorations; BOOL use_rdp5; - BOOL rdpclip; BOOL console_session; - BOOL numlock_sync; - BOOL lspci_enabled ; - BOOL owncolmap; - BOOL ownbackstore; /* We can't rely on external BackingStore */ - BOOL seamless_rdp; - uint32 embed_wnd; uint32 rdp5_performanceflags; /* Session Directory redirection */ BOOL redirect; - char redirect_server[64]; - char redirect_domain[16]; - char redirect_password[64]; - char redirect_username[64]; - char redirect_cookie[128]; + wchar_t * redirect_server; + wchar_t * redirect_domain; + wchar_t * redirect_password; + wchar_t * redirect_username; + char * redirect_cookie; uint32 redirect_flags; /* rdp.c */ @@ -319,7 +291,8 @@ struct rdpclient /* rdp.c */ struct rdp_ { - int ignore_; + int current_status; + #if WITH_DEBUG uint32 packetno; #endif @@ -355,269 +328,11 @@ struct rdpclient /* tcp.c */ struct tcp_ { - int sock; + SOCKET sock; struct stream in; struct stream out; } tcp; - -#if 0 - /* Public fields */ - /* disk.c */ -#define MAX_OPEN_FILES 0x100 - FILEINFO fileinfo[MAX_OPEN_FILES]; - BOOL notify_stamp; - - /* ewmhints.c */ - Atom net_wm_state_atom, net_wm_desktop_atom; - - /* rdpdr.c */ - /* If select() times out, the request for the device with handle min_timeout_fd is aborted */ - NTHANDLE min_timeout_fd; - uint32 num_devices; - - /* Table with information about rdpdr devices */ - RDPDR_DEVICE rdpdr_device[RDPDR_MAX_DEVICES]; - char *rdpdr_clientname; - - struct async_iorequest *iorequest; - - /* rdpsndXXX.c */ -#ifdef WITH_RDPSND - int dsp_fd; - BOOL dsp_busy; -#endif - -#if 0 - /* xwin.c */ - Display *display; - BOOL enable_compose; - BOOL Unobscured; /* used for screenblt */ - Time last_gesturetime; - Window wnd; -#endif - - /* Private fields */ - /* FIXME: it's not pretty to spill private fields this way. Use opaque pointers */ - /* cliprdr.c */ - struct cliprdr_ - { - VCHANNEL *channel; - uint8 *last_formats; - uint32 last_formats_length; - } - cliprdr; - - struct ewmhints_ - { - Atom state_maximized_vert_atom, state_maximized_horz_atom, - state_hidden_atom, name_atom, utf8_string_atom, - state_skip_taskbar_atom, state_skip_pager_atom, state_modal_atom; - } - ewmhints; - - /* rdpdr.c */ - struct rdpdr_ - { - VCHANNEL *channel; - } - rdpdr; - - /* rdpsnd.c */ - struct rdpsnd_ - { - VCHANNEL *channel; - - BOOL device_open; - -#define MAX_FORMATS 10 - WAVEFORMATEX formats[MAX_FORMATS]; - - unsigned int format_count; - unsigned int current_format; - } - rdpsnd; - - /* seamless.c */ - struct seamless_ - { - VCHANNEL *channel; - unsigned int serial; - } - seamless; - - /* xclip.c */ - struct xclip_ - { -#define MAX_TARGETS 8 - - /* Mode of operation. - - Auto: Look at both PRIMARY and CLIPBOARD and use the most recent. - - Non-auto: Look at just CLIPBOARD. */ - BOOL auto_mode; - /* Atoms of the two X selections we're dealing with: CLIPBOARD (explicit-copy) and PRIMARY (selection-copy) */ - Atom clipboard_atom, primary_atom; - /* Atom of the TARGETS clipboard target */ - Atom targets_atom; - /* Atom of the TIMESTAMP clipboard target */ - Atom timestamp_atom; - /* Atom _RDESKTOP_CLIPBOARD_TARGET which is used as the 'property' argument in - XConvertSelection calls: This is the property of our window into which - XConvertSelection will store the received clipboard data. */ - Atom rdesktop_clipboard_target_atom; - /* Atoms _RDESKTOP_PRIMARY_TIMESTAMP_TARGET and _RDESKTOP_CLIPBOARD_TIMESTAMP_TARGET - are used to store the timestamps for when a window got ownership of the selections. - We use these to determine which is more recent and should be used. */ - Atom rdesktop_primary_timestamp_target_atom, rdesktop_clipboard_timestamp_target_atom; - /* Storage for timestamps since we get them in two separate notifications. */ - Time primary_timestamp, clipboard_timestamp; - /* Clipboard target for getting a list of native Windows clipboard formats. The - presence of this target indicates that the selection owner is another rdesktop. */ - Atom rdesktop_clipboard_formats_atom; - /* The clipboard target (X jargon for "clipboard format") for rdesktop-to-rdesktop - interchange of Windows native clipboard data. The requestor must supply the - desired native Windows clipboard format in the associated property. */ - Atom rdesktop_native_atom; - /* Local copy of the list of native Windows clipboard formats. */ - uint8 *formats_data; - uint32 formats_data_length; - /* We need to know when another rdesktop process gets or loses ownership of a - selection. Without XFixes we do this by touching a property on the root window - which will generate PropertyNotify notifications. */ - Atom rdesktop_selection_notify_atom; - /* State variables that indicate if we're currently probing the targets of the - selection owner. reprobe_selections indicate that the ownership changed in - the middle of the current probe so it should be restarted. */ - BOOL probing_selections, reprobe_selections; - /* Atoms _RDESKTOP_PRIMARY_OWNER and _RDESKTOP_CLIPBOARD_OWNER. Used as properties - on the root window to indicate which selections that are owned by rdesktop. */ - Atom rdesktop_primary_owner_atom, rdesktop_clipboard_owner_atom; - Atom format_string_atom, format_utf8_string_atom, format_unicode_atom; - /* Atom of the INCR clipboard type (see ICCCM on "INCR Properties") */ - Atom incr_atom; - /* Stores the last "selection request" (= another X client requesting clipboard data from us). - To satisfy such a request, we request the clipboard data from the RDP server. - When we receive the response from the RDP server (asynchronously), this variable gives us - the context to proceed. */ - XSelectionRequestEvent selection_request; - /* Denotes we have a pending selection request. */ - Bool has_selection_request; - /* Stores the clipboard format (CF_TEXT, CF_UNICODETEXT etc.) requested in the last - CLIPDR_DATA_REQUEST (= the RDP server requesting clipboard data from us). - When we receive this data from whatever X client offering it, this variable gives us - the context to proceed. - */ - int rdp_clipboard_request_format; - /* Array of offered clipboard targets that will be sent to fellow X clients upon a TARGETS request. */ - Atom targets[MAX_TARGETS]; - int num_targets; - /* Denotes that an rdesktop (not this rdesktop) is owning the selection, - allowing us to interchange Windows native clipboard data directly. */ - BOOL rdesktop_is_selection_owner; - /* Time when we acquired the selection. */ - Time acquire_time; - - /* Denotes that an INCR ("chunked") transfer is in progress. */ - int waiting_for_INCR; - /* Denotes the target format of the ongoing INCR ("chunked") transfer. */ - Atom incr_target; - /* Buffers an INCR transfer. */ - uint8 *clip_buffer; - /* Denotes the size of clip_buffer. */ - uint32 clip_buflen; - } - xclip; - - /* xkeymap.c */ - struct xkeymap_ - { -#define KEYMAP_SIZE 0xffff+1 - BOOL keymap_loaded; - key_translation *keymap[KEYMAP_SIZE]; - int min_keycode; - uint16 remote_modifier_state; - uint16 saved_remote_modifier_state; - } - xkeymap; - -#if 0 - /* xwin.c */ - struct xwin_ - { - int x_socket; - Screen *screen; - - /* SeamlessRDP support */ - seamless_window *seamless_windows; - unsigned long seamless_focused; - BOOL seamless_started; /* Server end is up and running */ - BOOL seamless_active; /* We are currently in seamless mode */ - BOOL seamless_hidden; /* Desktop is hidden on server */ - - GC gc; - GC create_bitmap_gc; - GC create_glyph_gc; - XRectangle clip_rectangle; - Visual *visual; - /* Color depth of the X11 visual of our window (e.g. 24 for True Color R8G8B visual). - This may be 32 for R8G8B8 visuals, and then the rest of the bits are undefined - as far as we're concerned. */ - int depth; - /* Bits-per-Pixel of the pixmaps we'll be using to draw on our window. - This may be larger than depth, in which case some of the bits would - be kept solely for alignment (e.g. 32bpp pixmaps on a 24bpp visual). */ - int bpp; - XIM IM; - XIC IC; - XModifierKeymap *mod_map; - Cursor current_cursor; - HCURSOR null_cursor; - Atom protocol_atom, kill_atom; - BOOL focused; - BOOL mouse_in_wnd; - /* Indicates that: - 1) visual has 15, 16 or 24 depth and the same color channel masks - as its RDP equivalent (implies X server is LE), - 2) host is LE - This will trigger an optimization whose real value is questionable. - */ - BOOL compatible_arch; - /* Indicates whether RDP's bitmaps and our XImages have the same - binary format. If so, we can avoid an expensive translation. - Note that this can be true when compatible_arch is false, - e.g.: - - RDP(LE) <-> host(BE) <-> X-Server(LE) - - ('host' is the machine running rdesktop; the host simply memcpy's - so its endianess doesn't matter) - */ - BOOL no_translate_image; - - /* endianness */ - BOOL host_be; - BOOL xserver_be; - int red_shift_r, blue_shift_r, green_shift_r; - int red_shift_l, blue_shift_l, green_shift_l; - - /* software backing store */ - Pixmap backstore; - - /* Moving in single app mode */ - BOOL moving_wnd; - int move_x_offset; - int move_y_offset; - BOOL using_full_workarea; - - /* colour maps */ - Colormap xcolmap; - uint32 *colmap; - - XErrorHandler old_error_handler; - } - xwin; -#endif -#endif }; #ifndef MAKE_PROTO diff --git a/reactos/base/applications/tsclient/rdesktop/rdp.c b/reactos/base/applications/tsclient/rdesktop/rdp.c index 427714a97e3..97b61c1012a 100644 --- a/reactos/base/applications/tsclient/rdesktop/rdp.c +++ b/reactos/base/applications/tsclient/rdesktop/rdp.c @@ -35,9 +35,9 @@ /* Receive an RDP packet */ static STREAM -rdp_recv(RDPCLIENT * This, uint8 * type) +rdp_recv(RDPCLIENT * This, uint8 * type) // EXITS { - static STREAM rdp_s; + static STREAM rdp_s; // FIXME HORROR uint16 length, pdu_type; uint8 rdpver; @@ -55,7 +55,8 @@ rdp_recv(RDPCLIENT * This, uint8 * type) else if (rdpver != 3) { /* rdp5_process should move This->next_packet ok */ - rdp5_process(This, rdp_s); + if(!rdp5_process(This, rdp_s)) + return NULL; *type = 0; return rdp_s; } @@ -95,19 +96,23 @@ rdp_init_data(RDPCLIENT * This, int maxlen) STREAM s; s = sec_init(This, This->encryption ? SEC_ENCRYPT : 0, maxlen + 18); + + if(s == NULL) + return NULL; + s_push_layer(s, rdp_hdr, 18); return s; } /* Send an RDP data packet */ -static void +static BOOL rdp_send_data(RDPCLIENT * This, STREAM s, uint8 data_pdu_type) { uint16 length; s_pop_layer(s, rdp_hdr); - length = s->end - s->p; + length = (uint16)(s->end - s->p); out_uint16_le(s, length); out_uint16_le(s, (RDP_PDU_DATA | 0x10)); @@ -121,12 +126,12 @@ rdp_send_data(RDPCLIENT * This, STREAM s, uint8 data_pdu_type) out_uint8(s, 0); /* compress_type */ out_uint16(s, 0); /* compress_len */ - sec_send(This, s, This->encryption ? SEC_ENCRYPT : 0); + return sec_send(This, s, This->encryption ? SEC_ENCRYPT : 0); } /* Output a string in Unicode */ void -rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len) +rdp_out_unistr(RDPCLIENT * This, STREAM s, wchar_t *string, int len) { #ifdef HAVE_ICONV size_t ibl = strlen(string), obl = len + 2; @@ -180,6 +185,7 @@ rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len) } else #endif + // TODO { int i = 0, j = 0; @@ -187,8 +193,9 @@ rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len) while (i < len) { - s->p[i++] = string[j++]; - s->p[i++] = 0; + int c = string[j++]; + s->p[i++] = (c >> 0) & 0xFF; + s->p[i++] = (c >> 8) & 0xFF; } s->p += len; @@ -200,7 +207,7 @@ rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len) * Returns str_len of string */ int -rdp_in_unistr(RDPCLIENT * This, STREAM s, char *string, int uni_len) +rdp_in_unistr(RDPCLIENT * This, STREAM s, wchar_t *string, int uni_len) { #ifdef HAVE_ICONV size_t ibl = uni_len, obl = uni_len; @@ -238,6 +245,7 @@ rdp_in_unistr(RDPCLIENT * This, STREAM s, char *string, int uni_len) } else #endif + // TODO { int i = 0; @@ -253,18 +261,18 @@ rdp_in_unistr(RDPCLIENT * This, STREAM s, char *string, int uni_len) /* Parse a logon info packet */ -static void -rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user, - char *password, char *program, char *directory) +static BOOL +rdp_send_logon_info(RDPCLIENT * This, uint32 flags, wchar_t *domain, wchar_t *user, + wchar_t *password, wchar_t *program, wchar_t *directory) { - char *ipaddr = tcp_get_address(This); - int len_domain = 2 * strlen(domain); - int len_user = 2 * strlen(user); - int len_password = 2 * strlen(password); - int len_program = 2 * strlen(program); - int len_directory = 2 * strlen(directory); - int len_ip = 2 * strlen(ipaddr); - int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll"); + wchar_t *ipaddr = tcp_get_address(This); + int len_domain = 2 * (int)wcslen(domain); + int len_user = 2 * (int)wcslen(user); + int len_password = 2 * (int)wcslen(password); + int len_program = 2 * (int)wcslen(program); + int len_directory = 2 * (int)wcslen(directory); + int len_ip = 2 * (int)wcslen(ipaddr); + int len_dll = 2 * (int)wcslen(L"C:\\WINNT\\System32\\mstscax.dll"); int packetlen = 0; uint32 sec_flags = This->encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO; STREAM s; @@ -278,6 +286,9 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user, s = sec_init(This, sec_flags, 18 + len_domain + len_user + len_password + len_program + len_directory + 10); + if(s == NULL) + return False; + out_uint32(s, 0); out_uint32_le(s, flags); out_uint16_le(s, len_domain); @@ -322,6 +333,9 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user, s = sec_init(This, sec_flags, packetlen); DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen)); + if(s == NULL) + return False; + out_uint32(s, 0); /* Unknown */ out_uint32_le(s, flags); out_uint16_le(s, len_domain); @@ -371,13 +385,13 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user, out_uint16_le(s, len_ip + 2); /* Length of client ip */ rdp_out_unistr(This, s, ipaddr, len_ip); out_uint16_le(s, len_dll + 2); - rdp_out_unistr(This, s, "C:\\WINNT\\System32\\mstscax.dll", len_dll); + rdp_out_unistr(This, s, L"C:\\WINNT\\System32\\mstscax.dll", len_dll); tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60; - out_uint32_le(s, tzone); + out_uint32_le(s, (uint32)tzone); - rdp_out_unistr(This, s, "GTB, normaltid", 2 * strlen("GTB, normaltid")); - out_uint8s(s, 62 - 2 * strlen("GTB, normaltid")); + rdp_out_unistr(This, s, L"GTB, normaltid", 2 * (int)wcslen(L"GTB, normaltid")); + out_uint8s(s, 62 - 2 * wcslen(L"GTB, normaltid")); out_uint32_le(s, 0x0a0000); out_uint32_le(s, 0x050000); @@ -385,8 +399,8 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user, out_uint32_le(s, 0); out_uint32_le(s, 0); - rdp_out_unistr(This, s, "GTB, sommartid", 2 * strlen("GTB, sommartid")); - out_uint8s(s, 62 - 2 * strlen("GTB, sommartid")); + rdp_out_unistr(This, s, L"GTB, sommartid", 2 * (int)wcslen(L"GTB, sommartid")); + out_uint8s(s, 62 - 2 * wcslen(L"GTB, sommartid")); out_uint32_le(s, 0x30000); out_uint32_le(s, 0x050000); @@ -400,48 +414,57 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user, } s_mark_end(s); - sec_send(This, s, sec_flags); + return sec_send(This, s, sec_flags); } /* Send a control PDU */ -static void +static BOOL rdp_send_control(RDPCLIENT * This, uint16 action) { STREAM s; s = rdp_init_data(This, 8); + if(s == NULL) + return False; + out_uint16_le(s, action); out_uint16(s, 0); /* userid */ out_uint32(s, 0); /* control id */ s_mark_end(s); - rdp_send_data(This, s, RDP_DATA_PDU_CONTROL); + return rdp_send_data(This, s, RDP_DATA_PDU_CONTROL); } /* Send a synchronisation PDU */ -static void +static BOOL rdp_send_synchronise(RDPCLIENT * This) { STREAM s; s = rdp_init_data(This, 4); + if(s == NULL) + return False; + out_uint16_le(s, 1); /* type */ out_uint16_le(s, 1002); s_mark_end(s); - rdp_send_data(This, s, RDP_DATA_PDU_SYNCHRONISE); + return rdp_send_data(This, s, RDP_DATA_PDU_SYNCHRONISE); } /* Send a single input event */ -void +BOOL rdp_send_input(RDPCLIENT * This, uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2) { STREAM s; s = rdp_init_data(This, 16); + if(s == NULL) + return False; + out_uint16_le(s, 1); /* number of events */ out_uint16(s, 0); /* pad */ @@ -452,21 +475,23 @@ rdp_send_input(RDPCLIENT * This, uint32 time, uint16 message_type, uint16 device out_uint16_le(s, param2); s_mark_end(s); - rdp_send_data(This, s, RDP_DATA_PDU_INPUT); + return rdp_send_data(This, s, RDP_DATA_PDU_INPUT); } /* Send a client window information PDU */ -void +BOOL rdp_send_client_window_status(RDPCLIENT * This, int status) { STREAM s; - static int current_status = 1; - if (current_status == status) - return; + if (This->rdp.current_status == status) + return True; s = rdp_init_data(This, 12); + if(s == NULL) + return False; + out_uint32_le(s, status); switch (status) @@ -482,13 +507,13 @@ rdp_send_client_window_status(RDPCLIENT * This, int status) } s_mark_end(s); - rdp_send_data(This, s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS); - current_status = status; + This->rdp.current_status = status; + return rdp_send_data(This, s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS); } /* Send persistent bitmap cache enumeration PDU's */ -static void -rdp_enum_bmpcache2(RDPCLIENT * This) +static BOOL +rdp_enum_bmpcache2(RDPCLIENT * This) // THIS { STREAM s; HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS]; @@ -503,6 +528,9 @@ rdp_enum_bmpcache2(RDPCLIENT * This) s = rdp_init_data(This, 24 + count * sizeof(HASH_KEY)); + if(s == NULL) + return False; + flags = 0; if (offset == 0) flags |= PDU_FLAG_FIRST; @@ -524,27 +552,33 @@ rdp_enum_bmpcache2(RDPCLIENT * This) out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY)); s_mark_end(s); - rdp_send_data(This, s, 0x2b); + if(!rdp_send_data(This, s, 0x2b)) + return False; offset += 169; } + + return True; } /* Send an (empty) font information PDU */ -static void +static BOOL rdp_send_fonts(RDPCLIENT * This, uint16 seq) { STREAM s; s = rdp_init_data(This, 8); + if(s == NULL) + return False; + out_uint16(s, 0); /* number of fonts */ out_uint16_le(s, 0); /* pad? */ out_uint16_le(s, seq); /* unknown */ out_uint16_le(s, 0x32); /* entry size */ s_mark_end(s); - rdp_send_data(This, s, RDP_DATA_PDU_FONT2); + return rdp_send_data(This, s, RDP_DATA_PDU_FONT2); } /* Output general capability set */ @@ -777,7 +811,7 @@ rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, const uint8 * caps) #define RDP5_FLAG 0x0030 /* Send a confirm active PDU */ -static void +static BOOL rdp_send_confirm_active(RDPCLIENT * This) { STREAM s; @@ -792,6 +826,9 @@ rdp_send_confirm_active(RDPCLIENT * This) s = sec_init(This, sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE)); + if(s == NULL) + return False; + out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE)); out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */ out_uint16_le(s, (This->mcs_userid + 1001)); @@ -821,7 +858,7 @@ rdp_send_confirm_active(RDPCLIENT * This) rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */ s_mark_end(s); - sec_send(This, s, sec_flags); + return sec_send(This, s, sec_flags); } /* Process a general capability set */ @@ -910,8 +947,8 @@ rdp_process_server_caps(RDPCLIENT * This, STREAM s, uint16 length) } /* Respond to a demand active PDU */ -static void -process_demand_active(RDPCLIENT * This, STREAM s) +static BOOL +process_demand_active(RDPCLIENT * This, STREAM s) // EXITS { uint8 type; uint16 len_src_descriptor, len_combined_caps; @@ -924,29 +961,36 @@ process_demand_active(RDPCLIENT * This, STREAM s) DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", This->rdp_shareid)); rdp_process_server_caps(This, s, len_combined_caps); - rdp_send_confirm_active(This); - rdp_send_synchronise(This); - rdp_send_control(This, RDP_CTL_COOPERATE); - rdp_send_control(This, RDP_CTL_REQUEST_CONTROL); - rdp_recv(This, &type); /* RDP_PDU_SYNCHRONIZE */ - rdp_recv(This, &type); /* RDP_CTL_COOPERATE */ - rdp_recv(This, &type); /* RDP_CTL_GRANT_CONTROL */ - rdp_send_input(This, 0, RDP_INPUT_SYNCHRONIZE, 0, - /*This->numlock_sync ? ui_get_numlock_state(This, read_keyboard_state(This)) :*/ 0, 0); // TODO: keyboard mess + if + ( + !rdp_send_confirm_active(This) || + !rdp_send_synchronise(This) || + !rdp_send_control(This, RDP_CTL_COOPERATE) || + !rdp_send_control(This, RDP_CTL_REQUEST_CONTROL) || + !rdp_recv(This, &type) || /* RDP_PDU_SYNCHRONIZE */ + !rdp_recv(This, &type) || /* RDP_CTL_COOPERATE */ + !rdp_recv(This, &type) || /* RDP_CTL_GRANT_CONTROL */ + !rdp_send_input(This, 0, RDP_INPUT_SYNCHRONIZE, 0, + /*This->numlock_sync ? ui_get_numlock_state(This, read_keyboard_state(This)) :*/ 0, 0) // TODO: keyboard mess + ) + return False; if (This->use_rdp5) { - rdp_enum_bmpcache2(This); - rdp_send_fonts(This, 3); + if(!rdp_enum_bmpcache2(This) || !rdp_send_fonts(This, 3)) + return False; } else { - rdp_send_fonts(This, 1); - rdp_send_fonts(This, 2); + if(!rdp_send_fonts(This, 1) || !rdp_send_fonts(This, 2)) + return False; } - rdp_recv(This, &type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */ + if(!rdp_recv(This, &type)) /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */ + return False; + reset_order_state(This); + return True; } /* Process a colour pointer PDU */ @@ -1037,7 +1081,7 @@ process_pointer_pdu(RDPCLIENT * This, STREAM s) /* Process bitmap updates */ void -process_bitmap_updates(RDPCLIENT * This, STREAM s) +process_bitmap_updates(RDPCLIENT * This, STREAM s) // EXITS { uint16 num_updates; uint16 left, top, right, bottom, width, height; @@ -1097,7 +1141,11 @@ process_bitmap_updates(RDPCLIENT * This, STREAM s) in_uint8s(s, 4); /* line_size, final_size */ } in_uint8p(s, data, size); - bmpdata = (uint8 *) xmalloc(width * height * Bpp); + bmpdata = (uint8 *) malloc(width * height * Bpp); + + if(bmpdata == NULL) + return; + if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) { ui_paint_bitmap(This, left, top, cx, cy, width, height, bmpdata); @@ -1107,13 +1155,13 @@ process_bitmap_updates(RDPCLIENT * This, STREAM s) DEBUG_RDP5(("Failed to decompress data\n")); } - xfree(bmpdata); + free(bmpdata); } } /* Process a palette update */ void -process_palette(RDPCLIENT * This, STREAM s) +process_palette(RDPCLIENT * This, STREAM s) // EXITS { COLOURENTRY *entry; COLOURMAP map; @@ -1124,7 +1172,13 @@ process_palette(RDPCLIENT * This, STREAM s) in_uint16_le(s, map.ncolours); in_uint8s(s, 2); /* pad */ - map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours); + map.colours = (COLOURENTRY *) malloc(sizeof(COLOURENTRY) * map.ncolours); + + if(map.colours == NULL) + { + in_uint8s(s, sizeof(*entry) * map.ncolours); + return; + } DEBUG(("PALETTE(c=%d)\n", map.ncolours)); @@ -1139,7 +1193,7 @@ process_palette(RDPCLIENT * This, STREAM s) hmap = ui_create_colourmap(This, &map); ui_set_colourmap(This, hmap); - xfree(map.colours); + free(map.colours); } /* Process an update PDU */ @@ -1188,7 +1242,7 @@ process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason) /* Process data PDU */ static BOOL -process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason) +process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason) // EXITS { uint8 data_pdu_type; uint8 ctype; @@ -1208,6 +1262,8 @@ process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason) if (ctype & RDP_MPPC_COMPRESSED) { + void * p; + if (len > RDP_MPPC_DICT_SIZE) error("error decompressed packet size exceeds max\n"); if (mppc_expand(This, s->p, clen, ctype, &roff, &rlen) == -1) @@ -1216,7 +1272,15 @@ process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason) /* len -= 18; */ /* allocate memory and copy the uncompressed data into the temporary stream */ - ns->data = (uint8 *) xrealloc(ns->data, rlen); + p = realloc(ns->data, rlen); + + if(p == NULL) + { + This->disconnect_reason = 262; + return True; + } + + ns->data = (uint8 *) p; memcpy((ns->data), (unsigned char *) (This->mppc_dict.hist + roff), rlen); @@ -1252,6 +1316,7 @@ process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason) case RDP_DATA_PDU_LOGON: DEBUG(("Received Logon PDU\n")); + event_logon(This); /* User logged on */ break; @@ -1277,6 +1342,8 @@ process_redirect_pdu(RDPCLIENT * This, STREAM s /*, uint32 * ext_disc_reason */ { uint32 len; + // FIXME!!! allocate the strings used here + /* these 2 bytes are unknown, seem to be zeros */ in_uint8s(s, 2); @@ -1330,7 +1397,7 @@ rdp_main_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason) /* used in uiports and rdp_main_loop, processes the rdp packets waiting */ BOOL -rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason) +rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason) // EXITS { uint8 type; BOOL disc = False; /* True when a disconnect PDU was received */ @@ -1345,7 +1412,8 @@ rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason) switch (type) { case RDP_PDU_DEMAND_ACTIVE: - process_demand_active(This, s); + if(!process_demand_active(This, s)) + return False; *deactivated = False; break; case RDP_PDU_DEACTIVATE: @@ -1372,25 +1440,25 @@ rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason) /* Establish a connection up to the RDP layer */ BOOL -rdp_connect(RDPCLIENT * This, char *server, uint32 flags, char *domain, char *password, - char *command, char *directory) +rdp_connect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password, + wchar_t *command, wchar_t *directory, wchar_t *hostname, char *cookie) // EXITS { - if (!sec_connect(This, server, This->username)) + if (!sec_connect(This, server, hostname, cookie)) return False; - rdp_send_logon_info(This, flags, domain, This->username, password, command, directory); + rdp_send_logon_info(This, flags, domain, username, password, command, directory); return True; } /* Establish a reconnection up to the RDP layer */ BOOL -rdp_reconnect(RDPCLIENT * This, char *server, uint32 flags, char *domain, char *password, - char *command, char *directory, char *cookie) +rdp_reconnect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password, + wchar_t *command, wchar_t *directory, wchar_t *hostname, char *cookie) // EXITS { - if (!sec_reconnect(This, server)) + if (!sec_reconnect(This, server, hostname, cookie)) return False; - rdp_send_logon_info(This, flags, domain, This->username, password, command, directory); + rdp_send_logon_info(This, flags, domain, username, password, command, directory); return True; } diff --git a/reactos/base/applications/tsclient/rdesktop/rdp5.c b/reactos/base/applications/tsclient/rdesktop/rdp5.c index 37249567a33..cd1a060ad4b 100644 --- a/reactos/base/applications/tsclient/rdesktop/rdp5.c +++ b/reactos/base/applications/tsclient/rdesktop/rdp5.c @@ -21,7 +21,7 @@ #include "rdesktop.h" -void +BOOL rdp5_process(RDPCLIENT * This, STREAM s) { uint16 length, count, x, y; @@ -56,11 +56,21 @@ rdp5_process(RDPCLIENT * This, STREAM s) if (ctype & RDP_MPPC_COMPRESSED) { + void * p; + if (mppc_expand(This, s->p, length, ctype, &roff, &rlen) == -1) error("error while decompressing packet\n"); /* allocate memory and copy the uncompressed data into the temporary stream */ - ns->data = (uint8 *) xrealloc(ns->data, rlen); + p = realloc(ns->data, rlen); + + if(p == NULL) + { + This->disconnect_reason = 262; + return False; + } + + ns->data = (uint8 *) p; memcpy((ns->data), (unsigned char *) (This->mppc_dict.hist + roff), rlen); @@ -114,4 +124,5 @@ rdp5_process(RDPCLIENT * This, STREAM s) s->p = next; } ui_end_update(This); + return True; } diff --git a/reactos/base/applications/tsclient/rdesktop/secure.c b/reactos/base/applications/tsclient/rdesktop/secure.c index 665f6fa7e1e..491f51f3be9 100644 --- a/reactos/base/applications/tsclient/rdesktop/secure.c +++ b/reactos/base/applications/tsclient/rdesktop/secure.c @@ -290,7 +290,7 @@ sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * m BN_mod_exp(&y, &x, &exp, &mod, ctx); outlen = BN_bn2bin(&y, out); reverse(out, outlen); - if (outlen < modulus_size) + if ((uint32)outlen < modulus_size) memset(out + outlen, 0, modulus_size - outlen); BN_free(&y); @@ -312,6 +312,10 @@ sec_init(RDPCLIENT * This, uint32 flags, int maxlen) else hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0; s = mcs_init(This, maxlen + hdrlen); + + if(s == NULL) + return s; + s_push_layer(s, sec_hdr, hdrlen); return s; @@ -320,7 +324,7 @@ sec_init(RDPCLIENT * This, uint32 flags, int maxlen) /* Transmit secure transport packet over specified channel */ // !!! we need a lock here !!! -void +BOOL sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel) { int datalen; @@ -332,7 +336,7 @@ sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel) if (flags & SEC_ENCRYPT) { flags &= ~SEC_ENCRYPT; - datalen = s->end - s->p - 8; + datalen = (int)(s->end - s->p - 8); #if WITH_DEBUG DEBUG(("Sending encrypted packet:\n")); @@ -343,15 +347,15 @@ sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel) sec_encrypt(This, s->p + 8, datalen); } - mcs_send_to_channel(This, s, channel); + return mcs_send_to_channel(This, s, channel); } /* Transmit secure transport packet */ -void +BOOL sec_send(RDPCLIENT * This, STREAM s, uint32 flags) { - sec_send_to_channel(This, s, flags, MCS_GLOBAL_CHANNEL); + return sec_send_to_channel(This, s, flags, MCS_GLOBAL_CHANNEL); } @@ -375,9 +379,9 @@ sec_establish_key(RDPCLIENT * This) /* Output connect initial data blob */ static void -sec_out_mcs_data(RDPCLIENT * This, STREAM s) +sec_out_mcs_data(RDPCLIENT * This, STREAM s, wchar_t * hostname) { - int hostlen = 2 * strlen(This->hostname); + int hostlen = 2 * (int)wcslen(hostname); int length = 158 + 76 + 12 + 4; unsigned int i; @@ -417,7 +421,7 @@ sec_out_mcs_data(RDPCLIENT * This, STREAM s) out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */ /* Unicode name of client, padded to 32 bytes */ - rdp_out_unistr(This, s, This->hostname, hostlen); + rdp_out_unistr(This, s, hostname, hostlen); out_uint8s(s, 30 - hostlen); /* See @@ -607,6 +611,7 @@ sec_parse_crypt_info(RDPCLIENT * This, STREAM s, uint32 * rc4_key_size, if (certcount < 2) { error("Server didn't send enough X509 certificates\n"); + This->disconnect_reason = 1798; return False; } @@ -649,6 +654,7 @@ sec_parse_crypt_info(RDPCLIENT * This, STREAM s, uint32 * rc4_key_size, if (NULL == cacert) { error("Couldn't load CA Certificate from server\n"); + This->disconnect_reason = 1798; return False; } @@ -670,6 +676,7 @@ sec_parse_crypt_info(RDPCLIENT * This, STREAM s, uint32 * rc4_key_size, if (NULL == server_cert) { error("Couldn't load Certificate from server\n"); + This->disconnect_reason = 1798; return False; } @@ -683,6 +690,7 @@ sec_parse_crypt_info(RDPCLIENT * This, STREAM s, uint32 * rc4_key_size, { DEBUG_RDP5(("Didn't parse X509 correctly\n")); X509_free(server_cert); + This->disconnect_reason = 1798; return False; } X509_free(server_cert); @@ -822,7 +830,7 @@ sec_recv(RDPCLIENT * This, uint8 * rdpver) if (*rdpver & 0x80) { in_uint8s(s, 8); /* signature */ - sec_decrypt(This, s->p, s->end - s->p); + sec_decrypt(This, s->p, (int)(s->end - s->p)); } return s; } @@ -834,7 +842,7 @@ sec_recv(RDPCLIENT * This, uint8 * rdpver) if (sec_flags & SEC_ENCRYPT) { in_uint8s(s, 8); /* signature */ - sec_decrypt(This, s->p, s->end - s->p); + sec_decrypt(This, s->p, (int)(s->end - s->p)); } if (sec_flags & SEC_LICENCE_NEG) @@ -848,7 +856,7 @@ sec_recv(RDPCLIENT * This, uint8 * rdpver) uint8 swapbyte; in_uint8s(s, 8); /* signature */ - sec_decrypt(This, s->p, s->end - s->p); + sec_decrypt(This, s->p, (int)(s->end - s->p)); /* Check for a redirect packet, starts with 00 04 */ if (s->p[0] == 0 && s->p[1] == 4) @@ -894,43 +902,57 @@ sec_recv(RDPCLIENT * This, uint8 * rdpver) /* Establish a secure connection */ BOOL -sec_connect(RDPCLIENT * This, char *server, char *username) +sec_connect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie) // EXITS { struct stream mcs_data; + void * p = malloc(512); + + if(p == NULL) + { + This->disconnect_reason = 262; + return False; + } /* We exchange some RDP data during the MCS-Connect */ mcs_data.size = 512; - mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size); - sec_out_mcs_data(This, &mcs_data); + mcs_data.p = mcs_data.data = (uint8 *) p; + sec_out_mcs_data(This, &mcs_data, hostname); - if (!mcs_connect(This, server, &mcs_data, username)) + if (!mcs_connect(This, server, cookie, &mcs_data)) return False; /* sec_process_mcs_data(&mcs_data); */ if (This->encryption) sec_establish_key(This); - xfree(mcs_data.data); + free(mcs_data.data); return True; } /* Establish a secure connection */ BOOL -sec_reconnect(RDPCLIENT * This, char *server) +sec_reconnect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie) // EXITS { struct stream mcs_data; + void * p = malloc(512); + + if(p == NULL) + { + This->disconnect_reason = 262; + return False; + } /* We exchange some RDP data during the MCS-Connect */ mcs_data.size = 512; - mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size); - sec_out_mcs_data(This, &mcs_data); + mcs_data.p = mcs_data.data = (uint8 *) p; + sec_out_mcs_data(This, &mcs_data, hostname); - if (!mcs_reconnect(This, server, &mcs_data)) + if (!mcs_reconnect(This, server, cookie, &mcs_data)) return False; /* sec_process_mcs_data(&mcs_data); */ if (This->encryption) sec_establish_key(This); - xfree(mcs_data.data); + free(mcs_data.data); return True; } diff --git a/reactos/base/applications/tsclient/rdesktop/tcp.c b/reactos/base/applications/tsclient/rdesktop/tcp.c index 8d03272f9d8..f743033aa41 100644 --- a/reactos/base/applications/tsclient/rdesktop/tcp.c +++ b/reactos/base/applications/tsclient/rdesktop/tcp.c @@ -44,7 +44,17 @@ tcp_init(RDPCLIENT * This, uint32 maxlen) { if (maxlen > This->tcp.out.size) { - This->tcp.out.data = (uint8 *) xrealloc(This->tcp.out.data, maxlen); + void * p; + + p = realloc(This->tcp.out.data, maxlen); + + if (p == NULL) + { + This->disconnect_reason = 262; + return NULL; + } + + This->tcp.out.data = (uint8 *)p; This->tcp.out.size = maxlen; } @@ -54,10 +64,10 @@ tcp_init(RDPCLIENT * This, uint32 maxlen) } /* Send TCP transport data packet */ -void +BOOL tcp_send(RDPCLIENT * This, STREAM s) { - int length = s->end - s->data; + int length = (int)(s->end - s->data); int sent, total = 0; while (total < length) @@ -66,11 +76,14 @@ tcp_send(RDPCLIENT * This, STREAM s) if (sent <= 0) { // error("send: %s\n", strerror(errno)); // EOF - return; + This->disconnect_reason = 772; + return False; } total += sent; } + + return True; } /* Receive a message on the TCP layer */ @@ -85,7 +98,15 @@ tcp_recv(RDPCLIENT * This, STREAM s, uint32 length) /* read into "new" stream */ if (length > This->tcp.in.size) { - This->tcp.in.data = (uint8 *) xrealloc(This->tcp.in.data, length); + void * p = realloc(This->tcp.in.data, length); + + if(p == NULL) + { + This->disconnect_reason = 262; + return NULL; + } + + This->tcp.in.data = (uint8 *) p; This->tcp.in.size = length; } This->tcp.in.end = This->tcp.in.p = This->tcp.in.data; @@ -94,12 +115,20 @@ tcp_recv(RDPCLIENT * This, STREAM s, uint32 length) else { /* append to existing stream */ - new_length = (s->end - s->data) + length; + new_length = (unsigned int)(s->end - s->data) + length; if (new_length > s->size) { - p_offset = s->p - s->data; - end_offset = s->end - s->data; - s->data = (uint8 *) xrealloc(s->data, new_length); + void * p = realloc(s->data, new_length); + + if(p == NULL) + { + This->disconnect_reason = 262; + return NULL; + } + + p_offset = (unsigned int)(s->p - s->data); + end_offset = (unsigned int)(s->end - s->data); + s->data = (uint8 *) p; s->size = new_length; s->p = s->data + p_offset; s->end = s->data + end_offset; @@ -116,11 +145,13 @@ tcp_recv(RDPCLIENT * This, STREAM s, uint32 length) if (rcvd < 0) { // error("recv: %s\n", strerror(errno)); // EOF + This->disconnect_reason = 1028; return NULL; } else if (rcvd == 0) { error("Connection closed\n"); + This->disconnect_reason = 2308; return NULL; } @@ -189,6 +220,7 @@ tcp_connect(RDPCLIENT * This, char *server) else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE) { error("%s: unable to resolve host\n", server); + This->disconnect_reason = 260; return False; } @@ -204,7 +236,8 @@ tcp_connect(RDPCLIENT * This, char *server) if (connect(This->tcp.sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0) { // error("connect: %s\n", strerror(errno)); // EOF - close(This->tcp.sock); + This->disconnect_reason = 516; + closesocket(This->tcp.sock); return False; } @@ -213,24 +246,38 @@ tcp_connect(RDPCLIENT * This, char *server) setsockopt(This->tcp.sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true_value, sizeof(true_value)); This->tcp.in.size = 4096; - This->tcp.in.data = (uint8 *) xmalloc(This->tcp.in.size); + This->tcp.in.data = (uint8 *) malloc(This->tcp.in.size); + + if(This->tcp.in.data == NULL) + { + This->disconnect_reason = 262; + return False; + } This->tcp.out.size = 4096; - This->tcp.out.data = (uint8 *) xmalloc(This->tcp.out.size); + This->tcp.out.data = (uint8 *) malloc(This->tcp.out.size); + + if(This->tcp.out.data == NULL) + { + This->disconnect_reason = 262; + return False; + } return True; } /* Disconnect on the TCP layer */ -void +BOOL tcp_disconnect(RDPCLIENT * This) { - close(This->tcp.sock); + closesocket(This->tcp.sock); + return True; } -char * +wchar_t * tcp_get_address(RDPCLIENT * This) { +#if 0 static char ipaddr[32]; struct sockaddr_in sockaddr; socklen_t len = sizeof(sockaddr); @@ -242,6 +289,8 @@ tcp_get_address(RDPCLIENT * This) else strcpy(ipaddr, "127.0.0.1"); return ipaddr; +#endif + return NULL; // TODO } /* reset the state of the tcp layer */ @@ -253,7 +302,7 @@ tcp_reset_state(RDPCLIENT * This) /* Clear the incoming stream */ if (This->tcp.in.data != NULL) - xfree(This->tcp.in.data); + free(This->tcp.in.data); This->tcp.in.p = NULL; This->tcp.in.end = NULL; This->tcp.in.data = NULL; @@ -266,7 +315,7 @@ tcp_reset_state(RDPCLIENT * This) /* Clear the outgoing stream */ if (This->tcp.out.data != NULL) - xfree(This->tcp.out.data); + free(This->tcp.out.data); This->tcp.out.p = NULL; This->tcp.out.end = NULL; This->tcp.out.data = NULL;