284{
288 ULONG LengthIn, LengthOut;
290 PVOID BufferIn, BufferOut;
293
294 TRACE_(SERIAL,
"IRP_MJ_DEVICE_CONTROL dispatch\n");
295
297 LengthIn =
Stack->Parameters.DeviceIoControl.InputBufferLength;
298 LengthOut =
Stack->Parameters.DeviceIoControl.OutputBufferLength;
303
304
305
307 {
309 {
310 TRACE_(SERIAL,
"IOCTL_SERIAL_CLEAR_STATS\n");
314 DeviceExtension);
316 break;
317 }
319 {
320 TRACE_(SERIAL,
"IOCTL_SERIAL_CLR_DTR\n");
321
322
325 {
326 DeviceExtension->
MCR &= ~SR_MCR_DTR;
329 }
330 break;
331 }
333 {
334 TRACE_(SERIAL,
"IOCTL_SERIAL_CLR_RTS\n");
335
336
339 {
340 DeviceExtension->
MCR &= ~SR_MCR_RTS;
343 }
344 break;
345 }
347 {
348
350 TRACE_(SERIAL,
"IOCTL_SERIAL_CONFIG_SIZE\n");
351 if (LengthOut !=
sizeof(
ULONG) || BufferOut ==
NULL)
353 else
354 {
355 pConfigSize = (
PULONG)BufferOut;
356 *pConfigSize = 0;
359 }
360 break;
361 }
363 {
364 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_BAUD_RATE\n");
367 else if (BufferOut ==
NULL)
369 else
370 {
374 }
375 break;
376 }
378 {
379
381 ERR_(SERIAL,
"IOCTL_SERIAL_GET_CHARS not implemented.\n");
384 else if (BufferOut ==
NULL)
386 else
387 {
397 }
398 break;
399 }
401 {
402 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_COMMSTATUS\n");
405 else if (BufferOut ==
NULL)
407 else
408 {
411 }
412 break;
413 }
415 {
417 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_DTRRTS\n");
418 if (LengthOut !=
sizeof(
ULONG) || BufferOut ==
NULL)
420 else
421 {
422 pDtrRts = (
PULONG)BufferOut;
423 *pDtrRts = 0;
430 }
431 break;
432 }
434 {
435
437 ERR_(SERIAL,
"IOCTL_SERIAL_GET_HANDFLOW not implemented.\n");
440 else if (BufferOut ==
NULL)
442 else
443 {
451 }
452 break;
453 }
455 {
456 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_LINE_CONTROL\n");
459 else if (BufferOut ==
NULL)
461 else
462 {
466 }
467 break;
468 }
470 {
472 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_MODEM_CONTROL\n");
473 if (LengthOut !=
sizeof(
ULONG) || BufferOut ==
NULL)
475 else
476 {
478 *pMCR = DeviceExtension->
MCR;
481 }
482 break;
483 }
485 {
487 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_MODEMSTATUS\n");
488 if (LengthOut !=
sizeof(
ULONG) || BufferOut ==
NULL)
490 else
491 {
493 *pMSR = DeviceExtension->
MSR;
496 }
497 break;
498 }
500 {
501 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_PROPERTIES\n");
504 else if (BufferOut ==
NULL)
506 else
507 {
510 }
511 break;
512 }
514 {
515 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_STATS\n");
518 else if (BufferOut ==
NULL)
520 else
521 {
526 }
527 break;
528 }
530 {
531 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_TIMEOUTS\n");
534 else
535 {
539 }
540 break;
541 }
543 {
545 TRACE_(SERIAL,
"IOCTL_SERIAL_GET_WAIT_MASK\n");
546 if (LengthOut !=
sizeof(
ULONG) || BufferOut ==
NULL)
548 else
549 {
550 pWaitMask = (
PULONG)BufferOut;
551 *pWaitMask = DeviceExtension->
WaitMask;
554 }
555 break;
556 }
558 {
559
560 ERR_(SERIAL,
"IOCTL_SERIAL_IMMEDIATE_CHAR not implemented.\n");
562 break;
563 }
565 {
566
567 ERR_(SERIAL,
"IOCTL_SERIAL_LSRMST_INSERT not implemented.\n");
569 break;
570 }
572 {
574 TRACE_(SERIAL,
"IOCTL_SERIAL_PURGE\n");
575
576
577 if (LengthIn !=
sizeof(
ULONG) || BufferIn ==
NULL)
579 else
580 {
582
584
586 {
590 {
591
594 {
597 }
598 }
600 }
601
603 {
607 {
608
611 {
614 }
615 }
617 }
618 }
619 break;
620 }
622 {
623
624 ERR_(SERIAL,
"IOCTL_SERIAL_RESET_DEVICE not implemented.\n");
626 break;
627 }
629 {
631 TRACE_(SERIAL,
"IOCTL_SERIAL_SET_BAUD_RATE\n");
632 if (LengthIn !=
sizeof(
ULONG) || BufferIn ==
NULL)
634 else
635 {
636 pNewBaudRate = (
PULONG)BufferIn;
638 }
639 break;
640 }
642 {
643
644 ERR_(SERIAL,
"IOCTL_SERIAL_SET_BREAK_OFF not implemented.\n");
646 break;
647 }
649 {
650
651 ERR_(SERIAL,
"IOCTL_SERIAL_SET_BREAK_ON not implemented.\n");
653 break;
654 }
656 {
657
658 ERR_(SERIAL,
"IOCTL_SERIAL_SET_CHARS not implemented.\n");
660 break;
661 }
663 {
664
665
666 TRACE_(SERIAL,
"IOCTL_SERIAL_SET_DTR\n");
668 {
671 {
675 }
676 }
677 else
679 break;
680 }
682 {
683 TRACE_(SERIAL,
"IOCTL_SERIAL_SET_FIFO_CONTROL\n");
684 if (LengthIn !=
sizeof(
ULONG) || BufferIn ==
NULL)
686 else
687 {
690 {
693 }
694 }
695 break;
696 }
698 {
699
700 ERR_(SERIAL,
"IOCTL_SERIAL_SET_HANDFLOW not implemented.\n");
702 break;
703 }
705 {
706 TRACE_(SERIAL,
"IOCTL_SERIAL_SET_LINE_CONTROL\n");
709 else if (BufferIn ==
NULL)
711 else
713 break;
714 }
716 {
718 TRACE_(SERIAL,
"IOCTL_SERIAL_SET_MODEM_CONTROL\n");
719 if (LengthIn !=
sizeof(
ULONG) || BufferIn ==
NULL)
721 else
722 {
725 {
727 DeviceExtension->
MCR = (
UCHAR)(*pMCR & 0xff);
730 }
731 }
732 break;
733 }
735 {
738 else if (BufferIn ==
NULL)
740 else
741 {
746 {
750 }
752 {
756 }
757 }
758 break;
759 }
761 {
762
763
764 TRACE_(SERIAL,
"IOCTL_SERIAL_SET_RTS\n");
766 {
769 {
773 }
774 }
775 else
777 break;
778 }
780 {
781 TRACE_(SERIAL,
"IOCTL_SERIAL_SET_TIMEOUTS\n");
784 else
785 {
788 }
789 break;
790 }
792 {
794 TRACE_(SERIAL,
"IOCTL_SERIAL_SET_WAIT_MASK\n");
795
796 if (LengthIn !=
sizeof(
ULONG) || BufferIn ==
NULL)
799 {
800 WARN_(SERIAL,
"An IRP is already currently processed\n");
802 }
803 else
804 {
805 DeviceExtension->
WaitMask = *pWaitMask;
807 }
808 break;
809 }
811 {
812
813 ERR_(SERIAL,
"IOCTL_SERIAL_SET_XOFF not implemented.\n");
815 break;
816 }
818 {
819
820 ERR_(SERIAL,
"IOCTL_SERIAL_SET_XON not implemented.\n");
822 break;
823 }
825 {
827 TRACE_(SERIAL,
"IOCTL_SERIAL_WAIT_ON_MASK\n");
828
829 if (LengthOut !=
sizeof(
ULONG) || BufferOut ==
NULL)
831 else
832 {
834
839
840
841 if (WaitingIrp !=
NULL)
842 {
843
844 WARN_(SERIAL,
"Unable to pend a second IRP for IOCTL_SERIAL_WAIT_ON_MASK\n");
845 Irp->IoStatus.Information = 0;
848 }
850 }
851 break;
852 }
854 {
855
856 ERR_(SERIAL,
"IOCTL_SERIAL_XOFF_COUNTER not implemented.\n");
858 break;
859 }
860 default:
861 {
862
863 TRACE_(SERIAL,
"Unknown IOCTL code 0x%x\n",
Stack->Parameters.DeviceIoControl.IoControlCode);
866 }
867 }
868
871 {
873 }
874 else
875 {
878 }
880}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
NTSTATUS IncreaseCircularBufferSize(IN PCIRCULAR_BUFFER pBuffer, IN ULONG NewBufferSize)
#define STATUS_NOT_IMPLEMENTED
#define NT_SUCCESS(StatCode)
#define SR_FCR_CLEAR_RCVR
#define SR_FCR_CLEAR_XMIT
struct _SERIAL_DEVICE_EXTENSION * PSERIAL_DEVICE_EXTENSION
#define KeReleaseSpinLock(sl, irql)
#define KeAcquireSpinLock(sl, irql)
#define InterlockedCompareExchangePointer
#define SERIAL_PURGE_TXCLEAR
#define SERIAL_PURGE_RXCLEAR
#define IOCTL_SERIAL_SET_CHARS
#define IOCTL_SERIAL_SET_LINE_CONTROL
struct _SERIAL_CHARS * PSERIAL_CHARS
#define IOCTL_SERIAL_XOFF_COUNTER
#define IOCTL_SERIAL_SET_TIMEOUTS
struct _SERIAL_QUEUE_SIZE * PSERIAL_QUEUE_SIZE
struct _SERIAL_COMMPROP SERIAL_COMMPROP
#define IOCTL_SERIAL_WAIT_ON_MASK
#define IOCTL_SERIAL_SET_MODEM_CONTROL
#define IOCTL_SERIAL_IMMEDIATE_CHAR
#define IOCTL_SERIAL_GET_DTRRTS
#define IOCTL_SERIAL_SET_XOFF
#define IOCTL_SERIAL_GET_CHARS
struct _SERIAL_HANDFLOW * PSERIAL_HANDFLOW
struct _SERIALPERF_STATS SERIALPERF_STATS
struct _SERIAL_BAUD_RATE SERIAL_BAUD_RATE
struct _SERIAL_CHARS SERIAL_CHARS
#define IOCTL_SERIAL_SET_WAIT_MASK
#define IOCTL_SERIAL_SET_QUEUE_SIZE
#define IOCTL_SERIAL_RESET_DEVICE
struct _SERIAL_BAUD_RATE * PSERIAL_BAUD_RATE
struct _SERIAL_HANDFLOW SERIAL_HANDFLOW
#define IOCTL_SERIAL_GET_BAUD_RATE
#define IOCTL_SERIAL_GET_COMMSTATUS
#define IOCTL_SERIAL_SET_FIFO_CONTROL
#define IOCTL_SERIAL_GET_WAIT_MASK
#define IOCTL_SERIAL_SET_BREAK_OFF
#define IOCTL_SERIAL_CONFIG_SIZE
#define IOCTL_SERIAL_GET_MODEM_CONTROL
#define IOCTL_SERIAL_GET_TIMEOUTS
#define IOCTL_SERIAL_SET_XON
#define IOCTL_SERIAL_GET_STATS
#define IOCTL_SERIAL_CLR_DTR
struct _SERIAL_LINE_CONTROL * PSERIAL_LINE_CONTROL
#define IOCTL_SERIAL_SET_BAUD_RATE
#define IOCTL_SERIAL_GET_PROPERTIES
#define IOCTL_SERIAL_LSRMST_INSERT
#define IOCTL_SERIAL_CLR_RTS
#define IOCTL_SERIAL_GET_MODEMSTATUS
#define IOCTL_SERIAL_CLEAR_STATS
#define IOCTL_SERIAL_GET_LINE_CONTROL
struct _SERIAL_STATUS SERIAL_STATUS
#define IOCTL_SERIAL_SET_DTR
struct _SERIAL_TIMEOUTS * PSERIAL_TIMEOUTS
struct _SERIAL_LINE_CONTROL SERIAL_LINE_CONTROL
#define IOCTL_SERIAL_SET_BREAK_ON
#define IOCTL_SERIAL_GET_HANDFLOW
#define IOCTL_SERIAL_SET_RTS
#define IOCTL_SERIAL_SET_HANDFLOW
#define IOCTL_SERIAL_PURGE
#define IoSkipCurrentIrpStackLocation(Irp)
#define IoCompleteRequest
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
#define WRITE_PORT_UCHAR(p, d)
static NTSTATUS SerialGetCommProp(OUT PSERIAL_COMMPROP pCommProp, IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
static BOOLEAN NTAPI SerialGetPerfStats(IN PVOID SynchronizeContext)
static VOID SerialGetUserBuffers(IN PIRP Irp, IN ULONG IoControlCode, OUT PVOID *BufferIn, OUT PVOID *BufferOut)
static NTSTATUS SerialGetCommStatus(OUT PSERIAL_STATUS pSerialStatus, IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
NTSTATUS NTAPI SerialSetBaudRate(IN PSERIAL_DEVICE_EXTENSION DeviceExtension, IN ULONG NewBaudRate)
static BOOLEAN NTAPI SerialClearPerfStats(IN PVOID SynchronizeContext)
NTSTATUS NTAPI SerialSetLineControl(IN PSERIAL_DEVICE_EXTENSION DeviceExtension, IN PSERIAL_LINE_CONTROL NewSettings)
#define STATUS_BUFFER_TOO_SMALL
SERIAL_LINE_CONTROL SerialLineControl
PDEVICE_OBJECT LowerDevice
KSPIN_LOCK OutputBufferLock
KSPIN_LOCK InputBufferLock
IO_REMOVE_LOCK RemoveLock
CIRCULAR_BUFFER InputBuffer
CIRCULAR_BUFFER OutputBuffer
SERIAL_TIMEOUTS SerialTimeOuts
#define STATUS_INVALID_PARAMETER
_In_ PDEVICE_OBJECT DeviceObject
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
#define IoAcquireRemoveLock(RemoveLock, Tag)
#define IoReleaseRemoveLock(_RemoveLock, _Tag)