The freerdp type (also spelled rdp_freerdp) is the top-level handle for an RDP client connection. It holds the pointer to the rdpContext and all callbacks that drive connection behaviour.
In typical use you obtain a freerdp instance indirectly through freerdp_client_context_new() → context->instance. When lower-level control is needed you can allocate one directly.
Instance Lifecycle
/* Allocate a bare instance */
freerdp* freerdp_new(void);
/* Free an instance (context must already be freed) */
void freerdp_free(freerdp* instance);
Always call freerdp_context_free() (or freerdp_client_context_free()) before calling freerdp_free(). Freeing the instance before the context is undefined behaviour.
Direct allocation
freerdp* instance = freerdp_new();
if (!instance)
return -1;
/* Set custom context size before allocating the context */
instance->ContextSize = sizeof(MyContext);
instance->ContextNew = my_context_new_cb;
instance->ContextFree = my_context_free_cb;
if (!freerdp_context_new(instance))
goto fail;
/* ... connect, run, disconnect ... */
freerdp_context_free(instance);
fail:
freerdp_free(instance);
Key Fields
Pointer to the associated context. Allocated by freerdp_context_new(). Access settings, channels, GDI, etc. through this field.
The number of bytes to allocate for the context. Defaults to sizeof(rdpContext). Set to sizeof(MyContext) before calling freerdp_context_new() to use an extended context struct.
Internal field tracking whether PreConnect / PostConnect have been called. Do not modify directly.
Connection Callbacks
Set these on the freerdp instance — typically inside your ClientNew (i.e., pRdpClientNew) implementation — before calling freerdp_connect().
Authentication Callbacks
Certificate Verification Callbacks
VERIFY_CERT_FLAG_* Constants
| Constant | Value | Meaning |
|---|
VERIFY_CERT_FLAG_NONE | 0x00 | No special flags |
VERIFY_CERT_FLAG_LEGACY | 0x02 | Legacy certificate format |
VERIFY_CERT_FLAG_REDIRECT | 0x10 | Certificate presented after a redirect |
VERIFY_CERT_FLAG_GATEWAY | 0x20 | Certificate belongs to an RD Gateway |
VERIFY_CERT_FLAG_CHANGED | 0x40 | Certificate differs from stored copy |
VERIFY_CERT_FLAG_MISMATCH | 0x80 | Hostname mismatch detected |
VERIFY_CERT_FLAG_MATCH_LEGACY_SHA1 | 0x100 | Matches a stored legacy SHA-1 fingerprint |
VERIFY_CERT_FLAG_FP_IS_PEM | 0x200 | fingerprint is a PEM-encoded certificate |
Other Callbacks
Context Allocation Callbacks
These are set directly on the freerdp struct (not via RDP_CLIENT_ENTRY_POINTS) when using the lower-level freerdp_context_new() path:
Minimal Example
#include <freerdp/freerdp.h>
#include <freerdp/client.h>
#include <freerdp/client/cmdline.h>
static BOOL my_pre_connect(freerdp* instance)
{
rdpSettings* s = instance->context->settings;
/* Prefer PEM in certificate callbacks */
freerdp_settings_set_bool(s, FreeRDP_CertificateCallbackPreferPEM, TRUE);
return TRUE;
}
static BOOL my_post_connect(freerdp* instance)
{
/* Initialize GDI surface: XRGB32 pixel format */
if (!gdi_init(instance, PIXEL_FORMAT_XRGB32))
return FALSE;
instance->context->update->BeginPaint = my_begin_paint;
instance->context->update->EndPaint = my_end_paint;
return TRUE;
}
static void my_post_disconnect(freerdp* instance)
{
gdi_free(instance);
}
static DWORD my_verify_cert(freerdp* instance, const char* host,
UINT16 port, const char* common_name,
const char* subject, const char* issuer,
const char* fingerprint, DWORD flags)
{
/* Accept without prompting — DO NOT do this in production */
return 2; /* accept for this session only */
}
static BOOL my_client_new(freerdp* instance, rdpContext* context)
{
instance->PreConnect = my_pre_connect;
instance->PostConnect = my_post_connect;
instance->PostDisconnect = my_post_disconnect;
instance->VerifyCertificateEx = my_verify_cert;
return TRUE;
}
static void my_client_free(freerdp* instance, rdpContext* context)
{
(void)instance; (void)context;
}
static int my_client_start(rdpContext* c) { return 0; }
static int my_client_stop(rdpContext* c) { return 0; }
int main(int argc, char* argv[])
{
RDP_CLIENT_ENTRY_POINTS ep = { 0 };
ep.Version = RDP_CLIENT_INTERFACE_VERSION;
ep.Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
ep.ContextSize = sizeof(rdpClientContext);
ep.ClientNew = my_client_new;
ep.ClientFree = my_client_free;
ep.ClientStart = my_client_start;
ep.ClientStop = my_client_stop;
rdpContext* ctx = freerdp_client_context_new(&ep);
if (!ctx)
return 1;
freerdp_client_settings_parse_command_line(ctx->settings, argc, argv, FALSE);
/* connect, run event loop — see Connection API */
freerdp_client_context_free(ctx);
return 0;
}