/*++ Copyright (c) Microsoft Corporation. All rights reserved. Module Name: Where.c Abstract: Lists the files that matches Syntax: ------ WHERE [/R dir] [/Q] [/F] [/T] pattern... Author: Revision History: 25-Jan-2000 a-anurag in the 'found' function changed the printf format of the year in the date from %d to %02d and did ptm->tm_year%100 to display the right year in 2 digits. 06-Aug-1990 davegi Added check for no arguments 03-Mar-1987 danl Update usage 17-Feb-1987 BW Move strExeType to TOOLS.LIB 18-Jul-1986 DL Add /t 18-Jun-1986 DL handle *. properly Search current directory if no env specified 17-Jun-1986 DL Do look4match on Recurse and wildcards 16-Jun-1986 DL Add wild cards to $FOO:BAR, added /q 1-Jun-1986 DL Add /r, fix Match to handle pat ending with '*' 27-May-1986 MZ Add *NIX searching. 30-Jan-1998 ravisp Add /Q 02-Jul-2001 Wipro Technologies, has modified the tool for localization. /Q switch is changed to /f --*/ #include "pch.h" #include "where.h" #include DWORD _cdecl wmain( IN DWORD argc, IN LPCWSTR argv[] ) /*++ Routine Description : This is the main routine which calls other routines for processing the options and finding the files. [ IN ] argc : A DWORD variable having the argument count. [ IN ] argv : An array of constant strings of command line options. Return Value : DWORD Returns successfully if function is success otherwise return failure. --*/ { DWORD i = 0; DWORD dwStatus = 0; DWORD dwCount = 0; BOOL bQuiet = FALSE; BOOL bQuote = FALSE; BOOL bTime = FALSE; BOOL bUsage = FALSE; LPWSTR wszRecursive = NULL; LPWSTR wszPattern = NULL; TARRAY szPatternInArr = NULL; TARRAY szPatternArr = NULL; DWORD dw = 0; BOOL bFound = FALSE; LPWSTR szTemp = NULL; WCHAR *szTempPattern = NULL; BOOL *bMatched = NULL; if( argc<=1 ) { SetLastError( (DWORD)MK_E_SYNTAX ); SaveLastError(); ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); ShowMessage( stderr, GetResString( IDS_HELP_MESSAGE ) ); ReleaseGlobals(); return( EXIT_FAILURE_2 ); } //this error mode is set for not to display messagebox when device is not ready SetErrorMode( SEM_FAILCRITICALERRORS); dwStatus = ProcessOptions( argc, argv, &wszRecursive, &bQuiet, &bQuote, &bTime, &szPatternInArr, &bUsage); if( EXIT_FAILURE == dwStatus ) { DestroyDynamicArray(&szPatternInArr ); FreeMemory((LPVOID *) &wszRecursive ); ReleaseGlobals(); return( EXIT_FAILURE_2 ); } if( TRUE == bUsage ) { DisplayHelpUsage(); DestroyDynamicArray(&szPatternInArr ); FreeMemory((LPVOID *) &wszRecursive ); ReleaseGlobals(); return(EXIT_SUCCESS); } szPatternArr = CreateDynamicArray(); if( NULL == szPatternArr ) { SetLastError( ERROR_OUTOFMEMORY ); SaveLastError(); ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); DestroyDynamicArray(&szPatternInArr); FreeMemory((LPVOID *) &wszRecursive ); ReleaseGlobals(); return( EXIT_FAILURE_2 ); } //check for invalid slashes dwCount = DynArrayGetCount( szPatternInArr ); //fill bMatched array bMatched = (BOOL *) AllocateMemory( (dwCount+1)*sizeof(BOOL) ); if( NULL == bMatched ) { ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); DestroyDynamicArray(&szPatternInArr); DestroyDynamicArray(&szPatternArr ); FreeMemory((LPVOID *) &wszRecursive ); ReleaseGlobals(); return( EXIT_FAILURE_2 ); } for(dw=0;dwnext && dirTemp) dirTemp = dirTemp->next; dirTemp->next = dir; dir = dirNextLevel; dirNextLevel = NULL; dirTemp=NULL; } bStatus = Pop( &dir, &szDirectoryName ); }while( bStatus ); FreeMemory((LPVOID *) &lpszTempPattern ); FreeMemory((LPVOID *) &szTempPathExt ); FreeMemory((LPVOID *) &szPathExt ); FreeList(dir); if( !bFound ) { FreeMemory((LPVOID *) &bMatched ); return( EXIT_FAILURE ); } //display error messages for all patterns which dont have any matched files dwCount = DynArrayGetCount( PatternArr ); for( dw=0;dwszDirectoryName = (LPWSTR) AllocateMemory( (StringLengthW(szPath, 0)+10)*sizeof(WCHAR) ); if( NULL == tmp->szDirectoryName ) { return( EXIT_FAILURE ); } StringCopy(tmp->szDirectoryName, szPath, SIZE_OF_ARRAY_IN_CHARS(tmp->szDirectoryName) ); tmp->next = NULL; if( NULL == *dir ) //if stack is empty { *dir = tmp; return EXIT_SUCCESS; } for( tempnode=*dir;tempnode->next!=NULL;tempnode=tempnode->next); tempnode->next = tmp; return EXIT_SUCCESS; } BOOL Pop( IN DIRECTORY *dir, OUT LPWSTR *lpszDirectory) /* Routine Description : It will pop the directory name from the stack [ IN ] dir : Pointer to a list of files [ IN ] lpszDirectory : A pointer to a string will have the next directory in the list Return Value : DWORD Returns TRUE if list is not NULL, returns FALSE otherwise */ { DIRECTORY tmp = *dir; if( NULL == tmp ) //if there are no elements in stack return FALSE; *lpszDirectory = (LPWSTR )AllocateMemory( (StringLengthW( tmp->szDirectoryName, 0 )+10)*sizeof(WCHAR) ); if( NULL == *lpszDirectory ) { return( EXIT_FAILURE ); } StringCopy( *lpszDirectory, tmp->szDirectoryName, SIZE_OF_ARRAY_IN_CHARS(*lpszDirectory) ); *dir = tmp->next; //move to the next element FreeMemory((LPVOID *) &tmp->szDirectoryName); FreeMemory((LPVOID *) &tmp); return( TRUE ); } DWORD GetFileDateTimeandSize( LPWSTR wszFileName, DWORD *dwSize, LPWSTR wszDate, LPWSTR wszTime ) /*++ Routine Description : This function gets the date and time according to system locale. --*/ { HANDLE hFile; FILETIME fileLocalTime= {0,0}; SYSTEMTIME sysTime = {0,0,0,0,0,0,0,0}; LCID lcid; BOOL bLocaleChanged = FALSE; DWORD wBuffSize = 0; BY_HANDLE_FILE_INFORMATION FileInfo; struct _stat sbuf; struct tm *ptm; hFile = CreateFile( wszFileName, 0 ,FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS , NULL ); if ( INVALID_HANDLE_VALUE == hFile ) { if ( _wstat(wszFileName, &sbuf) != 0 ) return EXIT_FAILURE; ptm = localtime (&sbuf.st_mtime); if( NULL == ptm ) return EXIT_FAILURE; *dwSize = sbuf.st_size; sysTime.wYear = (WORD) ptm->tm_year+1900; sysTime.wMonth = (WORD)ptm->tm_mon+1; sysTime.wDayOfWeek = (WORD)ptm->tm_wday; sysTime.wDay = (WORD)ptm->tm_mday; sysTime.wHour = (WORD)ptm->tm_hour; sysTime.wMinute = (WORD)ptm->tm_min; sysTime.wSecond = (WORD)ptm->tm_sec; sysTime.wMilliseconds = (WORD)0; } else { *dwSize = GetFileSize( hFile, NULL ); if (FALSE == GetFileInformationByHandle( hFile, &FileInfo ) ) { CloseHandle (hFile); return EXIT_FAILURE; } if (FALSE == CloseHandle (hFile)) return EXIT_FAILURE; // get the creation time if ( FALSE == FileTimeToLocalFileTime ( &FileInfo.ftLastWriteTime, &fileLocalTime ) ) return EXIT_FAILURE; // get the creation time if ( FALSE == FileTimeToSystemTime ( &fileLocalTime, &sysTime ) ) return EXIT_FAILURE; } // verify whether console supports the current locale fully or not lcid = GetSupportedUserLocale( &bLocaleChanged ); //Retrieve the Date wBuffSize = GetDateFormat( lcid, 0, &sysTime, (( bLocaleChanged == TRUE ) ? L"MM/dd/yyyy" : NULL), wszDate, MAX_RES_STRING ); if( 0 == wBuffSize ) { SaveLastError(); return EXIT_FAILURE; } wBuffSize = GetTimeFormat( lcid, 0, &sysTime, (( bLocaleChanged == TRUE ) ? L"HH:mm:ss" : NULL), wszTime, MAX_RES_STRING ); if( 0 == wBuffSize ) return EXIT_FAILURE; return EXIT_SUCCESS; } DWORD DisplayHelpUsage() /*++ Routine Description : This routine is to display the help usage. Return Value : DWORD Returns success. --*/ { DWORD dw = 0; for(dw=IDS_MAIN_HELP_BEGIN;dw<=IDS_MAIN_HELP_END;dw++) ShowMessage(stdout, GetResString(dw) ); return( EXIT_SUCCESS); } DWORD ProcessOptions( IN DWORD argc, IN LPCWSTR argv[], OUT LPWSTR *lpszRecursive, OUT PBOOL pbQuiet, OUT PBOOL pbQuote, OUT PBOOL pbTime, OUT PTARRAY pArrVal, OUT PBOOL pbUsage ) /*++ Routine Description : Function used to process the main options Arguments: [ in ] argc : Number of command line arguments [ in ] argv : Array containing command line arguments [ out ] lpszRecursive : A string varibles returns recursive directory if specified. [ out ] pbQuiet : A pointer to boolean variable returns TRUE if Quiet option is specified. [ out ] pbQuote : A pointer to boolean variable returns TRUE if Quote option is specified. [ out ] pbTime : A pointer to boolean variable returns TRUE if Times option is specified. [ out ] pArrVal : A pointer to dynamic array returns patterns specified as default options. [ out ] pbUsage : A pointer to boolean variable returns TRUE if Usage option is specified. Return Type : DWORD A Integer value indicating EXIT_SUCCESS on successful parsing of command line else EXIT_FAILURE --*/ { DWORD dwAttr = 0; LPWSTR szFilePart = NULL; WCHAR szBuffer[MAX_MAX_PATH] = NULL_STRING; WCHAR *szBuffer1 = NULL; LPWSTR szLongPath = NULL; LPWSTR szFullPath = NULL; DWORD dwSize = 0; TCMDPARSER2 cmdOptions[6]; //Fill the structure for recursive option StringCopyA(cmdOptions[OI_RECURSIVE].szSignature, "PARSER2", 8 ); cmdOptions[OI_RECURSIVE].dwType = CP_TYPE_TEXT; cmdOptions[OI_RECURSIVE].dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL; // | CP_VALUE_MANDATORY; cmdOptions[OI_RECURSIVE].dwCount = 1; cmdOptions[OI_RECURSIVE].dwActuals = 0; cmdOptions[OI_RECURSIVE].pwszOptions = CMDOPTION_RECURSIVE; cmdOptions[OI_RECURSIVE].pwszFriendlyName = NULL; cmdOptions[OI_RECURSIVE].pwszValues = NULL; cmdOptions[OI_RECURSIVE].pValue = NULL; cmdOptions[OI_RECURSIVE].dwLength = 0; cmdOptions[OI_RECURSIVE].pFunction = NULL; cmdOptions[OI_RECURSIVE].pFunctionData = NULL; cmdOptions[OI_RECURSIVE].dwReserved = 0; cmdOptions[OI_RECURSIVE].pReserved1 = NULL; cmdOptions[OI_RECURSIVE].pReserved2 = NULL; cmdOptions[OI_RECURSIVE].pReserved3 = NULL; //Fill the structure for Quite option StringCopyA(cmdOptions[OI_QUITE].szSignature, "PARSER2", 8 ); cmdOptions[OI_QUITE].dwType = CP_TYPE_BOOLEAN; cmdOptions[OI_QUITE].dwFlags = 0; cmdOptions[OI_QUITE].dwCount = 1; cmdOptions[OI_QUITE].dwActuals = 0; cmdOptions[OI_QUITE].pwszOptions = CMDOPTION_QUITE; cmdOptions[OI_QUITE].pwszFriendlyName = NULL; cmdOptions[OI_QUITE].pwszValues = NULL; cmdOptions[OI_QUITE].pValue = pbQuiet; cmdOptions[OI_QUITE].dwLength = 0; cmdOptions[OI_QUITE].pFunction = NULL; cmdOptions[OI_QUITE].pFunctionData = NULL; cmdOptions[OI_QUITE].dwReserved = 0; cmdOptions[OI_QUITE].pReserved1 = NULL; cmdOptions[OI_QUITE].pReserved2 = NULL; cmdOptions[OI_QUITE].pReserved3 = NULL; //Fill the structure for Quote option StringCopyA(cmdOptions[OI_QUOTE].szSignature, "PARSER2", 8 ); cmdOptions[OI_QUOTE].dwType = CP_TYPE_BOOLEAN; cmdOptions[OI_QUOTE].dwFlags = 0; cmdOptions[OI_QUOTE].dwCount = 1; cmdOptions[OI_QUOTE].dwActuals = 0; cmdOptions[OI_QUOTE].pwszOptions = CMDOPTION_QUOTE; cmdOptions[OI_QUOTE].pwszFriendlyName = NULL; cmdOptions[OI_QUOTE].pwszValues = NULL; cmdOptions[OI_QUOTE].pValue = pbQuote; cmdOptions[OI_QUOTE].dwLength = 0; cmdOptions[OI_QUOTE].pFunction = NULL; cmdOptions[OI_QUOTE].pFunctionData = NULL; cmdOptions[OI_QUOTE].dwReserved = 0; cmdOptions[OI_QUOTE].pReserved1 = NULL; cmdOptions[OI_QUOTE].pReserved2 = NULL; cmdOptions[OI_QUOTE].pReserved3 = NULL; //Fill the structure for Quite option StringCopyA(cmdOptions[OI_TIME].szSignature, "PARSER2", 8 ); cmdOptions[OI_TIME].dwType = CP_TYPE_BOOLEAN; cmdOptions[OI_TIME].dwFlags = 0; cmdOptions[OI_TIME].dwCount = 1; cmdOptions[OI_TIME].dwActuals = 0; cmdOptions[OI_TIME].pwszOptions = CMDOPTION_TIME; cmdOptions[OI_TIME].pwszFriendlyName = NULL; cmdOptions[OI_TIME].pwszValues = NULL; cmdOptions[OI_TIME].pValue = pbTime; cmdOptions[OI_TIME].dwLength = 0; cmdOptions[OI_TIME].pFunction = NULL; cmdOptions[OI_TIME].pFunctionData = NULL; cmdOptions[OI_TIME].dwReserved = 0; cmdOptions[OI_TIME].pReserved1 = NULL; cmdOptions[OI_TIME].pReserved2 = NULL; cmdOptions[OI_TIME].pReserved3 = NULL; //Fill the structure for Quite option StringCopyA(cmdOptions[OI_USAGE].szSignature, "PARSER2", 8 ); cmdOptions[OI_USAGE].dwType = CP_TYPE_BOOLEAN; cmdOptions[OI_USAGE].dwFlags = CP2_USAGE; cmdOptions[OI_USAGE].dwCount = 1; cmdOptions[OI_USAGE].dwActuals = 0; cmdOptions[OI_USAGE].pwszOptions = CMDOPTION_USAGE; cmdOptions[OI_USAGE].pwszFriendlyName = NULL; cmdOptions[OI_USAGE].pwszValues = NULL; cmdOptions[OI_USAGE].pValue = pbUsage; cmdOptions[OI_USAGE].dwLength = 0; cmdOptions[OI_USAGE].pFunction = NULL; cmdOptions[OI_USAGE].pFunctionData = NULL; cmdOptions[OI_USAGE].dwReserved = 0; cmdOptions[OI_USAGE].pReserved1 = NULL; cmdOptions[OI_USAGE].pReserved2 = NULL; cmdOptions[OI_USAGE].pReserved3 = NULL; StringCopyA(cmdOptions[OI_DEFAULT].szSignature, "PARSER2", 8 ); cmdOptions[OI_DEFAULT].dwType = CP_TYPE_TEXT; cmdOptions[OI_DEFAULT].dwFlags =CP2_DEFAULT | CP2_MANDATORY | CP2_VALUE_MASK | CP2_MODE_ARRAY; cmdOptions[OI_DEFAULT].dwCount = 0; cmdOptions[OI_DEFAULT].dwActuals = 0; cmdOptions[OI_DEFAULT].pwszOptions = CMDOPTION_DEFAULT; cmdOptions[OI_DEFAULT].pwszFriendlyName = NULL; cmdOptions[OI_DEFAULT].pwszValues = NULL; cmdOptions[OI_DEFAULT].pValue = pArrVal; cmdOptions[OI_DEFAULT].dwLength = 0; cmdOptions[OI_DEFAULT].pFunction = NULL; cmdOptions[OI_DEFAULT].pFunctionData = NULL; cmdOptions[OI_DEFAULT].dwReserved = 0; cmdOptions[OI_DEFAULT].pReserved1 = NULL; cmdOptions[OI_DEFAULT].pReserved2 = NULL; cmdOptions[OI_DEFAULT].pReserved3 = NULL; *pArrVal=CreateDynamicArray(); if( NULL == *pArrVal ) { SetLastError( ERROR_OUTOFMEMORY ); SaveLastError(); ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); return( EXIT_FAILURE ); } //process the command line options and display error if it fails cmdOptions[OI_DEFAULT].pValue = pArrVal; if( DoParseParam2( argc, argv, -1, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) == FALSE ) { ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); return( EXIT_FAILURE ); } *lpszRecursive = cmdOptions[OI_RECURSIVE].pValue; //if usage specified with any other value display error and return with failure if( ( TRUE == *pbUsage ) && ( argc > 2 ) ) { SetLastError( (DWORD)MK_E_SYNTAX ); SaveLastError(); ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); ShowMessage( stderr, GetResString( IDS_HELP_MESSAGE ) ); return( EXIT_FAILURE ); } if( TRUE == *pbUsage ) return( EXIT_SUCCESS); StrTrim( *lpszRecursive, L" " ); if( 0 == StringLengthW(*lpszRecursive, 0) && cmdOptions[OI_RECURSIVE].dwActuals !=0 ) { ShowMessage( stderr, GetResString(IDS_NO_RECURSIVE) ); return( EXIT_FAILURE ); } //check for invalid characters in the directory name if ( (*lpszRecursive != NULL) && (szFilePart = wcspbrk(*lpszRecursive, INVALID_DIRECTORY_CHARACTERS ))!=NULL ) { ShowMessage( stderr, GetResString(IDS_INVALID_DIRECTORY_SPECIFIED) ); return( EXIT_FAILURE ); } //if recursive is specified check whether the given path is //a true directory or not. if( StringLengthW(*lpszRecursive, 0) != 0) { szBuffer1 = (LPWSTR) AllocateMemory( (StringLengthW(*lpszRecursive, 0)+10)*sizeof(WCHAR) ); if( NULL == szBuffer1 ) { ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); return EXIT_FAILURE; } //place a copy of recursive directory name into a temporary variable to check later for consequtive dots StringCopy( szBuffer1, *lpszRecursive, SIZE_OF_ARRAY_IN_CHARS(szBuffer1) ); //get the full path name of directory dwSize=GetFullPathName(*lpszRecursive, 0, szFullPath, &szFilePart ); if( dwSize != 0 ) { szFullPath = (WCHAR *) AllocateMemory( (dwSize+10)*sizeof(WCHAR) ); if( NULL == szFullPath ) { ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); FreeMemory((LPVOID *) &szBuffer1); return( EXIT_FAILURE ); } if( FALSE == GetFullPathName(*lpszRecursive, dwSize, szFullPath, &szFilePart ) ) { SaveLastError(); ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); FreeMemory((LPVOID *) &szBuffer1); return EXIT_FAILURE; } } else { SaveLastError(); ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); return EXIT_FAILURE; } //get the long path name dwSize = GetLongPathName( szFullPath, szLongPath, 0 ); if( dwSize == 0 ) { SaveLastError(); ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); FreeMemory((LPVOID *) &szBuffer1 ); FreeMemory((LPVOID *) &szFullPath); return( EXIT_FAILURE ); } szLongPath = (WCHAR *) AllocateMemory( (dwSize+10)*sizeof(WCHAR) ); if( NULL == szLongPath ) { ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); FreeMemory((LPVOID *) &szBuffer1 ); FreeMemory((LPVOID *) &szFullPath); return( EXIT_FAILURE ); } if( FALSE == GetLongPathName( szFullPath, szLongPath, dwSize+5 ) ) { ShowMessage(stderr,GetResString(IDS_INVALID_DIRECTORY_SPECIFIED)); FreeMemory((LPVOID *) &szBuffer1 ); FreeMemory((LPVOID *) &szFullPath); FreeMemory((LPVOID *) &szLongPath); return EXIT_FAILURE; } else { FreeMemory((LPVOID *) &(*lpszRecursive) ); *lpszRecursive = (LPWSTR ) AllocateMemory( (StringLengthW(szLongPath, 0)+10)*sizeof(WCHAR) ); if( NULL == *lpszRecursive ) { ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); FreeMemory((LPVOID *) &szBuffer1 ); FreeMemory((LPVOID *) &szFullPath); FreeMemory((LPVOID *) &szLongPath); return( EXIT_FAILURE ); } StringCopy( *lpszRecursive, szLongPath, SIZE_OF_ARRAY_IN_CHARS(*lpszRecursive) ); } dwAttr = GetFileAttributes( *lpszRecursive); if( -1 == dwAttr ) { SaveLastError(); ShowMessageEx( stderr, 2, TRUE, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() ); FreeMemory((LPVOID *) &szBuffer1 ); FreeMemory((LPVOID *) &szFullPath); FreeMemory((LPVOID *) &szLongPath); return EXIT_FAILURE; } if( !(dwAttr & FILE_ATTRIBUTE_DIRECTORY) ) { ShowMessage(stderr,GetResString(IDS_INVALID_DIRECTORY_SPECIFIED)); FreeMemory((LPVOID *) &szBuffer1 ); FreeMemory((LPVOID *) &szFullPath); FreeMemory((LPVOID *) &szLongPath); return EXIT_FAILURE; } //check if current directory is specified by more than two dots GetCurrentDirectory(MAX_MAX_PATH, szBuffer ); StringConcat( szBuffer, L"\\", MAX_MAX_PATH ); if( StringCompare(szBuffer, *lpszRecursive, TRUE, 0) == 0 && (szFilePart=(LPWSTR)FindString( szBuffer1, L"...", 0) )!= NULL ) { ShowMessage(stderr,GetResString(IDS_INVALID_DIRECTORY_SPECIFIED)); FreeMemory((LPVOID *) &szBuffer1 ); FreeMemory((LPVOID *) &szFullPath); FreeMemory((LPVOID *) &szLongPath); return EXIT_FAILURE; } } return( EXIT_SUCCESS ); } LPWSTR DivideToken( LPTSTR szString ) /*++ Routine Description : Function used to divide the string into tokens delimited by quotes or space Arguments: [ in ] szString : An LPTSTR string which is to parsed for quotes and spaces. Return Type : LPWSTR Returns the token upon successful, NULL otherwise --*/ { static WCHAR* str=NULL; WCHAR* szTemp=NULL; if( szString ) str = szString; szTemp = str; while( *str!=_T('*') && *str ) str++; if( *str ) { *str=_T('\0'); str++; } while( *str==_T('*') && *str ) str++; if( szTemp[0] ) return (szTemp ); else return( NULL ); } DWORD FreeList( DIRECTORY dir ) /*++ Routine Description : Function is used to free the linked list Arguments: [ in ] *dir : pointer to DIRECTORY list Return Type : LPWSTR Returns the EXIT_SUCCESS successful, EXIT_FAILURE otherwise --*/ { DIRECTORY temp; for( temp=dir; dir; temp=dir->next ) { FreeMemory( (LPVOID *)&temp->szDirectoryName ); FreeMemory((LPVOID*) &temp ); } return EXIT_SUCCESS; }