1220 lines
23 KiB
C++
1220 lines
23 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1990-2000 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
Com
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Takes care of request involving a COM device
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ramon Juan San Andres (ramonsa) 26-Jun-1991
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#include "mode.hxx"
|
|||
|
#include "com.hxx"
|
|||
|
#include "array.hxx"
|
|||
|
#include "arrayit.hxx"
|
|||
|
#include "file.hxx"
|
|||
|
#include "path.hxx"
|
|||
|
#include "registry.hxx"
|
|||
|
#include "regvalue.hxx"
|
|||
|
|
|||
|
|
|||
|
#define DEFAULT_PARITY COMM_PARITY_EVEN
|
|||
|
#define DEFAULT_DATA_BITS 7
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Local prototypes
|
|||
|
//
|
|||
|
BOOLEAN
|
|||
|
ComStatus(
|
|||
|
IN PCPATH DevicePath,
|
|||
|
IN PREQUEST_HEADER Request
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
ComSetup(
|
|||
|
IN PCPATH DevicePath,
|
|||
|
IN PREQUEST_HEADER Request
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
IsAValidCommDevice (
|
|||
|
IN DEVICE_TTYPE DeviceType,
|
|||
|
IN ULONG DeviceNumber,
|
|||
|
OUT PPATH *DevicePathPointer
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
ComAllocateStuff(
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Initializes Data Structures used for COMM processing.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
nonde
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if global data initialized, FALSE otherwise
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
ComDeAllocateStuff(
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Deallocates the stuff allocated by ComAllocateStuff.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
nonde
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if global data de-initialized, FALSE otherwise
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
ComHandler(
|
|||
|
IN PREQUEST_HEADER Request
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Handles serial port requests.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Request - Supplies pointer to request
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if request serviced,
|
|||
|
FALSE otherwise.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
PPATH DevicePath; // Name of Device
|
|||
|
BOOLEAN Served = TRUE; // TRUE if request served OK.
|
|||
|
|
|||
|
DebugPtrAssert( Request );
|
|||
|
DebugAssert( Request->DeviceType == DEVICE_TYPE_COM );
|
|||
|
|
|||
|
//
|
|||
|
// Make sure that the device exists, and at the same time get its
|
|||
|
// name ( For calling APIs ).
|
|||
|
//
|
|||
|
if ( Request->DeviceName ) {
|
|||
|
|
|||
|
if (!(DevicePath = NEW PATH)) {
|
|||
|
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
|
|||
|
NULL,
|
|||
|
(ULONG)EXIT_ERROR );
|
|||
|
return FALSE; // help lint
|
|||
|
}
|
|||
|
DevicePath->Initialize( Request->DeviceName );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
if ( !IsAValidCommDevice( Request->DeviceType, Request->DeviceNumber, &DevicePath )) {
|
|||
|
|
|||
|
DisplayMessageAndExit( MODE_ERROR_INVALID_DEVICE_NAME,
|
|||
|
DevicePath->GetPathString(),
|
|||
|
(ULONG)EXIT_ERROR );
|
|||
|
|
|||
|
} else if ( !IsAValidDevice( Request->DeviceType, Request->DeviceNumber, NULL ) ) {
|
|||
|
|
|||
|
DisplayMessageAndExit( MODE_ERROR_DEVICE_UNAVAILABLE,
|
|||
|
DevicePath->GetPathString(),
|
|||
|
(ULONG)EXIT_ERROR );
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// So the device is valid. Now serve the request
|
|||
|
//
|
|||
|
switch( Request->RequestType ) {
|
|||
|
|
|||
|
case REQUEST_TYPE_STATUS:
|
|||
|
|
|||
|
//
|
|||
|
// Display state of COM device
|
|||
|
//
|
|||
|
Served = ComStatus( DevicePath, Request );
|
|||
|
break;
|
|||
|
|
|||
|
case REQUEST_TYPE_COM_SET:
|
|||
|
|
|||
|
//
|
|||
|
// Set state of COM device
|
|||
|
//
|
|||
|
Served = ComSetup( DevicePath, Request );
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
DebugAssert( FALSE );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DELETE( DevicePath );
|
|||
|
|
|||
|
return Served;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
ComStatus(
|
|||
|
IN PCPATH DevicePath,
|
|||
|
IN PREQUEST_HEADER Request
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Displays status if a COM device
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DevicePath - Supplies pointer to path of device
|
|||
|
Request - Supplies pointer to request
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if status displayed successfully,
|
|||
|
FALSE otherwise
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DSTRING Data;
|
|||
|
COMM_DEVICE CommDevice; // Comm object of the device.
|
|||
|
BOOLEAN OpenError;
|
|||
|
BOOLEAN Status;
|
|||
|
|
|||
|
DebugPtrAssert( DevicePath );
|
|||
|
DebugPtrAssert( Request );
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the Comm object
|
|||
|
//
|
|||
|
Status = CommDevice.Initialize( DevicePath, &OpenError);
|
|||
|
|
|||
|
|
|||
|
if ( Status ) {
|
|||
|
|
|||
|
//
|
|||
|
// Write the Header
|
|||
|
//
|
|||
|
WriteStatusHeader( DevicePath );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Baud rate
|
|||
|
//
|
|||
|
Data.Initialize( (ULONG)CommDevice.QueryBaudRate() );
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_BAUD, &Data );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Parity
|
|||
|
//
|
|||
|
switch ( CommDevice.QueryParity() ) {
|
|||
|
|
|||
|
case COMM_PARITY_NONE:
|
|||
|
Data.Initialize( "None" );
|
|||
|
break;
|
|||
|
|
|||
|
case COMM_PARITY_ODD:
|
|||
|
Data.Initialize( "Odd" );
|
|||
|
break;
|
|||
|
|
|||
|
case COMM_PARITY_EVEN:
|
|||
|
Data.Initialize( "Even" );
|
|||
|
break;
|
|||
|
|
|||
|
case COMM_PARITY_MARK:
|
|||
|
Data.Initialize( "Mark" );
|
|||
|
break;
|
|||
|
|
|||
|
case COMM_PARITY_SPACE:
|
|||
|
Data.Initialize( "Space" );
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
DebugAssert( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_PARITY, &Data );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Data bits
|
|||
|
//
|
|||
|
Data.Initialize( (ULONG)CommDevice.QueryDataBits() );
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_DATA, &Data );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Stop bits
|
|||
|
//
|
|||
|
switch ( CommDevice.QueryStopBits() ) {
|
|||
|
|
|||
|
case COMM_STOPBITS_15:
|
|||
|
Data.Initialize( "1.5" );
|
|||
|
break;
|
|||
|
|
|||
|
case COMM_STOPBITS_1:
|
|||
|
Data.Initialize( 1 );
|
|||
|
break;
|
|||
|
|
|||
|
case COMM_STOPBITS_2:
|
|||
|
Data.Initialize( 2 );
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
DebugAssert( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_STOP, &Data );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// TimeOut
|
|||
|
//
|
|||
|
if ( CommDevice.QueryTimeOut() ) {
|
|||
|
//
|
|||
|
// TRUE means infinite timeout == no timeout
|
|||
|
//
|
|||
|
Data.Initialize( "OFF" );
|
|||
|
} else {
|
|||
|
Data.Initialize( "ON" );
|
|||
|
}
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_TIMEOUT, &Data );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// XON/XOFF
|
|||
|
//
|
|||
|
if ( CommDevice.QueryXon() ) {
|
|||
|
Data.Initialize( "ON" );
|
|||
|
} else {
|
|||
|
Data.Initialize( "OFF" );
|
|||
|
}
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_XON, &Data );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// CTS
|
|||
|
//
|
|||
|
if ( CommDevice.QueryOcts() ) {
|
|||
|
Data.Initialize( "ON" );
|
|||
|
} else {
|
|||
|
Data.Initialize( "OFF" );
|
|||
|
}
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_OCTS, &Data );
|
|||
|
|
|||
|
//
|
|||
|
// DSR handshaking
|
|||
|
//
|
|||
|
if ( CommDevice.QueryOdsr() ) {
|
|||
|
Data.Initialize( "ON" );
|
|||
|
} else {
|
|||
|
Data.Initialize( "OFF" );
|
|||
|
}
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_ODSR, &Data );
|
|||
|
|
|||
|
//
|
|||
|
// DSR sensitivity
|
|||
|
//
|
|||
|
if ( CommDevice.QueryIdsr() ) {
|
|||
|
Data.Initialize( "ON" );
|
|||
|
} else {
|
|||
|
Data.Initialize( "OFF" );
|
|||
|
}
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_IDSR, &Data );
|
|||
|
|
|||
|
//
|
|||
|
// DTR
|
|||
|
//
|
|||
|
switch( CommDevice.QueryDtrControl() ) {
|
|||
|
|
|||
|
case DTR_ENABLE:
|
|||
|
Data.Initialize( "ON" );
|
|||
|
break;
|
|||
|
|
|||
|
case DTR_DISABLE:
|
|||
|
Data.Initialize( "OFF" );
|
|||
|
break;
|
|||
|
|
|||
|
case DTR_HANDSHAKE:
|
|||
|
Data.Initialize( "HANDSHAKE" );
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
Data.Initialize( "UNKNOWN" );
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_DTR, &Data );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// RTS
|
|||
|
//
|
|||
|
switch( CommDevice.QueryRtsControl() ) {
|
|||
|
|
|||
|
case RTS_ENABLE:
|
|||
|
Data.Initialize( "ON" );
|
|||
|
break;
|
|||
|
|
|||
|
case RTS_DISABLE:
|
|||
|
Data.Initialize( "OFF" );
|
|||
|
break;
|
|||
|
|
|||
|
case RTS_HANDSHAKE:
|
|||
|
Data.Initialize( "HANDSHAKE" );
|
|||
|
break;
|
|||
|
|
|||
|
case RTS_TOGGLE:
|
|||
|
Data.Initialize( "TOGGLE" );
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
Data.Initialize( "UNKNOWN" );
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
DisplayMessage( MODE_MESSAGE_STATUS_RTS, &Data );
|
|||
|
|
|||
|
Get_Standard_Output_Stream()->WriteChar( '\r' );
|
|||
|
Get_Standard_Output_Stream()->WriteChar( '\n' );
|
|||
|
|
|||
|
} else if ( !OpenError ) {
|
|||
|
|
|||
|
DisplayMessage( MODE_ERROR_CANNOT_ACCESS_DEVICE,
|
|||
|
DevicePath->GetPathString() );
|
|||
|
|
|||
|
Status = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
ComSetup(
|
|||
|
IN PCPATH DevicePath,
|
|||
|
IN PREQUEST_HEADER Request
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Sets the state of a COM port
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DevicePath - Supplies pointer to path of device
|
|||
|
Request - Supplies pointer to request
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if state set successfully,
|
|||
|
FALSE otherwise
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
PCOMM_DEVICE CommDevice; // Comm object of the device.
|
|||
|
BOOLEAN Status = FALSE; // Indicates success or failure
|
|||
|
PREQUEST_DATA_COM_SET Data; // Request data
|
|||
|
BOOLEAN OpenError;
|
|||
|
DSTRING Number;
|
|||
|
|
|||
|
DebugPtrAssert( DevicePath );
|
|||
|
DebugPtrAssert( Request );
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the Comm object
|
|||
|
//
|
|||
|
CommDevice = NEW COMM_DEVICE;
|
|||
|
if ( !CommDevice ) {
|
|||
|
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR );
|
|||
|
return FALSE; // help lint
|
|||
|
}
|
|||
|
Status = CommDevice->Initialize( DevicePath, &OpenError );
|
|||
|
if ( Status ) {
|
|||
|
|
|||
|
//
|
|||
|
// We have the Comm object. Set the state according to
|
|||
|
// the request.
|
|||
|
//
|
|||
|
Data = &(((PCOM_REQUEST)Request)->Data.Set);
|
|||
|
|
|||
|
//
|
|||
|
// Baud rate
|
|||
|
//
|
|||
|
if ( Data->SetBaud ) {
|
|||
|
|
|||
|
CommDevice->SetBaudRate( Data->Baud );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Data Bits
|
|||
|
//
|
|||
|
if ( Data->SetDataBits ) {
|
|||
|
|
|||
|
CommDevice->SetDataBits( Data->DataBits );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Set default
|
|||
|
//
|
|||
|
if ( CommDevice->QueryDataBits() != DEFAULT_DATA_BITS ) {
|
|||
|
CommDevice->SetDataBits( DEFAULT_DATA_BITS );
|
|||
|
Number.Initialize( DEFAULT_DATA_BITS );
|
|||
|
DisplayMessage( MODE_MESSAGE_USED_DEFAULT_DATA, &Number );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Stop Bits
|
|||
|
//
|
|||
|
if ( Data->SetStopBits ) {
|
|||
|
|
|||
|
CommDevice->SetStopBits( Data->StopBits );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Set default
|
|||
|
//
|
|||
|
if ( CommDevice->QueryBaudRate() == 110 ) {
|
|||
|
if ( CommDevice->QueryStopBits() != COMM_STOPBITS_2 ) {
|
|||
|
CommDevice->SetStopBits( COMM_STOPBITS_2 );
|
|||
|
Number.Initialize( 2 );
|
|||
|
DisplayMessage( MODE_MESSAGE_USED_DEFAULT_STOP, &Number );
|
|||
|
}
|
|||
|
} else {
|
|||
|
if ( CommDevice->QueryStopBits() != COMM_STOPBITS_1 ) {
|
|||
|
CommDevice->SetStopBits( COMM_STOPBITS_1 );
|
|||
|
Number.Initialize( 1 );
|
|||
|
DisplayMessage( MODE_MESSAGE_USED_DEFAULT_STOP, &Number );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Parity
|
|||
|
//
|
|||
|
if ( Data->SetParity ) {
|
|||
|
|
|||
|
CommDevice->SetParity( Data->Parity );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Set default
|
|||
|
//
|
|||
|
if ( CommDevice->QueryParity() != DEFAULT_PARITY ) {
|
|||
|
CommDevice->SetParity( DEFAULT_PARITY );
|
|||
|
DisplayMessage( MODE_MESSAGE_USED_DEFAULT_PARITY, NULL );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Timeout
|
|||
|
//
|
|||
|
if ( Data->SetTimeOut ) {
|
|||
|
|
|||
|
CommDevice->SetTimeOut( Data->TimeOut );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// XON/XOFF
|
|||
|
//
|
|||
|
if ( Data->SetXon) {
|
|||
|
|
|||
|
CommDevice->SetXon( Data->Xon );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// CTS
|
|||
|
//
|
|||
|
if ( Data->SetOcts ) {
|
|||
|
|
|||
|
CommDevice->SetOcts( Data->Octs );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// DSR handshaking
|
|||
|
//
|
|||
|
if ( Data->SetOdsr ) {
|
|||
|
|
|||
|
CommDevice->SetOdsr( Data->Odsr );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// DSR sensitivity
|
|||
|
//
|
|||
|
if ( Data->SetIdsr ) {
|
|||
|
|
|||
|
CommDevice->SetIdsr( Data->Idsr );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// DTR
|
|||
|
//
|
|||
|
if ( Data->SetDtrControl ) {
|
|||
|
|
|||
|
CommDevice->SetDtrControl( Data->DtrControl );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// RTS
|
|||
|
//
|
|||
|
if ( Data->SetRtsControl ) {
|
|||
|
|
|||
|
CommDevice->SetRtsControl( Data->RtsControl );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Now Commit the changes
|
|||
|
//
|
|||
|
if ( !CommDevice->CommitState() ) {
|
|||
|
|
|||
|
DisplayMessage( MODE_ERROR_SERIAL_OPTIONS_NOT_SUPPORTED, NULL );
|
|||
|
DisplayMessageAndExit( MODE_MESSAGE_COM_NO_CHANGE,
|
|||
|
NULL,
|
|||
|
(ULONG)EXIT_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
} else if ( !OpenError ) {
|
|||
|
|
|||
|
DisplayMessageAndExit( MODE_ERROR_CANNOT_ACCESS_DEVICE,
|
|||
|
DevicePath->GetPathString(),
|
|||
|
(ULONG)EXIT_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
DELETE( CommDevice );
|
|||
|
|
|||
|
if ( Status ) {
|
|||
|
//
|
|||
|
// Display the status of the port (as confirmation ).
|
|||
|
//
|
|||
|
ComStatus( DevicePath, Request );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
LONG
|
|||
|
ConvertBaudRate (
|
|||
|
IN LONG BaudIn
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Validates a baud rate given as an argument to the program, and converts
|
|||
|
it to something that the COMM_DEVICE understands.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
BaudIn - Supplies the baud rate given by the user
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
LONG - The baud rate
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
LONG BaudRate;
|
|||
|
|
|||
|
switch ( BaudIn ) {
|
|||
|
|
|||
|
case 11:
|
|||
|
case 110:
|
|||
|
BaudRate = 110;
|
|||
|
break;
|
|||
|
|
|||
|
case 15:
|
|||
|
case 150:
|
|||
|
BaudRate = 150;
|
|||
|
break;
|
|||
|
|
|||
|
case 30:
|
|||
|
case 300:
|
|||
|
BaudRate = 300;
|
|||
|
break;
|
|||
|
|
|||
|
case 60:
|
|||
|
case 600:
|
|||
|
BaudRate = 600;
|
|||
|
break;
|
|||
|
|
|||
|
case 12:
|
|||
|
case 1200:
|
|||
|
BaudRate = 1200;
|
|||
|
break;
|
|||
|
|
|||
|
case 24:
|
|||
|
case 2400:
|
|||
|
BaudRate = 2400;
|
|||
|
break;
|
|||
|
|
|||
|
case 48:
|
|||
|
case 4800:
|
|||
|
BaudRate = 4800;
|
|||
|
break;
|
|||
|
|
|||
|
case 96:
|
|||
|
case 9600:
|
|||
|
BaudRate = 9600;
|
|||
|
break;
|
|||
|
|
|||
|
case 19:
|
|||
|
case 19200:
|
|||
|
BaudRate = 19200;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
BaudRate = BaudIn;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return BaudRate;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
LONG
|
|||
|
ConvertDataBits (
|
|||
|
IN LONG DataBitsIn
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Validates the number of data bits given as an argument to the program,
|
|||
|
and converts it to something that the COMM_DEVICE understands.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DataBitsIn - Supplies the number given by the user
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
LONG - The number of data bits
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
if ( ( DataBitsIn != 5 ) &&
|
|||
|
( DataBitsIn != 6 ) &&
|
|||
|
( DataBitsIn != 7 ) &&
|
|||
|
( DataBitsIn != 8 ) ) {
|
|||
|
|
|||
|
ParseError();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return DataBitsIn;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
STOPBITS
|
|||
|
ConvertStopBits (
|
|||
|
IN LONG StopBitsIn
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Validates a number of stop bits given as an argument to the program,
|
|||
|
and converts it to something that the COMM_DEVICE understands.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
StopBitsIn - Supplies the number given by the user
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STOPBITS - The number of stop bits
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
STOPBITS StopBits;
|
|||
|
|
|||
|
switch ( StopBitsIn ) {
|
|||
|
|
|||
|
case 1:
|
|||
|
StopBits = COMM_STOPBITS_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
StopBits = COMM_STOPBITS_2;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
ParseError();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return StopBits;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
PARITY
|
|||
|
ConvertParity (
|
|||
|
IN WCHAR ParityIn
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Validates a parity given as an argument to the program, and converts
|
|||
|
it to something that the COMM_DEVICE understands.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ParityIn - Supplies the baud rate given by the user
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
PARITY - The parity
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
DSTRING ParityString;;
|
|||
|
WCHAR Par;
|
|||
|
PARITY Parity;
|
|||
|
|
|||
|
//
|
|||
|
// Get the character that specifies parity. We lowercase it
|
|||
|
//
|
|||
|
ParityString.Initialize( " " );
|
|||
|
ParityString.SetChAt( ParityIn, 0 );
|
|||
|
|
|||
|
ParityString.Strlwr();
|
|||
|
Par = ParityString.QueryChAt( 0 );
|
|||
|
|
|||
|
//
|
|||
|
// Set the correct parity value depending on the character.
|
|||
|
//
|
|||
|
switch ( Par ) {
|
|||
|
|
|||
|
case 'n':
|
|||
|
Parity = COMM_PARITY_NONE;
|
|||
|
break;
|
|||
|
|
|||
|
case 'o':
|
|||
|
Parity = COMM_PARITY_ODD;
|
|||
|
break;
|
|||
|
|
|||
|
case 'e':
|
|||
|
Parity = COMM_PARITY_EVEN;
|
|||
|
break;
|
|||
|
|
|||
|
case 'm':
|
|||
|
Parity = COMM_PARITY_MARK;
|
|||
|
break;
|
|||
|
|
|||
|
case 's':
|
|||
|
Parity = COMM_PARITY_SPACE;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
ParseError();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return Parity;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
WCHAR
|
|||
|
ConvertRetry (
|
|||
|
IN WCHAR RetryIn
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Validates a retry value given as an argument to the program, and
|
|||
|
converts it to something that the COMM_DEVICE understands.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
RetryIn - Supplies the retry value given by the user
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
WCHAR - The retry value
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return RetryIn;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DTR_CONTROL
|
|||
|
ConvertDtrControl (
|
|||
|
IN PCWSTRING CmdLine,
|
|||
|
IN CHNUM IdxBegin,
|
|||
|
IN CHNUM IdxEnd
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Validates a DTR control value given as an argument to the
|
|||
|
program, and converts it to something that the COMM_DEVICE
|
|||
|
understands.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
CmdLine - Supplies the command line
|
|||
|
IdxBegin - Supplies Index of first character
|
|||
|
IdxEnd - Supplies Index of last character
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
DTR_CONTROL - The DTR control value
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DSTRING On;
|
|||
|
DSTRING Off;
|
|||
|
DSTRING Hs;
|
|||
|
|
|||
|
|
|||
|
if ( On.Initialize( "ON" ) &&
|
|||
|
Off.Initialize( "OFF" ) &&
|
|||
|
Hs.Initialize( "HS" ) ) {
|
|||
|
|
|||
|
|
|||
|
if ( !CmdLine->Stricmp( &On,
|
|||
|
IdxBegin,
|
|||
|
IdxEnd-IdxBegin+1,
|
|||
|
0,
|
|||
|
On.QueryChCount() ) ) {
|
|||
|
|
|||
|
return DTR_ENABLE;
|
|||
|
}
|
|||
|
|
|||
|
if ( !CmdLine->Stricmp( &Off,
|
|||
|
IdxBegin,
|
|||
|
IdxEnd-IdxBegin+1,
|
|||
|
0,
|
|||
|
Off.QueryChCount() ) ) {
|
|||
|
|
|||
|
return DTR_DISABLE;
|
|||
|
}
|
|||
|
|
|||
|
if ( !CmdLine->Stricmp( &Hs,
|
|||
|
IdxBegin,
|
|||
|
IdxEnd-IdxBegin+1,
|
|||
|
0,
|
|||
|
Hs.QueryChCount() ) ) {
|
|||
|
|
|||
|
return DTR_HANDSHAKE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ParseError();
|
|||
|
|
|||
|
return (DTR_CONTROL)-1;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
RTS_CONTROL
|
|||
|
ConvertRtsControl (
|
|||
|
IN PCWSTRING CmdLine,
|
|||
|
IN CHNUM IdxBegin,
|
|||
|
IN CHNUM IdxEnd
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Validates a RTS control value given as an argument to the
|
|||
|
program, and converts it to something that the COMM_DEVICE
|
|||
|
understands.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
CmdLine - Supplies the command line
|
|||
|
IdxBegin - Supplies Index of first character
|
|||
|
IdxEnd - Supplies Index of last character
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RTS_CONTROL - The RTS control value
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DSTRING On;
|
|||
|
DSTRING Off;
|
|||
|
DSTRING Hs;
|
|||
|
DSTRING Tg;
|
|||
|
|
|||
|
|
|||
|
if ( On.Initialize( "ON" ) &&
|
|||
|
Off.Initialize( "OFF" ) &&
|
|||
|
Hs.Initialize( "HS" ) &&
|
|||
|
Tg.Initialize( "TG" )
|
|||
|
) {
|
|||
|
|
|||
|
|
|||
|
if ( !CmdLine->Stricmp( &On,
|
|||
|
IdxBegin,
|
|||
|
IdxEnd-IdxBegin+1,
|
|||
|
0,
|
|||
|
On.QueryChCount() ) ) {
|
|||
|
|
|||
|
return RTS_ENABLE;
|
|||
|
}
|
|||
|
|
|||
|
if ( !CmdLine->Stricmp( &Off,
|
|||
|
IdxBegin,
|
|||
|
IdxEnd-IdxBegin+1,
|
|||
|
0,
|
|||
|
Off.QueryChCount() ) ) {
|
|||
|
|
|||
|
return RTS_DISABLE;
|
|||
|
}
|
|||
|
|
|||
|
if ( !CmdLine->Stricmp( &Hs,
|
|||
|
IdxBegin,
|
|||
|
IdxEnd-IdxBegin+1,
|
|||
|
0,
|
|||
|
Hs.QueryChCount() ) ) {
|
|||
|
|
|||
|
return RTS_HANDSHAKE;
|
|||
|
}
|
|||
|
|
|||
|
if ( !CmdLine->Stricmp( &Tg,
|
|||
|
IdxBegin,
|
|||
|
IdxEnd-IdxBegin+1,
|
|||
|
0,
|
|||
|
Tg.QueryChCount() ) ) {
|
|||
|
|
|||
|
return RTS_TOGGLE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ParseError();
|
|||
|
|
|||
|
return (RTS_CONTROL)-1;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
IsAValidCommDevice (
|
|||
|
IN DEVICE_TTYPE DeviceType,
|
|||
|
IN ULONG DeviceNumber,
|
|||
|
OUT PPATH *DevicePathPointer
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Determines if a certain comm device exists and optionally
|
|||
|
creates a path for it.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DeviceType - Supplies the type of device
|
|||
|
DeviceNumber - Supplies the device number
|
|||
|
DeviceName - Supplies a pointer to a pointer to the path for
|
|||
|
the device.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if the device exists,
|
|||
|
FALSE otherwise.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DSTRING DeviceName;
|
|||
|
DSTRING Number;
|
|||
|
BOOLEAN Valid = FALSE;
|
|||
|
REGISTRY Registry;
|
|||
|
DSTRING ParentName;
|
|||
|
DSTRING KeyName;
|
|||
|
ARRAY ValueArray;
|
|||
|
PARRAY_ITERATOR Iterator;
|
|||
|
ULONG ErrorCode;
|
|||
|
PCBYTE Data;
|
|||
|
DSTRING PortName;
|
|||
|
PREGISTRY_VALUE_ENTRY Value;
|
|||
|
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER( DeviceType );
|
|||
|
|
|||
|
|
|||
|
if ( DeviceName.Initialize( (LPWSTR)L"COM" )&&
|
|||
|
Number.Initialize( DeviceNumber ) &&
|
|||
|
DeviceName.Strcat( &Number ) &&
|
|||
|
ParentName.Initialize( "" ) &&
|
|||
|
KeyName.Initialize( COMM_KEY_NAME ) &&
|
|||
|
ValueArray.Initialize() &&
|
|||
|
Registry.Initialize()
|
|||
|
) {
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Get the names of all the serial ports
|
|||
|
//
|
|||
|
if ( Registry.QueryValues(
|
|||
|
PREDEFINED_KEY_LOCAL_MACHINE,
|
|||
|
&ParentName,
|
|||
|
&KeyName,
|
|||
|
&ValueArray,
|
|||
|
&ErrorCode
|
|||
|
) ) {
|
|||
|
|
|||
|
//
|
|||
|
// See if the given name matches any of the serial ports
|
|||
|
//
|
|||
|
if ( Iterator = (PARRAY_ITERATOR)ValueArray.QueryIterator() ) {
|
|||
|
|
|||
|
while ( Value = (PREGISTRY_VALUE_ENTRY)(Iterator->GetNext() ) ) {
|
|||
|
|
|||
|
if ( Value->GetData( &Data ) ) {
|
|||
|
|
|||
|
if ( PortName.Initialize( (PWSTR)Data ) ) {
|
|||
|
|
|||
|
if ( !DeviceName.Stricmp( &PortName ) ) {
|
|||
|
|
|||
|
Valid = TRUE;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DELETE( Iterator );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( DevicePathPointer ) {
|
|||
|
|
|||
|
if (!(*DevicePathPointer = NEW PATH)) {
|
|||
|
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
|
|||
|
NULL,
|
|||
|
(ULONG)EXIT_ERROR );
|
|||
|
return FALSE; // help lint
|
|||
|
}
|
|||
|
(*DevicePathPointer)->Initialize( &DeviceName );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return Valid;
|
|||
|
}
|