• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
FileSearchInit(FILE_SEARCH_DATA * FSData)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
FileSearchStart(FILE_SEARCH_DATA * FSData,char * FileMask,UINT32 SearchFlags)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
FileSearchFindNext(FILE_SEARCH_DATA * FSData)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
FileSearchDestroy(FILE_SEARCH_DATA * FSData)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
FileSearchMeetsCriteria(FILE_SEARCH_DATA * FSData)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
FileSearchExcludeDirs(FILE_SEARCH_DATA * FSData,STRING_LIST * StrList)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
FileSearchExcludeFiles(FILE_SEARCH_DATA * FSData,STRING_LIST * StrList)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
FileSearchExcludeExtensions(FILE_SEARCH_DATA * FSData,STRING_LIST * StrList)278 FileSearchExcludeExtensions (
279   FILE_SEARCH_DATA    *FSData,
280   STRING_LIST         *StrList
281   )
282 {
283   FSData->ExcludeExtensions = StrList;
284   return STATUS_SUCCESS;
285 }
286