Home | History | Annotate | Download | only in GuidChk
      1 /*++
      2 
      3 Copyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   FileSearch.c
     15 
     16 Abstract:
     17 
     18   Module used to support file searches on the system.
     19 
     20 --*/
     21 
     22 #include <stdio.h>
     23 
     24 #include "CommonUtils.h"
     25 #include "FileSearch.h"
     26 #include "UtilsMsgs.h"
     27 
     28 //
     29 // Internal file search flag for sanity checks
     30 //
     31 #define FILE_SEARCH_STARTED 0x8000
     32 #define FILE_SEARCH_INITED  0x4000
     33 
     34 static
     35 BOOLEAN
     36 FileSearchMeetsCriteria (
     37   FILE_SEARCH_DATA    *FSData
     38   );
     39 
     40 /*****************************************************************************/
     41 STATUS
     42 FileSearchInit (
     43   FILE_SEARCH_DATA    *FSData
     44   )
     45 {
     46   memset ((char *) FSData, 0, sizeof (FILE_SEARCH_DATA));
     47   FSData->Handle          = INVALID_HANDLE_VALUE;
     48   FSData->FileSearchFlags = FILE_SEARCH_INITED;
     49   FSData->FileName[0]     = 0;
     50   return STATUS_SUCCESS;
     51 }
     52 
     53 STATUS
     54 FileSearchStart (
     55   FILE_SEARCH_DATA    *FSData,
     56   char                *FileMask,
     57   UINT32              SearchFlags
     58   )
     59 {
     60   BOOLEAN Done;
     61 
     62   //
     63   // Save their flags, and set a flag to indicate that they called this
     64   // start function so we can perform extended checking in the other
     65   // routines we have in this module.
     66   //
     67   FSData->FileSearchFlags |= (SearchFlags | FILE_SEARCH_STARTED);
     68   FSData->FileName[0] = 0;
     69 
     70   //
     71   // Begin the search
     72   //
     73   FSData->Handle = FindFirstFile (FileMask, &(FSData->FindData));
     74   if (FSData->Handle == INVALID_HANDLE_VALUE) {
     75     return STATUS_ERROR;
     76   }
     77   //
     78   // Keep looping through until we find a file meeting the caller's
     79   // criteria per the search flags
     80   //
     81   Done = FALSE;
     82   while (!Done) {
     83     //
     84     // If we're done (we found a match) copy the file name found and return
     85     //
     86     Done = FileSearchMeetsCriteria (FSData);
     87     if (Done) {
     88       return STATUS_SUCCESS;
     89     }
     90     //
     91     // Go on to next file
     92     //
     93     if (!FindNextFile (FSData->Handle, &(FSData->FindData))) {
     94       return STATUS_NOT_FOUND;
     95     }
     96   }
     97   //
     98   // Not reached
     99   //
    100   return STATUS_NOT_FOUND;
    101 }
    102 
    103 //
    104 // Find the next file meeting their criteria and return it.
    105 //
    106 STATUS
    107 FileSearchFindNext (
    108   FILE_SEARCH_DATA    *FSData
    109   )
    110 {
    111   BOOLEAN Done;
    112 
    113   Done = FALSE;
    114   while (!Done) {
    115     if (!FindNextFile (FSData->Handle, &(FSData->FindData))) {
    116       return STATUS_NOT_FOUND;
    117     }
    118     //
    119     // See if it matches their criteria
    120     //
    121     Done = FileSearchMeetsCriteria (FSData);
    122     if (Done) {
    123       return STATUS_SUCCESS;
    124     }
    125   }
    126   //
    127   // Not reached
    128   //
    129   return STATUS_NOT_FOUND;
    130 }
    131 //
    132 // Perform any cleanup necessary to close down a search
    133 //
    134 STATUS
    135 FileSearchDestroy (
    136   FILE_SEARCH_DATA    *FSData
    137   )
    138 {
    139   if (FSData->Handle != INVALID_HANDLE_VALUE) {
    140     FindClose (FSData->Handle);
    141     FSData->Handle = INVALID_HANDLE_VALUE;
    142   }
    143 
    144   FSData->FileName[0]     = 0;
    145   FSData->FileSearchFlags = 0;
    146   return STATUS_SUCCESS;
    147 }
    148 
    149 static
    150 BOOLEAN
    151 FileSearchMeetsCriteria (
    152   FILE_SEARCH_DATA    *FSData
    153   )
    154 {
    155   BOOLEAN     Status;
    156   STRING_LIST *StrList;
    157   UINT32      ExtLen;
    158   UINT32      FileNameLen;
    159 
    160   Status = FALSE;
    161 
    162   //
    163   // First clear the flag indicating this is neither a file or a
    164   // directory.
    165   //
    166   FSData->FileFlags &= ~(FILE_SEARCH_DIR | FILE_SEARCH_FILE);
    167 
    168   //
    169   // We found a file. See if it matches the user's search criteria. First
    170   // check for this being a directory, and they want directories, and
    171   // it's not "." and it's not ".."
    172   //
    173   if ((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
    174       (FSData->FileSearchFlags & FILE_SEARCH_DIR) &&
    175       (strcmp (FSData->FindData.cFileName, ".")) &&
    176       (strcmp (FSData->FindData.cFileName, ".."))
    177       ) {
    178     //
    179     // Assume we'll make it past this check
    180     //
    181     Status = TRUE;
    182     //
    183     // If they have a list of exclude directories, then check for those
    184     //
    185     StrList = FSData->ExcludeDirs;
    186     while (StrList != NULL) {
    187       if (_stricmp (FSData->FindData.cFileName, StrList->Str) == 0) {
    188         Status = FALSE;
    189         break;
    190       }
    191 
    192       StrList = StrList->Next;
    193     }
    194     //
    195     // If we didn't fail due to excluded directories, then set the dir flag
    196     //
    197     if (Status) {
    198       FSData->FileFlags |= FILE_SEARCH_DIR;
    199     }
    200     //
    201     // Else check for a file, and they want files....
    202     //
    203   } else if (((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) &&
    204            (FSData->FileSearchFlags & FILE_SEARCH_FILE)
    205           ) {
    206     //
    207     // See if it's in our list of excluded files
    208     //
    209     Status  = TRUE;
    210     StrList = FSData->ExcludeFiles;
    211     while (StrList != NULL) {
    212       if (_stricmp (FSData->FindData.cFileName, StrList->Str) == 0) {
    213         Status = FALSE;
    214         break;
    215       }
    216 
    217       StrList = StrList->Next;
    218     }
    219 
    220     if (Status) {
    221       //
    222       // See if it's in our list of excluded file extensions
    223       //
    224       FileNameLen = strlen (FSData->FindData.cFileName);
    225       StrList     = FSData->ExcludeExtensions;
    226       while (StrList != NULL) {
    227         ExtLen = strlen (StrList->Str);
    228         if (_stricmp (
    229               FSData->FindData.cFileName + FileNameLen - ExtLen,
    230               StrList->Str
    231               ) == 0) {
    232           Status = FALSE;
    233           break;
    234         }
    235 
    236         StrList = StrList->Next;
    237       }
    238     }
    239 
    240     if (Status) {
    241       FSData->FileFlags |= FILE_SEARCH_FILE;
    242     }
    243   }
    244   //
    245   // If it's a match, copy the filename into another field of the structure
    246   // for portability.
    247   //
    248   if (Status) {
    249     strcpy (FSData->FileName, FSData->FindData.cFileName);
    250   }
    251 
    252   return Status;
    253 }
    254 //
    255 // Exclude a list of subdirectories.
    256 //
    257 STATUS
    258 FileSearchExcludeDirs (
    259   FILE_SEARCH_DATA    *FSData,
    260   STRING_LIST         *StrList
    261   )
    262 {
    263   FSData->ExcludeDirs = StrList;
    264   return STATUS_SUCCESS;
    265 }
    266 
    267 STATUS
    268 FileSearchExcludeFiles (
    269   FILE_SEARCH_DATA    *FSData,
    270   STRING_LIST         *StrList
    271   )
    272 {
    273   FSData->ExcludeFiles = StrList;
    274   return STATUS_SUCCESS;
    275 }
    276 
    277 STATUS
    278 FileSearchExcludeExtensions (
    279   FILE_SEARCH_DATA    *FSData,
    280   STRING_LIST         *StrList
    281   )
    282 {
    283   FSData->ExcludeExtensions = StrList;
    284   return STATUS_SUCCESS;
    285 }
    286