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.
1811 lines
62 KiB
1811 lines
62 KiB
/*++
|
|
|
|
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 ) );
|
|
}
|