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;
|
||
}
|