libfreerdp-core: more tsg in/out channel refactoring
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 12 Feb 2015 19:08:38 +0000 (14:08 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 12 Feb 2015 19:08:38 +0000 (14:08 -0500)
libfreerdp/core/gateway/ncacn_http.c
libfreerdp/core/gateway/rpc.c
libfreerdp/core/gateway/rpc.h
libfreerdp/core/gateway/rpc_bind.c
libfreerdp/core/gateway/rpc_client.c
libfreerdp/core/gateway/rpc_client.h
libfreerdp/core/gateway/rts.c
libfreerdp/core/gateway/tsg.c

index 00716de..77f8d2f 100644 (file)
@@ -81,7 +81,7 @@ int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc, RpcInChannel* inChannel)
        if (!s)
                return -1;
 
-       status = rpc_in_write(rpc, Stream_Buffer(s), Stream_Length(s));
+       status = rpc_in_channel_write(inChannel, Stream_Buffer(s), Stream_Length(s));
 
        Stream_Free(s, TRUE);
 
@@ -188,7 +188,7 @@ int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc, RpcOutChannel* outChann
        if (!s)
                return -1;
 
-       status = rpc_out_write(rpc, Stream_Buffer(s), Stream_Length(s));
+       status = rpc_out_channel_write(outChannel, Stream_Buffer(s), Stream_Length(s));
 
        Stream_Free(s, TRUE);
 
index 359a2e0..62df2cd 100644 (file)
@@ -125,11 +125,11 @@ BOOL rpc_connect(rdpRpc* rpc)
        inChannel = rpc->VirtualConnection->DefaultInChannel;
        outChannel = rpc->VirtualConnection->DefaultOutChannel;
 
-       rpc_client_virtual_connection_transition_to_state(rpc, rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_INITIAL);
+       rpc_virtual_connection_transition_to_state(rpc, rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_INITIAL);
 
        /* Connect IN Channel */
 
-       rpc_client_in_channel_transition_to_state(inChannel, CLIENT_IN_CHANNEL_STATE_CONNECTED);
+       rpc_in_channel_transition_to_state(inChannel, CLIENT_IN_CHANNEL_STATE_CONNECTED);
 
        if (rpc_ncacn_http_ntlm_init(rpc, (RpcChannel*) inChannel) < 0)
                return FALSE;
@@ -142,11 +142,11 @@ BOOL rpc_connect(rdpRpc* rpc)
                return FALSE;
        }
 
-       rpc_client_in_channel_transition_to_state(inChannel, CLIENT_IN_CHANNEL_STATE_SECURITY);
+       rpc_in_channel_transition_to_state(inChannel, CLIENT_IN_CHANNEL_STATE_SECURITY);
 
        /* Connect OUT Channel */
 
-       rpc_client_out_channel_transition_to_state(outChannel, CLIENT_OUT_CHANNEL_STATE_CONNECTED);
+       rpc_out_channel_transition_to_state(outChannel, CLIENT_OUT_CHANNEL_STATE_CONNECTED);
 
        if (rpc_ncacn_http_ntlm_init(rpc, (RpcChannel*) outChannel) < 0)
                return FALSE;
@@ -159,7 +159,7 @@ BOOL rpc_connect(rdpRpc* rpc)
                return FALSE;
        }
 
-       rpc_client_out_channel_transition_to_state(outChannel, CLIENT_OUT_CHANNEL_STATE_SECURITY);
+       rpc_out_channel_transition_to_state(outChannel, CLIENT_OUT_CHANNEL_STATE_SECURITY);
 
        return TRUE;
 }
@@ -390,10 +390,9 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l
        return TRUE;
 }
 
-int rpc_out_read(rdpRpc* rpc, BYTE* data, int length)
+int rpc_out_channel_read(RpcOutChannel* outChannel, BYTE* data, int length)
 {
        int status;
-       RpcOutChannel* outChannel = rpc->VirtualConnection->DefaultOutChannel;
 
        status = BIO_read(outChannel->tls->bio, data, length);
 
@@ -411,146 +410,25 @@ int rpc_out_read(rdpRpc* rpc, BYTE* data, int length)
        return -1;
 }
 
-int rpc_out_write(rdpRpc* rpc, const BYTE* data, int length)
+int rpc_in_channel_write(RpcInChannel* inChannel, const BYTE* data, int length)
 {
        int status;
-       RpcOutChannel* outChannel = rpc->VirtualConnection->DefaultOutChannel;
 
-       status = tls_write_all(outChannel->tls, data, length);
+       status = tls_write_all(inChannel->tls, data, length);
 
        return status;
 }
 
-int rpc_in_write(rdpRpc* rpc, const BYTE* data, int length)
+int rpc_out_channel_write(RpcOutChannel* outChannel, const BYTE* data, int length)
 {
        int status;
-       RpcInChannel* inChannel = rpc->VirtualConnection->DefaultInChannel;
 
-       status = tls_write_all(inChannel->tls, data, length);
+       status = tls_write_all(outChannel->tls, data, length);
 
        return status;
 }
 
