| /*++ | |
| Copyright (c) 2004, Intel Corporation | |
| All rights reserved. This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| Module Name: | |
| FileSearch.c | |
| Abstract: | |
| Module used to support file searches on the system. | |
| --*/ | |
| #include <stdio.h> | |
| #include "CommonUtils.h" | |
| #include "FileSearch.h" | |
| #include "UtilsMsgs.h" | |
| // | |
| // Internal file search flag for sanity checks | |
| // | |
| #define FILE_SEARCH_STARTED 0x8000 | |
| #define FILE_SEARCH_INITED 0x4000 | |
| static | |
| BOOLEAN | |
| FileSearchMeetsCriteria ( | |
| FILE_SEARCH_DATA *FSData | |
| ); | |
| /*****************************************************************************/ | |
| STATUS | |
| FileSearchInit ( | |
| FILE_SEARCH_DATA *FSData | |
| ) | |
| { | |
| memset ((char *) FSData, 0, sizeof (FILE_SEARCH_DATA)); | |
| FSData->Handle = INVALID_HANDLE_VALUE; | |
| FSData->FileSearchFlags = FILE_SEARCH_INITED; | |
| FSData->FileName[0] = 0; | |
| return STATUS_SUCCESS; | |
| } | |
| STATUS | |
| FileSearchStart ( | |
| FILE_SEARCH_DATA *FSData, | |
| char *FileMask, | |
| UINT32 SearchFlags | |
| ) | |
| { | |
| BOOLEAN Done; | |
| // | |
| // Save their flags, and set a flag to indicate that they called this | |
| // start function so we can perform extended checking in the other | |
| // routines we have in this module. | |
| // | |
| FSData->FileSearchFlags |= (SearchFlags | FILE_SEARCH_STARTED); | |
| FSData->FileName[0] = 0; | |
| // | |
| // Begin the search | |
| // | |
| FSData->Handle = FindFirstFile (FileMask, &(FSData->FindData)); | |
| if (FSData->Handle == INVALID_HANDLE_VALUE) { | |
| return STATUS_ERROR; | |
| } | |
| // | |
| // Keep looping through until we find a file meeting the caller's | |
| // criteria per the search flags | |
| // | |
| Done = FALSE; | |
| while (!Done) { | |
| // | |
| // If we're done (we found a match) copy the file name found and return | |
| // | |
| Done = FileSearchMeetsCriteria (FSData); | |
| if (Done) { | |
| return STATUS_SUCCESS; | |
| } | |
| // | |
| // Go on to next file | |
| // | |
| if (!FindNextFile (FSData->Handle, &(FSData->FindData))) { | |
| return STATUS_NOT_FOUND; | |
| } | |
| } | |
| // | |
| // Not reached | |
| // | |
| return STATUS_NOT_FOUND; | |
| } | |
| // | |
| // Find the next file meeting their criteria and return it. | |
| // | |
| STATUS | |
| FileSearchFindNext ( | |
| FILE_SEARCH_DATA *FSData | |
| ) | |
| { | |
| BOOLEAN Done; | |
| Done = FALSE; | |
| while (!Done) { | |
| if (!FindNextFile (FSData->Handle, &(FSData->FindData))) { | |
| return STATUS_NOT_FOUND; | |
| } | |
| // | |
| // See if it matches their criteria | |
| // | |
| Done = FileSearchMeetsCriteria (FSData); | |
| if (Done) { | |
| return STATUS_SUCCESS; | |
| } | |
| } | |
| // | |
| // Not reached | |
| // | |
| return STATUS_NOT_FOUND; | |
| } | |
| // | |
| // Perform any cleanup necessary to close down a search | |
| // | |
| STATUS | |
| FileSearchDestroy ( | |
| FILE_SEARCH_DATA *FSData | |
| ) | |
| { | |
| if (FSData->Handle != INVALID_HANDLE_VALUE) { | |
| FindClose (FSData->Handle); | |
| FSData->Handle = INVALID_HANDLE_VALUE; | |
| } | |
| FSData->FileName[0] = 0; | |
| FSData->FileSearchFlags = 0; | |
| return STATUS_SUCCESS; | |
| } | |
| static | |
| BOOLEAN | |
| FileSearchMeetsCriteria ( | |
| FILE_SEARCH_DATA *FSData | |
| ) | |
| { | |
| BOOLEAN Status; | |
| STRING_LIST *StrList; | |
| UINT32 ExtLen; | |
| UINT32 FileNameLen; | |
| Status = FALSE; | |
| // | |
| // First clear the flag indicating this is neither a file or a | |
| // directory. | |
| // | |
| FSData->FileFlags &= ~(FILE_SEARCH_DIR | FILE_SEARCH_FILE); | |
| // | |
| // We found a file. See if it matches the user's search criteria. First | |
| // check for this being a directory, and they want directories, and | |
| // it's not "." and it's not ".." | |
| // | |
| if ((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && | |
| (FSData->FileSearchFlags & FILE_SEARCH_DIR) && | |
| (strcmp (FSData->FindData.cFileName, ".")) && | |
| (strcmp (FSData->FindData.cFileName, "..")) | |
| ) { | |
| // | |
| // Assume we'll make it past this check | |
| // | |
| Status = TRUE; | |
| // | |
| // If they have a list of exclude directories, then check for those | |
| // | |
| StrList = FSData->ExcludeDirs; | |
| while (StrList != NULL) { | |
| if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) { | |
| Status = FALSE; | |
| break; | |
| } | |
| StrList = StrList->Next; | |
| } | |
| // | |
| // If we didn't fail due to excluded directories, then set the dir flag | |
| // | |
| if (Status) { | |
| FSData->FileFlags |= FILE_SEARCH_DIR; | |
| } | |
| // | |
| // Else check for a file, and they want files.... | |
| // | |
| } else if (((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) && | |
| (FSData->FileSearchFlags & FILE_SEARCH_FILE) | |
| ) { | |
| // | |
| // See if it's in our list of excluded files | |
| // | |
| Status = TRUE; | |
| StrList = FSData->ExcludeFiles; | |
| while (StrList != NULL) { | |
| if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) { | |
| Status = FALSE; | |
| break; | |
| } | |
| StrList = StrList->Next; | |
| } | |
| if (Status) { | |
| // | |
| // See if it's in our list of excluded file extensions | |
| // | |
| FileNameLen = strlen (FSData->FindData.cFileName); | |
| StrList = FSData->ExcludeExtensions; | |
| while (StrList != NULL) { | |
| ExtLen = strlen (StrList->Str); | |
| if (stricmp ( | |
| FSData->FindData.cFileName + FileNameLen - ExtLen, | |
| StrList->Str | |
| ) == 0) { | |
| Status = FALSE; | |
| break; | |
| } | |
| StrList = StrList->Next; | |
| } | |
| } | |
| if (Status) { | |
| FSData->FileFlags |= FILE_SEARCH_FILE; | |
| } | |
| } | |
| // | |
| // If it's a match, copy the filename into another field of the structure | |
| // for portability. | |
| // | |
| if (Status) { | |
| strcpy (FSData->FileName, FSData->FindData.cFileName); | |
| } | |
| return Status; | |
| } | |
| // | |
| // Exclude a list of subdirectories. | |
| // | |
| STATUS | |
| FileSearchExcludeDirs ( | |
| FILE_SEARCH_DATA *FSData, | |
| STRING_LIST *StrList | |
| ) | |
| { | |
| FSData->ExcludeDirs = StrList; | |
| return STATUS_SUCCESS; | |
| } | |
| STATUS | |
| FileSearchExcludeFiles ( | |
| FILE_SEARCH_DATA *FSData, | |
| STRING_LIST *StrList | |
| ) | |
| { | |
| FSData->ExcludeFiles = StrList; | |
| return STATUS_SUCCESS; | |
| } | |
| STATUS | |
| FileSearchExcludeExtensions ( | |
| FILE_SEARCH_DATA *FSData, | |
| STRING_LIST *StrList | |
| ) | |
| { | |
| FSData->ExcludeExtensions = StrList; | |
| return STATUS_SUCCESS; | |
| } |