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