22 #include <freerdp/config.h>
26 #include <freerdp/crypto/certificate.h>
30 #include <winpr/crt.h>
31 #include <winpr/file.h>
32 #include <winpr/path.h>
33 #include <winpr/sysinfo.h>
34 #include <winpr/registry.h>
35 #include <winpr/wtsapi.h>
37 #include <freerdp/settings.h>
38 #include <freerdp/build-config.h>
40 #include "../crypto/certificate.h"
41 #include "../crypto/privatekey.h"
42 #include "capabilities.h"
44 #define TAG FREERDP_TAG("settings")
48 #pragma warning(disable : 4244)
51 static const char client_dll[] =
"C:\\Windows\\System32\\mstscax.dll";
53 #define SERVER_KEY "Software\\" FREERDP_VENDOR_STRING "\\" FREERDP_PRODUCT_STRING "\\Server"
54 #define CLIENT_KEY "Software\\" FREERDP_VENDOR_STRING "\\" FREERDP_PRODUCT_STRING "\\Client"
55 #define BITMAP_CACHE_KEY CLIENT_KEY "\\BitmapCacheV2"
56 #define GLYPH_CACHE_KEY CLIENT_KEY "\\GlyphCache"
57 #define POINTER_CACHE_KEY CLIENT_KEY "\\PointerCache"
67 static struct bounds_t union_rect(const struct bounds_t* a,
const struct bounds_t* b)
72 struct bounds_t u = *a;
78 const INT32 rightA = a->x + a->width;
79 const INT32 rightB = b->x + b->width;
80 const INT32 right = MAX(rightA, rightB);
81 u.width = right - u.x;
83 const INT32 bottomA = a->y + a->height;
84 const INT32 bottomB = b->y + b->height;
85 const INT32 bottom = MAX(bottomA, bottomB);
86 u.height = bottom - u.y;
91 static BOOL intersect_rects(
const struct bounds_t* r1,
const struct bounds_t* r2)
96 const INT32 left = MAX(r1->x, r2->x);
97 const INT32 top = MAX(r1->y, r2->y);
98 const INT32 right = MIN(r1->x + r1->width, r2->x + r2->width);
99 const INT32 bottom = MIN(r1->y + r1->height, r2->y + r2->height);
101 return (left < right) && (top < bottom);
104 static BOOL align_rects(
const struct bounds_t* r1,
const struct bounds_t* r2)
109 const INT32 left = MAX(r1->x, r2->x);
110 const INT32 top = MAX(r1->y, r2->y);
111 const INT32 right = MIN(r1->x + r1->width, r2->x + r2->width);
112 const INT32 bottom = MIN(r1->y + r1->height, r2->y + r2->height);
114 return (left == right) || (top == bottom);
117 static BOOL settings_reg_query_dword_val(HKEY hKey,
const TCHAR* sub, DWORD* value)
122 dwSize =
sizeof(DWORD);
123 if (RegQueryValueEx(hKey, sub, NULL, &dwType, (BYTE*)value, &dwSize) != ERROR_SUCCESS)
125 if (dwType != REG_DWORD)
131 static BOOL settings_reg_query_word_val(HKEY hKey,
const TCHAR* sub, UINT16* value)
135 if (!settings_reg_query_dword_val(hKey, sub, &dwValue))
138 if (dwValue > UINT16_MAX)
141 *value = (UINT16)dwValue;
145 static BOOL settings_reg_query_bool_val(HKEY hKey,
const TCHAR* sub, BOOL* value)
149 if (!settings_reg_query_dword_val(hKey, sub, &dwValue))
151 *value = dwValue != 0;
155 static BOOL settings_reg_query_dword(rdpSettings* settings, FreeRDP_Settings_Keys_UInt32
id,
156 HKEY hKey,
const TCHAR* sub)
160 if (!settings_reg_query_dword_val(hKey, sub, &dwValue))
166 static BOOL settings_reg_query_bool(rdpSettings* settings, FreeRDP_Settings_Keys_Bool
id, HKEY hKey,
171 if (!settings_reg_query_dword_val(hKey, sub, &dwValue))
177 static void settings_client_load_hkey_local_machine(rdpSettings* settings)
181 status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, CLIENT_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
183 if (status == ERROR_SUCCESS)
185 settings_reg_query_dword(settings, FreeRDP_DesktopWidth, hKey, _T(
"DesktopWidth"));
186 settings_reg_query_dword(settings, FreeRDP_DesktopHeight, hKey, _T(
"DesktopHeight"));
187 settings_reg_query_bool(settings, FreeRDP_Fullscreen, hKey, _T(
"Fullscreen"));
188 settings_reg_query_dword(settings, FreeRDP_ColorDepth, hKey, _T(
"ColorDepth"));
189 settings_reg_query_dword(settings, FreeRDP_KeyboardType, hKey, _T(
"KeyboardType"));
190 settings_reg_query_dword(settings, FreeRDP_KeyboardSubType, hKey, _T(
"KeyboardSubType"));
191 settings_reg_query_dword(settings, FreeRDP_KeyboardFunctionKey, hKey,
192 _T(
"KeyboardFunctionKeys"));
193 settings_reg_query_dword(settings, FreeRDP_KeyboardLayout, hKey, _T(
"KeyboardLayout"));
194 settings_reg_query_bool(settings, FreeRDP_ExtSecurity, hKey, _T(
"ExtSecurity"));
195 settings_reg_query_bool(settings, FreeRDP_NlaSecurity, hKey, _T(
"NlaSecurity"));
196 settings_reg_query_bool(settings, FreeRDP_TlsSecurity, hKey, _T(
"TlsSecurity"));
197 settings_reg_query_bool(settings, FreeRDP_RdpSecurity, hKey, _T(
"RdpSecurity"));
198 settings_reg_query_bool(settings, FreeRDP_MstscCookieMode, hKey, _T(
"MstscCookieMode"));
199 settings_reg_query_dword(settings, FreeRDP_CookieMaxLength, hKey, _T(
"CookieMaxLength"));
200 settings_reg_query_bool(settings, FreeRDP_BitmapCacheEnabled, hKey, _T(
"BitmapCache"));
201 settings_reg_query_dword(settings, FreeRDP_OffscreenSupportLevel, hKey,
202 _T(
"OffscreenBitmapCache"));
203 settings_reg_query_dword(settings, FreeRDP_OffscreenCacheSize, hKey,
204 _T(
"OffscreenBitmapCacheSize"));
205 settings_reg_query_dword(settings, FreeRDP_OffscreenCacheEntries, hKey,
206 _T(
"OffscreenBitmapCacheEntries"));
211 RegOpenKeyExA(HKEY_LOCAL_MACHINE, BITMAP_CACHE_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
213 if (status == ERROR_SUCCESS)
215 settings_reg_query_dword(settings, FreeRDP_BitmapCacheV2NumCells, hKey, _T(
"NumCells"));
216 for (
unsigned x = 0; x < 5; x++)
219 TCHAR numentries[64] = { 0 };
220 TCHAR persist[64] = { 0 };
222 (void)_sntprintf(numentries, ARRAYSIZE(numentries), _T(
"Cell%uNumEntries"), x);
223 (void)_sntprintf(persist, ARRAYSIZE(persist), _T(
"Cell%uPersistent"), x);
224 if (!settings_reg_query_dword_val(hKey, numentries, &val) ||
225 !settings_reg_query_bool_val(hKey, persist, &cache.persistent) ||
226 !freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, x,
228 WLog_WARN(TAG,
"Failed to load registry keys to settings!");
229 cache.numEntries = val;
232 settings_reg_query_bool(settings, FreeRDP_AllowCacheWaitingList, hKey,
233 _T(
"AllowCacheWaitingList"));
238 RegOpenKeyExA(HKEY_LOCAL_MACHINE, GLYPH_CACHE_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
240 if (status == ERROR_SUCCESS)
243 UINT32 GlyphSupportLevel = 0;
244 settings_reg_query_dword(settings, FreeRDP_GlyphSupportLevel, hKey, _T(
"SupportLevel"));
248 TCHAR numentries[64] = { 0 };
249 TCHAR maxsize[64] = { 0 };
250 (void)_sntprintf(numentries, ARRAYSIZE(numentries), _T(
"Cache%uNumEntries"), x);
251 (void)_sntprintf(maxsize, ARRAYSIZE(maxsize), _T(
"Cache%uMaxCellSize"), x);
253 settings_reg_query_word_val(hKey, numentries, &cache.cacheEntries);
254 settings_reg_query_word_val(hKey, maxsize, &cache.cacheMaximumCellSize);
255 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_GlyphCache, x, &cache))
256 WLog_WARN(TAG,
"Failed to store GlyphCache %" PRIuz, x);
260 settings_reg_query_word_val(hKey, _T(
"FragCacheNumEntries"), &cache.cacheEntries);
261 settings_reg_query_word_val(hKey, _T(
"FragCacheMaxCellSize"),
262 &cache.cacheMaximumCellSize);
263 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_FragCache, x, &cache))
264 WLog_WARN(TAG,
"Failed to store FragCache");
270 WLog_WARN(TAG,
"Failed to load registry keys to settings!");
274 RegOpenKeyExA(HKEY_LOCAL_MACHINE, POINTER_CACHE_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
276 if (status == ERROR_SUCCESS)
278 settings_reg_query_dword(settings, FreeRDP_LargePointerFlag, hKey, _T(
"LargePointer"));
279 settings_reg_query_dword(settings, FreeRDP_PointerCacheSize, hKey, _T(
"PointerCacheSize"));
280 settings_reg_query_dword(settings, FreeRDP_ColorPointerCacheSize, hKey,
281 _T(
"ColorPointerCacheSize"));
286 static void settings_server_load_hkey_local_machine(rdpSettings* settings)
291 status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, SERVER_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
293 if (status != ERROR_SUCCESS)
296 settings_reg_query_bool(settings, FreeRDP_ExtSecurity, hKey, _T(
"ExtSecurity"));
297 settings_reg_query_bool(settings, FreeRDP_NlaSecurity, hKey, _T(
"NlaSecurity"));
298 settings_reg_query_bool(settings, FreeRDP_TlsSecurity, hKey, _T(
"TlsSecurity"));
299 settings_reg_query_dword(settings, FreeRDP_TlsSecLevel, hKey, _T(
"TlsSecLevel"));
300 settings_reg_query_bool(settings, FreeRDP_RdpSecurity, hKey, _T(
"RdpSecurity"));
305 static void settings_load_hkey_local_machine(rdpSettings* settings)
308 settings_server_load_hkey_local_machine(settings);
310 settings_client_load_hkey_local_machine(settings);
313 static BOOL settings_get_computer_name(rdpSettings* settings)
315 CHAR computerName[256] = { 0 };
316 DWORD nSize =
sizeof(computerName);
318 if (!GetComputerNameExA(ComputerNameNetBIOS, computerName, &nSize))
321 if (nSize > MAX_COMPUTERNAME_LENGTH)
322 computerName[MAX_COMPUTERNAME_LENGTH] =
'\0';
327 void freerdp_settings_print_warnings(
const rdpSettings* settings)
330 if (level != GLYPH_SUPPORT_NONE)
332 char buffer[32] = { 0 };
333 WLog_WARN(TAG,
"[experimental] enabled GlyphSupportLevel %s, expect visual artefacts!",
334 freerdp_settings_glyph_level_string(level, buffer,
sizeof(buffer)));
338 static BOOL monitor_operlaps(
const rdpSettings* settings, UINT32 start, UINT32 count,
341 const struct bounds_t rect1 = {
342 .x = compare->x, .y = compare->y, .width = compare->width, .height = compare->height
344 for (UINT32 x = start; x < count; x++)
347 freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorDefArray, x);
348 const struct bounds_t rect2 = {
349 .x = monitor->x, .y = monitor->y, .width = monitor->width, .height = monitor->height
352 if (intersect_rects(&rect1, &rect2))
356 "Mulitimonitor mode requested, but local layout has gaps or overlapping areas!");
357 WLog_ERR(TAG,
"Please reconfigure your local monitor setup so that thre are no gaps or "
358 "overlapping areas!");
365 static BOOL monitor_has_gaps(
const rdpSettings* settings, UINT32 start, UINT32 count,
368 const struct bounds_t rect1 = {
369 .x = compare->x, .y = compare->y, .width = compare->width, .height = compare->height
372 BOOL hasNeighbor = FALSE;
373 for (UINT32 i = 0; i < count; i++)
379 freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorDefArray, i);
381 const struct bounds_t rect2 = {
382 .x = monitor->x, .y = monitor->y, .width = monitor->width, .height = monitor->height
384 if (align_rects(&rect1, &rect2))
395 "Monitor configuration has gaps! Monitor %" PRIu32
" does not have any neighbor",
402 static void alloc_free(UINT32** ptr)
407 WINPR_ATTR_MALLOC(alloc_free, 1)
408 static UINT32** alloc_array(
size_t count)
411 BYTE* array = calloc(count *
sizeof(uintptr_t), count *
sizeof(UINT32));
412 UINT32** dst = (UINT32**)array;
413 UINT32* val = (UINT32*)(array + count *
sizeof(uintptr_t));
414 for (
size_t x = 0; x < count; x++)
428 static BOOL find_path_exists_with_dijkstra(UINT32** graph,
size_t count, UINT32 start)
433 WINPR_ASSERT(start < count);
435 UINT32** cost = alloc_array(count);
438 UINT32* distance = calloc(count,
sizeof(UINT32));
439 WINPR_ASSERT(distance);
441 UINT32* visited = calloc(count,
sizeof(UINT32));
442 WINPR_ASSERT(visited);
444 UINT32* parent = calloc(count,
sizeof(UINT32));
445 WINPR_ASSERT(parent);
447 for (
size_t x = 0; x < count; x++)
449 for (
size_t y = 0; y < count; y++)
451 if (graph[x][y] == 0)
452 cost[x][y] = UINT32_MAX;
454 cost[x][y] = graph[x][y];
458 for (UINT32 x = 0; x < count; x++)
460 distance[x] = cost[start][x];
469 UINT32 nextnode = UINT32_MAX;
470 while (pos < count - 1)
472 UINT32 mindistance = UINT32_MAX;
474 for (UINT32 x = 0; x < count; x++)
476 if ((distance[x] < mindistance) && !visited[x])
478 mindistance = distance[x];
483 visited[nextnode] = 1;
485 for (
size_t y = 0; y < count; y++)
489 if (mindistance + cost[nextnode][y] < distance[y])
490 parent[y] = nextnode;
497 for (
size_t x = 0; x < count; x++)
501 if (distance[x] == UINT32_MAX)
503 WLog_ERR(TAG,
"monitor %" PRIu32
" not connected with monitor %" PRIuz, start, x);
517 static BOOL freerdp_settings_client_monitors_have_gaps(
const rdpSettings* settings)
524 UINT32** graph = alloc_array(count);
527 for (UINT32 x = 0; x < count; x++)
530 freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorDefArray, x);
531 if (monitor_has_gaps(settings, x, count, monitor, graph))
535 rc = !find_path_exists_with_dijkstra(graph, count, 0);
543 static BOOL freerdp_settings_client_monitors_overlap(
const rdpSettings* settings)
546 for (UINT32 x = 0; x < count; x++)
549 freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorDefArray, x);
550 if (monitor_operlaps(settings, x + 1, count, monitor))
559 static BOOL freerdp_settings_client_monitors_check_primary_and_origin(
const rdpSettings* settings)
562 BOOL havePrimary = FALSE;
563 BOOL foundOrigin = FALSE;
566 struct bounds_t bounds = { 0 };
570 WLog_WARN(TAG,
"Monitor configuration empty.");
574 for (UINT32 x = 0; x < count; x++)
577 freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorDefArray, x);
578 struct bounds_t cur = {
579 .x = monitor->x, .y = monitor->y, .width = monitor->width, .height = monitor->height
582 bounds = union_rect(&bounds, &cur);
584 if (monitor->is_primary)
588 WLog_ERR(TAG,
"Monitor configuration contains multiple primary monitors!");
594 if ((monitor->x == 0) && (monitor->y == 0))
598 WLog_ERR(TAG,
"Monitor configuration does have multiple origin 0/0");
605 if ((bounds.width > 32766) || (bounds.width < 200))
608 "Monitor configuration virtual desktop width must be 200 <= %" PRId32
" <= 32766",
612 if ((bounds.height > 32766) || (bounds.height < 200))
615 "Monitor configuration virtual desktop height must be 200 <= %" PRId32
" <= 32766",
622 WLog_ERR(TAG,
"Monitor configuration does not contain a primary monitor!");
627 WLog_ERR(TAG,
"Monitor configuration must start at 0/0 for first monitor!");
634 BOOL freerdp_settings_check_client_after_preconnect(
const rdpSettings* settings)
636 if (freerdp_settings_client_monitors_overlap(settings))
638 if (freerdp_settings_client_monitors_have_gaps(settings))
640 if (!freerdp_settings_client_monitors_check_primary_and_origin(settings))
645 BOOL freerdp_settings_set_default_order_support(rdpSettings* settings)
651 ZeroMemory(OrderSupport, 32);
652 OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
653 OrderSupport[NEG_PATBLT_INDEX] = TRUE;
654 OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
655 OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE;
656 OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE;
657 OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE;
658 OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE;
659 OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE;
660 OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE;
661 OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE;
662 OrderSupport[NEG_LINETO_INDEX] = TRUE;
663 OrderSupport[NEG_POLYLINE_INDEX] = TRUE;
664 OrderSupport[NEG_MEMBLT_INDEX] =
666 OrderSupport[NEG_MEM3BLT_INDEX] =
668 OrderSupport[NEG_MEMBLT_V2_INDEX] =
670 OrderSupport[NEG_MEM3BLT_V2_INDEX] =
672 OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE;
673 OrderSupport[NEG_GLYPH_INDEX_INDEX] =
675 OrderSupport[NEG_FAST_INDEX_INDEX] =
677 OrderSupport[NEG_FAST_GLYPH_INDEX] =
679 OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE;
680 OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
681 OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
682 OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
686 BOOL freerdp_capability_buffer_allocate(rdpSettings* settings, UINT32 count)
688 WINPR_ASSERT(settings);
689 WINPR_ASSERT(count > 0);
690 WINPR_ASSERT(count == 32);
692 freerdp_capability_buffer_free(settings);
693 WINPR_ASSERT(settings->ReceivedCapabilitiesSize == 0);
695 settings->ReceivedCapabilitiesSize = count;
696 void* tmp = realloc(settings->ReceivedCapabilities, count *
sizeof(BYTE));
699 memset(tmp, 0, count *
sizeof(BYTE));
700 settings->ReceivedCapabilities = tmp;
702 tmp = realloc(settings->ReceivedCapabilityData, count *
sizeof(BYTE*));
705 memset(tmp, 0, count *
sizeof(BYTE*));
706 settings->ReceivedCapabilityData = tmp;
708 tmp = realloc(settings->ReceivedCapabilityDataSizes, count *
sizeof(UINT32));
711 memset(tmp, 0, count *
sizeof(UINT32));
712 settings->ReceivedCapabilityDataSizes = tmp;
714 return (settings->ReceivedCapabilities && settings->ReceivedCapabilityData &&
715 settings->ReceivedCapabilityDataSizes);
718 #if !defined(WITH_FULL_CONFIG_PATH)
719 static char* freerdp_settings_get_legacy_config_path(
void)
721 char product[
sizeof(FREERDP_PRODUCT_STRING)] = { 0 };
723 for (
size_t i = 0; i <
sizeof(product); i++)
724 product[i] = (
char)tolower(FREERDP_PRODUCT_STRING[i]);
726 return GetKnownSubPath(KNOWN_PATH_XDG_CONFIG_HOME, product);
736 #if !defined(WITH_FULL_CONFIG_PATH)
737 if (_stricmp(FREERDP_VENDOR_STRING, FREERDP_PRODUCT_STRING) == 0)
738 return freerdp_settings_get_legacy_config_path();
741 char* base = GetKnownSubPath(KNOWN_PATH_XDG_CONFIG_HOME, FREERDP_VENDOR_STRING);
743 path = GetCombinedPath(base, FREERDP_PRODUCT_STRING);
751 char* issuers[] = {
"FreeRDP",
"FreeRDP-licenser" };
753 const BOOL remote = (flags & FREERDP_SETTINGS_REMOTE_MODE) != 0 ? TRUE : FALSE;
754 rdpSettings* settings = (rdpSettings*)calloc(1,
sizeof(rdpSettings));
759 if (!server && !remote)
766 ORIENTATION_LANDSCAPE))
774 SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS |
775 SURFCMDS_FRAME_MARKER))
782 TS_CAPS_PROTOCOLVERSION))
786 CLIPRDR_FLAG_DEFAULT_MASK))
791 "FreeRDP-licensing-server"))
795 if (!freerdp_server_license_issuers_copy(settings, issuers, ARRAYSIZE(issuers)))
799 RNS_UD_32BPP_SUPPORT | RNS_UD_24BPP_SUPPORT |
800 RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT))
810 settings, FreeRDP_RemoteApplicationSupportMask,
811 RAIL_LEVEL_SUPPORTED | RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED |
812 RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED | RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED |
813 RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED |
814 RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED | RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED |
815 RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED) ||
818 NEGOTIATE_ORDER_SUPPORT | ZERO_BOUNDS_DELTA_SUPPORT |
819 COLOR_INDEX_SUPPORT) ||
842 DEFAULT_COOKIE_MAX_LENGTH) ||
850 KEYBOARD_HOOK_FULLSCREEN_ONLY) ||
869 CONNECTION_TYPE_AUTODETECT) ||
911 TRANSPORT_TYPE_UDP_FECR))
916 if (!settings_get_computer_name(settings))
922 if (!freerdp_capability_buffer_allocate(settings, 32))
926 char tmp[32] = { 0 };
932 char ClientHostname[33] = { 0 };
933 DWORD size =
sizeof(ClientHostname) - 2;
934 GetComputerNameA(ClientHostname, &size);
963 (LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384)) ||
974 settings->BitmapCacheV2CellInfo =
977 if (!settings->BitmapCacheV2CellInfo)
982 cache.numEntries = 600;
983 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, 0,
985 !freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, 1, &cache))
987 cache.numEntries = 2048;
988 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, 2,
990 !freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, 4, &cache))
992 cache.numEntries = 4096;
993 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, 3, &cache))
1003 if (!settings->GlyphCache)
1008 if (!settings->FragCache)
1011 for (
size_t x = 0; x < 10; x++)
1014 cache.cacheEntries = 254;
1019 cache.cacheMaximumCellSize = 4;
1023 cache.cacheMaximumCellSize = 8;
1026 cache.cacheMaximumCellSize = 16;
1029 cache.cacheMaximumCellSize = 32;
1032 cache.cacheMaximumCellSize = 64;
1035 cache.cacheMaximumCellSize = 128;
1038 cache.cacheMaximumCellSize = 256;
1041 cache.cacheMaximumCellSize = 256;
1047 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_GlyphCache, x, &cache))
1052 cache.cacheEntries = 256;
1053 cache.cacheMaximumCellSize = 256;
1054 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_FragCache, 0, &cache))
1065 WINDOW_LEVEL_SUPPORTED | WINDOW_LEVEL_SUPPORTED_EX) ||
1069 (server && !remote) ? CHANNEL_CHUNK_MAX_LENGTH
1070 : CHANNEL_CHUNK_LENGTH) ||
1074 server ? 0 : 608299) ||
1117 if (!settings->ClientTimeZone)
1120 if (!settings->ServerMode)
1127 GetTimeZoneInformation(tz);
1128 GetDynamicTimeZoneInformation(&dynamic);
1131 dynamic.TimeZoneKeyName,
1132 ARRAYSIZE(dynamic.TimeZoneKeyName)))
1136 dynamic.DynamicDaylightTimeDisabled))
1155 path = GetKnownPath(KNOWN_PATH_HOME);
1166 char* action = GetCombinedPath(config,
"action.sh");
1176 settings_load_hkey_local_machine(settings);
1182 settings->OrderSupport = calloc(1, 32);
1189 if (!settings->OrderSupport)
1192 if (!freerdp_settings_set_default_order_support(settings))
1198 const FreeRDP_Settings_Keys_Bool keys[] = { FreeRDP_SupportGraphicsPipeline,
1199 FreeRDP_SupportStatusInfoPdu,
1200 FreeRDP_SupportErrorInfoPdu,
1201 FreeRDP_SupportAsymetricKeys };
1203 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
1217 WINPR_PRAGMA_DIAG_PUSH
1218 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
1220 WINPR_PRAGMA_DIAG_POP
1224 static void freerdp_settings_free_internal(rdpSettings* settings)
1226 freerdp_server_license_issuers_free(settings);
1227 freerdp_target_net_addresses_free(settings);
1228 freerdp_device_collection_free(settings);
1229 freerdp_static_channel_collection_free(settings);
1230 freerdp_dynamic_channel_collection_free(settings);
1232 freerdp_capability_buffer_free(settings);
1235 freerdp_settings_free_keys(settings, TRUE);
1243 freerdp_settings_free_internal(settings);
1247 static BOOL freerdp_settings_int_buffer_copy(rdpSettings* _settings,
const rdpSettings* settings)
1251 if (!_settings || !settings)
1272 if (!freerdp_server_license_issuers_copy(_settings, settings->ServerLicenseProductIssuers,
1273 settings->ServerLicenseProductIssuersCount))
1282 if (settings->RdpServerCertificate)
1284 rdpCertificate* cert = freerdp_certificate_clone(settings->RdpServerCertificate);
1296 if (settings->RdpServerRsaKey)
1298 rdpPrivateKey* key = freerdp_key_clone(settings->RdpServerRsaKey);
1314 _settings, FreeRDP_ChannelDefArraySize,
1341 _settings->OrderSupport = malloc(32);
1343 if (!_settings->OrderSupport)
1346 if (!freerdp_capability_buffer_copy(_settings, settings))
1348 CopyMemory(_settings->OrderSupport, settings->OrderSupport, 32);
1350 const UINT32 cellInfoSize =
1358 const UINT32 glyphCacheCount = 10;
1365 const UINT32 fragCacheCount = 1;
1372 _settings, FreeRDP_ClientAutoReconnectCookie,
1376 _settings, FreeRDP_ServerAutoReconnectCookie,
1386 _settings, FreeRDP_RedirectionPasswordLength,
1389 const UINT32 redirectionPasswordLength =
1393 redirectionPasswordLength))
1396 const UINT32 RedirectionTsvUrlLength =
1398 const BYTE* RedirectionTsvUrl =
1401 RedirectionTsvUrlLength))
1405 if (!freerdp_target_net_adresses_reset(_settings, nrports))
1408 for (UINT32 i = 0; i < nrports; i++)
1410 const char* address =
1411 freerdp_settings_get_pointer_array(settings, FreeRDP_TargetNetAddresses, i);
1412 const UINT32* port =
1413 freerdp_settings_get_pointer_array(settings, FreeRDP_TargetNetPorts, i);
1414 if (!freerdp_settings_set_pointer_array(_settings, FreeRDP_TargetNetAddresses, i, address))
1416 if (!freerdp_settings_set_pointer_array(_settings, FreeRDP_TargetNetPorts, i, port))
1431 for (
size_t index = 0; index < count; index++)
1434 freerdp_settings_get_pointer_array(settings, FreeRDP_DeviceArray, index);
1435 if (!freerdp_settings_set_pointer_array(_settings, FreeRDP_DeviceArray, index, argv))
1450 for (
size_t index = 0; index < count; index++)
1453 freerdp_settings_get_pointer_array(settings, FreeRDP_StaticChannelArray, index);
1454 if (!freerdp_settings_set_pointer_array(_settings, FreeRDP_StaticChannelArray, index,
1470 for (
size_t index = 0; index < count; index++)
1473 freerdp_settings_get_pointer_array(settings, FreeRDP_DynamicChannelArray, index);
1474 if (!freerdp_settings_set_pointer_array(_settings, FreeRDP_DynamicChannelArray, index,
1491 if (!settings || !_settings)
1495 freerdp_settings_free_internal(_settings);
1498 rc = freerdp_settings_clone_keys(_settings, settings);
1500 _settings->LoadBalanceInfo = NULL;
1501 _settings->ServerRandom = NULL;
1502 _settings->ClientRandom = NULL;
1503 _settings->ServerCertificate = NULL;
1504 _settings->RdpServerCertificate = NULL;
1505 _settings->RdpServerRsaKey = NULL;
1506 _settings->ChannelDefArray = NULL;
1507 _settings->MonitorDefArray = NULL;
1508 _settings->MonitorIds = NULL;
1509 _settings->OrderSupport = NULL;
1510 _settings->BitmapCacheV2CellInfo = NULL;
1511 _settings->GlyphCache = NULL;
1512 _settings->FragCache = NULL;
1513 _settings->ClientAutoReconnectCookie = NULL;
1514 _settings->ServerAutoReconnectCookie = NULL;
1515 _settings->ClientTimeZone = NULL;
1516 _settings->RedirectionPassword = NULL;
1517 _settings->RedirectionTsvUrl = NULL;
1518 _settings->TargetNetAddresses = NULL;
1519 _settings->TargetNetPorts = NULL;
1520 _settings->DeviceArray = NULL;
1521 _settings->StaticChannelArray = NULL;
1522 _settings->DynamicChannelArray = NULL;
1523 _settings->ReceivedCapabilities = NULL;
1524 _settings->ReceivedCapabilityData = NULL;
1525 _settings->ReceivedCapabilityDataSizes = NULL;
1527 _settings->ServerLicenseProductIssuersCount = 0;
1528 _settings->ServerLicenseProductIssuers = NULL;
1534 if (!freerdp_settings_int_buffer_copy(_settings, settings))
1538 freerdp_settings_free_internal(_settings);
1544 rdpSettings* _settings = (rdpSettings*)calloc(1,
sizeof(rdpSettings));
1551 WINPR_PRAGMA_DIAG_PUSH
1552 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
1554 WINPR_PRAGMA_DIAG_POP
1558 #pragma warning(pop)
1561 static void zfree(WCHAR* str,
size_t len)
1564 memset(str, 0, len *
sizeof(WCHAR));
1568 BOOL identity_set_from_settings_with_pwd(SEC_WINNT_AUTH_IDENTITY* identity,
1569 const rdpSettings* settings,
1570 FreeRDP_Settings_Keys_String UserId,
1571 FreeRDP_Settings_Keys_String DomainId,
1572 const WCHAR* Password,
size_t pwdLen)
1574 WINPR_ASSERT(identity);
1575 WINPR_ASSERT(settings);
1578 size_t DomainLen = 0;
1583 const int rc = sspi_SetAuthIdentityWithLengthW(identity, Username, UserLen, Domain, DomainLen,
1585 zfree(Username, UserLen);
1586 zfree(Domain, DomainLen);
1593 FreeRDP_Settings_Keys_String UserId,
1594 FreeRDP_Settings_Keys_String DomainId,
1595 FreeRDP_Settings_Keys_String PwdId)
1597 WINPR_ASSERT(identity);
1598 WINPR_ASSERT(settings);
1605 identity_set_from_settings_with_pwd(identity, settings, UserId, DomainId, Password, PwdLen);
1606 zfree(Password, PwdLen);
1611 const rdpSettings* settings,
1612 FreeRDP_Settings_Keys_String userId,
1613 FreeRDP_Settings_Keys_String domainId,
1614 FreeRDP_Settings_Keys_String pwdId,
const BYTE* certSha1,
1619 LPWSTR marshalledCredentials = NULL;
1621 memcpy(certInfo.rgbHashOfCert, certSha1, MIN(sha1len,
sizeof(certInfo.rgbHashOfCert)));
1623 if (!CredMarshalCredentialW(CertCredential, &certInfo, &marshalledCredentials))
1625 WLog_ERR(TAG,
"error marshalling cert credentials");
1631 const int rc = sspi_SetAuthIdentityWithLengthW(
1632 identity, marshalledCredentials, _wcslen(marshalledCredentials), NULL, 0, Password, pwdLen);
1633 zfree(Password, pwdLen);
1634 CredFree(marshalledCredentials);
1639 if (!identity_set_from_settings(identity, settings, userId, domainId, pwdId))
1645 const char* freerdp_settings_glyph_level_string(UINT32 level,
char* buffer,
size_t size)
1647 const char* str =
"GLYPH_SUPPORT_UNKNOWN";
1650 case GLYPH_SUPPORT_NONE:
1651 str =
"GLYPH_SUPPORT_NONE";
1653 case GLYPH_SUPPORT_PARTIAL:
1654 str =
"GLYPH_SUPPORT_PARTIAL";
1656 case GLYPH_SUPPORT_FULL:
1657 str =
"GLYPH_SUPPORT_FULL";
1659 case GLYPH_SUPPORT_ENCODE:
1660 str =
"GLYPH_SUPPORT_ENCODE";
1666 (void)_snprintf(buffer, size,
"%s[0x%08" PRIx32
"]", str, level);
1670 BOOL freerdp_target_net_adresses_reset(rdpSettings* settings,
size_t size)
1672 freerdp_target_net_addresses_free(settings);
1676 if (!freerdp_settings_set_pointer_len_(settings, FreeRDP_TargetNetPorts, -1, NULL, size,
1679 if (!freerdp_settings_set_pointer_len_(settings, FreeRDP_TargetNetAddresses,
1680 FreeRDP_TargetNetAddressCount, NULL, size,
1687 BOOL freerdp_settings_enforce_monitor_exists(rdpSettings* settings)
1693 const BOOL useMonitors = fullscreen || multimon;
1700 if (!useMonitors || (count == 0))
1706 const UINT16 orientation =
1708 const UINT32 desktopScaleFactor =
1710 const UINT32 deviceScaleFactor =
1717 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_MonitorDefArray, 0);
1722 WINPR_ASSERT(width <= INT32_MAX);
1723 monitor->width = (INT32)width;
1724 WINPR_ASSERT(height <= INT32_MAX);
1725 monitor->height = (INT32)height;
1726 monitor->is_primary = TRUE;
1727 monitor->orig_screen = 0;
1728 monitor->attributes.physicalWidth = pwidth;
1729 monitor->attributes.physicalHeight = pheight;
1730 monitor->attributes.orientation = orientation;
1731 monitor->attributes.desktopScaleFactor = desktopScaleFactor;
1732 monitor->attributes.deviceScaleFactor = deviceScaleFactor;
1734 else if (fullscreen || (multimon && (count == 1)))
1740 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_MonitorDefArray, 0);
1745 monitor->is_primary = TRUE;
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
FREERDP_API BOOL freerdp_settings_set_string_from_utf16N(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const WCHAR *param, size_t length)
Sets a string settings value. The param is converted to UTF-8 and the copy stored.
rdpSettings * freerdp_settings_new(DWORD flags)
creates a new setting struct
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
char * freerdp_settings_get_config_path(void)
return the configuration directory for the library
void freerdp_settings_free(rdpSettings *settings)
Free a settings struct with all data in it.
#define FREERDP_SETTINGS_SERVER_MODE
FREERDP_API UINT16 freerdp_settings_get_uint16(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt16 id)
Returns a UINT16 settings value.
BOOL freerdp_settings_copy(rdpSettings *_settings, const rdpSettings *settings)
Deep copies settings from src to dst.
rdpSettings * freerdp_settings_clone(const rdpSettings *settings)
Creates a deep copy of settings.
FREERDP_API WCHAR * freerdp_settings_get_string_as_utf16(const rdpSettings *settings, FreeRDP_Settings_Keys_String id, size_t *pCharLen)
Return an allocated UTF16 string.
FREERDP_API BOOL freerdp_settings_set_string_len(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param, size_t len)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_uint16(rdpSettings *settings, FreeRDP_Settings_Keys_UInt16 id, UINT16 param)
Sets a UINT16 settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.
FREERDP_API void * freerdp_settings_get_pointer_writable(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a mutable pointer settings value.