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

📄 rdp.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
	in_uint16_le(s, masklen);
	in_uint16_le(s, datalen);
	in_uint8p(s, data, datalen);
	in_uint8p(s, mask, masklen);
	cursor = ui_create_cursor(This, x, y, width, height, mask, data);
	ui_set_cursor(This, cursor);
	cache_put_cursor(This, cache_idx, cursor);
}

/* Process a cached pointer PDU */
void
process_cached_pointer_pdu(RDPCLIENT * This, STREAM s)
{
	uint16 cache_idx;

	in_uint16_le(s, cache_idx);
	ui_set_cursor(This, cache_get_cursor(This, cache_idx));
}

/* Process a system pointer PDU */
void
process_system_pointer_pdu(RDPCLIENT * This, STREAM s)
{
	uint16 system_pointer_type;

	in_uint16(s, system_pointer_type);
	switch (system_pointer_type)
	{
		case RDP_NULL_POINTER:
			ui_set_null_cursor(This);
			break;

		default:
			unimpl("System pointer message 0x%x\n", system_pointer_type);
	}
}

/* Process a pointer PDU */
static void
process_pointer_pdu(RDPCLIENT * This, STREAM s)
{
	uint16 message_type;
	uint16 x, y;

	in_uint16_le(s, message_type);
	in_uint8s(s, 2);	/* pad */

	switch (message_type)
	{
		case RDP_POINTER_MOVE:
			in_uint16_le(s, x);
			in_uint16_le(s, y);
			if (s_check(s))
				ui_move_pointer(This, x, y);
			break;

		case RDP_POINTER_COLOR:
			process_colour_pointer_pdu(This, s);
			break;

		case RDP_POINTER_CACHED:
			process_cached_pointer_pdu(This, s);
			break;

		case RDP_POINTER_SYSTEM:
			process_system_pointer_pdu(This, s);
			break;

		default:
			unimpl("Pointer message 0x%x\n", message_type);
	}
}

/* Process bitmap updates */
void
process_bitmap_updates(RDPCLIENT * This, STREAM s)
{
	uint16 num_updates;
	uint16 left, top, right, bottom, width, height;
	uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
	uint8 *data, *bmpdata;
	int i;

	in_uint16_le(s, num_updates);

	for (i = 0; i < num_updates; i++)
	{
		in_uint16_le(s, left);
		in_uint16_le(s, top);
		in_uint16_le(s, right);
		in_uint16_le(s, bottom);
		in_uint16_le(s, width);
		in_uint16_le(s, height);
		in_uint16_le(s, bpp);
		Bpp = (bpp + 7) / 8;
		in_uint16_le(s, compress);
		in_uint16_le(s, bufsize);

		cx = right - left + 1;
		cy = bottom - top + 1;

		DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
		       left, top, right, bottom, width, height, Bpp, compress));

		if (!compress)
		{
#if 0
			int y;
			bmpdata = (uint8 *) xmalloc(width * height * Bpp);
			for (y = 0; y < height; y++)
			{
				in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
					  width * Bpp);
			}
			ui_paint_bitmap(This, left, top, cx, cy, width, height, bmpdata);
			xfree(bmpdata);
#else
			in_uint8p(s, bmpdata, width * height * Bpp);
			ui_paint_bitmap(This, left, top, cx, cy, width, height, bmpdata);
#endif
			continue;
		}


		if (compress & 0x400)
		{
			size = bufsize;
		}
		else
		{
			in_uint8s(s, 2);	/* pad */
			in_uint16_le(s, size);
			in_uint8s(s, 4);	/* line_size, final_size */
		}
		in_uint8p(s, data, size);
		bmpdata = (uint8 *) malloc(width * height * Bpp);

		if(bmpdata == NULL)
			return;

		if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
		{
			ui_paint_bitmap(This, left, top, cx, cy, width, height, bmpdata);
		}
		else
		{
			DEBUG_RDP5(("Failed to decompress data\n"));
		}

		free(bmpdata);
	}
}

