diff options
Diffstat (limited to '')
-rw-r--r-- | libfreerdp/common/CMakeLists.txt | 33 | ||||
-rw-r--r-- | libfreerdp/common/addin.c | 397 | ||||
-rw-r--r-- | libfreerdp/common/assistance.c | 1490 | ||||
-rw-r--r-- | libfreerdp/common/settings.c | 2185 | ||||
-rw-r--r-- | libfreerdp/common/settings_getters.c | 4153 | ||||
-rw-r--r-- | libfreerdp/common/settings_str.c | 477 | ||||
-rw-r--r-- | libfreerdp/common/settings_str.h | 612 | ||||
-rw-r--r-- | libfreerdp/common/test/CMakeLists.txt | 44 | ||||
-rw-r--r-- | libfreerdp/common/test/TestAddinArgv.c | 345 | ||||
-rw-r--r-- | libfreerdp/common/test/TestCommonAssistance.c | 293 | ||||
-rw-r--r-- | libfreerdp/common/test/TestFuzzCommonAssistanceBinToHexString.c | 8 | ||||
-rw-r--r-- | libfreerdp/common/test/TestFuzzCommonAssistanceHexStringToBin.c | 16 | ||||
-rw-r--r-- | libfreerdp/common/test/TestFuzzCommonAssistanceParseFileBuffer.c | 31 |
13 files changed, 10084 insertions, 0 deletions
diff --git a/libfreerdp/common/CMakeLists.txt b/libfreerdp/common/CMakeLists.txt new file mode 100644 index 0000000..36cda87 --- /dev/null +++ b/libfreerdp/common/CMakeLists.txt @@ -0,0 +1,33 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# libfreerdp-common cmake build script +# +# 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. + +set(MODULE_NAME "freerdp-common") +set(MODULE_PREFIX "FREERDP_COMMON") + +set(${MODULE_PREFIX}_SRCS + addin.c + settings.c + settings_getters.c + settings_str.c + settings_str.h + assistance.c) + +freerdp_module_add(${${MODULE_PREFIX}_SRCS}) + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/libfreerdp/common/addin.c b/libfreerdp/common/addin.c new file mode 100644 index 0000000..9c5cd1f --- /dev/null +++ b/libfreerdp/common/addin.c @@ -0,0 +1,397 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Addin Loader + * + * 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. + */ + +#include <freerdp/config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <winpr/crt.h> +#include <winpr/path.h> +#include <winpr/string.h> +#include <winpr/library.h> + +#include <freerdp/addin.h> +#include <freerdp/build-config.h> + +#include <freerdp/log.h> +#define TAG FREERDP_TAG("addin") + +static INLINE BOOL is_path_required(LPCSTR path, size_t len) +{ + if (!path || (len <= 1)) + return FALSE; + + if (strcmp(path, ".") == 0) + return FALSE; + + return TRUE; +} + +LPSTR freerdp_get_library_install_path(void) +{ + LPSTR pszPath = NULL; + size_t cchPath = 0; + size_t cchLibraryPath = 0; + size_t cchInstallPrefix = 0; + BOOL needLibPath = 0; + BOOL needInstallPath = 0; + LPCSTR pszLibraryPath = FREERDP_LIBRARY_PATH; + LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX; + cchLibraryPath = strlen(pszLibraryPath) + 1; + cchInstallPrefix = strlen(pszInstallPrefix) + 1; + cchPath = cchInstallPrefix + cchLibraryPath; + needInstallPath = is_path_required(pszInstallPrefix, cchInstallPrefix); + needLibPath = is_path_required(pszLibraryPath, cchLibraryPath); + + if (!needInstallPath && !needLibPath) + return NULL; + + pszPath = (LPSTR)malloc(cchPath + 1); + + if (!pszPath) + return NULL; + + if (needInstallPath) + { + CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix); + pszPath[cchInstallPrefix] = '\0'; + } + + if (needLibPath) + { + if (FAILED(NativePathCchAppendA(pszPath, cchPath + 1, pszLibraryPath))) + { + free(pszPath); + return NULL; + } + } + + return pszPath; +} + +LPSTR freerdp_get_dynamic_addin_install_path(void) +{ +#if defined(WITH_ADD_PLUGIN_TO_RPATH) + return NULL; +#else + LPSTR pszPath = NULL; + size_t cchPath = 0; + size_t cchAddinPath = 0; + size_t cchInstallPrefix = 0; + BOOL needLibPath = 0; + BOOL needInstallPath = 0; + LPCSTR pszAddinPath = FREERDP_ADDIN_PATH; + LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX; + cchAddinPath = strlen(pszAddinPath) + 1; + cchInstallPrefix = strlen(pszInstallPrefix) + 1; + cchPath = cchInstallPrefix + cchAddinPath; + needInstallPath = is_path_required(pszInstallPrefix, cchInstallPrefix); + needLibPath = is_path_required(pszAddinPath, cchAddinPath); + + WLog_DBG(TAG, + "freerdp_get_dynamic_addin_install_path <- pszInstallPrefix: %s, pszAddinPath: %s", + pszInstallPrefix, pszAddinPath); + + if (!needInstallPath && !needLibPath) + return NULL; + + pszPath = (LPSTR)calloc(cchPath + 1, sizeof(CHAR)); + + if (!pszPath) + return NULL; + + if (needInstallPath) + { + CopyMemory(pszPath, pszInstallPrefix, cchInstallPrefix); + pszPath[cchInstallPrefix] = '\0'; + } + + if (needLibPath) + { + if (FAILED(NativePathCchAppendA(pszPath, cchPath + 1, pszAddinPath))) + { + free(pszPath); + return NULL; + } + } + + WLog_DBG(TAG, "freerdp_get_dynamic_addin_install_path -> pszPath: %s", pszPath); + + return pszPath; +#endif +} + +PVIRTUALCHANNELENTRY freerdp_load_dynamic_addin(LPCSTR pszFileName, LPCSTR pszPath, + LPCSTR pszEntryName) +{ + LPSTR pszAddinInstallPath = freerdp_get_dynamic_addin_install_path(); + PVIRTUALCHANNELENTRY entry = NULL; + BOOL bHasExt = TRUE; + PCSTR pszExt = NULL; + size_t cchExt = 0; + HINSTANCE library = NULL; + size_t cchFileName = 0; + size_t cchFilePath = 0; + LPSTR pszAddinFile = NULL; + LPSTR pszFilePath = NULL; + LPSTR pszRelativeFilePath = NULL; + size_t cchAddinFile = 0; + size_t cchAddinInstallPath = 0; + + if (!pszFileName || !pszEntryName) + goto fail; + + WLog_DBG(TAG, "freerdp_load_dynamic_addin <- pszFileName: %s, pszPath: %s, pszEntryName: %s", + pszFileName, pszPath, pszEntryName); + + cchFileName = strlen(pszFileName); + + /* Get file name with prefix and extension */ + if (FAILED(PathCchFindExtensionA(pszFileName, cchFileName + 1, &pszExt))) + { + pszExt = PathGetSharedLibraryExtensionA(PATH_SHARED_LIB_EXT_WITH_DOT); + cchExt = strlen(pszExt); + bHasExt = FALSE; + } + + if (bHasExt) + { + pszAddinFile = _strdup(pszFileName); + + if (!pszAddinFile) + goto fail; + } + else + { + cchAddinFile = cchFileName + cchExt + 2 + sizeof(FREERDP_SHARED_LIBRARY_PREFIX); + pszAddinFile = (LPSTR)malloc(cchAddinFile + 1); + + if (!pszAddinFile) + goto fail; + + sprintf_s(pszAddinFile, cchAddinFile, FREERDP_SHARED_LIBRARY_PREFIX "%s%s", pszFileName, + pszExt); + } + + cchAddinFile = strlen(pszAddinFile); + + /* If a path is provided prefix the library name with it. */ + if (pszPath) + { + size_t relPathLen = strlen(pszPath) + cchAddinFile + 1; + pszRelativeFilePath = calloc(relPathLen, sizeof(CHAR)); + + if (!pszRelativeFilePath) + goto fail; + + sprintf_s(pszRelativeFilePath, relPathLen, "%s", pszPath); + const HRESULT hr = NativePathCchAppendA(pszRelativeFilePath, relPathLen, pszAddinFile); + if (FAILED(hr)) + goto fail; + } + else + pszRelativeFilePath = _strdup(pszAddinFile); + + if (!pszRelativeFilePath) + goto fail; + + /* If a system prefix path is provided try these locations too. */ + if (pszAddinInstallPath) + { + cchAddinInstallPath = strlen(pszAddinInstallPath); + cchFilePath = cchAddinInstallPath + cchFileName + 32; + pszFilePath = (LPSTR)malloc(cchFilePath + 1); + + if (!pszFilePath) + goto fail; + + CopyMemory(pszFilePath, pszAddinInstallPath, cchAddinInstallPath); + pszFilePath[cchAddinInstallPath] = '\0'; + const HRESULT hr = + NativePathCchAppendA((LPSTR)pszFilePath, cchFilePath + 1, pszRelativeFilePath); + if (FAILED(hr)) + goto fail; + } + else + pszFilePath = _strdup(pszRelativeFilePath); + + library = LoadLibraryX(pszFilePath); + + if (!library) + goto fail; + + entry = (PVIRTUALCHANNELENTRY)GetProcAddress(library, pszEntryName); +fail: + free(pszRelativeFilePath); + free(pszAddinFile); + free(pszFilePath); + free(pszAddinInstallPath); + + if (!entry && library) + FreeLibrary(library); + + return entry; +} + +PVIRTUALCHANNELENTRY freerdp_load_dynamic_channel_addin_entry(LPCSTR pszName, LPCSTR pszSubsystem, + LPCSTR pszType, DWORD dwFlags) +{ + PVIRTUALCHANNELENTRY entry = NULL; + LPSTR pszFileName = NULL; + const size_t cchBaseFileName = sizeof(FREERDP_SHARED_LIBRARY_PREFIX) + 32; + size_t nameLen = 0; + size_t subsystemLen = 0; + size_t typeLen = 0; + size_t cchFileName = 0; + + if (pszName) + nameLen = strnlen(pszName, MAX_PATH); + if (pszSubsystem) + subsystemLen = strnlen(pszSubsystem, MAX_PATH); + if (pszType) + typeLen = strnlen(pszType, MAX_PATH); + + if (pszName && pszSubsystem && pszType) + { + cchFileName = cchBaseFileName + nameLen + subsystemLen + typeLen; + pszFileName = (LPSTR)malloc(cchFileName); + + if (!pszFileName) + return NULL; + + sprintf_s(pszFileName, cchFileName, "%s-client-%s-%s", pszName, pszSubsystem, pszType); + } + else if (pszName && pszSubsystem) + { + cchFileName = cchBaseFileName + nameLen + subsystemLen; + pszFileName = (LPSTR)malloc(cchFileName); + + if (!pszFileName) + return NULL; + + sprintf_s(pszFileName, cchFileName, "%s-client-%s", pszName, pszSubsystem); + } + else if (pszName) + { + cchFileName = cchBaseFileName + nameLen; + pszFileName = (LPSTR)malloc(cchFileName); + + if (!pszFileName) + return NULL; + + sprintf_s(pszFileName, cchFileName, "%s-client", pszName); + } + else + { + return NULL; + } + + { + LPCSTR pszExtension = PathGetSharedLibraryExtensionA(0); + const char pszPrefix[] = FREERDP_SHARED_LIBRARY_PREFIX; + int rc = 0; + + cchFileName += strnlen(pszPrefix, ARRAYSIZE(pszPrefix)); + if (pszExtension) + cchFileName += strnlen(pszExtension, MAX_PATH) + 1; + LPSTR tmp = calloc(cchFileName, sizeof(CHAR)); + if (tmp) + rc = sprintf_s(tmp, cchFileName, "%s%s.%s", pszPrefix, pszFileName, pszExtension); + + free(pszFileName); + pszFileName = tmp; + if (!pszFileName || (rc < 0)) + { + free(pszFileName); + return NULL; + } + } + + if (pszSubsystem) + { + LPSTR pszEntryName = NULL; + size_t cchEntryName = 0; + /* subsystem add-in */ + cchEntryName = 64 + nameLen; + pszEntryName = (LPSTR)malloc(cchEntryName + 1); + + if (!pszEntryName) + { + free(pszFileName); + return NULL; + } + + sprintf_s(pszEntryName, cchEntryName + 1, "freerdp_%s_client_subsystem_entry", pszName); + entry = freerdp_load_dynamic_addin(pszFileName, NULL, pszEntryName); + free(pszEntryName); + free(pszFileName); + return entry; + } + + /* channel add-in */ + + if (dwFlags & FREERDP_ADDIN_CHANNEL_STATIC) + { + if (dwFlags & FREERDP_ADDIN_CHANNEL_ENTRYEX) + entry = freerdp_load_dynamic_addin(pszFileName, NULL, "VirtualChannelEntryEx"); + else + entry = freerdp_load_dynamic_addin(pszFileName, NULL, "VirtualChannelEntry"); + } + else if (dwFlags & FREERDP_ADDIN_CHANNEL_DYNAMIC) + entry = freerdp_load_dynamic_addin(pszFileName, NULL, "DVCPluginEntry"); + else if (dwFlags & FREERDP_ADDIN_CHANNEL_DEVICE) + entry = freerdp_load_dynamic_addin(pszFileName, NULL, "DeviceServiceEntry"); + else + entry = freerdp_load_dynamic_addin(pszFileName, NULL, pszType); + + free(pszFileName); + return entry; +} + +static FREERDP_LOAD_CHANNEL_ADDIN_ENTRY_FN freerdp_load_static_channel_addin_entry = NULL; + +int freerdp_register_addin_provider(FREERDP_LOAD_CHANNEL_ADDIN_ENTRY_FN provider, DWORD dwFlags) +{ + freerdp_load_static_channel_addin_entry = provider; + return 0; +} + +FREERDP_LOAD_CHANNEL_ADDIN_ENTRY_FN freerdp_get_current_addin_provider(void) +{ + return freerdp_load_static_channel_addin_entry; +} + +PVIRTUALCHANNELENTRY freerdp_load_channel_addin_entry(LPCSTR pszName, LPCSTR pszSubsystem, + LPCSTR pszType, DWORD dwFlags) +{ + PVIRTUALCHANNELENTRY entry = NULL; + + if (freerdp_load_static_channel_addin_entry) + entry = freerdp_load_static_channel_addin_entry(pszName, pszSubsystem, pszType, dwFlags); + + if (!entry) + entry = freerdp_load_dynamic_channel_addin_entry(pszName, pszSubsystem, pszType, dwFlags); + + if (!entry) + WLog_WARN(TAG, "Failed to load channel %s [%s]", pszName, pszSubsystem); + + return entry; +} diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c new file mode 100644 index 0000000..dc76d6a --- /dev/null +++ b/libfreerdp/common/assistance.c @@ -0,0 +1,1490 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Remote Assistance + * + * Copyright 2014 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. + */ + +#include <freerdp/config.h> + +#include <errno.h> + +#include <winpr/wtypes.h> +#include <winpr/collections.h> +#include <winpr/string.h> +#include <winpr/crt.h> +#include <winpr/crypto.h> +#include <winpr/print.h> +#include <winpr/windows.h> +#include <winpr/ssl.h> +#include <winpr/file.h> + +#include <freerdp/log.h> +#include <freerdp/client/file.h> +#include <freerdp/client/cmdline.h> + +#include <freerdp/assistance.h> + +#include "../core/settings.h" + +#define TAG FREERDP_TAG("common") + +struct rdp_assistance_file +{ + UINT32 Type; + + char* Username; + char* LHTicket; + char* RCTicket; + char* PassStub; + UINT32 DtStart; + UINT32 DtLength; + BOOL LowSpeed; + BOOL RCTicketEncrypted; + + char* ConnectionString1; + char* ConnectionString2; + + BYTE* EncryptedPassStub; + size_t EncryptedPassStubLength; + + BYTE* EncryptedLHTicket; + size_t EncryptedLHTicketLength; + + wArrayList* MachineAddresses; + wArrayList* MachinePorts; + wArrayList* MachineUris; + + char* RASessionId; + char* RASpecificParams; + char* RASpecificParams2; + + char* filename; + char* password; +}; + +static const char* strrstr(const char* haystack, size_t len, const char* needle) +{ + if (*needle == '\0') + return (const char*)haystack; + + char* result = NULL; + for (;;) + { + char* p = strstr(haystack, needle); + if (p == NULL) + break; + if (p > haystack + len) + return NULL; + + result = p; + haystack = p + 1; + } + + return result; +} + +static BOOL update_option(char** opt, const char* val, size_t len) +{ + WINPR_ASSERT(opt); + free(*opt); + *opt = NULL; + + if (!val && (len != 0)) + return FALSE; + else if (!val && (len == 0)) + return TRUE; + *opt = strndup(val, len); + return *opt != NULL; +} + +static BOOL update_name(rdpAssistanceFile* file, const char* name) +{ + WINPR_ASSERT(file); + + if (!name) + { + WLog_ERR(TAG, "ASSISTANCE file %s invalid name", name); + return FALSE; + } + + free(file->filename); + file->filename = _strdup(name); + return file->filename != NULL; +} + +static BOOL update_password(rdpAssistanceFile* file, const char* password) +{ + WINPR_ASSERT(file); + free(file->password); + file->password = NULL; + if (!password) + return TRUE; + file->password = _strdup(password); + return file->password != NULL; +} + +static BOOL update_connectionstring2_nocopy(rdpAssistanceFile* file, char* str) +{ + WINPR_ASSERT(file); + free(file->ConnectionString2); + file->ConnectionString2 = NULL; + if (!str) + return TRUE; + file->ConnectionString2 = str; + return file->ConnectionString2 != NULL; +} + +static BOOL update_connectionstring2(rdpAssistanceFile* file, const char* str, size_t len) +{ + char* strc = NULL; + if (!str && (len != 0)) + return FALSE; + + if (str && (len > 0)) + { + strc = strndup(str, len); + if (!strc) + return FALSE; + } + return update_connectionstring2_nocopy(file, strc); +} + +static BOOL update_connectionstring2_wchar(rdpAssistanceFile* file, const WCHAR* str, size_t len) +{ + char* strc = NULL; + + if (!str && (len != 0)) + return FALSE; + + if (str && (len > 0)) + { + strc = ConvertWCharNToUtf8Alloc(str, len, NULL); + if (!strc) + return FALSE; + } + return update_connectionstring2_nocopy(file, strc); +} + +/** + * Password encryption in establishing a remote assistance session of type 1: + * http://blogs.msdn.com/b/openspecification/archive/2011/10/31/password-encryption-in-establishing-a-remote-assistance-session-of-type-1.aspx + * + * Creation of PassStub for the Remote Assistance Ticket: + * http://social.msdn.microsoft.com/Forums/en-US/6316c3f4-ea09-4343-a4a1-9cca46d70d28/creation-of-passstub-for-the-remote-assistance-ticket?forum=os_windowsprotocols + */ + +/** + * CryptDeriveKey Function: + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa379916/ + * + * Let n be the required derived key length, in bytes. + * The derived key is the first n bytes of the hash value after the hash computation + * has been completed by CryptDeriveKey. If the hash is not a member of the SHA-2 + * family and the required key is for either 3DES or AES, the key is derived as follows: + * + * Form a 64-byte buffer by repeating the constant 0x36 64 times. + * Let k be the length of the hash value that is represented by the input parameter hBaseData. + * Set the first k bytes of the buffer to the result of an XOR operation of the first k bytes + * of the buffer with the hash value that is represented by the input parameter hBaseData. + * + * Form a 64-byte buffer by repeating the constant 0x5C 64 times. + * Set the first k bytes of the buffer to the result of an XOR operation of the first k bytes + * of the buffer with the hash value that is represented by the input parameter hBaseData. + * + * Hash the result of step 1 by using the same hash algorithm as that used to compute the hash + * value that is represented by the hBaseData parameter. + * + * Hash the result of step 2 by using the same hash algorithm as that used to compute the hash + * value that is represented by the hBaseData parameter. + * + * Concatenate the result of step 3 with the result of step 4. + * Use the first n bytes of the result of step 5 as the derived key. + */ + +static BOOL freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, size_t hashLength, BYTE* key, + size_t keyLength) +{ + BOOL rc = FALSE; + BYTE pad1[64] = { 0 }; + BYTE pad2[64] = { 0 }; + + memset(pad1, 0x36, sizeof(pad1)); + memset(pad2, 0x5C, sizeof(pad2)); + + for (size_t i = 0; i < hashLength; i++) + { + pad1[i] ^= hash[i]; + pad2[i] ^= hash[i]; + } + + BYTE* buffer = (BYTE*)calloc(hashLength, 2); + + if (!buffer) + goto fail; + + if (!winpr_Digest(WINPR_MD_SHA1, pad1, 64, buffer, hashLength)) + goto fail; + + if (!winpr_Digest(WINPR_MD_SHA1, pad2, 64, &buffer[hashLength], hashLength)) + goto fail; + + CopyMemory(key, buffer, keyLength); + rc = TRUE; +fail: + free(buffer); + return rc; +} + +static BOOL append_address_to_list(wArrayList* MachineAddresses, const char* str, size_t len) +{ + char* copy = NULL; + if (len > 0) + copy = strndup(str, len); + if (!copy) + return FALSE; + + const BOOL rc = ArrayList_Append(MachineAddresses, copy); + if (!rc) + free(copy); + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): ArrayList_Append takes ownership of copy + return rc; +} + +static BOOL append_address(rdpAssistanceFile* file, const char* host, const char* port) +{ + WINPR_ASSERT(file); + + errno = 0; + unsigned long p = strtoul(port, NULL, 0); + + if ((errno != 0) || (p == 0) || (p > UINT16_MAX)) + { + WLog_ERR(TAG, "Failed to parse ASSISTANCE file: ConnectionString2 invalid port value %s", + port); + return FALSE; + } + + if (!append_address_to_list(file->MachineAddresses, host, host ? strlen(host) : 0)) + return FALSE; + return ArrayList_Append(file->MachinePorts, (void*)(uintptr_t)p); +} + +static BOOL freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list) +{ + WINPR_ASSERT(file); + + WLog_DBG(TAG, "freerdp_assistance_parse_address_list list=%s", list); + + BOOL rc = FALSE; + + if (!list) + return FALSE; + + char* strp = list; + char* s = ";"; + + // get the first token + char* token = strtok(strp, s); + + // walk through other tokens + while (token != NULL) + { + char* port = strchr(token, ':'); + if (!port) + goto out; + *port = '\0'; + port++; + + if (!append_address(file, token, port)) + goto out; + + token = strtok(NULL, s); + } + rc = TRUE; +out: + return rc; +} + +static BOOL freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file) +{ + char* tokens[8] = { 0 }; + BOOL rc = FALSE; + + WINPR_ASSERT(file); + + if (!file->RCTicket) + return FALSE; + + /** + * <ProtocolVersion>,<protocolType>,<machineAddressList>,<assistantAccountPwd>, + * <RASessionID>,<RASessionName>,<RASessionPwd>,<protocolSpecificParms> + */ + char* str = _strdup(file->RCTicket); + + if (!str) + goto error; + + const size_t length = strlen(str); + + int count = 1; + for (size_t i = 0; i < length; i++) + { + if (str[i] == ',') + count++; + } + + if (count != 8) + goto error; + + count = 0; + tokens[count++] = str; + + for (size_t i = 0; i < length; i++) + { + if (str[i] == ',') + { + str[i] = '\0'; + tokens[count++] = &str[i + 1]; + } + } + + if (strcmp(tokens[0], "65538") != 0) + goto error; + + if (strcmp(tokens[1], "1") != 0) + goto error; + + if (strcmp(tokens[3], "*") != 0) + goto error; + + if (strcmp(tokens[5], "*") != 0) + goto error; + + if (strcmp(tokens[6], "*") != 0) + goto error; + + file->RASessionId = _strdup(tokens[4]); + + if (!file->RASessionId) + goto error; + + file->RASpecificParams = _strdup(tokens[7]); + + if (!file->RASpecificParams) + goto error; + + if (!freerdp_assistance_parse_address_list(file, tokens[2])) + goto error; + + rc = TRUE; +error: + free(str); + return rc; +} + +/** + * Decrypted Connection String 2: + * + * <E> + * <A KH="BNRjdu97DyczQSRuMRrDWoue+HA=" + * ID="+ULZ6ifjoCa6cGPMLQiGHRPwkg6VyJqGwxMnO6GcelwUh9a6/FBq3It5ADSndmLL"/> <C> <T ID="1" SID="0"> <L + * P="49228" N="fe80::1032:53d9:5a01:909b%3"/> <L P="49229" N="fe80::3d8f:9b2d:6b4e:6aa%6"/> <L + * P="49230" N="192.168.1.200"/> <L P="49231" N="169.254.6.170"/> + * </T> + * </C> + * </E> + */ + +static BOOL freerdp_assistance_parse_attr(const char** opt, size_t* plength, const char* key, + const char* tag) +{ + WINPR_ASSERT(opt); + WINPR_ASSERT(plength); + WINPR_ASSERT(key); + + *opt = NULL; + *plength = 0; + if (!tag) + return FALSE; + + char bkey[128] = { 0 }; + const int rc = _snprintf(bkey, sizeof(bkey), "%s=\"", key); + WINPR_ASSERT(rc > 0); + WINPR_ASSERT(rc < sizeof(bkey)); + + char* p = strstr(tag, bkey); + if (!p) + return TRUE; + + p += strlen(bkey); + char* q = strchr(p, '"'); + + if (!q) + { + WLog_ERR(TAG, "Failed to parse ASSISTANCE file: ConnectionString2 invalid field '%s=%s'", + key, p); + return FALSE; + } + + if (p > q) + { + WLog_ERR(TAG, + "Failed to parse ASSISTANCE file: ConnectionString2 invalid field " + "order for '%s'", + key); + return FALSE; + } + const size_t length = q - p; + *opt = p; + *plength = length; + + return TRUE; +} + +static BOOL freerdp_assistance_parse_attr_str(char** opt, const char* key, const char* tag) +{ + const char* copt = NULL; + size_t size = 0; + if (!freerdp_assistance_parse_attr(&copt, &size, key, tag)) + return FALSE; + return update_option(opt, copt, size); +} + +static BOOL freerdp_assistance_parse_attr_bool(BOOL* opt, const char* key, const char* tag) +{ + const char* copt = NULL; + size_t size = 0; + + WINPR_ASSERT(opt); + *opt = FALSE; + + if (!freerdp_assistance_parse_attr(&copt, &size, key, tag)) + return FALSE; + if (size != 1) + return TRUE; + + *opt = (copt[0] == '1'); + return TRUE; +} + +static BOOL freerdp_assistance_parse_attr_uint32(UINT32* opt, const char* key, const char* tag) +{ + const char* copt = NULL; + size_t size = 0; + + WINPR_ASSERT(opt); + *opt = 0; + + if (!freerdp_assistance_parse_attr(&copt, &size, key, tag)) + return FALSE; + + char buffer[64] = { 0 }; + if (size >= sizeof(buffer)) + { + WLog_WARN(TAG, "Invalid UINT32 string '%s' [%" PRIuz "]", copt, size); + return FALSE; + } + + strncpy(buffer, copt, size); + errno = 0; + unsigned long val = strtoul(buffer, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + { + WLog_ERR(TAG, "Failed to parse ASSISTANCE file: Invalid value %s", buffer); + return FALSE; + } + + *opt = val; + + return TRUE; +} + +static char* freerdp_assistance_contains_element(char* input, size_t ilen, const char* key, + size_t* plen, char** pdata, size_t* pdlen) +{ + WINPR_ASSERT(input); + WINPR_ASSERT(key); + WINPR_ASSERT(plen); + + char bkey[128] = { 0 }; + const int rc = _snprintf(bkey, sizeof(bkey), "<%s", key); + WINPR_ASSERT(rc > 0); + WINPR_ASSERT(rc < sizeof(bkey)); + + char* tag = strstr(input, bkey); + if (!tag || (tag > input + ilen)) + return NULL; + + char* data = tag + strnlen(bkey, sizeof(bkey)); + + /* Ensure there is a valid delimiter following our token */ + switch (data[0]) + { + case '>': + case '/': + case ' ': + case '\t': + break; + default: + WLog_ERR(TAG, + "Failed to parse ASSISTANCE file: ConnectionString2 missing delimiter after " + "field %s", + bkey); + return NULL; + } + + char* start = strstr(tag, ">"); + + if (!start || (start > input + ilen)) + { + WLog_ERR(TAG, "Failed to parse ASSISTANCE file: ConnectionString2 missing field %s", bkey); + return NULL; + } + + const char* end = start; + const char* dend = start - 1; + if (*dend != '/') + { + char ekey[128] = { 0 }; + const int erc = _snprintf(ekey, sizeof(ekey), "</%s>", key); + WINPR_ASSERT(erc > 0); + WINPR_ASSERT(erc < sizeof(ekey)); + const size_t offset = start - tag; + dend = end = strrstr(start, ilen - offset, ekey); + if (end) + end += strnlen(ekey, sizeof(ekey)); + } + + if (!end) + { + WLog_ERR(TAG, + "Failed to parse ASSISTANCE file: ConnectionString2 missing end tag for field %s", + key); + return NULL; + } + if (plen) + *plen = end - tag; + + if (pdata) + *pdata = data; + if (pdlen) + *pdlen = dend - data; + return tag; +} + +/**! \brief this function returns a XML element identified by \b key + * The input string will be manipulated, so that the element found is '\0' terminated. + * + * This function can not find multiple elements on the same level as the input string is changed! + */ +static BOOL freerdp_assistance_consume_input_and_get_element(char* input, const char* key, + char** element, size_t* elen) +{ + WINPR_ASSERT(input); + WINPR_ASSERT(key); + WINPR_ASSERT(element); + WINPR_ASSERT(elen); + + size_t len = 0; + size_t dlen = 0; + char* data = NULL; + char* tag = freerdp_assistance_contains_element(input, strlen(input), key, &len, &data, &dlen); + if (!tag) + return FALSE; + + char* end = data + dlen; + *tag = '\0'; + *end = '\0'; + *element = data; + *elen = dlen + 1; + return TRUE; +} + +static BOOL freerdp_assistance_get_element(char* input, size_t ilen, const char* key, + char** element, size_t* elen) +{ + WINPR_ASSERT(input); + WINPR_ASSERT(key); + WINPR_ASSERT(element); + WINPR_ASSERT(elen); + + size_t len = 0; + size_t dlen = 0; + char* data = NULL; + char* tag = freerdp_assistance_contains_element(input, ilen, key, &len, &data, &dlen); + if (!tag) + return FALSE; + + if (tag + len > input + ilen) + return FALSE; + + char* end = tag + len; + *element = data; + *elen = end - data + 1; + return TRUE; +} + +static BOOL freerdp_assistance_parse_all_elements_of(rdpAssistanceFile* file, char* data, + size_t len, const char* key, + BOOL (*fkt)(rdpAssistanceFile* file, + char* data, size_t len)) +{ + char* val = NULL; + size_t vlen = 0; + + while (freerdp_assistance_get_element(data, len, key, &val, &vlen)) + { + data = val + vlen; + len = strnlen(data, len); + if (vlen > 0) + { + val[vlen - 1] = '\0'; + + if (!fkt(file, val, vlen)) + return FALSE; + } + } + + return TRUE; +} + +static BOOL freerdp_assistance_parse_all_elements_of_l(rdpAssistanceFile* file, char* data, + size_t len) +{ + UINT32 p = 0; + const char* n = NULL; + const char* u = NULL; + size_t nlen = 0; + size_t ulen = 0; + if (!freerdp_assistance_parse_attr_uint32(&p, "P", data)) + return FALSE; + if (!freerdp_assistance_parse_attr(&n, &nlen, "N", data)) + return FALSE; + if (!freerdp_assistance_parse_attr(&u, &ulen, "U", data)) + return FALSE; + + if (n && (nlen > 0)) + { + if (!append_address_to_list(file->MachineAddresses, n, nlen)) + return FALSE; + if (!ArrayList_Append(file->MachinePorts, (void*)(uintptr_t)p)) + return FALSE; + } + if (u && (ulen > 0)) + { + if (!append_address_to_list(file->MachineAddresses, u, ulen)) + return FALSE; + if (!ArrayList_Append(file->MachinePorts, (void*)(uintptr_t)p)) + return FALSE; + } + return TRUE; +} + +static BOOL freerdp_assistance_parse_all_elements_of_t(rdpAssistanceFile* file, char* data, + size_t len) +{ + UINT32 id = 0; + UINT32 sid = 0; + if (!freerdp_assistance_parse_attr_uint32(&id, "ID", data)) + return FALSE; + if (!freerdp_assistance_parse_attr_uint32(&sid, "SID", data)) + return FALSE; + WLog_DBG(TAG, "transport id=%" PRIu32 ", sid=%" PRIu32, id, sid); + return freerdp_assistance_parse_all_elements_of(file, data, len, "L", + freerdp_assistance_parse_all_elements_of_l); +} + +static BOOL freerdp_assistance_parse_all_elements_of_c(rdpAssistanceFile* file, char* data, + size_t len) +{ + return freerdp_assistance_parse_all_elements_of(file, data, len, "T", + freerdp_assistance_parse_all_elements_of_t); +} + +static BOOL freerdp_assistance_parse_find_elements_of_c(rdpAssistanceFile* file, char* data, + size_t len) +{ + return freerdp_assistance_parse_all_elements_of(file, data, len, "C", + freerdp_assistance_parse_all_elements_of_c); +} + +static BOOL freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) +{ + BOOL rc = FALSE; + + WINPR_ASSERT(file); + + if (!file->ConnectionString2) + return FALSE; + + char* str = _strdup(file->ConnectionString2); + if (!str) + goto out_fail; + + char* e = NULL; + size_t elen = 0; + if (!freerdp_assistance_consume_input_and_get_element(str, "E", &e, &elen)) + goto out_fail; + + if (!e || (elen == 0)) + goto out_fail; + + char* a = NULL; + size_t alen = 0; + if (!freerdp_assistance_get_element(e, elen, "A", &a, &alen)) + goto out_fail; + + if (!a || (alen == 0)) + goto out_fail; + + if (!freerdp_assistance_parse_find_elements_of_c(file, e, elen)) + goto out_fail; + + /* '\0' terminate the detected XML elements so + * the parser can continue with terminated strings + */ + a[alen] = '\0'; + if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams, "KH", a)) + goto out_fail; + + if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams2, "KH2", a)) + goto out_fail; + + if (!freerdp_assistance_parse_attr_str(&file->RASessionId, "ID", a)) + goto out_fail; + + rc = TRUE; +out_fail: + free(str); + return rc; +} + +char* freerdp_assistance_construct_expert_blob(const char* name, const char* pass) +{ + size_t size = 0; + size_t nameLength = 0; + size_t passLength = 0; + char* ExpertBlob = NULL; + + if (!name || !pass) + return NULL; + + nameLength = strlen(name) + strlen("NAME="); + passLength = strlen(pass) + strlen("PASS="); + size = nameLength + passLength + 64; + ExpertBlob = (char*)calloc(1, size); + + if (!ExpertBlob) + return NULL; + + sprintf_s(ExpertBlob, size, "%" PRIdz ";NAME=%s%" PRIdz ";PASS=%s", nameLength, name, + passLength, pass); + return ExpertBlob; +} + +char* freerdp_assistance_generate_pass_stub(DWORD flags) +{ + UINT32 nums[14]; + char* passStub = NULL; + char set1[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*_"; + char set2[12] = "!@#$&^*()-+="; + char set3[10] = "0123456789"; + char set4[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char set5[26] = "abcdefghijklmnopqrstuvwxyz"; + passStub = (char*)malloc(15); + + if (!passStub) + return NULL; + + /** + * PassStub generation: + * + * Characters 0 and 5-13 are from the set A-Z a-z 0-9 * _ + * Character 1 is from the set !@#$&^*()-+= + * Character 2 is from the set 0-9 + * Character 3 is from the set A-Z + * Character 4 is from the set a-z + * + * Example: WB^6HsrIaFmEpi + */ + winpr_RAND(nums, sizeof(nums)); + passStub[0] = set1[nums[0] % sizeof(set1)]; /* character 0 */ + passStub[1] = set2[nums[1] % sizeof(set2)]; /* character 1 */ + passStub[2] = set3[nums[2] % sizeof(set3)]; /* character 2 */ + passStub[3] = set4[nums[3] % sizeof(set4)]; /* character 3 */ + passStub[4] = set5[nums[4] % sizeof(set5)]; /* character 4 */ + passStub[5] = set1[nums[5] % sizeof(set1)]; /* character 5 */ + passStub[6] = set1[nums[6] % sizeof(set1)]; /* character 6 */ + passStub[7] = set1[nums[7] % sizeof(set1)]; /* character 7 */ + passStub[8] = set1[nums[8] % sizeof(set1)]; /* character 8 */ + passStub[9] = set1[nums[9] % sizeof(set1)]; /* character 9 */ + passStub[10] = set1[nums[10] % sizeof(set1)]; /* character 10 */ + passStub[11] = set1[nums[11] % sizeof(set1)]; /* character 11 */ + passStub[12] = set1[nums[12] % sizeof(set1)]; /* character 12 */ + passStub[13] = set1[nums[13] % sizeof(set1)]; /* character 13 */ + passStub[14] = '\0'; + return passStub; +} + +BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub, + size_t* pEncryptedSize) +{ + BOOL rc = 0; + size_t cbPasswordW = 0; + size_t cbPassStubW = 0; + size_t EncryptedSize = 0; + BYTE PasswordHash[WINPR_MD5_DIGEST_LENGTH]; + WINPR_CIPHER_CTX* rc4Ctx = NULL; + BYTE* pbIn = NULL; + BYTE* pbOut = NULL; + size_t cbOut = 0; + size_t cbIn = 0; + size_t cbFinal = 0; + WCHAR* PasswordW = ConvertUtf8ToWCharAlloc(password, &cbPasswordW); + WCHAR* PassStubW = ConvertUtf8ToWCharAlloc(passStub, &cbPassStubW); + + if (!PasswordW || !PassStubW) + goto fail; + + cbPasswordW = (cbPasswordW) * sizeof(WCHAR); + cbPassStubW = (cbPassStubW) * sizeof(WCHAR); + if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*)PasswordHash, + sizeof(PasswordHash))) + goto fail; + + EncryptedSize = cbPassStubW + 4; + pbIn = (BYTE*)calloc(1, EncryptedSize); + pbOut = (BYTE*)calloc(1, EncryptedSize); + + if (!pbIn || !pbOut) + goto fail; + + *((UINT32*)pbIn) = (UINT32)cbPassStubW; + CopyMemory(&pbIn[4], PassStubW, cbPassStubW); + rc4Ctx = winpr_Cipher_New(WINPR_CIPHER_ARC4_128, WINPR_ENCRYPT, PasswordHash, NULL); + + if (!rc4Ctx) + { + WLog_ERR(TAG, "winpr_Cipher_New failure"); + goto fail; + } + + cbOut = cbFinal = 0; + cbIn = EncryptedSize; + rc = winpr_Cipher_Update(rc4Ctx, pbIn, cbIn, pbOut, &cbOut); + + if (!rc) + { + WLog_ERR(TAG, "winpr_Cipher_Update failure"); + goto fail; + } + + if (!winpr_Cipher_Final(rc4Ctx, pbOut + cbOut, &cbFinal)) + { + WLog_ERR(TAG, "winpr_Cipher_Final failure"); + goto fail; + } + + winpr_Cipher_Free(rc4Ctx); + free(pbIn); + free(PasswordW); + free(PassStubW); + *pEncryptedSize = EncryptedSize; + return pbOut; +fail: + winpr_Cipher_Free(rc4Ctx); + free(PasswordW); + free(PassStubW); + free(pbIn); + free(pbOut); + return NULL; +} + +static BOOL freerdp_assistance_decrypt2(rdpAssistanceFile* file) +{ + BOOL rc = FALSE; + int status = 0; + size_t cbPasswordW = 0; + size_t cchOutW = 0; + WINPR_CIPHER_CTX* aesDec = NULL; + WCHAR* PasswordW = NULL; + BYTE* pbIn = NULL; + BYTE* pbOut = NULL; + size_t cbOut = 0; + size_t cbIn = 0; + size_t cbFinal = 0; + BYTE DerivedKey[WINPR_AES_BLOCK_SIZE] = { 0 }; + BYTE InitializationVector[WINPR_AES_BLOCK_SIZE] = { 0 }; + BYTE PasswordHash[WINPR_SHA1_DIGEST_LENGTH] = { 0 }; + + WINPR_ASSERT(file); + + if (!file->password) + return FALSE; + + PasswordW = ConvertUtf8ToWCharAlloc(file->password, &cbPasswordW); + if (!PasswordW) + { + WLog_ERR(TAG, "Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed"); + return FALSE; + } + + cbPasswordW = (cbPasswordW) * sizeof(WCHAR); + + if (!winpr_Digest(WINPR_MD_SHA1, (BYTE*)PasswordW, cbPasswordW, PasswordHash, + sizeof(PasswordHash))) + goto fail; + + if (!freerdp_assistance_crypt_derive_key_sha1(PasswordHash, sizeof(PasswordHash), DerivedKey, + sizeof(DerivedKey))) + goto fail; + + aesDec = + winpr_Cipher_New(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, DerivedKey, InitializationVector); + + if (!aesDec) + goto fail; + + cbOut = cbFinal = 0; + cbIn = (size_t)file->EncryptedLHTicketLength; + pbIn = (BYTE*)file->EncryptedLHTicket; + pbOut = (BYTE*)calloc(1, cbIn + WINPR_AES_BLOCK_SIZE + 2); + + if (!pbOut) + goto fail; + + if (!winpr_Cipher_Update(aesDec, pbIn, cbIn, pbOut, &cbOut)) + goto fail; + + if (!winpr_Cipher_Final(aesDec, pbOut + cbOut, &cbFinal)) + { + WLog_ERR(TAG, "winpr_Cipher_Final failure"); + goto fail; + } + + cbOut += cbFinal; + cbFinal = 0; + + union + { + const WCHAR* wc; + const BYTE* b; + } cnv; + + cnv.b = pbOut; + cchOutW = cbOut / sizeof(WCHAR); + + if (!update_connectionstring2_wchar(file, cnv.wc, cchOutW)) + { + WLog_ERR(TAG, "Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed"); + goto fail; + } + + if (!freerdp_assistance_parse_connection_string2(file)) + goto fail; + + rc = TRUE; +fail: + winpr_Cipher_Free(aesDec); + free(PasswordW); + free(pbOut); + WLog_DBG(TAG, "freerdp_assistance_parse_connection_string2: %d", status); + return rc; +} + +BYTE* freerdp_assistance_hex_string_to_bin(const void* raw, size_t* size) +{ + BYTE* buffer = NULL; + if (!raw || !size) + return NULL; + *size = 0; + const size_t length = strlen(raw); + buffer = calloc(length, sizeof(BYTE)); + if (!buffer) + return NULL; + const size_t rc = winpr_HexStringToBinBuffer(raw, length, buffer, length); + if (rc == 0) + { + free(buffer); + return NULL; + } + *size = rc; + return buffer; +} + +char* freerdp_assistance_bin_to_hex_string(const void* raw, size_t size) +{ + return winpr_BinToHexString(raw, size, FALSE); +} + +static int freerdp_assistance_parse_uploadinfo(rdpAssistanceFile* file, char* uploadinfo, + size_t uploadinfosize) +{ + const char escalated[9] = "Escalated"; + const size_t esclen = sizeof(escalated); + const char* typestr = NULL; + size_t typelen = 0; + + if (!uploadinfo || (uploadinfosize == 0)) + return -1; + + if (strnlen(uploadinfo, uploadinfosize) == uploadinfosize) + { + WLog_WARN(TAG, "UPLOADINFOR string is not '\0' terminated"); + return -1; + } + + if (!freerdp_assistance_parse_attr(&typestr, &typelen, "TYPE", uploadinfo)) + return -1; + + if ((typelen != esclen) || (strncmp(typestr, escalated, esclen) != 0)) + { + WLog_ERR(TAG, + "Failed to parse ASSISTANCE file: Missing or invalid UPLOADINFO TYPE '%s' [%" PRIuz + "]", + typestr, typelen); + return -1; + } + + char* uploaddata = NULL; + size_t uploaddatasize = 0; + if (!freerdp_assistance_consume_input_and_get_element(uploadinfo, "UPLOADDATA", &uploaddata, + &uploaddatasize)) + return -1; + + /* Parse USERNAME */ + if (!freerdp_assistance_parse_attr_str(&file->Username, "USERNAME", uploaddata)) + return -1; + + /* Parse LHTICKET */ + if (!freerdp_assistance_parse_attr_str(&file->LHTicket, "LHTICKET", uploaddata)) + return -1; + + /* Parse RCTICKET */ + if (!freerdp_assistance_parse_attr_str(&file->RCTicket, "RCTICKET", uploaddata)) + return -1; + + /* Parse RCTICKETENCRYPTED */ + if (!freerdp_assistance_parse_attr_bool(&file->RCTicketEncrypted, "RCTICKETENCRYPTED", + uploaddata)) + return -1; + + /* Parse PassStub */ + if (!freerdp_assistance_parse_attr_str(&file->PassStub, "PassStub", uploaddata)) + return -1; + + if (file->PassStub) + { + const char* amp = "&"; + char* passtub = strstr(file->PassStub, amp); + while (passtub) + { + const char* end = passtub + 5; + const size_t len = strlen(end); + memmove(&passtub[1], end, len + 1); + passtub = strstr(passtub, amp); + } + } + + /* Parse DtStart */ + if (!freerdp_assistance_parse_attr_uint32(&file->DtStart, "DtStart", uploaddata)) + return -1; + + /* Parse DtLength */ + if (!freerdp_assistance_parse_attr_uint32(&file->DtLength, "DtLength", uploaddata)) + return -1; + + /* Parse L (LowSpeed) */ + if (!freerdp_assistance_parse_attr_bool(&file->LowSpeed, "L", uploaddata)) + return -1; + + file->Type = (file->LHTicket) ? 2 : 1; + int status = 0; + + switch (file->Type) + { + case 2: + { + file->EncryptedLHTicket = freerdp_assistance_hex_string_to_bin( + file->LHTicket, &file->EncryptedLHTicketLength); + + if (!freerdp_assistance_decrypt2(file)) + status = -1; + } + break; + + case 1: + { + if (!freerdp_assistance_parse_connection_string1(file)) + status = -1; + } + break; + + default: + return -1; + } + + if (status < 0) + { + WLog_ERR(TAG, "freerdp_assistance_parse_connection_string1 failure: %d", status); + return -1; + } + + file->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(file->password, file->PassStub, + &file->EncryptedPassStubLength); + + if (!file->EncryptedPassStub) + return -1; + + return 1; +} + +static int freerdp_assistance_parse_file_buffer_int(rdpAssistanceFile* file, char* buffer, + size_t size, const char* password) +{ + WINPR_ASSERT(file); + WINPR_ASSERT(buffer); + WINPR_ASSERT(size > 0); + + if (!update_password(file, password)) + return -1; + + char* uploadinfo = NULL; + size_t uploadinfosize = 0; + if (freerdp_assistance_consume_input_and_get_element(buffer, "UPLOADINFO", &uploadinfo, + &uploadinfosize)) + return freerdp_assistance_parse_uploadinfo(file, uploadinfo, uploadinfosize); + + size_t elen = 0; + const char* estr = freerdp_assistance_contains_element(buffer, size, "E", &elen, NULL, NULL); + if (!estr || (elen == 0)) + { + WLog_ERR(TAG, "Failed to parse ASSISTANCE file: Neither UPLOADINFO nor <E> found"); + return -1; + } + if (!update_connectionstring2(file, estr, elen)) + return -1; + + if (!freerdp_assistance_parse_connection_string2(file)) + return -1; + + return 1; +} + +int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* cbuffer, size_t size, + const char* password) +{ + WINPR_ASSERT(file); + if (!password) + { + WLog_WARN(TAG, "empty password supplied"); + } + + if (!cbuffer || (size == 0)) + { + WLog_WARN(TAG, "no data supplied [%p, %" PRIuz "]", cbuffer, size); + return -1; + } + + char* abuffer = strndup(cbuffer, size); + const size_t len = strnlen(cbuffer, size); + if (len == size) + WLog_WARN(TAG, "Input data not '\0' terminated"); + + if (!abuffer) + return -1; + + const int rc = freerdp_assistance_parse_file_buffer_int(file, abuffer, len + 1, password); + free(abuffer); + return rc; +} + +int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name, const char* password) +{ + int status = 0; + BYTE* buffer = NULL; + FILE* fp = NULL; + size_t readSize = 0; + union + { + INT64 i64; + size_t s; + } fileSize; + + if (!update_name(file, name)) + return -1; + + fp = winpr_fopen(name, "r"); + + if (!fp) + { + WLog_ERR(TAG, "Failed to open ASSISTANCE file %s ", name); + return -1; + } + + _fseeki64(fp, 0, SEEK_END); + fileSize.i64 = _ftelli64(fp); + _fseeki64(fp, 0, SEEK_SET); + + if (fileSize.i64 < 1) + { + WLog_ERR(TAG, "Failed to read ASSISTANCE file %s ", name); + fclose(fp); + return -1; + } + + buffer = (BYTE*)malloc(fileSize.s + 2); + + if (!buffer) + { + fclose(fp); + return -1; + } + + readSize = fread(buffer, fileSize.s, 1, fp); + + if (!readSize) + { + if (!ferror(fp)) + readSize = fileSize.s; + } + + fclose(fp); + + if (readSize < 1) + { + WLog_ERR(TAG, "Failed to read ASSISTANCE file %s ", name); + free(buffer); + buffer = NULL; + return -1; + } + + buffer[fileSize.s] = '\0'; + buffer[fileSize.s + 1] = '\0'; + status = freerdp_assistance_parse_file_buffer(file, (char*)buffer, fileSize.s, password); + free(buffer); + return status; +} + +BOOL freerdp_assistance_populate_settings_from_assistance_file(rdpAssistanceFile* file, + rdpSettings* settings) +{ + if (!freerdp_settings_set_bool(settings, FreeRDP_RemoteAssistanceMode, TRUE)) + return FALSE; + + if (!file->RASessionId || !file->MachineAddresses) + return FALSE; + + if (!freerdp_settings_set_string(settings, FreeRDP_RemoteAssistanceSessionId, + file->RASessionId)) + return FALSE; + + if (file->RCTicket) + { + if (!freerdp_settings_set_string(settings, FreeRDP_RemoteAssistanceRCTicket, + file->RCTicket)) + return FALSE; + } + else + { + if (!freerdp_settings_set_string(settings, FreeRDP_RemoteAssistanceRCTicket, + file->ConnectionString2)) + return FALSE; + } + + if (file->PassStub) + { + if (!freerdp_settings_set_string(settings, FreeRDP_RemoteAssistancePassStub, + file->PassStub)) + return FALSE; + } + + if (ArrayList_Count(file->MachineAddresses) < 1) + return FALSE; + + const char* addr = ArrayList_GetItem(file->MachineAddresses, 0); + if (!freerdp_settings_set_string(settings, FreeRDP_ServerHostname, addr)) + return FALSE; + + if (!freerdp_settings_set_string(settings, FreeRDP_AssistanceFile, file->filename)) + return FALSE; + + if (!freerdp_settings_set_string(settings, FreeRDP_RemoteAssistancePassword, file->password)) + return FALSE; + + if (file->Username) + { + if (!freerdp_settings_set_string(settings, FreeRDP_Username, file->Username)) + return FALSE; + } + + if (!freerdp_settings_set_bool(settings, FreeRDP_RemoteAssistanceMode, TRUE)) + return FALSE; + + const size_t ports = ArrayList_Count(file->MachinePorts); + const size_t addresses = ArrayList_Count(file->MachineAddresses); + if (ports < 1) + return FALSE; + if (ports != addresses) + return FALSE; + + const UINT32 port = (UINT32)ArrayList_GetItem(file->MachinePorts, 0); + if (!freerdp_settings_set_uint32(settings, FreeRDP_ServerPort, port)) + return FALSE; + + if (!freerdp_target_net_adresses_reset(settings, ports)) + return FALSE; + + for (size_t x = 0; x < ports; x++) + { + const UINT32 port = (UINT32)ArrayList_GetItem(file->MachinePorts, x); + if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetPorts, x, &port)) + return FALSE; + } + for (size_t i = 0; i < addresses; i++) + { + const char* maddr = ArrayList_GetItem(file->MachineAddresses, i); + if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetAddresses, i, maddr)) + return FALSE; + } + + return TRUE; +} + +static BOOL setup_string(wArrayList* list) +{ + WINPR_ASSERT(list); + + wObject* obj = ArrayList_Object(list); + if (!obj) + return FALSE; + obj->fnObjectFree = free; + // obj->fnObjectNew = wwinpr_ObjectStringClone; + return TRUE; +} + +rdpAssistanceFile* freerdp_assistance_file_new(void) +{ + winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT); + rdpAssistanceFile* file = calloc(1, sizeof(rdpAssistanceFile)); + if (!file) + return NULL; + + file->MachineAddresses = ArrayList_New(FALSE); + file->MachinePorts = ArrayList_New(FALSE); + file->MachineUris = ArrayList_New(FALSE); + + if (!file->MachineAddresses || !file->MachinePorts || !file->MachineUris) + goto fail; + + if (!setup_string(file->MachineAddresses) || !setup_string(file->MachineUris)) + goto fail; + + return file; + +fail: + WINPR_PRAGMA_DIAG_PUSH + WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC + freerdp_assistance_file_free(file); + WINPR_PRAGMA_DIAG_POP + return NULL; +} + +void freerdp_assistance_file_free(rdpAssistanceFile* file) +{ + if (!file) + return; + + update_password(file, NULL); + update_connectionstring2(file, NULL, 0); + free(file->filename); + free(file->Username); + free(file->LHTicket); + free(file->RCTicket); + free(file->PassStub); + free(file->ConnectionString1); + free(file->EncryptedLHTicket); + free(file->RASessionId); + free(file->RASpecificParams); + free(file->RASpecificParams2); + free(file->EncryptedPassStub); + + ArrayList_Free(file->MachineAddresses); + ArrayList_Free(file->MachinePorts); + ArrayList_Free(file->MachineUris); + free(file); +} + +void freerdp_assistance_print_file(rdpAssistanceFile* file, wLog* log, DWORD level) +{ + WINPR_ASSERT(file); + + WLog_Print(log, level, "Username: %s", file->Username); + WLog_Print(log, level, "LHTicket: %s", file->LHTicket); + WLog_Print(log, level, "RCTicket: %s", file->RCTicket); + WLog_Print(log, level, "RCTicketEncrypted: %" PRId32, file->RCTicketEncrypted); + WLog_Print(log, level, "PassStub: %s", file->PassStub); + WLog_Print(log, level, "DtStart: %" PRIu32, file->DtStart); + WLog_Print(log, level, "DtLength: %" PRIu32, file->DtLength); + WLog_Print(log, level, "LowSpeed: %" PRId32, file->LowSpeed); + WLog_Print(log, level, "RASessionId: %s", file->RASessionId); + WLog_Print(log, level, "RASpecificParams: %s", file->RASpecificParams); + WLog_Print(log, level, "RASpecificParams2: %s", file->RASpecificParams2); + + for (size_t x = 0; x < ArrayList_Count(file->MachineAddresses); x++) + { + UINT32 port = 0; + const char* uri = NULL; + const char* addr = ArrayList_GetItem(file->MachineAddresses, x); + if (x < ArrayList_Count(file->MachinePorts)) + port = (UINT32)ArrayList_GetItem(file->MachinePorts, x); + if (x < ArrayList_Count(file->MachineUris)) + uri = ArrayList_GetItem(file->MachineUris, x); + + WLog_Print(log, level, "MachineAddress [%" PRIdz ": %s", x, addr); + WLog_Print(log, level, "MachinePort [%" PRIdz ": %" PRIu32, x, port); + WLog_Print(log, level, "MachineURI [%" PRIdz ": %s", x, uri); + } +} + +BOOL freerdp_assistance_get_encrypted_pass_stub(rdpAssistanceFile* file, const char** pwd, + size_t* size) +{ + if (!file || !pwd || !size) + return FALSE; + + *pwd = (const char*)file->EncryptedPassStub; + *size = file->EncryptedPassStubLength; + return TRUE; +} + +int freerdp_assistance_set_connection_string2(rdpAssistanceFile* file, const char* string, + const char* password) +{ + if (!file || !string || !password) + return -1; + + char* str = _strdup(string); + if (!str) + return -1; + + if (!update_connectionstring2_nocopy(file, str)) + return -1; + if (!update_password(file, password)) + return -1; + return freerdp_assistance_parse_connection_string2(file); +} diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c new file mode 100644 index 0000000..34712c8 --- /dev/null +++ b/libfreerdp/common/settings.c @@ -0,0 +1,2185 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Settings Management + * + * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * Copyright 2016 Armin Novak <armin.novak@gmail.com> + * Copyright 2023 Armin Novak <anovak@thincast.com> + * Copyright 2023 Thincast Technologies GmbH + * + * 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. + */ + +#include <freerdp/config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <winpr/crt.h> +#include <winpr/assert.h> + +#include "../core/settings.h" +#include "../core/capabilities.h" + +#include <freerdp/crypto/certificate.h> +#include <freerdp/settings.h> +#include <freerdp/freerdp.h> +#include <freerdp/log.h> + +#define TAG FREERDP_TAG("common") + +BOOL freerdp_addin_argv_add_argument_ex(ADDIN_ARGV* args, const char* argument, size_t len) +{ + char* str = NULL; + char** new_argv = NULL; + + if (!args || !argument) + return FALSE; + + if (len == 0) + len = strlen(argument); + + new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1)); + + if (!new_argv) + return FALSE; + + args->argv = new_argv; + + str = calloc(len + 1, sizeof(char)); + if (!str) + return FALSE; + memcpy(str, argument, len); + args->argv[args->argc++] = str; + return TRUE; +} + +BOOL freerdp_addin_argv_add_argument(ADDIN_ARGV* args, const char* argument) +{ + return freerdp_addin_argv_add_argument_ex(args, argument, 0); +} + +BOOL freerdp_addin_argv_del_argument(ADDIN_ARGV* args, const char* argument) +{ + if (!args || !argument) + return FALSE; + for (int x = 0; x < args->argc; x++) + { + char* arg = args->argv[x]; + if (strcmp(argument, arg) == 0) + { + free(arg); + memmove_s(&args->argv[x], (args->argc - x) * sizeof(char*), &args->argv[x + 1], + (args->argc - x - 1) * sizeof(char*)); + args->argv[args->argc - 1] = NULL; + args->argc--; + return TRUE; + } + } + return FALSE; +} + +int freerdp_addin_set_argument(ADDIN_ARGV* args, const char* argument) +{ + if (!args || !argument) + return -2; + + for (int i = 0; i < args->argc; i++) + { + if (strcmp(args->argv[i], argument) == 0) + { + return 1; + } + } + + if (!freerdp_addin_argv_add_argument(args, argument)) + return -1; + return 0; +} + +int freerdp_addin_replace_argument(ADDIN_ARGV* args, const char* previous, const char* argument) +{ + if (!args || !previous || !argument) + return -2; + + for (int i = 0; i < args->argc; i++) + { + if (strcmp(args->argv[i], previous) == 0) + { + free(args->argv[i]); + + if (!(args->argv[i] = _strdup(argument))) + return -1; + + return 1; + } + } + + if (!freerdp_addin_argv_add_argument(args, argument)) + return -1; + return 0; +} + +int freerdp_addin_set_argument_value(ADDIN_ARGV* args, const char* option, const char* value) +{ + BOOL rc = 0; + char* p = NULL; + char* str = NULL; + size_t length = 0; + if (!args || !option || !value) + return -2; + length = strlen(option) + strlen(value) + 1; + str = (char*)calloc(length + 1, sizeof(char)); + + if (!str) + return -1; + + sprintf_s(str, length + 1, "%s:%s", option, value); + + for (int i = 0; i < args->argc; i++) + { + p = strchr(args->argv[i], ':'); + + if (p) + { + if (strncmp(args->argv[i], option, p - args->argv[i]) == 0) + { + free(args->argv[i]); + args->argv[i] = str; + return 1; + } + } + } + + rc = freerdp_addin_argv_add_argument(args, str); + free(str); + if (!rc) + return -1; + return 0; +} + +int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, const char* previous, const char* option, + const char* value) +{ + BOOL rc = 0; + char* str = NULL; + size_t length = 0; + if (!args || !previous || !option || !value) + return -2; + length = strlen(option) + strlen(value) + 1; + str = (char*)calloc(length + 1, sizeof(char)); + + if (!str) + return -1; + + sprintf_s(str, length + 1, "%s:%s", option, value); + + for (int i = 0; i < args->argc; i++) + { + if (strcmp(args->argv[i], previous) == 0) + { + free(args->argv[i]); + args->argv[i] = str; + return 1; + } + } + + rc = freerdp_addin_argv_add_argument(args, str); + free(str); + if (!rc) + return -1; + return 0; +} + +BOOL freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device) +{ + UINT32 count = 0; + UINT32 old = 0; + WINPR_ASSERT(settings); + WINPR_ASSERT(device); + + count = freerdp_settings_get_uint32(settings, FreeRDP_DeviceCount) + 1; + old = freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize); + if (old < count) + { + UINT32 new_size = old * 2; + RDPDR_DEVICE** new_array = NULL; + + if (new_size == 0) + new_size = count * 2; + + new_array = + (RDPDR_DEVICE**)realloc(settings->DeviceArray, new_size * sizeof(RDPDR_DEVICE*)); + + if (!new_array) + return FALSE; + + settings->DeviceArray = new_array; + memset(&settings->DeviceArray[old], 0, (new_size - old) * sizeof(RDPDR_DEVICE*)); + + if (!freerdp_settings_set_uint32(settings, FreeRDP_DeviceArraySize, new_size)) + return FALSE; + } + + settings->DeviceArray[settings->DeviceCount++] = device; + return TRUE; +} + +RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* name) +{ + RDPDR_DEVICE* device = NULL; + + WINPR_ASSERT(settings); + WINPR_ASSERT(name); + for (UINT32 index = 0; index < settings->DeviceCount; index++) + { + device = (RDPDR_DEVICE*)settings->DeviceArray[index]; + + if (!device->Name) + continue; + + if (strcmp(device->Name, name) == 0) + return device; + } + + return NULL; +} + +RDPDR_DEVICE* freerdp_device_collection_find_type(rdpSettings* settings, UINT32 type) +{ + RDPDR_DEVICE* device = NULL; + WINPR_ASSERT(settings); + + for (UINT32 index = 0; index < settings->DeviceCount; index++) + { + device = (RDPDR_DEVICE*)settings->DeviceArray[index]; + + if (device->Type == type) + return device; + } + + return NULL; +} + +RDPDR_DEVICE* freerdp_device_new(UINT32 Type, size_t count, const char* args[]) +{ + size_t size = 0; + union + { + RDPDR_DEVICE* base; + RDPDR_DRIVE* drive; + RDPDR_SERIAL* serial; + RDPDR_PRINTER* printer; + RDPDR_PARALLEL* parallel; + RDPDR_SMARTCARD* smartcard; + } device; + + device.base = NULL; + WINPR_ASSERT(args || (count == 0)); + + switch (Type) + { + case RDPDR_DTYP_PRINT: + size = sizeof(RDPDR_PRINTER); + break; + case RDPDR_DTYP_SERIAL: + size = sizeof(RDPDR_SERIAL); + break; + case RDPDR_DTYP_PARALLEL: + size = sizeof(RDPDR_PARALLEL); + break; + case RDPDR_DTYP_SMARTCARD: + size = sizeof(RDPDR_SMARTCARD); + break; + case RDPDR_DTYP_FILESYSTEM: + size = sizeof(RDPDR_DRIVE); + break; + default: + goto fail; + } + + device.base = calloc(1, size); + if (!device.base) + goto fail; + device.base->Id = 0; + device.base->Type = Type; + + if (count > 0) + { + device.base->Name = _strdup(args[0]); + if (!device.base->Name) + goto fail; + + switch (Type) + { + case RDPDR_DTYP_PRINT: + if (count > 1) + { + device.printer->DriverName = _strdup(args[1]); + if (!device.printer->DriverName) + goto fail; + } + + if (count > 2) + { + device.printer->IsDefault = _stricmp(args[2], "default") == 0; + } + break; + case RDPDR_DTYP_SERIAL: + if (count > 1) + { + device.serial->Path = _strdup(args[1]); + if (!device.serial->Path) + goto fail; + } + + if (count > 2) + { + device.serial->Driver = _strdup(args[2]); + if (!device.serial->Driver) + goto fail; + } + + if (count > 3) + { + device.serial->Permissive = _strdup(args[3]); + if (!device.serial->Permissive) + goto fail; + } + break; + case RDPDR_DTYP_PARALLEL: + if (count > 1) + { + device.parallel->Path = _strdup(args[1]); + if (!device.serial->Path) + goto fail; + } + break; + case RDPDR_DTYP_SMARTCARD: + break; + case RDPDR_DTYP_FILESYSTEM: + if (count > 1) + { + device.drive->Path = _strdup(args[1]); + if (!device.drive->Path) + goto fail; + } + if (count > 2) + device.drive->automount = (args[2] == NULL) ? TRUE : FALSE; + break; + default: + goto fail; + } + } + return device.base; + +fail: + freerdp_device_free(device.base); + return NULL; +} + +void freerdp_device_free(RDPDR_DEVICE* device) +{ + union + { + RDPDR_DEVICE* dev; + RDPDR_DRIVE* drive; + RDPDR_SERIAL* serial; + RDPDR_PRINTER* printer; + RDPDR_PARALLEL* parallel; + RDPDR_SMARTCARD* smartcard; + } cnv; + + cnv.dev = device; + if (!cnv.dev) + return; + + switch (device->Type) + { + case RDPDR_DTYP_PRINT: + free(cnv.printer->DriverName); + break; + case RDPDR_DTYP_SERIAL: + free(cnv.serial->Path); + free(cnv.serial->Driver); + free(cnv.serial->Permissive); + break; + case RDPDR_DTYP_PARALLEL: + free(cnv.parallel->Path); + break; + case RDPDR_DTYP_SMARTCARD: + break; + case RDPDR_DTYP_FILESYSTEM: + free(cnv.drive->Path); + break; + default: + break; + } + free(cnv.dev->Name); + free(cnv.dev); +} + +RDPDR_DEVICE* freerdp_device_clone(const RDPDR_DEVICE* device) +{ + union + { + const RDPDR_DEVICE* dev; + const RDPDR_DRIVE* drive; + const RDPDR_SERIAL* serial; + const RDPDR_PRINTER* printer; + const RDPDR_PARALLEL* parallel; + const RDPDR_SMARTCARD* smartcard; + } src; + + union + { + RDPDR_DEVICE* dev; + RDPDR_DRIVE* drive; + RDPDR_SERIAL* serial; + RDPDR_PRINTER* printer; + RDPDR_PARALLEL* parallel; + RDPDR_SMARTCARD* smartcard; + } copy; + size_t count = 0; + const char* args[4] = { 0 }; + + copy.dev = NULL; + src.dev = device; + + if (!device) + return NULL; + + if (device->Name) + { + count = 1; + args[0] = device->Name; + } + + switch (device->Type) + { + case RDPDR_DTYP_FILESYSTEM: + if (src.drive->Path) + { + args[1] = src.drive->Path; + count = 2; + } + break; + + case RDPDR_DTYP_PRINT: + if (src.printer->DriverName) + { + args[1] = src.printer->DriverName; + count = 2; + } + break; + + case RDPDR_DTYP_SMARTCARD: + break; + + case RDPDR_DTYP_SERIAL: + if (src.serial->Path) + { + args[1] = src.serial->Path; + count = 2; + } + + if (src.serial->Driver) + { + args[2] = src.serial->Driver; + count = 3; + } + + if (src.serial->Permissive) + { + args[3] = src.serial->Permissive; + count = 4; + } + break; + + case RDPDR_DTYP_PARALLEL: + if (src.parallel->Path) + { + args[1] = src.parallel->Path; + count = 2; + } + break; + default: + WLog_ERR(TAG, "unknown device type %" PRIu32 "", device->Type); + break; + } + + copy.dev = freerdp_device_new(device->Type, count, args); + if (!copy.dev) + return NULL; + + copy.dev->Id = device->Id; + + return copy.dev; +} + +void freerdp_device_collection_free(rdpSettings* settings) +{ + WINPR_ASSERT(settings); + + if (settings->DeviceArray) + { + for (UINT32 index = 0; index < settings->DeviceArraySize; index++) + freerdp_settings_set_pointer_array(settings, FreeRDP_DeviceArray, index, NULL); + } + + free(settings->DeviceArray); + + freerdp_settings_set_pointer(settings, FreeRDP_DeviceArray, NULL); + freerdp_settings_set_uint32(settings, FreeRDP_DeviceArraySize, 0); + freerdp_settings_set_uint32(settings, FreeRDP_DeviceCount, 0); +} + +BOOL freerdp_static_channel_collection_del(rdpSettings* settings, const char* name) +{ + const UINT32 count = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount); + if (!settings || !settings->StaticChannelArray) + return FALSE; + + for (UINT32 x = 0; x < count; x++) + { + ADDIN_ARGV* cur = settings->StaticChannelArray[x]; + if (cur && (cur->argc > 0)) + { + if (strcmp(name, cur->argv[0]) == 0) + { + const size_t rem = settings->StaticChannelArraySize - count + 1; + memmove_s(&settings->StaticChannelArray[x], (count - x) * sizeof(ADDIN_ARGV*), + &settings->StaticChannelArray[x + 1], + (count - x - 1) * sizeof(ADDIN_ARGV*)); + memset(&settings->StaticChannelArray[count - 1], 0, sizeof(ADDIN_ARGV*) * rem); + + freerdp_addin_argv_free(cur); + return freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelCount, count - 1); + } + } + } + { + const size_t rem = settings->StaticChannelArraySize - count; + memset(&settings->StaticChannelArray[count], 0, sizeof(ADDIN_ARGV*) * rem); + } + return FALSE; +} + +BOOL freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel) +{ + UINT32 count = 0; + + WINPR_ASSERT(settings); + WINPR_ASSERT(channel); + + count = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount) + 1; + if (freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize) < count) + { + const UINT32 oldSize = + freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize); + UINT32 new_size = oldSize * 2ul; + ADDIN_ARGV** new_array = NULL; + if (new_size == 0) + new_size = count * 2ul; + + new_array = + (ADDIN_ARGV**)realloc(settings->StaticChannelArray, new_size * sizeof(ADDIN_ARGV*)); + + if (!new_array) + return FALSE; + + settings->StaticChannelArray = new_array; + { + const size_t rem = new_size - oldSize; + memset(&settings->StaticChannelArray[oldSize], 0, sizeof(ADDIN_ARGV*) * rem); + } + if (!freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelArraySize, new_size)) + return FALSE; + } + + count = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount); + + ADDIN_ARGV** cur = &settings->StaticChannelArray[count++]; + freerdp_addin_argv_free(*cur); + *cur = channel; + return freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelCount, count); +} + +ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const char* name) +{ + ADDIN_ARGV* channel = NULL; + + WINPR_ASSERT(settings); + WINPR_ASSERT(name); + + for (UINT32 index = 0; + index < freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount); index++) + { + channel = settings->StaticChannelArray[index]; + + if (strcmp(channel->argv[0], name) == 0) + return channel; + } + + return NULL; +} + +void freerdp_static_channel_collection_free(rdpSettings* settings) +{ + if (!settings) + return; + + if (settings->StaticChannelArray) + { + for (UINT32 i = 0; + i < freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize); i++) + freerdp_addin_argv_free(settings->StaticChannelArray[i]); + } + + free(settings->StaticChannelArray); + freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelArraySize, 0); + settings->StaticChannelArray = NULL; + freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelCount, 0); +} + +BOOL freerdp_dynamic_channel_collection_del(rdpSettings* settings, const char* name) +{ + const UINT32 count = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount); + if (!settings || !settings->DynamicChannelArray) + return FALSE; + + for (UINT32 x = 0; x < count; x++) + { + ADDIN_ARGV* cur = settings->DynamicChannelArray[x]; + if (cur && (cur->argc > 0)) + { + if (strcmp(name, cur->argv[0]) == 0) + { + const size_t rem = settings->DynamicChannelArraySize - count + 1; + memmove_s(&settings->DynamicChannelArray[x], (count - x) * sizeof(ADDIN_ARGV*), + &settings->DynamicChannelArray[x + 1], + (count - x - 1) * sizeof(ADDIN_ARGV*)); + memset(&settings->DynamicChannelArray[count - 1], 0, sizeof(ADDIN_ARGV*) * rem); + + freerdp_addin_argv_free(cur); + return freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelCount, + count - 1); + } + } + } + + return FALSE; +} + +BOOL freerdp_dynamic_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel) +{ + UINT32 count = 0; + UINT32 oldSize = 0; + + WINPR_ASSERT(settings); + WINPR_ASSERT(channel); + + count = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount) + 1; + oldSize = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize); + if (oldSize < count) + { + ADDIN_ARGV** new_array = NULL; + UINT32 size = oldSize * 2; + if (size == 0) + size = count * 2; + + new_array = realloc(settings->DynamicChannelArray, sizeof(ADDIN_ARGV*) * size); + + if (!new_array) + return FALSE; + + settings->DynamicChannelArray = new_array; + { + const size_t rem = size - oldSize; + memset(&settings->DynamicChannelArray[oldSize], 0, sizeof(ADDIN_ARGV*) * rem); + } + if (!freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelArraySize, size)) + return FALSE; + } + + count = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount); + settings->DynamicChannelArray[count++] = channel; + return freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelCount, count); +} + +ADDIN_ARGV* freerdp_dynamic_channel_collection_find(const rdpSettings* settings, const char* name) +{ + WINPR_ASSERT(settings); + WINPR_ASSERT(name); + + for (UINT32 index = 0; + index < freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount); index++) + { + ADDIN_ARGV* channel = settings->DynamicChannelArray[index]; + + if (strcmp(channel->argv[0], name) == 0) + return channel; + } + + return NULL; +} + +void freerdp_addin_argv_free(ADDIN_ARGV* args) +{ + if (!args) + return; + + if (args->argv) + { + for (int index = 0; index < args->argc; index++) + free(args->argv[index]); + free(args->argv); + } + + free(args); +} + +ADDIN_ARGV* freerdp_addin_argv_new(size_t argc, const char* argv[]) +{ + ADDIN_ARGV* args = calloc(1, sizeof(ADDIN_ARGV)); + if (!args) + return NULL; + if (argc == 0) + return args; + + args->argc = argc; + args->argv = calloc(argc, sizeof(char*)); + if (!args->argv) + goto fail; + + if (argv) + { + for (size_t x = 0; x < argc; x++) + { + args->argv[x] = _strdup(argv[x]); + if (!args->argv[x]) + goto fail; + } + } + return args; + +fail: + freerdp_addin_argv_free(args); + return NULL; +} + +ADDIN_ARGV* freerdp_addin_argv_clone(const ADDIN_ARGV* args) +{ + union + { + char** c; + const char** cc; + } cnv; + if (!args) + return NULL; + cnv.c = args->argv; + return freerdp_addin_argv_new(args->argc, cnv.cc); +} + +void freerdp_dynamic_channel_collection_free(rdpSettings* settings) +{ + WINPR_ASSERT(settings); + + if (settings->DynamicChannelArray) + { + for (UINT32 i = 0; + i < freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize); i++) + freerdp_addin_argv_free(settings->DynamicChannelArray[i]); + } + + free(settings->DynamicChannelArray); + freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelArraySize, 0); + settings->DynamicChannelArray = NULL; + freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelCount, 0); +} + +void freerdp_capability_buffer_free(rdpSettings* settings) +{ + WINPR_ASSERT(settings); + + if (settings->ReceivedCapabilityData) + { + for (UINT32 x = 0; x < settings->ReceivedCapabilitiesSize; x++) + { + free(settings->ReceivedCapabilityData[x]); + settings->ReceivedCapabilityData[x] = NULL; + } + } + settings->ReceivedCapabilitiesSize = 0; + + free(settings->ReceivedCapabilityDataSizes); + settings->ReceivedCapabilityDataSizes = NULL; + + free(settings->ReceivedCapabilityData); + settings->ReceivedCapabilityData = NULL; + free(settings->ReceivedCapabilities); + settings->ReceivedCapabilities = NULL; +} + +BOOL freerdp_capability_buffer_copy(rdpSettings* settings, const rdpSettings* src) +{ + WINPR_ASSERT(settings); + WINPR_ASSERT(src); + + if (!freerdp_capability_buffer_allocate(settings, src->ReceivedCapabilitiesSize)) + return FALSE; + + for (UINT32 x = 0; x < src->ReceivedCapabilitiesSize; x++) + { + WINPR_ASSERT(settings->ReceivedCapabilities); + settings->ReceivedCapabilities[x] = src->ReceivedCapabilities[x]; + + WINPR_ASSERT(settings->ReceivedCapabilityDataSizes); + settings->ReceivedCapabilityDataSizes[x] = src->ReceivedCapabilityDataSizes[x]; + + WINPR_ASSERT(settings->ReceivedCapabilityData); + if (src->ReceivedCapabilityDataSizes[x] > 0) + { + void* tmp = realloc(settings->ReceivedCapabilityData[x], + settings->ReceivedCapabilityDataSizes[x]); + if (!tmp) + return FALSE; + memcpy(tmp, src->ReceivedCapabilityData[x], src->ReceivedCapabilityDataSizes[x]); + settings->ReceivedCapabilityData[x] = tmp; + } + else + { + free(settings->ReceivedCapabilityData[x]); + settings->ReceivedCapabilityData[x] = NULL; + } + } + return TRUE; +} + +void freerdp_target_net_addresses_free(rdpSettings* settings) +{ + WINPR_ASSERT(settings); + + if (settings->TargetNetAddresses) + { + for (UINT32 index = 0; index < settings->TargetNetAddressCount; index++) + free(settings->TargetNetAddresses[index]); + } + + free(settings->TargetNetAddresses); + free(settings->TargetNetPorts); + settings->TargetNetAddressCount = 0; + settings->TargetNetAddresses = NULL; + settings->TargetNetPorts = NULL; +} + +void freerdp_server_license_issuers_free(rdpSettings* settings) +{ + WINPR_ASSERT(settings); + + if (settings->ServerLicenseProductIssuers) + { + for (UINT32 x = 0; x < settings->ServerLicenseProductIssuersCount; x++) + free(settings->ServerLicenseProductIssuers[x]); + } + free(settings->ServerLicenseProductIssuers); + settings->ServerLicenseProductIssuers = NULL; + settings->ServerLicenseProductIssuersCount = 0; +} + +BOOL freerdp_server_license_issuers_copy(rdpSettings* settings, char** issuers, UINT32 count) +{ + WINPR_ASSERT(settings); + WINPR_ASSERT(issuers || (count == 0)); + + if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ServerLicenseProductIssuers, NULL, + count)) + return FALSE; + + for (UINT32 x = 0; x < count; x++) + { + char* issuer = _strdup(issuers[x]); + if (!issuer) + return FALSE; + settings->ServerLicenseProductIssuers[x] = issuer; + } + + return TRUE; +} + +void freerdp_performance_flags_make(rdpSettings* settings) +{ + UINT32 PerformanceFlags = PERF_FLAG_NONE; + + if (freerdp_settings_get_bool(settings, FreeRDP_AllowFontSmoothing)) + PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING; + + if (freerdp_settings_get_bool(settings, FreeRDP_AllowDesktopComposition)) + PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION; + + if (freerdp_settings_get_bool(settings, FreeRDP_DisableWallpaper)) + PerformanceFlags |= PERF_DISABLE_WALLPAPER; + + if (freerdp_settings_get_bool(settings, FreeRDP_DisableFullWindowDrag)) + PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG; + + if (freerdp_settings_get_bool(settings, FreeRDP_DisableMenuAnims)) + PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS; + + if (freerdp_settings_get_bool(settings, FreeRDP_DisableThemes)) + PerformanceFlags |= PERF_DISABLE_THEMING; + freerdp_settings_set_uint32(settings, FreeRDP_PerformanceFlags, PerformanceFlags); +} + +void freerdp_performance_flags_split(rdpSettings* settings) +{ + freerdp_settings_set_bool(settings, FreeRDP_AllowFontSmoothing, + (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) & + PERF_ENABLE_FONT_SMOOTHING) + ? TRUE + : FALSE); + freerdp_settings_set_bool(settings, FreeRDP_AllowDesktopComposition, + (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) & + PERF_ENABLE_DESKTOP_COMPOSITION) + ? TRUE + : FALSE); + freerdp_settings_set_bool( + settings, FreeRDP_DisableWallpaper, + (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) & PERF_DISABLE_WALLPAPER) + ? TRUE + : FALSE); + freerdp_settings_set_bool(settings, FreeRDP_DisableFullWindowDrag, + (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) & + PERF_DISABLE_FULLWINDOWDRAG) + ? TRUE + : FALSE); + freerdp_settings_set_bool(settings, FreeRDP_DisableMenuAnims, + (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) & + PERF_DISABLE_MENUANIMATIONS) + ? TRUE + : FALSE); + freerdp_settings_set_bool( + settings, FreeRDP_DisableThemes, + (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) & PERF_DISABLE_THEMING) + ? TRUE + : FALSE); +} + +BOOL freerdp_set_gateway_usage_method(rdpSettings* settings, UINT32 GatewayUsageMethod) +{ + if (!freerdp_settings_set_uint32(settings, FreeRDP_GatewayUsageMethod, GatewayUsageMethod)) + return FALSE; + + if (GatewayUsageMethod == TSC_PROXY_MODE_NONE_DIRECT) + { + if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, FALSE) || + !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE)) + return FALSE; + } + else if (GatewayUsageMethod == TSC_PROXY_MODE_DIRECT) + { + if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, TRUE) || + !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE)) + return FALSE; + } + else if (GatewayUsageMethod == TSC_PROXY_MODE_DETECT) + { + if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, TRUE) || + !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, TRUE)) + return FALSE; + } + else if (GatewayUsageMethod == TSC_PROXY_MODE_DEFAULT) + { + /** + * This corresponds to "Automatically detect RD Gateway server settings", + * which means the client attempts to use gateway group policy settings + * http://technet.microsoft.com/en-us/library/cc770601.aspx + */ + if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, FALSE) || + !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE)) + return FALSE; + } + else if (GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT) + { + if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, FALSE) || + !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE)) + return FALSE; + } + + return TRUE; +} + +void freerdp_update_gateway_usage_method(rdpSettings* settings, UINT32 GatewayEnabled, + UINT32 GatewayBypassLocal) +{ + UINT32 GatewayUsageMethod = 0; + + if (!GatewayEnabled && !GatewayBypassLocal) + GatewayUsageMethod = TSC_PROXY_MODE_NONE_DIRECT; + else if (GatewayEnabled && !GatewayBypassLocal) + GatewayUsageMethod = TSC_PROXY_MODE_DIRECT; + else if (GatewayEnabled && GatewayBypassLocal) + GatewayUsageMethod = TSC_PROXY_MODE_DETECT; + + freerdp_set_gateway_usage_method(settings, GatewayUsageMethod); +} + +#if defined(WITH_FREERDP_DEPRECATED) +BOOL freerdp_get_param_bool(const rdpSettings* settings, int id) +{ + return freerdp_settings_get_bool(settings, (FreeRDP_Settings_Keys_Bool)id); +} + +int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) +{ + return freerdp_settings_set_bool(settings, (FreeRDP_Settings_Keys_Bool)id, param) ? 0 : -1; +} + +int freerdp_get_param_int(const rdpSettings* settings, int id) +{ + return freerdp_settings_get_int32(settings, (FreeRDP_Settings_Keys_Int32)id); +} + +int freerdp_set_param_int(rdpSettings* settings, int id, int param) +{ + return freerdp_settings_set_int32(settings, (FreeRDP_Settings_Keys_Int32)id, param) ? 0 : -1; +} + +UINT32 freerdp_get_param_uint32(const rdpSettings* settings, int id) +{ + return freerdp_settings_get_uint32(settings, (FreeRDP_Settings_Keys_UInt32)id); +} + +int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) +{ + return freerdp_settings_set_uint32(settings, (FreeRDP_Settings_Keys_UInt32)id, param) ? 0 : -1; +} + +UINT64 freerdp_get_param_uint64(const rdpSettings* settings, int id) +{ + return freerdp_settings_get_uint64(settings, (FreeRDP_Settings_Keys_UInt64)id); +} + +int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param) +{ + return freerdp_settings_set_uint64(settings, (FreeRDP_Settings_Keys_UInt64)id, param) ? 0 : -1; +} + +char* freerdp_get_param_string(const rdpSettings* settings, int id) +{ + return (char*)freerdp_settings_get_string(settings, (FreeRDP_Settings_Keys_String)id); +} + +int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) +{ + return freerdp_settings_set_string(settings, (FreeRDP_Settings_Keys_String)id, param) ? 0 : -1; +} +#endif + +static BOOL value_to_uint(const char* value, ULONGLONG* result, ULONGLONG min, ULONGLONG max) +{ + char* endptr = NULL; + unsigned long long rc = 0; + + if (!value || !result) + return FALSE; + + errno = 0; + rc = _strtoui64(value, &endptr, 0); + + if (errno != 0) + return FALSE; + + if (endptr == value) + return FALSE; + + if ((rc < min) || (rc > max)) + return FALSE; + + *result = rc; + return TRUE; +} + +static BOOL value_to_int(const char* value, LONGLONG* result, LONGLONG min, LONGLONG max) +{ + char* endptr = NULL; + long long rc = 0; + + if (!value || !result) + return FALSE; + + errno = 0; + rc = _strtoi64(value, &endptr, 0); + + if (errno != 0) + return FALSE; + + if (endptr == value) + return FALSE; + + if ((rc < min) || (rc > max)) + return FALSE; + + *result = rc; + return TRUE; +} + +static BOOL parsing_fail(const char* key, const char* type, const char* value) +{ + WLog_ERR(TAG, "Failed to parse key [%s] of type [%s]: value [%s]", key, type, value); + return FALSE; +} + +BOOL freerdp_settings_set_value_for_name(rdpSettings* settings, const char* name, const char* value) +{ + ULONGLONG uval = 0; + LONGLONG ival = 0; + SSIZE_T type = 0; + + if (!settings || !name) + return FALSE; + + const SSIZE_T i = freerdp_settings_get_key_for_name(name); + if (i < 0) + { + WLog_ERR(TAG, "Invalid settings key [%s]", name); + return FALSE; + } + + const SSIZE_T index = i; + + type = freerdp_settings_get_type_for_key(index); + switch (type) + { + + case RDP_SETTINGS_TYPE_BOOL: + { + BOOL val = _strnicmp(value, "TRUE", 5) == 0; + if (!val && _strnicmp(value, "FALSE", 6) != 0) + return parsing_fail(name, "BOOL", value); + return freerdp_settings_set_bool(settings, (FreeRDP_Settings_Keys_Bool)index, val); + } + case RDP_SETTINGS_TYPE_UINT16: + if (!value_to_uint(value, &uval, 0, UINT16_MAX)) + return parsing_fail(name, "UINT16", value); + if (!freerdp_settings_set_uint16(settings, (FreeRDP_Settings_Keys_UInt16)index, uval)) + return parsing_fail(name, "UINT16", value); + return TRUE; + + case RDP_SETTINGS_TYPE_INT16: + if (!value_to_int(value, &ival, INT16_MIN, INT16_MAX)) + return parsing_fail(name, "INT16", value); + if (!freerdp_settings_set_int16(settings, (FreeRDP_Settings_Keys_Int16)index, ival)) + return parsing_fail(name, "INT16", value); + return TRUE; + case RDP_SETTINGS_TYPE_UINT32: + if (!value_to_uint(value, &uval, 0, UINT32_MAX)) + return parsing_fail(name, "UINT32", value); + if (!freerdp_settings_set_uint32(settings, (FreeRDP_Settings_Keys_UInt32)index, uval)) + return parsing_fail(name, "UINT32", value); + return TRUE; + case RDP_SETTINGS_TYPE_INT32: + if (!value_to_int(value, &ival, INT32_MIN, INT32_MAX)) + return parsing_fail(name, "INT32", value); + if (!freerdp_settings_set_int32(settings, (FreeRDP_Settings_Keys_Int32)index, ival)) + return parsing_fail(name, "INT32", value); + return TRUE; + case RDP_SETTINGS_TYPE_UINT64: + if (!value_to_uint(value, &uval, 0, UINT64_MAX)) + return parsing_fail(name, "UINT64", value); + if (!freerdp_settings_set_uint64(settings, (FreeRDP_Settings_Keys_UInt64)index, uval)) + return parsing_fail(name, "UINT64", value); + return TRUE; + case RDP_SETTINGS_TYPE_INT64: + if (!value_to_int(value, &ival, INT64_MIN, INT64_MAX)) + return parsing_fail(name, "INT64", value); + if (!freerdp_settings_set_int64(settings, (FreeRDP_Settings_Keys_Int64)index, ival)) + return parsing_fail(name, "INT64", value); + return TRUE; + + case RDP_SETTINGS_TYPE_STRING: + return freerdp_settings_set_string(settings, (FreeRDP_Settings_Keys_String)index, + value); + case RDP_SETTINGS_TYPE_POINTER: + return parsing_fail(name, "POINTER", value); + default: + return FALSE; + } + return FALSE; +} + +BOOL freerdp_settings_set_pointer_len_(rdpSettings* settings, FreeRDP_Settings_Keys_Pointer id, + SSIZE_T lenId, const void* data, size_t len, size_t size) +{ + BOOL rc = FALSE; + void* copy = NULL; + void* old = freerdp_settings_get_pointer_writable(settings, id); + free(old); + if (!freerdp_settings_set_pointer(settings, id, NULL)) + return FALSE; + if (lenId >= 0) + { + if (!freerdp_settings_set_uint32(settings, (FreeRDP_Settings_Keys_UInt32)lenId, 0)) + return FALSE; + } + + if (len == 0) + return TRUE; + copy = calloc(len, size); + if (!copy) + return FALSE; + if (data) + memcpy(copy, data, len * size); + rc = freerdp_settings_set_pointer(settings, id, copy); + if (!rc) + { + free(copy); + return FALSE; + } + + // freerdp_settings_set_pointer takes ownership of copy + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) + if (lenId < 0) + return TRUE; + return freerdp_settings_set_uint32(settings, (FreeRDP_Settings_Keys_UInt32)lenId, len); +} + +const void* freerdp_settings_get_pointer(const rdpSettings* settings, + FreeRDP_Settings_Keys_Pointer id) +{ + union + { + const rdpSettings* pc; + rdpSettings* p; + } cnv; + cnv.pc = settings; + return freerdp_settings_get_pointer_writable(cnv.p, id); +} + +BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, FreeRDP_Settings_Keys_Pointer id, + const void* data, size_t len) +{ + union + { + const void* cv; + void* v; + } cnv; + + cnv.cv = data; + if (!settings) + return FALSE; + + switch (id) + { + case FreeRDP_RdpServerCertificate: + freerdp_certificate_free(settings->RdpServerCertificate); + + if (len > 1) + { + WLog_ERR(TAG, "FreeRDP_RdpServerCertificate::len must be 0 or 1"); + return FALSE; + } + settings->RdpServerCertificate = cnv.v; + if (!settings->RdpServerCertificate && (len > 0)) + { + settings->RdpServerCertificate = freerdp_certificate_new(); + if (!settings->RdpServerCertificate) + return FALSE; + } + return TRUE; + case FreeRDP_RdpServerRsaKey: + freerdp_key_free(settings->RdpServerRsaKey); + if (len > 1) + { + WLog_ERR(TAG, "FreeRDP_RdpServerRsaKey::len must be 0 or 1"); + return FALSE; + } + settings->RdpServerRsaKey = (rdpPrivateKey*)cnv.v; + if (!settings->RdpServerRsaKey && (len > 0)) + { + settings->RdpServerRsaKey = freerdp_key_new(); + if (!settings->RdpServerRsaKey) + return FALSE; + } + return TRUE; + case FreeRDP_RedirectionPassword: + return freerdp_settings_set_pointer_len_( + settings, id, FreeRDP_RedirectionPasswordLength, data, len, sizeof(char)); + case FreeRDP_RedirectionTsvUrl: + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_RedirectionTsvUrlLength, + data, len, sizeof(char)); + case FreeRDP_RedirectionTargetCertificate: + freerdp_certificate_free(settings->RedirectionTargetCertificate); + + if (len > 1) + { + WLog_ERR(TAG, "FreeRDP_RedirectionTargetCertificate::len must be 0 or 1"); + return FALSE; + } + settings->RedirectionTargetCertificate = cnv.v; + if (!settings->RedirectionTargetCertificate && (len > 0)) + { + settings->RedirectionTargetCertificate = freerdp_certificate_new(); + if (!settings->RedirectionTargetCertificate) + return FALSE; + } + return TRUE; + case FreeRDP_RedirectionGuid: + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_RedirectionGuidLength, + data, len, sizeof(BYTE)); + case FreeRDP_LoadBalanceInfo: + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_LoadBalanceInfoLength, + data, len, sizeof(char)); + case FreeRDP_ServerRandom: + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ServerRandomLength, data, + len, sizeof(char)); + case FreeRDP_ClientRandom: + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ClientRandomLength, data, + len, sizeof(char)); + case FreeRDP_ServerCertificate: + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ServerCertificateLength, + data, len, sizeof(char)); + case FreeRDP_TargetNetAddresses: + if ((data == NULL) && (len == 0)) + { + freerdp_target_net_addresses_free(settings); + return TRUE; + } + WLog_WARN( + TAG, + "[BUG] FreeRDP_TargetNetAddresses must not be resized from outside the library!"); + return FALSE; + case FreeRDP_ServerLicenseProductIssuers: + if (data == NULL) + freerdp_server_license_issuers_free(settings); + return freerdp_settings_set_pointer_len_(settings, FreeRDP_ServerLicenseProductIssuers, + FreeRDP_ServerLicenseProductIssuersCount, data, + len, sizeof(char*)); + case FreeRDP_TargetNetPorts: + if ((data == NULL) && (len == 0)) + { + freerdp_target_net_addresses_free(settings); + return TRUE; + } + WLog_WARN(TAG, + "[BUG] FreeRDP_TargetNetPorts must not be resized from outside the library!"); + return FALSE; + case FreeRDP_DeviceArray: + if (data == NULL) + freerdp_device_collection_free(settings); + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_DeviceArraySize, data, + len, sizeof(ADDIN_ARGV*)); + case FreeRDP_ChannelDefArray: + if ((len > 0) && (len < CHANNEL_MAX_COUNT)) + WLog_WARN(TAG, + "FreeRDP_ChannelDefArray::len expected to be >= %" PRIu32 + ", but have %" PRIu32, + CHANNEL_MAX_COUNT, len); + return freerdp_settings_set_pointer_len_(settings, FreeRDP_ChannelDefArray, + FreeRDP_ChannelDefArraySize, data, len, + sizeof(CHANNEL_DEF)); + case FreeRDP_MonitorDefArray: + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_MonitorDefArraySize, + data, len, sizeof(rdpMonitor)); + case FreeRDP_ClientAutoReconnectCookie: + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, + sizeof(ARC_CS_PRIVATE_PACKET)); + case FreeRDP_ServerAutoReconnectCookie: + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, + sizeof(ARC_SC_PRIVATE_PACKET)); + case FreeRDP_ClientTimeZone: + if (len > 1) + { + WLog_ERR(TAG, "FreeRDP_ClientTimeZone::len must be 0 or 1"); + return FALSE; + } + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, + sizeof(TIME_ZONE_INFORMATION)); + case FreeRDP_BitmapCacheV2CellInfo: + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_BitmapCacheV2NumCells, + data, len, sizeof(BITMAP_CACHE_V2_CELL_INFO)); + case FreeRDP_GlyphCache: + if ((len != 0) && (len != 10)) + { + WLog_ERR(TAG, "FreeRDP_GlyphCache::len must be 0 or 10"); + return FALSE; + } + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, + sizeof(GLYPH_CACHE_DEFINITION)); + case FreeRDP_FragCache: + if (len > 1) + { + WLog_ERR(TAG, "FreeRDP_FragCache::len must be 0 or 1"); + return FALSE; + } + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, + sizeof(GLYPH_CACHE_DEFINITION)); + case FreeRDP_StaticChannelArray: + if (data == NULL) + freerdp_static_channel_collection_free(settings); + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_StaticChannelArraySize, + data, len, sizeof(ADDIN_ARGV*)); + case FreeRDP_DynamicChannelArray: + if (data == NULL) + freerdp_dynamic_channel_collection_free(settings); + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_DynamicChannelArraySize, + data, len, sizeof(ADDIN_ARGV*)); + case FreeRDP_ReceivedCapabilityData: + if (data == NULL) + freerdp_capability_buffer_free(settings); + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ReceivedCapabilitiesSize, + data, len, sizeof(BYTE*)); + case FreeRDP_ReceivedCapabilities: + if (data == NULL) + freerdp_capability_buffer_free(settings); + return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ReceivedCapabilitiesSize, + data, len, sizeof(char)); + case FreeRDP_OrderSupport: + return freerdp_settings_set_pointer_len_(settings, id, -1, data, len, sizeof(char)); + + case FreeRDP_MonitorIds: + return freerdp_settings_set_pointer_len_( + settings, FreeRDP_MonitorIds, FreeRDP_NumMonitorIds, data, len, sizeof(UINT32)); + + default: + if ((data == NULL) && (len == 0)) + { + freerdp_settings_set_pointer(settings, id, NULL); + } + else + WLog_WARN(TAG, "Invalid id %" PRIuz, id); + return FALSE; + } +} + +void* freerdp_settings_get_pointer_array_writable(const rdpSettings* settings, + FreeRDP_Settings_Keys_Pointer id, size_t offset) +{ + size_t max = 0; + if (!settings) + return NULL; + switch (id) + { + case FreeRDP_ClientAutoReconnectCookie: + max = 1; + if ((offset >= max) || !settings->ClientAutoReconnectCookie) + goto fail; + return &settings->ClientAutoReconnectCookie[offset]; + case FreeRDP_ServerAutoReconnectCookie: + max = 1; + if ((offset >= max) || !settings->ServerAutoReconnectCookie) + goto fail; + return &settings->ServerAutoReconnectCookie[offset]; + case FreeRDP_ServerCertificate: + max = freerdp_settings_get_uint32(settings, FreeRDP_ServerCertificateLength); + if (offset >= max) + goto fail; + return &settings->ServerCertificate[offset]; + case FreeRDP_ServerRandom: + max = freerdp_settings_get_uint32(settings, FreeRDP_ServerRandomLength); + if (offset >= max) + goto fail; + return &settings->ServerRandom[offset]; + case FreeRDP_ClientRandom: + max = freerdp_settings_get_uint32(settings, FreeRDP_ClientRandomLength); + if (offset >= max) + goto fail; + return &settings->ClientRandom[offset]; + case FreeRDP_LoadBalanceInfo: + max = freerdp_settings_get_uint32(settings, FreeRDP_LoadBalanceInfoLength); + if (offset >= max) + goto fail; + return &settings->LoadBalanceInfo[offset]; + + case FreeRDP_RedirectionTsvUrl: + max = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionTsvUrlLength); + if (offset >= max) + goto fail; + return &settings->RedirectionTsvUrl[offset]; + + case FreeRDP_RedirectionPassword: + max = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionPasswordLength); + if (offset >= max) + goto fail; + return &settings->RedirectionPassword[offset]; + + case FreeRDP_OrderSupport: + max = 32; + if (offset >= max) + goto fail; + return &settings->OrderSupport[offset]; + case FreeRDP_MonitorIds: + max = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds); + if (offset >= max) + goto fail; + return &settings->MonitorIds[offset]; + case FreeRDP_MonitorDefArray: + max = freerdp_settings_get_uint32(settings, FreeRDP_MonitorDefArraySize); + if (offset >= max) + goto fail; + return &settings->MonitorDefArray[offset]; + case FreeRDP_ChannelDefArray: + max = freerdp_settings_get_uint32(settings, FreeRDP_ChannelDefArraySize); + if (offset >= max) + goto fail; + return &settings->ChannelDefArray[offset]; + case FreeRDP_DeviceArray: + max = freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize); + if (offset >= max) + goto fail; + return settings->DeviceArray[offset]; + case FreeRDP_StaticChannelArray: + max = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize); + if (offset >= max) + goto fail; + return settings->StaticChannelArray[offset]; + case FreeRDP_DynamicChannelArray: + max = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize); + if (offset >= max) + goto fail; + return settings->DynamicChannelArray[offset]; + case FreeRDP_FragCache: + max = 1; + if (offset >= max) + goto fail; + return &settings->FragCache[offset]; + case FreeRDP_GlyphCache: + max = 10; + if (offset >= max) + goto fail; + return &settings->GlyphCache[offset]; + case FreeRDP_BitmapCacheV2CellInfo: + max = freerdp_settings_get_uint32(settings, FreeRDP_BitmapCacheV2NumCells); + if (offset >= max) + goto fail; + return &settings->BitmapCacheV2CellInfo[offset]; + case FreeRDP_ReceivedCapabilities: + max = freerdp_settings_get_uint32(settings, FreeRDP_ReceivedCapabilitiesSize); + if (offset >= max) + goto fail; + return &settings->ReceivedCapabilities[offset]; + case FreeRDP_TargetNetAddresses: + max = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount); + if (offset >= max) + goto fail; + return settings->TargetNetAddresses[offset]; + case FreeRDP_TargetNetPorts: + max = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount); + if (offset >= max) + goto fail; + return &settings->TargetNetPorts[offset]; + case FreeRDP_ClientTimeZone: + max = 1; + if (offset >= max) + goto fail; + return settings->ClientTimeZone; + case FreeRDP_RdpServerCertificate: + max = 1; + if (offset >= max) + goto fail; + return settings->RdpServerCertificate; + case FreeRDP_RdpServerRsaKey: + max = 1; + if (offset >= max) + goto fail; + return settings->RdpServerRsaKey; + default: + WLog_WARN(TAG, "Invalid id %s [%" PRIuz "]", freerdp_settings_get_name_for_key(id), id); + return NULL; + } + +fail: + WLog_WARN(TAG, "Invalid offset for %s [%" PRIuz "]: size=%" PRIuz ", offset=%" PRIuz, + freerdp_settings_get_name_for_key(id), id, max, offset); + return NULL; +} + +BOOL freerdp_settings_set_pointer_array(rdpSettings* settings, FreeRDP_Settings_Keys_Pointer id, + size_t offset, const void* data) +{ + size_t maxOffset = 0; + if (!settings) + return FALSE; + switch (id) + { + case FreeRDP_ClientAutoReconnectCookie: + maxOffset = 1; + if ((offset >= maxOffset) || !data || !settings->ClientAutoReconnectCookie) + goto fail; + settings->ClientAutoReconnectCookie[offset] = *(const ARC_CS_PRIVATE_PACKET*)data; + return TRUE; + case FreeRDP_ServerAutoReconnectCookie: + maxOffset = 1; + if ((offset >= maxOffset) || !data || !settings->ServerAutoReconnectCookie) + goto fail; + settings->ServerAutoReconnectCookie[offset] = *(const ARC_SC_PRIVATE_PACKET*)data; + return TRUE; + case FreeRDP_ServerCertificate: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ServerCertificateLength); + if ((offset >= maxOffset) || !data) + goto fail; + settings->ServerCertificate[offset] = *(const BYTE*)data; + return TRUE; + case FreeRDP_DeviceArray: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize); + if (offset >= maxOffset) + goto fail; + freerdp_device_free(settings->DeviceArray[offset]); + settings->DeviceArray[offset] = freerdp_device_clone(data); + return TRUE; + case FreeRDP_TargetNetAddresses: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount); + if ((offset >= maxOffset) || !data) + goto fail; + free(settings->TargetNetAddresses[offset]); + settings->TargetNetAddresses[offset] = _strdup((const char*)data); + return settings->TargetNetAddresses[offset] != NULL; + case FreeRDP_TargetNetPorts: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount); + if ((offset >= maxOffset) || !data) + goto fail; + settings->TargetNetPorts[offset] = *((const UINT32*)data); + return TRUE; + case FreeRDP_StaticChannelArray: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize); + if ((offset >= maxOffset) || !data) + goto fail; + freerdp_addin_argv_free(settings->StaticChannelArray[offset]); + settings->StaticChannelArray[offset] = freerdp_addin_argv_clone(data); + return TRUE; + case FreeRDP_DynamicChannelArray: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize); + if ((offset >= maxOffset) || !data) + goto fail; + freerdp_addin_argv_free(settings->DynamicChannelArray[offset]); + settings->DynamicChannelArray[offset] = freerdp_addin_argv_clone(data); + return TRUE; + case FreeRDP_BitmapCacheV2CellInfo: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_BitmapCacheV2NumCells); + if ((offset >= maxOffset) || !data) + goto fail; + { + const BITMAP_CACHE_V2_CELL_INFO* cdata = (const BITMAP_CACHE_V2_CELL_INFO*)data; + settings->BitmapCacheV2CellInfo[offset] = *cdata; + } + return TRUE; + case FreeRDP_ServerRandom: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ServerRandomLength); + if ((offset >= maxOffset) || !data) + goto fail; + settings->ServerRandom[offset] = *(const BYTE*)data; + return TRUE; + case FreeRDP_ClientRandom: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ClientRandomLength); + if ((offset >= maxOffset) || !data) + goto fail; + settings->ClientRandom[offset] = *(const BYTE*)data; + return TRUE; + case FreeRDP_LoadBalanceInfo: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_LoadBalanceInfoLength); + if ((offset >= maxOffset) || !data) + goto fail; + settings->LoadBalanceInfo[offset] = *(const BYTE*)data; + return TRUE; + case FreeRDP_RedirectionTsvUrl: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionTsvUrlLength); + if ((offset >= maxOffset) || !data) + goto fail; + settings->RedirectionTsvUrl[offset] = *(const BYTE*)data; + return TRUE; + case FreeRDP_RedirectionPassword: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionPasswordLength); + if ((offset >= maxOffset) || !data) + goto fail; + settings->RedirectionPassword[offset] = *(const BYTE*)data; + return TRUE; + case FreeRDP_OrderSupport: + maxOffset = 32; + if (!settings->OrderSupport) + goto fail; + if ((offset >= maxOffset) || !data) + goto fail; + settings->OrderSupport[offset] = *(const BOOL*)data; + return TRUE; + case FreeRDP_GlyphCache: + maxOffset = 10; + if (!settings->GlyphCache) + goto fail; + if ((offset >= maxOffset) || !data) + goto fail; + settings->GlyphCache[offset] = *(const GLYPH_CACHE_DEFINITION*)data; + return TRUE; + case FreeRDP_FragCache: + maxOffset = 1; + if (!settings->FragCache) + goto fail; + if ((offset >= maxOffset) || !data) + goto fail; + settings->FragCache[offset] = *(const GLYPH_CACHE_DEFINITION*)data; + return TRUE; + case FreeRDP_MonitorIds: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds); + if ((offset >= maxOffset) || !data) + goto fail; + settings->MonitorIds[offset] = *(const UINT32*)data; + return TRUE; + case FreeRDP_ChannelDefArray: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ChannelDefArraySize); + if ((offset >= maxOffset) || !data) + goto fail; + settings->ChannelDefArray[offset] = *(const CHANNEL_DEF*)data; + return TRUE; + case FreeRDP_MonitorDefArray: + maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_MonitorDefArraySize); + if ((offset >= maxOffset) || !data) + goto fail; + settings->MonitorDefArray[offset] = *(const rdpMonitor*)data; + return TRUE; + + case FreeRDP_ClientTimeZone: + maxOffset = 1; + if ((offset >= maxOffset) || !data || !settings->ClientTimeZone) + goto fail; + settings->ClientTimeZone[0] = *(const TIME_ZONE_INFORMATION*)data; + return TRUE; + + default: + WLog_WARN(TAG, "Invalid id %s [%" PRIuz "]", freerdp_settings_get_name_for_key(id), id); + return FALSE; + } + +fail: + WLog_WARN(TAG, "[%s] Invalid offset=%" PRIuz " [%" PRIuz "] or NULL data=%p", + freerdp_settings_get_name_for_key(id), offset, maxOffset, data); + return FALSE; +} + +const void* freerdp_settings_get_pointer_array(const rdpSettings* settings, + FreeRDP_Settings_Keys_Pointer id, size_t offset) +{ + return freerdp_settings_get_pointer_array_writable(settings, id, offset); +} + +UINT32 freerdp_settings_get_codecs_flags(const rdpSettings* settings) +{ + UINT32 flags = FREERDP_CODEC_ALL; + if (settings->RemoteFxCodec == FALSE) + { + flags &= ~FREERDP_CODEC_REMOTEFX; + } + if (settings->NSCodec == FALSE) + { + flags &= ~FREERDP_CODEC_NSCODEC; + } + /*TODO: check other codecs flags */ + return flags; +} + +const char* freerdp_settings_get_server_name(const rdpSettings* settings) +{ + WINPR_ASSERT(settings); + const char* hostname = settings->ServerHostname; + + if (settings->UserSpecifiedServerName) + hostname = settings->UserSpecifiedServerName; + + return hostname; +} + +#if defined(WITH_FREERDP_DEPRECATED) +ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel) +{ + return freerdp_addin_argv_clone(channel); +} + +ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel) +{ + return freerdp_addin_argv_clone(channel); +} +#endif + +BOOL freerdp_target_net_addresses_copy(rdpSettings* settings, char** addresses, UINT32 count) +{ + WINPR_ASSERT(settings); + WINPR_ASSERT(addresses); + + if (!freerdp_target_net_adresses_reset(settings, count)) + return FALSE; + + for (UINT32 i = 0; i < settings->TargetNetAddressCount; i++) + { + if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetAddresses, i, + addresses[i])) + { + freerdp_target_net_addresses_free(settings); + return FALSE; + } + } + + return TRUE; +} + +BOOL freerdp_device_equal(const RDPDR_DEVICE* what, const RDPDR_DEVICE* expect) +{ + if (!what && !expect) + return TRUE; + if (!what || !expect) + return FALSE; + + if (what->Id != expect->Id) + return FALSE; + if (what->Type != expect->Type) + return FALSE; + if (what->Name && expect->Name) + { + if (strcmp(what->Name, expect->Name) != 0) + return FALSE; + } + else + { + if (what->Name != expect->Name) + return FALSE; + } + + switch (what->Type) + { + case RDPDR_DTYP_PRINT: + { + const RDPDR_PRINTER* a = (const RDPDR_PRINTER*)what; + const RDPDR_PRINTER* b = (const RDPDR_PRINTER*)expect; + if (a->DriverName && b->DriverName) + return strcmp(a->DriverName, b->DriverName) == 0; + return a->DriverName == b->DriverName; + } + + case RDPDR_DTYP_SERIAL: + { + const RDPDR_SERIAL* a = (const RDPDR_SERIAL*)what; + const RDPDR_SERIAL* b = (const RDPDR_SERIAL*)expect; + + if (a->Path && b->Path) + { + if (strcmp(a->Path, b->Path) != 0) + return FALSE; + } + else if (a->Path != b->Path) + return FALSE; + + if (a->Driver && b->Driver) + { + if (strcmp(a->Driver, b->Driver) != 0) + return FALSE; + } + else if (a->Driver != b->Driver) + return FALSE; + if (a->Permissive && b->Permissive) + return strcmp(a->Permissive, b->Permissive) == 0; + return a->Permissive == b->Permissive; + } + + case RDPDR_DTYP_PARALLEL: + { + const RDPDR_PARALLEL* a = (const RDPDR_PARALLEL*)what; + const RDPDR_PARALLEL* b = (const RDPDR_PARALLEL*)expect; + if (a->Path && b->Path) + return strcmp(a->Path, b->Path) == 0; + return a->Path == b->Path; + } + + case RDPDR_DTYP_SMARTCARD: + break; + case RDPDR_DTYP_FILESYSTEM: + { + const RDPDR_DRIVE* a = (const RDPDR_DRIVE*)what; + const RDPDR_DRIVE* b = (const RDPDR_DRIVE*)expect; + if (a->automount != b->automount) + return FALSE; + if (a->Path && b->Path) + return strcmp(a->Path, b->Path) == 0; + return a->Path == b->Path; + } + + default: + return FALSE; + } + + return TRUE; +} + +char* freerdp_rail_support_flags_to_string(UINT32 flags, char* buffer, size_t length) +{ + const UINT32 mask = + RAIL_LEVEL_SUPPORTED | RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED | + RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED | RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED | + RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED | RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED | + RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED | RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED; + + if (flags & RAIL_LEVEL_SUPPORTED) + winpr_str_append("RAIL_LEVEL_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED) + winpr_str_append("RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED) + winpr_str_append("RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED) + winpr_str_append("RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED) + winpr_str_append("RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED) + winpr_str_append("RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED) + winpr_str_append("RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED) + winpr_str_append("RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED) + winpr_str_append("RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED", buffer, length, "|"); + if ((flags & ~mask) != 0) + { + char tbuffer[64] = { 0 }; + _snprintf(tbuffer, sizeof(tbuffer), "RAIL_FLAG_UNKNOWN 0x%08" PRIx32, flags & mask); + winpr_str_append(tbuffer, buffer, length, "|"); + } + return buffer; +} + +BOOL freerdp_settings_update_from_caps(rdpSettings* settings, const BYTE* capsFlags, + const BYTE** capsData, const UINT32* capsSizes, + UINT32 capsCount, BOOL serverReceivedCaps) +{ + WINPR_ASSERT(settings); + WINPR_ASSERT(capsFlags || (capsCount == 0)); + WINPR_ASSERT(capsData || (capsCount == 0)); + WINPR_ASSERT(capsSizes || (capsCount == 0)); + WINPR_ASSERT(capsCount <= UINT16_MAX); + + for (UINT32 x = 0; x < capsCount; x++) + { + if (capsFlags[x]) + { + wStream buffer; + wStream* sub = Stream_StaticConstInit(&buffer, capsData[x], capsSizes[x]); + + if (!rdp_read_capability_set(sub, (UINT16)x, settings, serverReceivedCaps)) + return FALSE; + } + } + + return TRUE; +} + +const char* freerdp_rdp_version_string(UINT32 version) +{ + switch (version) + { + case RDP_VERSION_4: + return "RDP_VERSION_4"; + case RDP_VERSION_5_PLUS: + return "RDP_VERSION_5_PLUS"; + case RDP_VERSION_10_0: + return "RDP_VERSION_10_0"; + case RDP_VERSION_10_1: + return "RDP_VERSION_10_1"; + case RDP_VERSION_10_2: + return "RDP_VERSION_10_2"; + case RDP_VERSION_10_3: + return "RDP_VERSION_10_3"; + case RDP_VERSION_10_4: + return "RDP_VERSION_10_4"; + case RDP_VERSION_10_5: + return "RDP_VERSION_10_5"; + case RDP_VERSION_10_6: + return "RDP_VERSION_10_6"; + case RDP_VERSION_10_7: + return "RDP_VERSION_10_7"; + case RDP_VERSION_10_8: + return "RDP_VERSION_10_8"; + case RDP_VERSION_10_9: + return "RDP_VERSION_10_9"; + case RDP_VERSION_10_10: + return "RDP_VERSION_10_10"; + case RDP_VERSION_10_11: + return "RDP_VERSION_10_11"; + case RDP_VERSION_10_12: + return "RDP_VERSION_10_12"; + default: + return "RDP_VERSION_UNKNOWN"; + } +} + +BOOL freerdp_settings_set_string_from_utf16(rdpSettings* settings, FreeRDP_Settings_Keys_String id, + const WCHAR* param) +{ + WINPR_ASSERT(settings); + + if (!param) + return freerdp_settings_set_string_copy_(settings, id, NULL, 0, TRUE); + + size_t len = 0; + + char* str = ConvertWCharToUtf8Alloc(param, &len); + if (!str && (len != 0)) + return FALSE; + + return freerdp_settings_set_string_(settings, id, str, len); +} + +BOOL freerdp_settings_set_string_from_utf16N(rdpSettings* settings, FreeRDP_Settings_Keys_String id, + const WCHAR* param, size_t length) +{ + size_t len = 0; + + WINPR_ASSERT(settings); + + if (!param) + return freerdp_settings_set_string_copy_(settings, id, NULL, length, TRUE); + + char* str = ConvertWCharNToUtf8Alloc(param, length, &len); + if (!str && (length != 0)) + { + /* If the input string is an empty string, but length > 0 + * consider the conversion a success */ + const size_t wlen = _wcsnlen(param, length); + if (wlen != 0) + return FALSE; + } + + return freerdp_settings_set_string_(settings, id, str, len); +} + +WCHAR* freerdp_settings_get_string_as_utf16(const rdpSettings* settings, + FreeRDP_Settings_Keys_String id, size_t* pCharLen) +{ + const char* str = freerdp_settings_get_string(settings, id); + if (pCharLen) + *pCharLen = 0; + if (!str) + return NULL; + return ConvertUtf8ToWCharAlloc(str, pCharLen); +} + +const char* freerdp_rdpdr_dtyp_string(UINT32 type) +{ + switch (type) + { + case RDPDR_DTYP_FILESYSTEM: + return "RDPDR_DTYP_FILESYSTEM"; + case RDPDR_DTYP_PARALLEL: + return "RDPDR_DTYP_PARALLEL"; + case RDPDR_DTYP_PRINT: + return "RDPDR_DTYP_PRINT"; + case RDPDR_DTYP_SERIAL: + return "RDPDR_DTYP_SERIAL"; + case RDPDR_DTYP_SMARTCARD: + return "RDPDR_DTYP_SMARTCARD"; + default: + return "RDPDR_DTYP_UNKNOWN"; + } +} + +const char* freerdp_encryption_level_string(UINT32 EncryptionLevel) +{ + switch (EncryptionLevel) + { + case ENCRYPTION_LEVEL_NONE: + return "ENCRYPTION_LEVEL_NONE"; + case ENCRYPTION_LEVEL_LOW: + return "ENCRYPTION_LEVEL_LOW"; + case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: + return "ENCRYPTION_LEVEL_CLIENT_COMPATIBLE"; + case ENCRYPTION_LEVEL_HIGH: + return "ENCRYPTION_LEVEL_HIGH"; + case ENCRYPTION_LEVEL_FIPS: + return "ENCRYPTION_LEVEL_FIPS"; + default: + return "ENCRYPTION_LEVEL_UNKNOWN"; + } +} + +const char* freerdp_encryption_methods_string(UINT32 EncryptionMethods, char* buffer, size_t size) +{ + if (EncryptionMethods == ENCRYPTION_METHOD_NONE) + { + winpr_str_append("ENCRYPTION_METHOD_NONE", buffer, size, "|"); + return buffer; + } + + if (EncryptionMethods & ENCRYPTION_METHOD_40BIT) + { + winpr_str_append("ENCRYPTION_METHOD_40BIT", buffer, size, "|"); + } + if (EncryptionMethods & ENCRYPTION_METHOD_128BIT) + { + winpr_str_append("ENCRYPTION_METHOD_128BIT", buffer, size, "|"); + } + if (EncryptionMethods & ENCRYPTION_METHOD_56BIT) + { + winpr_str_append("ENCRYPTION_METHOD_56BIT", buffer, size, "|"); + } + if (EncryptionMethods & ENCRYPTION_METHOD_FIPS) + { + winpr_str_append("ENCRYPTION_METHOD_FIPS", buffer, size, "|"); + } + + return buffer; +} + +const char* freerdp_supported_color_depths_string(UINT16 mask, char* buffer, size_t size) +{ + const UINT32 invalid = mask & ~(RNS_UD_32BPP_SUPPORT | RNS_UD_24BPP_SUPPORT | + RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT); + + if (mask & RNS_UD_32BPP_SUPPORT) + winpr_str_append("RNS_UD_32BPP_SUPPORT", buffer, size, "|"); + if (mask & RNS_UD_24BPP_SUPPORT) + winpr_str_append("RNS_UD_24BPP_SUPPORT", buffer, size, "|"); + if (mask & RNS_UD_16BPP_SUPPORT) + winpr_str_append("RNS_UD_16BPP_SUPPORT", buffer, size, "|"); + if (mask & RNS_UD_15BPP_SUPPORT) + winpr_str_append("RNS_UD_15BPP_SUPPORT", buffer, size, "|"); + + if (invalid != 0) + { + char str[32] = { 0 }; + _snprintf(str, sizeof(str), "RNS_UD_INVALID[0x%04" PRIx32 "]", invalid); + winpr_str_append(str, buffer, size, "|"); + } + char hex[32] = { 0 }; + _snprintf(hex, sizeof(hex), "[0x%04" PRIx16 "]", mask); + return buffer; +} + +BOOL freerdp_settings_append_string(rdpSettings* settings, FreeRDP_Settings_Keys_String id, + const char* separator, const char* param) +{ + const char* old = freerdp_settings_get_string(settings, id); + + size_t len = 0; + char* str = NULL; + + if (!old) + winpr_asprintf(&str, &len, "%s", param); + else if (!separator) + winpr_asprintf(&str, &len, "%s%s", old, param); + else + winpr_asprintf(&str, &len, "%s%s%s", old, separator, param); + + const BOOL rc = freerdp_settings_set_string_len(settings, id, str, len); + free(str); + return rc; +} + +BOOL freerdp_settings_are_valid(const rdpSettings* settings) +{ + return settings != NULL; +} diff --git a/libfreerdp/common/settings_getters.c b/libfreerdp/common/settings_getters.c new file mode 100644 index 0000000..ecec044 --- /dev/null +++ b/libfreerdp/common/settings_getters.c @@ -0,0 +1,4153 @@ +/* Generated by */ + +#include "../core/settings.h" + +#include <winpr/assert.h> +#include <freerdp/settings.h> +#include <freerdp/log.h> + +#define TAG FREERDP_TAG("common.settings") + +static void free_string(char** current, BOOL cleanup) +{ + if (cleanup) + { + if (*current) + memset(*current, 0, strlen(*current)); + free(*current); + (*current) = NULL; + } +} + +static BOOL alloc_empty_string(char** current, const char* next, size_t next_len) +{ + if (!next && (next_len > 0)) + { + *current = calloc(next_len, 1); + return (*current != NULL); + } + return FALSE; +} + +static BOOL update_string_copy_(char** current, const char* next, size_t next_len, BOOL cleanup) +{ + free_string(current, cleanup); + + if (alloc_empty_string(current, next, next_len)) + return TRUE; + + *current = (next ? strndup(next, next_len) : NULL); + return !next || (*current != NULL); +} + +static BOOL update_string_(char** current, char* next, size_t next_len) +{ + free_string(current, TRUE); + + if (alloc_empty_string(current, next, next_len)) + return TRUE; + + *current = next; + return !next || (*current != NULL); +} + +BOOL freerdp_settings_get_bool(const rdpSettings* settings, FreeRDP_Settings_Keys_Bool id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + case FreeRDP_AadSecurity: + return settings->AadSecurity; + + case FreeRDP_AllowCacheWaitingList: + return settings->AllowCacheWaitingList; + + case FreeRDP_AllowDesktopComposition: + return settings->AllowDesktopComposition; + + case FreeRDP_AllowFontSmoothing: + return settings->AllowFontSmoothing; + + case FreeRDP_AllowUnanouncedOrdersFromServer: + return settings->AllowUnanouncedOrdersFromServer; + + case FreeRDP_AltSecFrameMarkerSupport: + return settings->AltSecFrameMarkerSupport; + + case FreeRDP_AsyncChannels: + return settings->AsyncChannels; + + case FreeRDP_AsyncUpdate: + return settings->AsyncUpdate; + + case FreeRDP_AudioCapture: + return settings->AudioCapture; + + case FreeRDP_AudioPlayback: + return settings->AudioPlayback; + + case FreeRDP_Authentication: + return settings->Authentication; + + case FreeRDP_AuthenticationOnly: + return settings->AuthenticationOnly; + + case FreeRDP_AutoAcceptCertificate: + return settings->AutoAcceptCertificate; + + case FreeRDP_AutoDenyCertificate: + return settings->AutoDenyCertificate; + + case FreeRDP_AutoLogonEnabled: + return settings->AutoLogonEnabled; + + case FreeRDP_AutoReconnectionEnabled: + return settings->AutoReconnectionEnabled; + + case FreeRDP_BitmapCacheEnabled: + return settings->BitmapCacheEnabled; + + case FreeRDP_BitmapCachePersistEnabled: + return settings->BitmapCachePersistEnabled; + + case FreeRDP_BitmapCacheV3Enabled: + return settings->BitmapCacheV3Enabled; + + case FreeRDP_BitmapCompressionDisabled: + return settings->BitmapCompressionDisabled; + + case FreeRDP_CertificateCallbackPreferPEM: + return settings->CertificateCallbackPreferPEM; + + case FreeRDP_CompressionEnabled: + return settings->CompressionEnabled; + + case FreeRDP_ConnectChildSession: + return settings->ConnectChildSession; + + case FreeRDP_ConsoleSession: + return settings->ConsoleSession; + + case FreeRDP_CredentialsFromStdin: + return settings->CredentialsFromStdin; + + case FreeRDP_DeactivateClientDecoding: + return settings->DeactivateClientDecoding; + + case FreeRDP_Decorations: + return settings->Decorations; + + case FreeRDP_DesktopResize: + return settings->DesktopResize; + + case FreeRDP_DeviceRedirection: + return settings->DeviceRedirection; + + case FreeRDP_DisableCredentialsDelegation: + return settings->DisableCredentialsDelegation; + + case FreeRDP_DisableCtrlAltDel: + return settings->DisableCtrlAltDel; + + case FreeRDP_DisableCursorBlinking: + return settings->DisableCursorBlinking; + + case FreeRDP_DisableCursorShadow: + return settings->DisableCursorShadow; + + case FreeRDP_DisableFullWindowDrag: + return settings->DisableFullWindowDrag; + + case FreeRDP_DisableMenuAnims: + return settings->DisableMenuAnims; + + case FreeRDP_DisableRemoteAppCapsCheck: + return settings->DisableRemoteAppCapsCheck; + + case FreeRDP_DisableThemes: + return settings->DisableThemes; + + case FreeRDP_DisableWallpaper: + return settings->DisableWallpaper; + + case FreeRDP_DrawAllowColorSubsampling: + return settings->DrawAllowColorSubsampling; + + case FreeRDP_DrawAllowDynamicColorFidelity: + return settings->DrawAllowDynamicColorFidelity; + + case FreeRDP_DrawAllowSkipAlpha: + return settings->DrawAllowSkipAlpha; + + case FreeRDP_DrawGdiPlusCacheEnabled: + return settings->DrawGdiPlusCacheEnabled; + + case FreeRDP_DrawGdiPlusEnabled: + return settings->DrawGdiPlusEnabled; + + case FreeRDP_DrawNineGridEnabled: + return settings->DrawNineGridEnabled; + + case FreeRDP_DumpRemoteFx: + return settings->DumpRemoteFx; + + case FreeRDP_DynamicDaylightTimeDisabled: + return settings->DynamicDaylightTimeDisabled; + + case FreeRDP_DynamicResolutionUpdate: + return settings->DynamicResolutionUpdate; + + case FreeRDP_EmbeddedWindow: + return settings->EmbeddedWindow; + + case FreeRDP_EnableWindowsKey: + return settings->EnableWindowsKey; + + case FreeRDP_EncomspVirtualChannel: + return settings->EncomspVirtualChannel; + + case FreeRDP_ExtSecurity: + return settings->ExtSecurity; + + case FreeRDP_ExternalCertificateManagement: + return settings->ExternalCertificateManagement; + + case FreeRDP_FIPSMode: + return settings->FIPSMode; + + case FreeRDP_FastPathInput: + return settings->FastPathInput; + + case FreeRDP_FastPathOutput: + return settings->FastPathOutput; + + case FreeRDP_ForceEncryptedCsPdu: + return settings->ForceEncryptedCsPdu; + + case FreeRDP_ForceMultimon: + return settings->ForceMultimon; + + case FreeRDP_FrameMarkerCommandEnabled: + return settings->FrameMarkerCommandEnabled; + + case FreeRDP_Fullscreen: + return settings->Fullscreen; + + case FreeRDP_GatewayArmTransport: + return settings->GatewayArmTransport; + + case FreeRDP_GatewayBypassLocal: + return settings->GatewayBypassLocal; + + case FreeRDP_GatewayEnabled: + return settings->GatewayEnabled; + + case FreeRDP_GatewayHttpExtAuthSspiNtlm: + return settings->GatewayHttpExtAuthSspiNtlm; + + case FreeRDP_GatewayHttpTransport: + return settings->GatewayHttpTransport; + + case FreeRDP_GatewayHttpUseWebsockets: + return settings->GatewayHttpUseWebsockets; + + case FreeRDP_GatewayRpcTransport: + return settings->GatewayRpcTransport; + + case FreeRDP_GatewayUdpTransport: + return settings->GatewayUdpTransport; + + case FreeRDP_GatewayUseSameCredentials: + return settings->GatewayUseSameCredentials; + + case FreeRDP_GfxAVC444: + return settings->GfxAVC444; + + case FreeRDP_GfxAVC444v2: + return settings->GfxAVC444v2; + + case FreeRDP_GfxH264: + return settings->GfxH264; + + case FreeRDP_GfxPlanar: + return settings->GfxPlanar; + + case FreeRDP_GfxProgressive: + return settings->GfxProgressive; + + case FreeRDP_GfxProgressiveV2: + return settings->GfxProgressiveV2; + + case FreeRDP_GfxSendQoeAck: + return settings->GfxSendQoeAck; + + case FreeRDP_GfxSmallCache: + return settings->GfxSmallCache; + + case FreeRDP_GfxThinClient: + return settings->GfxThinClient; + + case FreeRDP_GrabKeyboard: + return settings->GrabKeyboard; + + case FreeRDP_GrabMouse: + return settings->GrabMouse; + + case FreeRDP_HasExtendedMouseEvent: + return settings->HasExtendedMouseEvent; + + case FreeRDP_HasHorizontalWheel: + return settings->HasHorizontalWheel; + + case FreeRDP_HasMonitorAttributes: + return settings->HasMonitorAttributes; + + case FreeRDP_HasQoeEvent: + return settings->HasQoeEvent; + + case FreeRDP_HasRelativeMouseEvent: + return settings->HasRelativeMouseEvent; + + case FreeRDP_HiDefRemoteApp: + return settings->HiDefRemoteApp; + + case FreeRDP_IPv6Enabled: + return settings->IPv6Enabled; + + case FreeRDP_IgnoreCertificate: + return settings->IgnoreCertificate; + + case FreeRDP_IgnoreInvalidDevices: + return settings->IgnoreInvalidDevices; + + case FreeRDP_JpegCodec: + return settings->JpegCodec; + + case FreeRDP_KerberosRdgIsProxy: + return settings->KerberosRdgIsProxy; + + case FreeRDP_ListMonitors: + return settings->ListMonitors; + + case FreeRDP_LocalConnection: + return settings->LocalConnection; + + case FreeRDP_LogonErrors: + return settings->LogonErrors; + + case FreeRDP_LogonNotify: + return settings->LogonNotify; + + case FreeRDP_LongCredentialsSupported: + return settings->LongCredentialsSupported; + + case FreeRDP_LyncRdpMode: + return settings->LyncRdpMode; + + case FreeRDP_MaximizeShell: + return settings->MaximizeShell; + + case FreeRDP_MouseAttached: + return settings->MouseAttached; + + case FreeRDP_MouseHasWheel: + return settings->MouseHasWheel; + + case FreeRDP_MouseMotion: + return settings->MouseMotion; + + case FreeRDP_MouseUseRelativeMove: + return settings->MouseUseRelativeMove; + + case FreeRDP_MstscCookieMode: + return settings->MstscCookieMode; + + case FreeRDP_MultiTouchGestures: + return settings->MultiTouchGestures; + + case FreeRDP_MultiTouchInput: + return settings->MultiTouchInput; + + case FreeRDP_NSCodec: + return settings->NSCodec; + + case FreeRDP_NSCodecAllowDynamicColorFidelity: + return settings->NSCodecAllowDynamicColorFidelity; + + case FreeRDP_NSCodecAllowSubsampling: + return settings->NSCodecAllowSubsampling; + + case FreeRDP_NegotiateSecurityLayer: + return settings->NegotiateSecurityLayer; + + case FreeRDP_NetworkAutoDetect: + return settings->NetworkAutoDetect; + + case FreeRDP_NlaSecurity: + return settings->NlaSecurity; + + case FreeRDP_NoBitmapCompressionHeader: + return settings->NoBitmapCompressionHeader; + + case FreeRDP_OldLicenseBehaviour: + return settings->OldLicenseBehaviour; + + case FreeRDP_PasswordIsSmartcardPin: + return settings->PasswordIsSmartcardPin; + + case FreeRDP_PercentScreenUseHeight: + return settings->PercentScreenUseHeight; + + case FreeRDP_PercentScreenUseWidth: + return settings->PercentScreenUseWidth; + + case FreeRDP_PlayRemoteFx: + return settings->PlayRemoteFx; + + case FreeRDP_PreferIPv6OverIPv4: + return settings->PreferIPv6OverIPv4; + + case FreeRDP_PrintReconnectCookie: + return settings->PrintReconnectCookie; + + case FreeRDP_PromptForCredentials: + return settings->PromptForCredentials; + + case FreeRDP_RdpSecurity: + return settings->RdpSecurity; + + case FreeRDP_RdstlsSecurity: + return settings->RdstlsSecurity; + + case FreeRDP_RedirectClipboard: + return settings->RedirectClipboard; + + case FreeRDP_RedirectDrives: + return settings->RedirectDrives; + + case FreeRDP_RedirectHomeDrive: + return settings->RedirectHomeDrive; + + case FreeRDP_RedirectParallelPorts: + return settings->RedirectParallelPorts; + + case FreeRDP_RedirectPrinters: + return settings->RedirectPrinters; + + case FreeRDP_RedirectSerialPorts: + return settings->RedirectSerialPorts; + + case FreeRDP_RedirectSmartCards: + return settings->RedirectSmartCards; + + case FreeRDP_RedirectWebAuthN: + return settings->RedirectWebAuthN; + + case FreeRDP_RefreshRect: + return settings->RefreshRect; + + case FreeRDP_RemdeskVirtualChannel: + return settings->RemdeskVirtualChannel; + + case FreeRDP_RemoteAppLanguageBarSupported: + return settings->RemoteAppLanguageBarSupported; + + case FreeRDP_RemoteApplicationMode: + return settings->RemoteApplicationMode; + + case FreeRDP_RemoteAssistanceMode: + return settings->RemoteAssistanceMode; + + case FreeRDP_RemoteAssistanceRequestControl: + return settings->RemoteAssistanceRequestControl; + + case FreeRDP_RemoteConsoleAudio: + return settings->RemoteConsoleAudio; + + case FreeRDP_RemoteCredentialGuard: + return settings->RemoteCredentialGuard; + + case FreeRDP_RemoteFxCodec: + return settings->RemoteFxCodec; + + case FreeRDP_RemoteFxImageCodec: + return settings->RemoteFxImageCodec; + + case FreeRDP_RemoteFxOnly: + return settings->RemoteFxOnly; + + case FreeRDP_RestrictedAdminModeRequired: + return settings->RestrictedAdminModeRequired; + + case FreeRDP_SaltedChecksum: + return settings->SaltedChecksum; + + case FreeRDP_SendPreconnectionPdu: + return settings->SendPreconnectionPdu; + + case FreeRDP_ServerLicenseRequired: + return settings->ServerLicenseRequired; + + case FreeRDP_ServerMode: + return settings->ServerMode; + + case FreeRDP_SmartSizing: + return settings->SmartSizing; + + case FreeRDP_SmartcardEmulation: + return settings->SmartcardEmulation; + + case FreeRDP_SmartcardLogon: + return settings->SmartcardLogon; + + case FreeRDP_SoftwareGdi: + return settings->SoftwareGdi; + + case FreeRDP_SoundBeepsEnabled: + return settings->SoundBeepsEnabled; + + case FreeRDP_SpanMonitors: + return settings->SpanMonitors; + + case FreeRDP_SupportAsymetricKeys: + return settings->SupportAsymetricKeys; + + case FreeRDP_SupportDisplayControl: + return settings->SupportDisplayControl; + + case FreeRDP_SupportDynamicChannels: + return settings->SupportDynamicChannels; + + case FreeRDP_SupportDynamicTimeZone: + return settings->SupportDynamicTimeZone; + + case FreeRDP_SupportEchoChannel: + return settings->SupportEchoChannel; + + case FreeRDP_SupportEdgeActionV1: + return settings->SupportEdgeActionV1; + + case FreeRDP_SupportEdgeActionV2: + return settings->SupportEdgeActionV2; + + case FreeRDP_SupportErrorInfoPdu: + return settings->SupportErrorInfoPdu; + + case FreeRDP_SupportGeometryTracking: + return settings->SupportGeometryTracking; + + case FreeRDP_SupportGraphicsPipeline: + return settings->SupportGraphicsPipeline; + + case FreeRDP_SupportHeartbeatPdu: + return settings->SupportHeartbeatPdu; + + case FreeRDP_SupportMonitorLayoutPdu: + return settings->SupportMonitorLayoutPdu; + + case FreeRDP_SupportMultitransport: + return settings->SupportMultitransport; + + case FreeRDP_SupportSSHAgentChannel: + return settings->SupportSSHAgentChannel; + + case FreeRDP_SupportSkipChannelJoin: + return settings->SupportSkipChannelJoin; + + case FreeRDP_SupportStatusInfoPdu: + return settings->SupportStatusInfoPdu; + + case FreeRDP_SupportVideoOptimized: + return settings->SupportVideoOptimized; + + case FreeRDP_SuppressOutput: + return settings->SuppressOutput; + + case FreeRDP_SurfaceCommandsEnabled: + return settings->SurfaceCommandsEnabled; + + case FreeRDP_SurfaceFrameMarkerEnabled: + return settings->SurfaceFrameMarkerEnabled; + + case FreeRDP_SuspendInput: + return settings->SuspendInput; + + case FreeRDP_SynchronousDynamicChannels: + return settings->SynchronousDynamicChannels; + + case FreeRDP_SynchronousStaticChannels: + return settings->SynchronousStaticChannels; + + case FreeRDP_TcpKeepAlive: + return settings->TcpKeepAlive; + + case FreeRDP_TlsSecurity: + return settings->TlsSecurity; + + case FreeRDP_ToggleFullscreen: + return settings->ToggleFullscreen; + + case FreeRDP_TransportDump: + return settings->TransportDump; + + case FreeRDP_TransportDumpReplay: + return settings->TransportDumpReplay; + + case FreeRDP_UnicodeInput: + return settings->UnicodeInput; + + case FreeRDP_UnmapButtons: + return settings->UnmapButtons; + + case FreeRDP_UseCommonStdioCallbacks: + return settings->UseCommonStdioCallbacks; + + case FreeRDP_UseMultimon: + return settings->UseMultimon; + + case FreeRDP_UseRdpSecurityLayer: + return settings->UseRdpSecurityLayer; + + case FreeRDP_UsingSavedCredentials: + return settings->UsingSavedCredentials; + + case FreeRDP_VideoDisable: + return settings->VideoDisable; + + case FreeRDP_VmConnectMode: + return settings->VmConnectMode; + + case FreeRDP_WaitForOutputBufferFlush: + return settings->WaitForOutputBufferFlush; + + case FreeRDP_Workarea: + return settings->Workarea; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return FALSE; + } +} + +BOOL freerdp_settings_set_bool(rdpSettings* settings, FreeRDP_Settings_Keys_Bool id, BOOL val) +{ + union + { + void* v; + const void* cv; + BOOL c; + const BOOL cc; + } cnv; + WINPR_ASSERT(settings); + + cnv.c = val; + + switch (id) + { + case FreeRDP_AadSecurity: + settings->AadSecurity = cnv.c; + break; + + case FreeRDP_AllowCacheWaitingList: + settings->AllowCacheWaitingList = cnv.c; + break; + + case FreeRDP_AllowDesktopComposition: + settings->AllowDesktopComposition = cnv.c; + break; + + case FreeRDP_AllowFontSmoothing: + settings->AllowFontSmoothing = cnv.c; + break; + + case FreeRDP_AllowUnanouncedOrdersFromServer: + settings->AllowUnanouncedOrdersFromServer = cnv.c; + break; + + case FreeRDP_AltSecFrameMarkerSupport: + settings->AltSecFrameMarkerSupport = cnv.c; + break; + + case FreeRDP_AsyncChannels: + settings->AsyncChannels = cnv.c; + break; + + case FreeRDP_AsyncUpdate: + settings->AsyncUpdate = cnv.c; + break; + + case FreeRDP_AudioCapture: + settings->AudioCapture = cnv.c; + break; + + case FreeRDP_AudioPlayback: + settings->AudioPlayback = cnv.c; + break; + + case FreeRDP_Authentication: + settings->Authentication = cnv.c; + break; + + case FreeRDP_AuthenticationOnly: + settings->AuthenticationOnly = cnv.c; + break; + + case FreeRDP_AutoAcceptCertificate: + settings->AutoAcceptCertificate = cnv.c; + break; + + case FreeRDP_AutoDenyCertificate: + settings->AutoDenyCertificate = cnv.c; + break; + + case FreeRDP_AutoLogonEnabled: + settings->AutoLogonEnabled = cnv.c; + break; + + case FreeRDP_AutoReconnectionEnabled: + settings->AutoReconnectionEnabled = cnv.c; + break; + + case FreeRDP_BitmapCacheEnabled: + settings->BitmapCacheEnabled = cnv.c; + break; + + case FreeRDP_BitmapCachePersistEnabled: + settings->BitmapCachePersistEnabled = cnv.c; + break; + + case FreeRDP_BitmapCacheV3Enabled: + settings->BitmapCacheV3Enabled = cnv.c; + break; + + case FreeRDP_BitmapCompressionDisabled: + settings->BitmapCompressionDisabled = cnv.c; + break; + + case FreeRDP_CertificateCallbackPreferPEM: + settings->CertificateCallbackPreferPEM = cnv.c; + break; + + case FreeRDP_CompressionEnabled: + settings->CompressionEnabled = cnv.c; + break; + + case FreeRDP_ConnectChildSession: + settings->ConnectChildSession = cnv.c; + break; + + case FreeRDP_ConsoleSession: + settings->ConsoleSession = cnv.c; + break; + + case FreeRDP_CredentialsFromStdin: + settings->CredentialsFromStdin = cnv.c; + break; + + case FreeRDP_DeactivateClientDecoding: + settings->DeactivateClientDecoding = cnv.c; + break; + + case FreeRDP_Decorations: + settings->Decorations = cnv.c; + break; + + case FreeRDP_DesktopResize: + settings->DesktopResize = cnv.c; + break; + + case FreeRDP_DeviceRedirection: + settings->DeviceRedirection = cnv.c; + break; + + case FreeRDP_DisableCredentialsDelegation: + settings->DisableCredentialsDelegation = cnv.c; + break; + + case FreeRDP_DisableCtrlAltDel: + settings->DisableCtrlAltDel = cnv.c; + break; + + case FreeRDP_DisableCursorBlinking: + settings->DisableCursorBlinking = cnv.c; + break; + + case FreeRDP_DisableCursorShadow: + settings->DisableCursorShadow = cnv.c; + break; + + case FreeRDP_DisableFullWindowDrag: + settings->DisableFullWindowDrag = cnv.c; + break; + + case FreeRDP_DisableMenuAnims: + settings->DisableMenuAnims = cnv.c; + break; + + case FreeRDP_DisableRemoteAppCapsCheck: + settings->DisableRemoteAppCapsCheck = cnv.c; + break; + + case FreeRDP_DisableThemes: + settings->DisableThemes = cnv.c; + break; + + case FreeRDP_DisableWallpaper: + settings->DisableWallpaper = cnv.c; + break; + + case FreeRDP_DrawAllowColorSubsampling: + settings->DrawAllowColorSubsampling = cnv.c; + break; + + case FreeRDP_DrawAllowDynamicColorFidelity: + settings->DrawAllowDynamicColorFidelity = cnv.c; + break; + + case FreeRDP_DrawAllowSkipAlpha: + settings->DrawAllowSkipAlpha = cnv.c; + break; + + case FreeRDP_DrawGdiPlusCacheEnabled: + settings->DrawGdiPlusCacheEnabled = cnv.c; + break; + + case FreeRDP_DrawGdiPlusEnabled: + settings->DrawGdiPlusEnabled = cnv.c; + break; + + case FreeRDP_DrawNineGridEnabled: + settings->DrawNineGridEnabled = cnv.c; + break; + + case FreeRDP_DumpRemoteFx: + settings->DumpRemoteFx = cnv.c; + break; + + case FreeRDP_DynamicDaylightTimeDisabled: + settings->DynamicDaylightTimeDisabled = cnv.c; + break; + + case FreeRDP_DynamicResolutionUpdate: + settings->DynamicResolutionUpdate = cnv.c; + break; + + case FreeRDP_EmbeddedWindow: + settings->EmbeddedWindow = cnv.c; + break; + + case FreeRDP_EnableWindowsKey: + settings->EnableWindowsKey = cnv.c; + break; + + case FreeRDP_EncomspVirtualChannel: + settings->EncomspVirtualChannel = cnv.c; + break; + + case FreeRDP_ExtSecurity: + settings->ExtSecurity = cnv.c; + break; + + case FreeRDP_ExternalCertificateManagement: + settings->ExternalCertificateManagement = cnv.c; + break; + + case FreeRDP_FIPSMode: + settings->FIPSMode = cnv.c; + break; + + case FreeRDP_FastPathInput: + settings->FastPathInput = cnv.c; + break; + + case FreeRDP_FastPathOutput: + settings->FastPathOutput = cnv.c; + break; + + case FreeRDP_ForceEncryptedCsPdu: + settings->ForceEncryptedCsPdu = cnv.c; + break; + + case FreeRDP_ForceMultimon: + settings->ForceMultimon = cnv.c; + break; + + case FreeRDP_FrameMarkerCommandEnabled: + settings->FrameMarkerCommandEnabled = cnv.c; + break; + + case FreeRDP_Fullscreen: + settings->Fullscreen = cnv.c; + break; + + case FreeRDP_GatewayArmTransport: + settings->GatewayArmTransport = cnv.c; + break; + + case FreeRDP_GatewayBypassLocal: + settings->GatewayBypassLocal = cnv.c; + break; + + case FreeRDP_GatewayEnabled: + settings->GatewayEnabled = cnv.c; + break; + + case FreeRDP_GatewayHttpExtAuthSspiNtlm: + settings->GatewayHttpExtAuthSspiNtlm = cnv.c; + break; + + case FreeRDP_GatewayHttpTransport: + settings->GatewayHttpTransport = cnv.c; + break; + + case FreeRDP_GatewayHttpUseWebsockets: + settings->GatewayHttpUseWebsockets = cnv.c; + break; + + case FreeRDP_GatewayRpcTransport: + settings->GatewayRpcTransport = cnv.c; + break; + + case FreeRDP_GatewayUdpTransport: + settings->GatewayUdpTransport = cnv.c; + break; + + case FreeRDP_GatewayUseSameCredentials: + settings->GatewayUseSameCredentials = cnv.c; + break; + + case FreeRDP_GfxAVC444: + settings->GfxAVC444 = cnv.c; + break; + + case FreeRDP_GfxAVC444v2: + settings->GfxAVC444v2 = cnv.c; + break; + + case FreeRDP_GfxH264: + settings->GfxH264 = cnv.c; + break; + + case FreeRDP_GfxPlanar: + settings->GfxPlanar = cnv.c; + break; + + case FreeRDP_GfxProgressive: + settings->GfxProgressive = cnv.c; + break; + + case FreeRDP_GfxProgressiveV2: + settings->GfxProgressiveV2 = cnv.c; + break; + + case FreeRDP_GfxSendQoeAck: + settings->GfxSendQoeAck = cnv.c; + break; + + case FreeRDP_GfxSmallCache: + settings->GfxSmallCache = cnv.c; + break; + + case FreeRDP_GfxThinClient: + settings->GfxThinClient = cnv.c; + break; + + case FreeRDP_GrabKeyboard: + settings->GrabKeyboard = cnv.c; + break; + + case FreeRDP_GrabMouse: + settings->GrabMouse = cnv.c; + break; + + case FreeRDP_HasExtendedMouseEvent: + settings->HasExtendedMouseEvent = cnv.c; + break; + + case FreeRDP_HasHorizontalWheel: + settings->HasHorizontalWheel = cnv.c; + break; + + case FreeRDP_HasMonitorAttributes: + settings->HasMonitorAttributes = cnv.c; + break; + + case FreeRDP_HasQoeEvent: + settings->HasQoeEvent = cnv.c; + break; + + case FreeRDP_HasRelativeMouseEvent: + settings->HasRelativeMouseEvent = cnv.c; + break; + + case FreeRDP_HiDefRemoteApp: + settings->HiDefRemoteApp = cnv.c; + break; + + case FreeRDP_IPv6Enabled: + settings->IPv6Enabled = cnv.c; + break; + + case FreeRDP_IgnoreCertificate: + settings->IgnoreCertificate = cnv.c; + break; + + case FreeRDP_IgnoreInvalidDevices: + settings->IgnoreInvalidDevices = cnv.c; + break; + + case FreeRDP_JpegCodec: + settings->JpegCodec = cnv.c; + break; + + case FreeRDP_KerberosRdgIsProxy: + settings->KerberosRdgIsProxy = cnv.c; + break; + + case FreeRDP_ListMonitors: + settings->ListMonitors = cnv.c; + break; + + case FreeRDP_LocalConnection: + settings->LocalConnection = cnv.c; + break; + + case FreeRDP_LogonErrors: + settings->LogonErrors = cnv.c; + break; + + case FreeRDP_LogonNotify: + settings->LogonNotify = cnv.c; + break; + + case FreeRDP_LongCredentialsSupported: + settings->LongCredentialsSupported = cnv.c; + break; + + case FreeRDP_LyncRdpMode: + settings->LyncRdpMode = cnv.c; + break; + + case FreeRDP_MaximizeShell: + settings->MaximizeShell = cnv.c; + break; + + case FreeRDP_MouseAttached: + settings->MouseAttached = cnv.c; + break; + + case FreeRDP_MouseHasWheel: + settings->MouseHasWheel = cnv.c; + break; + + case FreeRDP_MouseMotion: + settings->MouseMotion = cnv.c; + break; + + case FreeRDP_MouseUseRelativeMove: + settings->MouseUseRelativeMove = cnv.c; + break; + + case FreeRDP_MstscCookieMode: + settings->MstscCookieMode = cnv.c; + break; + + case FreeRDP_MultiTouchGestures: + settings->MultiTouchGestures = cnv.c; + break; + + case FreeRDP_MultiTouchInput: + settings->MultiTouchInput = cnv.c; + break; + + case FreeRDP_NSCodec: + settings->NSCodec = cnv.c; + break; + + case FreeRDP_NSCodecAllowDynamicColorFidelity: + settings->NSCodecAllowDynamicColorFidelity = cnv.c; + break; + + case FreeRDP_NSCodecAllowSubsampling: + settings->NSCodecAllowSubsampling = cnv.c; + break; + + case FreeRDP_NegotiateSecurityLayer: + settings->NegotiateSecurityLayer = cnv.c; + break; + + case FreeRDP_NetworkAutoDetect: + settings->NetworkAutoDetect = cnv.c; + break; + + case FreeRDP_NlaSecurity: + settings->NlaSecurity = cnv.c; + break; + + case FreeRDP_NoBitmapCompressionHeader: + settings->NoBitmapCompressionHeader = cnv.c; + break; + + case FreeRDP_OldLicenseBehaviour: + settings->OldLicenseBehaviour = cnv.c; + break; + + case FreeRDP_PasswordIsSmartcardPin: + settings->PasswordIsSmartcardPin = cnv.c; + break; + + case FreeRDP_PercentScreenUseHeight: + settings->PercentScreenUseHeight = cnv.c; + break; + + case FreeRDP_PercentScreenUseWidth: + settings->PercentScreenUseWidth = cnv.c; + break; + + case FreeRDP_PlayRemoteFx: + settings->PlayRemoteFx = cnv.c; + break; + + case FreeRDP_PreferIPv6OverIPv4: + settings->PreferIPv6OverIPv4 = cnv.c; + break; + + case FreeRDP_PrintReconnectCookie: + settings->PrintReconnectCookie = cnv.c; + break; + + case FreeRDP_PromptForCredentials: + settings->PromptForCredentials = cnv.c; + break; + + case FreeRDP_RdpSecurity: + settings->RdpSecurity = cnv.c; + break; + + case FreeRDP_RdstlsSecurity: + settings->RdstlsSecurity = cnv.c; + break; + + case FreeRDP_RedirectClipboard: + settings->RedirectClipboard = cnv.c; + break; + + case FreeRDP_RedirectDrives: + settings->RedirectDrives = cnv.c; + break; + + case FreeRDP_RedirectHomeDrive: + settings->RedirectHomeDrive = cnv.c; + break; + + case FreeRDP_RedirectParallelPorts: + settings->RedirectParallelPorts = cnv.c; + break; + + case FreeRDP_RedirectPrinters: + settings->RedirectPrinters = cnv.c; + break; + + case FreeRDP_RedirectSerialPorts: + settings->RedirectSerialPorts = cnv.c; + break; + + case FreeRDP_RedirectSmartCards: + settings->RedirectSmartCards = cnv.c; + break; + + case FreeRDP_RedirectWebAuthN: + settings->RedirectWebAuthN = cnv.c; + break; + + case FreeRDP_RefreshRect: + settings->RefreshRect = cnv.c; + break; + + case FreeRDP_RemdeskVirtualChannel: + settings->RemdeskVirtualChannel = cnv.c; + break; + + case FreeRDP_RemoteAppLanguageBarSupported: + settings->RemoteAppLanguageBarSupported = cnv.c; + break; + + case FreeRDP_RemoteApplicationMode: + settings->RemoteApplicationMode = cnv.c; + break; + + case FreeRDP_RemoteAssistanceMode: + settings->RemoteAssistanceMode = cnv.c; + break; + + case FreeRDP_RemoteAssistanceRequestControl: + settings->RemoteAssistanceRequestControl = cnv.c; + break; + + case FreeRDP_RemoteConsoleAudio: + settings->RemoteConsoleAudio = cnv.c; + break; + + case FreeRDP_RemoteCredentialGuard: + settings->RemoteCredentialGuard = cnv.c; + break; + + case FreeRDP_RemoteFxCodec: + settings->RemoteFxCodec = cnv.c; + break; + + case FreeRDP_RemoteFxImageCodec: + settings->RemoteFxImageCodec = cnv.c; + break; + + case FreeRDP_RemoteFxOnly: + settings->RemoteFxOnly = cnv.c; + break; + + case FreeRDP_RestrictedAdminModeRequired: + settings->RestrictedAdminModeRequired = cnv.c; + break; + + case FreeRDP_SaltedChecksum: + settings->SaltedChecksum = cnv.c; + break; + + case FreeRDP_SendPreconnectionPdu: + settings->SendPreconnectionPdu = cnv.c; + break; + + case FreeRDP_ServerLicenseRequired: + settings->ServerLicenseRequired = cnv.c; + break; + + case FreeRDP_ServerMode: + settings->ServerMode = cnv.c; + break; + + case FreeRDP_SmartSizing: + settings->SmartSizing = cnv.c; + break; + + case FreeRDP_SmartcardEmulation: + settings->SmartcardEmulation = cnv.c; + break; + + case FreeRDP_SmartcardLogon: + settings->SmartcardLogon = cnv.c; + break; + + case FreeRDP_SoftwareGdi: + settings->SoftwareGdi = cnv.c; + break; + + case FreeRDP_SoundBeepsEnabled: + settings->SoundBeepsEnabled = cnv.c; + break; + + case FreeRDP_SpanMonitors: + settings->SpanMonitors = cnv.c; + break; + + case FreeRDP_SupportAsymetricKeys: + settings->SupportAsymetricKeys = cnv.c; + break; + + case FreeRDP_SupportDisplayControl: + settings->SupportDisplayControl = cnv.c; + break; + + case FreeRDP_SupportDynamicChannels: + settings->SupportDynamicChannels = cnv.c; + break; + + case FreeRDP_SupportDynamicTimeZone: + settings->SupportDynamicTimeZone = cnv.c; + break; + + case FreeRDP_SupportEchoChannel: + settings->SupportEchoChannel = cnv.c; + break; + + case FreeRDP_SupportEdgeActionV1: + settings->SupportEdgeActionV1 = cnv.c; + break; + + case FreeRDP_SupportEdgeActionV2: + settings->SupportEdgeActionV2 = cnv.c; + break; + + case FreeRDP_SupportErrorInfoPdu: + settings->SupportErrorInfoPdu = cnv.c; + break; + + case FreeRDP_SupportGeometryTracking: + settings->SupportGeometryTracking = cnv.c; + break; + + case FreeRDP_SupportGraphicsPipeline: + settings->SupportGraphicsPipeline = cnv.c; + break; + + case FreeRDP_SupportHeartbeatPdu: + settings->SupportHeartbeatPdu = cnv.c; + break; + + case FreeRDP_SupportMonitorLayoutPdu: + settings->SupportMonitorLayoutPdu = cnv.c; + break; + + case FreeRDP_SupportMultitransport: + settings->SupportMultitransport = cnv.c; + break; + + case FreeRDP_SupportSSHAgentChannel: + settings->SupportSSHAgentChannel = cnv.c; + break; + + case FreeRDP_SupportSkipChannelJoin: + settings->SupportSkipChannelJoin = cnv.c; + break; + + case FreeRDP_SupportStatusInfoPdu: + settings->SupportStatusInfoPdu = cnv.c; + break; + + case FreeRDP_SupportVideoOptimized: + settings->SupportVideoOptimized = cnv.c; + break; + + case FreeRDP_SuppressOutput: + settings->SuppressOutput = cnv.c; + break; + + case FreeRDP_SurfaceCommandsEnabled: + settings->SurfaceCommandsEnabled = cnv.c; + break; + + case FreeRDP_SurfaceFrameMarkerEnabled: + settings->SurfaceFrameMarkerEnabled = cnv.c; + break; + + case FreeRDP_SuspendInput: + settings->SuspendInput = cnv.c; + break; + + case FreeRDP_SynchronousDynamicChannels: + settings->SynchronousDynamicChannels = cnv.c; + break; + + case FreeRDP_SynchronousStaticChannels: + settings->SynchronousStaticChannels = cnv.c; + break; + + case FreeRDP_TcpKeepAlive: + settings->TcpKeepAlive = cnv.c; + break; + + case FreeRDP_TlsSecurity: + settings->TlsSecurity = cnv.c; + break; + + case FreeRDP_ToggleFullscreen: + settings->ToggleFullscreen = cnv.c; + break; + + case FreeRDP_TransportDump: + settings->TransportDump = cnv.c; + break; + + case FreeRDP_TransportDumpReplay: + settings->TransportDumpReplay = cnv.c; + break; + + case FreeRDP_UnicodeInput: + settings->UnicodeInput = cnv.c; + break; + + case FreeRDP_UnmapButtons: + settings->UnmapButtons = cnv.c; + break; + + case FreeRDP_UseCommonStdioCallbacks: + settings->UseCommonStdioCallbacks = cnv.c; + break; + + case FreeRDP_UseMultimon: + settings->UseMultimon = cnv.c; + break; + + case FreeRDP_UseRdpSecurityLayer: + settings->UseRdpSecurityLayer = cnv.c; + break; + + case FreeRDP_UsingSavedCredentials: + settings->UsingSavedCredentials = cnv.c; + break; + + case FreeRDP_VideoDisable: + settings->VideoDisable = cnv.c; + break; + + case FreeRDP_VmConnectMode: + settings->VmConnectMode = cnv.c; + break; + + case FreeRDP_WaitForOutputBufferFlush: + settings->WaitForOutputBufferFlush = cnv.c; + break; + + case FreeRDP_Workarea: + settings->Workarea = cnv.c; + break; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} + +UINT16 freerdp_settings_get_uint16(const rdpSettings* settings, FreeRDP_Settings_Keys_UInt16 id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + case FreeRDP_CapsGeneralCompressionLevel: + return settings->CapsGeneralCompressionLevel; + + case FreeRDP_CapsGeneralCompressionTypes: + return settings->CapsGeneralCompressionTypes; + + case FreeRDP_CapsProtocolVersion: + return settings->CapsProtocolVersion; + + case FreeRDP_CapsRemoteUnshareFlag: + return settings->CapsRemoteUnshareFlag; + + case FreeRDP_CapsUpdateCapabilityFlag: + return settings->CapsUpdateCapabilityFlag; + + case FreeRDP_DesktopOrientation: + return settings->DesktopOrientation; + + case FreeRDP_OrderSupportFlags: + return settings->OrderSupportFlags; + + case FreeRDP_OrderSupportFlagsEx: + return settings->OrderSupportFlagsEx; + + case FreeRDP_ProxyPort: + return settings->ProxyPort; + + case FreeRDP_SupportedColorDepths: + return settings->SupportedColorDepths; + + case FreeRDP_TLSMaxVersion: + return settings->TLSMaxVersion; + + case FreeRDP_TLSMinVersion: + return settings->TLSMinVersion; + + case FreeRDP_TextANSICodePage: + return settings->TextANSICodePage; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return 0; + } +} + +BOOL freerdp_settings_set_uint16(rdpSettings* settings, FreeRDP_Settings_Keys_UInt16 id, UINT16 val) +{ + union + { + void* v; + const void* cv; + UINT16 c; + const UINT16 cc; + } cnv; + WINPR_ASSERT(settings); + + cnv.c = val; + + switch (id) + { + case FreeRDP_CapsGeneralCompressionLevel: + settings->CapsGeneralCompressionLevel = cnv.c; + break; + + case FreeRDP_CapsGeneralCompressionTypes: + settings->CapsGeneralCompressionTypes = cnv.c; + break; + + case FreeRDP_CapsProtocolVersion: + settings->CapsProtocolVersion = cnv.c; + break; + + case FreeRDP_CapsRemoteUnshareFlag: + settings->CapsRemoteUnshareFlag = cnv.c; + break; + + case FreeRDP_CapsUpdateCapabilityFlag: + settings->CapsUpdateCapabilityFlag = cnv.c; + break; + + case FreeRDP_DesktopOrientation: + settings->DesktopOrientation = cnv.c; + break; + + case FreeRDP_OrderSupportFlags: + settings->OrderSupportFlags = cnv.c; + break; + + case FreeRDP_OrderSupportFlagsEx: + settings->OrderSupportFlagsEx = cnv.c; + break; + + case FreeRDP_ProxyPort: + settings->ProxyPort = cnv.c; + break; + + case FreeRDP_SupportedColorDepths: + settings->SupportedColorDepths = cnv.c; + break; + + case FreeRDP_TLSMaxVersion: + settings->TLSMaxVersion = cnv.c; + break; + + case FreeRDP_TLSMinVersion: + settings->TLSMinVersion = cnv.c; + break; + + case FreeRDP_TextANSICodePage: + settings->TextANSICodePage = cnv.c; + break; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} + +INT16 freerdp_settings_get_int16(const rdpSettings* settings, FreeRDP_Settings_Keys_Int16 id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return 0; + } +} + +BOOL freerdp_settings_set_int16(rdpSettings* settings, FreeRDP_Settings_Keys_Int16 id, INT16 val) +{ + union + { + void* v; + const void* cv; + INT16 c; + const INT16 cc; + } cnv; + WINPR_ASSERT(settings); + + cnv.c = val; + + switch (id) + { + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} + +UINT32 freerdp_settings_get_uint32(const rdpSettings* settings, FreeRDP_Settings_Keys_UInt32 id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + case FreeRDP_AcceptedCertLength: + return settings->AcceptedCertLength; + + case FreeRDP_AuthenticationLevel: + return settings->AuthenticationLevel; + + case FreeRDP_AutoReconnectMaxRetries: + return settings->AutoReconnectMaxRetries; + + case FreeRDP_BitmapCacheV2NumCells: + return settings->BitmapCacheV2NumCells; + + case FreeRDP_BitmapCacheV3CodecId: + return settings->BitmapCacheV3CodecId; + + case FreeRDP_BitmapCacheVersion: + return settings->BitmapCacheVersion; + + case FreeRDP_BrushSupportLevel: + return settings->BrushSupportLevel; + + case FreeRDP_ChannelCount: + return settings->ChannelCount; + + case FreeRDP_ChannelDefArraySize: + return settings->ChannelDefArraySize; + + case FreeRDP_ClientBuild: + return settings->ClientBuild; + + case FreeRDP_ClientRandomLength: + return settings->ClientRandomLength; + + case FreeRDP_ClientSessionId: + return settings->ClientSessionId; + + case FreeRDP_ClipboardFeatureMask: + return settings->ClipboardFeatureMask; + + case FreeRDP_ClusterInfoFlags: + return settings->ClusterInfoFlags; + + case FreeRDP_ColorDepth: + return settings->ColorDepth; + + case FreeRDP_ColorPointerCacheSize: + return settings->ColorPointerCacheSize; + + case FreeRDP_CompDeskSupportLevel: + return settings->CompDeskSupportLevel; + + case FreeRDP_CompressionLevel: + return settings->CompressionLevel; + + case FreeRDP_ConnectionType: + return settings->ConnectionType; + + case FreeRDP_CookieMaxLength: + return settings->CookieMaxLength; + + case FreeRDP_DesktopHeight: + return settings->DesktopHeight; + + case FreeRDP_DesktopPhysicalHeight: + return settings->DesktopPhysicalHeight; + + case FreeRDP_DesktopPhysicalWidth: + return settings->DesktopPhysicalWidth; + + case FreeRDP_DesktopPosX: + return settings->DesktopPosX; + + case FreeRDP_DesktopPosY: + return settings->DesktopPosY; + + case FreeRDP_DesktopScaleFactor: + return settings->DesktopScaleFactor; + + case FreeRDP_DesktopWidth: + return settings->DesktopWidth; + + case FreeRDP_DeviceArraySize: + return settings->DeviceArraySize; + + case FreeRDP_DeviceCount: + return settings->DeviceCount; + + case FreeRDP_DeviceScaleFactor: + return settings->DeviceScaleFactor; + + case FreeRDP_DrawNineGridCacheEntries: + return settings->DrawNineGridCacheEntries; + + case FreeRDP_DrawNineGridCacheSize: + return settings->DrawNineGridCacheSize; + + case FreeRDP_DynamicChannelArraySize: + return settings->DynamicChannelArraySize; + + case FreeRDP_DynamicChannelCount: + return settings->DynamicChannelCount; + + case FreeRDP_EarlyCapabilityFlags: + return settings->EarlyCapabilityFlags; + + case FreeRDP_EncryptionLevel: + return settings->EncryptionLevel; + + case FreeRDP_EncryptionMethods: + return settings->EncryptionMethods; + + case FreeRDP_ExtEncryptionMethods: + return settings->ExtEncryptionMethods; + + case FreeRDP_FakeMouseMotionInterval: + return settings->FakeMouseMotionInterval; + + case FreeRDP_Floatbar: + return settings->Floatbar; + + case FreeRDP_FrameAcknowledge: + return settings->FrameAcknowledge; + + case FreeRDP_GatewayAcceptedCertLength: + return settings->GatewayAcceptedCertLength; + + case FreeRDP_GatewayCredentialsSource: + return settings->GatewayCredentialsSource; + + case FreeRDP_GatewayPort: + return settings->GatewayPort; + + case FreeRDP_GatewayUsageMethod: + return settings->GatewayUsageMethod; + + case FreeRDP_GfxCapsFilter: + return settings->GfxCapsFilter; + + case FreeRDP_GlyphSupportLevel: + return settings->GlyphSupportLevel; + + case FreeRDP_JpegCodecId: + return settings->JpegCodecId; + + case FreeRDP_JpegQuality: + return settings->JpegQuality; + + case FreeRDP_KeySpec: + return settings->KeySpec; + + case FreeRDP_KeyboardCodePage: + return settings->KeyboardCodePage; + + case FreeRDP_KeyboardFunctionKey: + return settings->KeyboardFunctionKey; + + case FreeRDP_KeyboardHook: + return settings->KeyboardHook; + + case FreeRDP_KeyboardLayout: + return settings->KeyboardLayout; + + case FreeRDP_KeyboardSubType: + return settings->KeyboardSubType; + + case FreeRDP_KeyboardType: + return settings->KeyboardType; + + case FreeRDP_LargePointerFlag: + return settings->LargePointerFlag; + + case FreeRDP_LoadBalanceInfoLength: + return settings->LoadBalanceInfoLength; + + case FreeRDP_MonitorAttributeFlags: + return settings->MonitorAttributeFlags; + + case FreeRDP_MonitorCount: + return settings->MonitorCount; + + case FreeRDP_MonitorDefArraySize: + return settings->MonitorDefArraySize; + + case FreeRDP_MonitorFlags: + return settings->MonitorFlags; + + case FreeRDP_MonitorLocalShiftX: + return settings->MonitorLocalShiftX; + + case FreeRDP_MonitorLocalShiftY: + return settings->MonitorLocalShiftY; + + case FreeRDP_MultifragMaxRequestSize: + return settings->MultifragMaxRequestSize; + + case FreeRDP_MultitransportFlags: + return settings->MultitransportFlags; + + case FreeRDP_NSCodecColorLossLevel: + return settings->NSCodecColorLossLevel; + + case FreeRDP_NSCodecId: + return settings->NSCodecId; + + case FreeRDP_NegotiationFlags: + return settings->NegotiationFlags; + + case FreeRDP_NumMonitorIds: + return settings->NumMonitorIds; + + case FreeRDP_OffscreenCacheEntries: + return settings->OffscreenCacheEntries; + + case FreeRDP_OffscreenCacheSize: + return settings->OffscreenCacheSize; + + case FreeRDP_OffscreenSupportLevel: + return settings->OffscreenSupportLevel; + + case FreeRDP_OsMajorType: + return settings->OsMajorType; + + case FreeRDP_OsMinorType: + return settings->OsMinorType; + + case FreeRDP_Password51Length: + return settings->Password51Length; + + case FreeRDP_PduSource: + return settings->PduSource; + + case FreeRDP_PercentScreen: + return settings->PercentScreen; + + case FreeRDP_PerformanceFlags: + return settings->PerformanceFlags; + + case FreeRDP_PointerCacheSize: + return settings->PointerCacheSize; + + case FreeRDP_PreconnectionId: + return settings->PreconnectionId; + + case FreeRDP_ProxyType: + return settings->ProxyType; + + case FreeRDP_RdpVersion: + return settings->RdpVersion; + + case FreeRDP_ReceivedCapabilitiesSize: + return settings->ReceivedCapabilitiesSize; + + case FreeRDP_RedirectedSessionId: + return settings->RedirectedSessionId; + + case FreeRDP_RedirectionAcceptedCertLength: + return settings->RedirectionAcceptedCertLength; + + case FreeRDP_RedirectionFlags: + return settings->RedirectionFlags; + + case FreeRDP_RedirectionGuidLength: + return settings->RedirectionGuidLength; + + case FreeRDP_RedirectionPasswordLength: + return settings->RedirectionPasswordLength; + + case FreeRDP_RedirectionPreferType: + return settings->RedirectionPreferType; + + case FreeRDP_RedirectionTsvUrlLength: + return settings->RedirectionTsvUrlLength; + + case FreeRDP_RemoteAppNumIconCacheEntries: + return settings->RemoteAppNumIconCacheEntries; + + case FreeRDP_RemoteAppNumIconCaches: + return settings->RemoteAppNumIconCaches; + + case FreeRDP_RemoteApplicationExpandCmdLine: + return settings->RemoteApplicationExpandCmdLine; + + case FreeRDP_RemoteApplicationExpandWorkingDir: + return settings->RemoteApplicationExpandWorkingDir; + + case FreeRDP_RemoteApplicationSupportLevel: + return settings->RemoteApplicationSupportLevel; + + case FreeRDP_RemoteApplicationSupportMask: + return settings->RemoteApplicationSupportMask; + + case FreeRDP_RemoteFxCaptureFlags: + return settings->RemoteFxCaptureFlags; + + case FreeRDP_RemoteFxCodecId: + return settings->RemoteFxCodecId; + + case FreeRDP_RemoteFxCodecMode: + return settings->RemoteFxCodecMode; + + case FreeRDP_RemoteWndSupportLevel: + return settings->RemoteWndSupportLevel; + + case FreeRDP_RequestedProtocols: + return settings->RequestedProtocols; + + case FreeRDP_SelectedProtocol: + return settings->SelectedProtocol; + + case FreeRDP_ServerCertificateLength: + return settings->ServerCertificateLength; + + case FreeRDP_ServerLicenseProductIssuersCount: + return settings->ServerLicenseProductIssuersCount; + + case FreeRDP_ServerLicenseProductVersion: + return settings->ServerLicenseProductVersion; + + case FreeRDP_ServerPort: + return settings->ServerPort; + + case FreeRDP_ServerRandomLength: + return settings->ServerRandomLength; + + case FreeRDP_ShareId: + return settings->ShareId; + + case FreeRDP_SmartSizingHeight: + return settings->SmartSizingHeight; + + case FreeRDP_SmartSizingWidth: + return settings->SmartSizingWidth; + + case FreeRDP_StaticChannelArraySize: + return settings->StaticChannelArraySize; + + case FreeRDP_StaticChannelCount: + return settings->StaticChannelCount; + + case FreeRDP_TargetNetAddressCount: + return settings->TargetNetAddressCount; + + case FreeRDP_TcpAckTimeout: + return settings->TcpAckTimeout; + + case FreeRDP_TcpConnectTimeout: + return settings->TcpConnectTimeout; + + case FreeRDP_TcpKeepAliveDelay: + return settings->TcpKeepAliveDelay; + + case FreeRDP_TcpKeepAliveInterval: + return settings->TcpKeepAliveInterval; + + case FreeRDP_TcpKeepAliveRetries: + return settings->TcpKeepAliveRetries; + + case FreeRDP_ThreadingFlags: + return settings->ThreadingFlags; + + case FreeRDP_TlsSecLevel: + return settings->TlsSecLevel; + + case FreeRDP_VCChunkSize: + return settings->VCChunkSize; + + case FreeRDP_VCFlags: + return settings->VCFlags; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return 0; + } +} + +BOOL freerdp_settings_set_uint32(rdpSettings* settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val) +{ + union + { + void* v; + const void* cv; + UINT32 c; + const UINT32 cc; + } cnv; + WINPR_ASSERT(settings); + + cnv.c = val; + + switch (id) + { + case FreeRDP_AcceptedCertLength: + settings->AcceptedCertLength = cnv.c; + break; + + case FreeRDP_AuthenticationLevel: + settings->AuthenticationLevel = cnv.c; + break; + + case FreeRDP_AutoReconnectMaxRetries: + settings->AutoReconnectMaxRetries = cnv.c; + break; + + case FreeRDP_BitmapCacheV2NumCells: + settings->BitmapCacheV2NumCells = cnv.c; + break; + + case FreeRDP_BitmapCacheV3CodecId: + settings->BitmapCacheV3CodecId = cnv.c; + break; + + case FreeRDP_BitmapCacheVersion: + settings->BitmapCacheVersion = cnv.c; + break; + + case FreeRDP_BrushSupportLevel: + settings->BrushSupportLevel = cnv.c; + break; + + case FreeRDP_ChannelCount: + settings->ChannelCount = cnv.c; + break; + + case FreeRDP_ChannelDefArraySize: + settings->ChannelDefArraySize = cnv.c; + break; + + case FreeRDP_ClientBuild: + settings->ClientBuild = cnv.c; + break; + + case FreeRDP_ClientRandomLength: + settings->ClientRandomLength = cnv.c; + break; + + case FreeRDP_ClientSessionId: + settings->ClientSessionId = cnv.c; + break; + + case FreeRDP_ClipboardFeatureMask: + settings->ClipboardFeatureMask = cnv.c; + break; + + case FreeRDP_ClusterInfoFlags: + settings->ClusterInfoFlags = cnv.c; + break; + + case FreeRDP_ColorDepth: + settings->ColorDepth = cnv.c; + break; + + case FreeRDP_ColorPointerCacheSize: + settings->ColorPointerCacheSize = cnv.c; + break; + + case FreeRDP_CompDeskSupportLevel: + settings->CompDeskSupportLevel = cnv.c; + break; + + case FreeRDP_CompressionLevel: + settings->CompressionLevel = cnv.c; + break; + + case FreeRDP_ConnectionType: + settings->ConnectionType = cnv.c; + break; + + case FreeRDP_CookieMaxLength: + settings->CookieMaxLength = cnv.c; + break; + + case FreeRDP_DesktopHeight: + settings->DesktopHeight = cnv.c; + break; + + case FreeRDP_DesktopPhysicalHeight: + settings->DesktopPhysicalHeight = cnv.c; + break; + + case FreeRDP_DesktopPhysicalWidth: + settings->DesktopPhysicalWidth = cnv.c; + break; + + case FreeRDP_DesktopPosX: + settings->DesktopPosX = cnv.c; + break; + + case FreeRDP_DesktopPosY: + settings->DesktopPosY = cnv.c; + break; + + case FreeRDP_DesktopScaleFactor: + settings->DesktopScaleFactor = cnv.c; + break; + + case FreeRDP_DesktopWidth: + settings->DesktopWidth = cnv.c; + break; + + case FreeRDP_DeviceArraySize: + settings->DeviceArraySize = cnv.c; + break; + + case FreeRDP_DeviceCount: + settings->DeviceCount = cnv.c; + break; + + case FreeRDP_DeviceScaleFactor: + settings->DeviceScaleFactor = cnv.c; + break; + + case FreeRDP_DrawNineGridCacheEntries: + settings->DrawNineGridCacheEntries = cnv.c; + break; + + case FreeRDP_DrawNineGridCacheSize: + settings->DrawNineGridCacheSize = cnv.c; + break; + + case FreeRDP_DynamicChannelArraySize: + settings->DynamicChannelArraySize = cnv.c; + break; + + case FreeRDP_DynamicChannelCount: + settings->DynamicChannelCount = cnv.c; + break; + + case FreeRDP_EarlyCapabilityFlags: + settings->EarlyCapabilityFlags = cnv.c; + break; + + case FreeRDP_EncryptionLevel: + settings->EncryptionLevel = cnv.c; + break; + + case FreeRDP_EncryptionMethods: + settings->EncryptionMethods = cnv.c; + break; + + case FreeRDP_ExtEncryptionMethods: + settings->ExtEncryptionMethods = cnv.c; + break; + + case FreeRDP_FakeMouseMotionInterval: + settings->FakeMouseMotionInterval = cnv.c; + break; + + case FreeRDP_Floatbar: + settings->Floatbar = cnv.c; + break; + + case FreeRDP_FrameAcknowledge: + settings->FrameAcknowledge = cnv.c; + break; + + case FreeRDP_GatewayAcceptedCertLength: + settings->GatewayAcceptedCertLength = cnv.c; + break; + + case FreeRDP_GatewayCredentialsSource: + settings->GatewayCredentialsSource = cnv.c; + break; + + case FreeRDP_GatewayPort: + settings->GatewayPort = cnv.c; + break; + + case FreeRDP_GatewayUsageMethod: + settings->GatewayUsageMethod = cnv.c; + break; + + case FreeRDP_GfxCapsFilter: + settings->GfxCapsFilter = cnv.c; + break; + + case FreeRDP_GlyphSupportLevel: + settings->GlyphSupportLevel = cnv.c; + break; + + case FreeRDP_JpegCodecId: + settings->JpegCodecId = cnv.c; + break; + + case FreeRDP_JpegQuality: + settings->JpegQuality = cnv.c; + break; + + case FreeRDP_KeySpec: + settings->KeySpec = cnv.c; + break; + + case FreeRDP_KeyboardCodePage: + settings->KeyboardCodePage = cnv.c; + break; + + case FreeRDP_KeyboardFunctionKey: + settings->KeyboardFunctionKey = cnv.c; + break; + + case FreeRDP_KeyboardHook: + settings->KeyboardHook = cnv.c; + break; + + case FreeRDP_KeyboardLayout: + settings->KeyboardLayout = cnv.c; + break; + + case FreeRDP_KeyboardSubType: + settings->KeyboardSubType = cnv.c; + break; + + case FreeRDP_KeyboardType: + settings->KeyboardType = cnv.c; + break; + + case FreeRDP_LargePointerFlag: + settings->LargePointerFlag = cnv.c; + break; + + case FreeRDP_LoadBalanceInfoLength: + settings->LoadBalanceInfoLength = cnv.c; + break; + + case FreeRDP_MonitorAttributeFlags: + settings->MonitorAttributeFlags = cnv.c; + break; + + case FreeRDP_MonitorCount: + settings->MonitorCount = cnv.c; + break; + + case FreeRDP_MonitorDefArraySize: + settings->MonitorDefArraySize = cnv.c; + break; + + case FreeRDP_MonitorFlags: + settings->MonitorFlags = cnv.c; + break; + + case FreeRDP_MonitorLocalShiftX: + settings->MonitorLocalShiftX = cnv.c; + break; + + case FreeRDP_MonitorLocalShiftY: + settings->MonitorLocalShiftY = cnv.c; + break; + + case FreeRDP_MultifragMaxRequestSize: + settings->MultifragMaxRequestSize = cnv.c; + break; + + case FreeRDP_MultitransportFlags: + settings->MultitransportFlags = cnv.c; + break; + + case FreeRDP_NSCodecColorLossLevel: + settings->NSCodecColorLossLevel = cnv.c; + break; + + case FreeRDP_NSCodecId: + settings->NSCodecId = cnv.c; + break; + + case FreeRDP_NegotiationFlags: + settings->NegotiationFlags = cnv.c; + break; + + case FreeRDP_NumMonitorIds: + settings->NumMonitorIds = cnv.c; + break; + + case FreeRDP_OffscreenCacheEntries: + settings->OffscreenCacheEntries = cnv.c; + break; + + case FreeRDP_OffscreenCacheSize: + settings->OffscreenCacheSize = cnv.c; + break; + + case FreeRDP_OffscreenSupportLevel: + settings->OffscreenSupportLevel = cnv.c; + break; + + case FreeRDP_OsMajorType: + settings->OsMajorType = cnv.c; + break; + + case FreeRDP_OsMinorType: + settings->OsMinorType = cnv.c; + break; + + case FreeRDP_Password51Length: + settings->Password51Length = cnv.c; + break; + + case FreeRDP_PduSource: + settings->PduSource = cnv.c; + break; + + case FreeRDP_PercentScreen: + settings->PercentScreen = cnv.c; + break; + + case FreeRDP_PerformanceFlags: + settings->PerformanceFlags = cnv.c; + break; + + case FreeRDP_PointerCacheSize: + settings->PointerCacheSize = cnv.c; + break; + + case FreeRDP_PreconnectionId: + settings->PreconnectionId = cnv.c; + break; + + case FreeRDP_ProxyType: + settings->ProxyType = cnv.c; + break; + + case FreeRDP_RdpVersion: + settings->RdpVersion = cnv.c; + break; + + case FreeRDP_ReceivedCapabilitiesSize: + settings->ReceivedCapabilitiesSize = cnv.c; + break; + + case FreeRDP_RedirectedSessionId: + settings->RedirectedSessionId = cnv.c; + break; + + case FreeRDP_RedirectionAcceptedCertLength: + settings->RedirectionAcceptedCertLength = cnv.c; + break; + + case FreeRDP_RedirectionFlags: + settings->RedirectionFlags = cnv.c; + break; + + case FreeRDP_RedirectionGuidLength: + settings->RedirectionGuidLength = cnv.c; + break; + + case FreeRDP_RedirectionPasswordLength: + settings->RedirectionPasswordLength = cnv.c; + break; + + case FreeRDP_RedirectionPreferType: + settings->RedirectionPreferType = cnv.c; + break; + + case FreeRDP_RedirectionTsvUrlLength: + settings->RedirectionTsvUrlLength = cnv.c; + break; + + case FreeRDP_RemoteAppNumIconCacheEntries: + settings->RemoteAppNumIconCacheEntries = cnv.c; + break; + + case FreeRDP_RemoteAppNumIconCaches: + settings->RemoteAppNumIconCaches = cnv.c; + break; + + case FreeRDP_RemoteApplicationExpandCmdLine: + settings->RemoteApplicationExpandCmdLine = cnv.c; + break; + + case FreeRDP_RemoteApplicationExpandWorkingDir: + settings->RemoteApplicationExpandWorkingDir = cnv.c; + break; + + case FreeRDP_RemoteApplicationSupportLevel: + settings->RemoteApplicationSupportLevel = cnv.c; + break; + + case FreeRDP_RemoteApplicationSupportMask: + settings->RemoteApplicationSupportMask = cnv.c; + break; + + case FreeRDP_RemoteFxCaptureFlags: + settings->RemoteFxCaptureFlags = cnv.c; + break; + + case FreeRDP_RemoteFxCodecId: + settings->RemoteFxCodecId = cnv.c; + break; + + case FreeRDP_RemoteFxCodecMode: + settings->RemoteFxCodecMode = cnv.c; + break; + + case FreeRDP_RemoteWndSupportLevel: + settings->RemoteWndSupportLevel = cnv.c; + break; + + case FreeRDP_RequestedProtocols: + settings->RequestedProtocols = cnv.c; + break; + + case FreeRDP_SelectedProtocol: + settings->SelectedProtocol = cnv.c; + break; + + case FreeRDP_ServerCertificateLength: + settings->ServerCertificateLength = cnv.c; + break; + + case FreeRDP_ServerLicenseProductIssuersCount: + settings->ServerLicenseProductIssuersCount = cnv.c; + break; + + case FreeRDP_ServerLicenseProductVersion: + settings->ServerLicenseProductVersion = cnv.c; + break; + + case FreeRDP_ServerPort: + settings->ServerPort = cnv.c; + break; + + case FreeRDP_ServerRandomLength: + settings->ServerRandomLength = cnv.c; + break; + + case FreeRDP_ShareId: + settings->ShareId = cnv.c; + break; + + case FreeRDP_SmartSizingHeight: + settings->SmartSizingHeight = cnv.c; + break; + + case FreeRDP_SmartSizingWidth: + settings->SmartSizingWidth = cnv.c; + break; + + case FreeRDP_StaticChannelArraySize: + settings->StaticChannelArraySize = cnv.c; + break; + + case FreeRDP_StaticChannelCount: + settings->StaticChannelCount = cnv.c; + break; + + case FreeRDP_TargetNetAddressCount: + settings->TargetNetAddressCount = cnv.c; + break; + + case FreeRDP_TcpAckTimeout: + settings->TcpAckTimeout = cnv.c; + break; + + case FreeRDP_TcpConnectTimeout: + settings->TcpConnectTimeout = cnv.c; + break; + + case FreeRDP_TcpKeepAliveDelay: + settings->TcpKeepAliveDelay = cnv.c; + break; + + case FreeRDP_TcpKeepAliveInterval: + settings->TcpKeepAliveInterval = cnv.c; + break; + + case FreeRDP_TcpKeepAliveRetries: + settings->TcpKeepAliveRetries = cnv.c; + break; + + case FreeRDP_ThreadingFlags: + settings->ThreadingFlags = cnv.c; + break; + + case FreeRDP_TlsSecLevel: + settings->TlsSecLevel = cnv.c; + break; + + case FreeRDP_VCChunkSize: + settings->VCChunkSize = cnv.c; + break; + + case FreeRDP_VCFlags: + settings->VCFlags = cnv.c; + break; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} + +INT32 freerdp_settings_get_int32(const rdpSettings* settings, FreeRDP_Settings_Keys_Int32 id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + case FreeRDP_XPan: + return settings->XPan; + + case FreeRDP_YPan: + return settings->YPan; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return 0; + } +} + +BOOL freerdp_settings_set_int32(rdpSettings* settings, FreeRDP_Settings_Keys_Int32 id, INT32 val) +{ + union + { + void* v; + const void* cv; + INT32 c; + const INT32 cc; + } cnv; + WINPR_ASSERT(settings); + + cnv.c = val; + + switch (id) + { + case FreeRDP_XPan: + settings->XPan = cnv.c; + break; + + case FreeRDP_YPan: + settings->YPan = cnv.c; + break; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} + +UINT64 freerdp_settings_get_uint64(const rdpSettings* settings, FreeRDP_Settings_Keys_UInt64 id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + case FreeRDP_ParentWindowId: + return settings->ParentWindowId; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return 0; + } +} + +BOOL freerdp_settings_set_uint64(rdpSettings* settings, FreeRDP_Settings_Keys_UInt64 id, UINT64 val) +{ + union + { + void* v; + const void* cv; + UINT64 c; + const UINT64 cc; + } cnv; + WINPR_ASSERT(settings); + + cnv.c = val; + + switch (id) + { + case FreeRDP_ParentWindowId: + settings->ParentWindowId = cnv.c; + break; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} + +INT64 freerdp_settings_get_int64(const rdpSettings* settings, FreeRDP_Settings_Keys_Int64 id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return 0; + } +} + +BOOL freerdp_settings_set_int64(rdpSettings* settings, FreeRDP_Settings_Keys_Int64 id, INT64 val) +{ + union + { + void* v; + const void* cv; + INT64 c; + const INT64 cc; + } cnv; + WINPR_ASSERT(settings); + + cnv.c = val; + + switch (id) + { + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} + +const char* freerdp_settings_get_string(const rdpSettings* settings, + FreeRDP_Settings_Keys_String id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + case FreeRDP_AadServerHostname: + return settings->AadServerHostname; + + case FreeRDP_AcceptedCert: + return settings->AcceptedCert; + + case FreeRDP_ActionScript: + return settings->ActionScript; + + case FreeRDP_AllowedTlsCiphers: + return settings->AllowedTlsCiphers; + + case FreeRDP_AlternateShell: + return settings->AlternateShell; + + case FreeRDP_AssistanceFile: + return settings->AssistanceFile; + + case FreeRDP_AuthenticationPackageList: + return settings->AuthenticationPackageList; + + case FreeRDP_AuthenticationServiceClass: + return settings->AuthenticationServiceClass; + + case FreeRDP_BitmapCachePersistFile: + return settings->BitmapCachePersistFile; + + case FreeRDP_CardName: + return settings->CardName; + + case FreeRDP_CertificateAcceptedFingerprints: + return settings->CertificateAcceptedFingerprints; + + case FreeRDP_CertificateName: + return settings->CertificateName; + + case FreeRDP_ClientAddress: + return settings->ClientAddress; + + case FreeRDP_ClientDir: + return settings->ClientDir; + + case FreeRDP_ClientHostname: + return settings->ClientHostname; + + case FreeRDP_ClientProductId: + return settings->ClientProductId; + + case FreeRDP_ClipboardUseSelection: + return settings->ClipboardUseSelection; + + case FreeRDP_ComputerName: + return settings->ComputerName; + + case FreeRDP_ConfigPath: + return settings->ConfigPath; + + case FreeRDP_ConnectionFile: + return settings->ConnectionFile; + + case FreeRDP_ContainerName: + return settings->ContainerName; + + case FreeRDP_CspName: + return settings->CspName; + + case FreeRDP_CurrentPath: + return settings->CurrentPath; + + case FreeRDP_Domain: + return settings->Domain; + + case FreeRDP_DrivesToRedirect: + return settings->DrivesToRedirect; + + case FreeRDP_DumpRemoteFxFile: + return settings->DumpRemoteFxFile; + + case FreeRDP_DynamicDSTTimeZoneKeyName: + return settings->DynamicDSTTimeZoneKeyName; + + case FreeRDP_GatewayAcceptedCert: + return settings->GatewayAcceptedCert; + + case FreeRDP_GatewayAccessToken: + return settings->GatewayAccessToken; + + case FreeRDP_GatewayAvdAadtenantid: + return settings->GatewayAvdAadtenantid; + + case FreeRDP_GatewayAvdActivityhint: + return settings->GatewayAvdActivityhint; + + case FreeRDP_GatewayAvdArmpath: + return settings->GatewayAvdArmpath; + + case FreeRDP_GatewayAvdDiagnosticserviceurl: + return settings->GatewayAvdDiagnosticserviceurl; + + case FreeRDP_GatewayAvdGeo: + return settings->GatewayAvdGeo; + + case FreeRDP_GatewayAvdHubdiscoverygeourl: + return settings->GatewayAvdHubdiscoverygeourl; + + case FreeRDP_GatewayAvdWvdEndpointPool: + return settings->GatewayAvdWvdEndpointPool; + + case FreeRDP_GatewayDomain: + return settings->GatewayDomain; + + case FreeRDP_GatewayHostname: + return settings->GatewayHostname; + + case FreeRDP_GatewayHttpExtAuthBearer: + return settings->GatewayHttpExtAuthBearer; + + case FreeRDP_GatewayPassword: + return settings->GatewayPassword; + + case FreeRDP_GatewayUrl: + return settings->GatewayUrl; + + case FreeRDP_GatewayUsername: + return settings->GatewayUsername; + + case FreeRDP_HomePath: + return settings->HomePath; + + case FreeRDP_ImeFileName: + return settings->ImeFileName; + + case FreeRDP_KerberosArmor: + return settings->KerberosArmor; + + case FreeRDP_KerberosCache: + return settings->KerberosCache; + + case FreeRDP_KerberosKdcUrl: + return settings->KerberosKdcUrl; + + case FreeRDP_KerberosKeytab: + return settings->KerberosKeytab; + + case FreeRDP_KerberosLifeTime: + return settings->KerberosLifeTime; + + case FreeRDP_KerberosRealm: + return settings->KerberosRealm; + + case FreeRDP_KerberosRenewableLifeTime: + return settings->KerberosRenewableLifeTime; + + case FreeRDP_KerberosStartTime: + return settings->KerberosStartTime; + + case FreeRDP_KeyboardPipeName: + return settings->KeyboardPipeName; + + case FreeRDP_KeyboardRemappingList: + return settings->KeyboardRemappingList; + + case FreeRDP_NtlmSamFile: + return settings->NtlmSamFile; + + case FreeRDP_Password: + return settings->Password; + + case FreeRDP_PasswordHash: + return settings->PasswordHash; + + case FreeRDP_Pkcs11Module: + return settings->Pkcs11Module; + + case FreeRDP_PkinitAnchors: + return settings->PkinitAnchors; + + case FreeRDP_PlayRemoteFxFile: + return settings->PlayRemoteFxFile; + + case FreeRDP_PreconnectionBlob: + return settings->PreconnectionBlob; + + case FreeRDP_ProxyHostname: + return settings->ProxyHostname; + + case FreeRDP_ProxyPassword: + return settings->ProxyPassword; + + case FreeRDP_ProxyUsername: + return settings->ProxyUsername; + + case FreeRDP_RDP2TCPArgs: + return settings->RDP2TCPArgs; + + case FreeRDP_ReaderName: + return settings->ReaderName; + + case FreeRDP_RedirectionAcceptedCert: + return settings->RedirectionAcceptedCert; + + case FreeRDP_RedirectionDomain: + return settings->RedirectionDomain; + + case FreeRDP_RedirectionTargetFQDN: + return settings->RedirectionTargetFQDN; + + case FreeRDP_RedirectionTargetNetBiosName: + return settings->RedirectionTargetNetBiosName; + + case FreeRDP_RedirectionUsername: + return settings->RedirectionUsername; + + case FreeRDP_RemoteApplicationCmdLine: + return settings->RemoteApplicationCmdLine; + + case FreeRDP_RemoteApplicationFile: + return settings->RemoteApplicationFile; + + case FreeRDP_RemoteApplicationGuid: + return settings->RemoteApplicationGuid; + + case FreeRDP_RemoteApplicationIcon: + return settings->RemoteApplicationIcon; + + case FreeRDP_RemoteApplicationName: + return settings->RemoteApplicationName; + + case FreeRDP_RemoteApplicationProgram: + return settings->RemoteApplicationProgram; + + case FreeRDP_RemoteApplicationWorkingDir: + return settings->RemoteApplicationWorkingDir; + + case FreeRDP_RemoteAssistancePassStub: + return settings->RemoteAssistancePassStub; + + case FreeRDP_RemoteAssistancePassword: + return settings->RemoteAssistancePassword; + + case FreeRDP_RemoteAssistanceRCTicket: + return settings->RemoteAssistanceRCTicket; + + case FreeRDP_RemoteAssistanceSessionId: + return settings->RemoteAssistanceSessionId; + + case FreeRDP_ServerHostname: + return settings->ServerHostname; + + case FreeRDP_ServerLicenseCompanyName: + return settings->ServerLicenseCompanyName; + + case FreeRDP_ServerLicenseProductName: + return settings->ServerLicenseProductName; + + case FreeRDP_ShellWorkingDirectory: + return settings->ShellWorkingDirectory; + + case FreeRDP_SmartcardCertificate: + return settings->SmartcardCertificate; + + case FreeRDP_SmartcardPrivateKey: + return settings->SmartcardPrivateKey; + + case FreeRDP_SspiModule: + return settings->SspiModule; + + case FreeRDP_TargetNetAddress: + return settings->TargetNetAddress; + + case FreeRDP_TerminalDescriptor: + return settings->TerminalDescriptor; + + case FreeRDP_TlsSecretsFile: + return settings->TlsSecretsFile; + + case FreeRDP_TransportDumpFile: + return settings->TransportDumpFile; + + case FreeRDP_UserSpecifiedServerName: + return settings->UserSpecifiedServerName; + + case FreeRDP_Username: + return settings->Username; + + case FreeRDP_WinSCardModule: + return settings->WinSCardModule; + + case FreeRDP_WindowTitle: + return settings->WindowTitle; + + case FreeRDP_WmClass: + return settings->WmClass; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return NULL; + } +} + +char* freerdp_settings_get_string_writable(rdpSettings* settings, FreeRDP_Settings_Keys_String id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + case FreeRDP_AadServerHostname: + return settings->AadServerHostname; + + case FreeRDP_AcceptedCert: + return settings->AcceptedCert; + + case FreeRDP_ActionScript: + return settings->ActionScript; + + case FreeRDP_AllowedTlsCiphers: + return settings->AllowedTlsCiphers; + + case FreeRDP_AlternateShell: + return settings->AlternateShell; + + case FreeRDP_AssistanceFile: + return settings->AssistanceFile; + + case FreeRDP_AuthenticationPackageList: + return settings->AuthenticationPackageList; + + case FreeRDP_AuthenticationServiceClass: + return settings->AuthenticationServiceClass; + + case FreeRDP_BitmapCachePersistFile: + return settings->BitmapCachePersistFile; + + case FreeRDP_CardName: + return settings->CardName; + + case FreeRDP_CertificateAcceptedFingerprints: + return settings->CertificateAcceptedFingerprints; + + case FreeRDP_CertificateName: + return settings->CertificateName; + + case FreeRDP_ClientAddress: + return settings->ClientAddress; + + case FreeRDP_ClientDir: + return settings->ClientDir; + + case FreeRDP_ClientHostname: + return settings->ClientHostname; + + case FreeRDP_ClientProductId: + return settings->ClientProductId; + + case FreeRDP_ClipboardUseSelection: + return settings->ClipboardUseSelection; + + case FreeRDP_ComputerName: + return settings->ComputerName; + + case FreeRDP_ConfigPath: + return settings->ConfigPath; + + case FreeRDP_ConnectionFile: + return settings->ConnectionFile; + + case FreeRDP_ContainerName: + return settings->ContainerName; + + case FreeRDP_CspName: + return settings->CspName; + + case FreeRDP_CurrentPath: + return settings->CurrentPath; + + case FreeRDP_Domain: + return settings->Domain; + + case FreeRDP_DrivesToRedirect: + return settings->DrivesToRedirect; + + case FreeRDP_DumpRemoteFxFile: + return settings->DumpRemoteFxFile; + + case FreeRDP_DynamicDSTTimeZoneKeyName: + return settings->DynamicDSTTimeZoneKeyName; + + case FreeRDP_GatewayAcceptedCert: + return settings->GatewayAcceptedCert; + + case FreeRDP_GatewayAccessToken: + return settings->GatewayAccessToken; + + case FreeRDP_GatewayAvdAadtenantid: + return settings->GatewayAvdAadtenantid; + + case FreeRDP_GatewayAvdActivityhint: + return settings->GatewayAvdActivityhint; + + case FreeRDP_GatewayAvdArmpath: + return settings->GatewayAvdArmpath; + + case FreeRDP_GatewayAvdDiagnosticserviceurl: + return settings->GatewayAvdDiagnosticserviceurl; + + case FreeRDP_GatewayAvdGeo: + return settings->GatewayAvdGeo; + + case FreeRDP_GatewayAvdHubdiscoverygeourl: + return settings->GatewayAvdHubdiscoverygeourl; + + case FreeRDP_GatewayAvdWvdEndpointPool: + return settings->GatewayAvdWvdEndpointPool; + + case FreeRDP_GatewayDomain: + return settings->GatewayDomain; + + case FreeRDP_GatewayHostname: + return settings->GatewayHostname; + + case FreeRDP_GatewayHttpExtAuthBearer: + return settings->GatewayHttpExtAuthBearer; + + case FreeRDP_GatewayPassword: + return settings->GatewayPassword; + + case FreeRDP_GatewayUrl: + return settings->GatewayUrl; + + case FreeRDP_GatewayUsername: + return settings->GatewayUsername; + + case FreeRDP_HomePath: + return settings->HomePath; + + case FreeRDP_ImeFileName: + return settings->ImeFileName; + + case FreeRDP_KerberosArmor: + return settings->KerberosArmor; + + case FreeRDP_KerberosCache: + return settings->KerberosCache; + + case FreeRDP_KerberosKdcUrl: + return settings->KerberosKdcUrl; + + case FreeRDP_KerberosKeytab: + return settings->KerberosKeytab; + + case FreeRDP_KerberosLifeTime: + return settings->KerberosLifeTime; + + case FreeRDP_KerberosRealm: + return settings->KerberosRealm; + + case FreeRDP_KerberosRenewableLifeTime: + return settings->KerberosRenewableLifeTime; + + case FreeRDP_KerberosStartTime: + return settings->KerberosStartTime; + + case FreeRDP_KeyboardPipeName: + return settings->KeyboardPipeName; + + case FreeRDP_KeyboardRemappingList: + return settings->KeyboardRemappingList; + + case FreeRDP_NtlmSamFile: + return settings->NtlmSamFile; + + case FreeRDP_Password: + return settings->Password; + + case FreeRDP_PasswordHash: + return settings->PasswordHash; + + case FreeRDP_Pkcs11Module: + return settings->Pkcs11Module; + + case FreeRDP_PkinitAnchors: + return settings->PkinitAnchors; + + case FreeRDP_PlayRemoteFxFile: + return settings->PlayRemoteFxFile; + + case FreeRDP_PreconnectionBlob: + return settings->PreconnectionBlob; + + case FreeRDP_ProxyHostname: + return settings->ProxyHostname; + + case FreeRDP_ProxyPassword: + return settings->ProxyPassword; + + case FreeRDP_ProxyUsername: + return settings->ProxyUsername; + + case FreeRDP_RDP2TCPArgs: + return settings->RDP2TCPArgs; + + case FreeRDP_ReaderName: + return settings->ReaderName; + + case FreeRDP_RedirectionAcceptedCert: + return settings->RedirectionAcceptedCert; + + case FreeRDP_RedirectionDomain: + return settings->RedirectionDomain; + + case FreeRDP_RedirectionTargetFQDN: + return settings->RedirectionTargetFQDN; + + case FreeRDP_RedirectionTargetNetBiosName: + return settings->RedirectionTargetNetBiosName; + + case FreeRDP_RedirectionUsername: + return settings->RedirectionUsername; + + case FreeRDP_RemoteApplicationCmdLine: + return settings->RemoteApplicationCmdLine; + + case FreeRDP_RemoteApplicationFile: + return settings->RemoteApplicationFile; + + case FreeRDP_RemoteApplicationGuid: + return settings->RemoteApplicationGuid; + + case FreeRDP_RemoteApplicationIcon: + return settings->RemoteApplicationIcon; + + case FreeRDP_RemoteApplicationName: + return settings->RemoteApplicationName; + + case FreeRDP_RemoteApplicationProgram: + return settings->RemoteApplicationProgram; + + case FreeRDP_RemoteApplicationWorkingDir: + return settings->RemoteApplicationWorkingDir; + + case FreeRDP_RemoteAssistancePassStub: + return settings->RemoteAssistancePassStub; + + case FreeRDP_RemoteAssistancePassword: + return settings->RemoteAssistancePassword; + + case FreeRDP_RemoteAssistanceRCTicket: + return settings->RemoteAssistanceRCTicket; + + case FreeRDP_RemoteAssistanceSessionId: + return settings->RemoteAssistanceSessionId; + + case FreeRDP_ServerHostname: + return settings->ServerHostname; + + case FreeRDP_ServerLicenseCompanyName: + return settings->ServerLicenseCompanyName; + + case FreeRDP_ServerLicenseProductName: + return settings->ServerLicenseProductName; + + case FreeRDP_ShellWorkingDirectory: + return settings->ShellWorkingDirectory; + + case FreeRDP_SmartcardCertificate: + return settings->SmartcardCertificate; + + case FreeRDP_SmartcardPrivateKey: + return settings->SmartcardPrivateKey; + + case FreeRDP_SspiModule: + return settings->SspiModule; + + case FreeRDP_TargetNetAddress: + return settings->TargetNetAddress; + + case FreeRDP_TerminalDescriptor: + return settings->TerminalDescriptor; + + case FreeRDP_TlsSecretsFile: + return settings->TlsSecretsFile; + + case FreeRDP_TransportDumpFile: + return settings->TransportDumpFile; + + case FreeRDP_UserSpecifiedServerName: + return settings->UserSpecifiedServerName; + + case FreeRDP_Username: + return settings->Username; + + case FreeRDP_WinSCardModule: + return settings->WinSCardModule; + + case FreeRDP_WindowTitle: + return settings->WindowTitle; + + case FreeRDP_WmClass: + return settings->WmClass; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return NULL; + } +} + +BOOL freerdp_settings_set_string_(rdpSettings* settings, FreeRDP_Settings_Keys_String id, char* val, + size_t len) +{ + union + { + void* v; + const void* cv; + char* c; + const char* cc; + } cnv; + WINPR_ASSERT(settings); + + cnv.cc = val; + + switch (id) + { + case FreeRDP_AadServerHostname: + return update_string_(&settings->AadServerHostname, cnv.c, len); + + case FreeRDP_AcceptedCert: + return update_string_(&settings->AcceptedCert, cnv.c, len); + + case FreeRDP_ActionScript: + return update_string_(&settings->ActionScript, cnv.c, len); + + case FreeRDP_AllowedTlsCiphers: + return update_string_(&settings->AllowedTlsCiphers, cnv.c, len); + + case FreeRDP_AlternateShell: + return update_string_(&settings->AlternateShell, cnv.c, len); + + case FreeRDP_AssistanceFile: + return update_string_(&settings->AssistanceFile, cnv.c, len); + + case FreeRDP_AuthenticationPackageList: + return update_string_(&settings->AuthenticationPackageList, cnv.c, len); + + case FreeRDP_AuthenticationServiceClass: + return update_string_(&settings->AuthenticationServiceClass, cnv.c, len); + + case FreeRDP_BitmapCachePersistFile: + return update_string_(&settings->BitmapCachePersistFile, cnv.c, len); + + case FreeRDP_CardName: + return update_string_(&settings->CardName, cnv.c, len); + + case FreeRDP_CertificateAcceptedFingerprints: + return update_string_(&settings->CertificateAcceptedFingerprints, cnv.c, len); + + case FreeRDP_CertificateName: + return update_string_(&settings->CertificateName, cnv.c, len); + + case FreeRDP_ClientAddress: + return update_string_(&settings->ClientAddress, cnv.c, len); + + case FreeRDP_ClientDir: + return update_string_(&settings->ClientDir, cnv.c, len); + + case FreeRDP_ClientHostname: + return update_string_(&settings->ClientHostname, cnv.c, len); + + case FreeRDP_ClientProductId: + return update_string_(&settings->ClientProductId, cnv.c, len); + + case FreeRDP_ClipboardUseSelection: + return update_string_(&settings->ClipboardUseSelection, cnv.c, len); + + case FreeRDP_ComputerName: + return update_string_(&settings->ComputerName, cnv.c, len); + + case FreeRDP_ConfigPath: + return update_string_(&settings->ConfigPath, cnv.c, len); + + case FreeRDP_ConnectionFile: + return update_string_(&settings->ConnectionFile, cnv.c, len); + + case FreeRDP_ContainerName: + return update_string_(&settings->ContainerName, cnv.c, len); + + case FreeRDP_CspName: + return update_string_(&settings->CspName, cnv.c, len); + + case FreeRDP_CurrentPath: + return update_string_(&settings->CurrentPath, cnv.c, len); + + case FreeRDP_Domain: + return update_string_(&settings->Domain, cnv.c, len); + + case FreeRDP_DrivesToRedirect: + return update_string_(&settings->DrivesToRedirect, cnv.c, len); + + case FreeRDP_DumpRemoteFxFile: + return update_string_(&settings->DumpRemoteFxFile, cnv.c, len); + + case FreeRDP_DynamicDSTTimeZoneKeyName: + return update_string_(&settings->DynamicDSTTimeZoneKeyName, cnv.c, len); + + case FreeRDP_GatewayAcceptedCert: + return update_string_(&settings->GatewayAcceptedCert, cnv.c, len); + + case FreeRDP_GatewayAccessToken: + return update_string_(&settings->GatewayAccessToken, cnv.c, len); + + case FreeRDP_GatewayAvdAadtenantid: + return update_string_(&settings->GatewayAvdAadtenantid, cnv.c, len); + + case FreeRDP_GatewayAvdActivityhint: + return update_string_(&settings->GatewayAvdActivityhint, cnv.c, len); + + case FreeRDP_GatewayAvdArmpath: + return update_string_(&settings->GatewayAvdArmpath, cnv.c, len); + + case FreeRDP_GatewayAvdDiagnosticserviceurl: + return update_string_(&settings->GatewayAvdDiagnosticserviceurl, cnv.c, len); + + case FreeRDP_GatewayAvdGeo: + return update_string_(&settings->GatewayAvdGeo, cnv.c, len); + + case FreeRDP_GatewayAvdHubdiscoverygeourl: + return update_string_(&settings->GatewayAvdHubdiscoverygeourl, cnv.c, len); + + case FreeRDP_GatewayAvdWvdEndpointPool: + return update_string_(&settings->GatewayAvdWvdEndpointPool, cnv.c, len); + + case FreeRDP_GatewayDomain: + return update_string_(&settings->GatewayDomain, cnv.c, len); + + case FreeRDP_GatewayHostname: + return update_string_(&settings->GatewayHostname, cnv.c, len); + + case FreeRDP_GatewayHttpExtAuthBearer: + return update_string_(&settings->GatewayHttpExtAuthBearer, cnv.c, len); + + case FreeRDP_GatewayPassword: + return update_string_(&settings->GatewayPassword, cnv.c, len); + + case FreeRDP_GatewayUrl: + return update_string_(&settings->GatewayUrl, cnv.c, len); + + case FreeRDP_GatewayUsername: + return update_string_(&settings->GatewayUsername, cnv.c, len); + + case FreeRDP_HomePath: + return update_string_(&settings->HomePath, cnv.c, len); + + case FreeRDP_ImeFileName: + return update_string_(&settings->ImeFileName, cnv.c, len); + + case FreeRDP_KerberosArmor: + return update_string_(&settings->KerberosArmor, cnv.c, len); + + case FreeRDP_KerberosCache: + return update_string_(&settings->KerberosCache, cnv.c, len); + + case FreeRDP_KerberosKdcUrl: + return update_string_(&settings->KerberosKdcUrl, cnv.c, len); + + case FreeRDP_KerberosKeytab: + return update_string_(&settings->KerberosKeytab, cnv.c, len); + + case FreeRDP_KerberosLifeTime: + return update_string_(&settings->KerberosLifeTime, cnv.c, len); + + case FreeRDP_KerberosRealm: + return update_string_(&settings->KerberosRealm, cnv.c, len); + + case FreeRDP_KerberosRenewableLifeTime: + return update_string_(&settings->KerberosRenewableLifeTime, cnv.c, len); + + case FreeRDP_KerberosStartTime: + return update_string_(&settings->KerberosStartTime, cnv.c, len); + + case FreeRDP_KeyboardPipeName: + return update_string_(&settings->KeyboardPipeName, cnv.c, len); + + case FreeRDP_KeyboardRemappingList: + return update_string_(&settings->KeyboardRemappingList, cnv.c, len); + + case FreeRDP_NtlmSamFile: + return update_string_(&settings->NtlmSamFile, cnv.c, len); + + case FreeRDP_Password: + return update_string_(&settings->Password, cnv.c, len); + + case FreeRDP_PasswordHash: + return update_string_(&settings->PasswordHash, cnv.c, len); + + case FreeRDP_Pkcs11Module: + return update_string_(&settings->Pkcs11Module, cnv.c, len); + + case FreeRDP_PkinitAnchors: + return update_string_(&settings->PkinitAnchors, cnv.c, len); + + case FreeRDP_PlayRemoteFxFile: + return update_string_(&settings->PlayRemoteFxFile, cnv.c, len); + + case FreeRDP_PreconnectionBlob: + return update_string_(&settings->PreconnectionBlob, cnv.c, len); + + case FreeRDP_ProxyHostname: + return update_string_(&settings->ProxyHostname, cnv.c, len); + + case FreeRDP_ProxyPassword: + return update_string_(&settings->ProxyPassword, cnv.c, len); + + case FreeRDP_ProxyUsername: + return update_string_(&settings->ProxyUsername, cnv.c, len); + + case FreeRDP_RDP2TCPArgs: + return update_string_(&settings->RDP2TCPArgs, cnv.c, len); + + case FreeRDP_ReaderName: + return update_string_(&settings->ReaderName, cnv.c, len); + + case FreeRDP_RedirectionAcceptedCert: + return update_string_(&settings->RedirectionAcceptedCert, cnv.c, len); + + case FreeRDP_RedirectionDomain: + return update_string_(&settings->RedirectionDomain, cnv.c, len); + + case FreeRDP_RedirectionTargetFQDN: + return update_string_(&settings->RedirectionTargetFQDN, cnv.c, len); + + case FreeRDP_RedirectionTargetNetBiosName: + return update_string_(&settings->RedirectionTargetNetBiosName, cnv.c, len); + + case FreeRDP_RedirectionUsername: + return update_string_(&settings->RedirectionUsername, cnv.c, len); + + case FreeRDP_RemoteApplicationCmdLine: + return update_string_(&settings->RemoteApplicationCmdLine, cnv.c, len); + + case FreeRDP_RemoteApplicationFile: + return update_string_(&settings->RemoteApplicationFile, cnv.c, len); + + case FreeRDP_RemoteApplicationGuid: + return update_string_(&settings->RemoteApplicationGuid, cnv.c, len); + + case FreeRDP_RemoteApplicationIcon: + return update_string_(&settings->RemoteApplicationIcon, cnv.c, len); + + case FreeRDP_RemoteApplicationName: + return update_string_(&settings->RemoteApplicationName, cnv.c, len); + + case FreeRDP_RemoteApplicationProgram: + return update_string_(&settings->RemoteApplicationProgram, cnv.c, len); + + case FreeRDP_RemoteApplicationWorkingDir: + return update_string_(&settings->RemoteApplicationWorkingDir, cnv.c, len); + + case FreeRDP_RemoteAssistancePassStub: + return update_string_(&settings->RemoteAssistancePassStub, cnv.c, len); + + case FreeRDP_RemoteAssistancePassword: + return update_string_(&settings->RemoteAssistancePassword, cnv.c, len); + + case FreeRDP_RemoteAssistanceRCTicket: + return update_string_(&settings->RemoteAssistanceRCTicket, cnv.c, len); + + case FreeRDP_RemoteAssistanceSessionId: + return update_string_(&settings->RemoteAssistanceSessionId, cnv.c, len); + + case FreeRDP_ServerHostname: + return update_string_(&settings->ServerHostname, cnv.c, len); + + case FreeRDP_ServerLicenseCompanyName: + return update_string_(&settings->ServerLicenseCompanyName, cnv.c, len); + + case FreeRDP_ServerLicenseProductName: + return update_string_(&settings->ServerLicenseProductName, cnv.c, len); + + case FreeRDP_ShellWorkingDirectory: + return update_string_(&settings->ShellWorkingDirectory, cnv.c, len); + + case FreeRDP_SmartcardCertificate: + return update_string_(&settings->SmartcardCertificate, cnv.c, len); + + case FreeRDP_SmartcardPrivateKey: + return update_string_(&settings->SmartcardPrivateKey, cnv.c, len); + + case FreeRDP_SspiModule: + return update_string_(&settings->SspiModule, cnv.c, len); + + case FreeRDP_TargetNetAddress: + return update_string_(&settings->TargetNetAddress, cnv.c, len); + + case FreeRDP_TerminalDescriptor: + return update_string_(&settings->TerminalDescriptor, cnv.c, len); + + case FreeRDP_TlsSecretsFile: + return update_string_(&settings->TlsSecretsFile, cnv.c, len); + + case FreeRDP_TransportDumpFile: + return update_string_(&settings->TransportDumpFile, cnv.c, len); + + case FreeRDP_UserSpecifiedServerName: + return update_string_(&settings->UserSpecifiedServerName, cnv.c, len); + + case FreeRDP_Username: + return update_string_(&settings->Username, cnv.c, len); + + case FreeRDP_WinSCardModule: + return update_string_(&settings->WinSCardModule, cnv.c, len); + + case FreeRDP_WindowTitle: + return update_string_(&settings->WindowTitle, cnv.c, len); + + case FreeRDP_WmClass: + return update_string_(&settings->WmClass, cnv.c, len); + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} + +BOOL freerdp_settings_set_string_len(rdpSettings* settings, FreeRDP_Settings_Keys_String id, + const char* val, size_t len) +{ + return freerdp_settings_set_string_copy_(settings, id, val, len, TRUE); +} + +BOOL freerdp_settings_set_string(rdpSettings* settings, FreeRDP_Settings_Keys_String id, + const char* val) +{ + size_t len = 0; + if (val) + len = strlen(val); + return freerdp_settings_set_string_copy_(settings, id, val, len, TRUE); +} + +BOOL freerdp_settings_set_string_copy_(rdpSettings* settings, FreeRDP_Settings_Keys_String id, + const char* val, size_t len, BOOL cleanup) +{ + union + { + void* v; + const void* cv; + char* c; + const char* cc; + } cnv; + WINPR_ASSERT(settings); + + cnv.cc = val; + + switch (id) + { + case FreeRDP_AadServerHostname: + return update_string_copy_(&settings->AadServerHostname, cnv.cc, len, cleanup); + + case FreeRDP_AcceptedCert: + return update_string_copy_(&settings->AcceptedCert, cnv.cc, len, cleanup); + + case FreeRDP_ActionScript: + return update_string_copy_(&settings->ActionScript, cnv.cc, len, cleanup); + + case FreeRDP_AllowedTlsCiphers: + return update_string_copy_(&settings->AllowedTlsCiphers, cnv.cc, len, cleanup); + + case FreeRDP_AlternateShell: + return update_string_copy_(&settings->AlternateShell, cnv.cc, len, cleanup); + + case FreeRDP_AssistanceFile: + return update_string_copy_(&settings->AssistanceFile, cnv.cc, len, cleanup); + + case FreeRDP_AuthenticationPackageList: + return update_string_copy_(&settings->AuthenticationPackageList, cnv.cc, len, cleanup); + + case FreeRDP_AuthenticationServiceClass: + return update_string_copy_(&settings->AuthenticationServiceClass, cnv.cc, len, cleanup); + + case FreeRDP_BitmapCachePersistFile: + return update_string_copy_(&settings->BitmapCachePersistFile, cnv.cc, len, cleanup); + + case FreeRDP_CardName: + return update_string_copy_(&settings->CardName, cnv.cc, len, cleanup); + + case FreeRDP_CertificateAcceptedFingerprints: + return update_string_copy_(&settings->CertificateAcceptedFingerprints, cnv.cc, len, + cleanup); + + case FreeRDP_CertificateName: + return update_string_copy_(&settings->CertificateName, cnv.cc, len, cleanup); + + case FreeRDP_ClientAddress: + return update_string_copy_(&settings->ClientAddress, cnv.cc, len, cleanup); + + case FreeRDP_ClientDir: + return update_string_copy_(&settings->ClientDir, cnv.cc, len, cleanup); + + case FreeRDP_ClientHostname: + return update_string_copy_(&settings->ClientHostname, cnv.cc, len, cleanup); + + case FreeRDP_ClientProductId: + return update_string_copy_(&settings->ClientProductId, cnv.cc, len, cleanup); + + case FreeRDP_ClipboardUseSelection: + return update_string_copy_(&settings->ClipboardUseSelection, cnv.cc, len, cleanup); + + case FreeRDP_ComputerName: + return update_string_copy_(&settings->ComputerName, cnv.cc, len, cleanup); + + case FreeRDP_ConfigPath: + return update_string_copy_(&settings->ConfigPath, cnv.cc, len, cleanup); + + case FreeRDP_ConnectionFile: + return update_string_copy_(&settings->ConnectionFile, cnv.cc, len, cleanup); + + case FreeRDP_ContainerName: + return update_string_copy_(&settings->ContainerName, cnv.cc, len, cleanup); + + case FreeRDP_CspName: + return update_string_copy_(&settings->CspName, cnv.cc, len, cleanup); + + case FreeRDP_CurrentPath: + return update_string_copy_(&settings->CurrentPath, cnv.cc, len, cleanup); + + case FreeRDP_Domain: + return update_string_copy_(&settings->Domain, cnv.cc, len, cleanup); + + case FreeRDP_DrivesToRedirect: + return update_string_copy_(&settings->DrivesToRedirect, cnv.cc, len, cleanup); + + case FreeRDP_DumpRemoteFxFile: + return update_string_copy_(&settings->DumpRemoteFxFile, cnv.cc, len, cleanup); + + case FreeRDP_DynamicDSTTimeZoneKeyName: + return update_string_copy_(&settings->DynamicDSTTimeZoneKeyName, cnv.cc, len, cleanup); + + case FreeRDP_GatewayAcceptedCert: + return update_string_copy_(&settings->GatewayAcceptedCert, cnv.cc, len, cleanup); + + case FreeRDP_GatewayAccessToken: + return update_string_copy_(&settings->GatewayAccessToken, cnv.cc, len, cleanup); + + case FreeRDP_GatewayAvdAadtenantid: + return update_string_copy_(&settings->GatewayAvdAadtenantid, cnv.cc, len, cleanup); + + case FreeRDP_GatewayAvdActivityhint: + return update_string_copy_(&settings->GatewayAvdActivityhint, cnv.cc, len, cleanup); + + case FreeRDP_GatewayAvdArmpath: + return update_string_copy_(&settings->GatewayAvdArmpath, cnv.cc, len, cleanup); + + case FreeRDP_GatewayAvdDiagnosticserviceurl: + return update_string_copy_(&settings->GatewayAvdDiagnosticserviceurl, cnv.cc, len, + cleanup); + + case FreeRDP_GatewayAvdGeo: + return update_string_copy_(&settings->GatewayAvdGeo, cnv.cc, len, cleanup); + + case FreeRDP_GatewayAvdHubdiscoverygeourl: + return update_string_copy_(&settings->GatewayAvdHubdiscoverygeourl, cnv.cc, len, + cleanup); + + case FreeRDP_GatewayAvdWvdEndpointPool: + return update_string_copy_(&settings->GatewayAvdWvdEndpointPool, cnv.cc, len, cleanup); + + case FreeRDP_GatewayDomain: + return update_string_copy_(&settings->GatewayDomain, cnv.cc, len, cleanup); + + case FreeRDP_GatewayHostname: + return update_string_copy_(&settings->GatewayHostname, cnv.cc, len, cleanup); + + case FreeRDP_GatewayHttpExtAuthBearer: + return update_string_copy_(&settings->GatewayHttpExtAuthBearer, cnv.cc, len, cleanup); + + case FreeRDP_GatewayPassword: + return update_string_copy_(&settings->GatewayPassword, cnv.cc, len, cleanup); + + case FreeRDP_GatewayUrl: + return update_string_copy_(&settings->GatewayUrl, cnv.cc, len, cleanup); + + case FreeRDP_GatewayUsername: + return update_string_copy_(&settings->GatewayUsername, cnv.cc, len, cleanup); + + case FreeRDP_HomePath: + return update_string_copy_(&settings->HomePath, cnv.cc, len, cleanup); + + case FreeRDP_ImeFileName: + return update_string_copy_(&settings->ImeFileName, cnv.cc, len, cleanup); + + case FreeRDP_KerberosArmor: + return update_string_copy_(&settings->KerberosArmor, cnv.cc, len, cleanup); + + case FreeRDP_KerberosCache: + return update_string_copy_(&settings->KerberosCache, cnv.cc, len, cleanup); + + case FreeRDP_KerberosKdcUrl: + return update_string_copy_(&settings->KerberosKdcUrl, cnv.cc, len, cleanup); + + case FreeRDP_KerberosKeytab: + return update_string_copy_(&settings->KerberosKeytab, cnv.cc, len, cleanup); + + case FreeRDP_KerberosLifeTime: + return update_string_copy_(&settings->KerberosLifeTime, cnv.cc, len, cleanup); + + case FreeRDP_KerberosRealm: + return update_string_copy_(&settings->KerberosRealm, cnv.cc, len, cleanup); + + case FreeRDP_KerberosRenewableLifeTime: + return update_string_copy_(&settings->KerberosRenewableLifeTime, cnv.cc, len, cleanup); + + case FreeRDP_KerberosStartTime: + return update_string_copy_(&settings->KerberosStartTime, cnv.cc, len, cleanup); + + case FreeRDP_KeyboardPipeName: + return update_string_copy_(&settings->KeyboardPipeName, cnv.cc, len, cleanup); + + case FreeRDP_KeyboardRemappingList: + return update_string_copy_(&settings->KeyboardRemappingList, cnv.cc, len, cleanup); + + case FreeRDP_NtlmSamFile: + return update_string_copy_(&settings->NtlmSamFile, cnv.cc, len, cleanup); + + case FreeRDP_Password: + return update_string_copy_(&settings->Password, cnv.cc, len, cleanup); + + case FreeRDP_PasswordHash: + return update_string_copy_(&settings->PasswordHash, cnv.cc, len, cleanup); + + case FreeRDP_Pkcs11Module: + return update_string_copy_(&settings->Pkcs11Module, cnv.cc, len, cleanup); + + case FreeRDP_PkinitAnchors: + return update_string_copy_(&settings->PkinitAnchors, cnv.cc, len, cleanup); + + case FreeRDP_PlayRemoteFxFile: + return update_string_copy_(&settings->PlayRemoteFxFile, cnv.cc, len, cleanup); + + case FreeRDP_PreconnectionBlob: + return update_string_copy_(&settings->PreconnectionBlob, cnv.cc, len, cleanup); + + case FreeRDP_ProxyHostname: + return update_string_copy_(&settings->ProxyHostname, cnv.cc, len, cleanup); + + case FreeRDP_ProxyPassword: + return update_string_copy_(&settings->ProxyPassword, cnv.cc, len, cleanup); + + case FreeRDP_ProxyUsername: + return update_string_copy_(&settings->ProxyUsername, cnv.cc, len, cleanup); + + case FreeRDP_RDP2TCPArgs: + return update_string_copy_(&settings->RDP2TCPArgs, cnv.cc, len, cleanup); + + case FreeRDP_ReaderName: + return update_string_copy_(&settings->ReaderName, cnv.cc, len, cleanup); + + case FreeRDP_RedirectionAcceptedCert: + return update_string_copy_(&settings->RedirectionAcceptedCert, cnv.cc, len, cleanup); + + case FreeRDP_RedirectionDomain: + return update_string_copy_(&settings->RedirectionDomain, cnv.cc, len, cleanup); + + case FreeRDP_RedirectionTargetFQDN: + return update_string_copy_(&settings->RedirectionTargetFQDN, cnv.cc, len, cleanup); + + case FreeRDP_RedirectionTargetNetBiosName: + return update_string_copy_(&settings->RedirectionTargetNetBiosName, cnv.cc, len, + cleanup); + + case FreeRDP_RedirectionUsername: + return update_string_copy_(&settings->RedirectionUsername, cnv.cc, len, cleanup); + + case FreeRDP_RemoteApplicationCmdLine: + return update_string_copy_(&settings->RemoteApplicationCmdLine, cnv.cc, len, cleanup); + + case FreeRDP_RemoteApplicationFile: + return update_string_copy_(&settings->RemoteApplicationFile, cnv.cc, len, cleanup); + + case FreeRDP_RemoteApplicationGuid: + return update_string_copy_(&settings->RemoteApplicationGuid, cnv.cc, len, cleanup); + + case FreeRDP_RemoteApplicationIcon: + return update_string_copy_(&settings->RemoteApplicationIcon, cnv.cc, len, cleanup); + + case FreeRDP_RemoteApplicationName: + return update_string_copy_(&settings->RemoteApplicationName, cnv.cc, len, cleanup); + + case FreeRDP_RemoteApplicationProgram: + return update_string_copy_(&settings->RemoteApplicationProgram, cnv.cc, len, cleanup); + + case FreeRDP_RemoteApplicationWorkingDir: + return update_string_copy_(&settings->RemoteApplicationWorkingDir, cnv.cc, len, + cleanup); + + case FreeRDP_RemoteAssistancePassStub: + return update_string_copy_(&settings->RemoteAssistancePassStub, cnv.cc, len, cleanup); + + case FreeRDP_RemoteAssistancePassword: + return update_string_copy_(&settings->RemoteAssistancePassword, cnv.cc, len, cleanup); + + case FreeRDP_RemoteAssistanceRCTicket: + return update_string_copy_(&settings->RemoteAssistanceRCTicket, cnv.cc, len, cleanup); + + case FreeRDP_RemoteAssistanceSessionId: + return update_string_copy_(&settings->RemoteAssistanceSessionId, cnv.cc, len, cleanup); + + case FreeRDP_ServerHostname: + return update_string_copy_(&settings->ServerHostname, cnv.cc, len, cleanup); + + case FreeRDP_ServerLicenseCompanyName: + return update_string_copy_(&settings->ServerLicenseCompanyName, cnv.cc, len, cleanup); + + case FreeRDP_ServerLicenseProductName: + return update_string_copy_(&settings->ServerLicenseProductName, cnv.cc, len, cleanup); + + case FreeRDP_ShellWorkingDirectory: + return update_string_copy_(&settings->ShellWorkingDirectory, cnv.cc, len, cleanup); + + case FreeRDP_SmartcardCertificate: + return update_string_copy_(&settings->SmartcardCertificate, cnv.cc, len, cleanup); + + case FreeRDP_SmartcardPrivateKey: + return update_string_copy_(&settings->SmartcardPrivateKey, cnv.cc, len, cleanup); + + case FreeRDP_SspiModule: + return update_string_copy_(&settings->SspiModule, cnv.cc, len, cleanup); + + case FreeRDP_TargetNetAddress: + return update_string_copy_(&settings->TargetNetAddress, cnv.cc, len, cleanup); + + case FreeRDP_TerminalDescriptor: + return update_string_copy_(&settings->TerminalDescriptor, cnv.cc, len, cleanup); + + case FreeRDP_TlsSecretsFile: + return update_string_copy_(&settings->TlsSecretsFile, cnv.cc, len, cleanup); + + case FreeRDP_TransportDumpFile: + return update_string_copy_(&settings->TransportDumpFile, cnv.cc, len, cleanup); + + case FreeRDP_UserSpecifiedServerName: + return update_string_copy_(&settings->UserSpecifiedServerName, cnv.cc, len, cleanup); + + case FreeRDP_Username: + return update_string_copy_(&settings->Username, cnv.cc, len, cleanup); + + case FreeRDP_WinSCardModule: + return update_string_copy_(&settings->WinSCardModule, cnv.cc, len, cleanup); + + case FreeRDP_WindowTitle: + return update_string_copy_(&settings->WindowTitle, cnv.cc, len, cleanup); + + case FreeRDP_WmClass: + return update_string_copy_(&settings->WmClass, cnv.cc, len, cleanup); + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} + +void* freerdp_settings_get_pointer_writable(rdpSettings* settings, FreeRDP_Settings_Keys_Pointer id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + case FreeRDP_BitmapCacheV2CellInfo: + return settings->BitmapCacheV2CellInfo; + + case FreeRDP_ChannelDefArray: + return settings->ChannelDefArray; + + case FreeRDP_ClientAutoReconnectCookie: + return settings->ClientAutoReconnectCookie; + + case FreeRDP_ClientRandom: + return settings->ClientRandom; + + case FreeRDP_ClientTimeZone: + return settings->ClientTimeZone; + + case FreeRDP_DeviceArray: + return settings->DeviceArray; + + case FreeRDP_DynamicChannelArray: + return settings->DynamicChannelArray; + + case FreeRDP_FragCache: + return settings->FragCache; + + case FreeRDP_GlyphCache: + return settings->GlyphCache; + + case FreeRDP_LoadBalanceInfo: + return settings->LoadBalanceInfo; + + case FreeRDP_MonitorDefArray: + return settings->MonitorDefArray; + + case FreeRDP_MonitorIds: + return settings->MonitorIds; + + case FreeRDP_OrderSupport: + return settings->OrderSupport; + + case FreeRDP_Password51: + return settings->Password51; + + case FreeRDP_RdpServerCertificate: + return settings->RdpServerCertificate; + + case FreeRDP_RdpServerRsaKey: + return settings->RdpServerRsaKey; + + case FreeRDP_ReceivedCapabilities: + return settings->ReceivedCapabilities; + + case FreeRDP_ReceivedCapabilityData: + return settings->ReceivedCapabilityData; + + case FreeRDP_ReceivedCapabilityDataSizes: + return settings->ReceivedCapabilityDataSizes; + + case FreeRDP_RedirectionGuid: + return settings->RedirectionGuid; + + case FreeRDP_RedirectionPassword: + return settings->RedirectionPassword; + + case FreeRDP_RedirectionTargetCertificate: + return settings->RedirectionTargetCertificate; + + case FreeRDP_RedirectionTsvUrl: + return settings->RedirectionTsvUrl; + + case FreeRDP_ServerAutoReconnectCookie: + return settings->ServerAutoReconnectCookie; + + case FreeRDP_ServerCertificate: + return settings->ServerCertificate; + + case FreeRDP_ServerLicenseProductIssuers: + return settings->ServerLicenseProductIssuers; + + case FreeRDP_ServerRandom: + return settings->ServerRandom; + + case FreeRDP_StaticChannelArray: + return settings->StaticChannelArray; + + case FreeRDP_TargetNetAddresses: + return settings->TargetNetAddresses; + + case FreeRDP_TargetNetPorts: + return settings->TargetNetPorts; + + case FreeRDP_instance: + return settings->instance; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + WINPR_ASSERT(FALSE); + return NULL; + } +} + +BOOL freerdp_settings_set_pointer(rdpSettings* settings, FreeRDP_Settings_Keys_Pointer id, + const void* val) +{ + union + { + void* v; + const void* cv; + } cnv; + WINPR_ASSERT(settings); + + cnv.cv = val; + + switch (id) + { + case FreeRDP_BitmapCacheV2CellInfo: + settings->BitmapCacheV2CellInfo = cnv.v; + break; + + case FreeRDP_ChannelDefArray: + settings->ChannelDefArray = cnv.v; + break; + + case FreeRDP_ClientAutoReconnectCookie: + settings->ClientAutoReconnectCookie = cnv.v; + break; + + case FreeRDP_ClientRandom: + settings->ClientRandom = cnv.v; + break; + + case FreeRDP_ClientTimeZone: + settings->ClientTimeZone = cnv.v; + break; + + case FreeRDP_DeviceArray: + settings->DeviceArray = cnv.v; + break; + + case FreeRDP_DynamicChannelArray: + settings->DynamicChannelArray = cnv.v; + break; + + case FreeRDP_FragCache: + settings->FragCache = cnv.v; + break; + + case FreeRDP_GlyphCache: + settings->GlyphCache = cnv.v; + break; + + case FreeRDP_LoadBalanceInfo: + settings->LoadBalanceInfo = cnv.v; + break; + + case FreeRDP_MonitorDefArray: + settings->MonitorDefArray = cnv.v; + break; + + case FreeRDP_MonitorIds: + settings->MonitorIds = cnv.v; + break; + + case FreeRDP_OrderSupport: + settings->OrderSupport = cnv.v; + break; + + case FreeRDP_Password51: + settings->Password51 = cnv.v; + break; + + case FreeRDP_RdpServerCertificate: + settings->RdpServerCertificate = cnv.v; + break; + + case FreeRDP_RdpServerRsaKey: + settings->RdpServerRsaKey = cnv.v; + break; + + case FreeRDP_ReceivedCapabilities: + settings->ReceivedCapabilities = cnv.v; + break; + + case FreeRDP_ReceivedCapabilityData: + settings->ReceivedCapabilityData = cnv.v; + break; + + case FreeRDP_ReceivedCapabilityDataSizes: + settings->ReceivedCapabilityDataSizes = cnv.v; + break; + + case FreeRDP_RedirectionGuid: + settings->RedirectionGuid = cnv.v; + break; + + case FreeRDP_RedirectionPassword: + settings->RedirectionPassword = cnv.v; + break; + + case FreeRDP_RedirectionTargetCertificate: + settings->RedirectionTargetCertificate = cnv.v; + break; + + case FreeRDP_RedirectionTsvUrl: + settings->RedirectionTsvUrl = cnv.v; + break; + + case FreeRDP_ServerAutoReconnectCookie: + settings->ServerAutoReconnectCookie = cnv.v; + break; + + case FreeRDP_ServerCertificate: + settings->ServerCertificate = cnv.v; + break; + + case FreeRDP_ServerLicenseProductIssuers: + settings->ServerLicenseProductIssuers = cnv.v; + break; + + case FreeRDP_ServerRandom: + settings->ServerRandom = cnv.v; + break; + + case FreeRDP_StaticChannelArray: + settings->StaticChannelArray = cnv.v; + break; + + case FreeRDP_TargetNetAddresses: + settings->TargetNetAddresses = cnv.v; + break; + + case FreeRDP_TargetNetPorts: + settings->TargetNetPorts = cnv.v; + break; + + case FreeRDP_instance: + settings->instance = cnv.v; + break; + + default: + WLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, + freerdp_settings_get_name_for_key(id), + freerdp_settings_get_type_name_for_key(id)); + return FALSE; + } + return TRUE; +} diff --git a/libfreerdp/common/settings_str.c b/libfreerdp/common/settings_str.c new file mode 100644 index 0000000..5072951 --- /dev/null +++ b/libfreerdp/common/settings_str.c @@ -0,0 +1,477 @@ +/* Generated by */ + +#include "../core/settings.h" +#include "settings_str.h" + +BOOL freerdp_settings_clone_keys(rdpSettings* dst, const rdpSettings* src) +{ + WINPR_ASSERT(dst); + WINPR_ASSERT(src); + + for (size_t x = 0; x < ARRAYSIZE(settings_map); x++) + { + const struct settings_str_entry* cur = &settings_map[x]; + switch (cur->type) + { + case FREERDP_SETTINGS_TYPE_BOOL: /* bool */ + { + BOOL sval = freerdp_settings_get_bool(src, (FreeRDP_Settings_Keys_Bool)cur->id); + if (!freerdp_settings_set_bool(dst, (FreeRDP_Settings_Keys_Bool)cur->id, sval)) + return FALSE; + } + break; + case FREERDP_SETTINGS_TYPE_UINT16: /* UINT16 */ + { + UINT16 sval = + freerdp_settings_get_uint16(src, (FreeRDP_Settings_Keys_UInt16)cur->id); + if (!freerdp_settings_set_uint16(dst, (FreeRDP_Settings_Keys_UInt16)cur->id, sval)) + return FALSE; + } + break; + case FREERDP_SETTINGS_TYPE_INT16: /* INT16 */ + { + INT16 sval = freerdp_settings_get_int16(src, (FreeRDP_Settings_Keys_Int16)cur->id); + if (!freerdp_settings_set_int16(dst, (FreeRDP_Settings_Keys_Int16)cur->id, sval)) + return FALSE; + } + break; + case FREERDP_SETTINGS_TYPE_UINT32: /* UINT32 */ + { + UINT32 sval = + freerdp_settings_get_uint32(src, (FreeRDP_Settings_Keys_UInt32)cur->id); + if (!freerdp_settings_set_uint32(dst, (FreeRDP_Settings_Keys_UInt32)cur->id, sval)) + return FALSE; + } + break; + case FREERDP_SETTINGS_TYPE_INT32: /* INT32 */ + { + INT32 sval = freerdp_settings_get_int32(src, (FreeRDP_Settings_Keys_Int32)cur->id); + if (!freerdp_settings_set_int32(dst, (FreeRDP_Settings_Keys_Int32)cur->id, sval)) + return FALSE; + } + break; + case FREERDP_SETTINGS_TYPE_UINT64: /* UINT64 */ + { + UINT64 sval = + freerdp_settings_get_uint64(src, (FreeRDP_Settings_Keys_UInt64)cur->id); + if (!freerdp_settings_set_uint64(dst, (FreeRDP_Settings_Keys_UInt64)cur->id, sval)) + return FALSE; + } + break; + case FREERDP_SETTINGS_TYPE_INT64: /* INT64 */ + { + INT64 sval = freerdp_settings_get_int64(src, (FreeRDP_Settings_Keys_Int64)cur->id); + if (!freerdp_settings_set_int64(dst, (FreeRDP_Settings_Keys_Int64)cur->id, sval)) + return FALSE; + } + break; + case FREERDP_SETTINGS_TYPE_STRING: /* strings */ + { + const char* sval = + freerdp_settings_get_string(src, (FreeRDP_Settings_Keys_String)cur->id); + size_t len = 0; + if (sval) + len = strlen(sval); + if (!freerdp_settings_set_string_copy_(dst, (FreeRDP_Settings_Keys_String)cur->id, + sval, len, FALSE)) + return FALSE; + } + break; + case FREERDP_SETTINGS_TYPE_POINTER: /* pointer */ + { + const void* sval = + freerdp_settings_get_pointer(src, (FreeRDP_Settings_Keys_Pointer)cur->id); + if (!freerdp_settings_set_pointer(dst, (FreeRDP_Settings_Keys_Pointer)cur->id, + sval)) + return FALSE; + } + break; + } + } + return TRUE; +} + +BOOL freerdp_settings_print_diff(wLog* log, DWORD level, const rdpSettings* settings, + const rdpSettings* other) +{ + BOOL rc = FALSE; + + WINPR_ASSERT(log); + WINPR_ASSERT(settings); + WINPR_ASSERT(other); + + for (size_t x = 0; x < ARRAYSIZE(settings_map); x++) + { + const struct settings_str_entry* cur = &settings_map[x]; + switch (cur->type) + { + case FREERDP_SETTINGS_TYPE_BOOL: /* bool */ + { + BOOL sval = + freerdp_settings_get_bool(settings, (FreeRDP_Settings_Keys_Bool)cur->id); + BOOL cval = freerdp_settings_get_bool(other, (FreeRDP_Settings_Keys_Bool)cur->id); + if (sval != cval) + { + rc = TRUE; + WLog_Print(log, level, "%s [BOOL]: %s -> %s", cur->str, sval ? "TRUE" : "FALSE", + cval ? "TRUE" : "FALSE"); + } + } + break; + case FREERDP_SETTINGS_TYPE_UINT16: /* UINT16 */ + { + UINT16 sval = + freerdp_settings_get_uint16(settings, (FreeRDP_Settings_Keys_UInt16)cur->id); + UINT16 cval = + freerdp_settings_get_uint16(other, (FreeRDP_Settings_Keys_UInt16)cur->id); + if (sval != cval) + { + rc = TRUE; + WLog_Print(log, level, "%s [UINT16]: %" PRIu16 " -> %" PRIu16, cur->str, sval, + cval); + } + } + break; + case FREERDP_SETTINGS_TYPE_INT16: /* INT16 */ + { + INT16 sval = + freerdp_settings_get_int16(settings, (FreeRDP_Settings_Keys_Int16)cur->id); + INT16 cval = + freerdp_settings_get_int16(other, (FreeRDP_Settings_Keys_Int16)cur->id); + if (sval != cval) + { + rc = TRUE; + WLog_Print(log, level, "%s [INT16]: %" PRId16 " -> %" PRId16, cur->str, sval, + cval); + } + } + break; + case FREERDP_SETTINGS_TYPE_UINT32: /* UINT32 */ + { + UINT32 sval = + freerdp_settings_get_uint32(settings, (FreeRDP_Settings_Keys_UInt32)cur->id); + UINT32 cval = + freerdp_settings_get_uint32(other, (FreeRDP_Settings_Keys_UInt32)cur->id); + if (sval != cval) + { + rc = TRUE; + WLog_Print(log, level, "%s [UINT32]: %" PRIu32 " -> %" PRIu32, cur->str, sval, + cval); + } + } + break; + case FREERDP_SETTINGS_TYPE_INT32: /* INT32 */ + { + INT32 sval = + freerdp_settings_get_int32(settings, (FreeRDP_Settings_Keys_Int32)cur->id); + INT32 cval = + freerdp_settings_get_int32(other, (FreeRDP_Settings_Keys_Int32)cur->id); + if (sval != cval) + { + rc = TRUE; + WLog_Print(log, level, "%s [INT32]: %" PRId32 " -> %" PRId32, cur->str, sval, + cval); + } + } + break; + case FREERDP_SETTINGS_TYPE_UINT64: /* UINT64 */ + { + UINT64 sval = + freerdp_settings_get_uint64(settings, (FreeRDP_Settings_Keys_UInt64)cur->id); + UINT64 cval = + freerdp_settings_get_uint64(other, (FreeRDP_Settings_Keys_UInt64)cur->id); + if (sval != cval) + { + rc = TRUE; + WLog_Print(log, level, "%s [UINT64]: %" PRIu64 " -> %" PRIu64, cur->str, sval, + cval); + } + } + break; + case FREERDP_SETTINGS_TYPE_INT64: /* INT64 */ + { + INT64 sval = + freerdp_settings_get_int64(settings, (FreeRDP_Settings_Keys_Int64)cur->id); + INT64 cval = + freerdp_settings_get_int64(other, (FreeRDP_Settings_Keys_Int64)cur->id); + if (sval != cval) + { + rc = TRUE; + WLog_Print(log, level, "%s [INT64]: %" PRId64 " -> %" PRId64, cur->str, sval, + cval); + } + } + break; + case FREERDP_SETTINGS_TYPE_STRING: /* strings */ + { + const char* sval = + freerdp_settings_get_string(settings, (FreeRDP_Settings_Keys_String)cur->id); + const char* cval = + freerdp_settings_get_string(other, (FreeRDP_Settings_Keys_String)cur->id); + if (sval != cval) + { + if (!sval || !cval || (strcmp(sval, cval) != 0)) + { + rc = TRUE; + WLog_Print(log, level, "%s [STRING]: '%s' -> '%s'", cur->str, sval, cval); + } + } + } + break; + case FREERDP_SETTINGS_TYPE_POINTER: /* pointer */ + { + const void* sval = + freerdp_settings_get_pointer(settings, (FreeRDP_Settings_Keys_Pointer)cur->id); + const void* cval = + freerdp_settings_get_pointer(other, (FreeRDP_Settings_Keys_Pointer)cur->id); + if (sval != cval) + { + if ((sval && !cval) || (!sval && cval)) + { + rc = TRUE; + WLog_Print(log, level, "%s [POINTER]: '%p' -> '%p'", cur->str, sval, cval); + } + } + } + break; + } + } + return rc; +} + +void freerdp_settings_dump(wLog* log, DWORD level, const rdpSettings* settings) +{ + WINPR_ASSERT(log); + WINPR_ASSERT(settings); + + for (size_t x = 0; x < ARRAYSIZE(settings_map); x++) + { + const struct settings_str_entry* cur = &settings_map[x]; + switch (cur->type) + { + case FREERDP_SETTINGS_TYPE_BOOL: /* bool */ + { + BOOL sval = + freerdp_settings_get_bool(settings, (FreeRDP_Settings_Keys_Bool)cur->id); + WLog_Print(log, level, "%s [BOOL]: %s", cur->str, sval ? "TRUE" : "FALSE"); + } + break; + case FREERDP_SETTINGS_TYPE_UINT16: /* UINT16 */ + { + UINT16 sval = + freerdp_settings_get_uint16(settings, (FreeRDP_Settings_Keys_UInt16)cur->id); + WLog_Print(log, level, "%s [UINT16]: %" PRIu16, cur->str, sval); + } + break; + case FREERDP_SETTINGS_TYPE_INT16: /* INT16 */ + { + INT16 sval = + freerdp_settings_get_int16(settings, (FreeRDP_Settings_Keys_Int16)cur->id); + WLog_Print(log, level, "%s [INT16]: %" PRId16, cur->str, sval); + } + break; + case FREERDP_SETTINGS_TYPE_UINT32: /* UINT32 */ + { + UINT32 sval = + freerdp_settings_get_uint32(settings, (FreeRDP_Settings_Keys_UInt32)cur->id); + WLog_Print(log, level, "%s [UINT32]: %" PRIu32, cur->str, sval); + } + break; + case FREERDP_SETTINGS_TYPE_INT32: /* INT32 */ + { + INT32 sval = + freerdp_settings_get_int32(settings, (FreeRDP_Settings_Keys_Int32)cur->id); + WLog_Print(log, level, "%s [INT32]: %" PRId32, cur->str, sval); + } + break; + case FREERDP_SETTINGS_TYPE_UINT64: /* UINT64 */ + { + UINT64 sval = + freerdp_settings_get_uint64(settings, (FreeRDP_Settings_Keys_UInt64)cur->id); + WLog_Print(log, level, "%s [UINT64]: %" PRIu64, cur->str, sval); + } + break; + case FREERDP_SETTINGS_TYPE_INT64: /* INT64 */ + { + INT64 sval = + freerdp_settings_get_int64(settings, (FreeRDP_Settings_Keys_Int64)cur->id); + WLog_Print(log, level, "%s [INT64]: %" PRId64, cur->str, sval); + } + break; + case FREERDP_SETTINGS_TYPE_STRING: /* strings */ + { + const char* sval = + freerdp_settings_get_string(settings, (FreeRDP_Settings_Keys_String)cur->id); + WLog_Print(log, level, "%s [STRING]: '%s'", cur->str, sval); + } + break; + case FREERDP_SETTINGS_TYPE_POINTER: /* pointer */ + { + const void* sval = + freerdp_settings_get_pointer(settings, (FreeRDP_Settings_Keys_Pointer)cur->id); + WLog_Print(log, level, "%s [POINTER]: '%p'", cur->str, sval); + } + break; + } + } +} + +void freerdp_settings_free_keys(rdpSettings* dst, BOOL cleanup) +{ + WINPR_ASSERT(dst); + + for (size_t x = 0; x < ARRAYSIZE(settings_map); x++) + { + const struct settings_str_entry* cur = &settings_map[x]; + switch (cur->type) + { + case FREERDP_SETTINGS_TYPE_STRING: /* strings */ + freerdp_settings_set_string_copy_(dst, (FreeRDP_Settings_Keys_String)cur->id, NULL, + 0, cleanup); + break; + case FREERDP_SETTINGS_TYPE_POINTER: /* pointer */ + freerdp_settings_set_pointer_len(dst, (FreeRDP_Settings_Keys_Pointer)cur->id, NULL, + 0); + break; + } + } +} + +SSIZE_T freerdp_settings_get_key_for_name(const char* value) +{ + WINPR_ASSERT(value); + + for (size_t x = 0; x < ARRAYSIZE(settings_map); x++) + { + const struct settings_str_entry* cur = &settings_map[x]; + if (strcmp(value, cur->str) == 0) + return cur->id; + } + return -1; +} + +SSIZE_T freerdp_settings_get_type_for_name(const char* value) +{ + WINPR_ASSERT(value); + + for (size_t x = 0; x < ARRAYSIZE(settings_map); x++) + { + const struct settings_str_entry* cur = &settings_map[x]; + if (strcmp(value, cur->str) == 0) + return cur->type; + } + return -1; +} + +const char* freerdp_settings_get_type_name_for_key(SSIZE_T key) +{ + const SSIZE_T type = freerdp_settings_get_type_for_key(key); + return freerdp_settings_get_type_name_for_type(type); +} + +const char* freerdp_settings_get_type_name_for_type(SSIZE_T type) +{ + switch (type) + { + case FREERDP_SETTINGS_TYPE_BOOL: + return "FREERDP_SETTINGS_TYPE_BOOL"; + case FREERDP_SETTINGS_TYPE_UINT16: + return "FREERDP_SETTINGS_TYPE_UINT16"; + case FREERDP_SETTINGS_TYPE_INT16: + return "FREERDP_SETTINGS_TYPE_INT16"; + case FREERDP_SETTINGS_TYPE_UINT32: + return "FREERDP_SETTINGS_TYPE_UINT32"; + case FREERDP_SETTINGS_TYPE_INT32: + return "FREERDP_SETTINGS_TYPE_INT32"; + case FREERDP_SETTINGS_TYPE_UINT64: + return "FREERDP_SETTINGS_TYPE_UINT64"; + case FREERDP_SETTINGS_TYPE_INT64: + return "FREERDP_SETTINGS_TYPE_INT64"; + case FREERDP_SETTINGS_TYPE_STRING: + return "FREERDP_SETTINGS_TYPE_STRING"; + case FREERDP_SETTINGS_TYPE_POINTER: + return "FREERDP_SETTINGS_TYPE_POINTER"; + default: + return "FREERDP_SETTINGS_TYPE_UNKNOWN"; + } +} + +SSIZE_T freerdp_settings_get_type_for_key(SSIZE_T key) +{ + for (size_t x = 0; x < ARRAYSIZE(settings_map); x++) + { + const struct settings_str_entry* cur = &settings_map[x]; + if (cur->id == key) + return cur->type; + } + return -1; +} + +const char* freerdp_settings_get_name_for_key(SSIZE_T key) +{ + for (size_t x = 0; x < ARRAYSIZE(settings_map); x++) + { + const struct settings_str_entry* cur = &settings_map[x]; + if (cur->id == key) + return cur->str; + } + return NULL; +} + +BOOL freerdp_settings_copy_item(rdpSettings* dst, const rdpSettings* src, SSIZE_T id) +{ + WINPR_ASSERT(dst); + WINPR_ASSERT(src); + + const SSIZE_T key = freerdp_settings_get_type_for_key(id); + switch (key) + { + case FREERDP_SETTINGS_TYPE_BOOL: + { + const BOOL val = freerdp_settings_get_bool(src, (FreeRDP_Settings_Keys_Bool)id); + return freerdp_settings_set_bool(dst, (FreeRDP_Settings_Keys_Bool)id, val); + } + case FREERDP_SETTINGS_TYPE_INT16: + { + const INT16 val = freerdp_settings_get_int16(src, (FreeRDP_Settings_Keys_Int16)id); + return freerdp_settings_set_int16(dst, (FreeRDP_Settings_Keys_Int16)id, val); + } + case FREERDP_SETTINGS_TYPE_INT32: + { + const INT32 val = freerdp_settings_get_int32(src, (FreeRDP_Settings_Keys_Int32)id); + return freerdp_settings_set_int32(dst, (FreeRDP_Settings_Keys_Int32)id, val); + } + case FREERDP_SETTINGS_TYPE_INT64: + { + const INT64 val = freerdp_settings_get_int64(src, (FreeRDP_Settings_Keys_Int64)id); + return freerdp_settings_set_int64(dst, (FreeRDP_Settings_Keys_Int64)id, val); + } + case FREERDP_SETTINGS_TYPE_UINT16: + { + const UINT16 val = freerdp_settings_get_uint16(src, (FreeRDP_Settings_Keys_UInt16)id); + return freerdp_settings_set_uint16(dst, (FreeRDP_Settings_Keys_UInt16)id, val); + } + case FREERDP_SETTINGS_TYPE_UINT32: + { + const UINT32 val = freerdp_settings_get_uint32(src, (FreeRDP_Settings_Keys_UInt32)id); + return freerdp_settings_set_uint32(dst, (FreeRDP_Settings_Keys_UInt32)id, val); + } + case FREERDP_SETTINGS_TYPE_UINT64: + { + const UINT64 val = freerdp_settings_get_uint64(src, (FreeRDP_Settings_Keys_UInt64)id); + return freerdp_settings_set_uint64(dst, (FreeRDP_Settings_Keys_UInt64)id, val); + } + case FREERDP_SETTINGS_TYPE_STRING: + { + const char* val = freerdp_settings_get_string(src, (FreeRDP_Settings_Keys_String)id); + return freerdp_settings_set_string(dst, (FreeRDP_Settings_Keys_String)id, val); + } + case FREERDP_SETTINGS_TYPE_POINTER: + { + const void* val = freerdp_settings_get_pointer(src, (FreeRDP_Settings_Keys_Pointer)id); + return freerdp_settings_set_pointer(dst, (FreeRDP_Settings_Keys_Pointer)id, val); + } + default: + return FALSE; + } +} diff --git a/libfreerdp/common/settings_str.h b/libfreerdp/common/settings_str.h new file mode 100644 index 0000000..a3c71fb --- /dev/null +++ b/libfreerdp/common/settings_str.h @@ -0,0 +1,612 @@ +/* Generated by */ + +#ifndef FREERDP_CORE_SETTINGS_STR_H +#define FREERDP_CORE_SETTINGS_STR_H + +#include "../core/settings.h" + +#include <freerdp/settings.h> +#include <freerdp/log.h> + +#define TAG FREERDP_TAG("common.settings") + +typedef enum +{ + FREERDP_SETTINGS_TYPE_BOOL, + FREERDP_SETTINGS_TYPE_UINT16, + FREERDP_SETTINGS_TYPE_INT16, + FREERDP_SETTINGS_TYPE_UINT32, + FREERDP_SETTINGS_TYPE_INT32, + FREERDP_SETTINGS_TYPE_UINT64, + FREERDP_SETTINGS_TYPE_INT64, + FREERDP_SETTINGS_TYPE_STRING, + FREERDP_SETTINGS_TYPE_POINTER +} FREERDP_SETTINGS_TYPE; + +struct settings_str_entry +{ + SSIZE_T id; + SSIZE_T type; + const char* str; +}; +static const struct settings_str_entry settings_map[] = { + { FreeRDP_AadSecurity, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AadSecurity" }, + { FreeRDP_AllowCacheWaitingList, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AllowCacheWaitingList" }, + { FreeRDP_AllowDesktopComposition, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_AllowDesktopComposition" }, + { FreeRDP_AllowFontSmoothing, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AllowFontSmoothing" }, + { FreeRDP_AllowUnanouncedOrdersFromServer, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_AllowUnanouncedOrdersFromServer" }, + { FreeRDP_AltSecFrameMarkerSupport, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_AltSecFrameMarkerSupport" }, + { FreeRDP_AsyncChannels, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AsyncChannels" }, + { FreeRDP_AsyncUpdate, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AsyncUpdate" }, + { FreeRDP_AudioCapture, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AudioCapture" }, + { FreeRDP_AudioPlayback, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AudioPlayback" }, + { FreeRDP_Authentication, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_Authentication" }, + { FreeRDP_AuthenticationOnly, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AuthenticationOnly" }, + { FreeRDP_AutoAcceptCertificate, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AutoAcceptCertificate" }, + { FreeRDP_AutoDenyCertificate, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AutoDenyCertificate" }, + { FreeRDP_AutoLogonEnabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_AutoLogonEnabled" }, + { FreeRDP_AutoReconnectionEnabled, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_AutoReconnectionEnabled" }, + { FreeRDP_BitmapCacheEnabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_BitmapCacheEnabled" }, + { FreeRDP_BitmapCachePersistEnabled, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_BitmapCachePersistEnabled" }, + { FreeRDP_BitmapCacheV3Enabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_BitmapCacheV3Enabled" }, + { FreeRDP_BitmapCompressionDisabled, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_BitmapCompressionDisabled" }, + { FreeRDP_CertificateCallbackPreferPEM, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_CertificateCallbackPreferPEM" }, + { FreeRDP_CompressionEnabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_CompressionEnabled" }, + { FreeRDP_ConnectChildSession, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ConnectChildSession" }, + { FreeRDP_ConsoleSession, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ConsoleSession" }, + { FreeRDP_CredentialsFromStdin, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_CredentialsFromStdin" }, + { FreeRDP_DeactivateClientDecoding, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_DeactivateClientDecoding" }, + { FreeRDP_Decorations, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_Decorations" }, + { FreeRDP_DesktopResize, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DesktopResize" }, + { FreeRDP_DeviceRedirection, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DeviceRedirection" }, + { FreeRDP_DisableCredentialsDelegation, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_DisableCredentialsDelegation" }, + { FreeRDP_DisableCtrlAltDel, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DisableCtrlAltDel" }, + { FreeRDP_DisableCursorBlinking, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DisableCursorBlinking" }, + { FreeRDP_DisableCursorShadow, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DisableCursorShadow" }, + { FreeRDP_DisableFullWindowDrag, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DisableFullWindowDrag" }, + { FreeRDP_DisableMenuAnims, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DisableMenuAnims" }, + { FreeRDP_DisableRemoteAppCapsCheck, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_DisableRemoteAppCapsCheck" }, + { FreeRDP_DisableThemes, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DisableThemes" }, + { FreeRDP_DisableWallpaper, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DisableWallpaper" }, + { FreeRDP_DrawAllowColorSubsampling, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_DrawAllowColorSubsampling" }, + { FreeRDP_DrawAllowDynamicColorFidelity, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_DrawAllowDynamicColorFidelity" }, + { FreeRDP_DrawAllowSkipAlpha, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DrawAllowSkipAlpha" }, + { FreeRDP_DrawGdiPlusCacheEnabled, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_DrawGdiPlusCacheEnabled" }, + { FreeRDP_DrawGdiPlusEnabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DrawGdiPlusEnabled" }, + { FreeRDP_DrawNineGridEnabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DrawNineGridEnabled" }, + { FreeRDP_DumpRemoteFx, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_DumpRemoteFx" }, + { FreeRDP_DynamicDaylightTimeDisabled, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_DynamicDaylightTimeDisabled" }, + { FreeRDP_DynamicResolutionUpdate, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_DynamicResolutionUpdate" }, + { FreeRDP_EmbeddedWindow, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_EmbeddedWindow" }, + { FreeRDP_EnableWindowsKey, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_EnableWindowsKey" }, + { FreeRDP_EncomspVirtualChannel, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_EncomspVirtualChannel" }, + { FreeRDP_ExtSecurity, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ExtSecurity" }, + { FreeRDP_ExternalCertificateManagement, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_ExternalCertificateManagement" }, + { FreeRDP_FIPSMode, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_FIPSMode" }, + { FreeRDP_FastPathInput, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_FastPathInput" }, + { FreeRDP_FastPathOutput, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_FastPathOutput" }, + { FreeRDP_ForceEncryptedCsPdu, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ForceEncryptedCsPdu" }, + { FreeRDP_ForceMultimon, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ForceMultimon" }, + { FreeRDP_FrameMarkerCommandEnabled, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_FrameMarkerCommandEnabled" }, + { FreeRDP_Fullscreen, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_Fullscreen" }, + { FreeRDP_GatewayArmTransport, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GatewayArmTransport" }, + { FreeRDP_GatewayBypassLocal, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GatewayBypassLocal" }, + { FreeRDP_GatewayEnabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GatewayEnabled" }, + { FreeRDP_GatewayHttpExtAuthSspiNtlm, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_GatewayHttpExtAuthSspiNtlm" }, + { FreeRDP_GatewayHttpTransport, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GatewayHttpTransport" }, + { FreeRDP_GatewayHttpUseWebsockets, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_GatewayHttpUseWebsockets" }, + { FreeRDP_GatewayRpcTransport, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GatewayRpcTransport" }, + { FreeRDP_GatewayUdpTransport, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GatewayUdpTransport" }, + { FreeRDP_GatewayUseSameCredentials, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_GatewayUseSameCredentials" }, + { FreeRDP_GfxAVC444, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GfxAVC444" }, + { FreeRDP_GfxAVC444v2, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GfxAVC444v2" }, + { FreeRDP_GfxH264, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GfxH264" }, + { FreeRDP_GfxPlanar, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GfxPlanar" }, + { FreeRDP_GfxProgressive, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GfxProgressive" }, + { FreeRDP_GfxProgressiveV2, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GfxProgressiveV2" }, + { FreeRDP_GfxSendQoeAck, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GfxSendQoeAck" }, + { FreeRDP_GfxSmallCache, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GfxSmallCache" }, + { FreeRDP_GfxThinClient, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GfxThinClient" }, + { FreeRDP_GrabKeyboard, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GrabKeyboard" }, + { FreeRDP_GrabMouse, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GrabMouse" }, + { FreeRDP_HasExtendedMouseEvent, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_HasExtendedMouseEvent" }, + { FreeRDP_HasHorizontalWheel, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_HasHorizontalWheel" }, + { FreeRDP_HasMonitorAttributes, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_HasMonitorAttributes" }, + { FreeRDP_HasQoeEvent, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_HasQoeEvent" }, + { FreeRDP_HasRelativeMouseEvent, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_HasRelativeMouseEvent" }, + { FreeRDP_HiDefRemoteApp, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_HiDefRemoteApp" }, + { FreeRDP_IPv6Enabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_IPv6Enabled" }, + { FreeRDP_IgnoreCertificate, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_IgnoreCertificate" }, + { FreeRDP_IgnoreInvalidDevices, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_IgnoreInvalidDevices" }, + { FreeRDP_JpegCodec, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_JpegCodec" }, + { FreeRDP_KerberosRdgIsProxy, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_KerberosRdgIsProxy" }, + { FreeRDP_ListMonitors, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ListMonitors" }, + { FreeRDP_LocalConnection, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_LocalConnection" }, + { FreeRDP_LogonErrors, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_LogonErrors" }, + { FreeRDP_LogonNotify, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_LogonNotify" }, + { FreeRDP_LongCredentialsSupported, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_LongCredentialsSupported" }, + { FreeRDP_LyncRdpMode, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_LyncRdpMode" }, + { FreeRDP_MaximizeShell, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_MaximizeShell" }, + { FreeRDP_MouseAttached, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_MouseAttached" }, + { FreeRDP_MouseHasWheel, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_MouseHasWheel" }, + { FreeRDP_MouseMotion, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_MouseMotion" }, + { FreeRDP_MouseUseRelativeMove, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_MouseUseRelativeMove" }, + { FreeRDP_MstscCookieMode, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_MstscCookieMode" }, + { FreeRDP_MultiTouchGestures, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_MultiTouchGestures" }, + { FreeRDP_MultiTouchInput, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_MultiTouchInput" }, + { FreeRDP_NSCodec, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_NSCodec" }, + { FreeRDP_NSCodecAllowDynamicColorFidelity, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_NSCodecAllowDynamicColorFidelity" }, + { FreeRDP_NSCodecAllowSubsampling, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_NSCodecAllowSubsampling" }, + { FreeRDP_NegotiateSecurityLayer, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_NegotiateSecurityLayer" }, + { FreeRDP_NetworkAutoDetect, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_NetworkAutoDetect" }, + { FreeRDP_NlaSecurity, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_NlaSecurity" }, + { FreeRDP_NoBitmapCompressionHeader, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_NoBitmapCompressionHeader" }, + { FreeRDP_OldLicenseBehaviour, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_OldLicenseBehaviour" }, + { FreeRDP_PasswordIsSmartcardPin, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_PasswordIsSmartcardPin" }, + { FreeRDP_PercentScreenUseHeight, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_PercentScreenUseHeight" }, + { FreeRDP_PercentScreenUseWidth, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_PercentScreenUseWidth" }, + { FreeRDP_PlayRemoteFx, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_PlayRemoteFx" }, + { FreeRDP_PreferIPv6OverIPv4, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_PreferIPv6OverIPv4" }, + { FreeRDP_PrintReconnectCookie, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_PrintReconnectCookie" }, + { FreeRDP_PromptForCredentials, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_PromptForCredentials" }, + { FreeRDP_RdpSecurity, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RdpSecurity" }, + { FreeRDP_RdstlsSecurity, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RdstlsSecurity" }, + { FreeRDP_RedirectClipboard, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RedirectClipboard" }, + { FreeRDP_RedirectDrives, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RedirectDrives" }, + { FreeRDP_RedirectHomeDrive, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RedirectHomeDrive" }, + { FreeRDP_RedirectParallelPorts, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RedirectParallelPorts" }, + { FreeRDP_RedirectPrinters, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RedirectPrinters" }, + { FreeRDP_RedirectSerialPorts, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RedirectSerialPorts" }, + { FreeRDP_RedirectSmartCards, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RedirectSmartCards" }, + { FreeRDP_RedirectWebAuthN, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RedirectWebAuthN" }, + { FreeRDP_RefreshRect, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RefreshRect" }, + { FreeRDP_RemdeskVirtualChannel, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RemdeskVirtualChannel" }, + { FreeRDP_RemoteAppLanguageBarSupported, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_RemoteAppLanguageBarSupported" }, + { FreeRDP_RemoteApplicationMode, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RemoteApplicationMode" }, + { FreeRDP_RemoteAssistanceMode, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RemoteAssistanceMode" }, + { FreeRDP_RemoteAssistanceRequestControl, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_RemoteAssistanceRequestControl" }, + { FreeRDP_RemoteConsoleAudio, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RemoteConsoleAudio" }, + { FreeRDP_RemoteCredentialGuard, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RemoteCredentialGuard" }, + { FreeRDP_RemoteFxCodec, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RemoteFxCodec" }, + { FreeRDP_RemoteFxImageCodec, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RemoteFxImageCodec" }, + { FreeRDP_RemoteFxOnly, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_RemoteFxOnly" }, + { FreeRDP_RestrictedAdminModeRequired, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_RestrictedAdminModeRequired" }, + { FreeRDP_SaltedChecksum, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SaltedChecksum" }, + { FreeRDP_SendPreconnectionPdu, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SendPreconnectionPdu" }, + { FreeRDP_ServerLicenseRequired, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ServerLicenseRequired" }, + { FreeRDP_ServerMode, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ServerMode" }, + { FreeRDP_SmartSizing, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SmartSizing" }, + { FreeRDP_SmartcardEmulation, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SmartcardEmulation" }, + { FreeRDP_SmartcardLogon, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SmartcardLogon" }, + { FreeRDP_SoftwareGdi, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SoftwareGdi" }, + { FreeRDP_SoundBeepsEnabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SoundBeepsEnabled" }, + { FreeRDP_SpanMonitors, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SpanMonitors" }, + { FreeRDP_SupportAsymetricKeys, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportAsymetricKeys" }, + { FreeRDP_SupportDisplayControl, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportDisplayControl" }, + { FreeRDP_SupportDynamicChannels, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SupportDynamicChannels" }, + { FreeRDP_SupportDynamicTimeZone, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SupportDynamicTimeZone" }, + { FreeRDP_SupportEchoChannel, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportEchoChannel" }, + { FreeRDP_SupportEdgeActionV1, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportEdgeActionV1" }, + { FreeRDP_SupportEdgeActionV2, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportEdgeActionV2" }, + { FreeRDP_SupportErrorInfoPdu, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportErrorInfoPdu" }, + { FreeRDP_SupportGeometryTracking, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SupportGeometryTracking" }, + { FreeRDP_SupportGraphicsPipeline, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SupportGraphicsPipeline" }, + { FreeRDP_SupportHeartbeatPdu, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportHeartbeatPdu" }, + { FreeRDP_SupportMonitorLayoutPdu, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SupportMonitorLayoutPdu" }, + { FreeRDP_SupportMultitransport, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportMultitransport" }, + { FreeRDP_SupportSSHAgentChannel, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SupportSSHAgentChannel" }, + { FreeRDP_SupportSkipChannelJoin, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SupportSkipChannelJoin" }, + { FreeRDP_SupportStatusInfoPdu, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportStatusInfoPdu" }, + { FreeRDP_SupportVideoOptimized, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportVideoOptimized" }, + { FreeRDP_SuppressOutput, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SuppressOutput" }, + { FreeRDP_SurfaceCommandsEnabled, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SurfaceCommandsEnabled" }, + { FreeRDP_SurfaceFrameMarkerEnabled, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SurfaceFrameMarkerEnabled" }, + { FreeRDP_SuspendInput, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SuspendInput" }, + { FreeRDP_SynchronousDynamicChannels, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SynchronousDynamicChannels" }, + { FreeRDP_SynchronousStaticChannels, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SynchronousStaticChannels" }, + { FreeRDP_TcpKeepAlive, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_TcpKeepAlive" }, + { FreeRDP_TlsSecurity, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_TlsSecurity" }, + { FreeRDP_ToggleFullscreen, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ToggleFullscreen" }, + { FreeRDP_TransportDump, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_TransportDump" }, + { FreeRDP_TransportDumpReplay, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_TransportDumpReplay" }, + { FreeRDP_UnicodeInput, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_UnicodeInput" }, + { FreeRDP_UnmapButtons, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_UnmapButtons" }, + { FreeRDP_UseCommonStdioCallbacks, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_UseCommonStdioCallbacks" }, + { FreeRDP_UseMultimon, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_UseMultimon" }, + { FreeRDP_UseRdpSecurityLayer, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_UseRdpSecurityLayer" }, + { FreeRDP_UsingSavedCredentials, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_UsingSavedCredentials" }, + { FreeRDP_VideoDisable, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_VideoDisable" }, + { FreeRDP_VmConnectMode, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_VmConnectMode" }, + { FreeRDP_WaitForOutputBufferFlush, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_WaitForOutputBufferFlush" }, + { FreeRDP_Workarea, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_Workarea" }, + { FreeRDP_CapsGeneralCompressionLevel, FREERDP_SETTINGS_TYPE_UINT16, + "FreeRDP_CapsGeneralCompressionLevel" }, + { FreeRDP_CapsGeneralCompressionTypes, FREERDP_SETTINGS_TYPE_UINT16, + "FreeRDP_CapsGeneralCompressionTypes" }, + { FreeRDP_CapsProtocolVersion, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_CapsProtocolVersion" }, + { FreeRDP_CapsRemoteUnshareFlag, FREERDP_SETTINGS_TYPE_UINT16, + "FreeRDP_CapsRemoteUnshareFlag" }, + { FreeRDP_CapsUpdateCapabilityFlag, FREERDP_SETTINGS_TYPE_UINT16, + "FreeRDP_CapsUpdateCapabilityFlag" }, + { FreeRDP_DesktopOrientation, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_DesktopOrientation" }, + { FreeRDP_OrderSupportFlags, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_OrderSupportFlags" }, + { FreeRDP_OrderSupportFlagsEx, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_OrderSupportFlagsEx" }, + { FreeRDP_ProxyPort, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_ProxyPort" }, + { FreeRDP_SupportedColorDepths, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_SupportedColorDepths" }, + { FreeRDP_TLSMaxVersion, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_TLSMaxVersion" }, + { FreeRDP_TLSMinVersion, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_TLSMinVersion" }, + { FreeRDP_TextANSICodePage, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_TextANSICodePage" }, + { FreeRDP_AcceptedCertLength, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_AcceptedCertLength" }, + { FreeRDP_AuthenticationLevel, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_AuthenticationLevel" }, + { FreeRDP_AutoReconnectMaxRetries, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_AutoReconnectMaxRetries" }, + { FreeRDP_BitmapCacheV2NumCells, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_BitmapCacheV2NumCells" }, + { FreeRDP_BitmapCacheV3CodecId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_BitmapCacheV3CodecId" }, + { FreeRDP_BitmapCacheVersion, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_BitmapCacheVersion" }, + { FreeRDP_BrushSupportLevel, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_BrushSupportLevel" }, + { FreeRDP_ChannelCount, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ChannelCount" }, + { FreeRDP_ChannelDefArraySize, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ChannelDefArraySize" }, + { FreeRDP_ClientBuild, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ClientBuild" }, + { FreeRDP_ClientRandomLength, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ClientRandomLength" }, + { FreeRDP_ClientSessionId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ClientSessionId" }, + { FreeRDP_ClipboardFeatureMask, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ClipboardFeatureMask" }, + { FreeRDP_ClusterInfoFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ClusterInfoFlags" }, + { FreeRDP_ColorDepth, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ColorDepth" }, + { FreeRDP_ColorPointerCacheSize, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_ColorPointerCacheSize" }, + { FreeRDP_CompDeskSupportLevel, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_CompDeskSupportLevel" }, + { FreeRDP_CompressionLevel, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_CompressionLevel" }, + { FreeRDP_ConnectionType, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ConnectionType" }, + { FreeRDP_CookieMaxLength, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_CookieMaxLength" }, + { FreeRDP_DesktopHeight, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DesktopHeight" }, + { FreeRDP_DesktopPhysicalHeight, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_DesktopPhysicalHeight" }, + { FreeRDP_DesktopPhysicalWidth, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DesktopPhysicalWidth" }, + { FreeRDP_DesktopPosX, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DesktopPosX" }, + { FreeRDP_DesktopPosY, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DesktopPosY" }, + { FreeRDP_DesktopScaleFactor, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DesktopScaleFactor" }, + { FreeRDP_DesktopWidth, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DesktopWidth" }, + { FreeRDP_DeviceArraySize, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DeviceArraySize" }, + { FreeRDP_DeviceCount, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DeviceCount" }, + { FreeRDP_DeviceScaleFactor, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DeviceScaleFactor" }, + { FreeRDP_DrawNineGridCacheEntries, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_DrawNineGridCacheEntries" }, + { FreeRDP_DrawNineGridCacheSize, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_DrawNineGridCacheSize" }, + { FreeRDP_DynamicChannelArraySize, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_DynamicChannelArraySize" }, + { FreeRDP_DynamicChannelCount, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_DynamicChannelCount" }, + { FreeRDP_EarlyCapabilityFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_EarlyCapabilityFlags" }, + { FreeRDP_EncryptionLevel, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_EncryptionLevel" }, + { FreeRDP_EncryptionMethods, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_EncryptionMethods" }, + { FreeRDP_ExtEncryptionMethods, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ExtEncryptionMethods" }, + { FreeRDP_FakeMouseMotionInterval, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_FakeMouseMotionInterval" }, + { FreeRDP_Floatbar, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_Floatbar" }, + { FreeRDP_FrameAcknowledge, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_FrameAcknowledge" }, + { FreeRDP_GatewayAcceptedCertLength, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_GatewayAcceptedCertLength" }, + { FreeRDP_GatewayCredentialsSource, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_GatewayCredentialsSource" }, + { FreeRDP_GatewayPort, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_GatewayPort" }, + { FreeRDP_GatewayUsageMethod, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_GatewayUsageMethod" }, + { FreeRDP_GfxCapsFilter, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_GfxCapsFilter" }, + { FreeRDP_GlyphSupportLevel, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_GlyphSupportLevel" }, + { FreeRDP_JpegCodecId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_JpegCodecId" }, + { FreeRDP_JpegQuality, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_JpegQuality" }, + { FreeRDP_KeySpec, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_KeySpec" }, + { FreeRDP_KeyboardCodePage, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_KeyboardCodePage" }, + { FreeRDP_KeyboardFunctionKey, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_KeyboardFunctionKey" }, + { FreeRDP_KeyboardHook, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_KeyboardHook" }, + { FreeRDP_KeyboardLayout, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_KeyboardLayout" }, + { FreeRDP_KeyboardSubType, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_KeyboardSubType" }, + { FreeRDP_KeyboardType, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_KeyboardType" }, + { FreeRDP_LargePointerFlag, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_LargePointerFlag" }, + { FreeRDP_LoadBalanceInfoLength, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_LoadBalanceInfoLength" }, + { FreeRDP_MonitorAttributeFlags, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_MonitorAttributeFlags" }, + { FreeRDP_MonitorCount, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorCount" }, + { FreeRDP_MonitorDefArraySize, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorDefArraySize" }, + { FreeRDP_MonitorFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorFlags" }, + { FreeRDP_MonitorLocalShiftX, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorLocalShiftX" }, + { FreeRDP_MonitorLocalShiftY, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorLocalShiftY" }, + { FreeRDP_MultifragMaxRequestSize, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_MultifragMaxRequestSize" }, + { FreeRDP_MultitransportFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MultitransportFlags" }, + { FreeRDP_NSCodecColorLossLevel, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_NSCodecColorLossLevel" }, + { FreeRDP_NSCodecId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_NSCodecId" }, + { FreeRDP_NegotiationFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_NegotiationFlags" }, + { FreeRDP_NumMonitorIds, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_NumMonitorIds" }, + { FreeRDP_OffscreenCacheEntries, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_OffscreenCacheEntries" }, + { FreeRDP_OffscreenCacheSize, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_OffscreenCacheSize" }, + { FreeRDP_OffscreenSupportLevel, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_OffscreenSupportLevel" }, + { FreeRDP_OsMajorType, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_OsMajorType" }, + { FreeRDP_OsMinorType, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_OsMinorType" }, + { FreeRDP_Password51Length, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_Password51Length" }, + { FreeRDP_PduSource, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_PduSource" }, + { FreeRDP_PercentScreen, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_PercentScreen" }, + { FreeRDP_PerformanceFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_PerformanceFlags" }, + { FreeRDP_PointerCacheSize, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_PointerCacheSize" }, + { FreeRDP_PreconnectionId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_PreconnectionId" }, + { FreeRDP_ProxyType, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ProxyType" }, + { FreeRDP_RdpVersion, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_RdpVersion" }, + { FreeRDP_ReceivedCapabilitiesSize, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_ReceivedCapabilitiesSize" }, + { FreeRDP_RedirectedSessionId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_RedirectedSessionId" }, + { FreeRDP_RedirectionAcceptedCertLength, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RedirectionAcceptedCertLength" }, + { FreeRDP_RedirectionFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_RedirectionFlags" }, + { FreeRDP_RedirectionGuidLength, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RedirectionGuidLength" }, + { FreeRDP_RedirectionPasswordLength, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RedirectionPasswordLength" }, + { FreeRDP_RedirectionPreferType, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RedirectionPreferType" }, + { FreeRDP_RedirectionTsvUrlLength, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RedirectionTsvUrlLength" }, + { FreeRDP_RemoteAppNumIconCacheEntries, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RemoteAppNumIconCacheEntries" }, + { FreeRDP_RemoteAppNumIconCaches, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RemoteAppNumIconCaches" }, + { FreeRDP_RemoteApplicationExpandCmdLine, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RemoteApplicationExpandCmdLine" }, + { FreeRDP_RemoteApplicationExpandWorkingDir, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RemoteApplicationExpandWorkingDir" }, + { FreeRDP_RemoteApplicationSupportLevel, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RemoteApplicationSupportLevel" }, + { FreeRDP_RemoteApplicationSupportMask, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RemoteApplicationSupportMask" }, + { FreeRDP_RemoteFxCaptureFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_RemoteFxCaptureFlags" }, + { FreeRDP_RemoteFxCodecId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_RemoteFxCodecId" }, + { FreeRDP_RemoteFxCodecMode, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_RemoteFxCodecMode" }, + { FreeRDP_RemoteWndSupportLevel, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_RemoteWndSupportLevel" }, + { FreeRDP_RequestedProtocols, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_RequestedProtocols" }, + { FreeRDP_SelectedProtocol, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_SelectedProtocol" }, + { FreeRDP_ServerCertificateLength, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_ServerCertificateLength" }, + { FreeRDP_ServerLicenseProductIssuersCount, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_ServerLicenseProductIssuersCount" }, + { FreeRDP_ServerLicenseProductVersion, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_ServerLicenseProductVersion" }, + { FreeRDP_ServerPort, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ServerPort" }, + { FreeRDP_ServerRandomLength, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ServerRandomLength" }, + { FreeRDP_ShareId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ShareId" }, + { FreeRDP_SmartSizingHeight, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_SmartSizingHeight" }, + { FreeRDP_SmartSizingWidth, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_SmartSizingWidth" }, + { FreeRDP_StaticChannelArraySize, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_StaticChannelArraySize" }, + { FreeRDP_StaticChannelCount, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_StaticChannelCount" }, + { FreeRDP_TargetNetAddressCount, FREERDP_SETTINGS_TYPE_UINT32, + "FreeRDP_TargetNetAddressCount" }, + { FreeRDP_TcpAckTimeout, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_TcpAckTimeout" }, + { FreeRDP_TcpConnectTimeout, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_TcpConnectTimeout" }, + { FreeRDP_TcpKeepAliveDelay, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_TcpKeepAliveDelay" }, + { FreeRDP_TcpKeepAliveInterval, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_TcpKeepAliveInterval" }, + { FreeRDP_TcpKeepAliveRetries, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_TcpKeepAliveRetries" }, + { FreeRDP_ThreadingFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ThreadingFlags" }, + { FreeRDP_TlsSecLevel, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_TlsSecLevel" }, + { FreeRDP_VCChunkSize, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_VCChunkSize" }, + { FreeRDP_VCFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_VCFlags" }, + { FreeRDP_XPan, FREERDP_SETTINGS_TYPE_INT32, "FreeRDP_XPan" }, + { FreeRDP_YPan, FREERDP_SETTINGS_TYPE_INT32, "FreeRDP_YPan" }, + { FreeRDP_ParentWindowId, FREERDP_SETTINGS_TYPE_UINT64, "FreeRDP_ParentWindowId" }, + { FreeRDP_AadServerHostname, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_AadServerHostname" }, + { FreeRDP_AcceptedCert, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_AcceptedCert" }, + { FreeRDP_ActionScript, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ActionScript" }, + { FreeRDP_AllowedTlsCiphers, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_AllowedTlsCiphers" }, + { FreeRDP_AlternateShell, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_AlternateShell" }, + { FreeRDP_AssistanceFile, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_AssistanceFile" }, + { FreeRDP_AuthenticationPackageList, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_AuthenticationPackageList" }, + { FreeRDP_AuthenticationServiceClass, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_AuthenticationServiceClass" }, + { FreeRDP_BitmapCachePersistFile, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_BitmapCachePersistFile" }, + { FreeRDP_CardName, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_CardName" }, + { FreeRDP_CertificateAcceptedFingerprints, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_CertificateAcceptedFingerprints" }, + { FreeRDP_CertificateName, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_CertificateName" }, + { FreeRDP_ClientAddress, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ClientAddress" }, + { FreeRDP_ClientDir, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ClientDir" }, + { FreeRDP_ClientHostname, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ClientHostname" }, + { FreeRDP_ClientProductId, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ClientProductId" }, + { FreeRDP_ClipboardUseSelection, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_ClipboardUseSelection" }, + { FreeRDP_ComputerName, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ComputerName" }, + { FreeRDP_ConfigPath, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ConfigPath" }, + { FreeRDP_ConnectionFile, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ConnectionFile" }, + { FreeRDP_ContainerName, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ContainerName" }, + { FreeRDP_CspName, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_CspName" }, + { FreeRDP_CurrentPath, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_CurrentPath" }, + { FreeRDP_Domain, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_Domain" }, + { FreeRDP_DrivesToRedirect, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_DrivesToRedirect" }, + { FreeRDP_DumpRemoteFxFile, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_DumpRemoteFxFile" }, + { FreeRDP_DynamicDSTTimeZoneKeyName, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_DynamicDSTTimeZoneKeyName" }, + { FreeRDP_GatewayAcceptedCert, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAcceptedCert" }, + { FreeRDP_GatewayAccessToken, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAccessToken" }, + { FreeRDP_GatewayAvdAadtenantid, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_GatewayAvdAadtenantid" }, + { FreeRDP_GatewayAvdActivityhint, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_GatewayAvdActivityhint" }, + { FreeRDP_GatewayAvdArmpath, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAvdArmpath" }, + { FreeRDP_GatewayAvdDiagnosticserviceurl, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_GatewayAvdDiagnosticserviceurl" }, + { FreeRDP_GatewayAvdGeo, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAvdGeo" }, + { FreeRDP_GatewayAvdHubdiscoverygeourl, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_GatewayAvdHubdiscoverygeourl" }, + { FreeRDP_GatewayAvdWvdEndpointPool, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_GatewayAvdWvdEndpointPool" }, + { FreeRDP_GatewayDomain, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayDomain" }, + { FreeRDP_GatewayHostname, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayHostname" }, + { FreeRDP_GatewayHttpExtAuthBearer, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_GatewayHttpExtAuthBearer" }, + { FreeRDP_GatewayPassword, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayPassword" }, + { FreeRDP_GatewayUrl, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayUrl" }, + { FreeRDP_GatewayUsername, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayUsername" }, + { FreeRDP_HomePath, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_HomePath" }, + { FreeRDP_ImeFileName, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ImeFileName" }, + { FreeRDP_KerberosArmor, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_KerberosArmor" }, + { FreeRDP_KerberosCache, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_KerberosCache" }, + { FreeRDP_KerberosKdcUrl, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_KerberosKdcUrl" }, + { FreeRDP_KerberosKeytab, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_KerberosKeytab" }, + { FreeRDP_KerberosLifeTime, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_KerberosLifeTime" }, + { FreeRDP_KerberosRealm, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_KerberosRealm" }, + { FreeRDP_KerberosRenewableLifeTime, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_KerberosRenewableLifeTime" }, + { FreeRDP_KerberosStartTime, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_KerberosStartTime" }, + { FreeRDP_KeyboardPipeName, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_KeyboardPipeName" }, + { FreeRDP_KeyboardRemappingList, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_KeyboardRemappingList" }, + { FreeRDP_NtlmSamFile, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_NtlmSamFile" }, + { FreeRDP_Password, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_Password" }, + { FreeRDP_PasswordHash, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_PasswordHash" }, + { FreeRDP_Pkcs11Module, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_Pkcs11Module" }, + { FreeRDP_PkinitAnchors, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_PkinitAnchors" }, + { FreeRDP_PlayRemoteFxFile, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_PlayRemoteFxFile" }, + { FreeRDP_PreconnectionBlob, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_PreconnectionBlob" }, + { FreeRDP_ProxyHostname, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ProxyHostname" }, + { FreeRDP_ProxyPassword, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ProxyPassword" }, + { FreeRDP_ProxyUsername, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ProxyUsername" }, + { FreeRDP_RDP2TCPArgs, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_RDP2TCPArgs" }, + { FreeRDP_ReaderName, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ReaderName" }, + { FreeRDP_RedirectionAcceptedCert, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RedirectionAcceptedCert" }, + { FreeRDP_RedirectionDomain, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_RedirectionDomain" }, + { FreeRDP_RedirectionTargetFQDN, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RedirectionTargetFQDN" }, + { FreeRDP_RedirectionTargetNetBiosName, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RedirectionTargetNetBiosName" }, + { FreeRDP_RedirectionUsername, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_RedirectionUsername" }, + { FreeRDP_RemoteApplicationCmdLine, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteApplicationCmdLine" }, + { FreeRDP_RemoteApplicationFile, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteApplicationFile" }, + { FreeRDP_RemoteApplicationGuid, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteApplicationGuid" }, + { FreeRDP_RemoteApplicationIcon, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteApplicationIcon" }, + { FreeRDP_RemoteApplicationName, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteApplicationName" }, + { FreeRDP_RemoteApplicationProgram, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteApplicationProgram" }, + { FreeRDP_RemoteApplicationWorkingDir, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteApplicationWorkingDir" }, + { FreeRDP_RemoteAssistancePassStub, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteAssistancePassStub" }, + { FreeRDP_RemoteAssistancePassword, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteAssistancePassword" }, + { FreeRDP_RemoteAssistanceRCTicket, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteAssistanceRCTicket" }, + { FreeRDP_RemoteAssistanceSessionId, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_RemoteAssistanceSessionId" }, + { FreeRDP_ServerHostname, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ServerHostname" }, + { FreeRDP_ServerLicenseCompanyName, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_ServerLicenseCompanyName" }, + { FreeRDP_ServerLicenseProductName, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_ServerLicenseProductName" }, + { FreeRDP_ShellWorkingDirectory, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_ShellWorkingDirectory" }, + { FreeRDP_SmartcardCertificate, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_SmartcardCertificate" }, + { FreeRDP_SmartcardPrivateKey, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_SmartcardPrivateKey" }, + { FreeRDP_SspiModule, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_SspiModule" }, + { FreeRDP_TargetNetAddress, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_TargetNetAddress" }, + { FreeRDP_TerminalDescriptor, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_TerminalDescriptor" }, + { FreeRDP_TlsSecretsFile, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_TlsSecretsFile" }, + { FreeRDP_TransportDumpFile, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_TransportDumpFile" }, + { FreeRDP_UserSpecifiedServerName, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_UserSpecifiedServerName" }, + { FreeRDP_Username, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_Username" }, + { FreeRDP_WinSCardModule, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_WinSCardModule" }, + { FreeRDP_WindowTitle, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_WindowTitle" }, + { FreeRDP_WmClass, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_WmClass" }, + { FreeRDP_BitmapCacheV2CellInfo, FREERDP_SETTINGS_TYPE_POINTER, + "FreeRDP_BitmapCacheV2CellInfo" }, + { FreeRDP_ChannelDefArray, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ChannelDefArray" }, + { FreeRDP_ClientAutoReconnectCookie, FREERDP_SETTINGS_TYPE_POINTER, + "FreeRDP_ClientAutoReconnectCookie" }, + { FreeRDP_ClientRandom, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ClientRandom" }, + { FreeRDP_ClientTimeZone, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ClientTimeZone" }, + { FreeRDP_DeviceArray, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_DeviceArray" }, + { FreeRDP_DynamicChannelArray, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_DynamicChannelArray" }, + { FreeRDP_FragCache, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_FragCache" }, + { FreeRDP_GlyphCache, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_GlyphCache" }, + { FreeRDP_LoadBalanceInfo, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_LoadBalanceInfo" }, + { FreeRDP_MonitorDefArray, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_MonitorDefArray" }, + { FreeRDP_MonitorIds, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_MonitorIds" }, + { FreeRDP_OrderSupport, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_OrderSupport" }, + { FreeRDP_Password51, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_Password51" }, + { FreeRDP_RdpServerCertificate, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_RdpServerCertificate" }, + { FreeRDP_RdpServerRsaKey, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_RdpServerRsaKey" }, + { FreeRDP_ReceivedCapabilities, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ReceivedCapabilities" }, + { FreeRDP_ReceivedCapabilityData, FREERDP_SETTINGS_TYPE_POINTER, + "FreeRDP_ReceivedCapabilityData" }, + { FreeRDP_ReceivedCapabilityDataSizes, FREERDP_SETTINGS_TYPE_POINTER, + "FreeRDP_ReceivedCapabilityDataSizes" }, + { FreeRDP_RedirectionGuid, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_RedirectionGuid" }, + { FreeRDP_RedirectionPassword, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_RedirectionPassword" }, + { FreeRDP_RedirectionTargetCertificate, FREERDP_SETTINGS_TYPE_POINTER, + "FreeRDP_RedirectionTargetCertificate" }, + { FreeRDP_RedirectionTsvUrl, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_RedirectionTsvUrl" }, + { FreeRDP_ServerAutoReconnectCookie, FREERDP_SETTINGS_TYPE_POINTER, + "FreeRDP_ServerAutoReconnectCookie" }, + { FreeRDP_ServerCertificate, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ServerCertificate" }, + { FreeRDP_ServerLicenseProductIssuers, FREERDP_SETTINGS_TYPE_POINTER, + "FreeRDP_ServerLicenseProductIssuers" }, + { FreeRDP_ServerRandom, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ServerRandom" }, + { FreeRDP_StaticChannelArray, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_StaticChannelArray" }, + { FreeRDP_TargetNetAddresses, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_TargetNetAddresses" }, + { FreeRDP_TargetNetPorts, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_TargetNetPorts" }, + { FreeRDP_instance, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_instance" }, +}; + +#endif diff --git a/libfreerdp/common/test/CMakeLists.txt b/libfreerdp/common/test/CMakeLists.txt new file mode 100644 index 0000000..c1f871b --- /dev/null +++ b/libfreerdp/common/test/CMakeLists.txt @@ -0,0 +1,44 @@ + +set(MODULE_NAME "TestCommon") +set(MODULE_PREFIX "TEST_COMMON") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestAddinArgv.c + TestCommonAssistance.c) + +set(${MODULE_PREFIX}_FUZZERS + TestFuzzCommonAssistanceParseFileBuffer.c + TestFuzzCommonAssistanceBinToHexString.c + TestFuzzCommonAssistanceHexStringToBin.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +target_link_libraries(${MODULE_NAME} freerdp winpr) + +if (BUILD_FUZZERS) + foreach(test ${${MODULE_PREFIX}_FUZZERS}) + get_filename_component(TestName ${test} NAME_WE) + add_executable(${TestName} ${test}) + # Use PUBLIC to force 'fuzzer_config' for all dependent targets. + target_link_libraries(${TestName} PUBLIC freerdp winpr fuzzer_config) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) + set_target_properties(${TestName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + add_dependencies(fuzzers ${TestName}) + endforeach() +endif (BUILD_FUZZERS) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Common/Test") + diff --git a/libfreerdp/common/test/TestAddinArgv.c b/libfreerdp/common/test/TestAddinArgv.c new file mode 100644 index 0000000..f9a1f8b --- /dev/null +++ b/libfreerdp/common/test/TestAddinArgv.c @@ -0,0 +1,345 @@ +#include <winpr/crt.h> +#include <winpr/crypto.h> + +#include <freerdp/settings.h> + +static BOOL test_alloc(void) +{ + BOOL rc = FALSE; + int rng = 0; + const char* param[] = { "foo:", "bar", "bla", "rdp", NULL }; + ADDIN_ARGV* arg1 = NULL; + ADDIN_ARGV* arg2 = NULL; + ADDIN_ARGV* arg3 = NULL; + ADDIN_ARGV* arg4 = NULL; + + /* Test empty allocation */ + arg1 = freerdp_addin_argv_new(0, NULL); + if (!arg1 || (arg1->argc != 0) || (arg1->argv)) + goto fail; + + /* Test allocation without initializing arguments of random size > 0 */ + winpr_RAND(&rng, sizeof(rng)); + rng = abs(rng % 8192) + 1; + + arg2 = freerdp_addin_argv_new(rng, NULL); + if (!arg2 || (arg2->argc != rng) || (!arg2->argv)) + goto fail; + for (int x = 0; x < arg2->argc; x++) + { + if (arg2->argv[x]) + goto fail; + } + + /* Test allocation with initializing arguments of size > 0 */ + arg3 = freerdp_addin_argv_new(ARRAYSIZE(param) - 1, param); + if (!arg3 || (arg3->argc != ARRAYSIZE(param) - 1) || (!arg3->argv)) + goto fail; + + for (int x = 0; x < arg3->argc; x++) + { + if (strcmp(arg3->argv[x], param[x]) != 0) + goto fail; + } + + /* Input lists with NULL elements are not allowed */ + arg4 = freerdp_addin_argv_new(ARRAYSIZE(param), param); + if (arg4) + goto fail; + rc = TRUE; +fail: + freerdp_addin_argv_free(arg1); + freerdp_addin_argv_free(arg2); + freerdp_addin_argv_free(arg3); + freerdp_addin_argv_free(arg4); + printf("%s: %d\n", __func__, rc); + return rc; +} + +static BOOL test_clone(void) +{ + BOOL rc = FALSE; + const char* param[] = { "foo:", "bar", "bla", "rdp" }; + ADDIN_ARGV* arg = NULL; + ADDIN_ARGV* clone = NULL; + ADDIN_ARGV* clone2 = NULL; + + arg = freerdp_addin_argv_new(ARRAYSIZE(param), param); + if (!arg || (arg->argc != ARRAYSIZE(param))) + goto fail; + clone = freerdp_addin_argv_clone(arg); + if (!clone || (clone->argc != arg->argc)) + goto fail; + + for (int x = 0; x < arg->argc; x++) + { + if (strcmp(param[x], arg->argv[x]) != 0) + goto fail; + if (strcmp(param[x], clone->argv[x]) != 0) + goto fail; + } + + clone2 = freerdp_addin_argv_clone(NULL); + if (clone2) + goto fail; + rc = TRUE; +fail: + freerdp_addin_argv_free(arg); + freerdp_addin_argv_free(clone); + freerdp_addin_argv_free(clone2); + printf("%s: %d\n", __func__, rc); + return rc; +} + +static BOOL test_add_remove(void) +{ + const char* args[] = { "foo", "bar", "bla", "gaga" }; + BOOL rc = FALSE; + ADDIN_ARGV* arg = freerdp_addin_argv_new(0, NULL); + + if (!arg || (arg->argc != 0) || arg->argv) + goto fail; + for (size_t y = 0; y < ARRAYSIZE(args); y++) + { + const char* param = args[y]; + if (!freerdp_addin_argv_add_argument(arg, param)) + goto fail; + if (arg->argc != (int)y + 1) + goto fail; + if (!arg->argv) + goto fail; + if (strcmp(arg->argv[y], param) != 0) + goto fail; + } + + /* Try to remove non existing element, must not return TRUE */ + if (freerdp_addin_argv_del_argument(arg, "foobar")) + goto fail; + + /* Invalid parameters, must return FALSE */ + if (freerdp_addin_argv_del_argument(NULL, "foobar")) + goto fail; + + /* Invalid parameters, must return FALSE */ + if (freerdp_addin_argv_del_argument(arg, NULL)) + goto fail; + + /* Remove elements one by one to test argument index move */ + for (size_t y = 0; y < ARRAYSIZE(args); y++) + { + const char* param = args[y]; + if (!freerdp_addin_argv_del_argument(arg, param)) + goto fail; + for (size_t x = y + 1; x < ARRAYSIZE(args); x++) + { + if (strcmp(arg->argv[x - y - 1], args[x]) != 0) + goto fail; + } + } + rc = TRUE; +fail: + freerdp_addin_argv_free(arg); + printf("%s: %d\n", __func__, rc); + return rc; +} + +static BOOL test_set_argument(void) +{ + int ret = 0; + const char* newarg = "foobar"; + const char* args[] = { "foo", "bar", "bla", "gaga" }; + BOOL rc = FALSE; + ADDIN_ARGV* arg = NULL; + + arg = freerdp_addin_argv_new(ARRAYSIZE(args), args); + if (!arg || (arg->argc != ARRAYSIZE(args)) || !arg->argv) + goto fail; + + /* Check invalid parameters */ + ret = freerdp_addin_set_argument(NULL, "foo"); + if (ret >= 0) + goto fail; + ret = freerdp_addin_set_argument(arg, NULL); + if (ret >= 0) + goto fail; + + /* Try existing parameter */ + ret = freerdp_addin_set_argument(arg, "foo"); + if ((ret != 1) || (arg->argc != ARRAYSIZE(args))) + goto fail; + + /* Try new parameter */ + ret = freerdp_addin_set_argument(arg, newarg); + if ((ret != 0) || (arg->argc != ARRAYSIZE(args) + 1) || + (strcmp(newarg, arg->argv[ARRAYSIZE(args)]) != 0)) + goto fail; + + rc = TRUE; +fail: + freerdp_addin_argv_free(arg); + printf("%s: %d\n", __func__, rc); + return rc; +} + +static BOOL test_replace_argument(void) +{ + int ret = 0; + const char* newarg = "foobar"; + const char* args[] = { "foo", "bar", "bla", "gaga" }; + BOOL rc = FALSE; + ADDIN_ARGV* arg = NULL; + + arg = freerdp_addin_argv_new(ARRAYSIZE(args), args); + if (!arg || (arg->argc != ARRAYSIZE(args)) || !arg->argv) + goto fail; + + /* Check invalid parameters */ + ret = freerdp_addin_replace_argument(NULL, "foo", newarg); + if (ret >= 0) + goto fail; + ret = freerdp_addin_replace_argument(arg, NULL, newarg); + if (ret >= 0) + goto fail; + ret = freerdp_addin_replace_argument(arg, "foo", NULL); + if (ret >= 0) + goto fail; + + /* Try existing parameter */ + ret = freerdp_addin_replace_argument(arg, "foo", newarg); + if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[0], newarg) != 0)) + goto fail; + + /* Try new parameter */ + ret = freerdp_addin_replace_argument(arg, "lalala", newarg); + if ((ret != 0) || (arg->argc != ARRAYSIZE(args) + 1) || + (strcmp(newarg, arg->argv[ARRAYSIZE(args)]) != 0)) + goto fail; + + rc = TRUE; +fail: + freerdp_addin_argv_free(arg); + printf("%s: %d\n", __func__, rc); + return rc; +} + +static BOOL test_set_argument_value(void) +{ + int ret = 0; + const char* newarg1 = "foobar"; + const char* newarg2 = "lalala"; + const char* fullnewarg1 = "foo:foobar"; + const char* fullnewarg2 = "foo:lalala"; + const char* fullnewvalue = "lalala:foobar"; + const char* args[] = { "foo", "foo:", "bar", "bla", "gaga" }; + BOOL rc = FALSE; + ADDIN_ARGV* arg = NULL; + + arg = freerdp_addin_argv_new(ARRAYSIZE(args), args); + if (!arg || (arg->argc != ARRAYSIZE(args)) || !arg->argv) + goto fail; + + /* Check invalid parameters */ + ret = freerdp_addin_set_argument_value(NULL, "foo", newarg1); + if (ret >= 0) + goto fail; + ret = freerdp_addin_set_argument_value(arg, NULL, newarg1); + if (ret >= 0) + goto fail; + ret = freerdp_addin_set_argument_value(arg, "foo", NULL); + if (ret >= 0) + goto fail; + + /* Try existing parameter */ + ret = freerdp_addin_set_argument_value(arg, "foo", newarg1); + if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[1], fullnewarg1) != 0)) + goto fail; + ret = freerdp_addin_set_argument_value(arg, "foo", newarg2); + if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[1], fullnewarg2) != 0)) + goto fail; + + /* Try new parameter */ + ret = freerdp_addin_set_argument_value(arg, newarg2, newarg1); + if ((ret != 0) || (arg->argc != ARRAYSIZE(args) + 1) || + (strcmp(fullnewvalue, arg->argv[ARRAYSIZE(args)]) != 0)) + goto fail; + + rc = TRUE; +fail: + freerdp_addin_argv_free(arg); + printf("%s: %d\n", __func__, rc); + return rc; +} + +static BOOL test_replace_argument_value(void) +{ + int ret = 0; + const char* newarg1 = "foobar"; + const char* newarg2 = "lalala"; + const char* fullnewarg1 = "foo:foobar"; + const char* fullnewarg2 = "foo:lalala"; + const char* fullnewvalue = "lalala:foobar"; + const char* args[] = { "foo", "foo:", "bar", "bla", "gaga" }; + BOOL rc = FALSE; + ADDIN_ARGV* arg = NULL; + + arg = freerdp_addin_argv_new(ARRAYSIZE(args), args); + if (!arg || (arg->argc != ARRAYSIZE(args)) || !arg->argv) + goto fail; + + /* Check invalid parameters */ + ret = freerdp_addin_replace_argument_value(NULL, "bar", "foo", newarg1); + if (ret >= 0) + goto fail; + ret = freerdp_addin_replace_argument_value(arg, NULL, "foo", newarg1); + if (ret >= 0) + goto fail; + ret = freerdp_addin_replace_argument_value(arg, "foo", NULL, newarg1); + if (ret >= 0) + goto fail; + ret = freerdp_addin_replace_argument_value(arg, "bar", "foo", NULL); + if (ret >= 0) + goto fail; + + /* Try existing parameter */ + ret = freerdp_addin_replace_argument_value(arg, "bla", "foo", newarg1); + if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[3], fullnewarg1) != 0)) + goto fail; + ret = freerdp_addin_replace_argument_value(arg, "foo", "foo", newarg2); + if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[0], fullnewarg2) != 0)) + goto fail; + + /* Try new parameter */ + ret = freerdp_addin_replace_argument_value(arg, "hahaha", newarg2, newarg1); + if ((ret != 0) || (arg->argc != ARRAYSIZE(args) + 1) || + (strcmp(fullnewvalue, arg->argv[ARRAYSIZE(args)]) != 0)) + goto fail; + + rc = TRUE; +fail: + freerdp_addin_argv_free(arg); + printf("%s: %d\n", __func__, rc); + return rc; +} + +int TestAddinArgv(int argc, char* argv[]) +{ + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!test_alloc()) + return -1; + if (!test_clone()) + return -1; + if (!test_add_remove()) + return -1; + if (!test_set_argument()) + return -1; + if (!test_replace_argument()) + return -1; + if (!test_set_argument_value()) + return -1; + if (!test_replace_argument_value()) + return -1; + return 0; +} diff --git a/libfreerdp/common/test/TestCommonAssistance.c b/libfreerdp/common/test/TestCommonAssistance.c new file mode 100644 index 0000000..35fe863 --- /dev/null +++ b/libfreerdp/common/test/TestCommonAssistance.c @@ -0,0 +1,293 @@ +#include <winpr/crt.h> +#include <winpr/print.h> +#include <winpr/ssl.h> +#include <winpr/wlog.h> +#include <winpr/platform.h> + +#include <freerdp/assistance.h> + +static const char TEST_MSRC_INCIDENT_PASSWORD_TYPE1[] = "Password1"; + +static const char TEST_MSRC_INCIDENT_FILE_TYPE1[] = + "<?xml version=\"1.0\" encoding=\"Unicode\" ?>" + "<UPLOADINFO TYPE=\"Escalated\">" + "<UPLOADDATA " + "USERNAME=\"Administrator\" " + "RCTICKET=\"65538,1,10.0.3.105:3389;winxpsp3.contoso3.com:3389,*," + "rb+v0oPmEISmi8N2zK/vuhgul/ABqlDt6wW0VxMyxK8=,*,*,IuaRySSbPDNna4+2mKcsKxsbJFI=\"" + "RCTICKETENCRYPTED=\"1\" " + "DtStart=\"1314905741\" " + "DtLength=\"180\" " + "PassStub=\"RT=0PvIndan52*\" " + "L=\"0\" />" + "</UPLOADINFO>"; + +WINPR_PRAGMA_DIAG_PUSH +WINPR_PRAGMA_DIAG_IGNORED_UNUSED_CONST_VAR +static const BYTE TEST_MSRC_INCIDENT_EXPERT_BLOB_TYPE1[32] = + "\x3C\x9C\xAE\x0B\xCE\x7A\xB1\x5C\x8A\xAC\x01\xD6\x76\x04\x5E\xDF" + "\x3F\xFA\xF0\x92\xE2\xDE\x36\x8A\x20\x17\xE6\x8A\x0D\xED\x7C\x90"; +WINPR_PRAGMA_DIAG_POP + +static const char TEST_MSRC_INCIDENT_PASSWORD_TYPE2[] = "48BJQ853X3B4"; + +static const char TEST_MSRC_INCIDENT_FILE_TYPE2[] = + "<?xml version=\"1.0\"?>" + "<UPLOADINFO TYPE=\"Escalated\">" + "<UPLOADDATA USERNAME=\"awake\" " + "LHTICKET=\"" + "20FCC407AA53E95F8505AB56D485D26835064B03AF86CDA326248FD304626AD4" + "DBDBDFFE0C473228EFFF7A1E6CEB445BBEC429294BB6616BBB600854438DDFB5" + "82FC377CF65A2060EB3221647643C9B29BF5EC320856180B34D1BE9827A528C7" + "E8F0DCD53C8D38F974160FEE317458FAC9DBDBA7B972D21DF3BC5B1AF0E01878" + "65F07A3B915618C03E6EAF843FC1185770A1208C29C836DBCA5A040CB276D3C4" + "1DDE2FA8CA9627E5E74FA750A92C0E01AD6C3D1000A5B1479DEB899BF5BCD402" + "CE3BB3BF104CE0286C3F985AA711943C88C5EEEEE86F35B63F68883A90ADBCFD" + "CBBAE3EAB993EFD9148E1A21D092CE9498695943946236D65D20B4A38D724C61" + "72319E38E19C04E98EBC03F56A4A190E971F8EAEBFE6B415A3A2D8F35F7BF785" + "26B9BFAAB48D11BDD6C905EFE503D2265678E1EAD2F2F124E570667F04103180" + "2F63587276C14E6A5AB436CE234F722CE7C9B5D244508F14C012E84A49FE6992" + "3F30320ABB3641F1EFA66205F3EA709E7E1C3E6874BB9642486FB96D2730CDF4" + "514AA738167F00FC13B2978AED1D6678413FDF62008B03DD729E36173BE02742" + "B69CAD44938512D0F56335394759338AF6ADBCF39CE829116D97435085D05BB5" + "9320A134698050DCDBE01305A6B4712FD6BD48958BD2DC497498FF35CAECC9A8" + "2C97FD1A5B5EC4BAF5FFB75A1471B765C465B35A7C950019066BB219B391C6E9" + "8AE8FD2038E774F36F226D9FB9A38BCC313785612165D1EF69D19E2B9CF6E0F7" + "FE1ECCF00AB81F9E8B626363CA82FAC719A3B7D243325C9D6042B2488EC95B80" + "A31273FF9B72FBBB86F946E6D3DF8816BE4533F0B547C8BC028309EA9784C1E6\" " + "RCTICKET=\"65538,1,192.168.1.200:49230;169.254.6.170:49231,*," + "+ULZ6ifjoCa6cGPMLQiGHRPwkg6VyJqGwxMnO6GcelwUh9a6/FBq3It5ADSndmLL," + "*,*,BNRjdu97DyczQSRuMRrDWoue+HA=\" " + "PassStub=\"WB^6HsrIaFmEpi\" " + "RCTICKETENCRYPTED=\"1\" " + "DtStart=\"1403972263\" " + "DtLength=\"14400\" " + "L=\"0\"/>" + "</UPLOADINFO>"; + +/** + * Decrypted Connection String 2: + * + * <E> + * <A KH="BNRjdu97DyczQSRuMRrDWoue+HA=" + * ID="+ULZ6ifjoCa6cGPMLQiGHRPwkg6VyJqGwxMnO6GcelwUh9a6/FBq3It5ADSndmLL"/> <C> <T ID="1" SID="0"> <L + * P="49228" N="fe80::1032:53d9:5a01:909b%3"/> <L P="49229" N="fe80::3d8f:9b2d:6b4e:6aa%6"/> <L + * P="49230" N="192.168.1.200"/> <L P="49231" N="169.254.6.170"/> + * </T> + * </C> + * </E> + */ +static const char connectionstr2[] = + "<E>\n" + "<A KH=\"YiKwWUY8Ioq5NB3wAQHSbs5kwrM=\"\n" + "KH2=\"sha256:wKSAkAV3sBfa9WpuRFJcP9q1twJc6wOBuoJ9tsyXwpk=\"\n" + "ID=\"8rYm30RBW8/4dAWoUsWbFCF5jno/7jr5tNpHQc2goLbw4uuBBJvLsU02YYLlBMg5\"/>\n" + "<C>\n" + "<T ID=\"1\" SID=\"1440550163\">\n" + "<L P=\"49749\" N=\"2001:4898:1a:5:79e2:3356:9b22:3470\"/>\n" + "<L P=\"49751\" N=\"172.31.250.64\"/>\n" + "</T>\n" + "</C>\n" + "</E>"; + +static const char* fail_tests[] = { + "<UPLOADINFOTYPE=\"Escalated\"><UPLOADDATARCTICKET=\"65538,1, ,*,,*,*,\"/></UPLOADINFO>", + "<UPLOADINFO>(E><UPLOADDATA " + "FOTYPE=\"Escalated\"æÁATAPassStub=\"␕:&A&␅RCTICKET=\"65538,1,ü,*,n,*,*,\"am␡/>␂</" + "UPLOADINFO>" +}; + +static const char connectionstr3[] = + "<?xml version=\"1.0\"?>\n" + "<UPLOADINFO TYPE=\"Escalated\"><UPLOADDATA USERNAME=\"fx\" " + "LHTICKET=" + "\"F9BBA098D84E1B20E37CD0983D9336B1FF4929925FCE5F3A1A9B9A596A524F2E169AD26D84255C7E8C0B88304A4C" + "40E0544624AD346A6828D6F2091C36C1315BD11255FE631F3A457F862FFD9948C496BC4B705B0AD2F26D0CDF7128E4" + "8625C8C501326B33888D42C591434F7ED4BBA0CEE02C8554921E49BCF130E1961F38FD0F0B7333001E639F89471940" + "93136CA5030EC4A92D05341488B79C40E11B28E1753F38682816EDF756CF5204943FD3F60DDD16416D220CA162B6FB" + "D43CC00C4F9D3F9FCF68ADAF191470B75EA4E8B37D03D2B9D3D844F54597D75FFF0A6216811518A3D06B26CA95F733" + "CCE8A46A4B1FF8F514971A1C06A8DC9D1DD0863087707045D3FCB74BB0444AF8B822FD6605DA68D8D628A7D8556212" + "D10F5BC4B1B7905E863F51346114FFED6A46D67314F3B933DF17F8A2E5EC6DAD2904349AC710E017652171A98C8621" + "4AF3801B1441E641CDA159BE76D8F2415129773283B5A4E0E7483580E6955B54B0E1432129612CFECD6770201F4206" + "1732E748B7F8A0C015EA8B36610962AC208C26373A483E830C7E01330492C9CBAB308A5E19272CC06F0F8008068816" + "78F8FB32667D876F6060C50D1A1251DDB9B339E2F846F48C0C7751BBDFF2138152B7A048AFECB31F6DE340E81EB8A4" + "EC7F8208B81E11E13033659B885686FEDF6881355679DCD96661201E5BC59D6C6EEFA1608B9E73E75F42D51A26E236" + "3690714D58A846B48E0AA2C753CA6347BAEA59CDCA5144527F3A69B560980BCC5DB77AC0FD1A68D19F802744D723D8" + "6595A48D1F72DAD0E3E61BA4D37E24EAAB9F49F21753CD481D6744036CA49DA0E432B961F48810FE90EB49DB0FB450" + "5FB316DCCAAC51E647B333EBA1C219A68F0A08BD65C9E4ED231D40EA15C2CEB80CB161495A0CADECAF2A00B5916AA9" + "91B78C7B17F26DA880DE25DFC09D9D823E174A8401CBC846D2A8B29B6B26EE92261C71C37E3C816540F77CB6DE916B" + "FCC7ED100949503251687B860E4A5F5B51CDADD11FF5CA408FA38E4A2AD6FA09D10E9B85523236D55132CD42936150" + "51913820DAE06877AC2954651049A157730A1AB67BD9A258CCB3A71909A8686F6F742FBC55312B041342C5475F808A" + "B04B629B99A1C69200740CDA5FE1602518B3117FB9835060BEF22EBAF20676662C9E0C3ED39C01E2F9A0822A2ADA07" + "D4718A93516AA04E4527C699A00FA8AFCAC7337F8D42949B3CB9F35A19BF5AC9BBF412C9E4AE82C593897BFF81240C" + "002486DF0F14845BB12A15966E95A9B6090C6512AF8B717F720F0CE452AA602106B65B98374CBCF9F6B5300FB077E5" + "554B489F6913E3857E352C94929A69C86EB13A67B872BB69980B9B3A1E05D6B9483C26A0D6D83CCD4C1AB6C21BA625" + "A5232C25BC1B7EB8B954B52D91B1BDF4277B2DCE039F4DBE2F18AE22533C2B877AB27B157ACE5DF21BC83E72104A31" + "C253704FDB2536308280D7172313F5D19D088E4C7F4F79C4786D6C65DEAB7FC16DE107AF8C61626502FA940497987F" + "60759878E40EDFAC98DED90BEA26E3020AA36A7307F2C9A9D5B19FAA34DF3633F643425F16A3615C996691EC705617" + "97CEB08463CBD0150F6B4C01BF1337E3B8B5E5355F62AD1AF949FCB3671327EA5AABC90081117E6CE11C6C42CF6E0E" + "DCB4C63EA9433D89F1030F65EDC82D45289C6367BF1E004D338CED13B7643C8708C42FF3671377A79DBFE3E4A39E19" + "F4759B84AA9CB03D64C2DBF5D2908DE64F5534AC07C11723F3A7602E307625F86B410BC7B54D85145B9F362E181860" + "AEF3574682CE4F3C57742870ED0B228CAC0E9183BD07BFF0435989263CA7EBF21B8CF25DBC2C7915FEB1000848A52F" + "94E7B34A416A826BFB1792E64F1CEA7FA3222131C53FA6DE38A786C99C355FE9C9D55B91D11B19087F1574CFF28C4D" + "AA9DE974A0939F0C13E9C408167ABAB90BD6BB25FA37B1588AAA3687AC86818543FEFD6E46D821D7F68BE1B0793585" + "4E7A81F6C9A0965159DAFF7B0E79C89A18DA3C52D6259EA711ED6B85CCC207AA35F62CB5D48299DAD003004702716E" + "65A96390033F8006FC7E7B1A09B9D1C6C17EC20811DE09EC19EB36844E45FCA18CF657A81E5922AB1B805721A5457E" + "01EB86334877FEDA378EDE6190491015158194ED1DEE3A99770DB8B9A87BC9FAE29A0AC17C4963DF07109B05AABA73" + "1A6AACDB8A02795CBDA935D51D0A7ABB35D8D1B6E598751E45BD507EC2778E285BEBAB2B50462FED1975B5A87F9751" + "25A6F272560E756CC941CF6D22FE72F7563CB2687E56F2FA2FC07FE01F3C8E6FCF7D4ECD60C1A53B98CA57AFB5BA18" + "97D4F530FCDEBDEB015D9CB1DE0BED20B7C3221283E292C252C742C23401B2E5A85EBD63E6916C3051FEAA1DC57975" + "410487AD7EE6CA0A346FE44F901E8BA81A7B398E94707E094081AE6391696EC42DD3F4B9189AB2A5311811481A48FB" + "0FAEFC1E9858547D15AA2F6FF01191F8EEC3564C59172605DA16C94F466156BE7A3E98E8C53BE50B671DEC5A3BD8A9" + "8C2A1B3FF47D27007AB17A4A1E155E094E3EA30FF531FBF6320F23BA57B3CAF8C470E176C93FACEE829C58B2399975" + "EBC4688B2F55132D102E83E45976C6607A57B90F43A33BCB68C03671E632B0E7C17B18406161AB46A8A0992DA7046A" + "08135E04142B68312BE3D0F7F5BBAE914E8DC5AAD04D992DA18FAB5B01EA34A0E27B253E92BEFE607578B1C79D4DAC" + "07DA6F92986F12AE036C227E4495662C46762E66EA3EC71C5C04BADD9DEDCAD725C16710825394179CFD17EDE482BA" + "11C421D0B4C806A2ED963831FAB4DE14FEAA904A3C5173AB9B86FCFF81E0F60DB45182A2471BC16DA992553EAE99DD" + "716E85DB11AC0F32BC960D6E8F6BE2250D59EDCAA69C19AF04E21362331225F94BD600EE76E1719417480AB6DC62DF" + "958DCCE951EBC64B4600DF3A826B9E702C536C0DF9E2952EDA7FAE6076C6F25CF41C0F7751768EC3C3293D727F8541" + "E997DA23E2D952D782B0472B3BFBC638CBDFDA43F367E3F6A7AAC9C8B07D51459432AEBB11564A669BF2EC1658B361" + "BE29B47F905352D13705E1E7F06B68A5F247B9FFA3B917CC54F7367386502A42F32CEE474F5E4D35CB5A44C3BA2192" + "A3F61DC334CE6D91E36D1C891E65A30C1E2B8F66A01B5DA8DDFB5CD051D61BD39B2E0516C6715F9AA7FE262BBD9BA4" + "CE8B785B42CA9582AD5EE24F8C11D2DA0DC6383506DE46C5187C03A930E5E507812A505884121C8A93C2569B269AE7" + "A26FDCF0BF7FA996250FFF790C3E97565B27C8DECFE5A15E2ED1A853FBF5D12207B8D3564CDD99549E508E92CB53DB" + "F6356F6EBF03E6A6672BFDE285A3DF84105F7C7E39577838C06B50D2ABB4F1C0377D45BE016ED022804F6BD9151BCD" + "883CE5FE8358798EE4EA3C24C67815D535CBCFA36094D7418EC104F90609C7AC008D07FDF89A6B3A0B5EC505E17DEC" + "57DA6256F4B2CC7DFF4E643FE89E4934440E2A360F035FA9C91F0F657A88AC9E7210A9ABAAAEA26D6B717EEAF231FB" + "79A0838B4BB85C11C9675F2BC746230F79A88137F911809C472750A5F6BB9415298C638FC3E24FA1763ACB513A4200" + "CB0BF550BC7DE0D2DC5D45AF18FF6073D96D2E4368A637B78257D087C9A471CC88E3368E810BFC29002D86C898F75D" + "3F6AE13648841038FDD1D3E8C4D2D5A4E1044614CAF544758A68F4947E3A3E736255CF01FE7A40A6FF136E7458F13D" + "759086A544FA14B47155511F784A2144E2B139EC5B5F3B0CAB52E511AAF84E00ABB4115644D42B0A7F91DA53F5C54D" + "744C583F5E838D402512A9644772E256CACCAA90ED300AE1616FDAA8309E5FB3FD92EB09F32216446CA2E737E8C136" + "C3E773FB986060A78D87CDF7CD92B187188CA7293998F0BC33C13A2FD8C7B0A76C2DAA662F0A71965E25930294D351" + "947DDE4800A237871F6BBFA77B7440339BFAE36035A84DA6AD87AA57FD52F7CDA342EB3D7B3E46F64592DFF327194C" + "D80C83272B5159BD97A9254089C90E1AFC7C30265BA814ED485550E4E4157FEDB14D9FB6D05AEE5983C81E799DF134" + "00766571BDBC8AC719AA2228C9DD592C102DE18A3F1C4B3501C6B29424B83B71D1740B1775967CFC984BC2D22C15\"" + " PassStub=\"e4=3CiFuM6h2qH\" RCTICKETENCRYPTED=\"1\" DtStart=\"1704288424\" DtLength=\"360\" " + "L=\"0\"/>" + "</UPLOADINFO>"; +static const char connectionpwd3[] = "4X638PTVZTKZ"; + +static BOOL run_test_parse(wLog* log, const char* input, size_t len, const char* password, + BOOL expect) +{ + rdpAssistanceFile* file = freerdp_assistance_file_new(); + if (!file) + return FALSE; + + const int status = freerdp_assistance_parse_file_buffer(file, input, len, password); + const BOOL success = status >= 0; + + freerdp_assistance_print_file(file, log, WLOG_INFO); + freerdp_assistance_file_free(file); + return success == expect; +} + +static BOOL test_file_to_settings(wLog* log, rdpAssistanceFile* file) +{ + rdpSettings* settings = freerdp_settings_new(0); + if (!settings) + return FALSE; + const BOOL rc = freerdp_assistance_populate_settings_from_assistance_file(file, settings); + freerdp_settings_free(settings); + return rc; +} + +static BOOL test_file_from_buffer(wLog* log, const char* data, size_t size, const char* pwd) +{ + BOOL rc = FALSE; + int status = 0; + char* pass = NULL; + char* expertBlob = NULL; + const char* EncryptedPassStub = NULL; + size_t EncryptedPassStubLength = 0; + rdpAssistanceFile* file = freerdp_assistance_file_new(); + + if (!file) + return FALSE; + + status = freerdp_assistance_parse_file_buffer(file, data, size, pwd); + WLog_Print(log, WLOG_INFO, "freerdp_assistance_parse_file_buffer: %d", status); + + if (status < 0) + goto fail; + + freerdp_assistance_print_file(file, WLog_Get("foo"), WLOG_INFO); + + if (!freerdp_assistance_get_encrypted_pass_stub(file, &EncryptedPassStub, + &EncryptedPassStubLength)) + goto fail; + + if (EncryptedPassStubLength > 0) + { + pass = freerdp_assistance_bin_to_hex_string(EncryptedPassStub, EncryptedPassStubLength); + + if (!pass) + goto fail; + + WLog_Print(log, WLOG_INFO, "freerdp_assistance_decrypt: %d %s [%" PRIdz "]", status, pass, + EncryptedPassStubLength); + expertBlob = freerdp_assistance_construct_expert_blob("Edgar Olougouna", pass); + + WLog_Print(log, WLOG_INFO, "expertBlob='%s'", expertBlob); + } + rc = test_file_to_settings(log, file); +fail: + freerdp_assistance_file_free(file); + free(pass); + free(expertBlob); + return rc; +} + +static BOOL test_msrsc_incident_file_type1(wLog* log) +{ + return test_file_from_buffer(log, TEST_MSRC_INCIDENT_FILE_TYPE1, + sizeof(TEST_MSRC_INCIDENT_FILE_TYPE1), + TEST_MSRC_INCIDENT_PASSWORD_TYPE1); +} + +static BOOL test_msrsc_incident_file_type2(wLog* log) +{ + if (!test_file_from_buffer(log, connectionstr2, sizeof(connectionstr2), + TEST_MSRC_INCIDENT_PASSWORD_TYPE2)) + return FALSE; + if (!test_file_from_buffer(log, connectionstr3, sizeof(connectionstr3), connectionpwd3)) + return FALSE; + if (!test_file_from_buffer(log, TEST_MSRC_INCIDENT_FILE_TYPE2, + sizeof(TEST_MSRC_INCIDENT_FILE_TYPE2), + TEST_MSRC_INCIDENT_PASSWORD_TYPE2)) + return FALSE; + return TRUE; +} + +int TestCommonAssistance(int argc, char* argv[]) +{ + wLog* log = NULL; + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + log = WLog_Get(__func__); + winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT); + + for (size_t x = 0; x < ARRAYSIZE(fail_tests); x++) + { + const char* test = fail_tests[x]; + const size_t len = strlen(test); + + if (!run_test_parse(log, test, len + 1, NULL, FALSE)) + return -1; + } + + if (!test_msrsc_incident_file_type1(log)) + { + WLog_Print(log, WLOG_ERROR, "test_msrsc_incident_file_type1 failed"); + return -1; + } + + if (!test_msrsc_incident_file_type2(log)) + { + WLog_Print(log, WLOG_ERROR, "test_msrsc_incident_file_type2 failed"); + return -1; + } + + return 0; +} diff --git a/libfreerdp/common/test/TestFuzzCommonAssistanceBinToHexString.c b/libfreerdp/common/test/TestFuzzCommonAssistanceBinToHexString.c new file mode 100644 index 0000000..6b23c78 --- /dev/null +++ b/libfreerdp/common/test/TestFuzzCommonAssistanceBinToHexString.c @@ -0,0 +1,8 @@ +#include <freerdp/assistance.h> + +int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) +{ + char* pass = freerdp_assistance_bin_to_hex_string((void*)Data, Size); + free(pass); + return 0; +} diff --git a/libfreerdp/common/test/TestFuzzCommonAssistanceHexStringToBin.c b/libfreerdp/common/test/TestFuzzCommonAssistanceHexStringToBin.c new file mode 100644 index 0000000..b0847d8 --- /dev/null +++ b/libfreerdp/common/test/TestFuzzCommonAssistanceHexStringToBin.c @@ -0,0 +1,16 @@ +#include <freerdp/assistance.h> + +int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) +{ + char* buf = calloc(Size + 1, sizeof(char)); + if (buf == NULL) + return 0; + memcpy(buf, Data, Size); + buf[Size] = '\0'; + + BYTE* pass = freerdp_assistance_hex_string_to_bin((void*)buf, &Size); + free(pass); + free(buf); + + return 0; +} diff --git a/libfreerdp/common/test/TestFuzzCommonAssistanceParseFileBuffer.c b/libfreerdp/common/test/TestFuzzCommonAssistanceParseFileBuffer.c new file mode 100644 index 0000000..1900977 --- /dev/null +++ b/libfreerdp/common/test/TestFuzzCommonAssistanceParseFileBuffer.c @@ -0,0 +1,31 @@ +#include <freerdp/assistance.h> + +static int parse_file_buffer(const uint8_t* Data, size_t Size) +{ + static const char TEST_MSRC_INCIDENT_PASSWORD_TYPE2[] = "48BJQ853X3B4"; + int status = -1; + rdpAssistanceFile* file = freerdp_assistance_file_new(); + if (!file) + return -1; + + char* buf = calloc(Size + 1, sizeof(char)); + if (buf == NULL) + goto err; + memcpy(buf, Data, Size); + buf[Size] = '\0'; + + status = freerdp_assistance_parse_file_buffer(file, (char*)buf, Size + 1, + TEST_MSRC_INCIDENT_PASSWORD_TYPE2); + +err: + freerdp_assistance_file_free(file); + free(buf); + + return status >= 0 ? TRUE : FALSE; +} + +int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) +{ + parse_file_buffer(Data, Size); + return 0; +} |