1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * FreeRDP Interface
4  *
5  * Copyright 2009-2011 Jay Sorg
6  * Copyright 2015 Thincast Technologies GmbH
7  * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *     http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifndef FREERDP_H
23 #define FREERDP_H
24 
25 typedef struct rdp_rdp rdpRdp;
26 typedef struct rdp_gdi rdpGdi;
27 typedef struct rdp_rail rdpRail;
28 typedef struct rdp_cache rdpCache;
29 typedef struct rdp_channels rdpChannels;
30 typedef struct rdp_graphics rdpGraphics;
31 typedef struct rdp_metrics rdpMetrics;
32 typedef struct rdp_codecs rdpCodecs;
33 
34 typedef struct rdp_freerdp freerdp;
35 typedef struct rdp_context rdpContext;
36 typedef struct rdp_freerdp_peer freerdp_peer;
37 
38 typedef struct rdp_client_context rdpClientContext;
39 typedef struct rdp_client_entry_points_v1 RDP_CLIENT_ENTRY_POINTS_V1;
40 typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS;
41 
42 #include <freerdp/api.h>
43 #include <freerdp/types.h>
44 #include <freerdp/error.h>
45 #include <freerdp/event.h>
46 #include <freerdp/codecs.h>
47 #include <freerdp/metrics.h>
48 #include <freerdp/settings.h>
49 #include <freerdp/extension.h>
50 
51 #include <winpr/stream.h>
52 
53 #include <freerdp/input.h>
54 #include <freerdp/update.h>
55 #include <freerdp/message.h>
56 #include <freerdp/autodetect.h>
57 #include <freerdp/heartbeat.h>
58 
59 #ifdef __cplusplus
60 extern "C"
61 {
62 #endif
63 
64 /* Flags used by certificate callbacks */
65 #define VERIFY_CERT_FLAG_NONE 0x00
66 #define VERIFY_CERT_FLAG_LEGACY 0x02
67 #define VERIFY_CERT_FLAG_REDIRECT 0x10
68 #define VERIFY_CERT_FLAG_GATEWAY 0x20
69 #define VERIFY_CERT_FLAG_CHANGED 0x40
70 #define VERIFY_CERT_FLAG_MISMATCH 0x80
71 #define VERIFY_CERT_FLAG_MATCH_LEGACY_SHA1 0x100
72 
73 /* Message types used by gateway messaging callback */
74 #define GATEWAY_MESSAGE_CONSENT 1
75 #define GATEWAY_MESSAGE_SERVICE 2
76 
77 	typedef BOOL (*pContextNew)(freerdp* instance, rdpContext* context);
78 	typedef void (*pContextFree)(freerdp* instance, rdpContext* context);
79 
80 	typedef BOOL (*pPreConnect)(freerdp* instance);
81 	typedef BOOL (*pPostConnect)(freerdp* instance);
82 	typedef void (*pPostDisconnect)(freerdp* instance);
83 	typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** password,
84 	                              char** domain);
85 
86 #if !defined(DEFINE_NO_DEPRECATED)
87 	/** @brief Callback used if user interaction is required to accept
88 	 *         an unknown certificate.
89 	 *
90 	 *  @deprecated Use pVerifyCertificateEx
91 	 *  @param common_name      The certificate registered hostname.
92 	 *  @param subject          The common name of the certificate.
93 	 *  @param issuer           The issuer of the certificate.
94 	 *  @param fingerprint      The fingerprint of the certificate.
95 	 *  @param host_mismatch    A flag indicating the certificate
96 	 *                          subject does not match the host connecting to.
97 	 *
98 	 *  @return 1 to accept and store a certificate, 2 to accept
99 	 *          a certificate only for this session, 0 otherwise.
100 	 */
101 	typedef DWORD (*pVerifyCertificate)(freerdp* instance, const char* common_name,
102 	                                    const char* subject, const char* issuer,
103 	                                    const char* fingerprint, BOOL host_mismatch);
104 #endif
105 	/** @brief Callback used if user interaction is required to accept
106 	 *         an unknown certificate.
107 	 *
108 	 *  @param host             The hostname connecting to.
109 	 *  @param port             The port connecting to.
110 	 *  @param common_name      The certificate registered hostname.
111 	 *  @param subject          The common name of the certificate.
112 	 *  @param issuer           The issuer of the certificate.
113 	 *  @param fingerprint      The fingerprint of the certificate.
114 	 *  @param flags            Flags of type VERIFY_CERT_FLAG*
115 	 *
116 	 *  @return 1 to accept and store a certificate, 2 to accept
117 	 *          a certificate only for this session, 0 otherwise.
118 	 */
119 	typedef DWORD (*pVerifyCertificateEx)(freerdp* instance, const char* host, UINT16 port,
120 	                                      const char* common_name, const char* subject,
121 	                                      const char* issuer, const char* fingerprint, DWORD flags);
122 
123 #if !defined(DEFINE_NO_DEPRECATED)
124 	/** @brief Callback used if user interaction is required to accept
125 	 *         a changed certificate.
126 	 *
127 	 *  @deprecated Use pVerifyChangedCertificateEx
128 	 *  @param common_name      The certificate registered hostname.
129 	 *  @param subject          The common name of the new certificate.
130 	 *  @param issuer           The issuer of the new certificate.
131 	 *  @param fingerprint      The fingerprint of the new certificate.
132 	 *  @param old_subject      The common name of the old certificate.
133 	 *  @param old_issuer       The issuer of the new certificate.
134 	 *  @param old_fingerprint  The fingerprint of the old certificate.
135 	 *
136 	 *  @return 1 to accept and store a certificate, 2 to accept
137 	 *          a certificate only for this session, 0 otherwise.
138 	 */
139 
140 	typedef DWORD (*pVerifyChangedCertificate)(freerdp* instance, const char* common_name,
141 	                                           const char* subject, const char* issuer,
142 	                                           const char* new_fingerprint, const char* old_subject,
143 	                                           const char* old_issuer, const char* old_fingerprint);
144 #endif
145 
146 	/** @brief Callback used if user interaction is required to accept
147 	 *         a changed certificate.
148 	 *
149 	 *  @param host             The hostname connecting to.
150 	 *  @param port             The port connecting to.
151 	 *  @param common_name      The certificate registered hostname.
152 	 *  @param subject          The common name of the new certificate.
153 	 *  @param issuer           The issuer of the new certificate.
154 	 *  @param fingerprint      The fingerprint of the new certificate.
155 	 *  @param old_subject      The common name of the old certificate.
156 	 *  @param old_issuer       The issuer of the new certificate.
157 	 *  @param old_fingerprint  The fingerprint of the old certificate.
158 	 *  @param flags            Flags of type VERIFY_CERT_FLAG*
159 	 *
160 	 *  @return 1 to accept and store a certificate, 2 to accept
161 	 *          a certificate only for this session, 0 otherwise.
162 	 */
163 
164 	typedef DWORD (*pVerifyChangedCertificateEx)(freerdp* instance, const char* host, UINT16 port,
165 	                                             const char* common_name, const char* subject,
166 	                                             const char* issuer, const char* new_fingerprint,
167 	                                             const char* old_subject, const char* old_issuer,
168 	                                             const char* old_fingerprint, DWORD flags);
169 
170 	/** @brief Callback used if user interaction is required to accept
171 	 *         a certificate.
172 	 *
173 	 *  @param instance         Pointer to the freerdp instance.
174 	 *  @param data             Pointer to certificate data in PEM format.
175 	 *  @param length           The length of the certificate data.
176 	 *  @param hostname         The hostname connecting to.
177 	 *  @param port             The port connecting to.
178 	 *  @param flags            Flags of type VERIFY_CERT_FLAG*
179 	 *
180 	 *  @return 1 to accept and store a certificate, 2 to accept
181 	 *          a certificate only for this session, 0 otherwise.
182 	 */
183 	typedef int (*pVerifyX509Certificate)(freerdp* instance, const BYTE* data, size_t length,
184 	                                      const char* hostname, UINT16 port, DWORD flags);
185 
186 	typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type);
187 
188 	typedef BOOL (*pSendChannelData)(freerdp* instance, UINT16 channelId, const BYTE* data,
189 	                                 size_t size);
190 	typedef BOOL (*pReceiveChannelData)(freerdp* instance, UINT16 channelId, const BYTE* data,
191 	                                    size_t size, UINT32 flags, size_t totalSize);
192 
193 	/* type can be one of the GATEWAY_MESSAGE_ type defines */
194 	typedef BOOL (*pPresentGatewayMessage)(freerdp* instance, UINT32 type, BOOL isDisplayMandatory,
195 	                                       BOOL isConsentMandatory, size_t length,
196 	                                       const WCHAR* message);
197 
198 	/**
199 	 * Defines the context for a given instance of RDP connection.
200 	 * It is embedded in the rdp_freerdp structure, and allocated by a call to
201 	 * freerdp_context_new(). It is deallocated by a call to freerdp_context_free().
202 	 */
203 	struct rdp_context
204 	{
205 		ALIGN64 freerdp* instance;  /**< (offset 0)
206 		                       Pointer to a rdp_freerdp structure.
207 		                       This is a back-link to retrieve the freerdp instance from the context.
208 		                       It is set by the freerdp_context_new() function */
209 		ALIGN64 freerdp_peer* peer; /**< (offset 1)
210 		                       Pointer to the client peer.
211 		                       This is set by a call to freerdp_peer_context_new() during peer
212 		                       initialization. This field is used only on the server side. */
213 		ALIGN64 BOOL ServerMode;    /**< (offset 2) true when context is in server mode */
214 
215 		ALIGN64 UINT32 LastError; /* 3 */
216 
217 		UINT64 paddingA[16 - 4]; /* 4 */
218 
219 		ALIGN64 int argc;    /**< (offset 16)
220 		                Number of arguments given to the program at launch time.
221 		                Used to keep this data available and used later on, typically just before
222 		                connection initialization.
223 		                @see freerdp_parse_args() */
224 		ALIGN64 char** argv; /**< (offset 17)
225 		                List of arguments given to the program at launch time.
226 		                Used to keep this data available and used later on, typically just before
227 		                connection initialization.
228 		                @see freerdp_parse_args() */
229 
230 		ALIGN64 wPubSub* pubSub; /* (offset 18) */
231 
232 		ALIGN64 HANDLE channelErrorEvent; /* (offset 19)*/
233 		ALIGN64 UINT channelErrorNum;     /*(offset 20)*/
234 		ALIGN64 char* errorDescription;   /*(offset 21)*/
235 
236 		UINT64 paddingB[32 - 22]; /* 22 */
237 
238 		ALIGN64 rdpRdp*
239 		    rdp;                           /**< (offset 32)
240 		                              Pointer to a rdp_rdp structure used to keep the connection's parameters.
241 		                              It is allocated by freerdp_context_new() and deallocated by
242 		                              freerdp_context_free(), at the same		       time that this rdp_context
243 		                              structure -		       there is no need to specifically allocate/deallocate this. */
244 		ALIGN64 rdpGdi* gdi;               /**< (offset 33)
245 		                              Pointer to a rdp_gdi structure used to keep the gdi settings.
246 		                              It is allocated by gdi_init() and deallocated by gdi_free().
247 		                              It must be deallocated before deallocating this rdp_context structure. */
248 		ALIGN64 rdpRail* rail;             /* 34 */
249 		ALIGN64 rdpCache* cache;           /* 35 */
250 		ALIGN64 rdpChannels* channels;     /* 36 */
251 		ALIGN64 rdpGraphics* graphics;     /* 37 */
252 		ALIGN64 rdpInput* input;           /* 38 */
253 		ALIGN64 rdpUpdate* update;         /* 39 */
254 		ALIGN64 rdpSettings* settings;     /* 40 */
255 		ALIGN64 rdpMetrics* metrics;       /* 41 */
256 		ALIGN64 rdpCodecs* codecs;         /* 42 */
257 		ALIGN64 rdpAutoDetect* autodetect; /* 43 */
258 		ALIGN64 HANDLE abortEvent;         /* 44 */
259 		ALIGN64 int disconnectUltimatum;   /* 45 */
260 		UINT64 paddingC[64 - 46];          /* 46 */
261 
262 		UINT64 paddingD[96 - 64];  /* 64 */
263 		UINT64 paddingE[128 - 96]; /* 96 */
264 	};
265 
266 	/**
267 	 *  Defines the possible disconnect reasons in the MCS Disconnect Provider
268 	 *  Ultimatum PDU
269 	 */
270 
271 	enum Disconnect_Ultimatum
272 	{
273 		Disconnect_Ultimatum_domain_disconnected = 0,
274 		Disconnect_Ultimatum_provider_initiated = 1,
275 		Disconnect_Ultimatum_token_purged = 2,
276 		Disconnect_Ultimatum_user_requested = 3,
277 		Disconnect_Ultimatum_channel_purged = 4
278 	};
279 
280 #include <freerdp/client.h>
281 
282 	/** Defines the options for a given instance of RDP connection.
283 	 *  This is built by the client and given to the FreeRDP library to create the connection
284 	 *  with the expected options.
285 	 *  It is allocated by a call to freerdp_new() and deallocated by a call to freerdp_free().
286 	 *  Some of its content need specific allocation/deallocation - see field description for
287 	 * details.
288 	 */
289 	struct rdp_freerdp
290 	{
291 		ALIGN64
292 		rdpContext* context; /**< (offset 0)
293 		                  Pointer to a rdpContext structure.
294 		                  Client applications can use the ContextSize field to register a
295 		                  context bigger than the rdpContext structure. This allow clients to
296 		                  use additional context information. When using this capability, client
297 		                  application should ALWAYS declare their structure with the rdpContext
298 		                  field first, and any additional content following it. Can be allocated
299 		                  by a call to freerdp_context_new(). Must be deallocated by a call to
300 		                  freerdp_context_free() before deallocating the current instance. */
301 
302 		ALIGN64 RDP_CLIENT_ENTRY_POINTS* pClientEntryPoints;
303 
304 		UINT64 paddingA[16 - 2]; /* 2 */
305 
306 		ALIGN64 rdpInput* input; /* (offset 16)
307 		                    Input handle for the connection.
308 		                    Will be initialized by a call to freerdp_context_new() */
309 		ALIGN64 rdpUpdate*
310 		    update;                        /* (offset 17)
311 		                              Update display parameters. Used to register display events callbacks and settings.
312 		                              Will be initialized by a call to freerdp_context_new() */
313 		ALIGN64 rdpSettings* settings;     /**< (offset 18)
314 		                                Pointer to a rdpSettings structure. Will be used to maintain the
315 		                                required RDP	 settings.		              Will be
316 		                                initialized by	 a call to freerdp_context_new()
317 		                              */
318 		ALIGN64 rdpAutoDetect* autodetect; /* (offset 19)
319 		                                Auto-Detect handle for the connection.
320 		                                Will be initialized by a call to freerdp_context_new() */
321 		ALIGN64 rdpHeartbeat* heartbeat;   /* (offset 21) */
322 
323 		UINT64 paddingB[32 - 21]; /* 21 */
324 
325 		ALIGN64 size_t
326 		    ContextSize; /* (offset 32)
327 		             Specifies the size of the 'context' field. freerdp_context_new() will use this
328 		             size to allocate the context buffer. freerdp_new() sets it to
329 		             sizeof(rdpContext). If modifying it, there should always be a minimum of
330 		             sizeof(rdpContext), as the freerdp library will assume it can use the 'context'
331 		             field to set the required informations in it. Clients will typically make it
332 		             bigger, and use a context structure embedding the rdpContext, and adding
333 		             additional information after that.
334 		          */
335 
336 		ALIGN64 pContextNew
337 		    ContextNew; /**< (offset 33)
338 		             Callback for context allocation
339 		             Can be set before calling freerdp_context_new() to have it executed after
340 		             allocation and initialization. Must be set to NULL if not needed. */
341 
342 		ALIGN64 pContextFree
343 		    ContextFree;          /**< (offset 34)
344 		                       Callback for context deallocation
345 		                       Can be set before calling freerdp_context_free() to have it executed before
346 		                       deallocation.		  Must be set to NULL if not needed. */
347 		UINT64 paddingC[47 - 35]; /* 35 */
348 
349 		ALIGN64 UINT ConnectionCallbackState; /* 47 */
350 
351 		ALIGN64 pPreConnect
352 		    PreConnect; /**< (offset 48)
353 		             Callback for pre-connect operations.
354 		             Can be set before calling freerdp_connect() to have it executed before the
355 		             actual connection happens. Must be set to NULL if not needed. */
356 
357 		ALIGN64 pPostConnect
358 		    PostConnect; /**< (offset 49)
359 		              Callback for post-connect operations.
360 		              Can be set before calling freerdp_connect() to have it executed after the
361 		              actual connection has succeeded. Must be set to NULL if not needed. */
362 
363 		ALIGN64 pAuthenticate Authenticate;                         /**< (offset 50)
364 		                                                         Callback for authentication.
365 		                                                         It is used to get the username/password when it was not
366 		                                                         provided at connection time. */
367 #if !defined(DEFINE_NO_DEPRECATED)
368 		WINPR_DEPRECATED(ALIGN64 pVerifyCertificate VerifyCertificate); /**< (offset 51)
369 		                                           Callback for certificate validation.
370 		                                           Used to verify that an unknown certificate is
371 	 trusted. DEPRECATED: Use VerifyChangedCertificateEx*/
372 		WINPR_DEPRECATED(
373 		    ALIGN64 pVerifyChangedCertificate VerifyChangedCertificate); /**< (offset 52)
374 		                                            Callback for changed certificate
375 		         validation. Used when a certificate differs from stored fingerprint.
376 		         DEPRECATED: Use VerifyChangedCertificateEx */
377 #endif
378 
379 		ALIGN64 pVerifyX509Certificate
380 		    VerifyX509Certificate; /**< (offset 53)  Callback for X509 certificate verification (PEM
381 		                              format) */
382 
383 		ALIGN64 pLogonErrorInfo
384 		    LogonErrorInfo; /**< (offset 54)  Callback for logon error info, important for logon
385 		                       system messages with RemoteApp */
386 
387 		ALIGN64 pPostDisconnect
388 		    PostDisconnect; /**< (offset 55)
389 		                                                                Callback for cleaning up
390 		                       resources allocated by connect callbacks. */
391 
392 		ALIGN64 pAuthenticate GatewayAuthenticate; /**< (offset 56)
393 		                                 Callback for gateway authentication.
394 		                                 It is used to get the username/password when it was not
395 		                                 provided at connection time. */
396 
397 		ALIGN64 pPresentGatewayMessage PresentGatewayMessage; /**< (offset 57)
398 		                                  Callback for gateway consent messages.
399 		                                  It is used to present consent messages to the user. */
400 
401 		UINT64 paddingD[64 - 58]; /* 58 */
402 
403 		ALIGN64 pSendChannelData
404 		    SendChannelData; /* (offset 64)
405 		                Callback for sending data to a channel.
406 		                By default, it is set by freerdp_new() to freerdp_send_channel_data(), which
407 		                eventually calls freerdp_channel_send() */
408 		ALIGN64 pReceiveChannelData
409 		    ReceiveChannelData; /* (offset 65)
410 		                   Callback for receiving data from a channel.
411 		                   This is called by freerdp_channel_process() (if not NULL).
412 		                   Clients will typically use a function that calls freerdp_channels_data()
413 		                   to perform the needed tasks. */
414 
415 		ALIGN64 pVerifyCertificateEx
416 		    VerifyCertificateEx; /**< (offset 66)
417 		                  Callback for certificate validation.
418 		                  Used to verify that an unknown certificate is trusted. */
419 		ALIGN64 pVerifyChangedCertificateEx
420 		    VerifyChangedCertificateEx; /**< (offset 67)
421 		                         Callback for changed certificate validation.
422 		                         Used when a certificate differs from stored fingerprint. */
423 		UINT64 paddingE[80 - 68];       /* 68 */
424 	};
425 
426 	struct rdp_channel_handles
427 	{
428 		wListDictionary* init;
429 		wListDictionary* open;
430 	};
431 	typedef struct rdp_channel_handles rdpChannelHandles;
432 
433 	FREERDP_API BOOL freerdp_context_new(freerdp* instance);
434 	FREERDP_API void freerdp_context_free(freerdp* instance);
435 
436 	FREERDP_API BOOL freerdp_connect(freerdp* instance);
437 	FREERDP_API BOOL freerdp_abort_connect(freerdp* instance);
438 	FREERDP_API BOOL freerdp_shall_disconnect(freerdp* instance);
439 	FREERDP_API BOOL freerdp_disconnect(freerdp* instance);
440 
441 	FREERDP_API BOOL freerdp_disconnect_before_reconnect(freerdp* instance);
442 	FREERDP_API BOOL freerdp_reconnect(freerdp* instance);
443 
444 	FREERDP_API UINT freerdp_channel_add_init_handle_data(rdpChannelHandles* handles,
445 	                                                      void* pInitHandle, void* pUserData);
446 	FREERDP_API void* freerdp_channel_get_init_handle_data(rdpChannelHandles* handles,
447 	                                                       void* pInitHandle);
448 	FREERDP_API void freerdp_channel_remove_init_handle_data(rdpChannelHandles* handles,
449 	                                                         void* pInitHandle);
450 
451 	FREERDP_API UINT freerdp_channel_add_open_handle_data(rdpChannelHandles* handles,
452 	                                                      DWORD openHandle, void* pUserData);
453 	FREERDP_API void* freerdp_channel_get_open_handle_data(rdpChannelHandles* handles,
454 	                                                       DWORD openHandle);
455 	FREERDP_API void freerdp_channel_remove_open_handle_data(rdpChannelHandles* handles,
456 	                                                         DWORD openHandle);
457 
458 	FREERDP_API UINT freerdp_channels_attach(freerdp* instance);
459 	FREERDP_API UINT freerdp_channels_detach(freerdp* instance);
460 
461 	FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds,
462 	                                 int* wcount);
463 	FREERDP_API BOOL freerdp_check_fds(freerdp* instance);
464 
465 	FREERDP_API DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count);
466 	FREERDP_API BOOL freerdp_check_event_handles(rdpContext* context);
467 
468 	FREERDP_API wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD id);
469 	FREERDP_API HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id);
470 	FREERDP_API int freerdp_message_queue_process_message(freerdp* instance, DWORD id,
471 	                                                      wMessage* message);
472 	FREERDP_API int freerdp_message_queue_process_pending_messages(freerdp* instance, DWORD id);
473 
474 	FREERDP_API UINT32 freerdp_error_info(freerdp* instance);
475 	FREERDP_API void freerdp_set_error_info(rdpRdp* rdp, UINT32 error);
476 	FREERDP_API BOOL freerdp_send_error_info(rdpRdp* rdp);
477 	FREERDP_API BOOL freerdp_get_stats(rdpRdp* rdp, UINT64* inBytes, UINT64* outBytes,
478 	                                   UINT64* inPackets, UINT64* outPackets);
479 
480 	FREERDP_API void freerdp_get_version(int* major, int* minor, int* revision);
481 	FREERDP_API const char* freerdp_get_version_string(void);
482 	FREERDP_API const char* freerdp_get_build_date(void);
483 	FREERDP_API const char* freerdp_get_build_revision(void);
484 	FREERDP_API const char* freerdp_get_build_config(void);
485 
486 	FREERDP_API freerdp* freerdp_new(void);
487 	FREERDP_API void freerdp_free(freerdp* instance);
488 
489 	FREERDP_API BOOL freerdp_focus_required(freerdp* instance);
490 	FREERDP_API void freerdp_set_focus(freerdp* instance);
491 
492 	FREERDP_API int freerdp_get_disconnect_ultimatum(rdpContext* context);
493 
494 	FREERDP_API UINT32 freerdp_get_last_error(rdpContext* context);
495 	FREERDP_API const char* freerdp_get_last_error_name(UINT32 error);
496 	FREERDP_API const char* freerdp_get_last_error_string(UINT32 error);
497 	FREERDP_API const char* freerdp_get_last_error_category(UINT32 error);
498 
499 	FREERDP_API void freerdp_set_last_error(rdpContext* context, UINT32 lastError);
500 
501 #define freerdp_set_last_error_if_not(context, lastError)             \
502 	do                                                                \
503 	{                                                                 \
504 		if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS) \
505 			freerdp_set_last_error_log(context, lastError);           \
506 	} while (0)
507 
508 #define freerdp_set_last_error_log(context, lastError) \
509 	freerdp_set_last_error_ex((context), (lastError), __FUNCTION__, __FILE__, __LINE__)
510 	FREERDP_API void freerdp_set_last_error_ex(rdpContext* context, UINT32 lastError,
511 	                                           const char* fkt, const char* file, int line);
512 
513 	FREERDP_API const char* freerdp_get_logon_error_info_type(UINT32 type);
514 	FREERDP_API const char* freerdp_get_logon_error_info_data(UINT32 data);
515 
516 	FREERDP_API ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount);
517 
518 	FREERDP_API BOOL freerdp_nla_impersonate(rdpContext* context);
519 	FREERDP_API BOOL freerdp_nla_revert_to_self(rdpContext* context);
520 
521 	FREERDP_API void clearChannelError(rdpContext* context);
522 	FREERDP_API HANDLE getChannelErrorEventHandle(rdpContext* context);
523 	FREERDP_API UINT getChannelError(rdpContext* context);
524 	FREERDP_API const char* getChannelErrorDescription(rdpContext* context);
525 	FREERDP_API void setChannelError(rdpContext* context, UINT errorNum, char* description);
526 	FREERDP_API BOOL checkChannelErrorEvent(rdpContext* context);
527 
528 	FREERDP_API const char* freerdp_nego_get_routing_token(rdpContext* context, DWORD* length);
529 
530 #ifdef __cplusplus
531 }
532 #endif
533 
534 #endif /* FREERDP_H */
535