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