-int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
-{
-       UINT32 offset;
-       BYTE* buffer = NULL;
-       UINT32 stub_data_pad;
-       SecBuffer Buffers[2];
-       SecBufferDesc Message;
-       RpcClientCall* clientCall;
-       SECURITY_STATUS encrypt_status;
-       rpcconn_request_hdr_t* request_pdu = NULL;
-       rdpNtlm* ntlm = rpc->ntlm;
-
-       if (!ntlm || !ntlm->table)
-       {
-               WLog_ERR(TAG, "invalid ntlm context");
-               return -1;
-       }
-
-       if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK)
-       {
-               WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure");
-               return -1;
-       }
-
-       ZeroMemory(&Buffers, sizeof(Buffers));
-
-       request_pdu = (rpcconn_request_hdr_t*) calloc(1, sizeof(rpcconn_request_hdr_t));
-
-       if (!request_pdu)
-               return -1;
-
-       rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) request_pdu);
-       request_pdu->ptype = PTYPE_REQUEST;
-       request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
-       request_pdu->auth_length = (UINT16) ntlm->ContextSizes.cbMaxSignature;
-       request_pdu->call_id = rpc->CallId++;
-       request_pdu->alloc_hint = length;
-       request_pdu->p_cont_id = 0x0000;
-       request_pdu->opnum = opnum;
-
-       clientCall = rpc_client_call_new(request_pdu->call_id, request_pdu->opnum);
-
-       if (!clientCall)
-               goto out_free_pdu;
-
-       if (ArrayList_Add(rpc->client->ClientCallList, clientCall) < 0)
-               goto out_free_clientCall;
-
-       if (request_pdu->opnum == TsProxySetupReceivePipeOpnum)
-               rpc->PipeCallId = request_pdu->call_id;
-
-       request_pdu->stub_data = data;
-       offset = 24;
-       stub_data_pad = 0;
-       stub_data_pad = rpc_offset_align(&offset, 8);
-       offset += length;
-       request_pdu->auth_verifier.auth_pad_length = rpc_offset_align(&offset, 4);
-       request_pdu->auth_verifier.auth_type = RPC_C_AUTHN_WINNT;
-       request_pdu->auth_verifier.auth_level = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;
-       request_pdu->auth_verifier.auth_reserved = 0x00;
-       request_pdu->auth_verifier.auth_context_id = 0x00000000;
-       offset += (8 + request_pdu->auth_length);
-       request_pdu->frag_length = offset;
-
-       buffer = (BYTE*) calloc(1, request_pdu->frag_length);
-
-       if (!buffer)
-               goto out_free_pdu;
-
-       CopyMemory(buffer, request_pdu, 24);
-       offset = 24;
-       rpc_offset_pad(&offset, stub_data_pad);
-       CopyMemory(&buffer[offset], request_pdu->stub_data, length);
-       offset += length;
-       rpc_offset_pad(&offset, request_pdu->auth_verifier.auth_pad_length);
-       CopyMemory(&buffer[offset], &request_pdu->auth_verifier.auth_type, 8);
-       offset += 8;
-       Buffers[0].BufferType = SECBUFFER_DATA; /* auth_data */
-       Buffers[1].BufferType = SECBUFFER_TOKEN; /* signature */
-       Buffers[0].pvBuffer = buffer;
-       Buffers[0].cbBuffer = offset;
-       Buffers[1].cbBuffer = ntlm->ContextSizes.cbMaxSignature;
-       Buffers[1].pvBuffer = calloc(1, Buffers[1].cbBuffer);
-
-       if (!Buffers[1].pvBuffer)
-               goto out_free_pdu;
-
-       Message.cBuffers = 2;
-       Message.ulVersion = SECBUFFER_VERSION;
-       Message.pBuffers = (PSecBuffer) &Buffers;
-       encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->SendSeqNum++);
-
-       if (encrypt_status != SEC_E_OK)
-       {
-               WLog_ERR(TAG, "EncryptMessage status: 0x%08X", encrypt_status);
-               goto out_free_pdu;
-       }
-
-       CopyMemory(&buffer[offset], Buffers[1].pvBuffer, Buffers[1].cbBuffer);
-       offset += Buffers[1].cbBuffer;
-       free(Buffers[1].pvBuffer);
-
-       if (rpc_send_pdu(rpc, buffer, request_pdu->frag_length) < 0)
-               length = -1;
-
-       free(request_pdu);
-       free(buffer);
-
-       return length;
-
-out_free_clientCall:
-       rpc_client_call_free(clientCall);
-out_free_pdu:
-       free(buffer);
-       free(Buffers[1].pvBuffer);
-       free(request_pdu);
-       return -1;
-}
-
-int rpc_client_in_channel_transition_to_state(RpcInChannel* inChannel, CLIENT_IN_CHANNEL_STATE state)
+int rpc_in_channel_transition_to_state(RpcInChannel* inChannel, CLIENT_IN_CHANNEL_STATE state)
 {
        int status = 1;
        const char* str = "CLIENT_IN_CHANNEL_STATE_UNKNOWN";
@@ -592,7 +470,7 @@ int rpc_client_in_channel_transition_to_state(RpcInChannel* inChannel, CLIENT_IN
        return status;
 }
 
-int rpc_client_in_channel_rpch_init(rdpRpc* rpc, RpcInChannel* inChannel)
+int rpc_in_channel_rpch_init(rdpRpc* rpc, RpcInChannel* inChannel)
 {
        HttpContext* http;
 
@@ -622,23 +500,24 @@ int rpc_client_in_channel_rpch_init(rdpRpc* rpc, RpcInChannel* inChannel)
        return 1;
 }
 
-int rpc_client_in_channel_init(rdpRpc* rpc, RpcInChannel* inChannel)
+int rpc_in_channel_init(rdpRpc* rpc, RpcInChannel* inChannel)
 {
        rts_generate_cookie((BYTE*) &inChannel->Cookie);
 
+       inChannel->rpc = rpc;
        inChannel->State = CLIENT_IN_CHANNEL_STATE_INITIAL;
        inChannel->BytesSent = 0;
        inChannel->SenderAvailableWindow = rpc->ReceiveWindow;
        inChannel->PingOriginator.ConnectionTimeout = 30;
        inChannel->PingOriginator.KeepAliveInterval = 0;
 
-       if (rpc_client_in_channel_rpch_init(rpc, inChannel) < 0)
+       if (rpc_in_channel_rpch_init(rpc, inChannel) < 0)
                return -1;
 
        return 1;
 }
 
-void rpc_client_in_channel_rpch_uninit(RpcInChannel* inChannel)
+void rpc_in_channel_rpch_uninit(RpcInChannel* inChannel)
 {
        if (inChannel->ntlm)
        {
@@ -653,7 +532,7 @@ void rpc_client_in_channel_rpch_uninit(RpcInChannel* inChannel)
        }
 }
 
-RpcInChannel* rpc_client_in_channel_new(rdpRpc* rpc)
+RpcInChannel* rpc_in_channel_new(rdpRpc* rpc)
 {
        RpcInChannel* inChannel = NULL;
 
@@ -661,23 +540,23 @@ RpcInChannel* rpc_client_in_channel_new(rdpRpc* rpc)
 
        if (inChannel)
        {
-               rpc_client_in_channel_init(rpc, inChannel);
+               rpc_in_channel_init(rpc, inChannel);
        }
 
        return inChannel;
 }
 
-void rpc_client_in_channel_free(RpcInChannel* inChannel)
+void rpc_in_channel_free(RpcInChannel* inChannel)
 {
        if (!inChannel)
                return;
 
-       rpc_client_in_channel_rpch_uninit(inChannel);
+       rpc_in_channel_rpch_uninit(inChannel);
 
        free(inChannel);
 }
 
-int rpc_client_out_channel_transition_to_state(RpcOutChannel* outChannel, CLIENT_OUT_CHANNEL_STATE state)
+int rpc_out_channel_transition_to_state(RpcOutChannel* outChannel, CLIENT_OUT_CHANNEL_STATE state)
 {
        int status = 1;
        const char* str = "CLIENT_OUT_CHANNEL_STATE_UNKNOWN";
@@ -727,7 +606,7 @@ int rpc_client_out_channel_transition_to_state(RpcOutChannel* outChannel, CLIENT
        return status;
 }
 
-int rpc_client_out_channel_rpch_init(rdpRpc* rpc, RpcOutChannel* outChannel)
+int rpc_out_channel_rpch_init(rdpRpc* rpc, RpcOutChannel* outChannel)
 {
        HttpContext* http;
 
@@ -759,10 +638,11 @@ int rpc_client_out_channel_rpch_init(rdpRpc* rpc, RpcOutChannel* outChannel)
        return 1;
 }
 
-int rpc_client_out_channel_init(rdpRpc* rpc, RpcOutChannel* outChannel)
+int rpc_out_channel_init(rdpRpc* rpc, RpcOutChannel* outChannel)
 {
        rts_generate_cookie((BYTE*) &outChannel->Cookie);
 
+       outChannel->rpc = rpc;
        outChannel->State = CLIENT_OUT_CHANNEL_STATE_INITIAL;
        outChannel->BytesReceived = 0;
        outChannel->ReceiverAvailableWindow = rpc->ReceiveWindow;
@@ -770,13 +650,13 @@ int rpc_client_out_channel_init(rdpRpc* rpc, RpcOutChannel* outChannel)
        outChannel->ReceiveWindowSize = rpc->ReceiveWindow;
        outChannel->AvailableWindowAdvertised = rpc->ReceiveWindow;
 
-       if (rpc_client_out_channel_rpch_init(rpc, outChannel) < 0)
+       if (rpc_out_channel_rpch_init(rpc, outChannel) < 0)
                return -1;
 
        return 1;
 }
 
-void rpc_client_out_channel_rpch_uninit(RpcOutChannel* outChannel)
+void rpc_out_channel_rpch_uninit(RpcOutChannel* outChannel)
 {
        if (outChannel->ntlm)
        {
@@ -791,7 +671,7 @@ void rpc_client_out_channel_rpch_uninit(RpcOutChannel* outChannel)
        }
 }
 
-RpcOutChannel* rpc_client_out_channel_new(rdpRpc* rpc)
+RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc)
 {
        RpcOutChannel* outChannel = NULL;
 
@@ -799,23 +679,23 @@ RpcOutChannel* rpc_client_out_channel_new(rdpRpc* rpc)
 
        if (outChannel)
        {
-               rpc_client_out_channel_init(rpc, outChannel);
+               rpc_out_channel_init(rpc, outChannel);
        }
 
        return outChannel;
 }
 
-void rpc_client_out_channel_free(RpcOutChannel* outChannel)
+void rpc_out_channel_free(RpcOutChannel* outChannel)
 {
        if (!outChannel)
                return;
 
-       rpc_client_out_channel_rpch_uninit(outChannel);
+       rpc_out_channel_rpch_uninit(outChannel);
 
        free(outChannel);
 }
 
-int rpc_client_virtual_connection_transition_to_state(rdpRpc* rpc,
+int rpc_virtual_connection_transition_to_state(rdpRpc* rpc,
                RpcVirtualConnection* connection, VIRTUAL_CONNECTION_STATE state)
 {
        int status = 1;
@@ -854,7 +734,7 @@ int rpc_client_virtual_connection_transition_to_state(rdpRpc* rpc,
        return status;
 }
 
-RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
+RpcVirtualConnection* rpc_virtual_connection_new(rdpRpc* rpc)
 {
        RpcVirtualConnection* connection;
 
@@ -868,12 +748,12 @@ RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
 
        connection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
 
-       connection->DefaultInChannel = rpc_client_in_channel_new(rpc);
+       connection->DefaultInChannel = rpc_in_channel_new(rpc);
 
        if (!connection->DefaultInChannel)
                goto out_free;
 
-       connection->DefaultOutChannel = rpc_client_out_channel_new(rpc);
+       connection->DefaultOutChannel = rpc_out_channel_new(rpc);
 
        if (!connection->DefaultOutChannel)
                goto out_default_in;
@@ -886,16 +766,16 @@ out_free:
        return NULL;
 }
 
-void rpc_client_virtual_connection_free(RpcVirtualConnection* connection)
+void rpc_virtual_connection_free(RpcVirtualConnection* connection)
 {
        if (!connection)
                return;
 
-       rpc_client_in_channel_free(connection->DefaultInChannel);
-       rpc_client_in_channel_free(connection->NonDefaultInChannel);
+       rpc_in_channel_free(connection->DefaultInChannel);
+       rpc_in_channel_free(connection->NonDefaultInChannel);
 
-       rpc_client_out_channel_free(connection->DefaultOutChannel);
-       rpc_client_out_channel_free(connection->NonDefaultOutChannel);
+       rpc_out_channel_free(connection->DefaultOutChannel);
+       rpc_out_channel_free(connection->NonDefaultOutChannel);
 
        free(connection);
 }
@@ -940,7 +820,7 @@ rdpRpc* rpc_new(rdpTransport* transport)
        rpc->CurrentKeepAliveInterval = rpc->KeepAliveInterval;
        rpc->CurrentKeepAliveTime = 0;
 
-       rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);
+       rpc->VirtualConnection = rpc_virtual_connection_new(rpc);
 
        if (!rpc->VirtualConnection)
                goto out_free_virtual_connection;
@@ -954,7 +834,7 @@ rdpRpc* rpc_new(rdpTransport* transport)
 out_free_rpc_client:
        rpc_client_free(rpc);
 out_free_virtual_connection:
-       rpc_client_virtual_connection_free(rpc->VirtualConnection);
+       rpc_virtual_connection_free(rpc->VirtualConnection);
 out_free:
        free(rpc);
        return NULL;
@@ -973,7 +853,7 @@ void rpc_free(rdpRpc* rpc)
                        rpc->ntlm = NULL;
                }
 
-               rpc_client_virtual_connection_free(rpc->VirtualConnection);
+               rpc_virtual_connection_free(rpc->VirtualConnection);
 
                free(rpc);
        }
