windows-nt/Source/XPSP1/NT/base/fs/utils/mode/argument.old
2020-09-26 16:20:57 +08:00

1519 lines
28 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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:
--*/
{