/* Process a palette update */
void
process_palette(RDPCLIENT * This, STREAM s)
{
	COLOURENTRY *entry;
	COLOURMAP map;
	HCOLOURMAP hmap;
	int i;

	in_uint8s(s, 2);	/* pad */
	in_uint16_le(s, map.ncolours);
	in_uint8s(s, 2);	/* pad */

	map.colours = (COLOURENTRY *) malloc(sizeof(COLOURENTRY) * map.ncolours);

	if(map.colours == NULL)
	{
		in_uint8s(s, sizeof(*entry) * map.ncolours);
		return;
	}

	DEBUG(("PALETTE(c=%d)\n", map.ncolours));

	for (i = 0; i < map.ncolours; i++)
	{
		entry = &map.colours[i];
		in_uint8(s, entry->red);
		in_uint8(s, entry->green);
		in_uint8(s, entry->blue);
	}

	hmap = ui_create_colourmap(This, &map);
	ui_set_colourmap(This, hmap);

	free(map.colours);
}

/* Process an update PDU */
static void
process_update_pdu(RDPCLIENT * This, STREAM s)
{
	uint16 update_type, count;

	in_uint16_le(s, update_type);

	ui_begin_update(This);
	switch (update_type)
	{
		case RDP_UPDATE_ORDERS:
			in_uint8s(s, 2);	/* pad */
			in_uint16_le(s, count);
			in_uint8s(s, 2);	/* pad */
			process_orders(This, s, count);
			break;

		case RDP_UPDATE_BITMAP:
			process_bitmap_updates(This, s);
			break;

		case RDP_UPDATE_PALETTE:
			process_palette(This, s);
			break;

		case RDP_UPDATE_SYNCHRONIZE:
			break;

		default:
			unimpl("update %d\n", update_type);
	}
	ui_end_update(This);
}

/* Process a disconnect PDU */
void
process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
{
	in_uint32_le(s, *ext_disc_reason);

	DEBUG(("Received disconnect PDU\n"));
}

/* Process data PDU */
static BOOL
process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason)
{
	uint8 data_pdu_type;
	uint8 ctype;
	uint16 clen;
	uint32 len;

	uint32 roff, rlen;

	struct stream *ns = &(This->mppc_dict.ns);

	in_uint8s(s, 6);	/* shareid, pad, streamid */
	in_uint16(s, len);
	in_uint8(s, data_pdu_type);
	in_uint8(s, ctype);
	in_uint16(s, clen);
	clen -= 18;

	if (ctype & RDP_MPPC_COMPRESSED)
	{
		void * p;

		if (len > RDP_MPPC_DICT_SIZE)
			error("error decompressed packet size exceeds max\n");
		if (mppc_expand(This, s->p, clen, ctype, &roff, &rlen) == -1)
			error("error while decompressing packet\n");

		/* len -= 18; */

		/* allocate memory and copy the uncompressed data into the temporary stream */
		p = realloc(ns->data, rlen);

		if(p == NULL)
		{
			This->disconnect_reason = 262;
			return True;
		}

		ns->data = (uint8 *) p;

		memcpy((ns->data), (unsigned char *) (This->mppc_dict.hist + roff), rlen);

		ns->size = rlen;
		ns->end = (ns->data + ns->size);
		ns->p = ns->data;
		ns->rdp_hdr = ns->p;

		s = ns;
	}

	switch (data_pdu_type)
	{
		case RDP_DATA_PDU_UPDATE:
			process_update_pdu(This, s);
			break;

		case RDP_DATA_PDU_CONTROL:
			DEBUG(("Received Control PDU\n"));
			break;

		case RDP_DATA_PDU_SYNCHRONISE:
			DEBUG(("Received Sync PDU\n"));
			break;

		case RDP_DATA_PDU_POINTER:
			process_pointer_pdu(This, s);
			break;

		case RDP_DATA_PDU_BELL:
			ui_bell(This);
			break;

		case RDP_DATA_PDU_LOGON:
			DEBUG(("Received Logon PDU\n"));
			event_logon(This);
			/* User logged on */
			break;

		case RDP_DATA_PDU_DISCONNECT:
			process_disconnect_pdu(s, ext_disc_reason);

			/* We used to return true and disconnect immediately here, but
			 * Windows Vista sends a disconnect PDU with reason 0 when
			 * reconnecting to a disconnected session, and MSTSC doesn't
			 * drop the connection.  I think we should just save the status.
			 */
			break;

		default:
			unimpl("data PDU %d\n", data_pdu_type);
	}
	return False;
}