index 8d0f95a..a5c4dd5 100644 (file)
@@ -585,6 +585,7 @@ struct rpc_client_call
 typedef struct rpc_client_call RpcClientCall;
 
 #define RPC_CHANNEL_COMMON() \
+       rdpRpc* rpc; \
        rdpTcp* tcp; \
        rdpTls* tls; \
        rdpNtlm* ntlm; \
@@ -767,27 +768,25 @@ void rpc_pdu_header_init(rdpRpc* rpc, rpcconn_hdr_t* header);
 UINT32 rpc_offset_align(UINT32* offset, UINT32 alignment);
 UINT32 rpc_offset_pad(UINT32* offset, UINT32 pad);
 
-int rpc_out_read(rdpRpc* rpc, BYTE* data, int length);
+BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* length);
 
-int rpc_out_write(rdpRpc* rpc, const BYTE* data, int length);
-int rpc_in_write(rdpRpc* rpc, const BYTE* data, int length);
+int rpc_in_channel_write(RpcInChannel* inChannel, const BYTE* data, int length);
 
-BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* length);
+int rpc_out_channel_read(RpcOutChannel* outChannel, BYTE* data, int length);
+int rpc_out_channel_write(RpcOutChannel* outChannel, const BYTE* data, int length);
 
 RpcInChannel* rpc_client_in_channel_new(rdpRpc* rpc);
