Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1205 lines
38 KiB

/*++
Copyright (c) Microsoft Corporation
Module Name:
ExecCommand.c
Abstract:
Command having hexadecimal values are converted to their respective ASCII characters ,
flags that are present in the command string are replaced by their values and
the command formed after the replacement of hexadecimal values and flags is
executed .
Author:
V Vijaya Bhaskar
Revision History:
14-Jun-2001 : Created by V Vijaya Bhaskar ( Wipro Technologies ).
--*/
#include "Global.h"
#include "ExecCommand.h"
// Declared in ForFiles.cpp , holds starting node memory location .
// No need to free this variable here, it will be freed in calling function
extern LPWSTR g_lpszFileToSearch ;
// Declared in ForFiles.cpp , holds path name specified at command prompt .
extern LPWSTR g_lpszStartPath ;
// Stores values of flags specified at command prompt.
static WCHAR *szValue[ TOTAL_FLAGS ] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } ;
// Stores the command to execute.
static LPWSTR g_f_lpszStoreCommand = NULL ;
/******************************************************************************
** Function Prototypes Local To This File **
******************************************************************************/
BOOL
IsHex(
IN WCHAR tIsNum
) ;
DWORD
CharToNum(
OUT DWORD dwNumber
) ;
BOOL
ReplaceString(
IN OUT LPWSTR lpszString ,
IN DWORD dwIndex
) ;
BOOL
ReplacePercentChar(
void
) ;
void
ReleaseFlagArray(
IN DWORD dwTotalFlags
) ;
BOOL
FormatMessageString(
IN DWORD dwIndex
) ;
BOOL
SeperateFileAndArgs(
IN OUT LPWSTR* lpszArguments,
OUT LPWSTR* lpszFileName
) ;
/*************************************************************************
/* Function Definition starts from here . **
*************************************************************************/
BOOL
ReplaceHexToChar(
OUT LPWSTR lpszCommand
)
/*++
Routine Description:
Replaces all hexadecimal values in a string to their ASCII characters .
Arguments:
[ OUT ] lpszCommand : Contains string in which hexadecimal values
are to be converted to ASCII characters.
Return value:
FALSE : Memory is insufficient.
TRUE
--*/
{
WCHAR *szTemp = NULL ; // Memory pointer .
unsigned char cHexChar[ 5 ]; // Contains ASCII character.
WCHAR wszHexChar[ 5 ]; // Contains UNICODE character.
SecureZeroMemory( wszHexChar, 5 * sizeof( WCHAR ) );
SecureZeroMemory( cHexChar, 5 * sizeof( unsigned char ) );
if( NULL == lpszCommand )
{
SetLastError( ERROR_INVALID_PARAMETER );
SaveLastError() ;
DISPLAY_GET_REASON();
return FALSE ;
}
szTemp = lpszCommand ; // Initialized.
// Continue while there are any hex character left .
do
{
szTemp = FindSubString( szTemp , IS_HEX ) ;
if( ( NULL != szTemp ) &&
( TRUE == IsHex( *( szTemp + 2 ) ) ) &&
( TRUE == IsHex( *( szTemp + 3 ) ) ) )
{
// An integer value of a hex "0x( HIGH_VALUE )( LOW_VALUE )" can
// be obtained by ( HIGH_VALUE *16 + LOW_VALUE ) .
cHexChar[ 0 ] = ( unsigned char )( ( CharToNum( *( szTemp + 2 ) ) * 16 ) +
CharToNum( *( szTemp + 3 ) ) ) ;
cHexChar[ 1 ] = '\0';
// Code page is static.
MultiByteToWideChar( US_ENG_CODE_PAGE, 0, (LPCSTR)cHexChar, -1, wszHexChar, 5 );
*szTemp = ( WCHAR ) wszHexChar[0];
// Copy STRING[0] = 0 , STRING[1] = x , STRING[2] = 1 , STRING[3] = a
// To , STRING[0] = VALID_CHAR .
StringCopy( ( szTemp + 1 ) , ( szTemp + 4 ), StringLength( ( szTemp + 1 ), 0 ) ) ;
szTemp += 1 ;
}
else
{
/* Suppose the string contains 0xP then control should come here ,
and this is the main purpose of this else block. */
if( NULL != szTemp )
{
szTemp += 2 ;
}
// Now 'szTemp' is pointing to
}
} while( NULL != szTemp ) ;
return TRUE;
}
BOOL
IsHex(
IN WCHAR wIsNum
)
/*++
Routine Description:
Checks whether the character falls in rangeof
hex or not ( To fall in the range of hex a character
must be either between 0 to 9 or a to f ).
Arguments:
[ IN ] tIsNum : Conatins a character which is to be checked for hex range .
Return value:
BOOL .
--*/
{
if( ( ( _T( '0' ) <= wIsNum ) && ( _T( '9' ) >= wIsNum ) ) ||
( ( _T( 'A' ) <= wIsNum ) && ( _T( 'F' ) >= wIsNum ) ) ||
( ( _T( 'a' ) <= wIsNum ) && ( _T( 'f' ) >= wIsNum ) ) )
{
return TRUE ; // Character is in the range of hex . "
}
else
{
return FALSE ;
}
}
DWORD
CharToNum(
OUT DWORD dwNumber
)
/*++
Routine Description:
Converts a character to number in HEX .
It can be 0 - 9 or A - F .
Arguments:
[ OUT ] dwNumber : Conatins an ASCII value .
Return value:
DWORD .
--*/
{
if( ( ASCII_0 <= dwNumber ) &&
( ASCII_9 >= dwNumber ) )
{ // Character is between 0 - 9 .
dwNumber -= ASCII_0 ;
}
else
{
if( ( ASCII_a <= dwNumber ) &&
( ASCII_f >= dwNumber ) )
{ // Character is between a - f .In hex a = 10.
dwNumber -= 87 ;
}
else
{
if( ( ASCII_A <= dwNumber ) &&
( ASCII_F >= dwNumber ) )
{ // Character is between A - F . In hex A = 10.
dwNumber -= 55 ;
}
}
}
return dwNumber ; // Return the obtained HEX number .
}
BOOL
ExecuteCommand(
void
)
/*++
Routine Description:
Executes a command .
Arguments:
NONE
Return value:
BOOL .
--*/
{
STARTUPINFO stInfo ;
PROCESS_INFORMATION piProcess ;
LPWSTR lpwszFileName = NULL;
LPWSTR lpwszPathName = NULL;
LPWSTR lpwFilePtr = NULL;
DWORD dwFilePathLen = 0;
DWORD dwTemp = 0;
if( NULL == g_lpszFileToSearch )
{
SetLastError( ERROR_INVALID_PARAMETER );
SaveLastError() ;
DISPLAY_GET_REASON();
return FALSE ;
}
// Initialize Process Info Structure With 0's
SecureZeroMemory( &piProcess, sizeof( PROCESS_INFORMATION ) );
// Initialize Startup Info Structure With 0's
SecureZeroMemory( &stInfo, sizeof( STARTUPINFO ) );
stInfo.cb = sizeof( stInfo ) ;
if( FALSE == SeperateFileAndArgs( &g_lpszFileToSearch, &lpwszFileName ) )
{ // Error is displayed by called function.
DISPLAY_MEMORY_ALLOC_FAIL();
FREE_MEMORY( lpwszFileName );
return FALSE;
}
dwFilePathLen = SearchPath( NULL, lpwszFileName, L".exe",
dwTemp, lpwszPathName, &lpwFilePtr );
if( 0 == dwFilePathLen )
{
SetLastError( GetLastError() );
SaveLastError();
DISPLAY_GET_REASON();
FREE_MEMORY( lpwszFileName );
return FALSE;
}
ASSIGN_MEMORY( lpwszPathName , WCHAR , dwFilePathLen + EXTRA_MEM ) ;
if( NULL == lpwszPathName )
{
DISPLAY_MEMORY_ALLOC_FAIL();
FREE_MEMORY( lpwszFileName );
return FALSE;
}
dwTemp = SearchPath( NULL, lpwszFileName, L".exe",
dwFilePathLen + EXTRA_MEM - 1,
lpwszPathName, &lpwFilePtr );
if( 0 == dwTemp )
{
SetLastError( GetLastError() );
SaveLastError();
DISPLAY_GET_REASON();
FREE_MEMORY( lpwszFileName );
FREE_MEMORY( lpwszPathName );
return FALSE;
}
// Create a new process .
if( FALSE == CreateProcess( lpwszPathName, g_lpszFileToSearch , NULL , NULL , FALSE ,
0 , NULL , NULL , &stInfo , &piProcess ) )
{
if( ERROR_BAD_EXE_FORMAT == GetLastError() )
{
ShowMessageEx( stderr, 5, FALSE, L"%1 %2%3%4%5", TAG_ERROR_DISPLAY,
DOUBLE_QUOTES_TO_DISPLAY, _X3( lpwszFileName ),
DOUBLE_QUOTES_TO_DISPLAY, NOT_WIN32_APPL ) ;
}
else
{
SaveLastError() ;
DISPLAY_GET_REASON();
}
FREE_MEMORY( lpwszFileName );
FREE_MEMORY( lpwszPathName );
return FALSE;
}
// Wait infinitly for the object just executed to terminate .
WaitForSingleObject( piProcess.hProcess , INFINITE ) ;
CloseHandle( piProcess.hProcess ) ; // Close handle of process .
CloseHandle( piProcess.hThread ) ; // Close handle of thread .
FREE_MEMORY( lpwszPathName );
FREE_MEMORY( lpwszFileName );
return TRUE ;
}
BOOL
ReplaceTokensWithValidValue(
IN LPWSTR lpszPathName ,
IN WIN32_FIND_DATA wfdFindFile
)
/*++
Routine Description:
Replaces tokens such as @flag , @path etc. with appropriate value .
Arguments:
[ IN ] lpszPathName - Contains current processes path name or CurrentDirectory .
[ IN ] wfdFindFile - Conatins information about current file being opened .
Return value:
BOOL is returned .
--*/
{
static BOOL bFirstLoop = TRUE ;
DWORD dwLength = 0; // Contains length of a buffer.
DWORD dwIndex = 0 ; // Contains number of flags for which space is allocated.
LPWSTR pwTemporary = NULL ; // Temporary data . Points to a memory location .
SYSTEMTIME stFileTime ; // Stores current file creation date and time information .
FILETIME ftFileTime ;
WCHAR szwCharSize[ MAX_PATH ] ;
WCHAR szwCharSizeTemp[ MAX_PATH * 2 ] ;
unsigned _int64 uint64FileSize = 0 ; // Used store data of 64 int .
LCID lcidCurrentUserLocale = 0; // Stores current user locale.
BOOL bLocaleChanged = FALSE ;
if( ( NULL == lpszPathName ) ||
( NULL == g_lpszFileToSearch ) )
{
SetLastError( ERROR_INVALID_PARAMETER );
SaveLastError() ;
DISPLAY_GET_REASON();
return FALSE ;
}
SecureZeroMemory( szwCharSize, MAX_PATH * sizeof( WCHAR ) );
SecureZeroMemory( szwCharSizeTemp, MAX_PATH * 2 * sizeof( WCHAR ) );
SecureZeroMemory( &stFileTime, sizeof( SYSTEMTIME ) );
SecureZeroMemory( &ftFileTime, sizeof( FILETIME ) );
// Replacement of '%NUMBER' to '%%NUMBER' is done once only.
if( TRUE == bFirstLoop )
{
if( FALSE == ReplacePercentChar() )
{
return FALSE ;
}
}
// Search for @fname.
if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_WITHOUT_EXT ) ) )
{
REPLACE_PERC_CHAR( bFirstLoop, FILE_WITHOUT_EXT, dwIndex );
dwLength = StringLength( wfdFindFile.cFileName, 0 ) + EXTRA_MEM;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
// Copy file name to the buffer.
StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
// ConCat file name .
StringConcat( szValue[ dwIndex - 1 ] , wfdFindFile.cFileName, dwLength ) ;
// Search for a '.' which separetes a file name with extension and put '\0' at '.' .
if( NULL != ( pwTemporary =StrRChr( szValue[ dwIndex - 1 ] , NULL, _T( '.' ) ) ) )
{
*pwTemporary = L'\0' ;
}
StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ; // Copy file name .
}
// Search for @file.
if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_NAME ) ) )
{
REPLACE_PERC_CHAR( bFirstLoop, FILE_NAME, dwIndex );
dwLength = StringLength( wfdFindFile.cFileName, 0 ) + EXTRA_MEM ;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
// Copy file name to the buffer.
StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
StringConcat( szValue[ dwIndex - 1 ], wfdFindFile.cFileName, dwLength );
StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
}
// Search for @ext.
if( NULL != ( FindSubString( g_lpszFileToSearch, EXTENSION ) ) )
{
REPLACE_PERC_CHAR( bFirstLoop, EXTENSION, dwIndex );
// Check '.' character exist or not.
// Check for '.' and replace ext .
if( NULL != StrRChr( wfdFindFile.cFileName, NULL, _T( '.' ) ) )
{
dwLength = StringLength( StrRChr( wfdFindFile.cFileName, NULL, _T( '.' ) ), 0 ) + EXTRA_MEM;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
// If number of characters appearing after '.' is zero, than assign '\0'.
if( StringLength( ( StrRChr( wfdFindFile.cFileName, NULL, _T( '.' ) ) + 1 ), 0 ) > 0 )
{
StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
StringConcat( szValue[ dwIndex - 1 ] ,
( StrRChr( wfdFindFile.cFileName, NULL, _T( '.' ) ) + 1 ), dwLength ) ;
StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength) ;
}
else
{ // If the filename has a '.' at the end , no extension . EX: File.
StringCopy( szValue[ dwIndex - 1 ], L"\"\"", dwLength );
}
}
else
{
dwLength = EXTRA_MEM + StringLength( L"\"\"", 0 );
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
StringCopy( szValue[ dwIndex - 1 ], L"\"\"", dwLength );
}
}
// Search for @path.
if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_PATH ) ) )
{
REPLACE_PERC_CHAR( bFirstLoop, FILE_PATH, dwIndex );
dwLength = StringLength( lpszPathName, 0 ) + StringLength( wfdFindFile.cFileName, 0 )+ EXTRA_MEM ;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
// Copy path to the buffer. Path copied should be enclosed in '\"' .
StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
StringConcat( szValue[ dwIndex - 1 ] , lpszPathName, dwLength ) ;
StringConcat( szValue[ dwIndex - 1 ] , wfdFindFile.cFileName, dwLength ) ;
StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
}
// Search for @relpath.
if( NULL != ( FindSubString( g_lpszFileToSearch, RELATIVE_PATH ) ) )
{
REPLACE_PERC_CHAR( bFirstLoop, RELATIVE_PATH, dwIndex );
StringCopy( szwCharSizeTemp , lpszPathName, MAX_PATH * 2 ) ;
StringConcat( szwCharSizeTemp , wfdFindFile.cFileName, MAX_PATH * 2 ) ;
// Obtain relative path to the current file.
if( FALSE == PathRelativePathTo( szwCharSize , g_lpszStartPath ,
FILE_ATTRIBUTE_DIRECTORY ,
szwCharSizeTemp , wfdFindFile.dwFileAttributes ) )
{
// Failed to find relative path.
SaveLastError() ;
DISPLAY_GET_REASON();
ReleaseFlagArray( dwIndex );
return FALSE ;
}
dwLength = StringLength( szwCharSize, 0 ) + EXTRA_MEM;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
// Copy relative path.
StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
StringConcat( szValue[ dwIndex - 1 ] , szwCharSize, dwLength ) ;
StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
}
// Search for @ext
if( NULL != ( FindSubString( g_lpszFileToSearch, IS_DIRECTORY ) ) )
{
REPLACE_PERC_CHAR( bFirstLoop, IS_DIRECTORY, dwIndex );
if( 0 != ( wfdFindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
{
dwLength = StringLength( GetResString( IDS_TRUE ), 0 ) + EXTRA_MEM ;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
StringCopy( szValue[ dwIndex - 1 ] , GetResString( IDS_TRUE ), dwLength ) ;
}
else
{
dwLength = StringLength( GetResString( IDS_FALSE ), 0 ) + EXTRA_MEM;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
// Copy 'false' to the buffer.
StringCopy( szValue[ dwIndex - 1 ] , GetResString( IDS_FALSE ), dwLength ) ;
}
}
// Search for @fsize
if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_SIZE ) ) )
{
REPLACE_PERC_CHAR( bFirstLoop, FILE_SIZE, dwIndex );
uint64FileSize = wfdFindFile.nFileSizeHigh * MAXDWORD ;
uint64FileSize += wfdFindFile.nFileSizeHigh + wfdFindFile.nFileSizeLow ;
#if _UNICODE // If Unicode .
_ui64tow( uint64FileSize , ( WCHAR * )szwCharSize , 10 ) ;
#else // If Multibyte .
_ui64toa( uint64FileSize , ( WCHAR * )szwCharSize , 10 ) ;
#endif
dwLength = StringLength( szwCharSize, 0 )+ EXTRA_MEM ;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
StringCopy( szValue[ dwIndex - 1 ] , ( WCHAR * )szwCharSize, dwLength ) ;
}
// Convert obtained file date time information to user locale .
// Convert file date time to SYSTEMTIME structure.
if( ( TRUE == FileTimeToLocalFileTime( &wfdFindFile.ftLastWriteTime , &ftFileTime ) ) &&
( TRUE == FileTimeToSystemTime( &ftFileTime , &stFileTime ) ) )
{
// verify whether console supports the current locale 100% or not
lcidCurrentUserLocale = GetSupportedUserLocale( &bLocaleChanged ) ;
// Check whether @fdate exist in the user specified string.
if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_DATE ) ) )
{
REPLACE_PERC_CHAR( bFirstLoop, FILE_DATE, dwIndex );
if( 0 == GetDateFormat( lcidCurrentUserLocale , DATE_SHORTDATE , &stFileTime ,
((bLocaleChanged == TRUE) ? L"MM/dd/yyyy" : NULL) ,
szwCharSize , MAX_STRING_LENGTH ) )
{
SaveLastError() ;
DISPLAY_GET_REASON();
ReleaseFlagArray( dwIndex );
return FALSE ;
}
dwLength = StringLength( szwCharSize, 0 )+ EXTRA_MEM;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
StringCopy( szValue[ dwIndex - 1 ] , szwCharSize, dwLength ) ;
}
// Check whether @ftime exist in the user specified string.
if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_TIME ) ) )
{
REPLACE_PERC_CHAR( bFirstLoop, FILE_TIME, dwIndex );
if( 0 == GetTimeFormat( LOCALE_USER_DEFAULT , 0 , &stFileTime ,
((bLocaleChanged == TRUE) ? L"HH:mm:ss" : NULL) ,
szwCharSize , MAX_STRING_LENGTH ) )
{
SaveLastError() ;
DISPLAY_GET_REASON();
ReleaseFlagArray( dwIndex );
return FALSE ;
}
dwLength = StringLength( szwCharSize, 0 )+ EXTRA_MEM ;
// Assign memory to the buffer.
ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
dwIndex += 1;
// Check whether memory allocation is successful.
if( NULL == szValue[ dwIndex - 1 ] )
{
// Memory allocation failed.
// Release buffers.
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
StringCopy( szValue[ dwIndex - 1 ] , szwCharSize, dwLength ) ;
}
}
if( TRUE == bFirstLoop )
{
dwLength = StringLength( g_lpszFileToSearch, 0 ) + EXTRA_MEM ;
REALLOC_MEMORY( g_f_lpszStoreCommand , WCHAR , dwLength ) ;
if( NULL == g_f_lpszStoreCommand )
{
DISPLAY_MEMORY_ALLOC_FAIL() ;
ReleaseFlagArray( dwIndex );
return FALSE ;
}
StringCopy( g_f_lpszStoreCommand, g_lpszFileToSearch, dwLength );
}
// Make 'bFirstLoop' flase, so we don't have to replace @FLAG for
// command store in 'g_f_lpszStoreCommand' in '%NUMBER' format for furthur loops.
bFirstLoop = FALSE ;
if( FALSE == FormatMessageString( dwIndex ) )
{
ReleaseFlagArray( dwIndex );
return FALSE ;
}
ReleaseFlagArray( dwIndex );
return TRUE ;
}
BOOL
ReplaceString(
IN OUT LPWSTR lpszString ,
IN DWORD dwIndex
)
/*++
Routine Description:
This function replaces flags with '%NUMBER' string so to
make FormatMEssage() comaptible.
Arguments:
[ IN OUT ] lpszString - Contains string which is a command to execute
having flags which will be replace by "%NUMBER".
[ IN ] dwIndex - Conatins a number which will form 'NUMBER' of '%NUMBER'.
Return value:
If success returns TRUE else FALSE.
--*/
{
DWORD dwLength = 0; // Contains length of a buffer.
DWORD dwNumOfChars = 0 ; // Contains index from where search has to be started.
LPWSTR lpszStoreData = NULL ; // Temporary variable to hold data.
// Conatins number in string format which forms 'NUMBER' of '%NUMBER'.
// 15 is because a number or DWORD cannot be more than 10 digits.
WCHAR szStoreIndex[ 15 ] ;
WCHAR *pwTemporary = NULL ; // Temporary variable, points to an index in a buffer.
#ifdef _WIN64
__int64 dwStringLen = 0 ;
#else
DWORD dwStringLen = 0 ;
#endif
if( ( NULL == g_lpszFileToSearch ) ||
( NULL == lpszString ) )
{
SetLastError( ERROR_INVALID_PARAMETER );
SaveLastError() ;
DISPLAY_GET_REASON();
return FALSE ;
}
SecureZeroMemory( szStoreIndex, 15 * sizeof( WCHAR ) );
// If Unicode .
_ultow( dwIndex, ( WCHAR * )szStoreIndex, 10 );
// Loops till @FLAG to be searched doesn't get replaced by a '%NUMBER' string.
while( NULL != ( pwTemporary = FindSubString( g_lpszFileToSearch + dwNumOfChars , lpszString ) ) )
{
dwLength = StringLength( pwTemporary, 0 ) + EXTRA_MEM;
// Get memory in which to store the data present after the @FLAG.
ASSIGN_MEMORY( lpszStoreData , WCHAR , dwLength ) ;
// Check whether memory allocation was successful.
if( NULL == lpszStoreData )
{ // Memory allocation was unsuccessful.
DISPLAY_MEMORY_ALLOC_FAIL();
return FALSE ;
}
// Copy data appering after @FLAG into temporary variable.
StringCopy( lpszStoreData , ( pwTemporary + StringLength( lpszString, 0 ) ), dwLength ) ;
// Replace @FLAG with '%NUMBER' string.
if( NULL != ( pwTemporary = FindSubString( g_lpszFileToSearch + dwNumOfChars , lpszString ) ) )
{
dwStringLen = pwTemporary - g_lpszFileToSearch;
// Copy '%' character.
StringCopy( pwTemporary , L"%",
( ( GetBufferSize( g_lpszFileToSearch )/ sizeof( WCHAR ) ) - (DWORD)dwStringLen ) ) ;
// Copy 'NUMBER' string into buffer.
StringConcat( pwTemporary , szStoreIndex,
( ( GetBufferSize( g_lpszFileToSearch )/ sizeof( WCHAR ) ) - (DWORD)dwStringLen ) ) ;
}
// Get index from where to start search for next @FLAG.
dwNumOfChars = StringLength( g_lpszFileToSearch, 0 ) ;
// Concat data which was appearing after replaced @FLAG.
StringConcat( g_lpszFileToSearch , lpszStoreData,
( GetBufferSize( g_lpszFileToSearch )/sizeof( WCHAR ) ) ) ;
// Free memory.
FREE_MEMORY( lpszStoreData ) ;
}
return TRUE;
}
BOOL
ReplacePercentChar(
void
)
/*++
Routine Description:
This function replaces '%' characters with '%%' string.
This is needed to distinguish between '%NUMBER' character which
is replaced by FormatMessageString() .
Arguments:
Return value:
If success returns TRUE else FALSE.
--*/
{
DWORD dwLength = 0; //Contains length of a buffer.
DWORD dwReallocLength = 0;
DWORD dwPercentChar = 0 ; // Keep record of number '%' char to be replaced.
#ifdef _WIN64
__int64 dwNumOfChars = 0 ;
#else
DWORD dwNumOfChars = 0 ; // Keep record of position or index from where to start next search.
#endif
LPWSTR lpszStoreData = NULL ; // Temporary variable to store data.
WCHAR *pwTemporary = NULL ; // Temporary pointer.
// Check whether variable is valid.
if( NULL == g_lpszFileToSearch )
{
SetLastError( ERROR_INVALID_PARAMETER );
SaveLastError() ;
DISPLAY_GET_REASON();
return FALSE ;
}
// Check number of '%' characters to replace with '%%'.
while( NULL != ( pwTemporary = StrPBrk( g_lpszFileToSearch + dwNumOfChars , L"%" ) ) )
{
dwPercentChar += 1;
// Point index to present char plus 2.
dwNumOfChars = pwTemporary - g_lpszFileToSearch + 1 ;
}
dwNumOfChars = 0 ; // Initialize variable to zero.
dwReallocLength = StringLength( g_lpszFileToSearch, 0 ) + dwPercentChar + EXTRA_MEM;
// Reallocate the orginal buffer and copy path to traverse .
REALLOC_MEMORY( g_lpszFileToSearch , WCHAR , dwReallocLength ) ;
if( NULL == g_lpszFileToSearch )
{ // Reallocation failed .'g_lpszFileToSearch' will be freed in calling function.
DISPLAY_MEMORY_ALLOC_FAIL() ;
return FALSE ;
}
// Loop till '%' character exist.
while( NULL != ( pwTemporary = StrPBrk( g_lpszFileToSearch + dwNumOfChars , L"%" ) ) )
{
dwLength = StringLength( pwTemporary, 0 ) + EXTRA_MEM;
// Assign memory.
ASSIGN_MEMORY( lpszStoreData , WCHAR , dwLength ) ;
// Check is memory allocation successful.
if( NULL == lpszStoreData )
{
// Memory allocation failed.
DISPLAY_MEMORY_ALLOC_FAIL() ;
return FALSE ;
}
// Copy data appearing after '%'.
StringCopy( lpszStoreData , ( pwTemporary + StringLength( L"%", 0 ) ), dwLength ) ;
// Replace '%' with '%%'.
if( NULL != ( pwTemporary = FindSubString( g_lpszFileToSearch + dwNumOfChars , L"%" ) ) )
{
StringCopy( pwTemporary , L"%%",
( ( GetBufferSize( g_lpszFileToSearch )/ sizeof( WCHAR ) ) - (LONG)dwNumOfChars ) );
}
// Point index to position which is not searched till.
dwNumOfChars = StringLength( g_lpszFileToSearch, 0 ) ;
// Concat data appearing after '%'.
StringConcat( g_lpszFileToSearch , lpszStoreData, dwReallocLength ) ;
FREE_MEMORY( lpszStoreData ) ;
}
return TRUE;
}
void
ReleaseStoreCommand(
void
)
/*++
Routine Description:
Releases 'g_f_lpszStoreCommand' global variable to this file.
Arguments:
Return value:
VOID is returned.
--*/
{
FREE_MEMORY( g_f_lpszStoreCommand ) ;
return;
}
void
ReleaseFlagArray(
IN DWORD dwTotalFlags
)
/*++
Routine Description:
Releases variables used to store values replacing @FLAG.
Arguments:
[ IN ] dwTotalFlags - Contains index of an array till which memory is assigned.
Return value:
VOID is returned.
--*/
{
DWORD i = 0 ;
for( i = 0 ; i < dwTotalFlags ; i++ )
{
FREE_MEMORY( szValue[ i ] ) ;
}
return ;
}
BOOL
FormatMessageString(
DWORD dwIndex
)
/*++
Routine Description:
Replaces '%NUMBER' with its appropriate values.
Arguments:
[ IN ] dwIndex - Contains index of an array till which memory is assigned.
Return value:
FALSE is returned when memory allocation failed else TRUE is returned..
--*/
{
DWORD dwLength = 0 ; //Contains length of a string.
DWORD dwTemp = 0 ;
DWORD dwNumber = 0 ; // Stores 'NUMBER' %NUMBER to replace.
// Keep record of position or index from where to start next search.
#ifdef _WIN64
__int64 dwLocation = 0 ;
#else
DWORD dwLocation = 0 ;
#endif
LPWSTR lpszTempStr = NULL ;
LPWSTR lpszTempStr1 = NULL ;
LPWSTR lpszDataToStore = NULL ;
if( NULL == g_f_lpszStoreCommand )
{
SetLastError( ERROR_INVALID_PARAMETER );
SaveLastError();
DISPLAY_GET_REASON();
return FALSE ;
}
dwLength = StringLength( g_f_lpszStoreCommand, 0 ) + EXTRA_MEM ;
// Realloc memory.
REALLOC_MEMORY( g_lpszFileToSearch , WCHAR , dwLength ) ;
if( NULL == g_lpszFileToSearch )
{
DISPLAY_MEMORY_ALLOC_FAIL() ;
return FALSE ;
}
StringCopy( g_lpszFileToSearch, g_f_lpszStoreCommand, dwLength );
// Loop until no more '%' are left.
while( NULL != ( lpszTempStr = FindAChar( ( g_lpszFileToSearch + dwLocation ), _T( '%' ) ) ) )
{
// Check whether '%' or 'NUMBER' is present after '%'.
if( _T( '%' ) == *( lpszTempStr + 1 ) )
{
// If '%%' is present then replace it with '%'.
dwLocation = lpszTempStr - g_lpszFileToSearch ;
// Set pointer to point to first '%'
lpszTempStr1 = lpszTempStr;
// Move pointer to point to second '%'.
lpszTempStr += 1 ;
// Copy.
StringCopy( lpszTempStr1, lpszTempStr, ( dwLength - ( DWORD ) dwLocation ) ) ;
dwLocation += 1 ;
}
else
{
// Replace '%NUMBER' with appropriate value.
dwNumber = *( lpszTempStr + 1 ) - 48 ;
if( dwIndex >= dwNumber )
{
ASSIGN_MEMORY( lpszDataToStore , WCHAR ,
StringLength( lpszTempStr, 0 ) + EXTRA_MEM ) ;
if( NULL == lpszDataToStore )
{ // No need to worry for 'g_lpszFileToSearch',
// will be freed in calling function.
DISPLAY_MEMORY_ALLOC_FAIL() ;
return FALSE ;
}
dwTemp = StringLength( szValue[ dwNumber - 1 ], 0 ) ;
dwLength = StringLength( g_lpszFileToSearch, 0 ) + dwTemp + EXTRA_MEM ;
REALLOC_MEMORY( g_lpszFileToSearch , WCHAR , dwLength ) ;
if( NULL == g_lpszFileToSearch )
{
FREE_MEMORY( lpszDataToStore ) ;
DISPLAY_MEMORY_ALLOC_FAIL() ;
return FALSE ;
}
// Check for '%' in the string after reallocation.
if( NULL != ( lpszTempStr = FindAChar( ( g_lpszFileToSearch + dwLocation ), _T( '%' ) ) ) )
{
// Store data after '%NUMBER' into a different string.
StringCopy( lpszDataToStore, ( lpszTempStr + 2 ),
( GetBufferSize( lpszDataToStore )/ sizeof( WCHAR ) ) );
// Copy value to be replaced by '%NUMBER'.
dwLocation = lpszTempStr - g_lpszFileToSearch;
StringCopy( lpszTempStr, szValue[ dwNumber - 1 ], ( dwLength - ( DWORD ) dwLocation ) );
// Copy string present after '%NUMBER' to origiinal strnig.
StringConcat( lpszTempStr, lpszDataToStore,
( dwLength - ( DWORD ) dwLocation ) );
dwLocation = ( lpszTempStr - g_lpszFileToSearch ) + dwTemp ;
}
FREE_MEMORY( lpszDataToStore ) ;
}
else
{
dwLocation += 1 ;
}
}
}
return TRUE;
}
BOOL
SeperateFileAndArgs(
IN OUT LPWSTR* lpszArguments,
OUT LPWSTR* lpszFileName
)
/*++
Routine Description:
Separates EXE and ARGUMENTS from a command line argument.
Arguments:
[ IN OUT ] *lpszArguments - Contains command line arguments.
[ IN ] *lpszFileName - Contains file name to execute.
Return value:
FALSE is returned when memory allocation failed els TRUE is returned..
--*/
{
LPWSTR lpTemp = NULL;
LPWSTR lpDummy = NULL;
DWORD dwLength = 0;
// Check for invalid parameter.
if( ( NULL == lpszArguments ) ||
( NULL == *lpszArguments ) ||
( NULL == lpszFileName ) ||
( NULL != *lpszFileName ) )
{
SetLastError( ERROR_INVALID_PARAMETER );
SaveLastError();
DISPLAY_GET_REASON();
return FALSE ;
}
// Initialize.
lpTemp = *lpszArguments;
// Remove any spaces appearing before the EXE.
if( _T( ' ' ) == lpTemp[ 0 ] )
{
TrimString2( lpTemp, _T( " " ), TRIM_LEFT );
}
// Search for end of the EXE
if( _T( '\"' ) == lpTemp[ 0 ] )
{ // EXE is wrapped in quotes.
lpTemp += 1;
lpDummy = FindAChar( lpTemp, _T( '\"' ) );
}
else
{ // Assumed that EXE is not wrapped in quotes.
lpDummy = FindAChar( lpTemp, _T( ' ' ) );
}
// Get length of buffer to allocate.
if( NULL == lpDummy )
{
dwLength = StringLength( lpTemp, 0 );
}
else
{
dwLength = ( DWORD ) ( DWORD_PTR ) ( lpDummy - lpTemp );
}
// Assign memory.
ASSIGN_MEMORY( *lpszFileName , WCHAR , dwLength + EXTRA_MEM ) ;
if( NULL == *lpszFileName )
{
DISPLAY_MEMORY_ALLOC_FAIL();
return FALSE;
}
// '+1' for null termination.
StringCopy( *lpszFileName, lpTemp, dwLength + 1 );
if( NULL == lpDummy )
{
StringCopy( lpTemp, _T( "" ), StringLength( lpTemp, 0 ) );
}
else
{
if( _T( '\"' ) == *lpDummy )
{
StringCopy( lpTemp, lpTemp + dwLength + 2, StringLength( lpTemp, 0 ) );
}
else
{
StringCopy( lpTemp, lpTemp + dwLength + 1, StringLength( lpTemp, 0 ) );
}
}
return TRUE;
}