/* Process redirect PDU from Session Directory */
static BOOL
process_redirect_pdu(RDPCLIENT * This, STREAM s /*, uint32 * ext_disc_reason */ )
{
	uint32 flags;

	uint32 server_len;
	wchar_t * server;

	uint32 cookie_len;
	char * cookie;

	uint32 username_len;
	wchar_t * username;

	uint32 domain_len;
	wchar_t * domain;

	uint32 password_len;
	wchar_t * password;

	/* these 2 bytes are unknown, seem to be zeros */
	in_uint8s(s, 2);

	/* read connection flags */
	in_uint32_le(s, flags);

	/* read length of ip string */
	in_uint32_le(s, server_len);

	/* read ip string */
	server = (wchar_t *)s->p;
	in_uint8s(s, server_len);

	/* read length of cookie string */
	in_uint32_le(s, cookie_len);

	/* read cookie string (plain ASCII) */
	cookie = (char *)s->p;
	in_uint8s(s, cookie_len);

	/* read length of username string */
	in_uint32_le(s, username_len);

	/* read username string */
	username = (wchar_t *)s->p;
	in_uint8s(s, username_len);

	/* read length of domain string */
	in_uint32_le(s, domain_len);

	/* read domain string */
	domain = (wchar_t *)s->p;
	in_uint8s(s, domain_len);

	/* read length of password string */
	in_uint32_le(s, password_len);

	/* read password string */
	password = (wchar_t *)s->p;
	in_uint8s(s, password_len);

	This->redirect = True;

	return event_redirect
	(
		This,
		flags,
		server_len,
		server,
		cookie_len,
		cookie,
		username_len,
		username,
		domain_len,
		domain,
		password_len,
		password
	);
}

/* Process incoming packets */
/* nevers gets out of here till app is done */
void
rdp_main_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason)
{
	while (rdp_loop(This, deactivated, ext_disc_reason))
		;
}

/* used in uiports and rdp_main_loop, processes the rdp packets waiting */
BOOL
rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason)
{
	uint8 type;
	BOOL disc = False;	/* True when a disconnect PDU was received */
	BOOL cont = True;
	STREAM s;

	while (cont)
	{
		s = rdp_recv(This, &type);
		if (s == NULL)
			return False;
		switch (type)
		{
			case RDP_PDU_DEMAND_ACTIVE:
				if(!process_demand_active(This, s))
					return False;
				*deactivated = False;
				break;
			case RDP_PDU_DEACTIVATE:
				DEBUG(("RDP_PDU_DEACTIVATE\n"));
				*deactivated = True;
				break;
			case RDP_PDU_REDIRECT:
				return process_redirect_pdu(This, s);
				break;
			case RDP_PDU_DATA:
				disc = process_data_pdu(This, s, ext_disc_reason);
				break;
			case 0:
				break;
			default:
				unimpl("PDU %d\n", type);
		}
		if (disc)
			return False;
		cont = This->next_packet < s->end;
	}
	return True;
}

/* Establish a connection up to the RDP layer */
BOOL
rdp_connect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password,
	    wchar_t *command, wchar_t *directory, wchar_t *hostname, char *cookie)
{
	if (!sec_connect(This, server, hostname, cookie))
		return False;

	rdp_send_logon_info(This, flags, domain, username, password, command, directory);
	return True;
}

/* Establish a reconnection up to the RDP layer */
BOOL
rdp_reconnect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password,
	      wchar_t *command, wchar_t *directory, wchar_t *hostname, char *cookie)
{
	if (!sec_reconnect(This, server, hostname, cookie))
		return False;

	rdp_send_logon_info(This, flags, domain, username, password, command, directory);
	return True;
}

/* Called during redirection to reset the state to support redirection */
void
rdp_reset_state(RDPCLIENT * This)
{
	This->next_packet = NULL;	/* reset the packet information */
	This->rdp_shareid = 0;
	sec_reset_state(This);
}

/* Disconnect from the RDP layer */
void
rdp_disconnect(RDPCLIENT * This)
{
	sec_disconnect(This);
}

⌨️ 快捷键说明

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