-void rpc_client_in_channel_free(RpcInChannel* inChannel);
+void rpc_in_channel_free(RpcInChannel* inChannel);
 
-RpcOutChannel* rpc_client_out_channel_new(rdpRpc* rpc);
+RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc);
 void rpc_client_out_channel_free(RpcOutChannel* outChannel);
 
-int rpc_client_in_channel_transition_to_state(RpcInChannel* inChannel, CLIENT_IN_CHANNEL_STATE state);
-int rpc_client_out_channel_transition_to_state(RpcOutChannel* outChannel, CLIENT_OUT_CHANNEL_STATE state);
+int rpc_in_channel_transition_to_state(RpcInChannel* inChannel, CLIENT_IN_CHANNEL_STATE state);
+int rpc_out_channel_transition_to_state(RpcOutChannel* outChannel, CLIENT_OUT_CHANNEL_STATE state);
 
-int rpc_client_virtual_connection_transition_to_state(rdpRpc* rpc,
+int rpc_virtual_connection_transition_to_state(rdpRpc* rpc,
                RpcVirtualConnection* connection, VIRTUAL_CONNECTION_STATE state);
 
-int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum);
-
 BOOL rpc_connect(rdpRpc* rpc);
 
 rdpRpc* rpc_new(rdpTransport* transport);
index 741491e..4c04563 100644 (file)
@@ -114,9 +114,11 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
        RpcClientCall* clientCall;
        p_cont_elem_t* p_cont_elem;
        rpcconn_bind_hdr_t* bind_pdu;
-       rdpSettings* settings = rpc->settings;
        BOOL promptPassword = FALSE;
+       rdpSettings* settings = rpc->settings;
        freerdp* instance = (freerdp*) settings->instance;
+       RpcVirtualConnection* connection = rpc->VirtualConnection;
+       RpcInChannel* inChannel = connection->DefaultInChannel;
 
        WLog_DBG(TAG, "Sending Bind PDU");
 
@@ -238,6 +240,7 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
        bind_pdu->frag_length = offset;
 
        buffer = (BYTE*) malloc(bind_pdu->frag_length);
+
        if (!buffer)
                return -1;
 
@@ -271,7 +274,7 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
                return -1;
        }
 
-       status = rpc_send_pdu(rpc, buffer, length);
+       status = rpc_in_channel_send_pdu(inChannel, buffer, length);
 
        free(bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes);
        free(bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes);
@@ -347,6 +350,8 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
        UINT32 length;
        RpcClientCall* clientCall;
        rpcconn_rpc_auth_3_hdr_t* auth_3_pdu;
+       RpcVirtualConnection* connection = rpc->VirtualConnection;
+       RpcInChannel* inChannel = connection->DefaultInChannel;
 
        WLog_DBG(TAG, "Sending RpcAuth3 PDU");
 
@@ -397,7 +402,7 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
        clientCall = rpc_client_call_new(auth_3_pdu->call_id, 0);
        ArrayList_Add(rpc->client->ClientCallList, clientCall);
 
-       status = rpc_send_pdu(rpc, buffer, length);
+       status = rpc_in_channel_send_pdu(inChannel, buffer, length);
 
        free(auth_3_pdu);
        free(buffer);
index 7d71bb0..2d9890a 100644 (file)
@@ -205,7 +205,7 @@ int rpc_client_recv_pdu(rdpRpc* rpc, RPC_PDU* pdu)
                                        return -1;
                                }
 
-                               rpc_client_virtual_connection_transition_to_state(rpc,
+                               rpc_virtual_connection_transition_to_state(rpc,
                                                rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_C2);
 
                                status = 1;
@@ -230,7 +230,7 @@ int rpc_client_recv_pdu(rdpRpc* rpc, RPC_PDU* pdu)
                                        return -1;
                                }
 
-                               rpc_client_virtual_connection_transition_to_state(rpc,
+                               rpc_virtual_connection_transition_to_state(rpc,
                                                rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_OPENED);
 
                                rpc_client_transition_to_state(rpc, RPC_CLIENT_STATE_ESTABLISHED);
@@ -452,82 +452,6 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment)
        return 1;
 }
 
-int rpc_client_recv(rdpRpc* rpc)
-{
-       int status = -1;
-       wStream* fragment;
-       rpcconn_common_hdr_t* header;
-
-       fragment = rpc->client->ReceiveFragment;
-
-       while (1)
-       {
-               while (Stream_GetPosition(fragment) < RPC_COMMON_FIELDS_LENGTH)
-               {
-                       status = rpc_out_read(rpc, Stream_Pointer(fragment),
-                                       RPC_COMMON_FIELDS_LENGTH - Stream_GetPosition(fragment));
-
-                       if (status < 0)
-                               return -1;
-
-                       if (!status)
-                               return 0;
-
-                       Stream_Seek(fragment, status);
-               }
-
-               if (Stream_GetPosition(fragment) < RPC_COMMON_FIELDS_LENGTH)
-                       return status;
-
-               header = (rpcconn_common_hdr_t*) Stream_Buffer(fragment);
-
-               if (header->frag_length > rpc->max_recv_frag)
-               {
-                       WLog_ERR(TAG, "rpc_client_recv: invalid fragment size: %d (max: %d)",
-                                        header->frag_length, rpc->max_recv_frag);
-                       winpr_HexDump(TAG, WLOG_ERROR, Stream_Buffer(fragment), Stream_GetPosition(fragment));
-                       return -1;
-               }
-
-               while (Stream_GetPosition(fragment) < header->frag_length)
-               {
-                       status = rpc_out_read(rpc, Stream_Pointer(fragment),
-                                       header->frag_length - Stream_GetPosition(fragment));
-
-                       if (status < 0)
-                       {
-                               WLog_ERR(TAG, "error reading fragment body");
-                               return -1;
-                       }
-
-                       if (!status)
-                               return 0;
-
-                       Stream_Seek(fragment, status);
-               }
-
-               if (status < 0)
-                       return -1;
-
-               if (Stream_GetPosition(fragment) >= header->frag_length)
-               {
-                       /* complete fragment received */
-
-                       Stream_SealLength(fragment);
-                       Stream_SetPosition(fragment, 0);
-
-                       status = rpc_client_recv_fragment(rpc, fragment);
-
-                       if (status < 0)
-                               return status;
-
-                       Stream_SetPosition(fragment, 0);
-               }
-       }
-
-       return 1;
-}
-
 int rpc_client_out_channel_recv(rdpRpc* rpc)
 {
        int status = -1;
@@ -565,7 +489,7 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
 
                        rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*) outChannel);
 
