|
|
/*++
Copyright (c) Microsoft Corporation
Module Name:
ForFiles.c
Abstract:
This file finds files present in a directory and subdirectory and calls appropriate function to perform the rest of task.
Author:
V Vijaya Bhaskar
Revision History:
14-Jun-2001 : Created by V Vijaya Bhaskar ( Wipro Technologies ).
--*/
#include "Global.h"
#include "FileDate.h"
#include "ExecCommand.h"
#include "Forfiles.h"
PStore_Path_Name g_pPathName = NULL ; // Holds path name from where started .
PStore_Path_Name g_pFollowPathName = NULL ; // Holds information about a subdirectory .
LPWSTR g_lpszFileToSearch = NULL; // Holds information about directories and subdirectories .
LPWSTR g_lpszStartPath = NULL ;
/******************************************************************************
** Function Prototypes ** ******************************************************************************/ BOOL ProcessOptions( IN DWORD argc , IN LPCWSTR *argv , OUT LPWSTR lpszPathName , OUT LPWSTR lpszSearchMask , OUT LPWSTR lpszCommand , OUT LPWSTR lpszDate , OUT BOOL *pbRecurse , OUT BOOL *pbUsage , OUT BOOL *pbSearchFilter ) ;
BOOL DisplayUsage( IN DWORD dwStartUsage , IN DWORD dwEndUsage ) ;
BOOL DisplayMatchedFiles( IN LPWSTR lpszPathName , IN LPWSTR lpszSearchMask , IN LPWSTR lpszCommand , IN Valid_File_Date vfdValidFileDate , IN DWORD dwDateGreater , IN BOOL bRecurse , IN BOOL bSearchFilter ) ;
BOOL Push( IN LPWSTR lpszPathName ) ;
BOOL Pop( void ) ;
BOOL DisplayFile( IN OUT BOOL *pbHeader , IN LPWSTR lpszPathName , IN DWORD dwDateGreater , IN LPWSTR lpszCommand , IN Valid_File_Date vfdValidFileDate , IN OUT BOOL *pbReturn , IN LPWSTR lpszSearchMask , IN BOOL bRecurse ) ;
BOOL FindAndReplaceString( IN OUT LPWSTR lpszString, IN LPWSTR lpszFlag ) ;
BOOL InitStartPath( LPWSTR lpszPathName, LPWSTR lpszCommand ) ;
BOOL CheckDateLocalized( LPWSTR lpwszDate, DWORD* pdwDateFormat, LPWSTR lpszDateSep );
BOOL PatternMatch( IN LPWSTR szPat, IN LPWSTR szFile );
/*************************************************************************
/* Function Definition starts from here . **
*************************************************************************/
DWORD __cdecl _tmain( IN DWORD argc , IN LPCWSTR argv[] ) /*++
Routine Description:
This is the main entry point to this code . Input supplied is read and appropriate function is called to achieve the functionality .
Arguments:
[ IN ] argc - Contains number of arguments passed at command prompt . [ IN ] argv - Contains value of each argument in string format .
Return value:
0 if tool succedded and 1 if tool failed .
--*/ {
// Variables to be passed to other functions .
DWORD dwDateGreater = 2 ; DWORD dwOldErrorMode = 0; Valid_File_Date vfdValidFileDate ;
// Variables required to hold command line inputs .
WCHAR szPathName[ MAX_STRING_LENGTH * 2 ] ; WCHAR szCommand[ MAX_STRING_LENGTH ] ; BOOL bRecurse = FALSE; BOOL bUsage = FALSE; BOOL bSearchFilter = TRUE ;
// Variables required to hold command line inputs .
// Variables to be passed to other functions but are to be
// removed or freed when they are not needed .
LPWSTR lpszDate = NULL ; LPWSTR lpszSearchMask = NULL ;
// Initialize to zero.
SecureZeroMemory( &vfdValidFileDate, sizeof( Valid_File_Date ) ); SecureZeroMemory( szPathName, MAX_STRING_LENGTH * 2 * sizeof( WCHAR ) ); SecureZeroMemory( szCommand, MAX_STRING_LENGTH * sizeof( WCHAR ) );
// Allocate memory to these variables .
ASSIGN_MEMORY( lpszDate , WCHAR , MAX_STRING_LENGTH ) ; ASSIGN_MEMORY( lpszSearchMask , WCHAR , MAX_STRING_LENGTH ) ;
// Check whether memory allocation was successfully .
if( ( NULL == lpszSearchMask ) || ( NULL == lpszDate ) ) { // Memory Allocation Failed .
DISPLAY_MEMORY_ALLOC_FAIL(); FREE_MEMORY( lpszDate ) ; FREE_MEMORY( lpszSearchMask ) ; ReleaseGlobals() ; return EXIT_FAILURE ; // 1 errorlevel
}
dwOldErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS ); // Check out whether arguments passed are valid and is the syntax right .
if( FALSE == ProcessOptions( argc, argv, szPathName, lpszSearchMask, szCommand, lpszDate, &bRecurse, &bUsage, &bSearchFilter ) ) { // Some error occured , free memory allocated , and exit .
FREE_MEMORY( lpszDate ) ; FREE_MEMORY( lpszSearchMask ) ; ReleaseGlobals() ; SetErrorMode( dwOldErrorMode ); return EXIT_FAILURE ; // 1 errorlevel
}
// Check whether /? was specified at command prompt .
if( TRUE == bUsage ) { // Free variable , and display help .
// Since 'dwDateGreater' is no more used, it is used for
// return value only in this block.
dwDateGreater = EXIT_SUCCESS; if( FALSE == DisplayUsage( IDS_HELP_START , IDS_HELP_END ) ) { dwDateGreater = EXIT_FAILURE; } FREE_MEMORY( lpszDate ) ; FREE_MEMORY( lpszSearchMask ) ; ReleaseGlobals() ; SetErrorMode( dwOldErrorMode ); return dwDateGreater ; // 0 or 1 errorlevel.
}
if( TRUE == SetCurrentDirectory( szPathName ) ) { // Sets process directory to supplied directory .
if( TRUE == InitStartPath( szPathName, szCommand ) ) {// Start path is intialized.
if( TRUE == Push( szPathName ) ) { // Push the current directory .
// 'bUsage' is not needed anymore. Can be used for other purpose.
bUsage = TRUE; if( 0 != StringLength( lpszDate, 0 ) ) { bUsage = ValidDateForFile( &dwDateGreater , &vfdValidFileDate , lpszDate ); } if( TRUE == bUsage ) { // Get date from where to display files .
FREE_MEMORY( lpszDate ) ; if( TRUE == DisplayMatchedFiles( szPathName , lpszSearchMask , szCommand , vfdValidFileDate , dwDateGreater , bRecurse , bSearchFilter ) ) { FREE_MEMORY( g_lpszStartPath ) ; FREE_MEMORY( lpszSearchMask ) ; ReleaseStoreCommand(); ReleaseGlobals() ; SetErrorMode( dwOldErrorMode ); return EXIT_SUCCESS ; } } } } } else { // Path supplied was wrong .
dwDateGreater = GetLastError(); switch( dwDateGreater ) { case ERROR_BAD_NET_NAME: case ERROR_BAD_NETPATH: SetLastError( ERROR_INVALID_NAME ) ; SaveLastError() ; DISPLAY_GET_REASON() ; break; case ERROR_ACCESS_DENIED: SetLastError( ERROR_ACCESS_DENIED ); SaveLastError() ; DISPLAY_GET_REASON() ; break; case ERROR_INVALID_NAME: SetLastError( ERROR_DIRECTORY ); SaveLastError() ; DISPLAY_GET_REASON() ; break; default: ShowMessageEx( stderr, 2, FALSE, L"%1 %2",TAG_ERROR_DISPLAY, ERROR_DIRECTORY_INVALID ) ; } }
// Free nodes in a linked list .
while( NULL != g_pPathName ) { // More than one node is present .
g_pFollowPathName = g_pPathName ; g_pPathName = g_pFollowPathName->NextNode ; FREE_MEMORY( g_pFollowPathName->pszDirName ) ; FREE_MEMORY( g_pFollowPathName ) ; }
FREE_MEMORY( g_lpszStartPath ) ; FREE_MEMORY( lpszSearchMask ) ; FREE_MEMORY( lpszDate ) ; ReleaseStoreCommand(); ReleaseGlobals() ; SetErrorMode( dwOldErrorMode ); return EXIT_FAILURE ; }
BOOL ProcessOptions( IN DWORD argc , IN LPCWSTR *argv , OUT LPWSTR lpszPathName , OUT LPWSTR lpszSearchMask , OUT LPWSTR lpszCommand , OUT LPWSTR lpszDate , OUT BOOL *pbRecurse , OUT BOOL *pbUsage , OUT BOOL *pbSearchFilter ) /*++
Routine Description:
Arguments supplied at command line are checked in this function for syntax or boundary or invalid command etc .
Arguments:
[ IN ] argc - Contains number of arguments passed at command prompt . [ IN ] *argv - Contains value of each argument in tring format . [ OUT ] lpszPathName - Contain path of a directory , if /pa option is specified . [ OUT ] lpszSearchMask - Contain search mask with which a file is to be searched , if /m option is specified . [ OUT ] lpszCommand - Contain command to execute , if /c option is specified . [ OUT ] lpszDate - Contain date , if /d option is specifed . [ OUT ] *pbRecurse - Whether to recurse into subdirectories , if /sd option specifed . [ OUT ] *pbUsage - Display help usage , if /? is specifed . [ OUT ] *pbSearchFilter- Search Filter /m option is specified or not .
Return value:
TRUE if syntax and arguments supplied to option are right else FALSE .
--*/ { // local variables
LPWSTR lpCharTemp = NULL ; // Pointer To Memory Location .
PTCMDPARSER2 pcmdOption = NULL; TCMDPARSER2 cmdOptions[ MAX_OPTIONS ]; // If user supplied file name is of 255 characters , then need some extra
// space for copying the directory into it .
WCHAR lpszTemp[ MAX_STRING_LENGTH * 2 ];
if( ( NULL == argv ) || ( NULL == lpszPathName ) || ( NULL == lpszSearchMask ) || ( NULL == lpszCommand ) || ( NULL == lpszDate ) || ( NULL == pbRecurse ) || ( NULL == pbUsage ) || ( NULL == pbSearchFilter ) ) { SetLastError( ERROR_INVALID_PARAMETER ); SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; }
// prepare the command options
SecureZeroMemory( cmdOptions, sizeof( TCMDPARSER2 ) * MAX_OPTIONS ); SecureZeroMemory( lpszTemp, MAX_STRING_LENGTH * 2 * sizeof( WCHAR ) );
// -?
pcmdOption = &cmdOptions[ OI_USAGE ] ;
StringCopyA( pcmdOption->szSignature, "PARSER2", 8 ); pcmdOption->dwType = CP_TYPE_BOOLEAN; pcmdOption->pwszOptions = OPTION_USAGE; pcmdOption->pwszFriendlyName = NULL; pcmdOption->pwszValues = NULL; pcmdOption->dwFlags = CP2_USAGE; pcmdOption->dwCount = 1; pcmdOption->dwActuals = 0; pcmdOption->pValue = pbUsage; pcmdOption->dwLength = 0; pcmdOption->pFunction = NULL; pcmdOption->pFunctionData = NULL; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL;
// -p
pcmdOption = &cmdOptions[ OI_PATH ] ;
StringCopyA( pcmdOption->szSignature, "PARSER2", 8 ); pcmdOption->dwType = CP_TYPE_TEXT; pcmdOption->pwszOptions = OPTION_PATH; pcmdOption->pwszFriendlyName = NULL; pcmdOption->pwszValues = NULL; pcmdOption->dwFlags = CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL; pcmdOption->dwCount = 1; pcmdOption->dwActuals = 0; pcmdOption->pValue = lpszPathName; pcmdOption->dwLength = ( MAX_STRING_LENGTH * 2 ); pcmdOption->pFunction = NULL; pcmdOption->pFunctionData = NULL; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL;
// -m
pcmdOption = &cmdOptions[ OI_SEARCHMASK ] ;
StringCopyA( pcmdOption->szSignature, "PARSER2", 8 ); pcmdOption->dwType = CP_TYPE_TEXT; pcmdOption->pwszOptions = OPTION_SEARCHMASK; pcmdOption->pwszFriendlyName = NULL; pcmdOption->pwszValues = NULL; pcmdOption->dwFlags = CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL; pcmdOption->dwCount = 1; pcmdOption->dwActuals = 0; pcmdOption->pValue = lpszSearchMask; pcmdOption->dwLength = MAX_STRING_LENGTH; pcmdOption->pFunction = NULL; pcmdOption->pFunctionData = NULL; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL;
// -c
pcmdOption = &cmdOptions[ OI_COMMAND ] ;
StringCopyA( pcmdOption->szSignature, "PARSER2", 8 ); pcmdOption->dwType = CP_TYPE_TEXT; pcmdOption->pwszOptions = OPTION_COMMAND; pcmdOption->pwszFriendlyName = NULL; pcmdOption->pwszValues = NULL; pcmdOption->dwFlags = CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL; pcmdOption->dwCount = 1; pcmdOption->dwActuals = 0; pcmdOption->pValue = lpszCommand; pcmdOption->dwLength = MAX_STRING_LENGTH; pcmdOption->pFunction = NULL; pcmdOption->pFunctionData = NULL; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL;
// -d
pcmdOption = &cmdOptions[ OI_DATE ] ;
StringCopyA( pcmdOption->szSignature, "PARSER2", 8 ); pcmdOption->dwType = CP_TYPE_TEXT; pcmdOption->pwszOptions = OPTION_DATE; pcmdOption->pwszFriendlyName = NULL; pcmdOption->pwszValues = NULL; pcmdOption->dwFlags = CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL; pcmdOption->dwCount = 1; pcmdOption->dwActuals = 0; pcmdOption->pValue = lpszDate; /*************************************************************
** If '+' or '-' is not specified then one character buffer ** ** extra is needed. That's why 1 less buffer is passed. If ** ** -1 is removed then overflow of buffer occurs which ** ** incorrect information. ** *************************************************************/ pcmdOption->dwLength = MAX_STRING_LENGTH - 1; pcmdOption->pFunction = NULL; pcmdOption->pFunctionData = NULL; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL;
// -s
pcmdOption = &cmdOptions[ OI_RECURSE ] ;
StringCopyA( pcmdOption->szSignature, "PARSER2", 8 ); pcmdOption->dwType = CP_TYPE_BOOLEAN; pcmdOption->pwszOptions = OPTION_RECURSE; pcmdOption->pwszFriendlyName = NULL; pcmdOption->pwszValues = NULL; pcmdOption->dwFlags = 0; pcmdOption->dwCount = 1; pcmdOption->dwActuals = 0; pcmdOption->pValue = pbRecurse; pcmdOption->dwLength = 0; pcmdOption->pFunction = NULL; pcmdOption->pFunctionData = NULL; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL;
// Do the parsing of supplied input .
if( FALSE == DoParseParam2( argc , argv , -1, SIZE_OF_ARRAY( cmdOptions ), cmdOptions, 0 ) ) { // Invalid synatx .
DISPLAY_GET_REASON() ; return FALSE ; }
// If /? is specified .
if( TRUE == *pbUsage ) { if( argc > 2 ) // If some other option is specified with the /? .
{ ShowMessageEx( stderr, 3, FALSE, L"%1 %2%3",TAG_ERROR_DISPLAY, ERROR_INVALID_SYNTAX, ERROR_DISPLAY_HELP ) ; return FALSE ; } else { // No need of furthur checking , display Help .
return TRUE ; } }
// Empty path is not valid
if( 0 == cmdOptions[ OI_PATH ].dwActuals ) { StringCopy( lpszPathName, _T( "." ), MAX_STRING_LENGTH ); }
/******************************************************************************
/* If option not specified then add a default value if required . **
/*****************************************************************************/
// If UNC path is specified then display error and return.
if( ( _T( '\\' ) == lpszPathName[ 0 ] ) && ( _T( '\\' ) == lpszPathName[ 1 ] )) { // Check whether specified path is in \\machine\share format.
lpCharTemp = FindAChar( ( lpszPathName + 2 ), _T('\\') ); if( ( NULL == lpCharTemp ) || ( ( _T( '\0' ) == lpCharTemp[ 1 ] ) || ( _T( '\\' ) == lpCharTemp[ 1 ] ) ) ) { SetLastError( ERROR_DIRECTORY ); SaveLastError(); DISPLAY_GET_REASON() ; return FALSE; } ShowMessageEx( stderr, 2, FALSE, L"%1 %2", TAG_ERROR_DISPLAY, ERROR_UNC_PATH_NAME ); return FALSE; } else { // Check does path name have more than '\' in the specified string.
// Check does path name have any '/' in the specified string.
if( ( NULL != FindSubString( lpszPathName, _T("...") ) ) || ( NULL != FindSubString( lpszPathName, DOUBLE_SLASH ) ) || ( NULL != FindSubString( lpszPathName, _T( "/" ) ) ) ) { SetLastError( ERROR_DIRECTORY ); SaveLastError(); DISPLAY_GET_REASON() ; return FALSE; } }
// Check Whether -m Is Specified At Command Prompt , If Not Initialize It To "*"
if( 0 == cmdOptions[ OI_SEARCHMASK ].dwActuals ) { StringCopy( lpszSearchMask , DEFAULT_SEARCH_MASK, MAX_STRING_LENGTH ) ; *pbSearchFilter = FALSE ; }
// Check whether -c is specified at command prompt.
// If not initialize it to "cmd /c echo @file".
if( 0 == cmdOptions[ OI_COMMAND ].dwActuals ) { StringCopy( lpszCommand , DEFAULT_COMMAND, MAX_STRING_LENGTH ) ; } else { // Replace Any Hex Value In String To An ASCII Character .
if( FALSE == ReplaceHexToChar( lpszCommand ) ) { // Error is displayed by the called function.
return FALSE; } // All flags are converted to lower case.
if( ( FALSE == FindAndReplaceString( lpszCommand, FILE_NAME ) ) || ( FALSE == FindAndReplaceString( lpszCommand, FILE_WITHOUT_EXT ) ) || ( FALSE == FindAndReplaceString( lpszCommand, EXTENSION ) ) || ( FALSE == FindAndReplaceString( lpszCommand, FILE_PATH ) ) || ( FALSE == FindAndReplaceString( lpszCommand, RELATIVE_PATH ) ) || ( FALSE == FindAndReplaceString( lpszCommand, IS_DIRECTORY ) ) || ( FALSE == FindAndReplaceString( lpszCommand, FILE_SIZE ) ) || ( FALSE == FindAndReplaceString( lpszCommand, FILE_DATE ) ) || ( FALSE == FindAndReplaceString( lpszCommand, FILE_TIME ) ) ) { // Error is displayed by the called function.
return FALSE; } }
// Check whether -d is specified.
if( 0 != cmdOptions[ OI_DATE ].dwActuals ) { // First character must be '+' or '-' .
if( ( PLUS != *lpszDate ) && ( MINUS != *lpszDate ) ) { StringCopy( lpszTemp, lpszDate, MAX_STRING_LENGTH * 2 ); StringCopy( lpszDate, L"+", MAX_STRING_LENGTH ); StringConcat( lpszDate, lpszTemp, MAX_STRING_LENGTH ); } // Now string length of 'lpszDate' should be more than 1.
if( ( ( ( PLUS != *lpszDate ) && ( MINUS != *lpszDate ) ) || ( 1 >= StringLength( lpszDate, 0 ) ) ) ) { // Invalid Date Specified .
DISPLAY_INVALID_DATE(); return FALSE ; }
if( FALSE == CheckDateLocalized( lpszDate, NULL, NULL ) ) { // Error is displayed by the called function.
return FALSE ; }
if( NULL != FindAChar( ( lpszDate + 1 ), _T('/') ) ) { // 'lpszDate' is in '{+|-}MM/dd/yyyy' format.
return TRUE; } } return TRUE ; }
BOOL DisplayMatchedFiles( IN LPWSTR lpszPathName , IN LPWSTR lpszSearchMask , IN LPWSTR lpszCommand , IN Valid_File_Date vfdValidFileDate , IN DWORD dwDateGreater , IN BOOL bRecurse , IN BOOL bSearchFilter ) /*++
Routine Description:
Path to search for a file is retrived and passed to functions for furthur processing.
Arguments:
[ IN ] lpszPathName - Contains path of a directory from where files matching a criteria are to be displayed . [ IN ] lpszSearchMask - Contains search mask with which a file is to be searched . [ IN ] lpszCommand - Contains command to execute . [ IN ] vfdValidFileDate - Contains a date files created before or after this date are to be displayed . [ IN ] dwDateGreater - File created before or after is decided by this variable . [ IN ] bRecurse - Whether to recurse into subdirectories . [ IN ] bSearchFilter - Whether search filter was specified at command prompt or not .
Return value:
TRUE if succeded in displaying the the obtained files else FALSE .
--*/ { BOOL bHeader = FALSE ; // Check for whether first item is displayed.
DWORD dwLength = 0; // Length of reallocted string.
BOOL bReturn = FALSE; // Contains return value.
// Loop until data strycture( stack) has no item left in it .
while( NULL != g_pPathName ) { // Pop a directory from stack which has to be traveresed .
if( FALSE == Pop( ) ) { // Control should come here only when linkedlist have no node to POP .
FREE_MEMORY( g_lpszFileToSearch ) ; // Error message is already displayed .
return FALSE ; } // Copy path name to variable which is the only source to get the current working directory .
StringCopy( lpszPathName , g_lpszFileToSearch, MAX_STRING_LENGTH * 2 ) ;
// Sets process directory to supplied directory .
if( FALSE == SetCurrentDirectory( lpszPathName ) ) { if( ERROR_ACCESS_DENIED == GetLastError()) { ShowMessageEx( stderr, 6 , FALSE, L"%1 %2%3%4%5%6", TAG_ERROR_DISPLAY, TAG_ERROR_ACCESS_DENIED, DOUBLE_QUOTES_TO_DISPLAY, lpszPathName, DOUBLE_QUOTES_TO_DISPLAY, APPEND_AT_END ) ; } else { SaveLastError() ; DISPLAY_GET_REASON() ; }
FREE_MEMORY( g_lpszFileToSearch ) ; continue ; } dwLength = StringLength( g_lpszFileToSearch, 0 ) + StringLength( lpszSearchMask, 0 ) + EXTRA_MEM ;
// Reallocate to copy search mask to original buffer .
REALLOC_MEMORY( g_lpszFileToSearch , WCHAR , dwLength ) ; if( NULL == g_lpszFileToSearch ) { DISPLAY_MEMORY_ALLOC_FAIL() ; return FALSE ; }
StringConcat( g_lpszFileToSearch , DEFAULT_SEARCH_MASK, dwLength ) ;
if( FALSE == DisplayFile( &bHeader , lpszPathName , dwDateGreater , lpszCommand , vfdValidFileDate , &bReturn , lpszSearchMask , bRecurse ) ) { FREE_MEMORY( g_lpszFileToSearch ) ; return FALSE ; } // Free memory.
FREE_MEMORY( g_lpszFileToSearch ) ; }
// If nothing is displayed on to the stdout then display error stderr .
if( FALSE == bHeader ) { // If some search criteria is specified.
if( NO_RESTRICTION_DATE != dwDateGreater ) { ShowMessageEx( stderr, 2, FALSE, L"%1 %2", TAG_ERROR_DISPLAY, ERROR_CRITERIA_MISMATCHED ) ; } else { // Search criteria is 'search mask' only.
if( TRUE == bSearchFilter ) { ShowMessageEx( stderr, 6, FALSE, L"%1 %2%3%4%5%6", TAG_ERROR_DISPLAY, ERROR_NOFILE_FOUND, DOUBLE_QUOTES_TO_DISPLAY, _X3(lpszSearchMask), DOUBLE_QUOTES_TO_DISPLAY, ERROR_NOFILE_FOUND1 ) ; } else { // Displays output as invalid handle , changed to file not found .
switch( GetLastError() ) { case ERROR_NO_MORE_FILES: case ERROR_INVALID_HANDLE: SetLastError( ERROR_FILE_NOT_FOUND ) ; SaveLastError() ; DISPLAY_GET_REASON() ; break; default: SaveLastError() ; DISPLAY_GET_REASON() ; } } } bReturn = FALSE ; }
FREE_MEMORY( g_lpszFileToSearch ) ; return bReturn ; }
BOOL DisplayFile( IN OUT BOOL *pbHeader , IN LPWSTR lpszPathName , IN DWORD dwDateGreater , IN LPWSTR lpszCommand , IN Valid_File_Date vfdValidFileDate , IN OUT BOOL *pbReturn , IN LPWSTR lpszSearchMask , IN BOOL bRecurse ) /*++
Routine Description:
Find subdirectories and files present in a directory and is passed to functions for furthur processing, such as , file was created between specified date or not , and replace the flags present in command with appropriate values etc.
Arguments:
[ IN OUT ] *pbHeader - Contains value to display errormessage if nothing is displayed . [ IN ] lpszPathName - Contains path of a directory from where files matching a criteria are to be displayed . [ IN ] dwDateGreater - File created before or after is decided by this variable . [ IN ] lpszCommand - Contains command to execute . [ IN ] vfdValidFileDate - Contains a date files created before or after this date are to be displayed . [ IN OUT ] *pbReturn - Contains exit value . [ IN ] lpszSearchMask - Contains search mask with which a file is to be searched . [ IN ] bRecurse - Contains TRUE when child directories are also to be searched else FALSE.
Return value:
TRUE if succeded in executing the command and finding a file falling in range of specified date else FALSE .
--*/ { HANDLE hFindFile = NULL ; // Handle to a file .
WIN32_FIND_DATA wfdFindFile ; // Structure keeping information about the found file .
DWORD dwLength = 0;
if( ( NULL == pbHeader ) || ( NULL == pbReturn ) || ( NULL == lpszPathName ) || ( NULL == lpszSearchMask ) || ( NULL == lpszCommand ) ) { SetLastError( ERROR_INVALID_PARAMETER ); SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; }
SecureZeroMemory( &wfdFindFile , sizeof( WIN32_FIND_DATA ) ) ; // From here onwards directory and file information should be displayed .
if( INVALID_HANDLE_VALUE != ( hFindFile = FindFirstFile( g_lpszFileToSearch , &wfdFindFile ) ) ) { do // Loop until files are present in the directory to display .
{ // Check whether files are "." or "..".
if( ( 0 == StringCompare( wfdFindFile.cFileName , SINGLE_DOT, TRUE, 0 ) ) || ( 0 == StringCompare( wfdFindFile.cFileName , DOUBLE_DOT, TRUE, 0 ) ) ) { continue ; }
// Check again whether obtained handle points to a directory or file .
// If directory then check whether files in subdir are to be displayed .
if( ( TRUE == bRecurse ) && ( 0 != ( wfdFindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) ) { dwLength = StringLength( lpszPathName, 0 ) + StringLength( wfdFindFile.cFileName, 0 ) + EXTRA_MEM ; // Reallocate memory .
REALLOC_MEMORY( g_lpszFileToSearch , WCHAR , dwLength ) ; if( NULL == g_lpszFileToSearch ) { // Reallocation failed .
DISPLAY_MEMORY_ALLOC_FAIL() ; CLOSE_FILE_HANDLE( hFindFile ) ; return FALSE ; } // Copy Path, Concat FileName, Concat '\' as it is required .
StringCopy( g_lpszFileToSearch , lpszPathName, dwLength ) ; StringConcat( g_lpszFileToSearch , wfdFindFile.cFileName, dwLength ) ; StringConcat( g_lpszFileToSearch , SINGLE_SLASH, dwLength ) ; // Copy current path name and store it .
if( FALSE == Push( g_lpszFileToSearch ) ) { // Control comes here when memory allocation fails .
CLOSE_FILE_HANDLE( hFindFile ) ; return FALSE ; } // Push Is Over .
}
// Check out whether the file matches pattern specified and if yes then
// file obtained is created on a valid date as specified by user.
if( ( TRUE == PatternMatch( lpszSearchMask, wfdFindFile.cFileName ) ) && ( ( NO_RESTRICTION_DATE == dwDateGreater ) || ( TRUE == FileDateValid( dwDateGreater , vfdValidFileDate , wfdFindFile.ftLastWriteTime ) ) ) ) { // Execute a command specified at command prompt .
// Reallocate memory .
dwLength = StringLength( lpszCommand, 0 ) + EXTRA_MEM; REALLOC_MEMORY( g_lpszFileToSearch , WCHAR , dwLength ) ; if( NULL == g_lpszFileToSearch ) { // Reallocation failed .
DISPLAY_MEMORY_ALLOC_FAIL() ; CLOSE_FILE_HANDLE( hFindFile ) ; return FALSE ; } // Contains original command to execute .
StringCopy( g_lpszFileToSearch , lpszCommand, dwLength ) ; // Value can be anything , Filename , Extension name , PathName etc.
if( TRUE == ReplaceTokensWithValidValue( lpszPathName , wfdFindFile ) ) { // Tokens are replaced , know execute this command .
if( FALSE == *pbHeader ) { ShowMessage( stdout , _T( "\n" ) ) ; } if( TRUE == ExecuteCommand( ) ) { *pbReturn = TRUE ; } // Make header TRUE because it tell us :
// a) No need to display header .
// b) If FindFirstFile() returns invalidHandle then ,
// display error if Handle == FALSE .
*pbHeader = TRUE ; } else { // Failed to replace tokens , might be memory insuffcient .
*pbReturn = FALSE ; CLOSE_FILE_HANDLE( hFindFile ) ; return FALSE ; } } // Continue till no files are present to display.
} while( 0 != FindNextFile( hFindFile , &wfdFindFile ) ) ; }
CLOSE_FILE_HANDLE( hFindFile ) ; // Close open find file handle .
g_pFollowPathName = NULL ; return TRUE ; }
BOOL Push( IN LPWSTR szPathName ) /*++
Routine Description:
Store the path of obtained subdirectory .
Arguments:
[ IN ] szPathName - Contains path of a subdirectory .
Return value:
TRUE if succedded in storing a path else FALSE if failed to get memory.
--*/ { // Get a temporary variable .
PStore_Path_Name pAddPathName = NULL; DWORD dwLength = 0;
if( NULL == szPathName ) { SetLastError( ERROR_INVALID_PARAMETER ); SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; }
// Assign memory To Temporary Variable .
ASSIGN_MEMORY( pAddPathName , struct __STORE_PATH_NAME , 1 ) ; if( NULL == pAddPathName ) // Check memory allocation is successful.
{ // Memory allocation is unsuccessful .
DISPLAY_MEMORY_ALLOC_FAIL() ; return FALSE ; }
dwLength = StringLength( szPathName, 0 ) + EXTRA_MEM ; // Assign memory to string variable which is going to store full path name
// of a valid directory .
ASSIGN_MEMORY( pAddPathName->pszDirName , WCHAR , dwLength ) ; if( NULL == pAddPathName->pszDirName ) // Check memory allocation is successful.
{ // Memory allocation was unsuccessful .
DISPLAY_MEMORY_ALLOC_FAIL() ; FREE_MEMORY( pAddPathName ) ; return FALSE ; }
// Copy path name to memory allocated string variable .
StringCopy( ( LPWSTR ) pAddPathName->pszDirName , szPathName, dwLength ) ; pAddPathName->NextNode = NULL ; // Assign null , had only one subdirectory stored.
// Check global variable is NULL or not .
if( NULL == g_pPathName ) { // Add memory to store path of subdirectory .
g_pPathName = pAddPathName ; g_pFollowPathName = g_pPathName ; } else { if( NULL == g_pFollowPathName ) { // Store first obtained subdirectory .
pAddPathName->NextNode = g_pPathName ; g_pPathName = pAddPathName ; g_pFollowPathName = g_pPathName ; } else { // Stroe subdirectory in the middle
pAddPathName->NextNode = g_pFollowPathName->NextNode ; g_pFollowPathName->NextNode = pAddPathName ; g_pFollowPathName = pAddPathName ; } } return TRUE ; }
BOOL Pop( void ) /*++
Routine Description:
Get a subdirectory which has to be searched for a file matching a user specified criteria .
Arguments:
Return value:
TRUE if successful in getting a path else FALSE if failed to get memory or if no path is stored .
--*/ { // Linked list has more than 1 node .
PStore_Path_Name pDelPathName = g_pPathName ; DWORD dwLength = 0;
// Check whether linked list is having any nodes .
if( NULL == g_pPathName ) { // No nodes present , return False ,
// Should not happen ever . Control should not come here .
DISPLAY_MEMORY_ALLOC_FAIL() ; return FALSE ; }
dwLength = StringLength( g_pPathName->pszDirName, 0 ) + EXTRA_MEM; // Realloc memory and give buffer space in which path name can fix .
ASSIGN_MEMORY( g_lpszFileToSearch , WCHAR , dwLength ) ; if( NULL == g_lpszFileToSearch ) { // Memory reallocation failed .
DISPLAY_MEMORY_ALLOC_FAIL() ; return FALSE ; }
g_pPathName = pDelPathName->NextNode ; // Memory allocation successful. Copy pathname to the buffer.
StringCopy( g_lpszFileToSearch, pDelPathName->pszDirName, dwLength ) ; // Free node.
FREE_MEMORY( pDelPathName->pszDirName ) ; FREE_MEMORY( pDelPathName ) ; return TRUE ; }
BOOL DisplayUsage( IN DWORD dwStartUsage , IN DWORD dwEndUsage ) /*++
Routine Description:
This function displays help on this tool .
Arguments:
[ IN ] dwStartUsage - Start Resource String ID in Resiurce file for help usage . [ IN ] dwEndUsage - End Resource String ID in Resiurce file for help usage .
Return value:
If success returns TRUE else FALSE .
--*/ { DWORD dwLoop = 0 ; WCHAR wszDisplayStr[ 256 ]; // Contains string to display.
WCHAR wszDateFormat[ 20 ]; // Contains date format w.r.t locale.
WCHAR wszString[ 5 ]; // Contains date seperator w.r.t locale.
WCHAR wszDateDisplay[ 50 ]; // Contains date w.r.t locale for examples in help.
WCHAR wszStaticDateDisplay[ 50 ]; // Contains date w.r.t locale for examples in help.
SYSTEMTIME sysTimeAndDate ; DWORD dwDateFormat = 0 ;
SecureZeroMemory( wszDisplayStr, SIZE_OF_ARRAY( wszDisplayStr ) * sizeof( WCHAR ) ); SecureZeroMemory( wszDateFormat, SIZE_OF_ARRAY( wszDateFormat ) * sizeof( WCHAR ) ); SecureZeroMemory( wszString, SIZE_OF_ARRAY( wszString ) * sizeof( WCHAR ) ); SecureZeroMemory( wszDateDisplay, SIZE_OF_ARRAY( wszDateDisplay ) * sizeof( WCHAR ) ); SecureZeroMemory( wszStaticDateDisplay, SIZE_OF_ARRAY( wszStaticDateDisplay ) * sizeof( WCHAR ) ); SecureZeroMemory( &sysTimeAndDate, sizeof( SYSTEMTIME ) );
if( FALSE == CheckDateLocalized( NULL, &dwDateFormat, wszString ) ) { // Error is displayed by the called function.
return FALSE; }
// 'void' is returned so need to check return value.
GetLocalTime( &sysTimeAndDate );
// Fill up all the strings with required values.
switch( dwDateFormat ) { // 'MM/yyyy/dd' format.
case 1: StringCchPrintfW( wszDateFormat, SIZE_OF_ARRAY( wszDateFormat ), FORMAT_1, wszString, wszString ); StringCchPrintfW( wszStaticDateDisplay, SIZE_OF_ARRAY( wszStaticDateDisplay ), L"01%s2001%s01", wszString, wszString ); StringCchPrintfW( wszDateDisplay, SIZE_OF_ARRAY( wszDateDisplay ), DATE_FORMAT, sysTimeAndDate.wMonth, wszString, sysTimeAndDate.wYear, wszString, sysTimeAndDate.wDay ); break;
// 'dd/MM/yyyy' format.
case 2: StringCchPrintfW( wszDateFormat, SIZE_OF_ARRAY( wszDateFormat ), FORMAT_2, wszString, wszString ); StringCchPrintfW( wszStaticDateDisplay, SIZE_OF_ARRAY( wszStaticDateDisplay ), L"01%s01%s2001", wszString, wszString ); StringCchPrintfW( wszDateDisplay, SIZE_OF_ARRAY( wszDateDisplay ), DATE_FORMAT, sysTimeAndDate.wDay, wszString, sysTimeAndDate.wMonth, wszString, sysTimeAndDate.wYear ); break;
// 'dd/yyyy/MM' format.
case 3: StringCchPrintfW( wszDateFormat, SIZE_OF_ARRAY( wszDateFormat ), FORMAT_3, wszString, wszString ); StringCchPrintfW( wszStaticDateDisplay, SIZE_OF_ARRAY( wszStaticDateDisplay ), L"01%s2001%s01", wszString, wszString ); StringCchPrintfW( wszDateDisplay, SIZE_OF_ARRAY( wszDateDisplay ), DATE_FORMAT, sysTimeAndDate.wDay, wszString, sysTimeAndDate.wYear, wszString, sysTimeAndDate.wMonth ); break;
// 'yyyy/dd/MM' format.
case 4: StringCchPrintfW( wszDateFormat, SIZE_OF_ARRAY( wszDateFormat ), FORMAT_4, wszString, wszString ); StringCchPrintfW( wszStaticDateDisplay, SIZE_OF_ARRAY( wszStaticDateDisplay ), L"2001%s01%s01", wszString, wszString ); StringCchPrintfW( wszDateDisplay, SIZE_OF_ARRAY( wszDateDisplay ), DATE_FORMAT, sysTimeAndDate.wYear, wszString, sysTimeAndDate.wDay, wszString, sysTimeAndDate.wMonth ); break;
// 'yyyy/MM/dd' format.
case 5: StringCchPrintfW( wszDateFormat, SIZE_OF_ARRAY( wszDateFormat ), FORMAT_5, wszString, wszString ); StringCchPrintfW( wszStaticDateDisplay, SIZE_OF_ARRAY( wszStaticDateDisplay ), L"2001%s01%s01", wszString, wszString ); StringCchPrintfW( wszDateDisplay, SIZE_OF_ARRAY( wszDateDisplay ), DATE_FORMAT, sysTimeAndDate.wYear, wszString, sysTimeAndDate.wMonth, wszString, sysTimeAndDate.wDay ); break;
// 'MM/dd/yyyy' format.
default: StringCchPrintfW( wszDateFormat, SIZE_OF_ARRAY( wszDateFormat ), FORMAT_0, wszString, wszString ); StringCchPrintfW( wszStaticDateDisplay, SIZE_OF_ARRAY( wszStaticDateDisplay ), L"01%s01%s2001", wszString, wszString ); StringCchPrintfW( wszDateDisplay, SIZE_OF_ARRAY( wszDateDisplay ), DATE_FORMAT, sysTimeAndDate.wMonth, wszString, sysTimeAndDate.wDay, wszString, sysTimeAndDate.wYear ); break; }
// Keep on displaying the help.
for( dwLoop = dwStartUsage ; dwLoop <= dwEndUsage ; dwLoop++ ) { switch( dwLoop ) { case IDS_HELP_SYNTAX2 : SecureZeroMemory( wszDisplayStr, SIZE_OF_ARRAY( wszDisplayStr ) ); StringCchPrintfW( wszDisplayStr, SIZE_OF_ARRAY( wszDisplayStr ), GetResString( dwLoop ), wszDateFormat ); ShowMessage( stdout , _X(wszDisplayStr) ) ; break; case IDS_HELP_D1: case IDS_HELP_D2: case IDS_HELP_D3: case IDS_HELP_D4: case IDS_HELP_D5: case IDS_HELP_D6: case IDS_HELP_D7: case IDS_HELP_D8: case IDS_HELP_D9: case IDS_HELP_D10: SecureZeroMemory( wszDisplayStr, SIZE_OF_ARRAY( wszDisplayStr ) ); StringCchPrintfW( wszDisplayStr, SIZE_OF_ARRAY( wszDisplayStr ), GetResString( dwLoop ), wszDateFormat ); ShowMessage( stdout , _X(wszDisplayStr) ) ; break; case IDS_HELP_E8: SecureZeroMemory( wszDisplayStr, SIZE_OF_ARRAY( wszDisplayStr ) ); StringCchPrintfW( wszDisplayStr, SIZE_OF_ARRAY( wszDisplayStr ), GetResString( dwLoop ), wszStaticDateDisplay ); ShowMessage( stdout , _X(wszDisplayStr) ) ; break; case IDS_HELP_E10: SecureZeroMemory( wszDisplayStr, SIZE_OF_ARRAY( wszDisplayStr ) ); StringCchPrintfW( wszDisplayStr, SIZE_OF_ARRAY( wszDisplayStr ), GetResString( dwLoop ), wszDateDisplay ); ShowMessage( stdout , _X(wszDisplayStr) ) ; break; default: ShowMessage( stdout , GetResString( dwLoop ) ) ; } }
// Successful.
return TRUE; }
BOOL FindAndReplaceString( IN OUT LPWSTR lpszString, IN LPWSTR lpszFlag ) /*++
Routine Description:
This function finds flags ( Eg: @file, @path etc.) given by user in any case and converts them to lowercase.
Arguments:
[ IN ] lpszString - String in which to replace flags to lowercase . [ IN ] lpszFlag - Flag to be replaced .
Return value:
Returns FALSE if memory allocation fails else returns TRUE .
--*/ { DWORD dwLength = 0 ; DWORD dwIndex = 0 ; LPWSTR lpszTemp = NULL ; LPWSTR lpszDup = NULL ;
// Keep record of position or index from where to start next search.
#ifdef _WIN64
__int64 dwLocation = 0 ; #else
DWORD dwLocation = 0 ; #endif
if( ( NULL == lpszString ) || ( NULL == lpszFlag ) ) { SetLastError( ERROR_INVALID_PARAMETER ); SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; }
// Get a duplicate string.
lpszDup = StrDup( lpszString );
if( NULL == lpszDup ) { DISPLAY_MEMORY_ALLOC_FAIL() ; return FALSE ; } // Convert duplicate string to lowercase.
CharLower( lpszDup );
lpszTemp = lpszDup ; // Get Length of duplicate string.
dwLength = StringLength( lpszFlag, 0 ) ;
// Loop until all the strings "FLAG" are note replaced.
// Here string replaced is of original string, duplicate string
// used to get the index or location of flag.
while( NULL != ( lpszTemp = FindSubString( lpszTemp, lpszFlag ) ) ) { // Get the index from where the "FLAG" is starting.
dwLocation = lpszTemp - lpszDup ; // Add length of the flag to the string pointer to get ready
// for next iteration.
lpszTemp += dwLength ; // Check is the character to be replaced is in uppercase.
for( dwIndex = 1 ; dwIndex < dwLength ; dwIndex++ ) { // Character to be replaced is in uppercase.
if( ( 65 <= (DWORD)*( lpszString + dwLocation + dwIndex ) ) && ( 90 >= (DWORD)*( lpszString + dwLocation + dwIndex ) ) ) { // Add 32 to convert uppercase letter to lowercase.
*( lpszString + dwLocation + dwIndex ) += 32 ; } } } LocalFree( lpszDup ); return TRUE ; }
BOOL InitStartPath( LPWSTR lpszPathName, LPWSTR lpszCommand ) /*++
Routine Description:
This function copies start path to global variable.
Arguments:
[ IN ] lpszPathName - Current process path. [ IN ] lpszCommand - Command to execute.
Return value:
Returns FALSE if memory allocation fails else returns TRUE .
--*/ { DWORD dwLength = 0;
if( ( NULL == lpszPathName ) || ( NULL == lpszCommand ) ) { SetLastError( ERROR_INVALID_PARAMETER ); SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; }
// If not specified then get current directory path.
if( 0 == GetCurrentDirectory( ( MAX_STRING_LENGTH * 2 ) , lpszPathName ) ) { SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; } if( _T( '\\' ) != lpszPathName[ StringLength( lpszPathName, 0 ) - 1 ] ) { // String should contain a '\' in end. EX: "c:\windows\"
StringConcat( lpszPathName, _T( "\\" ), MAX_STRING_LENGTH * 2 ); }
// Set only if '@relpath' is specified in the command to execute.
if( NULL != FindSubString( lpszCommand , RELATIVE_PATH ) ) { dwLength = StringLength( lpszPathName, 0 ) + EXTRA_MEM; // Allocate memory to global variable .
ASSIGN_MEMORY( g_lpszStartPath , WCHAR , dwLength ) ; // Check whether memory allocation was successfully .
if( NULL == g_lpszStartPath ) { // Memory Allocation Failed .
DISPLAY_MEMORY_ALLOC_FAIL() ; return FALSE ; }
// Copied path to global variable .
StringCopy( g_lpszStartPath , lpszPathName, dwLength ) ; } return TRUE; }
BOOL CheckDateLocalized( LPWSTR lpwszDate, DWORD* pdwDateFormat, LPWSTR lpszDateSep ) /*++
Routine Description:
This function converts a date in accordance with locale to mm/dd/yyyy format. If date is in {+|-}dd format then some validation is also done.
Arguments:
[ IN ] lpwszDate - Contains date. [ OUT ] pdwDateFormat - Contains date format being used by current locale. [ OUT ] lpszDateSep - Contains seperator.
Return value:
Return FALSE if date does not have the separator as locale settings. Return TRUE if date is converted to MM/dd/yyyy format successfully.
--*/ { WCHAR wszString[ MAX_STRING_LENGTH ]; LCID lcidCurrentUserLocale = 0 ; // Stores current user locale.
BOOL bLocaleChanged = TRUE; LPWSTR lpTemp = NULL; LPWSTR lpTemp1 = NULL; DWORD dwInteger = 0 ;
if((( NULL == lpwszDate ) && ( NULL == pdwDateFormat ) && ( NULL == lpszDateSep )) || (( NULL == lpwszDate ) && ( NULL != pdwDateFormat ) && ( NULL == lpszDateSep )) || (( NULL == lpwszDate ) && ( NULL == pdwDateFormat ) && ( NULL != lpszDateSep ))) { SetLastError( ERROR_INVALID_PARAMETER ); SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; }
SecureZeroMemory( wszString, MAX_STRING_LENGTH * sizeof( WCHAR ) );
// verify whether console supports the current locale 100% or not
lcidCurrentUserLocale = GetSupportedUserLocale( &bLocaleChanged ) ;
// Get date seperator.
dwInteger = GetLocaleInfo( lcidCurrentUserLocale, LOCALE_SDATE, wszString, SIZE_OF_ARRAY( wszString ));
if( 0 == dwInteger ) { SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; }
// Date seperator is obtained.
if( NULL != lpszDateSep ) { // Get date seperator.
// Date seperator
StringCopy( lpszDateSep, wszString, 5 ); } else { // Date seperator is known.
// Check whether the string contains any
lpTemp = FindSubString( ( lpwszDate + 1 ), wszString ); // Replace locale date seperator by '/'.
if( NULL == lpTemp ) { // Check whether only number is present or some string is present.
if( FALSE == IsNumeric( lpwszDate, 10, TRUE ) ) { DISPLAY_INVALID_DATE(); return FALSE ; } return TRUE; } else { *lpTemp = _T( '/' ); if( 1 < StringLength( wszString, 0 ) ) { StringCopy( ( lpTemp + 1 ), ( lpTemp + StringLength( wszString, 0 ) ), 1 + StringLength( ( lpTemp + StringLength( wszString, 0 ) ), 0 ) ); }
lpTemp1 = FindSubString( lpTemp, wszString ); if( NULL == lpTemp1 ) { DISPLAY_INVALID_DATE(); return FALSE ; } else { *lpTemp1 = _T( '/' ); if( 1 < StringLength( wszString, 0 ) ) { StringCopy( ( lpTemp1 + 1 ), ( lpTemp1 + StringLength( wszString, 0 ) ), 1 + StringLength( ( lpTemp1 + StringLength( wszString, 0 ) ), 0 ) ); } } } }
// Get type of date format. 'wszString' should not contain characters more than 80.
dwInteger = GetLocaleInfo( lcidCurrentUserLocale, LOCALE_IDATE, wszString, SIZE_OF_ARRAY( wszString ));
if( 0 == dwInteger ) { SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; } // Jump to type of date format.
switch( wszString[ 0 ] ) { case _T( '0' ): dwInteger = GetLocaleInfo( lcidCurrentUserLocale, LOCALE_SSHORTDATE, wszString, SIZE_OF_ARRAY( wszString )); if( 0 == dwInteger ) { SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; } lpTemp = StrPBrkW( wszString, L"dy" );
if( NULL == lpTemp ) { DISPLAY_INVALID_DATE(); return FALSE ; }
if( _T( 'y' ) == lpTemp[ 0 ] ) { if( NULL != pdwDateFormat ) { *pdwDateFormat = 1; return TRUE; }
// Will work only for MM/yyyy/dd.
StringCopy( wszString, lpwszDate, MAX_STRING_LENGTH ); // Get dd from MM/yyyy/dd.
lpTemp = StrRChrW( lpwszDate, NULL, L'/' ); lpTemp1 = FindAChar( lpwszDate, _T( '/' ) ); if( ( NULL == lpTemp ) || ( NULL == lpTemp1 ) ) { DISPLAY_INVALID_DATE(); return FALSE ; }
StringCopy( ( lpTemp1 + 1 ),( lpTemp + 1 ), 1 + StringLength( ( lpTemp1 + 1 ), 0 ) );
StringConcat( lpwszDate, _T( "/" ), MAX_STRING_LENGTH );
// Now date string is MM/dd/
lpTemp = StrRChrW( wszString, NULL, _T( '/' ) ); if( NULL == lpTemp ) { DISPLAY_INVALID_DATE(); return FALSE ; } *lpTemp = _T( '\0' ); // Copy 'yyyy'.
dwInteger = StringLength( wszString, 0 ); StringConcat( lpwszDate, ( wszString + dwInteger - 4 ), MAX_STRING_LENGTH ); } else { if( NULL != pdwDateFormat ) { *pdwDateFormat = 0; return TRUE; } } return TRUE;
case _T( '1' ): dwInteger = GetLocaleInfo( lcidCurrentUserLocale, LOCALE_SSHORTDATE, wszString, SIZE_OF_ARRAY( wszString ));
if( 0 == dwInteger ) { SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; } lpTemp = StrPBrkW( wszString, L"My" );
if( NULL == lpTemp ) { DISPLAY_INVALID_DATE(); return FALSE ; }
if( _T( 'M' ) == lpTemp[ 0 ] ) { if( NULL != pdwDateFormat ) { *pdwDateFormat = 2; return TRUE; }
// Will work only for dd/MM/yyyy
StringCopy( wszString, lpwszDate, MAX_STRING_LENGTH ); // Get
// Pointing at "yyyy"
lpTemp = StrRChrW( wszString, NULL, _T( '/' ) ); // Pointing at "MM"
lpTemp1 = FindAChar( wszString, _T( '/' ) ); if( ( NULL == lpTemp ) || ( NULL == lpTemp1 ) ) { DISPLAY_INVALID_DATE(); return FALSE ; } StringCopy( ( lpwszDate + 1 ), ( lpTemp1 + 1 ), MAX_STRING_LENGTH - 1 );
StringCopy( lpTemp1, lpTemp, MAX_STRING_LENGTH - (DWORD)(DWORD_PTR)(lpTemp1 - wszString)); lpTemp = FindAChar( lpwszDate, _T( '/' ) ); if( NULL == lpTemp ) { DISPLAY_INVALID_DATE(); return FALSE ; }
StringCopy( ( lpTemp + 1 ), ( wszString + 1 ), MAX_STRING_LENGTH - (DWORD)(DWORD_PTR)(lpTemp - lpwszDate)); } else { if( NULL != pdwDateFormat ) { *pdwDateFormat = 3; return TRUE; }
// Will work only for dd/yyyy/MM
StringCopy( wszString, lpwszDate, MAX_STRING_LENGTH ); // Get MM.
lpTemp = StrRChr( wszString, NULL, _T( '/' ) ); if( NULL == lpTemp ) { DISPLAY_INVALID_DATE(); return FALSE ; } StringCopy( ( lpwszDate + 1 ), ( lpTemp + 1 ), MAX_STRING_LENGTH - 1 ); *lpTemp = _T( '\0' ); // Date string is MM.
StringConcat( lpwszDate , _T( "/" ), MAX_STRING_LENGTH ); StringConcat( lpwszDate, ( wszString + 1 ), MAX_STRING_LENGTH ); } return TRUE;
case _T( '2' ): dwInteger = GetLocaleInfo( lcidCurrentUserLocale, LOCALE_SSHORTDATE, wszString, SIZE_OF_ARRAY( wszString ));
if( 0 == dwInteger ) { SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; }
lpTemp = StrPBrkW( wszString, L"Md" );
if( NULL == lpTemp ) { DISPLAY_INVALID_DATE(); return FALSE ; } // Make modification to the date string.
if( _T( 'd' ) == lpTemp[ 0 ] ) { if( NULL != pdwDateFormat ) { *pdwDateFormat = 4; return TRUE; }
// Will work only for yyyy/dd/MM.
StringCopy( wszString, lpwszDate, MAX_STRING_LENGTH ); // Get MM
lpTemp = StrRChr( wszString, NULL, _T( '/' ) ); if( NULL == lpTemp ) { DISPLAY_INVALID_DATE(); return FALSE ; } StringCopy( ( lpwszDate + 1 ), ( lpTemp + 1 ), MAX_STRING_LENGTH -1 ); StringConcat( ( lpwszDate + 1 ), _T( "/" ), MAX_STRING_LENGTH ); *lpTemp = _T( '\0' ) ; // Get dd, date string contains "yyyy/dd" only.
lpTemp = StrRChr( wszString, NULL, _T( '/' ) ); if( NULL == lpTemp ) { DISPLAY_INVALID_DATE(); return FALSE ; } StringConcat( lpwszDate, ( lpTemp + 1 ), MAX_STRING_LENGTH ); StringConcat( ( lpwszDate + 1 ), _T( "/" ), MAX_STRING_LENGTH ); *lpTemp = _T( '\0' ) ; // Get
StringConcat( lpwszDate, ( wszString + 1 ), MAX_STRING_LENGTH ); } else { if( NULL != pdwDateFormat ) { *pdwDateFormat = 5; return TRUE; }
// Will work only for yyyy/MM/dd.
StringCopy( wszString, lpwszDate, MAX_STRING_LENGTH ); StringCopy( lpwszDate + 1, ( wszString + 6 ),MAX_STRING_LENGTH - 1 ); wszString[ 5 ] = _T( '\0' ); StringConcat( lpwszDate, _T( "/" ), MAX_STRING_LENGTH ); StringConcat( lpwszDate, ( wszString + 1 ), MAX_STRING_LENGTH ); } return TRUE;
default: DISPLAY_INVALID_DATE(); return FALSE ; } }
BOOL PatternMatch( IN LPWSTR szPat, IN LPWSTR szFile ) /*++
Routine Description : This routine is used to check whether file is mathced against pattern or not.
[ IN ] szPat : A string variable pattern against which the file name to be matched.
[ IN ] szFile : A pattern string which specifies the file name to be matched.
Return Value : BOOL Returns successfully if function is success other wise return failure. --*/
{ if( ( NULL == szPat ) || ( NULL == szFile ) ) { SetLastError( ERROR_INVALID_PARAMETER ); SaveLastError() ; DISPLAY_GET_REASON() ; return FALSE ; }
// Apply recursive pattern match.
switch( *szPat ) { case '\0': return ( *szFile == L'\0' );
case '?': return ( ( *szFile != L'\0' ) && PatternMatch( szPat + 1, szFile + 1 ) );
case '*': do { if( TRUE == PatternMatch( szPat + 1, szFile ) ) { return TRUE; } } while( *szFile++ ); return FALSE;
default: return ( ( toupper( *szFile ) == toupper( *szPat ) ) && PatternMatch( szPat + 1, szFile + 1 ) ); } }
LPWSTR FindAChar( IN LPWSTR szString, IN WCHAR wCharToFind ) /*++
Routine Description : This routine is used to find a case sensitive character in a string.
[ IN ] szString : String in which to search for a character.
[ IN ] wCharTofind : Char to search for.
Return Value : LPWSTR If found a character then memory location of that character will be returned else NULL is returned. --*/ { if( NULL == szString ) { return NULL; }
return ( StrChrW( szString, wCharToFind ) ); }
LPWSTR FindSubString( IN LPWSTR szString, IN LPWSTR szSubString ) /*++
Routine Description : This routine is used to find a case sensitive substring in a string.
[ IN ] szString : String in which to search for a substring.
[ IN ] szSubString : SubString to search for.
Return Value : LPWSTR If found a character then memory location of that character will be returned else NULL is returned. --*/ { if( ( NULL == szString ) || ( NULL == szSubString ) ) { return NULL; }
return ( StrStrW( szString, szSubString ) ); }
|