git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			286 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			286 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*++
 | |
| 
 | |
| 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;
 | |
| }
 |