-                       rpc_client_out_channel_transition_to_state(outChannel,
+                       rpc_out_channel_transition_to_state(outChannel,
                                        CLIENT_OUT_CHANNEL_STATE_NEGOTIATED);
 
                        /* Send CONN/A1 PDU over OUT channel */
@@ -576,12 +500,12 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
                                return -1;
                        }
 
-                       rpc_client_out_channel_transition_to_state(outChannel,
+                       rpc_out_channel_transition_to_state(outChannel,
                                        CLIENT_OUT_CHANNEL_STATE_OPENED);
 
                        if (inChannel->State == CLIENT_IN_CHANNEL_STATE_OPENED)
                        {
-                               rpc_client_virtual_connection_transition_to_state(rpc,
+                               rpc_virtual_connection_transition_to_state(rpc,
                                        rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT);
                        }
 
@@ -621,14 +545,82 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
 
                http_response_free(response);
 
-               rpc_client_virtual_connection_transition_to_state(rpc,
+               rpc_virtual_connection_transition_to_state(rpc,
                                rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_A3W);
 
                status = 1;
        }
        else
        {
-               status = rpc_client_recv(rpc);
+               wStream* fragment;
+               rpcconn_common_hdr_t* header;
+
+               fragment = rpc->client->ReceiveFragment;
+
+               while (1)
+               {
+                       while (Stream_GetPosition(fragment) < RPC_COMMON_FIELDS_LENGTH)
+                       {
+                               status = rpc_out_channel_read(outChannel, Stream_Pointer(fragment),
+                                               RPC_COMMON_FIELDS_LENGTH - Stream_GetPosition(fragment));
+
+                               if (status < 0)
+                                       return -1;
+
+                               if (!status)
+                                       return 0;
+
+                               Stream_Seek(fragment, status);
+                       }
+
+                       if (Stream_GetPosition(fragment) < RPC_COMMON_FIELDS_LENGTH)
+                               return status;
+
+                       header = (rpcconn_common_hdr_t*) Stream_Buffer(fragment);
+
+                       if (header->frag_length > rpc->max_recv_frag)
+                       {
+                               WLog_ERR(TAG, "rpc_client_recv: invalid fragment size: %d (max: %d)",
+                                                header->frag_length, rpc->max_recv_frag);
+                               winpr_HexDump(TAG, WLOG_ERROR, Stream_Buffer(fragment), Stream_GetPosition(fragment));
+                               return -1;
+                       }
+
+                       while (Stream_GetPosition(fragment) < header->frag_length)
+                       {
+                               status = rpc_out_channel_read(outChannel, Stream_Pointer(fragment),
+                                               header->frag_length - Stream_GetPosition(fragment));
+
+                               if (status < 0)
+                               {
+                                       WLog_ERR(TAG, "error reading fragment body");
+                                       return -1;
+                               }
+
+                               if (!status)
+                                       return 0;
+
+                               Stream_Seek(fragment, status);
+                       }
+
+                       if (status < 0)
+                               return -1;
+
+                       if (Stream_GetPosition(fragment) >= header->frag_length)
+                       {
+                               /* complete fragment received */
+
+                               Stream_SealLength(fragment);
+                               Stream_SetPosition(fragment, 0);
+
+                               status = rpc_client_recv_fragment(rpc, fragment);
+
+                               if (status < 0)
+                                       return status;
+
+                               Stream_SetPosition(fragment, 0);
+                       }
+               }
        }
 
        return status;
@@ -675,7 +667,7 @@ int rpc_client_in_channel_recv(rdpRpc* rpc)
 
                        rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*) inChannel);
 
-                       rpc_client_in_channel_transition_to_state(inChannel,
+                       rpc_in_channel_transition_to_state(inChannel,
                                        CLIENT_IN_CHANNEL_STATE_NEGOTIATED);
 
                        /* Send CONN/B1 PDU over IN channel */
@@ -686,12 +678,12 @@ int rpc_client_in_channel_recv(rdpRpc* rpc)
                                return -1;
                        }
 
