|
|
/*****************************************************************************
* * Copyright (c) 1996-1999 Microsoft Corporation * * @doc * @module ioctl.c | IrSIR NDIS Miniport Driver * @comm * *----------------------------------------------------------------------------- * * Author: Scott Holden (sholden) * * Date: 9/30/1996 (created) * * Contents: * Wrappers to the io control functions of the serial port. * *****************************************************************************/
#include "irsir.h"
NTSTATUS SerialFlush(IN PDEVICE_OBJECT pSerialDevObj);
VOID SendIoctlToSerial( PDEVICE_OBJECT DeviceObject, PIO_STATUS_BLOCK StatusBlock, ULONG IoCtl, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength );
#pragma alloc_text(PAGE, SendIoctlToSerial)
#pragma alloc_text(PAGE, SerialGetStats)
#pragma alloc_text(PAGE, SerialClearStats)
#pragma alloc_text(PAGE, SerialGetProperties)
#pragma alloc_text(PAGE, SerialGetModemStatus)
#pragma alloc_text(PAGE, SerialGetCommStatus)
#pragma alloc_text(PAGE, SerialResetDevice)
#pragma alloc_text(PAGE, SerialPurge)
#pragma alloc_text(PAGE, SerialLSRMSTInsert)
#pragma alloc_text(PAGE, SerialGetBaudRate)
#pragma alloc_text(PAGE, SerialSetBaudRate)
#pragma alloc_text(PAGE, SerialSetQueueSize)
#pragma alloc_text(PAGE, SerialGetHandflow)
#pragma alloc_text(PAGE, SerialSetHandflow)
#pragma alloc_text(PAGE, SerialGetLineControl)
#pragma alloc_text(PAGE, SerialSetLineControl)
#pragma alloc_text(PAGE, SerialSetBreakOn)
#pragma alloc_text(PAGE, SerialSetBreakOff)
#pragma alloc_text(PAGE, SerialSetTimeouts)
#pragma alloc_text(PAGE, SerialSetDTR)
#pragma alloc_text(PAGE, SerialClrDTR)
#pragma alloc_text(PAGE, SerialSetRTS)
#pragma alloc_text(PAGE, SerialClrRTS)
#pragma alloc_text(PAGE, SerialSetWaitMask)
#pragma alloc_text(PAGE, SerialFlush)
#pragma alloc_text(PAGE, SerialSynchronousWrite)
#pragma alloc_text(PAGE, SerialSynchronousRead)
//
// NOTE:
// all IOCTL_SERIAL_xxx control codes are built using the CTL_CODE macro
// i.e. #define IOCTL_SERIAL_GET_BAUD_RATE \ // CTL_CODE( FILE_DEVICE_SERIAL_PORT, \ // 20, \ // METHOD_BUFFERED, \ // FILE_ANY_ACCESS)
//
// the CTL_CODE macro is defined as:
// #define CTL_CODE( DeviceType, Function, Method, Access ) \ // ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) )
//
// all of the serial io control codes use Method = METHOD_BUFFERED
//
// when using the IoBuildDeviceIoControlRequest(..), the function checks
// IOCTL_SERIAL_xxx & 3
//
// since METHOD_BUFFERED = 0
// IoBuildDeviceIoControlRequest will always follow case 0 and allocate a buffer
// which is large enough to contain both the input and output buffers and then
// set the appropriate fields in the irp.
//
// the input buffer is always copied into the buffer, so we don't have to do
// it in the following wrapper functions
//
VOID SendIoctlToSerial( PDEVICE_OBJECT DeviceObject, PIO_STATUS_BLOCK StatusBlock, ULONG IoCtl, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength )
{ KEVENT Event; PIRP Irp; NTSTATUS Status;
PAGED_CODE();
if (DeviceObject == NULL) {
DEBUGMSG(DBG_OUT, (" SendIoctlToSerial() No device object.\n"));
StatusBlock->Status=STATUS_INVALID_PARAMETER;
return; }
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &Event, NotificationEvent, FALSE );
//
// build irp to get performance stats and wait for event signalled
//
// irp is released by io manager
//
Irp = IoBuildDeviceIoControlRequest( IoCtl, // io control code
DeviceObject, // device object
InputBuffer, // input buffer
InputBufferLength, // input buffer length
OutputBuffer, // output buffer
OutputBufferLength, // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&Event, // event to wait for completion
StatusBlock // io status block to be set
);
if (Irp == NULL) {
DEBUGMSG(DBG_OUT, (" SendIoctlToSerial(): IoBuildDeviceIoControlRequest failed.\n")); StatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
return; }
Status = IoCallDriver(DeviceObject, Irp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (Status == STATUS_PENDING) {
KeWaitForSingleObject( &Event, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
}
return; }
/*****************************************************************************
* * Function: SerialGetStats * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetStats( IN PDEVICE_OBJECT pSerialDevObj, OUT PSERIALPERF_STATS pPerfStats ) { SERIALPERF_STATS PerfStats; IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialGetStats\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_GET_STATS, NULL, 0, &PerfStats, // output buffer
sizeof(SERIALPERF_STATS) // output buffer length
);
ASSERT(sizeof(*pPerfStats) >= sizeof(SERIALPERF_STATS));
if (NT_SUCCESS(ioStatusBlock.Status)) {
RtlCopyMemory(pPerfStats, &PerfStats, sizeof(SERIALPERF_STATS)); }
DEBUGMSG(DBG_FUNC, ("-SerialGetStats\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialClearStats * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialClearStats( IN PDEVICE_OBJECT pSerialDevObj ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialClearStats\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_CLEAR_STATS, NULL, 0, NULL, // output buffer
0 // output buffer length
);
DEBUGMSG(DBG_FUNC, ("-SerialClearStats\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialGetProperties * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetProperties( IN PDEVICE_OBJECT pSerialDevObj, OUT PSERIAL_COMMPROP pCommProp ) { SERIAL_COMMPROP CommProp; IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialGetProperties\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_GET_PROPERTIES, NULL, 0, &CommProp, // output buffer
sizeof(SERIAL_COMMPROP) // output buffer length
);
ASSERT(sizeof(*pCommProp) >= sizeof(SERIAL_COMMPROP));
if (NT_SUCCESS(ioStatusBlock.Status)) {
RtlCopyMemory(pCommProp, &CommProp, sizeof(SERIAL_COMMPROP)); }
DEBUGMSG(DBG_FUNC, ("-SerialGetProperties\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialGetModemStatus * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetModemStatus( IN PDEVICE_OBJECT pSerialDevObj, OUT ULONG *pModemStatus ) { ULONG ModemStatus; IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialGetModemStatus\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_GET_MODEMSTATUS, NULL, 0, &ModemStatus, // output buffer
sizeof(ULONG) // output buffer length
);
ASSERT(sizeof(*pModemStatus) >= sizeof(ULONG));
if (NT_SUCCESS(ioStatusBlock.Status)) {
RtlCopyMemory(pModemStatus, &ModemStatus, sizeof(ULONG)); }
DEBUGMSG(DBG_FUNC, ("-SerialGetModemStatus\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialGetCommStatus * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetCommStatus( IN PDEVICE_OBJECT pSerialDevObj, OUT PSERIAL_STATUS pCommStatus ) { SERIAL_STATUS CommStatus; IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialGetCommStatus\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0, &CommStatus, // output buffer
sizeof(SERIAL_STATUS) // output buffer length
);
ASSERT(sizeof(*pCommStatus) >= sizeof(SERIAL_STATUS));
if (NT_SUCCESS(ioStatusBlock.Status)) {
RtlCopyMemory(pCommStatus, &CommStatus, sizeof(SERIAL_STATUS)); }
DEBUGMSG(DBG_FUNC, ("-SerialGetCommStatus\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialResetDevice * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialResetDevice( IN PDEVICE_OBJECT pSerialDevObj ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialResetDevice\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_RESET_DEVICE, NULL, 0, NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialResetDevice\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialPurge * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialPurge( IN PDEVICE_OBJECT pSerialDevObj ) { ULONG BitMask; IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialPurge\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_PURGE, &BitMask, // input buffer
sizeof(ULONG), // input buffer length
NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialPurge\n"));
return ioStatusBlock.Status;
} #if 0
/*****************************************************************************
* * Function: SerialLSRMSTInsert * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialLSRMSTInsert( IN PDEVICE_OBJECT pSerialDevObj, IN UCHAR *pInsertionMode ) { UCHAR InsertionMode; IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialLSRMSTInsert\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_LSRMST_INSERT, pInsertionMode, // input buffer
sizeof(UCHAR), // input buffer length
NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialLSRMSTInsert\n"));
return IoStatusBlock.Status;
} #endif
/*****************************************************************************
* * Function: SerialGetBaudRate * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetBaudRate( IN PDEVICE_OBJECT pSerialDevObj, OUT ULONG *pBaudRate ) { ULONG BaudRate; IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialGetBaudRate\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_GET_BAUD_RATE, // io control code
NULL, 0, &BaudRate, // output buffer
sizeof(ULONG) // output buffer length
);
ASSERT(sizeof(*pBaudRate) >= sizeof(ULONG));
if (NT_SUCCESS(ioStatusBlock.Status)) {
RtlCopyMemory(pBaudRate, &BaudRate, sizeof(ULONG)); }
DEBUGMSG(DBG_FUNC, ("-SerialGetBaudRate\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialSetBaudRate * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetBaudRate( IN PDEVICE_OBJECT pSerialDevObj, IN ULONG *pBaudRate ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetBaudRate\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_BAUD_RATE, // io control code
pBaudRate, // input buffer
sizeof(ULONG), // input buffer length
NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialSetBaudRate\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialSetQueueSize * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetQueueSize( IN PDEVICE_OBJECT pSerialDevObj, IN PSERIAL_QUEUE_SIZE pQueueSize ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetQueueSize\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_QUEUE_SIZE, // io control code
pQueueSize, // input buffer
sizeof(SERIAL_QUEUE_SIZE), // input buffer length
NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialSetQueueSize\n"));
return ioStatusBlock.Status;
} #if 0
/*****************************************************************************
* * Function: SerialGetHandflow * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetHandflow( IN PDEVICE_OBJECT pSerialDevObj, OUT PSERIAL_HANDFLOW pHandflow ) { SERIAL_HANDFLOW Handflow; IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialGetHandflow\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_GET_HANDFLOW, // io control code
NULL, 0, &Handflow, // output buffer
sizeof(SERIAL_HANDFLOW), // output buffer length
);
ASSERT(sizeof(*pHandflow) >= sizeof(SERIAL_HANDFLOW));
RtlCopyMemory(pHandflow, &Handflow, sizeof(SERIAL_HANDFLOW));
DEBUGMSG(DBG_FUNC, ("-SerialGetHandflow\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialSetHandflow * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetHandflow( IN PDEVICE_OBJECT pSerialDevObj, IN PSERIAL_HANDFLOW pHandflow ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetHandflow\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_HANDFLOW, // io control code
pHandflow, // input buffer
sizeof(SERIAL_HANDFLOW), // input buffer length
NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialSetHandflow\n"));
return ioStatusBlock.Status;
} #endif
/*****************************************************************************
* * Function: SerialGetLineControl * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetLineControl( IN PDEVICE_OBJECT pSerialDevObj, OUT PSERIAL_LINE_CONTROL pLineControl ) { SERIAL_LINE_CONTROL LineControl; IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialGetLineControl\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_GET_LINE_CONTROL, NULL, 0, &LineControl, // output buffer
sizeof(SERIAL_LINE_CONTROL) // output buffer length
);
ASSERT(sizeof(*pLineControl) >= sizeof(SERIAL_LINE_CONTROL));
if (NT_SUCCESS(ioStatusBlock.Status)) {
RtlCopyMemory(pLineControl, &LineControl, sizeof(SERIAL_LINE_CONTROL)); }
DEBUGMSG(DBG_FUNC, ("-SerialGetLineControl\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialSetLineControl * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetLineControl( IN PDEVICE_OBJECT pSerialDevObj, IN PSERIAL_LINE_CONTROL pLineControl ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetLineControl\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_LINE_CONTROL, // io control code
pLineControl, // input buffer
sizeof(SERIAL_LINE_CONTROL), // input buffer length
NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialResetDevice\n"));
return ioStatusBlock.Status;
}
/*****************************************************************************
* * Function: SerialSetBreakOn * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetBreakOn( IN PDEVICE_OBJECT pSerialDevObj ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetBreakOn\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_BREAK_ON, // io control code
NULL, 0, NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialSetBreakOn\n"));
return ioStatusBlock.Status;
} /*****************************************************************************
* * Function: SerialSetBreakOff * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetBreakOff( IN PDEVICE_OBJECT pSerialDevObj ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetBreakOff\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_BREAK_OFF, // io control code
NULL, 0, NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialSetBreakOff\n"));
return ioStatusBlock.Status;
} #if 0
/*****************************************************************************
* * Function: SerialGetTimeouts * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetTimeouts( IN PDEVICE_OBJECT pSerialDevObj, OUT PSERIAL_TIMEOUTS pTimeouts ) { PIRP pIrp; SERIAL_TIMEOUTS Timeouts; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialGetTimeouts\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to get baud rate and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_GET_TIMEOUTS, // io control code
pSerialDevObj, // device object
NULL, // input buffer
0, // input buffer length
&Timeouts, // output buffer
sizeof(SERIAL_TIMEOUTS), // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
ASSERT(sizeof(*pTimeouts) >= sizeof(SERIAL_TIMEOUTS));
RtlCopyMemory(pTimeouts, &Timeouts, sizeof(SERIAL_TIMEOUTS));
done: DEBUGMSG(DBG_FUNC, ("-SerialGetTimeouts\n")); return status; } #endif
/*****************************************************************************
* * Function: SerialSetTimeouts * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetTimeouts( IN PDEVICE_OBJECT pSerialDevObj, IN SERIAL_TIMEOUTS *pTimeouts ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetTimeouts\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_TIMEOUTS, // io control code
pTimeouts, // input buffer
sizeof(SERIAL_TIMEOUTS), // input buffer length
NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialSetTimeouts\n"));
return ioStatusBlock.Status; } #if 0
/*****************************************************************************
* * Function: SerialImmediateChar * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialImmediateChar( IN PDEVICE_OBJECT pSerialDevObj, IN UCHAR *pImmediateChar ) { PIRP pIrp; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialImmediateChar\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to set baud rate and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_IMMEDIATE_CHAR, // io control code
pSerialDevObj, // device object
pImmediateChar, // input buffer
sizeof(UCHAR), // input buffer length
NULL, // output buffer
0, // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
done: DEBUGMSG(DBG_FUNC, ("-SerialImmediateChar\n")); return status; } /*****************************************************************************
* * Function: SerialXoffCounter * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/ NTSTATUS SerialXoffCounter( IN PDEVICE_OBJECT pSerialDevObj, IN PSERIAL_XOFF_COUNTER pXoffCounter ) { PIRP pIrp; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialXoffCounter\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to set baud rate and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_XOFF_COUNTER, // io control code
pSerialDevObj, // device object
pXoffCounter, // input buffer
sizeof(SERIAL_XOFF_COUNTER), // input buffer length
NULL, // output buffer
0, // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
done: DEBUGMSG(DBG_FUNC, ("-SerialXoffCounter\n")); return status; } #endif
/*****************************************************************************
* * Function: SerialSetDTR * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetDTR( IN PDEVICE_OBJECT pSerialDevObj ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetDTR\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_DTR, // io control code
NULL, 0, NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialSetDTR\n"));
return ioStatusBlock.Status; }
/*****************************************************************************
* * Function: SerialClrDTR * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialClrDTR( IN PDEVICE_OBJECT pSerialDevObj ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialClrDTR\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_CLR_DTR, // io control code
NULL, 0, NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialClrDTR\n"));
return ioStatusBlock.Status; }
/*****************************************************************************
* * Function: SerialSetRTS * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetRTS( IN PDEVICE_OBJECT pSerialDevObj ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetRTS\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_RTS, // io control code
NULL, 0, NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialSetRTS\n"));
return ioStatusBlock.Status; }
/*****************************************************************************
* * Function: SerialClrRTS * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialClrRTS( IN PDEVICE_OBJECT pSerialDevObj ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialClrRTS\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_CLR_RTS, // io control code
NULL, 0, NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialClrRTS\n"));
return ioStatusBlock.Status; } #if 0
/*****************************************************************************
* * Function: SerialGetDtrRts * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetDtrRts( IN PDEVICE_OBJECT pSerialDevObj, OUT ULONG *pDtrRts ) { PIRP pIrp; ULONG DtrRts; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialGetDtrRts\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to get baud rate and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_GET_DTRRTS, // io control code
pSerialDevObj, // device object
NULL, // input buffer
0, // input buffer length
&DtrRts, // output buffer
sizeof(ULONG), // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
ASSERT(sizeof(*pDtrRts) >= sizeof(ULONG));
RtlCopyMemory(pDtrRts, &DtrRts, sizeof(ULONG));
done: DEBUGMSG(DBG_FUNC, ("-SerialGetDtrRts\n")); return status; } #endif
#if 0
/*****************************************************************************
* * Function: SerialSetXon * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetXon( IN PDEVICE_OBJECT pSerialDevObj ) { PIRP pIrp; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialSetXon\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to set Xon and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_SET_XON, // io control code
pSerialDevObj, // device object
NULL, // input buffer
0, // input buffer length
NULL, // output buffer
0, // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
done: DEBUGMSG(DBG_FUNC, ("-SerialSetXon\n")); return status; }
/*****************************************************************************
* * Function: SerialSetXoff * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetXoff( IN PDEVICE_OBJECT pSerialDevObj ) { PIRP pIrp; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialSetXoff\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to set Xoff and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_SET_XON, // io control code
pSerialDevObj, // device object
NULL, // input buffer
0, // input buffer length
NULL, // output buffer
0, // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
done: DEBUGMSG(DBG_FUNC, ("-SerialSetXoff\n")); return status; } #endif
#if 0
/*****************************************************************************
* * Function: SerialGetWaitMask * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetWaitMask( IN PDEVICE_OBJECT pSerialDevObj, OUT ULONG *pWaitMask ) { PIRP pIrp; ULONG WaitMask; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialGetWaitMask\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to get baud rate and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_GET_WAIT_MASK, // io control code
pSerialDevObj, // device object
NULL, // input buffer
0, // input buffer length
&WaitMask, // output buffer
sizeof(ULONG), // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
ASSERT(sizeof(*pWaitMask) >= sizeof(ULONG));
RtlCopyMemory(pWaitMask, &WaitMask, sizeof(ULONG));
done: DEBUGMSG(DBG_FUNC, ("-SerialGetWaitMask\n")); return status; } #endif
/*****************************************************************************
* * Function: SerialSetWaitMask * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetWaitMask( IN PDEVICE_OBJECT pSerialDevObj, IN ULONG *pWaitMask ) { IO_STATUS_BLOCK ioStatusBlock;
DEBUGMSG(DBG_FUNC, ("+SerialSetWaitMask\n"));
SendIoctlToSerial( pSerialDevObj, &ioStatusBlock, IOCTL_SERIAL_SET_WAIT_MASK, // io control code
pWaitMask, // input buffer
sizeof(ULONG), // input buffer length
NULL, 0 );
DEBUGMSG(DBG_FUNC, ("-SerialSetWaitMask\n"));
return ioStatusBlock.Status; } #if 0
/*****************************************************************************
* * Function: SerialWaitOnMask * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialWaitOnMask( IN PDEVICE_OBJECT pSerialDevObj, OUT ULONG *pWaitOnMask ) { PIRP pIrp; ULONG WaitOnMask; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialWaitOnMask\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to get baud rate and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_WAIT_ON_MASK, // io control code
pSerialDevObj, // device object
NULL, // input buffer
0, // input buffer length
&WaitOnMask, // output buffer
sizeof(ULONG), // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
*pWaitOnMask = WaitOnMask;
done: DEBUGMSG(DBG_FUNC, ("-SerialWaitOnMask\n")); return status; } #endif
/*****************************************************************************
* * Function: SerialCallbackOnMask * * Synopsis: Asynchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 10-03-1998 stana author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialCallbackOnMask( IN PDEVICE_OBJECT pSerialDevObj, IN PIO_COMPLETION_ROUTINE pRoutine, IN PIO_STATUS_BLOCK pIosb, IN PVOID Context, OUT PULONG pResult ) { PIRP pIrp; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialCallbackOnMask\n"));
NdisZeroMemory(pIosb, sizeof(IO_STATUS_BLOCK));
//
// build irp to get baud rate and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_WAIT_ON_MASK, // io control code
pSerialDevObj, // device object
NULL, // input buffer
0, // input buffer length
pResult, // output buffer
sizeof(ULONG), // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
NULL, // event to wait for completion
pIosb // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
IoSetCompletionRoutine(pIrp, pRoutine, Context, TRUE, TRUE, TRUE);
LOG_ENTRY('WI', Context, pIrp, 0); status = IoCallDriver(pSerialDevObj, pIrp);
done: DEBUGMSG(DBG_FUNC, ("-SerialCallbackOnMask\n")); return status; }
#if 0
/*****************************************************************************
* * Function: SerialGetChars * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialGetChars( IN PDEVICE_OBJECT pSerialDevObj, OUT PSERIAL_CHARS pChars ) { PIRP pIrp; SERIAL_CHARS Chars; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialGetChars\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to get baud rate and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_GET_CHARS, // io control code
pSerialDevObj, // device object
NULL, // input buffer
0, // input buffer length
&Chars, // output buffer
sizeof(SERIAL_CHARS), // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
ASSERT(sizeof(*pChars) >= sizeof(SERIAL_CHARS));
RtlCopyMemory(pChars, &Chars, sizeof(SERIAL_CHARS));
done: DEBUGMSG(DBG_FUNC, ("-SerialGetChars\n")); return status; }
/*****************************************************************************
* * Function: SerialSetChars * * Synopsis: Synchronous I/O control request to serial device object. * * Arguments: * * Returns: STATUS_SUCCESS * STATUS_INSUFFICIENT_RESOURCES * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails * * Algorithm: * * History: dd-mm-yyyy Author Comment * 9/30/1996 sholden author * * Notes: * * This routine must be called from IRQL PASSIVE_LEVEL. * *****************************************************************************/
NTSTATUS SerialSetChars( IN PDEVICE_OBJECT pSerialDevObj, IN PSERIAL_CHARS pChars ) { PIRP pIrp; KEVENT eventComplete; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialSetChars\n"));
//
// event to wait for completion of serial driver
//
KeInitializeEvent( &eventComplete, NotificationEvent, FALSE );
//
// build irp to set baud rate and wait for event signalled
//
// irp is released by io manager
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_SERIAL_SET_CHARS, // io control code
pSerialDevObj, // device object
pChars, // input buffer
sizeof(SERIAL_CHARS), // input buffer length
NULL, // output buffer
0, // output buffer length
FALSE, // calls IRP_MJ_DEVICE_CONTROL
// rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
&eventComplete, // event to wait for completion
&ioStatusBlock // io status block to be set
);
if (pIrp == NULL) { DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES;
goto done; }
status = IoCallDriver(pSerialDevObj, pIrp);
//
// if IoCallDriver returns STATUS_PENDING, we need to wait for the event
//
if (status == STATUS_PENDING) { KeWaitForSingleObject( &eventComplete, // object to wait for
Executive, // reason to wait
KernelMode, // processor mode
FALSE, // alertable
NULL // timeout
);
//
// we can get the status of the IoCallDriver from the io status
// block
//
status = ioStatusBlock.Status; }
//
// if IoCallDriver returns something other that STATUS_PENDING, then it
// is the same as what the serial driver set in ioStatusBlock.Status
//
if (status != STATUS_SUCCESS) { DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
goto done; }
done: DEBUGMSG(DBG_FUNC, ("-SerialSetChars\n")); return status; } #endif
NTSTATUS IrpCompleteSetEvent(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pContext) { PKEVENT pEvent = pContext;
DEBUGMSG(DBG_FUNC, ("+IrpCompleteSetEvent\n")); KeSetEvent(pEvent, 0, FALSE);
*pIrp->UserIosb = pIrp->IoStatus;
IoFreeIrp(pIrp);
DEBUGMSG(DBG_FUNC, ("-IrpCompleteSetEvent\n")); return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS SerialFlush(IN PDEVICE_OBJECT pSerialDevObj) { PIRP Irp; PIO_STACK_LOCATION IrpSp; NTSTATUS Status; KEVENT Event; IO_STATUS_BLOCK IOStatus; ULONG WaitMask = SERIAL_EV_TXEMPTY;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialFlush\n"));
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
KeInitializeEvent( &Event, NotificationEvent, FALSE );
RtlZeroMemory(&IOStatus, sizeof(IOStatus));
Irp = SerialBuildReadWriteIrp(pSerialDevObj, IRP_MJ_FLUSH_BUFFERS, NULL, 0, &IOStatus);
if (Irp == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto sfDone; }
IoSetCompletionRoutine(Irp, IrpCompleteSetEvent, &Event, TRUE, TRUE, TRUE);
Status = IoCallDriver(pSerialDevObj, Irp);
if (Status == STATUS_PENDING) { KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL ); } Status = IOStatus.Status;
sfDone:
#if DBG
if (Status != STATUS_SUCCESS) { DEBUGMSG(DBG_ERR, (" SerialFlush() Failed. 0x%08X\n\n", Status)); } #endif
DEBUGMSG(DBG_FUNC, ("-SerialFlush\n")); return Status; }
NTSTATUS SerialSynchronousWrite( IN PDEVICE_OBJECT pSerialDevObj, IN PVOID pBuffer, IN ULONG dwLength, OUT PULONG pdwBytesWritten) { PIRP Irp; PIO_STACK_LOCATION IrpSp; NTSTATUS Status; KEVENT Event; IO_STATUS_BLOCK IOStatus; ULONG WaitMask = SERIAL_EV_TXEMPTY;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialSynchronousWrite\n"));
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
//(void)SerialSetWaitMask(pSerialDevObj, &WaitMask);
KeInitializeEvent( &Event, NotificationEvent, FALSE );
RtlZeroMemory(&IOStatus, sizeof(IOStatus));
Irp = SerialBuildReadWriteIrp(pSerialDevObj, IRP_MJ_WRITE, pBuffer, dwLength, &IOStatus);
if (Irp == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto sswDone; }
IoSetCompletionRoutine(Irp, IrpCompleteSetEvent, &Event, TRUE, TRUE, TRUE);
Status = IoCallDriver(pSerialDevObj, Irp);
if (Status == STATUS_PENDING) { KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL ); } Status = IOStatus.Status;
// This truncates if 64 bits. Don't think we'll be reading or writing more than
// 4.5 GB to a serial port soon.
*pdwBytesWritten = (ULONG)IOStatus.Information;
(void)SerialFlush(pSerialDevObj); //(void)SerialWaitOnMask(pSerialDevObj, &WaitMask);
sswDone:
#if DBG
if (Status != STATUS_SUCCESS) { DEBUGMSG(DBG_ERR, (" SerialSynchronousWrite() Failed. 0x%08X\n\n", Status)); } #endif
DEBUGMSG(DBG_FUNC, ("-SerialSynchronousWrite\n")); return Status; }
NTSTATUS SerialSynchronousRead( IN PDEVICE_OBJECT pSerialDevObj, OUT PVOID pBuffer, IN ULONG dwLength, OUT PULONG pdwBytesRead) { PIRP Irp; PIO_STACK_LOCATION IrpSp; NTSTATUS Status; KEVENT Event; IO_STATUS_BLOCK IOStatus;
*pdwBytesRead = 0;
if (!pSerialDevObj) { DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n")); return STATUS_INVALID_PARAMETER; }
DEBUGMSG(DBG_FUNC, ("+SerialSynchronousRead\n"));
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
KeInitializeEvent( &Event, NotificationEvent, FALSE );
RtlZeroMemory(&IOStatus, sizeof(IOStatus));
Irp = SerialBuildReadWriteIrp(pSerialDevObj, IRP_MJ_READ, pBuffer, dwLength, &IOStatus);
if (Irp == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto ssrDone; }
IoSetCompletionRoutine(Irp, IrpCompleteSetEvent, &Event, TRUE, TRUE, TRUE);
Status = IoCallDriver(pSerialDevObj, Irp);
if (Status == STATUS_PENDING) { KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL ); }
Status = IOStatus.Status;
// This truncates if 64 bits. Don't think we'll be reading or writing more than
// 4.5 GB to a serial port soon.
*pdwBytesRead = (ULONG)IOStatus.Information;
ssrDone:
#if DBG
if (Status != STATUS_SUCCESS) { DEBUGMSG(DBG_WARN, (" SerialSynchronousRead() Failed. 0x%08X\n\n", Status)); } #endif
DEBUGMSG(DBG_FUNC, ("-SerialSynchronousRead\n")); return Status; }
|