⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rdesktop.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
				if (*p == '+' || *p == '-')
				{
					This->pos |= (*p == '-') ? 4 : 1;
					This->ypos = strtol(p, NULL, 10);
				}

				break;

			case 'f':
				This->fullscreen = True;
				break;

			case 'b':
				This->bitmap_cache = False;
				break;

			case 'B':
				This->ownbackstore = False;
				break;

			case 'e':
				This->encryption = False;
				break;
			case 'E':
				This->packet_encryption = False;
				break;
			case 'm':
				This->sendmotion = False;
				break;

			case 'C':
				This->owncolmap = True;
				break;

			case 'D':
				This->hide_decorations = True;
				break;

			case 'K':
				This->grab_keyboard = False;
				break;

			case 'S':
				if (!strcmp(optarg, "standard"))
				{
					This->win_button_size = 18;
					break;
				}

				This->win_button_size = strtol(optarg, &p, 10);

				if (*p)
				{
					error("invalid button size\n");
					return 1;
				}

				break;

			case 'T':
				STRNCPY(This->title, optarg, sizeof(This->title));
				break;

			case 'N':
				This->numlock_sync = True;
				break;

			case 'X':
				This->embed_wnd = strtol(optarg, NULL, 0);
				break;

			case 'a':
				This->server_depth = strtol(optarg, NULL, 10);
				if (This->server_depth != 8 &&
				    This->server_depth != 16 &&
				    This->server_depth != 15 && This->server_depth != 24)
				{
					error("Invalid server colour depth.\n");
					return 1;
				}
				break;

			case 'z':
				DEBUG(("rdp compression enabled\n"));
				flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
				break;

			case 'x':
				if (str_startswith(optarg, "m"))	/* modem */
				{
					This->rdp5_performanceflags =
						RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
						RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
				}
				else if (str_startswith(optarg, "b"))	/* broadband */
				{
					This->rdp5_performanceflags = RDP5_NO_WALLPAPER;
				}
				else if (str_startswith(optarg, "l"))	/* lan */
				{
					This->rdp5_performanceflags = RDP5_DISABLE_NOTHING;
				}
				else
				{
					This->rdp5_performanceflags = strtol(optarg, NULL, 16);
				}
				break;

			case 'P':
				This->bitmap_cache_persist_enable = True;
				break;

			case 'r':

				if (str_startswith(optarg, "sound"))
				{
					optarg += 5;

					if (*optarg == ':')
					{
						optarg++;
						while ((p = next_arg(optarg, ',')))
						{
							if (str_startswith(optarg, "remote"))
								flags |= RDP_LOGON_LEAVE_AUDIO;

							if (str_startswith(optarg, "local"))
#ifdef WITH_RDPSND
								This->rdpsnd_enabled = True;
#else
								warning("Not compiled with sound support\n");
#endif

							if (str_startswith(optarg, "off"))
#ifdef WITH_RDPSND
								This->rdpsnd_enabled = False;
#else
								warning("Not compiled with sound support\n");
#endif

							optarg = p;
						}
					}
					else
					{
#ifdef WITH_RDPSND
						This->rdpsnd_enabled = True;
#else
						warning("Not compiled with sound support\n");
#endif
					}
				}
				else if (str_startswith(optarg, "disk"))
				{
					/* -r disk:h:=/mnt/floppy */
					disk_enum_devices(This, &This->num_devices, optarg + 4);
				}
				else if (str_startswith(optarg, "comport"))
				{
					serial_enum_devices(This, &This->num_devices, optarg + 7);
				}
				else if (str_startswith(optarg, "lspci"))
				{
					This->lspci_enabled = True;
				}
				else if (str_startswith(optarg, "lptport"))
				{
					parallel_enum_devices(This, &This->num_devices, optarg + 7);
				}
				else if (str_startswith(optarg, "printer"))
				{
					printer_enum_devices(This, &This->num_devices, optarg + 7);
				}
				else if (str_startswith(optarg, "clientname"))
				{
					This->rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
					strcpy(This->rdpdr_clientname, optarg + 11);
				}
				else if (str_startswith(optarg, "clipboard"))
				{
					optarg += 9;

					if (*optarg == ':')
					{
						optarg++;

						if (str_startswith(optarg, "off"))
							This->rdpclip = False;
						else
							cliprdr_set_mode(This, optarg);
					}
					else
						This->rdpclip = True;
				}
				else
				{
					warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard\n");
				}
				break;

			case '0':
				This->console_session = True;
				break;

			case '4':
				This->use_rdp5 = False;
				break;

			case '5':
				This->use_rdp5 = True;
				break;

			case 'h':
			case '?':
			default:
				usage(argv[0]);
				return 1;
		}
	}

	if (argc - optind != 1)
	{
		usage(argv[0]);
		return 1;
	}

	STRNCPY(server, argv[optind], sizeof(server));
	parse_server_and_port(This, server);

	if (This->seamless_rdp)
	{
		if (This->win_button_size)
		{
			error("You cannot use -S and -A at the same time\n");
			return 1;
		}
		This->rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
		if (geometry_option)
		{
			error("You cannot use -g and -A at the same time\n");
			return 1;
		}
		if (This->fullscreen)
		{
			error("You cannot use -f and -A at the same time\n");
			return 1;
		}
		if (This->hide_decorations)
		{
			error("You cannot use -D and -A at the same time\n");
			return 1;
		}
		if (This->embed_wnd)
		{
			error("You cannot use -X and -A at the same time\n");
			return 1;
		}
		if (!This->use_rdp5)
		{
			error("You cannot use -4 and -A at the same time\n");
			return 1;
		}
		This->width = -100;
		This->grab_keyboard = False;
	}

	if (!username_option)
	{
		pw = getpwuid(getuid());
		if ((pw == NULL) || (pw->pw_name == NULL))
		{
			error("could not determine username, use -u\n");
			return 1;
		}

		STRNCPY(This->username, pw->pw_name, sizeof(This->username));
	}

