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.
1386 lines
44 KiB
1386 lines
44 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Choice.c
|
|
|
|
Abstract:
|
|
|
|
Choice is a Win32 console application designed to duplicate
|
|
the functionality of the choice.com utility found in MSDOS version
|
|
6.0. Rather than simply using the C run-time routines, choice
|
|
utilizes Win32 console routines and the signalling abilities of the
|
|
file objects.
|
|
|
|
Author:
|
|
Wipro Technologies 2-July.-2001 (Created it)
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#include "pch.h"
|
|
#include "choice.h"
|
|
|
|
DWORD
|
|
__cdecl wmain(
|
|
IN DWORD argc,
|
|
IN LPCWSTR argv[] )
|
|
/*++
|
|
|
|
Routine description : Main function which calls all the other main functions
|
|
depending on the option specified by the user.
|
|
|
|
Arguments:
|
|
[in] argc : argument count specified at the command prompt.
|
|
[in] argv : arguments specified at the command prompt.
|
|
|
|
Return Value : DWORD
|
|
0 : If the utility successfully performs the operation.
|
|
1 : If the utility is unsuccessful in performing the specified
|
|
operation.
|
|
--*/
|
|
{
|
|
|
|
|
|
TCMDPARSER2 cmdOptions[ MAX_COMMANDLINE_OPTION ]; //command line options
|
|
|
|
WCHAR szChoice[MAX_STRING_LENGTH] ; // to store options for /c
|
|
WCHAR szMessage[256] ; // Message to be shown for
|
|
WCHAR szPromptStr[512] ;//Message finaly prompted
|
|
WCHAR szDefaultChoice[256] ; //default choice string
|
|
WCHAR wszBuffer[2*MAX_RES_STRING] ;
|
|
|
|
|
|
BOOL bShowChoice = FALSE;//choice to be shown or not
|
|
BOOL bCaseSensitive = FALSE; // choice will be case sensitive or not
|
|
BOOL bUsage = FALSE; // is help required
|
|
LONG lTimeoutFactor = 0; //Time out factor
|
|
BOOL bReturn = FALSE; // Stores the return value
|
|
DWORD lReturnValue = EXIT__FAILURE; // Return value of application
|
|
BOOL bErrorOnCarriageReturn = FALSE;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
SecureZeroMemory(szChoice, MAX_STRING_LENGTH * sizeof(WCHAR));
|
|
SecureZeroMemory(szMessage, 256 * sizeof(WCHAR));
|
|
SecureZeroMemory(szPromptStr, 512 * sizeof(WCHAR));
|
|
SecureZeroMemory(szDefaultChoice, 256 * sizeof(WCHAR));
|
|
SecureZeroMemory(wszBuffer, (2*MAX_RES_STRING) * sizeof(WCHAR));
|
|
|
|
|
|
bReturn = ProcessCMDLine( argc,
|
|
argv,
|
|
&cmdOptions[ 0 ], // Command line struct
|
|
&bUsage, // Is help
|
|
szChoice, // Choice
|
|
&bCaseSensitive, // Casesensitive
|
|
&bShowChoice, // Show Choice
|
|
&lTimeoutFactor, // Timeout factor
|
|
szDefaultChoice, // Timeout choice
|
|
szMessage // Message
|
|
);
|
|
|
|
if( FALSE == bReturn)
|
|
{
|
|
// Show Error message on screen depending on Reason Set
|
|
|
|
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
|
|
|
|
|
|
// Release all global memory allocation. This allocation are done
|
|
// by common functionality.
|
|
ReleaseGlobals();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
if ( TRUE == bUsage)
|
|
{
|
|
ShowUsage(); // Display Usage
|
|
// Release all global memory allocation. This allocation are done
|
|
// by common functionality.
|
|
ReleaseGlobals();
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
// Check if timeout factor is 0
|
|
|
|
|
|
bReturn = BuildPrompt( cmdOptions,
|
|
bShowChoice,
|
|
szChoice,
|
|
szMessage,
|
|
szPromptStr); // Show message on Prompt.
|
|
if (FALSE == bReturn)
|
|
{
|
|
// Release all global memory allocation. This allocation are done
|
|
// by common functionality.
|
|
ReleaseGlobals();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
if((cmdOptions[ ID_TIMEOUT_FACTOR ].dwActuals > 0) &&
|
|
( 0 == lTimeoutFactor ))
|
|
{
|
|
// Release all global memory allocation. This allocation are done
|
|
// by common functionality.
|
|
|
|
// Safely return from utility
|
|
|
|
SecureZeroMemory(wszBuffer, 2*MAX_STRING_LENGTH);
|
|
|
|
hr = StringCchPrintf(wszBuffer, SIZE_OF_ARRAY(wszBuffer), L"%s%s\n", _X(szPromptStr), _X2(szDefaultChoice));
|
|
if(FAILED(hr))
|
|
{
|
|
SetLastError(HRESULT_CODE(hr));
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
ShowMessage(stdout,wszBuffer);
|
|
|
|
ReleaseGlobals();
|
|
return UniStrChr( szChoice, szDefaultChoice[0] );
|
|
|
|
}
|
|
|
|
// Now wait for input OR expire of timeout
|
|
lReturnValue = GetChoice( szPromptStr,
|
|
lTimeoutFactor,
|
|
bCaseSensitive,
|
|
szChoice,
|
|
szDefaultChoice,
|
|
&bErrorOnCarriageReturn);
|
|
|
|
if(EXIT__FAILURE == lReturnValue)
|
|
{
|
|
if(bErrorOnCarriageReturn == FALSE)
|
|
{
|
|
// Show Error message on screen depending on Reason Set
|
|
|
|
StringCopyW( szPromptStr, GetReason(), 2*MAX_STRING_LENGTH );
|
|
|
|
|
|
if(StringLengthW(szPromptStr, 0) == 0)
|
|
{
|
|
ShowMessage(stderr, szPromptStr);
|
|
ShowMessage(stderr, GetResString(IDS_FILE_EMPTY));
|
|
|
|
}
|
|
else
|
|
{
|
|
hr = StringCchPrintf(szPromptStr, SIZE_OF_ARRAY(szPromptStr), L"\n%s %s", TAG_ERROR, GetReason());
|
|
if(FAILED(hr))
|
|
{
|
|
SetLastError(HRESULT_CODE(hr));
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
ShowMessage(stderr, szPromptStr);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
ShowMessage(stderr, GetReason());
|
|
}
|
|
// Release all global memory allocation. This allocation are done
|
|
// by common functionality.
|
|
ReleaseGlobals();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
|
|
// Release all global memory allocation. This allocation are done
|
|
// by common functionality.
|
|
ReleaseGlobals();
|
|
return lReturnValue;
|
|
}
|
|
// End of function wmain
|
|
|
|
BOOL
|
|
ProcessCMDLine(
|
|
IN DWORD argc,
|
|
IN LPCWSTR argv[],
|
|
OUT TCMDPARSER2 *pcmdParcerHead,
|
|
OUT PBOOL pbUsage,
|
|
OUT LPWSTR pszChoice,
|
|
OUT PBOOL pbCaseSensitive,
|
|
OUT PBOOL pbShowChoice,
|
|
OUT PLONG plTimeOutFactor,
|
|
OUT LPWSTR pszDefaultChoice,
|
|
OUT LPWSTR pszMessage)
|
|
/*++
|
|
Routine Description:
|
|
This function will prepare column structure for DoParseParam Function.
|
|
|
|
Arguments:
|
|
IN argc : Command line argument count
|
|
IN argv : Command line argument
|
|
OUT pcmdParcerHead : Pointer to Command line parcer structure
|
|
OUT pbUsage : Stores the status if help required
|
|
OUT pszChoice : Stores choices given
|
|
OUT pbCaseSensitive : Stores the status if choices are case-sensitive
|
|
OUT pbShowChoice : Stores the status if choices to be shown
|
|
OUT plTimeOutFactor : Stores time out factor
|
|
OUT pszDefaultChoice : Stores default choices
|
|
OUT pszMessage : Stores message string
|
|
Return Value:
|
|
TRUE : Return successfully
|
|
FALSE: Return due to error
|
|
--*/
|
|
{
|
|
BOOL bReturn = FALSE;// strore return value
|
|
|
|
WCHAR szErrorMsg[64] ;
|
|
WCHAR szCharac[2] ;
|
|
WCHAR szTemp[128] ;
|
|
WCHAR szTimeFactor[MAX_STRING_LENGTH] ;
|
|
TCMDPARSER2* pcmdParcer = NULL;
|
|
TCMDPARSER2* pcmdTmp = NULL;
|
|
DWORD dw =0;
|
|
DWORD dwVal =0;
|
|
DWORD dwcount = 0;
|
|
DWORD dwLen = 0;
|
|
|
|
WCHAR* pszStopTimeFactor = NULL;
|
|
HRESULT hr;
|
|
|
|
const WCHAR* wszOptionHelp = L"?"; //OPTION_HELP
|
|
const WCHAR* wszOptionChoice = L"C" ; //OPTION_CHOICE
|
|
const WCHAR* wszOptionPromptChoice = L"N" ; //OPTION_PROMPT_CHOICE
|
|
const WCHAR* wszOptionCaseSensitive = L"CS" ; //OPTION_CASE_SENSITIVE
|
|
const WCHAR* wszOptionDefaultChoice = L"D" ; //wszOptionDefaultChoice
|
|
const WCHAR* wszOptionTimeoutFactor = L"T" ; //OPTION_TIMEOUT_FACTOR
|
|
const WCHAR* wszOptionDefaultString = L"M" ; //OPTION_DEFAULT_STRING
|
|
|
|
SecureZeroMemory(szErrorMsg, 64 * sizeof(WCHAR));
|
|
SecureZeroMemory(szCharac, 2 * sizeof(WCHAR));
|
|
SecureZeroMemory(szTemp, 128 * sizeof(WCHAR));
|
|
SecureZeroMemory(szTimeFactor, MAX_STRING_LENGTH * sizeof(WCHAR));
|
|
|
|
|
|
// Check validity of Pointer
|
|
if( (NULL == pcmdParcerHead) ||
|
|
(NULL == pbUsage) ||
|
|
(NULL == pszChoice) ||
|
|
(NULL == pbCaseSensitive) ||
|
|
(NULL == pbShowChoice) ||
|
|
(NULL == plTimeOutFactor) ||
|
|
(NULL == pszDefaultChoice) ||
|
|
(NULL == pszMessage))
|
|
{
|
|
SetLastError( RPC_X_NULL_REF_POINTER );
|
|
SaveLastError();
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
// Filling m_cmdOptions structure
|
|
// -?
|
|
|
|
pcmdParcer = pcmdParcerHead + ID_HELP;
|
|
|
|
StringCopyA( pcmdParcer->szSignature, "PARSER2\0", 8 );
|
|
|
|
pcmdParcer-> dwType = CP_TYPE_BOOLEAN;
|
|
|
|
pcmdParcer-> pwszOptions = wszOptionHelp;
|
|
pcmdParcer-> pwszFriendlyName = NULL;
|
|
pcmdParcer-> pwszValues = NULL;
|
|
|
|
pcmdParcer->dwFlags = CP2_USAGE;
|
|
pcmdParcer->dwCount = 1;
|
|
pcmdParcer->dwActuals = 0;
|
|
pcmdParcer->pValue = pbUsage;
|
|
pcmdParcer->dwLength = MAX_STRING_LENGTH;
|
|
|
|
pcmdParcer-> pFunction = NULL;
|
|
pcmdParcer-> pFunctionData = NULL;
|
|
pcmdParcer-> dwReserved = 0;
|
|
pcmdParcer-> pReserved1 = NULL;
|
|
pcmdParcer-> pReserved2 = NULL;
|
|
pcmdParcer-> pReserved3 = NULL;
|
|
|
|
|
|
// -c choices
|
|
pcmdParcer = pcmdParcerHead + ID_CHOICE;
|
|
|
|
StringCopyA( pcmdParcer-> szSignature, "PARSER2\0", 8 );
|
|
|
|
pcmdParcer-> dwType = CP_TYPE_TEXT;
|
|
|
|
pcmdParcer-> pwszOptions = wszOptionChoice;
|
|
pcmdParcer-> pwszFriendlyName = NULL;
|
|
pcmdParcer-> pwszValues = NULL;
|
|
pcmdParcer->dwFlags = 0;
|
|
pcmdParcer->dwCount = 1;
|
|
pcmdParcer->dwActuals = 0;
|
|
pcmdParcer->pValue = pszChoice;
|
|
pcmdParcer->dwLength = MAX_STRING_LENGTH;
|
|
pcmdParcer->pFunction = NULL;
|
|
pcmdParcer->pFunctionData = NULL;
|
|
pcmdParcer-> dwReserved = 0;
|
|
pcmdParcer-> pReserved1 = NULL;
|
|
pcmdParcer-> pReserved2 = NULL;
|
|
pcmdParcer-> pReserved3 = NULL;
|
|
|
|
|
|
//-n Show choice
|
|
pcmdParcer = pcmdParcerHead + ID_PROMPT_CHOICE;
|
|
|
|
StringCopyA( pcmdParcer-> szSignature, "PARSER2\0", 8 );
|
|
|
|
pcmdParcer-> dwType = CP_TYPE_BOOLEAN;
|
|
|
|
pcmdParcer-> pwszOptions = wszOptionPromptChoice;
|
|
pcmdParcer-> pwszFriendlyName = NULL;
|
|
pcmdParcer-> pwszValues = NULL;
|
|
pcmdParcer->dwFlags = 0;
|
|
pcmdParcer->dwCount = 1;
|
|
pcmdParcer->dwActuals = 0;
|
|
pcmdParcer->pValue = pbShowChoice;
|
|
pcmdParcer->dwLength = MAX_STRING_LENGTH;
|
|
|
|
pcmdParcer->pFunction = NULL;
|
|
pcmdParcer->pFunctionData = NULL;
|
|
pcmdParcer-> dwReserved = 0;
|
|
pcmdParcer-> pReserved1 = NULL;
|
|
pcmdParcer-> pReserved2 = NULL;
|
|
pcmdParcer-> pReserved3 = NULL;
|
|
|
|
|
|
// -cs case sensitive
|
|
pcmdParcer = pcmdParcerHead + ID_CASE_SENSITIVE;
|
|
|
|
StringCopyA( pcmdParcer-> szSignature, "PARSER2\0", 8 );
|
|
|
|
pcmdParcer-> dwType = CP_TYPE_BOOLEAN;
|
|
|
|
pcmdParcer-> pwszOptions = wszOptionCaseSensitive;
|
|
pcmdParcer-> pwszFriendlyName = NULL;
|
|
pcmdParcer-> pwszValues = NULL;
|
|
pcmdParcer->dwFlags = 0;
|
|
pcmdParcer->dwCount = 1;
|
|
pcmdParcer->dwActuals = 0;
|
|
pcmdParcer->pValue = pbCaseSensitive;
|
|
pcmdParcer->dwLength = MAX_STRING_LENGTH;
|
|
|
|
pcmdParcer->pFunction = NULL;
|
|
pcmdParcer->pFunctionData = NULL;
|
|
pcmdParcer-> dwReserved = 0;
|
|
pcmdParcer-> pReserved1 = NULL;
|
|
pcmdParcer-> pReserved2 = NULL;
|
|
pcmdParcer-> pReserved3 = NULL;
|
|
|
|
|
|
|
|
// -d default choice
|
|
pcmdParcer = pcmdParcerHead + ID_DEFAULT_CHOICE;
|
|
|
|
StringCopyA( pcmdParcer-> szSignature, "PARSER2\0", 8 );
|
|
|
|
pcmdParcer-> dwType = CP_TYPE_TEXT;
|
|
|
|
pcmdParcer-> pwszOptions = wszOptionDefaultChoice;
|
|
pcmdParcer-> pwszFriendlyName = NULL;
|
|
pcmdParcer-> pwszValues = NULL;
|
|
pcmdParcer->dwFlags = CP2_VALUE_TRIMINPUT;
|
|
pcmdParcer->dwCount = 1;
|
|
pcmdParcer->dwActuals = 0;
|
|
pcmdParcer->pValue = pszDefaultChoice;
|
|
pcmdParcer->dwLength = MAX_STRING_LENGTH;
|
|
|
|
pcmdParcer->pFunction = NULL;
|
|
pcmdParcer->pFunctionData = NULL;
|
|
pcmdParcer-> dwReserved = 0;
|
|
pcmdParcer-> pReserved1 = NULL;
|
|
pcmdParcer-> pReserved2 = NULL;
|
|
pcmdParcer-> pReserved3 = NULL;
|
|
|
|
|
|
// -t time-out factor
|
|
pcmdParcer = pcmdParcerHead + ID_TIMEOUT_FACTOR;
|
|
|
|
StringCopyA( pcmdParcer-> szSignature, "PARSER2\0", 8 );
|
|
|
|
pcmdParcer-> dwType = CP_TYPE_TEXT;
|
|
|
|
pcmdParcer-> pwszOptions = wszOptionTimeoutFactor;
|
|
pcmdParcer-> pwszFriendlyName = NULL;
|
|
pcmdParcer-> pwszValues = NULL;
|
|
pcmdParcer->dwFlags = CP2_VALUE_TRIMINPUT;
|
|
pcmdParcer->dwCount = 1;
|
|
pcmdParcer->dwActuals = 0;
|
|
pcmdParcer->pValue = szTimeFactor;
|
|
pcmdParcer->dwLength = MAX_STRING_LENGTH;
|
|
|
|
pcmdParcer->pFunction = NULL;
|
|
pcmdParcer->pFunctionData = NULL;
|
|
pcmdParcer-> dwReserved = 0;
|
|
pcmdParcer-> pReserved1 = NULL;
|
|
pcmdParcer-> pReserved2 = NULL;
|
|
pcmdParcer-> pReserved3 = NULL;
|
|
|
|
|
|
|
|
// -m message text
|
|
pcmdParcer = pcmdParcerHead + ID_MESSAGE_STRING;
|
|
|
|
StringCopyA( pcmdParcer-> szSignature, "PARSER2\0", 8 );
|
|
|
|
pcmdParcer-> dwType = CP_TYPE_TEXT;
|
|
|
|
pcmdParcer-> pwszOptions = wszOptionDefaultString;
|
|
pcmdParcer-> pwszFriendlyName = NULL;
|
|
pcmdParcer-> pwszValues = NULL;
|
|
pcmdParcer->dwFlags = CP2_VALUE_TRIMINPUT;
|
|
pcmdParcer->dwCount = 1;
|
|
pcmdParcer->dwActuals = 0;
|
|
pcmdParcer->pValue = pszMessage;
|
|
pcmdParcer->dwLength = MAX_STRING_LENGTH;
|
|
|
|
pcmdParcer->pFunction = NULL;
|
|
pcmdParcer->pFunctionData = NULL;
|
|
pcmdParcer-> dwReserved = 0;
|
|
pcmdParcer-> pReserved1 = NULL;
|
|
pcmdParcer-> pReserved2 = NULL;
|
|
pcmdParcer-> pReserved3 = NULL;
|
|
|
|
// re-assign it to head position
|
|
pcmdParcer = pcmdParcerHead;
|
|
|
|
bReturn = DoParseParam2( argc, argv, -1, MAX_COMMANDLINE_OPTION, pcmdParcer, 0);
|
|
if( FALSE == bReturn) // Invalid commandline
|
|
{
|
|
// Reason is already set by DoParseParam
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
if( TRUE == *pbUsage )
|
|
{
|
|
if(2 == argc )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
else
|
|
{
|
|
|
|
StringCopyW( szErrorMsg, GetResString( IDS_INCORRECT_SYNTAX ), SIZE_OF_ARRAY(szErrorMsg) );
|
|
|
|
SetReason( szErrorMsg );
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// /d can be specified only if /t is specified.
|
|
pcmdParcer = pcmdParcerHead + ID_DEFAULT_CHOICE;
|
|
pcmdTmp = pcmdParcerHead + ID_TIMEOUT_FACTOR;
|
|
if((pcmdParcer-> dwActuals > 0 ) &&( 0 == pcmdTmp-> dwActuals ))
|
|
{
|
|
// Error String will be ..
|
|
//Invalid syntax. /D can be specified only when /T is
|
|
//specified.
|
|
//Type CHOICE /? for usage.
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_D_WITHOUT_T ), SIZE_OF_ARRAY(szTemp) );
|
|
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
// /f should come if /d is given
|
|
pcmdParcer = pcmdParcerHead + ID_DEFAULT_CHOICE;
|
|
pcmdTmp = pcmdParcerHead + ID_TIMEOUT_FACTOR;
|
|
if(( 0 == pcmdParcer-> dwActuals ) &&( pcmdTmp-> dwActuals > 0 ) )
|
|
{
|
|
// Error String will be ..
|
|
// Invalid syntax. /D missing.
|
|
// Type CHOICE /? for usage.
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_D_MISSING ), SIZE_OF_ARRAY(szTemp) );
|
|
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
// Time factor value should be in range TIMEOUT_MIN - TIMEOUT_MAX
|
|
pcmdParcer = pcmdParcerHead + ID_DEFAULT_CHOICE;
|
|
|
|
if(pcmdParcer-> dwActuals > 0 && szTimeFactor != NULL && StringLengthW(szTimeFactor, 0) == 0)
|
|
{
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_TFACTOR_NULL_STIRNG ), SIZE_OF_ARRAY(szTemp) );
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
*plTimeOutFactor = wcstol(szTimeFactor,&pszStopTimeFactor,10);
|
|
|
|
if((errno == ERANGE) || (NULL != pszStopTimeFactor && StringLengthW(pszStopTimeFactor, 0) != 0))
|
|
{
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_INVALID_TIMEOUT_FACTOR ), SIZE_OF_ARRAY(szTemp) );
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if( pcmdParcer-> dwActuals > 0 &&
|
|
(( *plTimeOutFactor < TIMEOUT_MIN)||
|
|
( *plTimeOutFactor > TIMEOUT_MAX )))
|
|
{
|
|
// Error String will be ..
|
|
// Invalid syntax. Valid range for /t is (0 - 99).
|
|
// Type CHOICE /? for usage.
|
|
|
|
hr = StringCchPrintf(szTemp, SIZE_OF_ARRAY(szTemp), GetResString(IDS_T_INVALID_VALUE),TIMEOUT_MIN,TIMEOUT_MAX);
|
|
if(FAILED(hr))
|
|
{
|
|
SetLastError(HRESULT_CODE(hr));
|
|
SaveLastError();
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
// if /c is specified then it cannot be empty
|
|
pcmdParcer = pcmdParcerHead + ID_CHOICE;
|
|
|
|
|
|
if( pcmdParcer-> dwActuals > 0 && (StringLengthW( pszChoice, 0 ) == 0))
|
|
{
|
|
// Error String will be ..
|
|
// Invalid syntax. Choice cannot be empty.
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_C_EMPTY ), SIZE_OF_ARRAY(szTemp) );
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
if( pcmdParcer-> dwActuals > 0)
|
|
{
|
|
|
|
|
|
dwVal = StringLengthW( pszChoice, 0 );
|
|
|
|
for(dwcount;dwcount < dwVal;dwcount++)
|
|
{
|
|
szCharac[0] = pszChoice[dwcount];
|
|
szCharac[1] = '\0';
|
|
if((dwLen = StringLengthInBytes(szCharac)) > 1)
|
|
{
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_TWO_BYTES_NOTALLOWED ), SIZE_OF_ARRAY(szTemp) );
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
for(dw;dw < dwVal;dw++)
|
|
{
|
|
if( ((DWORD)pszChoice[dw]) <= 47 ||
|
|
(((DWORD)pszChoice[dw]) > 122 &&((DWORD)pszChoice[dw]) < 127)||
|
|
(((DWORD)pszChoice[dw]) > 57 &&((DWORD)pszChoice[dw]) < 65 ) ||
|
|
(((DWORD)pszChoice[dw]) > 90 &&((DWORD)pszChoice[dw]) < 97 ) ||
|
|
((DWORD)pszChoice[dw]) == 160)
|
|
{
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_CHOICE_INVALID ), SIZE_OF_ARRAY(szTemp) );
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// if /c is not specified then make default choice as "YN"
|
|
pcmdParcer = pcmdParcerHead + ID_CHOICE;
|
|
if(0 == pcmdParcer-> dwActuals)
|
|
{
|
|
|
|
StringCopyW( pszChoice, DEFAULT_CHOICE, MAX_STRING_LENGTH);
|
|
}
|
|
|
|
|
|
pcmdParcer = pcmdParcerHead + ID_CHOICE;
|
|
if((pcmdParcer-> dwActuals > 0 ) && ( FALSE == *pbCaseSensitive ))
|
|
{
|
|
dw = 0;
|
|
for(dw;dw < dwVal;dw++)
|
|
{
|
|
if( ((DWORD)pszChoice[dw]) <= 127 )
|
|
{
|
|
if(0 == CharUpperBuff( pszChoice+dw, 1))
|
|
{
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_ERR_CHARUPPER ), SIZE_OF_ARRAY(szTemp) );
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//now check for duplicates in choice
|
|
if(FALSE == CheckforDuplicates( pszChoice ) )
|
|
{
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_DUPLICATE_CHOICE ), SIZE_OF_ARRAY(szTemp) );
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
pcmdParcer = pcmdParcerHead + ID_DEFAULT_CHOICE;
|
|
if( pcmdParcer-> dwActuals > 0 )
|
|
{
|
|
|
|
if(0 == StringLengthW( pszDefaultChoice, 0 ))
|
|
{
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_DEFAULT_EMPTY ), SIZE_OF_ARRAY(szTemp) );
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if( FALSE == *pbCaseSensitive )
|
|
{
|
|
// Make the string to upper case
|
|
if( ((DWORD)pszDefaultChoice[0]) <= 127 )
|
|
{
|
|
|
|
if( 0 == CharUpperBuff( pszDefaultChoice, StringLengthW( pszDefaultChoice, 0 )))
|
|
{
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_ERR_CHARUPPER ), SIZE_OF_ARRAY(szTemp) );
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// length of /d cannot be more than one character
|
|
pcmdParcer = pcmdParcerHead + ID_DEFAULT_CHOICE;
|
|
|
|
|
|
if(( pcmdParcer-> dwActuals > 0 ) &&(StringLengthW( pszDefaultChoice, 0 ) > 1 ))
|
|
{
|
|
// Error String will be ..
|
|
// Invalid syntax. /D7/2/2001 accepts only single character.
|
|
// Type CHOICE /? for usage.
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_D_BIG ), SIZE_OF_ARRAY(szTemp) );
|
|
|
|
// Set the reason in memory
|
|
SetReason(szTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// check if timeout choice is given in choice list
|
|
pcmdParcer = pcmdParcerHead + ID_DEFAULT_CHOICE;
|
|
if (pcmdParcer-> dwActuals > 0 )
|
|
{
|
|
|
|
if(0 == UniStrChr( pszChoice, pszDefaultChoice[ 0 ] ))
|
|
{
|
|
// Error String will be ..
|
|
// Invalid syntax. Time Factor choice not in specified choices.
|
|
// Type CHOICE /? for usage.
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_D_NOT_MATCHED_TO_C ), SIZE_OF_ARRAY(szTemp) );
|
|
|
|
// Set the reason in memory
|
|
SetReason( szTemp );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
pcmdParcer = pcmdParcerHead + ID_MESSAGE_STRING;
|
|
if(pcmdParcer-> dwActuals > 0)
|
|
{
|
|
|
|
if( StringLengthW(pszMessage, 0) > MAX_STRING_LENGTH )
|
|
{
|
|
|
|
StringCopyW( szTemp, GetResString( IDS_MESSAGE_OVERFLOW ), SIZE_OF_ARRAY(szTemp) );
|
|
SetReason( szTemp );
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
// End of function ProcessCMDLine
|
|
|
|
void
|
|
ShowUsage( void )
|
|
/*--
|
|
Routine Description
|
|
This function shows help message for CHOICE
|
|
Arguments:
|
|
NONE
|
|
Return Value
|
|
None
|
|
--*/
|
|
{
|
|
DWORD dwIndx = 0; // Index Variable
|
|
|
|
for(dwIndx = IDS_HELP1; dwIndx <= IDS_HELP_END; dwIndx++ )
|
|
{
|
|
|
|
ShowMessage( stdout, GetResString( dwIndx ) );
|
|
}
|
|
|
|
return;
|
|
}
|
|
// End of function ShowUsage
|
|
|
|
BOOL
|
|
BuildPrompt(
|
|
IN TCMDPARSER2 *pcmdParcer,
|
|
IN BOOL bShowChoice,
|
|
IN LPWSTR pszChoice,
|
|
IN LPWSTR pszMessage,
|
|
OUT LPWSTR pszPromptStr)
|
|
/*++
|
|
Routine Description:
|
|
This function will Build command message prompt
|
|
|
|
Arguments:
|
|
[IN] pcmdParcer : Pointer to Command line parcer structure
|
|
[IN] bShowChoice : Stores the status, if choice to be shown
|
|
[IN] pszChoice : Choice string
|
|
[IN] pszMessage : Message String
|
|
[OUT] pszPromptStr : Final String to be shown on screen
|
|
|
|
Return Value:
|
|
TRUE if success
|
|
FALSE if failure
|
|
--*/
|
|
{
|
|
|
|
WCHAR szChar[32] ;
|
|
|
|
LPWSTR pszTemp = NULL; // Temp. string pointer
|
|
|
|
SecureZeroMemory(szChar, 32 * sizeof(WCHAR));
|
|
|
|
// Check for validity of pointer variables
|
|
if (( NULL == pcmdParcer) ||
|
|
( NULL == pszPromptStr))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
szChar[1] = NULL_U_CHAR; // make second character as end of line
|
|
// check if /M is given if given copy it to prompt string
|
|
pcmdParcer += ID_MESSAGE_STRING;
|
|
|
|
if( pcmdParcer-> dwActuals > 0 )
|
|
{
|
|
|
|
StringCopyW( pszPromptStr, pszMessage, 2*MAX_STRING_LENGTH );
|
|
|
|
StringConcat(pszPromptStr, SPACE, 2*MAX_STRING_LENGTH);
|
|
}
|
|
|
|
if( TRUE == bShowChoice )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// now append '[' to it
|
|
|
|
StringConcat(pszPromptStr, OPEN_BRACKET, 2*MAX_STRING_LENGTH);
|
|
// now append prompt characters to it
|
|
pszTemp = pszChoice;
|
|
|
|
do
|
|
{
|
|
szChar[ 0 ] = pszTemp[ 0 ]; // always assing first character of
|
|
//m_pszChoice as first character is
|
|
// changing in this loop
|
|
|
|
|
|
StringConcat(pszPromptStr, szChar, 2*MAX_STRING_LENGTH);
|
|
// now append a COMMA to this
|
|
// comma will be appended only if length of m_pszChoise
|
|
// is grester than 1
|
|
|
|
if( StringLengthW( pszTemp, 0 ) > 1 )
|
|
|
|
{
|
|
|
|
StringConcat(pszPromptStr, COMMA, 2*MAX_STRING_LENGTH);
|
|
}
|
|
pszTemp = CharNext( pszTemp );
|
|
|
|
}while( StringLengthW( pszTemp, 0 ) != 0);
|
|
|
|
// now close the bracket
|
|
|
|
StringConcat(pszPromptStr, CLOSED_BRACKET, 2*MAX_STRING_LENGTH);
|
|
|
|
return TRUE;
|
|
}
|
|
// End of function BuildPrompt
|
|
|
|
DWORD
|
|
UniStrChr(
|
|
IN LPWSTR pszBuf,
|
|
IN WCHAR szChar
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function finds the character in given string
|
|
Arguments:
|
|
[IN] pszBuf : Target String in which character is be find
|
|
[IN] szChar : Character to be found
|
|
Return Value:
|
|
returned string pointer after the character found.
|
|
--*/
|
|
{
|
|
LONG lPos = 0;
|
|
// find the character in string
|
|
while( NULL_U_CHAR != *pszBuf ) // Loop till string teminated character found
|
|
// 0 is always teminated character
|
|
{
|
|
lPos++;
|
|
if ( *(pszBuf++) == szChar )
|
|
{
|
|
|
|
return(lPos) ;
|
|
}
|
|
|
|
}
|
|
return(0);
|
|
|
|
}
|
|
// End of function UniStrChr
|
|
|
|
DWORD
|
|
GetChoice(
|
|
IN LPCWSTR pszPromptStr,
|
|
IN LONG lTimeOutFactor,
|
|
IN BOOL bCaseSensitive,
|
|
IN LPWSTR pszChoice,
|
|
IN LPCWSTR pszDefaultChoice,
|
|
OUT PBOOL pbErrorOnCarriageReturn)
|
|
/*++
|
|
Routine Description:
|
|
This function get choice from console OR wait for timeout
|
|
|
|
Arguments:
|
|
IN pszPromptStr : String to be shown as prompt
|
|
IN lTimeOutFactor : Time out factor
|
|
IN bCaseSensitive : Stores the state, if choice is case-sensitive
|
|
IN pszChoice : Choice string
|
|
IN pszDefaultChoice : Default choice character
|
|
OUT pbErrorOnCarriageReturn : True, if there is an error on carriage return
|
|
Return Value:
|
|
DWORD
|
|
--*/
|
|
{
|
|
//This function reads the keyboard and handles the I/O
|
|
HANDLE hInput = 0;// Stores the input handle device
|
|
HANDLE hOutput = 0;// Stores the output handle device
|
|
DWORD dwSignal = 0;// Stores return value for WaitForSingleObject
|
|
|
|
DWORD dwBytesRead = 0;// Stores number of byes read from console
|
|
DWORD dwBytesRead2 = 0;// Stores number of byes read from console
|
|
DWORD dwMode = 0;// Stores mode for input device
|
|
|
|
DWORD lTimeBefore = 0;
|
|
DWORD lTimeAfter = 0;
|
|
DWORD lPosition = 0;
|
|
DWORD dwRead = 0L;
|
|
BOOL bSuccess = FALSE; // Stores return value
|
|
BOOL bStatus = TRUE;
|
|
BOOL bIndirectionInput = FALSE;
|
|
BOOL bGetChoice = FALSE;
|
|
WCHAR szTempChar = NULL_U_CHAR; // Temperory variable
|
|
WCHAR szTempBuf[ MAX_RES_STRING ] = L"\0"; // Temp. string variable
|
|
CHAR chTmp = '\0';
|
|
WCHAR wchTmp = NULL_U_CHAR;
|
|
CHAR szAnsiBuf[ 10 ] = "\0"; // buffer of two characters is enough -- but still
|
|
INPUT_RECORD InputBuffer[ MAX_NUM_RECS ] = {0};
|
|
|
|
|
|
SecureZeroMemory(szTempBuf, MAX_RES_STRING * sizeof(WCHAR));
|
|
|
|
// Get handle for Input device
|
|
hInput = GetStdHandle( STD_INPUT_HANDLE );
|
|
|
|
if( INVALID_HANDLE_VALUE == hInput)
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
if( ( hInput != (HANDLE)0x0000000F )&&( hInput != (HANDLE)0x00000003 ) && ( hInput != INVALID_HANDLE_VALUE ) )
|
|
{
|
|
|
|
bIndirectionInput = TRUE;
|
|
}
|
|
|
|
|
|
// Get handle for Output device
|
|
hOutput = GetStdHandle( STD_OUTPUT_HANDLE );
|
|
|
|
if( INVALID_HANDLE_VALUE == hOutput )
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
// Get console mode, so we can change the input mode
|
|
bSuccess = GetConsoleMode( hInput, &dwMode );
|
|
if ( TRUE == bSuccess)
|
|
{
|
|
// turn off line input and echo
|
|
dwMode &= ~( ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT );
|
|
bSuccess = SetConsoleMode( hInput, dwMode );
|
|
|
|
if (FALSE == bSuccess)
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
|
|
}
|
|
|
|
if ( FlushConsoleInputBuffer( hInput ) == FALSE )
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show prompt message on screen.....
|
|
|
|
|
|
ShowMessage( stdout, _X(pszPromptStr) );
|
|
|
|
bStatus = SetConsoleCtrlHandler( &HandlerRoutine, TRUE );
|
|
if ( FALSE == bStatus )
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
// init the ANSI buffer with 0's in it
|
|
ZeroMemory( szAnsiBuf, SIZE_OF_ARRAY( szAnsiBuf ) * sizeof( CHAR ) );
|
|
|
|
while( FALSE == bGetChoice)
|
|
{
|
|
//The WaitForSingleObject function returns when one of the
|
|
// following occurs:
|
|
// 1. The specified object is in the signaled state i.e. Key press
|
|
// from keyboard
|
|
// 2.The time-out interval elapses.
|
|
|
|
lTimeBefore = GetTickCount();
|
|
|
|
dwSignal = WaitForSingleObject( hInput,
|
|
( lTimeOutFactor ) ?
|
|
( lTimeOutFactor * MILI_SEC_TO_SEC_FACTOR)
|
|
: INFINITE );
|
|
lTimeAfter = GetTickCount();
|
|
|
|
|
|
switch(dwSignal)
|
|
{
|
|
case WAIT_OBJECT_0: // The input buffer has something
|
|
{ // get first character
|
|
|
|
szTempBuf[ 1 ] = NULL_U_CHAR;
|
|
// Get character from console
|
|
if ( bIndirectionInput == FALSE )
|
|
{
|
|
|
|
if( PeekConsoleInput(hInput, InputBuffer, MAX_NUM_RECS, &dwRead ) == FALSE )
|
|
{
|
|
|
|
SaveLastError();
|
|
ReleaseGlobals();
|
|
return( EXIT__FAILURE );
|
|
}
|
|
|
|
//Ignore all the virtual keys like tab,break,scroll lock etc...
|
|
|
|
if(((InputBuffer[0].Event.KeyEvent.wVirtualKeyCode >= VK_LEFT)
|
|
&& (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode <= VK_DOWN))
|
|
|| (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_HOME)
|
|
|| (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_END)
|
|
|| (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_INSERT)
|
|
|| (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_DELETE)
|
|
||(InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_PRIOR)
|
|
||(InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_NEXT)
|
|
||(InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_TAB)
|
|
||(InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_SPACE))
|
|
|
|
{
|
|
|
|
if( lTimeOutFactor )
|
|
{
|
|
lTimeOutFactor -= ( DWORD )(( lTimeAfter - lTimeBefore) / MILI_SEC_TO_SEC_FACTOR);
|
|
}
|
|
if(0 == Beep( FREQUENCY_IN_HERTZ, DURETION_IN_MILI_SEC ))
|
|
{
|
|
if(TRUE == IsConsoleFile(stdout))
|
|
{
|
|
|
|
ShowMessage(stdout, L"\a");
|
|
}
|
|
}
|
|
if ( FlushConsoleInputBuffer( hInput ) == FALSE )
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
else if((InputBuffer[0].Event.KeyEvent.wVirtualKeyCode >= VK_F1)
|
|
&& (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode <= VK_F16)
|
|
|| (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
|
|
|| ((InputBuffer[0].Event.KeyEvent.wVirtualKeyCode >= VK_LBUTTON)
|
|
&& (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode <= VK_XBUTTON2))
|
|
||(InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_PAUSE)
|
|
||(InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_CAPITAL)
|
|
||(InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_NUMLOCK)
|
|
||(InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_SCROLL)
|
|
|| ((InputBuffer[0].Event.KeyEvent.wVirtualKeyCode >= VK_SELECT)
|
|
&& (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode <= VK_SNAPSHOT))
|
|
|| (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_HELP)
|
|
|| (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_LWIN)
|
|
|| (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_RWIN)
|
|
|| (InputBuffer[0].Event.KeyEvent.wVirtualKeyCode == VK_APPS)
|
|
)
|
|
{
|
|
if( lTimeOutFactor )
|
|
{
|
|
lTimeOutFactor -= ( DWORD )(( lTimeAfter - lTimeBefore) / MILI_SEC_TO_SEC_FACTOR);
|
|
}
|
|
|
|
if ( FlushConsoleInputBuffer( hInput ) == FALSE )
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
//Ignore changing the focus,doing alt+tab etc..
|
|
|
|
if(FOCUS_EVENT == InputBuffer[0].EventType
|
|
|| (VK_MENU == InputBuffer[0].Event.KeyEvent.wVirtualKeyCode )
|
|
||(VK_CONTROL == InputBuffer[0].Event.KeyEvent.wVirtualKeyCode)
|
|
||(VK_SHIFT == InputBuffer[0].Event.KeyEvent.wVirtualKeyCode)
|
|
||WINDOW_BUFFER_SIZE_EVENT == InputBuffer[0].EventType
|
|
||MOUSE_EVENT == InputBuffer[0].EventType
|
|
||MENU_EVENT == InputBuffer[0].EventType
|
|
||(FALSE == InputBuffer[0].Event.KeyEvent.bKeyDown))
|
|
{
|
|
if( lTimeOutFactor )
|
|
{
|
|
lTimeOutFactor -= ( DWORD )(( lTimeAfter - lTimeBefore) / MILI_SEC_TO_SEC_FACTOR);
|
|
}
|
|
|
|
if ( FlushConsoleInputBuffer( hInput ) == FALSE )
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
StringCopyW( szTempBuf, NULL_U_STRING, MAX_RES_STRING );
|
|
|
|
bSuccess = ReadConsole(hInput,
|
|
szTempBuf,
|
|
MAX_RES_STRING,
|
|
&dwBytesRead,
|
|
NULL);
|
|
|
|
|
|
|
|
if ( FALSE == bSuccess)
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
//read the contents of file
|
|
if ( ReadFile(hInput, &chTmp, 1, &dwBytesRead, NULL) == FALSE )
|
|
{
|
|
if(ERROR_BROKEN_PIPE == GetLastError())
|
|
{
|
|
// End of the pipe is reached, so inform the caller
|
|
*pbErrorOnCarriageReturn = TRUE;
|
|
StringCopyW( szTempBuf, GetResString(IDS_FILE_EMPTY), MAX_RES_STRING );
|
|
SetReason( szTempBuf );
|
|
}
|
|
else
|
|
{
|
|
SaveLastError();
|
|
}
|
|
return EXIT__FAILURE;
|
|
}
|
|
else
|
|
{
|
|
szAnsiBuf[ 0 ] = chTmp;
|
|
dwBytesRead2 = SIZE_OF_ARRAY( szTempBuf );
|
|
GetAsUnicodeString2( szAnsiBuf, szTempBuf, &dwBytesRead2 );
|
|
wchTmp = szTempBuf[ 0 ];
|
|
}
|
|
|
|
|
|
if ( (dwBytesRead == 0)) //|| wchTmp == CARRIAGE_RETURN))
|
|
{
|
|
|
|
if((StringLengthW((LPWSTR)pszDefaultChoice, 0)) != 0)
|
|
{
|
|
|
|
WaitForSingleObject( hInput,( lTimeOutFactor * MILI_SEC_TO_SEC_FACTOR));
|
|
|
|
|
|
ShowMessage( stdout, _X(pszDefaultChoice) );
|
|
|
|
ShowMessage( stdout, _X(END_OF_LINE) );
|
|
return UniStrChr( pszChoice, pszDefaultChoice[0] );
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
*pbErrorOnCarriageReturn = TRUE;
|
|
|
|
StringCopyW( szTempBuf, GetResString(IDS_FILE_EMPTY), MAX_RES_STRING );
|
|
SetReason( szTempBuf );
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
}
|
|
|
|
szTempBuf[0] = wchTmp;
|
|
|
|
}
|
|
|
|
|
|
//exit if non ascii character is given
|
|
|
|
|
|
if( ((DWORD)szTempBuf[0]) <= 47 ||
|
|
(((DWORD)szTempBuf[0])> 122 &&((DWORD)szTempBuf[0])< 127)||
|
|
(((DWORD)szTempBuf[0])> 57 &&((DWORD)szTempBuf[0])< 65 ) ||
|
|
(((DWORD)szTempBuf[0])> 90 &&((DWORD)szTempBuf[0])< 97 ) ||
|
|
((DWORD)szTempBuf[0])== 255)
|
|
{
|
|
if(0 == Beep( FREQUENCY_IN_HERTZ, DURETION_IN_MILI_SEC ))
|
|
{
|
|
if(TRUE == IsConsoleFile(stdout))
|
|
{
|
|
|
|
ShowMessage( stdout, L"\a" );
|
|
}
|
|
}
|
|
|
|
if ( FALSE == bIndirectionInput && FlushConsoleInputBuffer( hInput ) == FALSE )
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
if( lTimeOutFactor )
|
|
{
|
|
lTimeOutFactor -= ( DWORD )( lTimeAfter - lTimeBefore) / MILI_SEC_TO_SEC_FACTOR;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
if ( FALSE == bCaseSensitive )
|
|
{
|
|
if( ((DWORD)szTempBuf[0]) <= 127 )
|
|
{
|
|
if(0 == CharUpperBuff( szTempBuf, 1 ))
|
|
{
|
|
|
|
StringCopyW( szTempBuf, GetResString(IDS_ERR_CHARUPPER), MAX_RES_STRING );
|
|
// Set the reason in memory
|
|
SetReason(szTempBuf);
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
szTempChar = szTempBuf[ 0 ]; // Get first character
|
|
|
|
lPosition = UniStrChr( pszChoice, szTempChar );
|
|
|
|
szTempBuf[ 1 ] = NULL_U_CHAR; // Make second character as NULL
|
|
|
|
if (0 != lPosition)
|
|
{
|
|
StringCchPrintfW( szTempBuf,SIZE_OF_ARRAY(szTempBuf), L"%c\n", szTempChar );
|
|
|
|
// show the input character on output console
|
|
|
|
ShowMessage( stdout, _X(szTempBuf) );
|
|
return lPosition;
|
|
}
|
|
else // Character enterted not matches with Specified choice
|
|
{
|
|
if(0 == Beep( FREQUENCY_IN_HERTZ, DURETION_IN_MILI_SEC ))
|
|
{
|
|
if(TRUE == IsConsoleFile(stdout))
|
|
{
|
|
|
|
ShowMessage( stdout, L"\a" );
|
|
}
|
|
}
|
|
|
|
if ( FALSE == bIndirectionInput && FlushConsoleInputBuffer( hInput ) == FALSE )
|
|
{
|
|
|
|
SaveLastError();
|
|
return EXIT__FAILURE;
|
|
}
|
|
|
|
if( lTimeOutFactor )
|
|
{
|
|
lTimeOutFactor -= ( DWORD )( lTimeAfter - lTimeBefore) / MILI_SEC_TO_SEC_FACTOR;
|
|
}
|
|
|
|
}
|
|
}
|
|
break;
|
|
case WAIT_TIMEOUT: // The timeout exhausted
|
|
{
|
|
|
|
// Show timeout message on screen
|
|
|
|
ShowMessage( stdout, _X(pszDefaultChoice) );
|
|
|
|
ShowMessage( stdout, _X(END_OF_LINE) );
|
|
return UniStrChr( pszChoice, pszDefaultChoice[0] );
|
|
|
|
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return EXIT__FAILURE;
|
|
}
|
|
// End of function GetChoice
|
|
|
|
BOOL
|
|
CheckforDuplicates( IN LPWSTR lpszChoice
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function checks for the duplicate choices
|
|
|
|
Arguments:
|
|
IN lpszChoice : The list of choices in which the duplication of choice is to be checked
|
|
|
|
Return Value:
|
|
TRUE on success and FALSE on failure
|
|
|
|
--*/
|
|
{
|
|
WCHAR wTemp = NULL_U_CHAR;
|
|
|
|
while( lpszChoice[0] )
|
|
{
|
|
wTemp = lpszChoice[0];
|
|
lpszChoice++;
|
|
|
|
if( NULL != wcschr( lpszChoice, wTemp ) )
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
//end of checkforDuplicate function
|
|
|
|
|
|
BOOL WINAPI HandlerRoutine(
|
|
DWORD dwCtrlType
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function handles the control key CTRL+C and CTRL+BREAK.
|
|
|
|
Arguments:
|
|
IN dwCtrlType : Error control type
|
|
|
|
Return Value:
|
|
TRUE on success and FALSE on failure
|
|
--*/
|
|
{
|
|
// check for CTRL+C key
|
|
if ( ( dwCtrlType == CTRL_C_EVENT ) ||( dwCtrlType == CTRL_BREAK_EVENT ) )
|
|
{
|
|
exit ( FALSE);
|
|
}
|
|
|
|
// for remaining keys return false
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|