mirror of https://github.com/tongzx/nt5src
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
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:
|
|
|
|
--*/
|
|
|
|
{
|