summaryrefslogtreecommitdiffstats
path: root/libfreerdp/core/gateway/rpc.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:24:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:24:41 +0000
commita9bcc81f821d7c66f623779fa5147e728eb3c388 (patch)
tree98676963bcdd537ae5908a067a8eb110b93486a6 /libfreerdp/core/gateway/rpc.h
parentInitial commit. (diff)
downloadfreerdp3-a9bcc81f821d7c66f623779fa5147e728eb3c388.tar.xz
freerdp3-a9bcc81f821d7c66f623779fa5147e728eb3c388.zip
Adding upstream version 3.3.0+dfsg1.upstream/3.3.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libfreerdp/core/gateway/rpc.h')
-rw-r--r--libfreerdp/core/gateway/rpc.h796
1 files changed, 796 insertions, 0 deletions
diff --git a/libfreerdp/core/gateway/rpc.h b/libfreerdp/core/gateway/rpc.h
new file mode 100644
index 0000000..73b9998
--- /dev/null
+++ b/libfreerdp/core/gateway/rpc.h
@@ -0,0 +1,796 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * RPC over HTTP
+ *
+ * Copyright 2012 Fujitsu Technology Solutions GmbH
+ * Copyright 2012 Dmitrij Jasnov <dmitrij.jasnov@ts.fujitsu.com>
+ * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FREERDP_LIB_CORE_GATEWAY_RPC_H
+#define FREERDP_LIB_CORE_GATEWAY_RPC_H
+
+#include <winpr/wtypes.h>
+#include <winpr/stream.h>
+#include <winpr/collections.h>
+#include <winpr/interlocked.h>
+
+#include <freerdp/log.h>
+#include <freerdp/utils/ringbuffer.h>
+
+#include "../../crypto/tls.h"
+
+typedef struct rdp_rpc rdpRpc;
+
+#pragma pack(push, 1)
+
+typedef struct
+{
+ BYTE rpc_vers;
+ BYTE rpc_vers_minor;
+ BYTE ptype;
+ BYTE pfc_flags;
+ BYTE packed_drep[4];
+ UINT16 frag_length;
+ UINT16 auth_length;
+ UINT32 call_id;
+} rpcconn_common_hdr_t;
+
+#define RPC_COMMON_FIELDS_LENGTH sizeof(rpcconn_common_hdr_t)
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ UINT16 Flags;
+ UINT16 NumberOfCommands;
+} rpcconn_rts_hdr_t;
+
+#define RTS_PDU_HEADER_LENGTH 20
+
+#define RPC_PDU_FLAG_STUB 0x00000001
+
+typedef struct
+{
+ wStream* s;
+ UINT32 Type;
+ UINT32 Flags;
+ UINT32 CallId;
+} RPC_PDU, *PRPC_PDU;
+
+#pragma pack(pop)
+
+#include "../tcp.h"
+#include "../transport.h"
+
+#include "http.h"
+#include "../credssp_auth.h"
+
+#include <time.h>
+
+#include <winpr/sspi.h>
+#include <winpr/interlocked.h>
+
+#include <freerdp/types.h>
+#include <freerdp/settings.h>
+#include <freerdp/crypto/crypto.h>
+#include <freerdp/api.h>
+
+#include <winpr/print.h>
+
+/**
+ * CAE Specification
+ * DCE 1.1: Remote Procedure Call
+ * Document Number: C706
+ * http://pubs.opengroup.org/onlinepubs/9629399/
+ */
+
+#define PTYPE_REQUEST 0x00
+#define PTYPE_PING 0x01
+#define PTYPE_RESPONSE 0x02
+#define PTYPE_FAULT 0x03
+#define PTYPE_WORKING 0x04
+#define PTYPE_NOCALL 0x05
+#define PTYPE_REJECT 0x06
+#define PTYPE_ACK 0x07
+#define PTYPE_CL_CANCEL 0x08
+#define PTYPE_FACK 0x09
+#define PTYPE_CANCEL_ACK 0x0A
+#define PTYPE_BIND 0x0B
+#define PTYPE_BIND_ACK 0x0C
+#define PTYPE_BIND_NAK 0x0D
+#define PTYPE_ALTER_CONTEXT 0x0E
+#define PTYPE_ALTER_CONTEXT_RESP 0x0F
+#define PTYPE_RPC_AUTH_3 0x10
+#define PTYPE_SHUTDOWN 0x11
+#define PTYPE_CO_CANCEL 0x12
+#define PTYPE_ORPHANED 0x13
+#define PTYPE_RTS 0x14
+
+#define PFC_FIRST_FRAG 0x01
+#define PFC_LAST_FRAG 0x02
+#define PFC_PENDING_CANCEL 0x04
+#define PFC_SUPPORT_HEADER_SIGN 0x04
+#define PFC_RESERVED_1 0x08
+#define PFC_CONC_MPX 0x10
+#define PFC_DID_NOT_EXECUTE 0x20
+#define PFC_MAYBE 0x40
+#define PFC_OBJECT_UUID 0x80
+
+/* Minimum fragment sizes */
+#define RPC_CO_MUST_RECV_FRAG_SIZE 1432
+#define RPC_CL_MUST_RECV_FRAG_SIZE 1464
+
+/**
+ * The PDU maximum header length is enough
+ * to contain either the RPC common fields
+ * or all fields up to the stub data in PDUs
+ * that use it (request, response, fault)
+ */
+#define RPC_PDU_HEADER_MAX_LENGTH 32
+
+#pragma pack(push, 1)
+
+typedef UINT16 p_context_id_t;
+typedef UINT16 p_reject_reason_t;
+
+typedef struct
+{
+ UINT32 time_low;
+ UINT16 time_mid;
+ UINT16 time_hi_and_version;
+ BYTE clock_seq_hi_and_reserved;
+ BYTE clock_seq_low;
+ BYTE node[6];
+} p_uuid_t;
+
+#define ndr_c_int_big_endian 0
+#define ndr_c_int_little_endian 1
+#define ndr_c_float_ieee 0
+#define ndr_c_float_vax 1
+#define ndr_c_float_cray 2
+#define ndr_c_float_ibm 3
+#define ndr_c_char_ascii 0
+#define ndr_c_char_ebcdic 1
+
+typedef struct
+{
+ BYTE int_rep;
+ BYTE char_rep;
+ BYTE float_rep;
+ BYTE reserved;
+} ndr_format_t, *ndr_format_p_t;
+
+typedef struct ndr_context_handle
+{
+ UINT32 context_handle_attributes;
+ p_uuid_t context_handle_uuid;
+} ndr_context_handle;
+
+typedef struct
+{
+ p_uuid_t if_uuid;
+ UINT32 if_version;
+} p_syntax_id_t;
+
+typedef struct
+{
+ p_context_id_t p_cont_id;
+ BYTE n_transfer_syn; /* number of items */
+ BYTE reserved; /* alignment pad, m.b.z. */
+ p_syntax_id_t abstract_syntax; /* transfer syntax list */
+ p_syntax_id_t* transfer_syntaxes; /* size_is(n_transfer_syn) */
+} p_cont_elem_t;
+
+typedef struct
+{
+ BYTE n_context_elem; /* number of items */
+ BYTE reserved; /* alignment pad, m.b.z. */
+ UINT16 reserved2; /* alignment pad, m.b.z. */
+ p_cont_elem_t* p_cont_elem; /* size_is(n_cont_elem) */
+} p_cont_list_t;
+
+typedef enum
+{
+ acceptance,
+ user_rejection,
+ provider_rejection
+} p_cont_def_result_t;
+
+typedef enum
+{
+ reason_not_specified,
+ abstract_syntax_not_supported,
+ proposed_transfer_syntaxes_not_supported,
+ local_limit_exceeded
+} p_provider_reason_t;
+
+typedef struct
+{
+ p_cont_def_result_t result;
+ p_provider_reason_t reason;
+ p_syntax_id_t transfer_syntax;
+} p_result_t;
+
+/* Same order and number of elements as in bind request */
+
+typedef struct
+{
+ BYTE n_results; /* count */
+ BYTE reserved; /* alignment pad, m.b.z. */
+ UINT16 reserved2; /* alignment pad, m.b.z. */
+ p_result_t* p_results; /* size_is(n_results) */
+} p_result_list_t;
+
+typedef struct
+{
+ BYTE major;
+ BYTE minor;
+} version_t;
+typedef version_t p_rt_version_t;
+
+typedef struct
+{
+ BYTE n_protocols; /* count */
+ p_rt_version_t* p_protocols; /* size_is(n_protocols) */
+} p_rt_versions_supported_t;
+
+typedef struct
+{
+ UINT16 length;
+ char* port_spec; /* port string spec; size_is(length) */
+} port_any_t;
+
+#define REASON_NOT_SPECIFIED 0
+#define TEMPORARY_CONGESTION 1
+#define LOCAL_LIMIT_EXCEEDED 2
+#define CALLED_PADDR_UNKNOWN 3
+#define PROTOCOL_VERSION_NOT_SUPPORTED 4
+#define DEFAULT_CONTEXT_NOT_SUPPORTED 5
+#define USER_DATA_NOT_READABLE 6
+#define NO_PSAP_AVAILABLE 7
+
+typedef UINT16 rpcrt_reason_code_t;
+
+typedef struct
+{
+ BYTE rpc_vers;
+ BYTE rpc_vers_minor;
+ BYTE reserved[2];
+ BYTE packed_drep[4];
+ UINT32 reject_status;
+ BYTE reserved2[4];
+} rpcrt_optional_data_t;
+
+typedef struct
+{
+ rpcrt_reason_code_t reason_code;
+ rpcrt_optional_data_t rpc_info;
+} rpcconn_reject_optional_data_t;
+
+typedef struct
+{
+ rpcrt_reason_code_t reason_code;
+ rpcrt_optional_data_t rpc_info;
+} rpcconn_disc_optional_data_t;
+
+typedef struct
+{
+ BYTE signature[8];
+} rpc_sec_verification_trailer;
+
+struct auth_verifier_co_s
+{
+ /* restore 4-byte alignment */
+
+ BYTE auth_type;
+ BYTE auth_level;
+ BYTE auth_pad_length;
+ BYTE auth_reserved;
+ UINT32 auth_context_id;
+
+ BYTE* auth_value;
+};
+
+typedef struct auth_verifier_co_s rpc_sec_trailer;
+typedef struct auth_verifier_co_s auth_verifier_co_t;
+
+/* Connection-oriented PDU Definitions */
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ UINT16 max_xmit_frag;
+ UINT16 max_recv_frag;
+ UINT32 assoc_group_id;
+
+ p_cont_list_t p_context_elem;
+
+ auth_verifier_co_t auth_verifier;
+
+} rpcconn_alter_context_hdr_t;
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ UINT16 max_xmit_frag;
+ UINT16 max_recv_frag;
+ UINT32 assoc_group_id;
+ port_any_t sec_addr;
+
+ /* restore 4-octet alignment */
+
+ p_result_list_t p_result_list;
+
+ auth_verifier_co_t auth_verifier;
+} rpcconn_alter_context_response_hdr_t;
+
+/* bind header */
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ UINT16 max_xmit_frag;
+ UINT16 max_recv_frag;
+ UINT32 assoc_group_id;
+
+ p_cont_list_t p_context_elem;
+
+ auth_verifier_co_t auth_verifier;
+} rpcconn_bind_hdr_t;
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ UINT16 max_xmit_frag;
+ UINT16 max_recv_frag;
+ UINT32 assoc_group_id;
+
+ port_any_t sec_addr;
+
+ /* restore 4-octet alignment */
+
+ p_result_list_t p_result_list;
+
+ auth_verifier_co_t auth_verifier;
+} rpcconn_bind_ack_hdr_t;
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ UINT16 max_xmit_frag;
+ UINT16 max_recv_frag;
+
+ auth_verifier_co_t auth_verifier;
+} rpcconn_rpc_auth_3_hdr_t;
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ p_reject_reason_t provider_reject_reason;
+
+ p_rt_versions_supported_t versions;
+} rpcconn_bind_nak_hdr_t;
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ auth_verifier_co_t auth_verifier;
+
+} rpcconn_cancel_hdr_t;
+
+#pragma pack(pop)
+
+/* fault codes */
+
+typedef struct
+{
+ UINT32 code;
+ const char* name;
+ const char* category;
+} RPC_FAULT_CODE;
+
+#define DEFINE_RPC_FAULT_CODE(_code, cat) \
+ { \
+ _code, #_code, cat \
+ }
+
+#define nca_s_comm_failure 0x1C010001
+#define nca_s_op_rng_error 0x1C010002
+#define nca_s_unk_if 0x1C010003
+#define nca_s_wrong_boot_time 0x1C010006
+#define nca_s_you_crashed 0x1C010009
+#define nca_s_proto_error 0x1C01000B
+#define nca_s_out_args_too_big 0x1C010013
+#define nca_s_server_too_busy 0x1C010014
+#define nca_s_fault_string_too_long 0x1C010015
+#define nca_s_unsupported_type 0x1C010017
+#define nca_s_fault_int_div_by_zero 0x1C000001
+#define nca_s_fault_addr_error 0x1C000002
+#define nca_s_fault_fp_div_zero 0x1C000003
+#define nca_s_fault_fp_underflow 0x1C000004
+#define nca_s_fault_fp_overflow 0x1C000005
+#define nca_s_fault_invalid_tag 0x1C000006
+#define nca_s_fault_invalid_bound 0x1C000007
+#define nca_s_rpc_version_mismatch 0x1C000008
+#define nca_s_unspec_reject 0x1C000009
+#define nca_s_bad_actid 0x1C00000A
+#define nca_s_who_are_you_failed 0x1C00000B
+#define nca_s_manager_not_entered 0x1C00000C
+#define nca_s_fault_cancel 0x1C00000D
+#define nca_s_fault_ill_inst 0x1C00000E
+#define nca_s_fault_fp_error 0x1C00000F
+#define nca_s_fault_int_overflow 0x1C000010
+#define nca_s_fault_unspec 0x1C000012
+#define nca_s_fault_remote_comm_failure 0x1C000013
+#define nca_s_fault_pipe_empty 0x1C000014
+#define nca_s_fault_pipe_closed 0x1C000015
+#define nca_s_fault_pipe_order 0x1C000016
+#define nca_s_fault_pipe_discipline 0x1C000017
+#define nca_s_fault_pipe_comm_error 0x1C000018
+#define nca_s_fault_pipe_memory 0x1C000019
+#define nca_s_fault_context_mismatch 0x1C00001A
+#define nca_s_fault_remote_no_memory 0x1C00001B
+#define nca_s_invalid_pres_context_id 0x1C00001C
+#define nca_s_unsupported_authn_level 0x1C00001D
+#define nca_s_invalid_checksum 0x1C00001F
+#define nca_s_invalid_crc 0x1C000020
+#define nca_s_fault_user_defined 0x1C000021
+#define nca_s_fault_tx_open_failed 0x1C000022
+#define nca_s_fault_codeset_conv_error 0x1C000023
+#define nca_s_fault_object_not_found 0x1C000024
+#define nca_s_fault_no_client_stub 0x1C000025
+
+#pragma pack(push, 1)
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ UINT32 alloc_hint;
+ p_context_id_t p_cont_id;
+
+ BYTE cancel_count;
+ BYTE reserved;
+
+ UINT32 status;
+
+ /* align(8) */
+
+ BYTE* stub_data;
+
+ auth_verifier_co_t auth_verifier;
+} rpcconn_fault_hdr_t;
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ auth_verifier_co_t auth_verifier;
+} rpcconn_orphaned_hdr_t;
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ UINT32 alloc_hint;
+
+ p_context_id_t p_cont_id;
+ UINT16 opnum;
+
+ /* optional field for request, only present if the PFC_OBJECT_UUID field is non-zero */
+ p_uuid_t object;
+
+ /* align(8) */
+
+ BYTE* stub_data;
+
+ auth_verifier_co_t auth_verifier;
+} rpcconn_request_hdr_t;
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+
+ UINT32 alloc_hint;
+ p_context_id_t p_cont_id;
+
+ BYTE cancel_count;
+ BYTE reserved;
+
+ /* align(8) */
+
+ BYTE* stub_data;
+
+ auth_verifier_co_t auth_verifier;
+} rpcconn_response_hdr_t;
+
+typedef struct
+{
+ rpcconn_common_hdr_t header;
+} rpcconn_shutdown_hdr_t;
+
+typedef union
+{
+ rpcconn_common_hdr_t common;
+ rpcconn_alter_context_hdr_t alter_context;
+ rpcconn_alter_context_response_hdr_t alter_context_response;
+ rpcconn_bind_hdr_t bind;
+ rpcconn_bind_ack_hdr_t bind_ack;
+ rpcconn_rpc_auth_3_hdr_t rpc_auth_3;
+ rpcconn_bind_nak_hdr_t bind_nak;
+ rpcconn_cancel_hdr_t cancel;
+ rpcconn_fault_hdr_t fault;
+ rpcconn_orphaned_hdr_t orphaned;
+ rpcconn_request_hdr_t request;
+ rpcconn_response_hdr_t response;
+ rpcconn_shutdown_hdr_t shutdown;
+ rpcconn_rts_hdr_t rts;
+} rpcconn_hdr_t;
+
+#pragma pack(pop)
+
+typedef struct
+{
+ UINT32 Id;
+ LONG EvenLegs;
+ LONG NumLegs;
+} RPC_SECURITY_PROVIDER_INFO;
+
+typedef enum
+{
+ RPC_CLIENT_STATE_INITIAL,
+ RPC_CLIENT_STATE_ESTABLISHED,
+ RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK,
+ RPC_CLIENT_STATE_WAIT_UNSECURE_BIND_ACK,
+ RPC_CLIENT_STATE_WAIT_SECURE_ALTER_CONTEXT_RESPONSE,
+ RPC_CLIENT_STATE_CONTEXT_NEGOTIATED,
+ RPC_CLIENT_STATE_WAIT_RESPONSE,
+ RPC_CLIENT_STATE_FINAL
+} RPC_CLIENT_STATE;
+
+typedef enum
+{
+ RPC_CLIENT_CALL_STATE_INITIAL,
+ RPC_CLIENT_CALL_STATE_SEND_PDUS,
+ RPC_CLIENT_CALL_STATE_DISPATCHED,
+ RPC_CLIENT_CALL_STATE_RECEIVE_PDU,
+ RPC_CLIENT_CALL_STATE_COMPLETE,
+ RPC_CLIENT_CALL_STATE_FAULT,
+ RPC_CLIENT_CALL_STATE_FINAL
+} RPC_CLIENT_CALL_STATE;
+
+typedef struct
+{
+ UINT32 CallId;
+ UINT32 OpNum;
+ RPC_CLIENT_CALL_STATE State;
+} RpcClientCall;
+
+typedef struct
+{
+ rdpContext* context;
+ RPC_PDU* pdu;
+ HANDLE PipeEvent;
+ RingBuffer ReceivePipe;
+ wStream* ReceiveFragment;
+ CRITICAL_SECTION PipeLock;
+ wArrayList* ClientCallList;
+ char* host;
+ UINT16 port;
+ BOOL isProxy;
+} RpcClient;
+
+typedef struct
+{
+ RpcClient* client;
+ BIO* bio;
+ rdpTls* tls;
+ rdpCredsspAuth* auth;
+ HttpContext* http;
+ GUID Cookie;
+ rdpRpc* rpc;
+} RpcChannel;
+
+/* Ping Originator */
+
+typedef struct
+{
+ UINT32 ConnectionTimeout;
+ UINT32 LastPacketSentTimestamp;
+ UINT32 KeepAliveInterval;
+} RpcPingOriginator;
+
+/* Client In Channel */
+
+typedef enum
+{
+ CLIENT_IN_CHANNEL_STATE_INITIAL,
+ CLIENT_IN_CHANNEL_STATE_CONNECTED,
+ CLIENT_IN_CHANNEL_STATE_SECURITY,
+ CLIENT_IN_CHANNEL_STATE_NEGOTIATED,
+ CLIENT_IN_CHANNEL_STATE_OPENED,
+ CLIENT_IN_CHANNEL_STATE_OPENED_A4W,
+ CLIENT_IN_CHANNEL_STATE_FINAL
+} CLIENT_IN_CHANNEL_STATE;
+
+typedef struct
+{
+ /* Sending Channel */
+
+ RpcChannel common;
+
+ CLIENT_IN_CHANNEL_STATE State;
+
+ UINT32 PlugState;
+ void* SendQueue;
+ UINT32 BytesSent;
+ UINT32 SenderAvailableWindow;
+ UINT32 PeerReceiveWindow;
+
+ /* Ping Originator */
+
+ RpcPingOriginator PingOriginator;
+} RpcInChannel;
+
+/* Client Out Channel */
+
+typedef enum
+{
+ CLIENT_OUT_CHANNEL_STATE_INITIAL,
+ CLIENT_OUT_CHANNEL_STATE_CONNECTED,
+ CLIENT_OUT_CHANNEL_STATE_SECURITY,
+ CLIENT_OUT_CHANNEL_STATE_NEGOTIATED,
+ CLIENT_OUT_CHANNEL_STATE_OPENED,
+ CLIENT_OUT_CHANNEL_STATE_OPENED_A6W,
+ CLIENT_OUT_CHANNEL_STATE_OPENED_A10W,
+ CLIENT_OUT_CHANNEL_STATE_OPENED_B3W,
+ CLIENT_OUT_CHANNEL_STATE_RECYCLED,
+ CLIENT_OUT_CHANNEL_STATE_FINAL
+} CLIENT_OUT_CHANNEL_STATE;
+
+typedef struct
+{
+ /* Receiving Channel */
+
+ RpcChannel common;
+
+ CLIENT_OUT_CHANNEL_STATE State;
+
+ UINT32 ReceiveWindow;
+ UINT32 ReceiveWindowSize;
+ UINT32 ReceiverAvailableWindow;
+ UINT32 BytesReceived;
+ UINT32 AvailableWindowAdvertised;
+} RpcOutChannel;
+
+/* Client Virtual Connection */
+
+typedef enum
+{
+ VIRTUAL_CONNECTION_STATE_INITIAL,
+ VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT,
+ VIRTUAL_CONNECTION_STATE_WAIT_A3W,
+ VIRTUAL_CONNECTION_STATE_WAIT_C2,
+ VIRTUAL_CONNECTION_STATE_OPENED,
+ VIRTUAL_CONNECTION_STATE_FINAL
+} VIRTUAL_CONNECTION_STATE;
+
+typedef struct
+{
+ GUID Cookie;
+ GUID AssociationGroupId;
+ VIRTUAL_CONNECTION_STATE State;
+ RpcInChannel* DefaultInChannel;
+ RpcInChannel* NonDefaultInChannel;
+ RpcOutChannel* DefaultOutChannel;
+ RpcOutChannel* NonDefaultOutChannel;
+} RpcVirtualConnection;
+
+/* Virtual Connection Cookie Table */
+
+#define RPC_UUID_FORMAT_STRING \
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
+#define RPC_UUID_FORMAT_ARGUMENTS(_rpc_uuid) \
+ _rpc_uuid[0], _rpc_uuid[1], _rpc_uuid[2], _rpc_uuid[3], _rpc_uuid[4], _rpc_uuid[5], \
+ _rpc_uuid[6], _rpc_uuid[7], _rpc_uuid[8], _rpc_uuid[9], _rpc_uuid[10], _rpc_uuid[11], \
+ _rpc_uuid[12], _rpc_uuid[13], _rpc_uuid[14], _rpc_uuid[15]
+
+typedef struct
+{
+ GUID Cookie;
+ UINT32 ReferenceCount;
+ RpcVirtualConnection* Reference;
+} RpcVirtualConnectionCookieEntry;
+
+struct rdp_rpc
+{
+ RPC_CLIENT_STATE State;
+
+ UINT32 result;
+
+ rdpCredsspAuth* auth;
+ size_t SendSeqNum;
+
+ RpcClient* client;
+
+ rdpTransport* transport;
+
+ UINT32 CallId;
+ UINT32 PipeCallId;
+
+ UINT32 StubCallId;
+ UINT32 StubFragCount;
+
+ BYTE rpc_vers;
+ BYTE rpc_vers_minor;
+ BYTE packed_drep[4];
+
+ UINT16 max_xmit_frag;
+ UINT16 max_recv_frag;
+
+ UINT32 ReceiveWindow;
+ UINT32 ChannelLifetime;
+ UINT32 KeepAliveInterval;
+ UINT32 CurrentKeepAliveTime;
+ UINT32 CurrentKeepAliveInterval;
+
+ RpcVirtualConnection* VirtualConnection;
+ wLog* log;
+};
+
+FREERDP_LOCAL const char* rpc_vc_state_str(VIRTUAL_CONNECTION_STATE state);
+FREERDP_LOCAL void rpc_pdu_header_print(wLog* log, const rpcconn_hdr_t* header);
+FREERDP_LOCAL rpcconn_common_hdr_t rpc_pdu_header_init(const rdpRpc* rpc);
+
+FREERDP_LOCAL size_t rpc_offset_align(size_t* offset, size_t alignment);
+FREERDP_LOCAL size_t rpc_offset_pad(size_t* offset, size_t pad);
+
+FREERDP_LOCAL BOOL rpc_get_stub_data_info(rdpRpc* rpc, const rpcconn_hdr_t* header, size_t* offset,
+ size_t* length);
+
+FREERDP_LOCAL SSIZE_T rpc_channel_write(RpcChannel* channel, const BYTE* data, size_t length);
+
+FREERDP_LOCAL SSIZE_T rpc_channel_read(RpcChannel* channel, wStream* s, size_t length);
+
+FREERDP_LOCAL void rpc_channel_free(RpcChannel* channel);
+
+WINPR_ATTR_MALLOC(rpc_channel_free, 1)
+FREERDP_LOCAL RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc, const GUID* guid);
+FREERDP_LOCAL int rpc_out_channel_replacement_connect(RpcOutChannel* outChannel, int timeout);
+
+FREERDP_LOCAL BOOL rpc_in_channel_transition_to_state(RpcInChannel* inChannel,
+ CLIENT_IN_CHANNEL_STATE state);
+FREERDP_LOCAL BOOL rpc_out_channel_transition_to_state(RpcOutChannel* outChannel,
+ CLIENT_OUT_CHANNEL_STATE state);
+
+FREERDP_LOCAL BOOL rpc_virtual_connection_transition_to_state(rdpRpc* rpc,
+ RpcVirtualConnection* connection,
+ VIRTUAL_CONNECTION_STATE state);
+
+FREERDP_LOCAL BOOL rpc_connect(rdpRpc* rpc, UINT32 timeout);
+
+FREERDP_LOCAL void rpc_free(rdpRpc* rpc);
+
+WINPR_ATTR_MALLOC(rpc_free, 1)
+FREERDP_LOCAL rdpRpc* rpc_new(rdpTransport* transport);
+
+#endif /* FREERDP_LIB_CORE_GATEWAY_RPC_H */