@@ -228,9 +228,10 @@ impl IoControl {
228228 } ;
229229 let input_buffer_size = src. read_u32 ( ) . try_into ( ) . map_err ( |e| other_err ! ( source: e) ) ?;
230230 ensure_size ! ( in: src,
231- size: input_buffer_size /* InputBuffer */ + 4 /* OutputBufferSize */ + 4 /* RequestId */ ) ;
231+ size: input_buffer_size) ;
232232 // TODO: size limit
233233 let input_buffer = src. read_slice ( input_buffer_size) . to_vec ( ) ;
234+ ensure_size ! ( in: src, size: 4 /*output buffer size */ + 4 /* request id */ ) ;
234235 let output_buffer_size = src. read_u32 ( ) ;
235236 let req_id = src. read_u32 ( ) ;
236237 let io_control = Self {
@@ -374,11 +375,11 @@ impl IoctlInternalUsb {
374375/// [\[MS-RDPEUSB\] 2.2.13 USB Internal IO Control Code][1].
375376///
376377/// [1]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpeusb/55d1cd44-eda3-4cba-931c-c3cb8b3c3c92
377- #[ repr( u32 ) ]
378- #[ non_exhaustive]
379- #[ derive( Debug , PartialEq , Clone ) ]
378+ #[ derive( Debug , PartialEq , Clone , Copy ) ]
380379#[ doc( alias = "IOCTL_TSUSBGD_IOCTL_USBDI_QUERY_BUS_TIME" ) ]
381- pub enum UsbInternalIoctlCode {
380+ pub struct UsbInternalIoctlCode ( pub u32 ) ;
381+
382+ impl UsbInternalIoctlCode {
382383 /// [\[MS-RDPEUSB\] 2.2.13.1 IOCTL_TSUSBGD_IOCTL_USBDI_QUERY_BUS_TIME][1].
383384 ///
384385 /// Sent when the server receives a request its system to query the device's current frame
@@ -389,11 +390,9 @@ pub enum UsbInternalIoctlCode {
389390 ///
390391 /// [1]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpeusb/68506bc9-fedc-4fc1-b826-3cdbb1988774
391392 #[ doc( alias = "IOCTL_TSUSBGD_IOCTL_USBDI_QUERY_BUS_TIME" ) ]
392- IoctlTsusbgdIoctlUsbdiQueryBusTime = 0x00224000 ,
393+ pub const QUERY_BUS_TIME : Self = Self ( 0x00224000 ) ;
393394}
394395
395- const IOCTL_TSUSBGD_IOCTL_USBDI_QUERY_BUS_TIME : u32 = 0x00224000 ;
396-
397396/// [\[MS-RDPEUSB\] 2.2.6.4 Internal IO Control Message (INTERNAL_IO_CONTROL)][1] message.
398397///
399398/// Sent from the server to the client to submit an internal IO control request to the USB device.
@@ -404,28 +403,18 @@ const IOCTL_TSUSBGD_IOCTL_USBDI_QUERY_BUS_TIME: u32 = 0x00224000;
404403pub struct InternalIoControl {
405404 pub msg_id : MessageId ,
406405 pub udev_iface : InterfaceId ,
407- // Should make adding new codes easier.
408406 pub ioctl_code : UsbInternalIoctlCode ,
409- /// As of **v20240423**, all codes used for this message require sending an empty input buffer.
410- ///
411- /// * [MS-RDPEUSB 2.2.13 USB Internal IO Control Code][1]
412- ///
413- /// [1]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpeusb/55d1cd44-eda3-4cba-931c-c3cb8b3c3c92
414407 pub input_buffer : Vec < u8 > ,
415408 pub output_buffer_size : u32 ,
416409 pub req_id : RequestIdIoctl ,
417410}
418411
419412impl InternalIoControl {
420- #[ expect( clippy:: identity_op, reason = "for developer documentation purposes?" ) ]
421- pub const PAYLOAD_SIZE : usize = 4 // IoControlCode
413+ pub const PAYLOAD_MIN_SIZE : usize = 4 // IoControlCode
422414 + 4 // InputBufferSize
423- + 0 // InputBuffer
424415 + 4 // OutputBufferSize
425416 + 4 ; // RequestId
426417
427- pub const FIXED_PART_SIZE : usize = SharedMsgHeader :: SIZE_REQ /* Header */ + Self :: PAYLOAD_SIZE ;
428-
429418 pub fn header ( & self ) -> SharedMsgHeader {
430419 SharedMsgHeader {
431420 iface_id : self . udev_iface . with_mask ( Mask :: Proxy ) ,
@@ -435,40 +424,23 @@ impl InternalIoControl {
435424 }
436425
437426 pub ( crate ) fn decode ( src : & mut ReadCursor < ' _ > , msg_id : MessageId , udev_iface : InterfaceId ) -> DecodeResult < Self > {
438- ensure_size ! ( in: src, size: Self :: PAYLOAD_SIZE ) ;
427+ ensure_size ! ( in: src, size: Self :: PAYLOAD_MIN_SIZE ) ;
439428
440- {
441- let code = src. read_u32 ( ) ;
442- if code != IOCTL_TSUSBGD_IOCTL_USBDI_QUERY_BUS_TIME {
443- return Err ( unsupported_value_err ! (
444- "INTERNAL_IO_CONTROL::IoControlCode" ,
445- format!( "{code:#X}" )
446- ) ) ;
447- }
448- }
449- {
450- let size = src. read_u32 ( /* InputBufferSize */ ) ;
451- if size != 0 {
452- return Err ( unsupported_value_err ! (
453- "INTERNAL_IO_CONTROL::InputBufferSize" ,
454- format!( "{size:#X}" )
455- ) ) ;
456- }
457- }
429+ let code = src. read_u32 ( ) ;
430+
431+ let size = src. read_u32 ( ) . try_into ( ) . map_err ( |e| other_err ! ( source: e) ) ?;
432+ ensure_size ! ( in: src, size: size) ;
433+ let input_buffer = src. read_slice ( size) . to_vec ( ) ;
434+
435+ ensure_size ! ( in: src, size: 4 /*output buffer size */ + 4 /* request id */ ) ;
458436 let output_buffer_size = src. read_u32 ( /* OutputBufferSize */ ) ;
459- if output_buffer_size != 0x4 {
460- return Err ( unsupported_value_err ! (
461- "INTERNAL_IO_CONTROL::OutputBufferSize" ,
462- format!( "{output_buffer_size:#X}" )
463- ) ) ;
464- }
465437 let req_id = src. read_u32 ( ) ;
466438
467439 Ok ( Self {
468440 msg_id,
469441 udev_iface,
470- ioctl_code : UsbInternalIoctlCode :: IoctlTsusbgdIoctlUsbdiQueryBusTime ,
471- input_buffer : Vec :: new ( ) ,
442+ ioctl_code : UsbInternalIoctlCode ( code ) ,
443+ input_buffer,
472444 output_buffer_size,
473445 req_id,
474446 } )
@@ -477,12 +449,12 @@ impl InternalIoControl {
477449
478450impl Encode for InternalIoControl {
479451 fn encode ( & self , dst : & mut WriteCursor < ' _ > ) -> EncodeResult < ( ) > {
480- ensure_fixed_part_size ! ( in: dst) ;
481-
452+ ensure_size ! ( in: dst, size: self . size( ) ) ;
482453 self . header ( ) . encode ( dst) ?;
483- dst. write_u32 ( IOCTL_TSUSBGD_IOCTL_USBDI_QUERY_BUS_TIME ) ; // IoControlCode
484- dst. write_u32 ( 0x0 ) ; // InputBufferSize
485- dst. write_u32 ( 0x4 ) ; // OutputBufferSize
454+ dst. write_u32 ( self . ioctl_code . 0 ) ; // IoControlCode
455+ dst. write_u32 ( self . input_buffer . len ( ) . try_into ( ) . map_err ( |e| other_err ! ( source: e) ) ?) ; // InputBufferSize
456+ dst. write_slice ( & self . input_buffer ) ; // InputBuffer
457+ dst. write_u32 ( self . output_buffer_size ) ; // OutputBufferSize
486458 dst. write_u32 ( self . req_id ) ;
487459
488460 Ok ( ( ) )
@@ -493,7 +465,7 @@ impl Encode for InternalIoControl {
493465 }
494466
495467 fn size ( & self ) -> usize {
496- Self :: FIXED_PART_SIZE
468+ SharedMsgHeader :: SIZE_REQ + Self :: PAYLOAD_MIN_SIZE + self . input_buffer . len ( )
497469 }
498470}
499471
0 commit comments