#ifdef HAVE_ICONV
	if (This->codepage[0] == 0)
	{
		if (setlocale(LC_CTYPE, ""))
		{
			STRNCPY(This->codepage, nl_langinfo(CODESET), sizeof(This->codepage));
		}
		else
		{
			STRNCPY(This->codepage, DEFAULT_CODEPAGE, sizeof(This->codepage));
		}
	}
#endif

	if (This->hostname[0] == 0)
	{
		if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
		{
			error("could not determine local hostname, use -n\n");
			return 1;
		}

		p = strchr(fullhostname, '.');
		if (p != NULL)
			*p = 0;

		STRNCPY(This->hostname, fullhostname, sizeof(This->hostname));
	}

	if (This->keymapname[0] == 0)
	{
		if (locale && xkeymap_from_locale(This, locale))
		{
			fprintf(stderr, "Autoselected keyboard map %s\n", This->keymapname);
		}
		else
		{
			STRNCPY(This->keymapname, "en-us", sizeof(This->keymapname));
		}
	}
	if (locale)
		xfree(locale);


	if (prompt_password && read_password(password, sizeof(password)))
		flags |= RDP_LOGON_AUTO;

	if (This->title[0] == 0)
	{
		strcpy(This->title, "rdesktop - ");
		strncat(This->title, server, sizeof(This->title) - sizeof("rdesktop - "));
	}

#ifdef RDP2VNC
	rdp2vnc_connect(server, flags, domain, password, shell, directory);
	return 0;
#else

	if (!ui_init(This))
		return 1;

#ifdef WITH_RDPSND
	if (This->rdpsnd_enabled)
		rdpsnd_init(This);
