|
|
/*++
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; }
|