-                       rpc_client_in_channel_transition_to_state(inChannel,
+                       rpc_in_channel_transition_to_state(inChannel,
                                        CLIENT_IN_CHANNEL_STATE_OPENED);
 
                        if (outChannel->State == CLIENT_OUT_CHANNEL_STATE_OPENED)
                        {
-                               rpc_client_virtual_connection_transition_to_state(rpc,
+                               rpc_virtual_connection_transition_to_state(rpc,
                                        rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT);
                        }
 
@@ -753,16 +745,14 @@ void rpc_client_call_free(RpcClientCall* clientCall)
        free(clientCall);
 }
 
-int rpc_send_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
+int rpc_in_channel_send_pdu(RpcInChannel* inChannel, BYTE* buffer, UINT32 length)
 {
        int status;
-       RpcInChannel* inChannel;
        RpcClientCall* clientCall;
        rpcconn_common_hdr_t* header;
+       rdpRpc* rpc = inChannel->rpc;
 
-       inChannel = rpc->VirtualConnection->DefaultInChannel;
-
-       status = rpc_in_write(rpc, buffer, length);
+       status = rpc_in_channel_write(inChannel, buffer, length);
 
        if (status <= 0)
                return -1;
@@ -787,6 +777,127 @@ int rpc_send_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
        return status;
 }
 
+int rpc_client_write_call(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
+{
+       UINT32 offset;
+       BYTE* buffer = NULL;
+       UINT32 stub_data_pad;
+       SecBuffer Buffers[2];
+       SecBufferDesc Message;
+       RpcClientCall* clientCall;
+       rdpNtlm* ntlm = rpc->ntlm;
+       SECURITY_STATUS encrypt_status;
+       rpcconn_request_hdr_t* request_pdu = NULL;
+       RpcVirtualConnection* connection = rpc->VirtualConnection;
+       RpcInChannel* inChannel = connection->DefaultInChannel;
+
+       if (!ntlm || !ntlm->table)
+       {
+               WLog_ERR(TAG, "invalid ntlm context");
+               return -1;
+       }
+
+       if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK)
+       {
+               WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure");
+               return -1;
+       }
+
+       ZeroMemory(&Buffers, sizeof(Buffers));
+
+       request_pdu = (rpcconn_request_hdr_t*) calloc(1, sizeof(rpcconn_request_hdr_t));
+
+       if (!request_pdu)
+               return -1;
+
+       rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) request_pdu);
+       request_pdu->ptype = PTYPE_REQUEST;
+       request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
+       request_pdu->auth_length = (UINT16) ntlm->ContextSizes.cbMaxSignature;
+       request_pdu->call_id = rpc->CallId++;
+       request_pdu->alloc_hint = length;
+       request_pdu->p_cont_id = 0x0000;
+       request_pdu->opnum = opnum;
+
+       clientCall = rpc_client_call_new(request_pdu->call_id, request_pdu->opnum);
+
+       if (!clientCall)
+               goto out_free_pdu;
+
+       if (ArrayList_Add(rpc->client->ClientCallList, clientCall) < 0)
+               goto out_free_clientCall;
+
+       if (request_pdu->opnum == TsProxySetupReceivePipeOpnum)
+               rpc->PipeCallId = request_pdu->call_id;
+
+       request_pdu->stub_data = data;
+       offset = 24;
+       stub_data_pad = 0;
+       stub_data_pad = rpc_offset_align(&offset, 8);
+       offset += length;
+       request_pdu->auth_verifier.auth_pad_length = rpc_offset_align(&offset, 4);
+       request_pdu->auth_verifier.auth_type = RPC_C_AUTHN_WINNT;
+       request_pdu->auth_verifier.auth_level = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;
+       request_pdu->auth_verifier.auth_reserved = 0x00;
+       request_pdu->auth_verifier.auth_context_id = 0x00000000;
+       offset += (8 + request_pdu->auth_length);
+       request_pdu->frag_length = offset;
+
+       buffer = (BYTE*) calloc(1, request_pdu->frag_length);
+
+       if (!buffer)
+               goto out_free_pdu;
+
+       CopyMemory(buffer, request_pdu, 24);
+       offset = 24;
+       rpc_offset_pad(&offset, stub_data_pad);
+       CopyMemory(&buffer[offset], request_pdu->stub_data, length);
+       offset += length;
+       rpc_offset_pad(&offset, request_pdu->auth_verifier.auth_pad_length);
+       CopyMemory(&buffer[offset], &request_pdu->auth_verifier.auth_type, 8);
+       offset += 8;
+       Buffers[0].BufferType = SECBUFFER_DATA; /* auth_data */
+       Buffers[1].BufferType = SECBUFFER_TOKEN; /* signature */
+       Buffers[0].pvBuffer = buffer;
+       Buffers[0].cbBuffer = offset;
+       Buffers[1].cbBuffer = ntlm->ContextSizes.cbMaxSignature;
+       Buffers[1].pvBuffer = calloc(1, Buffers[1].cbBuffer);
+
+       if (!Buffers[1].pvBuffer)
+               goto out_free_pdu;
+
+       Message.cBuffers = 2;
+       Message.ulVersion = SECBUFFER_VERSION;
+       Message.pBuffers = (PSecBuffer) &Buffers;
+       encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->SendSeqNum++);
+
+       if (encrypt_status != SEC_E_OK)
+       {
+               WLog_ERR(TAG, "EncryptMessage status: 0x%08X", encrypt_status);
+               goto out_free_pdu;
+       }
+
+       CopyMemory(&buffer[offset], Buffers[1].pvBuffer, Buffers[1].cbBuffer);
+       offset += Buffers[1].cbBuffer;
+       free(Buffers[1].pvBuffer);
+
+       if (rpc_in_channel_send_pdu(inChannel, buffer, request_pdu->frag_length) < 0)
+               length = -1;
+
+       free(request_pdu);
+       free(buffer);
+
+       return length;
+
+out_free_clientCall:
+       rpc_client_call_free(clientCall);
+out_free_pdu:
+       free(buffer);
+       free(Buffers[1].pvBuffer);
+       free(request_pdu);
+       return -1;
+}
+
 int rpc_client_new(rdpRpc* rpc)
 {
        RpcClient* client;
index ec9760c..1750cff 100644 (file)
@@ -27,14 +27,15 @@ RpcClientCall* rpc_client_call_find_by_id(rdpRpc* rpc, UINT32 CallId);
 RpcClientCall* rpc_client_call_new(UINT32 CallId, UINT32 OpNum);
 void rpc_client_call_free(RpcClientCall* client_call);
 
-int rpc_send_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length);
-int rpc_client_recv(rdpRpc* rpc);
+int rpc_in_channel_send_pdu(RpcInChannel* inChannel, BYTE* buffer, UINT32 length);
 
 int rpc_client_in_channel_recv(rdpRpc* rpc);
 int rpc_client_out_channel_recv(rdpRpc* rpc);
 
 int rpc_client_receive_pipe_read(rdpRpc* rpc, BYTE* buffer, size_t length);
 
+int rpc_client_write_call(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum);
+
 int rpc_client_new(rdpRpc* rpc);
 void rpc_client_free(rdpRpc* rpc);
 
index a0f3e3a..95b107d 100644 (file)
@@ -435,6 +435,8 @@ int rts_send_CONN_A1_pdu(rdpRpc* rpc)
        UINT32 ReceiveWindowSize;
        BYTE* OUTChannelCookie;
        BYTE* VirtualConnectionCookie;
+       RpcVirtualConnection* connection = rpc->VirtualConnection;
+       RpcOutChannel* outChannel = connection->DefaultOutChannel;
 
        rts_pdu_header_init(&header);
        header.frag_length = 76;
@@ -443,9 +445,9 @@ int rts_send_CONN_A1_pdu(rdpRpc* rpc)
 
        WLog_DBG(TAG, "Sending CONN_A1 RTS PDU");
 
-       VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie);
-       OUTChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannel->Cookie);
-       ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow;
+       VirtualConnectionCookie = (BYTE*) &(connection->Cookie);
+       OUTChannelCookie = (BYTE*) &(outChannel->Cookie);
+       ReceiveWindowSize = outChannel->ReceiveWindow;
 
        buffer = (BYTE*) malloc(header.frag_length);
 
@@ -458,7 +460,7 @@ int rts_send_CONN_A1_pdu(rdpRpc* rpc)
        rts_cookie_command_write(&buffer[48], OUTChannelCookie); /* OUTChannelCookie (20 bytes) */
        rts_receive_window_size_command_write(&buffer[68], ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
 
-       status = rpc_out_write(rpc, buffer, header.frag_length);
+       status = rpc_out_channel_write(outChannel, buffer, header.frag_length);
 
        free(buffer);
 
@@ -489,6 +491,8 @@ int rts_send_CONN_B1_pdu(rdpRpc* rpc)
        BYTE* INChannelCookie;
        BYTE* AssociationGroupId;
        BYTE* VirtualConnectionCookie;
+       RpcVirtualConnection* connection = rpc->VirtualConnection;
+       RpcInChannel* inChannel = connection->DefaultInChannel;
 
        rts_pdu_header_init(&header);
        header.frag_length = 104;
@@ -497,9 +501,9 @@ int rts_send_CONN_B1_pdu(rdpRpc* rpc)
 
        WLog_DBG(TAG, "Sending CONN_B1 RTS PDU");
 
-       VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie);
-       INChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultInChannel->Cookie);
-       AssociationGroupId = (BYTE*) &(rpc->VirtualConnection->AssociationGroupId);
+       VirtualConnectionCookie = (BYTE*) &(connection->Cookie);
+       INChannelCookie = (BYTE*) &(inChannel->Cookie);
+       AssociationGroupId = (BYTE*) &(connection->AssociationGroupId);
 
        buffer = (BYTE*) malloc(header.frag_length);
 
@@ -516,7 +520,7 @@ int rts_send_CONN_B1_pdu(rdpRpc* rpc)
 
        length = header.frag_length;
 
-       status = rpc_in_write(rpc, buffer, length);
+       status = rpc_in_channel_write(inChannel, buffer, length);
 
        free(buffer);
 
@@ -553,6 +557,7 @@ int rts_send_keep_alive_pdu(rdpRpc* rpc)
        BYTE* buffer;
        UINT32 length;
        rpcconn_rts_hdr_t header;
+       RpcInChannel* inChannel = rpc->VirtualConnection->DefaultInChannel;
 
        rts_pdu_header_init(&header);
        header.frag_length = 28;
@@ -571,7 +576,7 @@ int rts_send_keep_alive_pdu(rdpRpc* rpc)
 
        length = header.frag_length;
 
-       status = rpc_in_write(rpc, buffer, length);
+       status = rpc_in_channel_write(inChannel, buffer, length);
 
        free(buffer);
 
@@ -587,6 +592,9 @@ int rts_send_flow_control_ack_pdu(rdpRpc* rpc)
        UINT32 BytesReceived;
        UINT32 AvailableWindow;
        BYTE* ChannelCookie;
+       RpcVirtualConnection* connection = rpc->VirtualConnection;
+       RpcInChannel* inChannel = connection->DefaultInChannel;
+       RpcOutChannel* outChannel = connection->DefaultOutChannel;
 
        rts_pdu_header_init(&header);
        header.frag_length = 56;
@@ -595,12 +603,11 @@ int rts_send_flow_control_ack_pdu(rdpRpc* rpc)
 
        WLog_DBG(TAG, "Sending FlowControlAck RTS PDU");
 
-       BytesReceived = rpc->VirtualConnection->DefaultOutChannel->BytesReceived;
-       AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->AvailableWindowAdvertised;
-       ChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannel->Cookie);
+       BytesReceived = outChannel->BytesReceived;
+       AvailableWindow = outChannel->AvailableWindowAdvertised;
+       ChannelCookie = (BYTE*) &(outChannel->Cookie);
 
-       rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow =
-                       rpc->VirtualConnection->DefaultOutChannel->AvailableWindowAdvertised;
+       outChannel->ReceiverAvailableWindow = outChannel->AvailableWindowAdvertised;
 
        buffer = (BYTE*) malloc(header.frag_length);
 
@@ -615,7 +622,7 @@ int rts_send_flow_control_ack_pdu(rdpRpc* rpc)
 
        length = header.frag_length;
 
-       status = rpc_in_write(rpc, buffer, length);
+       status = rpc_in_channel_write(inChannel, buffer, length);
 
        free(buffer);
 
@@ -692,6 +699,7 @@ int rts_send_ping_pdu(rdpRpc* rpc)
        BYTE* buffer;
        UINT32 length;
        rpcconn_rts_hdr_t header;
+       RpcInChannel* inChannel = rpc->VirtualConnection->DefaultInChannel;
 
        rts_pdu_header_init(&header);
        header.frag_length = 20;
@@ -709,7 +717,7 @@ int rts_send_ping_pdu(rdpRpc* rpc)
 
        length = header.frag_length;
 
-       status = rpc_in_write(rpc, buffer, length);
+       status = rpc_in_channel_write(inChannel, buffer, length);
 
        free(buffer);
 
@@ -797,6 +805,8 @@ int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
        BYTE* buffer;
        rpcconn_rts_hdr_t header;
        BYTE* SuccessorChannelCookie;
+       RpcOutChannel* outChannel = rpc->VirtualConnection->DefaultOutChannel;
+       RpcOutChannel* nextOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
 
        rts_pdu_header_init(&header);
        header.frag_length = 56;
@@ -805,7 +815,7 @@ int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
 
        WLog_DBG(TAG, "Sending OUT R2/A7 RTS PDU");
 
-       SuccessorChannelCookie = (BYTE*) &(rpc->VirtualConnection->NonDefaultOutChannel->Cookie);
+       SuccessorChannelCookie = (BYTE*) &(nextOutChannel->Cookie);
 
        buffer = (BYTE*) malloc(header.frag_length);
 
@@ -817,7 +827,7 @@ int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
        rts_cookie_command_write(&buffer[28], SuccessorChannelCookie); /* SuccessorChannelCookie (20 bytes) */
        rts_version_command_write(&buffer[48]); /* Version (8 bytes) */
 
-       status = rpc_out_write(rpc, buffer, header.frag_length);
+       status = rpc_out_channel_write(outChannel, buffer, header.frag_length);
 
        free(buffer);
 
@@ -829,6 +839,7 @@ int rts_send_OUT_R2_C1_pdu(rdpRpc* rpc)
        int status;
        BYTE* buffer;
        rpcconn_rts_hdr_t header;
+       RpcOutChannel* outChannel = rpc->VirtualConnection->DefaultOutChannel;
 
        rts_pdu_header_init(&header);
        header.frag_length = 24;
@@ -845,7 +856,7 @@ int rts_send_OUT_R2_C1_pdu(rdpRpc* rpc)
        CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
        rts_empty_command_write(&buffer[20]); /* Empty command (4 bytes) */
 
-       status = rpc_out_write(rpc, buffer, header.frag_length);
+       status = rpc_out_channel_write(outChannel, buffer, header.frag_length);
 
        free(buffer);
 
@@ -861,6 +872,9 @@ int rts_send_OUT_R1_A3_pdu(rdpRpc* rpc)
        BYTE* VirtualConnectionCookie;
        BYTE* PredecessorChannelCookie;
        BYTE* SuccessorChannelCookie;