#endif

	if (This->lspci_enabled)
		lspci_init(This);

	rdpdr_init(This);

	while (run_count < 2 && continue_connect)	/* add support for Session Directory; only reconnect once */
	{
		if (run_count == 0)
		{
			if (!rdp_connect(This, server, flags, domain, password, shell, directory))
				return 1;
		}
		else if (!rdp_reconnect
			 (This, server, flags, domain, password, shell, directory, This->redirect_cookie))
			return 1;

		/* By setting encryption to False here, we have an encrypted login
		   packet but unencrypted transfer of other packets */
		if (!This->packet_encryption)
			This->encryption = False;


		DEBUG(("Connection successful.\n"));
		memset(password, 0, sizeof(password));

		if (run_count == 0)
			if (!ui_create_window(This))
				continue_connect = False;

		if (continue_connect)
			rdp_main_loop(This, &deactivated, &ext_disc_reason);

		DEBUG(("Disconnecting...\n"));
		rdp_disconnect(This);

		if ((This->redirect == True) && (run_count == 0))	/* Support for Session Directory */
		{
			/* reset state of major globals */
			rdesktop_reset_state(This);

			STRNCPY(domain, This->redirect_domain, sizeof(domain));
			STRNCPY(This->username, This->redirect_username, sizeof(This->username));
			STRNCPY(password, This->redirect_password, sizeof(password));
			STRNCPY(server, This->redirect_server, sizeof(server));
			flags |= RDP_LOGON_AUTO;

			This->redirect = False;
		}
		else
		{
			continue_connect = False;
			ui_destroy_window(This);
			break;
		}

		run_count++;
	}

	cache_save_state(This);
	ui_deinit(This);

	if (ext_disc_reason >= 2)
		print_disconnect_reason(ext_disc_reason);

	if (deactivated)
	{
		/* clean disconnect */
		return 0;
	}
	else
	{
		if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect
		    || ext_disc_reason == exDiscReasonAPIInitiatedLogoff)
		{
			/* not so clean disconnect, but nothing to worry about */
			return 0;
		}
		else
		{
			/* return error */
			return 2;
		}
	}

#endif

}

#ifdef EGD_SOCKET
/* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
static BOOL
generate_random_egd(uint8 * buf)
{
	struct sockaddr_un addr;
	BOOL ret = False;
	int fd;

	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (fd == -1)
		return False;

	addr.sun_family = AF_UNIX;
	memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
	if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
		goto err;

	/* PRNGD and EGD use a simple communications protocol */
	buf[0] = 1;		/* Non-blocking (similar to /dev/urandom) */
	buf[1] = 32;		/* Number of requested random bytes */
	if (write(fd, buf, 2) != 2)
		goto err;

	if ((read(fd, buf, 1) != 1) || (buf[0] == 0))	/* Available? */
		goto err;

	if (read(fd, buf, 32) != 32)
		goto err;

	ret = True;

      err:
	close(fd);
	return ret;
}
#endif

/* Generate a 32-byte random for the secure transport code. */
void
generate_random(uint8 * random)
{
	struct stat st;
	struct tms tmsbuf;
	MD5_CTX md5;
	uint32 *r;
	int fd, n;

	/* If we have a kernel random device, try that first */
	if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
	    || ((fd = open("/dev/random", O_RDONLY)) != -1))
	{
		n = read(fd, random, 32);
		close(fd);
		if (n == 32)
			return;
	}

#ifdef EGD_SOCKET
	/* As a second preference use an EGD */
	if (generate_random_egd(random))
		return;
#endif

	/* Otherwise use whatever entropy we can gather - ideas welcome. */
	r = (uint32 *) random;
	r[0] = (getpid()) | (getppid() << 16);
	r[1] = (getuid()) | (getgid() << 16);
	r[2] = times(&tmsbuf);	/* system uptime (clocks) */
	gettimeofday((struct timeval *) &r[3], NULL);	/* sec and usec */
	stat("/tmp", &st);
	r[5] = st.st_atime;
	r[6] = st.st_mtime;
	r[7] = st.st_ctime;

	/* Hash both halves with MD5 to obscure possible patterns */
	MD5_Init(&md5);
	MD5_Update(&md5, random, 16);
	MD5_Final(random, &md5);
	MD5_Update(&md5, random + 16, 16);
	MD5_Final(random + 16, &md5);
}

/* malloc; exit if out of memory */
void *
xmalloc(int size)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -