Esempio n. 1
0
/**
 * Parse command-line arguments and update rdpSettings members accordingly.
 * @param settings pointer to rdpSettings struct to be updated.
 * @param argc number of arguments available.
 * @param argv string array of the arguments.
 * @param plugin_callback function to be called when a plugin needs to be loaded.
 * @param plugin_user_data pointer to be passed to the plugin_callback function.
 * @param ui_callback function to be called when a UI-specific argument is being processed.
 * @param ui_user_data pointer to be passed to the ui_callback function.
 * @return number of arguments that were parsed, or FREERDP_ARGS_PARSE_RESULT on failure or --version/--help
 */
int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
	ProcessPluginArgs plugin_callback, void* plugin_user_data,
	ProcessUIArgs ui_callback, void* ui_user_data)
{
	int t;
	char* p;
	int i, j;
	int index = 1;
	int num_extensions = 0;
	RDP_PLUGIN_DATA* plugin_data;

	while (index < argc)
	{
		if ((strcmp("-h", argv[index]) == 0 ) || (strcmp("--help", argv[index]) == 0 ))
		{
			printf("\n"
				"FreeRDP - A Free Remote Desktop Protocol Client\n"
				"See http://www.freerdp.com for more information\n"
				"\n"
				"Usage: %s [options] server:port\n"
				"  -0: connect to console session\n"
				"  -a: set color depth in bit, default is 16\n"
				"  -c: initial working directory\n"
				"  -D: hide window decorations\n"
				"  -T: window title\n"
				"  -d: domain\n"
				"  -f: fullscreen mode\n"
				"  -g: set geometry, using format WxH or X%% or 'workarea', default is 1024x768\n"
				"  -h: print this help\n"
				"  -k: set keyboard layout ID\n"
				"  -K: do not interfere with window manager bindings\n"
				"  -n: hostname\n"
				"  -o: console audio\n"
				"  -p: password\n"
				"  -s: set startup-shell\n"
				"  -t: alternative port number, default is 3389\n"
				"  -u: username\n"
				"  -x: performance flags (m[odem], b[roadband] or l[an])\n"
				"  -X: embed into another window with a given XID.\n"
				"  -z: enable compression\n"
				"  --app: RemoteApp connection. This implies -g workarea\n"
				"  --ext: load an extension\n"
				"  --no-auth: disable authentication\n"
				"  --authonly: authentication only, no UI\n"
				"  --from-stdin: unspecified username, password, domain and hostname params are prompted\n"
				"  --no-fastpath: disable fast-path\n"
				"  --no-motion: don't send mouse motion events\n"
				"  --gdi: graphics rendering (hw, sw)\n"
				"  --no-osb: disable offscreen bitmaps\n"
				"  --no-bmp-cache: disable bitmap cache\n"
				"  --bcv3: codec for bitmap cache v3 (rfx, nsc, jpeg)\n"
				"  --plugin: load a virtual channel plugin\n"
				"  --rfx: enable RemoteFX\n"
				"  --rfx-mode: RemoteFX operational flags (v[ideo], i[mage]), default is video\n"
				"  --frame-ack: number of frames pending to be acknowledged, default is 2 (disable with 0)\n"
				"  --nsc: enable NSCodec (experimental)\n"
#ifdef WITH_JPEG
				"  --jpeg: enable jpeg codec, uses 75 quality\n"
				"  --jpegex: enable jpeg and set quality(1..99)\n"
#endif
				"  --disable-wallpaper: disables wallpaper\n"
				"  --composition: enable desktop composition\n"
				"  --disable-full-window-drag: disables full window drag\n"
				"  --disable-menu-animations: disables menu animations\n"
				"  --disable-theming: disables theming\n"
				"  --no-nego: disable negotiation of security layer and enforce highest enabled security protocol\n"
				"  --no-rdp: disable Standard RDP encryption\n"
				"  --no-tls: disable TLS encryption\n"
				"  --no-nla: disable network level authentication\n"
				"  --ntlm: force NTLM authentication protocol version (1 or 2)\n"
				"  --ignore-certificate: ignore verification of logon certificate\n"
				"  --certificate-name: use this name for the logon certificate, instead of the server name\n"
				"  --sec: force protocol security (rdp, tls or nla)\n"
				"  --tsg: Terminal Server Gateway (<username> <password> <hostname>)\n"
				"  --kbd-list: list all keyboard layout ids used by -k\n"
				"  --no-salted-checksum: disable salted checksums with Standard RDP encryption\n"
				"  --pcid: preconnection id\n"
				"  --pcb: preconnection blob\n"
				"  --version: print version information\n"
				"\n", argv[0]);
			return FREERDP_ARGS_PARSE_HELP; /* TODO: What is the correct return? */
		}
		else if (strcmp("-a", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing color depth\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->color_depth = atoi(argv[index]);
		}
		else if (strcmp("-u", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing username\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->username = _strdup(argv[index]);
		}
		else if (strcmp("-p", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing password\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->password = _strdup(argv[index]);
			settings->autologon = 1;

			/*
			 * Overwrite original password which could be revealed by a simple "ps aux" command.
			 * This approach won't hide the password length, but it is better than nothing.
			 */

			memset(argv[index], '*', strlen(argv[index]));
		}
		else if (strcmp("-d", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing domain\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->domain = _strdup(argv[index]);
		}
		else if (strcmp("-s", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing shell\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->shell = _strdup(argv[index]);
		}
		else if (strcmp("-c", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing directory\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->directory = _strdup(argv[index]);
		}
		else if (strcmp("-g", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing dimensions\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}

			if (strncmp("workarea", argv[index], 1) == 0)
			{
				settings->workarea = TRUE;
			}
			else
			{
				settings->width = (UINT16) strtol(argv[index], &p, 10);

				if (*p == 'x')
				{
					settings->height = (UINT16) strtol(p + 1, &p, 10);
				}
				if (*p == '%')
				{
					settings->percent_screen = settings->width;
					if (settings->percent_screen <= 0 || settings->percent_screen > 100)
					{
						printf("invalid geometry percentage\n");
						return FREERDP_ARGS_PARSE_FAILURE;
					}
				}
				else
				{
					if (ui_callback != NULL)
						ui_callback(settings, "-g", p, ui_user_data);
				}
			}
		}
		else if (strcmp("-f", argv[index]) == 0)
		{
			settings->fullscreen = TRUE;
		}
		else if (strcmp("-D", argv[index]) == 0)
		{
			settings->decorations = FALSE;
		}
		else if (strcmp("-T", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing window title\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}

			settings->window_title = _strdup(argv[index]);
		}
		else if (strcmp("-t", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing port number\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->port = atoi(argv[index]);
		}
		else if (strcmp("-k", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing keyboard layout id\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			sscanf(argv[index], "%X", &(settings->kbd_layout));
		}
		else if (strcmp("-K", argv[index]) == 0)
		{
			settings->grab_keyboard = FALSE;
		}
		else if (strcmp("-n", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing client hostname\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			strncpy(settings->client_hostname, argv[index], 31);
			settings->client_hostname[31] = 0;
		}
		else if (strcmp("-o", argv[index]) == 0)
		{
			settings->console_audio = TRUE;
		}
		else if (strcmp("-0", argv[index]) == 0)
		{
			settings->console_session = TRUE;
		}
		else if (strcmp("-z", argv[index]) == 0)
		{
			settings->compression = TRUE;
		}
		else if (strcmp("--ntlm", argv[index]) == 0)
		{
			index++;

			settings->ntlm_version = atoi(argv[index]);

			if (settings->ntlm_version != 2)
				settings->ntlm_version = 1;
		}
		else if (strcmp("--no-glyph-cache", argv[index]) == 0)
		{
			settings->glyphSupportLevel = GLYPH_SUPPORT_NONE;
		}
		else if (strcmp("--no-osb", argv[index]) == 0)
		{
			settings->offscreen_bitmap_cache = FALSE;
		}
		else if (strcmp("--no-bmp-cache", argv[index]) == 0)
		{
			settings->bitmap_cache = FALSE;
		}
		else if (strcmp("--no-auth", argv[index]) == 0)
		{
			settings->authentication = FALSE;
		}
		else if (strcmp("--authonly", argv[index]) == 0)
		{
			settings->authentication_only = TRUE;
		}
		else if (strcmp("--from-stdin", argv[index]) == 0)
		{
			settings->from_stdin = TRUE;
		}
		else if (strcmp("--ignore-certificate", argv[index]) == 0)
		{
			settings->ignore_certificate = TRUE;
		}
		else if (strcmp("--certificate-name", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing certificate name\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}

			settings->certificate_name = _strdup(argv[index]);
		}
		else if (strcmp("--no-fastpath", argv[index]) == 0)
		{
			settings->fastpath_input = FALSE;
			settings->fastpath_output = FALSE;
		}
		else if (strcmp("--gdi", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing GDI backend\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			if (strncmp("sw", argv[index], 1) == 0) /* software */
			{
				settings->sw_gdi = TRUE;
			}
			else if (strncmp("hw", argv[index], 1) == 0) /* hardware */
			{
				settings->sw_gdi = FALSE;
			}
			else
			{
				printf("unknown GDI backend\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
		}
		else if (strcmp("--bcv3", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing codec name\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->bitmap_cache_v3 = TRUE;
			if (strcmp("rfx", argv[index]) == 0)
			{
				printf("setting rfx\n");
				settings->v3_codec_id = CODEC_ID_REMOTEFX;
				settings->rfx_codec = TRUE;
			}
			else if (strcmp("nsc", argv[index]) == 0)
			{
				printf("setting codec nsc\n");
				settings->v3_codec_id = CODEC_ID_NSCODEC;
				settings->ns_codec = TRUE;
			}
#ifdef WITH_JPEG
			else if (strcmp("jpeg", argv[index]) == 0)
			{
				printf("setting codec jpeg\n");
				settings->v3_codec_id = CODEC_ID_JPEG;
				settings->jpeg_codec = TRUE;
				if (settings->jpeg_quality == 0)
					settings->jpeg_quality = 75;
			}
#endif
			else
			{
				printf("bad codec name\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
		}
#ifdef WITH_JPEG
		else if (strcmp("--jpeg", argv[index]) == 0)
		{
			settings->jpeg_codec = TRUE;
			settings->jpeg_quality = 75;
		}
		else if (strcmp("--jpegex", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing codec name\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->jpeg_codec = TRUE;
			settings->jpeg_quality = atoi(argv[index]);
		}
#endif
		else if (strcmp("--rfx", argv[index]) == 0)
		{
			settings->rfx_codec = TRUE;
			settings->fastpath_output = TRUE;
			settings->color_depth = 32;
			settings->performance_flags = PERF_FLAG_NONE;
			settings->large_pointer = TRUE;
		}
		else if (strcmp("--rfx-mode", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing RemoteFX mode flag\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			if (argv[index][0] == 'v') /* video */
			{
				settings->rfx_codec_mode = 0x00;
			}
			else if (argv[index][0] == 'i') /* image */
			{
				settings->rfx_codec_mode = 0x02;
			}
			else
			{
				printf("unknown RemoteFX mode flag\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
		}
		else if (strcmp("--frame-ack", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing frame acknowledge number\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->frame_acknowledge = atoi(argv[index]);
		}
		else if (strcmp("--nsc", argv[index]) == 0)
		{
			settings->ns_codec = TRUE;
		}
		else if (strcmp("--dump-rfx", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing file name\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->dump_rfx_file = _strdup(argv[index]);
			settings->dump_rfx = TRUE;
			settings->rfx_codec_only = TRUE;
		}
		else if (strcmp("--play-rfx", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing file name\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			settings->play_rfx_file = _strdup(argv[index]);
			settings->play_rfx = TRUE;
		}
		else if (strcmp("--fonts", argv[index]) == 0)
		{
			settings->smooth_fonts = TRUE;
		}
		else if (strcmp("--disable-wallpaper", argv[index]) == 0)
		{
			settings->disable_wallpaper = TRUE;
		}
		else if (strcmp("--disable-full-window-drag", argv[index]) == 0)
		{
			settings->disable_full_window_drag = TRUE;
		}
		else if (strcmp("--disable-menu-animations", argv[index]) == 0)
		{
			settings->disable_menu_animations = TRUE;
		}
		else if (strcmp("--disable-theming", argv[index]) == 0)
		{
			settings->disable_theming = TRUE;
		}
		else if (strcmp("--composition", argv[index]) == 0)
		{
			settings->desktop_composition = TRUE;
		}
		else if (strcmp("--no-motion", argv[index]) == 0)
		{
			settings->mouse_motion = FALSE;
		}
		else if (strcmp("--app", argv[index]) == 0)
		{
			settings->remote_app = TRUE;
			settings->rail_langbar_supported = TRUE;
			settings->workarea = TRUE;
			settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG;
		}
		else if (strcmp("-x", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing performance flag\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			if (argv[index][0] == 'm') /* modem */
			{
				settings->performance_flags = PERF_DISABLE_WALLPAPER |
					PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
					PERF_DISABLE_THEMING;

				settings->connection_type = CONNECTION_TYPE_MODEM;
			}
			else if (argv[index][0] == 'b') /* broadband */
			{
				settings->performance_flags = PERF_DISABLE_WALLPAPER;
				settings->connection_type = CONNECTION_TYPE_BROADBAND_HIGH;
			}
			else if (argv[index][0] == 'l') /* lan */
			{
				settings->performance_flags = PERF_FLAG_NONE;
				settings->connection_type = CONNECTION_TYPE_LAN;
			}
			else
			{
				settings->performance_flags = strtol(argv[index], 0, 16);
			}
		}
		else if (strcmp("-X", argv[index]) == 0)
		{
			index++;

			if (index == argc)
			{
				printf("missing parent window XID\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}

			settings->parent_window_xid = strtol(argv[index], NULL, 0);

			if (settings->parent_window_xid == 0)
			{
				printf("invalid parent window XID\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
		}
		else if (strcmp("--no-rdp", argv[index]) == 0)
		{
			settings->rdp_security = FALSE;
		}
		else if (strcmp("--no-tls", argv[index]) == 0)
		{
			settings->tls_security = FALSE;
		}
		else if (strcmp("--no-nla", argv[index]) == 0)
		{
			settings->nla_security = FALSE;
		}
		else if (strcmp("--sec", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing protocol security\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			if (strncmp("rdp", argv[index], 1) == 0) /* Standard RDP */
			{
				settings->rdp_security = TRUE;
				settings->tls_security = FALSE;
				settings->nla_security = FALSE;
				settings->encryption = TRUE;
				settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
				settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
			}
			else if (strncmp("tls", argv[index], 1) == 0) /* TLS */
			{
				settings->rdp_security = FALSE;
				settings->tls_security = TRUE;
				settings->nla_security = FALSE;
			}
			else if (strncmp("nla", argv[index], 1) == 0) /* NLA */
			{
				settings->rdp_security = FALSE;
				settings->tls_security = FALSE;
				settings->nla_security = TRUE;
			}
			else
			{
				printf("unknown protocol security\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
		}
		else if (strcmp("--no-nego", argv[index]) == 0)
		{
			settings->security_layer_negotiation = FALSE;
		}
		else if (strcmp("--tsg", argv[index]) == 0)
		{
			settings->ts_gateway = TRUE;
			index++;
			if (index == argc)
			{
				printf("missing TSG username\n");
				return -1;
			}
			settings->tsg_username = _strdup(argv[index]);
			index++;
			if (index == argc)
			{
				printf("missing TSG password\n");
				return -1;
			}
			settings->tsg_password = _strdup(argv[index]);
			index++;
			if (index == argc)
			{
				printf("missing TSG server\n");
				return -1;
			}
			settings->tsg_hostname = _strdup(argv[index]);
		}
		else if (strcmp("--plugin", argv[index]) == 0)
		{
			index++;
			t = index;
			if (index == argc)
			{
				printf("missing plugin name\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			plugin_data = NULL;
			if (strstr(argv[t], "rdpsnd"))
				settings->audio_playback = TRUE;
			if (index < argc - 1 && strcmp("--data", argv[index + 1]) == 0)
			{
				index += 2;
				i = 0;
				while (index < argc && strcmp("--", argv[index]) != 0)
				{
					if (plugin_data == NULL)
						plugin_data = (RDP_PLUGIN_DATA*) malloc(sizeof(RDP_PLUGIN_DATA) * (i + 2));
					else
						plugin_data = (RDP_PLUGIN_DATA*) realloc(plugin_data, sizeof(RDP_PLUGIN_DATA) * (i + 2));

					if (strstr(argv[t], "drdynvc") && strstr(argv[index], "audin"))
						settings->audio_capture = TRUE;

					plugin_data[i].size = sizeof(RDP_PLUGIN_DATA);
					plugin_data[i].data[0] = NULL;
					plugin_data[i].data[1] = NULL;
					plugin_data[i].data[2] = NULL;
					plugin_data[i].data[3] = NULL;
					plugin_data[i + 1].size = 0;

					for (j = 0, p = argv[index]; j < 4 && p != NULL; j++)
					{
						if (*p == '\'')
						{
							plugin_data[i].data[j] = p + 1;
							p = strchr(p + 1, '\'');
							if (p)
								*p++ = 0;
						}
						else
							plugin_data[i].data[j] = p;

						p = strchr(p, ':');
						if (p != NULL)
							*p++ = 0;
					}
					index++;
					i++;
				}
			}

			if (plugin_callback != NULL)
			{
				if (!plugin_callback(settings, argv[t], plugin_data, plugin_user_data))
					return FREERDP_ARGS_PARSE_FAILURE;
			}
		}
		else if (strcmp("--ext", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing extension name\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			if (num_extensions >= ARRAY_SIZE(settings->extensions))
			{
				printf("maximum extensions reached\n");
				return FREERDP_ARGS_PARSE_FAILURE;
			}
			snprintf(settings->extensions[num_extensions].name,
				sizeof(settings->extensions[num_extensions].name),
				"%s", argv[index]);
			settings->extensions[num_extensions].data = NULL;
			if (index < argc - 1 && strcmp("--data", argv[index + 1]) == 0)
			{
				index += 2;
				settings->extensions[num_extensions].data = argv[index];
				i = 0;
				while (index < argc && strcmp("--", argv[index]) != 0)
				{
					index++;
					i++;
				}
			}
			num_extensions++;
		}
		else if (strcmp("--no-salted-checksum", argv[index]) == 0)
		{
			settings->salted_checksum = FALSE;
		}
		else if (strcmp("--pcid", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing preconnection id value\n");
				return -1;
			}
			settings->send_preconnection_pdu = TRUE;
			settings->preconnection_id = atoi(argv[index]);
		}
		else if (strcmp("--pcb", argv[index]) == 0)
		{
			index++;
			if (index == argc)
			{
				printf("missing preconnection blob value\n");
				return -1;
			}
			settings->send_preconnection_pdu = TRUE;
			settings->preconnection_blob = _strdup(argv[index]);
		}
		else if (strcmp("--version", argv[index]) == 0)
		{
			printf("This is FreeRDP version %s (git %s)\n", FREERDP_VERSION_FULL, GIT_REVISION);
			return FREERDP_ARGS_PARSE_VERSION;
		}
		else if (argv[index][0] != '-')
		{
			freerdp_parse_hostname(settings, argv[index]);

			/* server is the last argument for the current session. arguments
			   followed will be parsed for the next session. */
			index++;

			if (settings->smooth_fonts)
				settings->performance_flags |= PERF_ENABLE_FONT_SMOOTHING;

			if (settings->desktop_composition)
				settings->performance_flags |= PERF_ENABLE_DESKTOP_COMPOSITION;

			if (settings->disable_wallpaper)
				settings->performance_flags |= PERF_DISABLE_WALLPAPER;

			if (settings->disable_full_window_drag)
				settings->performance_flags |= PERF_DISABLE_FULLWINDOWDRAG;

			if (settings->disable_menu_animations)
				settings->performance_flags |= PERF_DISABLE_MENUANIMATIONS;

			if (settings->disable_theming)
				settings->performance_flags |= PERF_DISABLE_THEMING;

			break; /* post process missing arguments */

		}
		else
		{
			if (ui_callback != NULL)
			{
				t = ui_callback(settings, argv[index], (index + 1 < argc && argv[index + 1][0] != '-' ?
					argv[index + 1] : NULL), ui_user_data);
				if (t == 0)
				{
					printf("invalid option: %s\n", argv[index]);
					return FREERDP_ARGS_PARSE_FAILURE;
				}
				index += t - 1;
			}
		}
		index++;
	}


	/* --from-stdin will prompt for missing arguments only.
		 You can prompt for username, password, domain and hostname to avoid disclosing
		 these settings to ps. */

	if (settings->from_stdin)
	{
		/* username */
		if (NULL == settings->username)
		{
			char input[512];
			input[0] = '\0';
			printf("username: "******"%511s%*c", input) > 0)
			{
				settings->username = _strdup(input);
			}
		}
		/* password */
		if (NULL == settings->password)
		{
			settings->password = malloc(512 * sizeof(char));
			if (isatty(STDIN_FILENO))
			{
				freerdp_passphrase_read("password: "******"password: "******"%511s%*c", settings->password) <= 0)
				{
					free(settings->password);
					settings->password = NULL;
				}
			}
		}
		/* domain */
		if (NULL == settings->domain)
		{
			char input[512];
			input[0] = '\0';
			printf("domain (control-D to skip): ");
			if (scanf("%511s%*c", input) > 0)
			{
				/* Try to catch the cases where the string is NULL-ish right
				   at the get go */
				if (input[0] != '\0' && !(input[0] == '.' && input[1] == '\0'))
				{
					settings->domain = _strdup(input);
				}
			}
			if (feof(stdin))
			{
				printf("\n");
				clearerr(stdin);
			}
		}
		/* hostname */
		if (NULL == settings->hostname)
		{
			char input[512];
			input[0] = '\0';
			printf("hostname: ");
			if (scanf("%511s%*c", input) > 0)
			{
				freerdp_parse_hostname(settings, input);
			}
		}
	}

	/* Must have a hostname. Do you? */
	if (NULL == settings->hostname)
	{
		printf("missing server name\n");
		return FREERDP_ARGS_PARSE_FAILURE;
	}
	else
	{
		return index;
	}

}
Esempio n. 2
0
BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings)
{
	if (~((size_t) file->Domain))
		freerdp_set_param_string(settings, FreeRDP_Domain, file->Domain);

	if (~((size_t) file->Username))
	{
		char* user = NULL;
		char* domain = NULL;

		freerdp_parse_username(file->Username, &user, &domain);
		freerdp_set_param_string(settings, FreeRDP_Username, user);

		if (domain)
			freerdp_set_param_string(settings, FreeRDP_Domain, domain);

		if (user)
			free(user);

		if (domain)
			free(domain);
	}

	if (~((size_t) file->FullAddress))
	{
		int port = -1;
		char* host = NULL;

		freerdp_parse_hostname(file->FullAddress, &host, &port);

		freerdp_set_param_string(settings, FreeRDP_ServerHostname, host);

		if (port > 0)
			freerdp_set_param_uint32(settings, FreeRDP_ServerPort, (UINT32) port);

		free(host);
	}

	if (~file->ServerPort)
		freerdp_set_param_uint32(settings, FreeRDP_ServerPort, file->ServerPort);

	if (~file->DesktopWidth)
		freerdp_set_param_uint32(settings, FreeRDP_DesktopWidth, file->DesktopWidth);
	if (~file->DesktopHeight)
		freerdp_set_param_uint32(settings, FreeRDP_DesktopHeight, file->DesktopHeight);
	if (~file->SessionBpp)
		freerdp_set_param_uint32(settings, FreeRDP_ColorDepth, file->SessionBpp);
	if (~file->ConnectToConsole)
		freerdp_set_param_bool(settings, FreeRDP_ConsoleSession, file->ConnectToConsole);
	if (~file->AdministrativeSession)
		freerdp_set_param_bool(settings, FreeRDP_ConsoleSession, file->AdministrativeSession);
	if (~file->NegotiateSecurityLayer)
		freerdp_set_param_bool(settings, FreeRDP_NegotiateSecurityLayer, file->NegotiateSecurityLayer);
	if (~file->EnableCredSSPSupport)
		freerdp_set_param_bool(settings, FreeRDP_NlaSecurity, file->EnableCredSSPSupport);
	if (~((size_t) file->AlternateShell))
		freerdp_set_param_string(settings, FreeRDP_AlternateShell, file->AlternateShell);
	if (~((size_t) file->ShellWorkingDirectory))
		freerdp_set_param_string(settings, FreeRDP_ShellWorkingDirectory, file->ShellWorkingDirectory);

	if (~file->ScreenModeId)
	{
		/**
		 * Screen Mode Id:
		 * http://technet.microsoft.com/en-us/library/ff393692/
		 *
		 * This setting corresponds to the selection in the Display
		 * configuration slider on the Display tab under Options in RDC.
		 *
		 * Values:
		 *
		 * 1: The remote session will appear in a window.
		 * 2: The remote session will appear full screen.
		 */

		freerdp_set_param_bool(settings, FreeRDP_Fullscreen,
				(file->ScreenModeId == 2) ? TRUE : FALSE);
	}

	if (~((size_t) file->SmartSizing))
	{
		freerdp_set_param_bool(settings, FreeRDP_SmartSizing,
				(file->SmartSizing == 1) ? TRUE : FALSE);
	}

	if (~((size_t) file->LoadBalanceInfo))
	{
		settings->LoadBalanceInfo = (BYTE*) _strdup(file->LoadBalanceInfo);
		settings->LoadBalanceInfoLength = (int) strlen((char*) settings->LoadBalanceInfo);
	}

	if (~file->AuthenticationLevel)
	{
		/**
		 * Authentication Level:
		 * http://technet.microsoft.com/en-us/library/ff393709/
		 *
		 * This setting corresponds to the selection in the If server authentication
		 * fails drop-down list on the Advanced tab under Options in RDC.
		 *
		 * Values:
		 *
		 * 0: If server authentication fails, connect to the computer without warning (Connect and don’t warn me).
		 * 1: If server authentication fails, do not establish a connection (Do not connect).
		 * 2: If server authentication fails, show a warning and allow me to connect or refuse the connection (Warn me).
		 * 3: No authentication requirement is specified.
		 */

		freerdp_set_param_bool(settings, FreeRDP_IgnoreCertificate,
				(file->AuthenticationLevel == 0) ? TRUE : FALSE);
	}

	if (~file->ConnectionType)
		freerdp_set_param_uint32(settings, FreeRDP_ConnectionType, file->ConnectionType);

	if (~file->AudioMode)
	{
		if (file->AudioMode == AUDIO_MODE_REDIRECT)
		{
			freerdp_set_param_bool(settings, FreeRDP_AudioPlayback, TRUE);
		}
		else if (file->AudioMode == AUDIO_MODE_PLAY_ON_SERVER)
		{
			freerdp_set_param_bool(settings, FreeRDP_RemoteConsoleAudio, TRUE);
		}
		else if (file->AudioMode == AUDIO_MODE_NONE)
		{
			freerdp_set_param_bool(settings, FreeRDP_AudioPlayback, FALSE);
			freerdp_set_param_bool(settings, FreeRDP_RemoteConsoleAudio, FALSE);
		}
	}

	if (~file->Compression)
		freerdp_set_param_bool(settings, FreeRDP_CompressionEnabled, file->Compression);

	if (~((size_t) file->GatewayHostname))
	{
		int port = -1;
		char* host = NULL;

		freerdp_parse_hostname(file->GatewayHostname, &host, &port);

		freerdp_set_param_string(settings, FreeRDP_GatewayHostname, host);

		if (port > 0)
			freerdp_set_param_uint32(settings, FreeRDP_GatewayPort, (UINT32) port);

		free(host);
	}

	if (~file->GatewayUsageMethod)
		freerdp_set_gateway_usage_method(settings, file->GatewayUsageMethod);

	if (~file->PromptCredentialOnce)
		freerdp_set_param_bool(settings, FreeRDP_GatewayUseSameCredentials, file->PromptCredentialOnce);
	
	if (~file->RemoteApplicationMode)
		freerdp_set_param_bool(settings, FreeRDP_RemoteApplicationMode, file->RemoteApplicationMode);
	if (~((size_t) file->RemoteApplicationProgram))
		freerdp_set_param_string(settings, FreeRDP_RemoteApplicationProgram, file->RemoteApplicationProgram);
	if (~((size_t) file->RemoteApplicationName))
		freerdp_set_param_string(settings, FreeRDP_RemoteApplicationName, file->RemoteApplicationName);
	if (~((size_t) file->RemoteApplicationIcon))
		freerdp_set_param_string(settings, FreeRDP_RemoteApplicationIcon, file->RemoteApplicationIcon);
	if (~((size_t) file->RemoteApplicationFile))
		freerdp_set_param_string(settings, FreeRDP_RemoteApplicationGuid, file->RemoteApplicationGuid);
	if (~((size_t) file->RemoteApplicationCmdLine))
		freerdp_set_param_string(settings, FreeRDP_RemoteApplicationCmdLine, file->RemoteApplicationCmdLine);

	if (~file->SpanMonitors)
		freerdp_set_param_bool(settings, FreeRDP_SpanMonitors, file->SpanMonitors);
	if (~file->UseMultiMon)
		freerdp_set_param_bool(settings, FreeRDP_UseMultimon, file->UseMultiMon);

	if (~file->AllowFontSmoothing)
		freerdp_set_param_bool(settings, FreeRDP_AllowFontSmoothing, file->AllowFontSmoothing);
	if (~file->DisableWallpaper)
		freerdp_set_param_bool(settings, FreeRDP_DisableWallpaper, file->DisableWallpaper);
	if (~file->DisableFullWindowDrag)
		freerdp_set_param_bool(settings, FreeRDP_DisableFullWindowDrag, file->DisableFullWindowDrag);
	if (~file->DisableMenuAnims)
		freerdp_set_param_bool(settings, FreeRDP_DisableMenuAnims, file->DisableMenuAnims);
	if (~file->DisableThemes)
		freerdp_set_param_bool(settings, FreeRDP_DisableThemes, file->DisableThemes);
	if (~file->AllowDesktopComposition)
		freerdp_set_param_bool(settings, FreeRDP_AllowDesktopComposition, file->AllowDesktopComposition);

	if (~file->BitmapCachePersistEnable)
		freerdp_set_param_bool(settings, FreeRDP_BitmapCachePersistEnabled, file->BitmapCachePersistEnable);

	if (~file->DisableRemoteAppCapsCheck)
		freerdp_set_param_bool(settings, FreeRDP_DisableRemoteAppCapsCheck, file->DisableRemoteAppCapsCheck);

	if (~file->AutoReconnectionEnabled)
		freerdp_set_param_bool(settings, FreeRDP_AutoReconnectionEnabled, file->AutoReconnectionEnabled);
	if (~file->AutoReconnectMaxRetries)
		freerdp_set_param_uint32(settings, FreeRDP_AutoReconnectMaxRetries, file->AutoReconnectMaxRetries);

	if (~file->RedirectSmartCards)
		freerdp_set_param_bool(settings, FreeRDP_RedirectSmartCards, file->RedirectSmartCards);

	if (~file->RedirectClipboard)
		freerdp_set_param_bool(settings, FreeRDP_RedirectClipboard, file->RedirectClipboard);

	if (~file->RedirectPrinters)
		freerdp_set_param_bool(settings, FreeRDP_RedirectPrinters, file->RedirectPrinters);

	if (~file->RedirectDrives)
		freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, file->RedirectDrives);

	if (~file->RedirectPosDevices)
	{
		freerdp_set_param_bool(settings, FreeRDP_RedirectSerialPorts, file->RedirectComPorts);
		freerdp_set_param_bool(settings, FreeRDP_RedirectParallelPorts, file->RedirectComPorts);
	}

	if (~file->RedirectComPorts)
	{
		freerdp_set_param_bool(settings, FreeRDP_RedirectSerialPorts, file->RedirectComPorts);
		freerdp_set_param_bool(settings, FreeRDP_RedirectParallelPorts, file->RedirectComPorts);
	}

	if (~file->RedirectDirectX)
	{
		/* What is this?! */
	}

	if (~((size_t) file->DevicesToRedirect))
	{
		/**
		 * Devices to redirect:
		 * http://technet.microsoft.com/en-us/library/ff393728/
		 *
		 * This setting corresponds to the selections for Other supported Plug and Play
		 * (PnP) devices under More on the Local Resources tab under Options in RDC.
		 *
		 * Values:
		 *
		 * '*':
		 * 	Redirect all supported Plug and Play devices.
		 *
		 * 'DynamicDevices':
		 * 	Redirect any supported Plug and Play devices that are connected later.
		 *
		 * The hardware ID for the supported Plug and Play device:
		 * 	Redirect the specified supported Plug and Play device.
		 *
		 * Examples:
		 * 	devicestoredirect:s:*
		 * 	devicestoredirect:s:DynamicDevices
		 * 	devicestoredirect:s:USB\VID_04A9&PID_30C1\6&4BD985D&0&2;,DynamicDevices
		 *
		 */

		freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE);
	}

	if (~((size_t) file->DrivesToRedirect))
	{
		/*
		 * Drives to redirect:
		 *
		 * Very similar to DevicesToRedirect, but can contain a
		 * comma-separated list of drive letters to redirect.
		 */

		freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE);
	}

	if (file->argc > 1)
	{
		char* ConnectionFile = settings->ConnectionFile;

		settings->ConnectionFile = NULL;
		freerdp_client_settings_parse_command_line(settings, file->argc, file->argv);
		settings->ConnectionFile = ConnectionFile;
	}

	return TRUE;
}