CVS: rdesktop rdpsnd.c, 1.29, 1.30 rdpsnd_dsp.c, 1.22, 1.23 rdpsnd_dsp.h, 1.3, 1.4

Pierre Ossman <[email protected]> Wed, 06 Dec 2006 05:29:44 -0800
Newsgroups gmane.network.rdesktop.cvs
Message-ID <[email protected]>
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv15232

Modified Files:
	rdpsnd.c rdpsnd_dsp.c rdpsnd_dsp.h 
Log Message:
New packet based parser for the rdpsnd protocol.


Index: rdpsnd.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -C2 -d -r1.29 -r1.30
*** rdpsnd.c	6 Dec 2006 13:18:36 -0000	1.29
--- rdpsnd.c	6 Dec 2006 13:29:41 -0000	1.30
***************
*** 51,54 ****
--- 51,57 ----
  struct audio_packet packet_queue[MAX_QUEUE];
  
+ static uint8 packet_opcode;
+ static struct stream packet;
+ 
  void (*wave_out_play) (void);
  
***************
*** 196,208 ****
  
  static void
! rdpsnd_process(STREAM s)
  {
- 	uint8 type;
- 	uint16 datalen;
  	uint16 vol_left, vol_right;
  	static uint16 tick, format;
  	static uint8 packet_index;
- 	static BOOL awaiting_data_packet;
- 	static unsigned char missing_bytes[4] = { 0, 0, 0, 0 };
  
  #ifdef RDPSND_DEBUG
--- 199,207 ----
  
  static void
! rdpsnd_process_packet(uint8 opcode, STREAM s)
  {
  	uint16 vol_left, vol_right;
  	static uint16 tick, format;
  	static uint8 packet_index;
  
  #ifdef RDPSND_DEBUG
***************
*** 211,263 ****
  #endif
  
! 	if (awaiting_data_packet)
  	{
! 		if (format >= MAX_FORMATS)
! 		{
! 			error("RDPSND: Invalid format index\n");
! 			return;
! 		}
  
! 		if (!device_open || (format != current_format))
! 		{
! 			if (!device_open && !current_driver->wave_out_open())
  			{
! 				rdpsnd_send_completion(tick, packet_index);
! 				return;
  			}
! 			if (!current_driver->wave_out_set_format(&formats[format]))
  			{
! 				rdpsnd_send_completion(tick, packet_index);
! 				current_driver->wave_out_close();
! 				device_open = False;
! 				return;
  			}
- 			device_open = True;
- 			current_format = format;
- 		}
  
! 		/* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */
! 		memcpy(s->data, missing_bytes, 4);
! 
! 		rdpsnd_queue_write(rdpsnd_dsp_process
! 				   (s, current_driver, &formats[current_format]), tick,
! 				   packet_index);
! 		awaiting_data_packet = False;
! 		return;
! 	}
! 
! 	in_uint8(s, type);
! 	in_uint8s(s, 1);	/* unknown? */
! 	in_uint16_le(s, datalen);
! 
! 	switch (type)
! 	{
! 		case RDPSND_WRITE:
! 			in_uint16_le(s, tick);
! 			in_uint16_le(s, format);
! 			in_uint8(s, packet_index);
! 			/* Here are our lost bytes, but why? */
! 			memcpy(missing_bytes, s->end - 4, 4);
! 			awaiting_data_packet = True;
  			break;
  		case RDPSND_CLOSE:
--- 210,249 ----
  #endif
  
! 	switch (opcode)
  	{
! 		case RDPSND_WRITE:
! 			in_uint16_le(s, tick);
! 			in_uint16_le(s, format);
! 			in_uint8(s, packet_index);
! 			in_uint8s(s, 3);
  
! 			if (format >= MAX_FORMATS)
  			{
! 				error("RDPSND: Invalid format index\n");
! 				break;
  			}
! 
! 			if (!device_open || (format != current_format))
  			{
! 				if (!device_open && !current_driver->wave_out_open())
! 				{
! 					rdpsnd_send_completion(tick, packet_index);
! 					break;
! 				}
! 				if (!current_driver->wave_out_set_format(&formats[format]))
! 				{
! 					rdpsnd_send_completion(tick, packet_index);
! 					current_driver->wave_out_close();
! 					device_open = False;
! 					break;
! 				}
! 				device_open = True;
! 				current_format = format;
  			}
  
! 			rdpsnd_queue_write(rdpsnd_dsp_process
! 					   (s->p, s->end - s->p, current_driver,
! 					    &formats[current_format]), tick, packet_index);
! 			return;
  			break;
  		case RDPSND_CLOSE:
***************
*** 278,286 ****
  			break;
  		default:
! 			unimpl("RDPSND packet type %d\n", type);
  			break;
  	}
  }
  
  static BOOL
  rdpsnd_auto_open(void)
--- 264,325 ----
  			break;
  		default:
! 			unimpl("RDPSND packet type %x\n", opcode);
  			break;
  	}
  }
  
+ static void
+ rdpsnd_process(STREAM s)
+ {
+ 	uint16 len;
+ 
+ 	while (!s_check_end(s))
+ 	{
+ 		/* New packet */
+ 		if (packet.size == 0)
+ 		{
+ 			if ((s->end - s->p) < 4)
+ 			{
+ 				error("RDPSND: Split at packet header. Things will go south from here...\n");
+ 				return;
+ 			}
+ 			in_uint8(s, packet_opcode);
+ 			in_uint8s(s, 1);	/* Padding */
+ 			in_uint16_le(s, len);
+ 
+ 			packet.p = packet.data;
+ 			packet.end = packet.data + len;
+ 			packet.size = len;
+ 		}
+ 		else
+ 		{
+ 			len = MIN(s->end - s->p, packet.end - packet.p);
+ 
+ 			/* Microsoft's server is so broken it's not even funny... */
+ 			if (packet_opcode == RDPSND_WRITE)
+ 			{
+ 				if ((packet.p - packet.data) < 12)
+ 					len = MIN(len, 12 - (packet.p - packet.data));
+ 				else if ((packet.p - packet.data) == 12)
+ 				{
+ 					in_uint8s(s, 4);
+ 					len -= 4;
+ 				}
+ 			}
+ 
+ 			in_uint8a(s, packet.p, len);
+ 			packet.p += len;
+ 		}
+ 
+ 		/* Packet fully assembled */
+ 		if (packet.p == packet.end)
+ 		{
+ 			packet.p = packet.data;
+ 			rdpsnd_process_packet(packet_opcode, &packet);
+ 			packet.size = 0;
+ 		}
+ 	}
+ }
+ 
  static BOOL
  rdpsnd_auto_open(void)
***************
*** 358,361 ****
--- 397,404 ----
  	drivers = NULL;
  
+ 	packet.data = xmalloc(65536);
+ 	packet.p = packet.end = packet.data;
+ 	packet.size = 0;
+ 
  	rdpsnd_channel =
  		channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,

Index: rdpsnd_dsp.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_dsp.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -d -r1.22 -r1.23
*** rdpsnd_dsp.c	27 Oct 2006 12:58:13 -0000	1.22
--- rdpsnd_dsp.c	6 Dec 2006 13:29:42 -0000	1.23
***************
*** 385,389 ****
  
  STREAM
! rdpsnd_dsp_process(STREAM s, struct audio_driver * current_driver, WAVEFORMATEX * format)
  {
  	static struct stream out;
--- 385,390 ----
  
  STREAM
! rdpsnd_dsp_process(unsigned char *data, unsigned int size, struct audio_driver * current_driver,
! 		   WAVEFORMATEX * format)
  {
  	static struct stream out;
***************
*** 393,402 ****
  	   return, so they can operate on the input-stream */
  	if (current_driver->wave_out_volume == rdpsnd_dsp_softvol_set)
! 		rdpsnd_dsp_softvol(s->data, s->size, format);
  
  #ifdef B_ENDIAN
  	if (current_driver->need_byteswap_on_be)
  	{
! 		rdpsnd_dsp_swapbytes(s->data, s->size, format);
  		stream_be = True;
  	}
--- 394,403 ----
  	   return, so they can operate on the input-stream */
  	if (current_driver->wave_out_volume == rdpsnd_dsp_softvol_set)
! 		rdpsnd_dsp_softvol(data, size, format);
  
  #ifdef B_ENDIAN
  	if (current_driver->need_byteswap_on_be)
  	{
! 		rdpsnd_dsp_swapbytes(data, size, format);
  		stream_be = True;
  	}
***************
*** 406,416 ****
  
  	if (current_driver->need_resampling)
! 		out.size = rdpsnd_dsp_resample(&out.data, s->data, s->size, format, stream_be);
  
  	if (out.data == NULL)
  	{
! 		out.data = xmalloc(s->size);
! 		memcpy(out.data, s->data, s->size);
! 		out.size = s->size;
  	}
  
--- 407,417 ----
  
  	if (current_driver->need_resampling)
! 		out.size = rdpsnd_dsp_resample(&out.data, data, size, format, stream_be);
  
  	if (out.data == NULL)
  	{
! 		out.data = xmalloc(size);
! 		memcpy(out.data, data, size);
! 		out.size = size;
  	}
  

Index: rdpsnd_dsp.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_dsp.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** rdpsnd_dsp.h	1 Oct 2006 12:16:50 -0000	1.3
--- rdpsnd_dsp.h	6 Dec 2006 13:29:42 -0000	1.4
***************
*** 27,29 ****
  BOOL rdpsnd_dsp_resample_supported(WAVEFORMATEX * pwfx);
  
! STREAM rdpsnd_dsp_process(STREAM s, struct audio_driver *current_driver, WAVEFORMATEX * format);
--- 27,30 ----
  BOOL rdpsnd_dsp_resample_supported(WAVEFORMATEX * pwfx);
  
! STREAM rdpsnd_dsp_process(unsigned char *data, unsigned int size,
! 			  struct audio_driver *current_driver, WAVEFORMATEX * format);


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV