Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1518 lines
28 KiB

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
Argument
Abstract:
Argument processing for the Mode utility. After parsing the
arguments off the command line, a minimum verification is done and
a request packet is formed and returned.
The request packet is eventually routed to the handler for a specific
device, which performs further verification and takes proper
action.
Author:
Ramon Juan San Andres (ramonsa) 26-Jun-1991
Notes:
BUGBUG ramonsa 7/9/91
The number of stop bits can be 1, 1.5 or 2, Currently the library will
not support floating point operations, so there are no
floating-point-number arguments. We use a flag argument to handle
the 1.5 case. This should be fixed whenever the library supports
floating point.
The mode command-line can take any of the following forms:
MODE [/?]
MODE [device] [/STATUS]
MODE device CP PREPARE=string
MODE device CP REFRESH
MODE device CP SELECT=codepage
MODE device CP [/STATUS]
MODE LPTn[:] [COLS=c] [LINES=l] [RETRY=r]
MODE LPTn[:] = COMm[:]
MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s] [RETRY=r]
MODE CON[:] [COLS=c] [LINES=l]
MODE CON[:] [RATE=r DELAY=d]
Revision History:
--*/
#include "mode.hxx"
#include "arg.hxx"
#include "array.hxx"
#include "common.hxx"
#include "lpt.hxx"
#include "com.hxx"
#include "con.hxx"
//
// BUGBUG all variables here should be static
//
PWSTRING LptPattern = NULL;
PWSTRING LptColonPattern = NULL;
PWSTRING ComPattern = NULL;
PWSTRING ComColonPattern = NULL;
PWSTRING ConPattern = NULL;
PWSTRING ConColonPattern = NULL;
PWSTRING StatusPattern = NULL;
PWSTRING ColPattern = NULL;
PWSTRING LinesPattern = NULL;
PWSTRING CpPattern = NULL;
PWSTRING PreparePattern = NULL;
PWSTRING RetryPattern = NULL;
PWSTRING EqualPattern = NULL;
PWSTRING BaudPattern = NULL;
PWSTRING ParityPattern = NULL;
PWSTRING DataPattern = NULL;
PWSTRING StopPattern = NULL;
PWSTRING Stop15Pattern = NULL;
PWSTRING SelectPattern = NULL;
PWSTRING RefreshPattern = NULL;
PWSTRING RatePattern = NULL;
PWSTRING DelayPattern = NULL;
PWSTRING HelpPattern = NULL;
//
// Parsing preferences
//
PWSTRING Switches = NULL;
//
// Arguments
//
PPATH_ARGUMENT ProgramNameArg;
PLONG_ARGUMENT LptArg;
PLONG_ARGUMENT LptColonArg;
PLONG_ARGUMENT ComArg;
PLONG_ARGUMENT ComColonArg;
PFLAG_ARGUMENT ConArg;
PFLAG_ARGUMENT ConColonArg;
PSTRING_ARGUMENT StatusArg;
PLONG_ARGUMENT ColArg;
PLONG_ARGUMENT LinesArg;
PFLAG_ARGUMENT CpArg;
PSTRING_ARGUMENT PrepareArg;
PSTRING_ARGUMENT RetryArg;
PFLAG_ARGUMENT EqualArg;
PLONG_ARGUMENT BaudArg;
PSTRING_ARGUMENT ParityArg;
PLONG_ARGUMENT DataArg;
PLONG_ARGUMENT StopArg;
PFLAG_ARGUMENT Stop15Arg;
PLONG_ARGUMENT SelectArg;
PFLAG_ARGUMENT RefreshArg;
PLONG_ARGUMENT RateArg;
PLONG_ARGUMENT DelayArg;
PFLAG_ARGUMENT HelpArg;
//
// The Argument lexemizer and lexeme array.
//
PARGUMENT_LEXEMIZER ArgLex;
PARRAY LexArray;
//
// Some device information so we don't have to be querying the arguments
// all the time.
//
BOOLEAN LptSet;
ULONG LptNumber;
BOOLEAN ComSet;
ULONG ComNumber;
BOOLEAN ConSet;
VOID
AllocateStuff(
);
VOID
DeallocateStuff(
);
PARRAY
GetArgumentArray(
);
VOID
ParseArguments(
IN PARRAY ArgArray
);
PREQUEST_HEADER
MakeRequest(
);
PREQUEST_HEADER
MakeStatusRequest(
);
PREQUEST_HEADER
MakeCodePageRequest(
);
PREQUEST_HEADER
MakeLptRequest(
);
PREQUEST_HEADER
MakeComRequest(
);
PREQUEST_HEADER
MakeConRequest(
);
PREQUEST_HEADER
GetRequest(
)
/*++
Routine Description:
Forms a device request based on the command line arguments.
Arguments:
None.
Return Value:
Pointer to the device request.
Notes:
--*/
{
PARRAY ArgArray;
PREQUEST_HEADER Request;
//
// Get strings from resource messages
//
AllocateStuff();
//
// Get array of arguments
//
ArgArray = GetArgumentArray();
DbgPtrAssert( ArgArray);
//
// Parse the arguments
//
ParseArguments( ArgArray );
//
// Verify the arguments and form a request packet
//
Request = MakeRequest();
DbgPtrAssert( Request );
//
// Deallocate resources
//
DELETE( ArgArray );
DeallocateStuff();
return Request;
}
VOID
AllocateStuff(
)
/*++
Routine Description:
Obtains all necessary strings (e.g. argument patterns, switches) from
message.
Arguments:
None.
Return Value:
None
Notes:
--*/
{
//
// Get strings from resource
//
if ( !( ( LptPattern = QueryMessageString( MODE_PATTERN_LPT )) &&
( LptColonPattern = QueryMessageString( MODE_PATTERN_LPTCOLON )) &&
( ComPattern = QueryMessageString( MODE_PATTERN_COM )) &&
( ComColonPattern = QueryMessageString( MODE_PATTERN_COMCOLON )) &&
( ConPattern = QueryMessageString( MODE_PATTERN_CON )) &&
( ConColonPattern = QueryMessageString( MODE_PATTERN_CONCOLON )) &&
( StatusPattern = QueryMessageString( MODE_PATTERN_STATUS )) &&
( ColPattern = QueryMessageString( MODE_PATTERN_COLUMNS )) &&
( LinesPattern = QueryMessageString( MODE_PATTERN_LINES )) &&
( CpPattern = QueryMessageString( MODE_PATTERN_CODEPAGE )) &&
( PreparePattern = QueryMessageString( MODE_PATTERN_PREPARE )) &&
( RetryPattern = QueryMessageString( MODE_PATTERN_RETRY )) &&
( EqualPattern = QueryMessageString( MODE_PATTERN_EQUAL )) &&
( BaudPattern = QueryMessageString( MODE_PATTERN_BAUD )) &&
( ParityPattern = QueryMessageString( MODE_PATTERN_PARITY )) &&
( DataPattern = QueryMessageString( MODE_PATTERN_DATA )) &&
( StopPattern = QueryMessageString( MODE_PATTERN_STOP )) &&
( Stop15Pattern = QueryMessageString( MODE_PATTERN_STOP_15 )) &&
( SelectPattern = QueryMessageString( MODE_PATTERN_SELECT )) &&
( RefreshPattern = QueryMessageString( MODE_PATTERN_REFRESH )) &&
( RatePattern = QueryMessageString( MODE_PATTERN_RATE )) &&
( DelayPattern = QueryMessageString( MODE_PATTERN_DELAY )) &&
( HelpPattern = QueryMessageString( MODE_PATTERN_HELP )) &&
( Switches = QueryMessageString( MODE_SWITCHES )) )) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
//
// Get argument objects. These are not global because the Create
// method would not be called on them.
//
if ( !( ProgramNameArg = NEW PATH_ARGUMENT) ||
!( LptArg = NEW LONG_ARGUMENT) ||
!( LptColonArg = NEW LONG_ARGUMENT) ||
!( ComArg = NEW LONG_ARGUMENT) ||
!( ComColonArg = NEW LONG_ARGUMENT) ||
!( ConArg = NEW FLAG_ARGUMENT) ||
!( ConColonArg = NEW FLAG_ARGUMENT) ||
!( StatusArg = NEW STRING_ARGUMENT) ||
!( ColArg = NEW LONG_ARGUMENT) ||
!( LinesArg = NEW LONG_ARGUMENT) ||
!( CpArg = NEW FLAG_ARGUMENT) ||
!( PrepareArg = NEW STRING_ARGUMENT) ||
!( RetryArg = NEW STRING_ARGUMENT) ||
!( EqualArg = NEW FLAG_ARGUMENT) ||
!( BaudArg = NEW LONG_ARGUMENT) ||
!( ParityArg = NEW STRING_ARGUMENT) ||
!( DataArg = NEW LONG_ARGUMENT) ||
!( StopArg = NEW LONG_ARGUMENT) ||
!( Stop15Arg = NEW FLAG_ARGUMENT) ||
!( SelectArg = NEW LONG_ARGUMENT) ||
!( RefreshArg = NEW FLAG_ARGUMENT) ||
!( RateArg = NEW LONG_ARGUMENT) ||
!( DelayArg = NEW LONG_ARGUMENT) ||
!( HelpArg = NEW FLAG_ARGUMENT) ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
//
// Lexemizer stuff
//
if ( !( ArgLex = NEW ARGUMENT_LEXEMIZER) ||
!( LexArray = NEW ARRAY) ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
}
VOID
DeallocateStuff(
)
/*++
Routine Description:
Deletes all the allocated strings.
Arguments:
None.
Return Value:
None
Notes:
--*/
{
//
// The string from the resource
//
DELETE( LptPattern );
DELETE( LptColonPattern );
DELETE( ComPattern );
DELETE( ComColonPattern );
DELETE( ConPattern );
DELETE( ConColonPattern );
DELETE( StatusPattern );
DELETE( ColPattern );
DELETE( LinesPattern );
DELETE( CpPattern );
DELETE( PreparePattern );
DELETE( RetryPattern );
DELETE( EqualPattern );
DELETE( BaudPattern );
DELETE( ParityPattern );
DELETE( DataPattern );
DELETE( StopPattern );
DELETE( SelectPattern );
DELETE( RefreshPattern );
DELETE( RatePattern );
DELETE( DelayPattern );
DELETE( HelpPattern );
DELETE( Switches );
//
// The arguments
//
DELETE( ProgramNameArg );
DELETE( ProgramNameArg );
DELETE( LptArg );
DELETE( LptColonArg );
DELETE( ComArg );
DELETE( ComColonArg );
DELETE( ConArg );
DELETE( ConColonArg );
DELETE( StatusArg );
DELETE( ColArg );
DELETE( LinesArg );
DELETE( CpArg );
DELETE( PrepareArg );
DELETE( RetryArg );
DELETE( EqualArg );
DELETE( BaudArg );
DELETE( ParityArg );
DELETE( DataArg );
DELETE( StopArg );
DELETE( Stop15Arg );
DELETE( SelectArg );
DELETE( RefreshArg );
DELETE( RateArg );
DELETE( DelayArg );
DELETE( HelpArg );
//
// The lexemizer stuff
//
DELETE( ArgLex );
DELETE( LexArray );
}
PARRAY
GetArgumentArray(
)
/*++
Routine Description:
Initializes all the arguments
Arguments:
None.
Return Value:
None
Notes:
--*/
{
PARRAY ArgArray;
if ( !( ( ArgArray = NEW ARRAY ) &&
( ArgArray->Initialize( 22, 22, 0) ) &&
( ProgramNameArg->Initialize( "*" )) &&
( LptArg->Initialize( LptPattern )) &&
( LptColonArg->Initialize( LptColonPattern )) &&
( ComArg->Initialize( ComPattern )) &&
( ComColonArg->Initialize( ComColonPattern )) &&
( ConArg->Initialize( ConPattern )) &&
( ConColonArg->Initialize( ConColonPattern )) &&
( StatusArg->Initialize( StatusPattern )) &&
( ColArg->Initialize( ColPattern )) &&
( LinesArg->Initialize( LinesPattern )) &&
( CpArg->Initialize( CpPattern )) &&
( PrepareArg->Initialize( PreparePattern )) &&
( RetryArg->Initialize( RetryPattern )) &&
( EqualArg->Initialize( EqualPattern )) &&
( BaudArg->Initialize( BaudPattern )) &&
( ParityArg->Initialize( ParityPattern )) &&
( DataArg->Initialize( DataPattern )) &&
( StopArg->Initialize( StopPattern )) &&
( Stop15Arg->Initialize( Stop15Pattern )) &&
( SelectArg->Initialize( SelectPattern )) &&
( RefreshArg->Initialize( RefreshPattern )) &&
( RateArg->Initialize( RatePattern )) &&
( DelayArg->Initialize( DelayPattern )) &&
( HelpArg->Initialize( HelpPattern )) )) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
if ( !( ( ArgArray->Put( ProgramNameArg ) ) &&
( ArgArray->Put( LptColonArg ) ) &&
( ArgArray->Put( LptArg ) ) &&
( ArgArray->Put( ComColonArg ) ) &&
( ArgArray->Put( ComArg ) ) &&
( ArgArray->Put( ConColonArg ) ) &&
( ArgArray->Put( ConArg ) ) &&
( ArgArray->Put( StatusArg ) ) &&
( ArgArray->Put( ColArg ) ) &&
( ArgArray->Put( LinesArg ) ) &&
( ArgArray->Put( CpArg ) ) &&
( ArgArray->Put( PrepareArg ) ) &&
( ArgArray->Put( RetryArg ) ) &&
( ArgArray->Put( EqualArg ) ) &&
( ArgArray->Put( BaudArg ) ) &&
( ArgArray->Put( ParityArg ) ) &&
( ArgArray->Put( DataArg ) ) &&
( ArgArray->Put( Stop15Arg ) ) &&
( ArgArray->Put( StopArg ) ) &&
( ArgArray->Put( SelectArg ) ) &&
( ArgArray->Put( RefreshArg ) ) &&
( ArgArray->Put( RateArg ) ) &&
( ArgArray->Put( DelayArg ) ) &&
( ArgArray->Put( HelpArg ) ) ) ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
return ArgArray;
}
VOID
ParseArguments(
IN PARRAY ArgArray
)
/*++
Routine Description:
Parses the command line
Arguments:
ArgArray - Supplies pointer to array of arguments
Return Value:
none
Notes:
--*/
{
WSTRING CmdLine;
//
// Initialize the argument lexemizer
//
if ( !( CmdLine.Initialize( GetCommandLine() ) &&
LexArray->Initialize( 8, 8, 0) &&
ArgLex->Initialize( LexArray ) ) ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
//
// Set our parsing preferences
//
ArgLex->PutSeparators( "," );
ArgLex->PutSwitches( Switches );
ArgLex->SetCaseSensitive( FALSE );
//
// Parse the arguments
//
if ( !(ArgLex->PrepareToParse( &CmdLine ))) {
DisplayMessageAndExit( MODE_ERROR_PARSE,
NULL,
EXIT_ERROR );
}
if ( !ArgLex->DoParsing( ArgArray ) ) {
DisplayMessageAndExit( MODE_ERROR_INVALID_PARAMETER,
ArgLex->QueryInvalidArgument(),
EXIT_ERROR );
}
}
PREQUEST_HEADER
MakeRequest(
)
/*++
Routine Description:
Verifies the parameters and forms a device request.
Arguments:
None.
Return Value:
Pointer to the device request.
Notes:
--*/
{
//
// See if Help requested
//
// MODE [/?]
//
if ( HelpArg->QueryFlag() ) {
DisplayMessageAndExit( MODE_MESSAGE_HELP, NULL, EXIT_ERROR );
}
//
// We cannot have LPT1 and LPT1: at the same time
//
if ( ( LptArg->IsValueSet() && LptColonArg->IsValueSet() ) ||
( ComArg->IsValueSet() && ComColonArg->IsValueSet() ) ||
( ConArg->IsValueSet() && ConColonArg->IsValueSet() ) ) {
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
//
// Set the global device info. so we don't have to query the
// arguments all the time.
//
if ( LptArg->IsValueSet() ) {
LptSet = TRUE;
LptNumber = (ULONG)LptArg->QueryLong();
}
if ( LptColonArg->IsValueSet() ) {
LptSet = TRUE;
LptNumber = (ULONG)LptColonArg->QueryLong();
}
if ( ComArg->IsValueSet() ) {
ComSet = TRUE;
ComNumber = (ULONG)ComArg->QueryLong();
}
if ( ComColonArg->IsValueSet() ) {
ComSet = TRUE;
ComNumber = (ULONG)ComColonArg->QueryLong();
}
ConSet = (BOOLEAN)(ConArg->IsValueSet() || ConColonArg->IsValueSet());
//
// See if codepage stuff requested
//
// MODE device CP [/STATUS]
// MODE device CP PREPARE=string
// MODE device CP REFRESH
// MODE device CP SELECT=codepage
//
if ( CpArg->QueryFlag() ) {
return MakeCodePageRequest();
}
//
// See if Status requested
//
// MODE [device] [/STATUS]
//
if ( ( ArgLex->QueryConsumedCount() == 1 ) || StatusArg->IsValueSet() ) {
return MakeStatusRequest();
}
//
// See if LPT request
//
// MODE LPTn[:] [COLS=c] [LINES=l] [RETRY=r]
// MODE LPTn[:] = COMm[:]
//
if ( LptSet ) {
return MakeLptRequest();
}
//
// See if COM request
//
// MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s] [RETRY=r]
//
if ( ComSet ) {
return MakeComRequest();
}
//
// See if CON request
//
// MODE CON[:] [COLS=c] [LINES=l]
//
// MODE CON[:] [RATE=r DELAY=d]
//
if ( ConSet ) {
return MakeConRequest();
}
//
// The request is incorrect
//
DisplayMessageAndExit( MODE_ERROR_INVALID_PARAMETER,
(PWSTRING)(LexArray->GetAt( 1 )),
EXIT_ERROR );
//
// To keep the compiler happy
//
return NULL;
}
PREQUEST_HEADER
MakeStatusRequest(
)
/*++
Routine Description:
Verifies the parameters and forms a status request.
Arguments:
None.
Return Value:
Pointer to the device request.
Notes:
--*/
{
PREQUEST_HEADER Request;
//
// The maximum number of parameters is 3:
//
// MODE [device] /STATUS
//
if ( ArgLex->QueryConsumedCount() > 3 ) {
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
//
// Allocate the request header
//
Request = (PREQUEST_HEADER)MALLOC( sizeof( REQUEST_HEADER ) );
DbgPtrAssert( Request );
if ( !Request ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
//
// Now initialzie the request according to the device type
//
Request->RequestType = REQUEST_TYPE_STATUS;
if ( LptSet ) {
//
// LPT Status request
//
Request->DeviceType = DEVICE_TYPE_LPT;
Request->DeviceNumber = LptNumber;
} else if ( ComSet ) {
//
// COM Status request
//
Request->DeviceType = DEVICE_TYPE_COM;
Request->DeviceNumber = ComNumber;
} else if ( ConSet ) {
//
// CON Status request
//
Request->DeviceType = DEVICE_TYPE_CON;
Request->DeviceNumber = 0;
} else {
//
// Everybody's status request
//
Request->DeviceType = DEVICE_TYPE_ALL;
Request->DeviceNumber = ALL_DEVICES;
}
return Request;
}
PREQUEST_HEADER
MakeCodePageRequest(
)
/*++
Routine Description:
Verifies the parameters and forms a codepage request.
Arguments:
None.
Return Value:
Pointer to the device request.
Notes:
--*/
{
PREQUEST_HEADER Request;
PCON_REQUEST ConRequest;
//
// Only CON accepts codepage requests.
//
if ( LptSet || ComSet ) {
DisplayMessageAndExit( MODE_ERROR_CODEPAGE_OPERATION_NOT_SUPPORTED,
NULL,
EXIT_ERROR );
}
if ( !ConSet ) {
DisplayMessageAndExit( MODE_ERROR_INVALID_PARAMETER,
(PWSTRING)(LexArray->GetAt( 1 )),
EXIT_ERROR );
}
//
// Form the request depending on the Codepage option
//
if ( RefreshArg->IsValueSet() || PrepareArg->IsValueSet() ) {
//
// REFRESH - This is a NO-OP
// PREPARE - This is a NO-OP
//
if ( ArgLex->QueryConsumedCount() != 4 ) {
//
// Must have 4 arguments:
//
// MODE CON: CP REFRESH
//
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
Request = (PREQUEST_HEADER)MALLOC( sizeof( REQUEST_HEADER) );
DbgPtrAssert( Request );
if ( !Request ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request->RequestType = REQUEST_TYPE_NULL;
Request->DeviceType = DEVICE_TYPE_ALL;
} else if ( SelectArg->IsValueSet() ) {
//
// SELECT
//
if ( ArgLex->QueryConsumedCount() != 4 ) {
//
// Must have 4 arguments:
//
// MODE CON: CP Select=codepage
//
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
ConRequest = (PCON_REQUEST)MALLOC( sizeof( CON_REQUEST ) );
DbgPtrAssert( ConRequest );
if ( !ConRequest ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request = &(ConRequest->Header);
Request->RequestType = REQUEST_TYPE_CODEPAGE_SELECT;
Request->DeviceType = DEVICE_TYPE_CON;
Request->DeviceNumber = 0;
ConRequest->Data.CpSelect.Codepage = (ULONG)SelectArg->QueryLong();
} else {
//
// STATUS
//
if ( ArgLex->QueryConsumedCount() != (ULONG)(StatusArg->IsValueSet() ? 4 : 3) ) {
// Must have 3 or 4 arguments:
//
// MODE CON: CP [ /STATUS]
//
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
Request = (PREQUEST_HEADER)MALLOC( sizeof( REQUEST_HEADER) );
DbgPtrAssert( Request );
if ( !Request ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request->RequestType = REQUEST_TYPE_CODEPAGE_STATUS;
Request->DeviceType = DEVICE_TYPE_CON;
Request->DeviceNumber = 0;
}
return Request;
}
PREQUEST_HEADER
MakeLptRequest(
)
/*++
Routine Description:
Verifies the parameters and forms an LPT request.
Arguments:
None.
Return Value:
Pointer to the device request.
Notes:
--*/
{
PREQUEST_HEADER Request;
PLPT_REQUEST LptRequest;
ULONG ArgCnt;
//
// Form the request depending on the argument line
//
if ( ArgLex->QueryConsumedCount() == 2 ) {
//
// STATUS
//
Request = (PREQUEST_HEADER)MALLOC( sizeof( REQUEST_HEADER) );
DbgPtrAssert( Request );
if ( !Request ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request->RequestType = REQUEST_TYPE_STATUS;
Request->DeviceType = DEVICE_TYPE_LPT;
Request->DeviceNumber = LptNumber;
} else if ( EqualArg->IsValueSet() ) {
//
// REDIRECTION
//
// MODE LPTn[:] = COMm[:]
if ( ArgLex->QueryConsumedCount() != 4 ) {
//
// Must have 4 arguments:
//
// MODE LPT1 = COM1
//
// BUGBUG What happens line is "LPT1=COM1" ?
//
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
//
// Can only redirect to COM
//
if ( !ComSet ) {
DisplayMessageAndExit( MODE_ERROR_INVALID_PARAMETER,
(PWSTRING)(LexArray->GetAt( 1 )),
EXIT_ERROR );
}
LptRequest = (PLPT_REQUEST)MALLOC( sizeof( LPT_REQUEST ) );
DbgPtrAssert( LptRequest );
if ( !LptRequest ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request = &(LptRequest->Header);
Request->RequestType = REQUEST_TYPE_LPT_REDIRECT;
Request->DeviceType = DEVICE_TYPE_LPT;
Request->DeviceNumber = LptNumber;
LptRequest->Data.Redirect.DeviceType = DEVICE_TYPE_COM;
LptRequest->Data.Redirect.DeviceNumber = ComNumber;
} else if ( (ArgCnt = ( ColArg->IsValueSet() ? 1 : 0 ) +
( LinesArg->IsValueSet() ? 1 : 0 ) +
( RetryArg->IsValueSet() ? 1 : 0 )) > 0 ) {
//
// SET Lines & Columns
//
if ( ArgLex->QueryConsumedCount() > (ULONG)(2 + ArgCnt) ) {
//
// Must have 2 + ArgCnt arguments:
//
// MODE LPT1: [COLS=c] [LINES=l] [RETRY=r]
//
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
LptRequest = (PLPT_REQUEST)MALLOC( sizeof( LPT_REQUEST ) );
DbgPtrAssert( LptRequest );
if ( !LptRequest ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request = &(LptRequest->Header);
Request->RequestType = REQUEST_TYPE_LPT_SETUP;
Request->DeviceType = DEVICE_TYPE_LPT;
Request->DeviceNumber = LptNumber;
LptRequest->Data.Setup.SetCol = FALSE;
LptRequest->Data.Setup.SetLines = FALSE;
LptRequest->Data.Setup.SetRetry = FALSE;
if ( ColArg->IsValueSet() ) {
LptRequest->Data.Setup.SetCol = TRUE;
LptRequest->Data.Setup.Col = ColArg->QueryLong();
}
if ( LinesArg->IsValueSet() ) {
LptRequest->Data.Setup.SetLines = TRUE;
LptRequest->Data.Setup.Lines = LinesArg->QueryLong();
}
if ( RetryArg->IsValueSet() ) {
LptRequest->Data.Setup.SetRetry = TRUE;
LptRequest->Data.Setup.Retry = 0;
}
} else {
//
// Invalid request
//
DisplayMessageAndExit( MODE_ERROR_INVALID_PARAMETER,
(PWSTRING)(LexArray->GetAt( 1 )),
EXIT_ERROR );
}
return Request;
}
PREQUEST_HEADER
MakeComRequest(
)
/*++
Routine Description:
Verifies the parameters and forms a COM request.
Arguments:
None.
Return Value:
Pointer to the device request.
Notes:
--*/
{
PREQUEST_HEADER Request;
PCOM_REQUEST ComRequest;
ULONG ArgCnt;
if ( ArgLex->QueryConsumedCount() == 2 ) {
//
// Status request
//
Request = (PREQUEST_HEADER)MALLOC( sizeof( REQUEST_HEADER ) );
DbgPtrAssert( Request );
if ( !Request ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request->RequestType = REQUEST_TYPE_STATUS;
Request->DeviceType = DEVICE_TYPE_COM;
Request->DeviceNumber = ComNumber;
} else if ( (ArgCnt = ( BaudArg->IsValueSet() ? 1 : 0 ) +
( ParityArg->IsValueSet() ? 1 : 0 ) +
( DataArg->IsValueSet() ? 1 : 0 ) +
( Stop15Arg->IsValueSet() ? 1 : 0 ) +
( StopArg->IsValueSet() ? 1 : 0 ) +
( RetryArg->IsValueSet() ? 1 : 0 )) > 0 ) {
//
// Set COM Configuration
//
if ( ArgLex->QueryConsumedCount() > (ULONG)(2 + ArgCnt) ) {
//
// Must have 2 + ArgCnt arguments:
//
// MODE COM1: [ all options ]
//
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
ComRequest = (PCOM_REQUEST)MALLOC( sizeof( COM_REQUEST ) );
DbgPtrAssert( ComRequest );
if ( !ComRequest ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request = &(ComRequest->Header);
Request->RequestType = REQUEST_TYPE_COM_SET;
Request->DeviceType = DEVICE_TYPE_COM;
Request->DeviceNumber = ComNumber;
ComRequest->Data.Set.SetBaud = FALSE;
ComRequest->Data.Set.SetDataBits = FALSE;
ComRequest->Data.Set.SetStopBits = FALSE;
ComRequest->Data.Set.SetParity = FALSE;
ComRequest->Data.Set.SetRetry = FALSE;
if ( BaudArg->IsValueSet() ) {
ComRequest->Data.Set.SetBaud = TRUE;
ComRequest->Data.Set.Baud = ConvertBaudRate( BaudArg->QueryLong(), ArgLex->GetLexemeAt( BaudArg->GetLexemeIndex()) );
}
if ( DataArg->IsValueSet() ) {
ComRequest->Data.Set.SetDataBits = TRUE;
ComRequest->Data.Set.DataBits = ConvertDataBits( DataArg->QueryLong(), ArgLex->GetLexemeAt( DataArg->GetLexemeIndex()) );
}
if ( Stop15Arg->IsValueSet() ) {
ComRequest->Data.Set.SetStopBits = TRUE;
ComRequest->Data.Set.StopBits = STOPBITS_15;
} else if ( StopArg->IsValueSet() ) {
ComRequest->Data.Set.SetStopBits = TRUE;
ComRequest->Data.Set.StopBits = ConvertStopBits( StopArg->QueryLong(), ArgLex->GetLexemeAt( StopArg->GetLexemeIndex()) );
}
if ( ParityArg->IsValueSet() ) {
ComRequest->Data.Set.SetParity = TRUE;
ComRequest->Data.Set.Parity = ConvertParity( ParityArg->GetString(), ArgLex->GetLexemeAt( ParityArg->GetLexemeIndex()) );
}
if ( RetryArg->IsValueSet() ) {
ComRequest->Data.Set.SetRetry = TRUE;
ComRequest->Data.Set.Retry = ConvertRetry( RetryArg->GetString(), ArgLex->GetLexemeAt( RetryArg->GetLexemeIndex()) );
}
} else {
//
// Invalid request
//
DisplayMessageAndExit( MODE_ERROR_INVALID_PARAMETER,
(PWSTRING)(LexArray->GetAt( 1 )),
EXIT_ERROR );
}
return Request;
}
PREQUEST_HEADER
MakeConRequest(
)
/*++
Routine Description:
Verifies the parameters and forms a CON request.
Arguments:
None.
Return Value:
Pointer to the device request.
Notes:
--*/
{
PREQUEST_HEADER Request;
PCON_REQUEST ConRequest;
ULONG ArgCnt;
if ( ArgLex->QueryConsumedCount() == 2 ) {
//
// Status request
//
Request = (PREQUEST_HEADER)MALLOC( sizeof( REQUEST_HEADER ) );
DbgPtrAssert( Request );
if ( !Request ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request->RequestType = REQUEST_TYPE_STATUS;
Request->DeviceType = DEVICE_TYPE_CON;
Request->DeviceNumber = 0;
} else if ( (ArgCnt = ( ColArg->IsValueSet() ? 1 : 0 ) +
( LinesArg->IsValueSet() ? 1 : 0 )) > 0 ) {
//
// Set Lines and Columns
//
if ( ArgLex->QueryConsumedCount() > (ULONG)(2 + ArgCnt) ) {
//
// Must have 2 + ArgCnt arguments:
//
// MODE CON: [COLS=c] [ LINES=l]
//
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
ConRequest = (PCON_REQUEST)MALLOC( sizeof( CON_REQUEST ) );
DbgPtrAssert( ConRequest );
if ( !ConRequest ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request = &(ConRequest->Header);
Request->RequestType = REQUEST_TYPE_CON_SET_ROWCOL;
Request->DeviceType = DEVICE_TYPE_CON;
Request->DeviceNumber = 0;
ConRequest->Data.RowCol.SetCol = FALSE;
ConRequest->Data.RowCol.SetLines = FALSE;
if ( ColArg->IsValueSet() ) {
ConRequest->Data.RowCol.SetCol = TRUE;
ConRequest->Data.RowCol.Col = ColArg->QueryLong();
}
if ( LinesArg->IsValueSet() ) {
ConRequest->Data.RowCol.SetLines = TRUE;
ConRequest->Data.RowCol.Lines = LinesArg->QueryLong();
}
} else if ( (ArgCnt = ( RateArg->IsValueSet() ? 1 : 0 ) +
( DelayArg->IsValueSet() ? 1 : 0 )) > 0 ) {
//
// Set Typematic rate
//
if ( ArgLex->QueryConsumedCount() > (ULONG)(2 + ArgCnt) ) {
//
// Must have 2 + ArgCnt arguments:
//
// MODE CON: [RATE=r] [DELAY=d]
//
DisplayMessageAndExit( MODE_ERROR_INVALID_NUMBER_OF_PARAMETERS,
NULL,
EXIT_ERROR );
}
ConRequest = (PCON_REQUEST)MALLOC( sizeof( CON_REQUEST ) );
DbgPtrAssert( ConRequest );
if ( !ConRequest ) {
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY,
NULL,
EXIT_ERROR );
}
Request = &(ConRequest->Header);
Request->RequestType = REQUEST_TYPE_CON_SET_TYPEMATIC;
Request->DeviceType = DEVICE_TYPE_CON;
Request->DeviceNumber = 0;
ConRequest->Data.Typematic.SetRate = FALSE;
ConRequest->Data.Typematic.SetDelay = FALSE;
if ( RateArg->IsValueSet() ) {
ConRequest->Data.Typematic.SetRate = TRUE;
ConRequest->Data.Typematic.Rate = RateArg->QueryLong();
}
if ( DelayArg->IsValueSet() ) {
ConRequest->Data.Typematic.SetDelay = TRUE;
ConRequest->Data.Typematic.Delay = DelayArg->QueryLong();
}
} else {
//
// Invalid request
//
DisplayMessageAndExit( MODE_ERROR_INVALID_PARAMETER,
(PWSTRING)(LexArray->GetAt( 1 )),
EXIT_ERROR );
}
return Request;
}
PREQUEST_HEADER
MakeRequest(
)
/*++
Routine Description:
Makes a request and initializes its header
Arguments:
None.
Return Value:
Pointer to the device request.
Notes:
--*/
{