+       RpcVirtualConnection* connection = rpc->VirtualConnection;
+       RpcOutChannel* outChannel = connection->DefaultOutChannel;
+       RpcOutChannel* nextOutChannel = connection->NonDefaultOutChannel;
 
        rts_pdu_header_init(&header);
        header.frag_length = 96;
@@ -869,10 +883,10 @@ int rts_send_OUT_R1_A3_pdu(rdpRpc* rpc)
 
        WLog_DBG(TAG, "Sending OUT R1/A3 RTS PDU");
 
-       VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie);
-       PredecessorChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannel->Cookie);
-       SuccessorChannelCookie = (BYTE*) &(rpc->VirtualConnection->NonDefaultOutChannel->Cookie);
-       ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow;
+       VirtualConnectionCookie = (BYTE*) &(connection->Cookie);
+       PredecessorChannelCookie = (BYTE*) &(outChannel->Cookie);
+       SuccessorChannelCookie = (BYTE*) &(nextOutChannel->Cookie);
+       ReceiveWindowSize = outChannel->ReceiveWindow;
 
        buffer = (BYTE*) malloc(header.frag_length);
 
@@ -886,7 +900,7 @@ int rts_send_OUT_R1_A3_pdu(rdpRpc* rpc)
        rts_cookie_command_write(&buffer[68], SuccessorChannelCookie); /* SuccessorChannelCookie (20 bytes) */
        rts_receive_window_size_command_write(&buffer[88], ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
 
-       status = rpc_out_write(rpc, buffer, header.frag_length);
+       status = rpc_out_channel_write(outChannel, buffer, header.frag_length);
 
        free(buffer);
 
@@ -906,7 +920,7 @@ int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
 
        WLog_ERR(TAG, "TS Gateway channel recycling is incomplete");
 
-       connection->NonDefaultOutChannel = rpc_client_out_channel_new(rpc);
+       connection->NonDefaultOutChannel = rpc_out_channel_new(rpc);
 
        return 1;
 }
index 6aa7e94..9a5dbb9 100644 (file)
@@ -116,8 +116,8 @@ DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], UINT32 count,
        if (buffer3Length > 0)
                Stream_Write(s, buffer3, buffer3Length); /* buffer3 (variable) */
 
-       Stream_Length(s) = Stream_GetPosition(s);
-       status = rpc_write(tsg->rpc, Stream_Buffer(s), Stream_Length(s), TsProxySendToServerOpnum);
+       Stream_SealLength(s);
+       status = rpc_client_write_call(tsg->rpc, Stream_Buffer(s), Stream_Length(s), TsProxySendToServerOpnum);
        Stream_Free(s, TRUE);
 
        if (status <= 0)
@@ -215,7 +215,7 @@ BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg)
        CopyMemory(&buffer[88], &NDR_UUID, sizeof(p_uuid_t));
        *((UINT32*) &buffer[104]) = NDR_SYNTAX_IF_VERSION;
 
-       status = rpc_write(rpc, buffer, length, TsProxyCreateTunnelOpnum);
+       status = rpc_client_write_call(rpc, buffer, length, TsProxyCreateTunnelOpnum);
 
        if (status <= 0)
                return FALSE;
@@ -601,7 +601,7 @@ BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSE
        ZeroMemory(&buffer[offset - pad], pad);
        *((UINT32*) &buffer[offset]) = 0x00000000; /* MaxCount */
        offset += 4;
-       status = rpc_write(rpc, buffer, length, TsProxyAuthorizeTunnelOpnum);
+       status = rpc_client_write_call(rpc, buffer, length, TsProxyAuthorizeTunnelOpnum);
 
        if (status <= 0)
                return FALSE;
@@ -763,7 +763,7 @@ BOOL TsProxyMakeTunnelCallWriteRequest(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSER
        *((UINT32*) &buffer[28]) = TSG_PACKET_TYPE_MSGREQUEST_PACKET; /* SwitchValue */
        *((UINT32*) &buffer[32]) = 0x00020000; /* PacketMsgRequestPtr */
        *((UINT32*) &buffer[36]) = 0x00000001; /* MaxMessagesPerBatch */
-       status = rpc_write(rpc, buffer, length, TsProxyMakeTunnelCallOpnum);
+       status = rpc_client_write_call(rpc, buffer, length, TsProxyMakeTunnelCallOpnum);
 
        if (status <= 0)
                return FALSE;
@@ -962,7 +962,7 @@ BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERI
        *((UINT32*) &buffer[52]) = 0; /* Offset */
        *((UINT32*) &buffer[56]) = count; /* ActualCount */
        CopyMemory(&buffer[60], tsg->Hostname, count * 2); /* Array */
-       status = rpc_write(rpc, buffer, length, TsProxyCreateChannelOpnum);
+       status = rpc_client_write_call(rpc, buffer, length, TsProxyCreateChannelOpnum);
 
        if (status <= 0)
                return FALSE;
@@ -1035,7 +1035,7 @@ BOOL TsProxyCloseChannelWriteRequest(rdpTsg* tsg, PCHANNEL_CONTEXT_HANDLE_NOSERI
        /* TunnelContext */
        CopyMemory(&buffer[0], &tsg->ChannelContext.ContextType, 4); /* ContextType */
        CopyMemory(&buffer[4], tsg->ChannelContext.ContextUuid, 16); /* ContextUuid */
-       status = rpc_write(rpc, buffer, length, TsProxyCloseChannelOpnum);
+       status = rpc_client_write_call(rpc, buffer, length, TsProxyCloseChannelOpnum);
 
        if (status <= 0)
                return FALSE;
@@ -1099,7 +1099,7 @@ BOOL TsProxyCloseTunnelWriteRequest(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_SERIALIZ
        /* TunnelContext */
        CopyMemory(&buffer[0], &tsg->TunnelContext.ContextType, 4); /* ContextType */
        CopyMemory(&buffer[4], tsg->TunnelContext.ContextUuid, 16); /* ContextUuid */
-       status = rpc_write(rpc, buffer, length, TsProxyCloseTunnelOpnum);
+       status = rpc_client_write_call(rpc, buffer, length, TsProxyCloseTunnelOpnum);
 
        if (status <= 0)
                return FALSE;
@@ -1163,7 +1163,7 @@ BOOL TsProxySetupReceivePipeWriteRequest(rdpTsg* tsg)
        /* ChannelContext */
        CopyMemory(&buffer[0], &tsg->ChannelContext.ContextType, 4); /* ContextType */
        CopyMemory(&buffer[4], tsg->ChannelContext.ContextUuid, 16); /* ContextUuid */
-       status = rpc_write(rpc, buffer, length, TsProxySetupReceivePipeOpnum);
+       status = rpc_client_write_call(rpc, buffer, length, TsProxySetupReceivePipeOpnum);
 
        if (status <= 0)
                return FALSE;