|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 /** |
|
20 @file |
|
21 @internalComponent |
|
22 @released |
|
23 */ |
|
24 |
|
25 #include "dirreader.h" |
|
26 #include "e32reader.h" |
|
27 |
|
28 #ifdef __LINUX__ |
|
29 #include <dirent.h> |
|
30 #include <sys/stat.h> |
|
31 #else |
|
32 #include <io.h> |
|
33 #include <direct.h> |
|
34 #endif |
|
35 |
|
36 #define MAXPATHLEN 255 |
|
37 |
|
38 /** |
|
39 Constructor. |
|
40 |
|
41 @internalComponent |
|
42 @released |
|
43 */ |
|
44 DirReader::DirReader(char* aDirName) |
|
45 :ImageReader(aDirName) |
|
46 { |
|
47 } |
|
48 |
|
49 /** |
|
50 Destructor. |
|
51 |
|
52 @internalComponent |
|
53 @released |
|
54 */ |
|
55 DirReader::~DirReader(void) |
|
56 { |
|
57 ExeVsE32ImageMap::iterator begin = iExeVsE32ImageMap.begin(); |
|
58 ExeVsE32ImageMap::iterator end = iExeVsE32ImageMap.end(); |
|
59 while(begin != end) |
|
60 { |
|
61 DELETE(begin->second); |
|
62 ++begin; |
|
63 } |
|
64 iExeVsE32ImageMap.clear(); |
|
65 } |
|
66 |
|
67 /** |
|
68 Function to check whether the node is an executable or not. |
|
69 |
|
70 @internalComponent |
|
71 @released |
|
72 |
|
73 @param aName - Executable name |
|
74 */ |
|
75 bool DirReader::IsExecutable(String aName) |
|
76 { |
|
77 unsigned int strPos = aName.find_last_of('.'); |
|
78 if(strPos != String::npos) |
|
79 { |
|
80 aName = aName.substr(strPos); |
|
81 if(aName.length() <= 4) |
|
82 { |
|
83 ReaderUtil::ToLower(aName); |
|
84 if (aName.find(".exe") != String::npos || aName.find(".dll") != String::npos || |
|
85 aName.find(".prt") != String::npos || aName.find(".nif") != String::npos || |
|
86 aName.find(".pdl") != String::npos || aName.find(".csy") != String::npos || |
|
87 aName.find(".agt") != String::npos || aName.find(".ani") != String::npos || |
|
88 aName.find(".loc") != String::npos || aName.find(".drv") != String::npos || |
|
89 aName.find(".pdd") != String::npos || aName.find(".ldd") != String::npos || |
|
90 aName.find(".tsy") != String::npos || aName.find(".fsy") != String::npos || |
|
91 aName.find(".fxt") != String::npos) |
|
92 { |
|
93 return true; |
|
94 } |
|
95 } |
|
96 } |
|
97 return false; |
|
98 } |
|
99 |
|
100 /** |
|
101 Dummy function to be compatible with other Readers. |
|
102 |
|
103 @internalComponent |
|
104 @released |
|
105 */ |
|
106 void DirReader::ReadImage(void) |
|
107 { |
|
108 } |
|
109 |
|
110 /** |
|
111 Function to |
|
112 1. Preserve the present working directory |
|
113 2. Invoke the function which reads the directory entires recursively. |
|
114 3. Go back to the original directory. |
|
115 |
|
116 @internalComponent |
|
117 @released |
|
118 */ |
|
119 void DirReader::ProcessImage() |
|
120 { |
|
121 char* cwd = new char[MAXPATHLEN]; |
|
122 getcwd(cwd,MAXPATHLEN); |
|
123 ReadDir(iImgFileName); |
|
124 chdir(cwd); |
|
125 if(cwd != NULL) |
|
126 delete [] cwd; |
|
127 cwd = 0; |
|
128 } |
|
129 |
|
130 /** |
|
131 Function to |
|
132 1. Read the directory entires recursively. |
|
133 2. Prepare the ExeVsE32ImageMap. |
|
134 |
|
135 @internalComponent |
|
136 @released |
|
137 |
|
138 @param aPath - Directory name. |
|
139 */ |
|
140 void DirReader::ReadDir(String aPath) |
|
141 { |
|
142 int handle; |
|
143 int retVal = 0; |
|
144 E32Image* e32Image = KNull; |
|
145 |
|
146 #ifdef __LINUX__ |
|
147 DIR* dirEntry = opendir( aPath.c_str()); |
|
148 static struct dirent* dirPtr; |
|
149 while ((dirPtr= readdir(dirEntry)) != NULL) |
|
150 { |
|
151 if ((strcmp(dirPtr->d_name, KChildDir.c_str()) == 0) || |
|
152 (strcmp(dirPtr->d_name, KParentDir.c_str()) == 0)) |
|
153 continue; // current dir || parent dir |
|
154 |
|
155 String fullName( aPath + "/" + dirPtr->d_name ); |
|
156 |
|
157 struct stat fileEntrybuf; |
|
158 int retVal = stat((char*)fullName.c_str(), &fileEntrybuf); |
|
159 if(retVal >= 0) |
|
160 { |
|
161 if(S_ISDIR(fileEntrybuf.st_mode)) //Is Directory? |
|
162 { |
|
163 ReadDir(fullName); |
|
164 } |
|
165 else if(S_ISREG(fileEntrybuf.st_mode)) //Is regular file? |
|
166 { |
|
167 if ((fileEntrybuf.st_blksize > 0) && IsExecutable(String(dirPtr->d_name)) && E32Image::IsE32ImageFile((char*)fullName.c_str())) |
|
168 { |
|
169 iExeAvailable = true; |
|
170 e32Image = new E32Image(); |
|
171 Ifstream inputStream((char*)fullName.c_str(), Ios::binary | Ios::in); |
|
172 inputStream.seekg(0, Ios::end); |
|
173 TUint32 aSz = inputStream.tellg(); |
|
174 inputStream.seekg(0, Ios::beg); |
|
175 e32Image->iFileSize=aSz; |
|
176 e32Image->Adjust(aSz); |
|
177 inputStream >> *e32Image; |
|
178 String exeName(dirPtr->d_name); |
|
179 ReaderUtil::ToLower(exeName); |
|
180 if(iExeVsE32ImageMap.find(exeName) != iExeVsE32ImageMap.end()) |
|
181 { |
|
182 cout << "Warning: "<< "Duplicate entry '" << dirPtr->d_name << " '"<< endl; |
|
183 continue; |
|
184 } |
|
185 iExeVsE32ImageMap.insert(std::make_pair(exeName, e32Image)); |
|
186 iExecutableList.push_back(exeName); |
|
187 } |
|
188 else |
|
189 { |
|
190 cout << "Warning: "<< dirPtr->d_name << " is not a valid E32 executable" << endl; |
|
191 } |
|
192 } |
|
193 } |
|
194 } |
|
195 closedir(dirEntry); |
|
196 |
|
197 #else |
|
198 retVal = chdir(aPath.c_str()); |
|
199 struct _finddata_t finder; |
|
200 handle = _findfirst("*.*", &finder); |
|
201 while (retVal == 0) |
|
202 { |
|
203 if ((strcmp(finder.name, KChildDir.c_str()) == 0) || |
|
204 (strcmp(finder.name, KParentDir.c_str()) == 0) ) // current dir || parent dir |
|
205 { |
|
206 retVal = _findnext(handle, &finder); |
|
207 continue; |
|
208 } |
|
209 |
|
210 if (finder.attrib & _A_SUBDIR) |
|
211 { |
|
212 ReadDir(finder.name); |
|
213 chdir(KParentDir.c_str()); |
|
214 } |
|
215 else |
|
216 { |
|
217 if ((finder.size > 0) && IsExecutable(String(finder.name)) && E32Image::IsE32ImageFile(finder.name)) |
|
218 { |
|
219 e32Image = new E32Image(); |
|
220 Ifstream inputStream(finder.name, Ios::binary | Ios::in); |
|
221 iExeAvailable = true; |
|
222 e32Image->iFileSize=finder.size; |
|
223 e32Image->Adjust(finder.size); |
|
224 inputStream >> *e32Image; |
|
225 String exeName(finder.name); |
|
226 ReaderUtil::ToLower(exeName); |
|
227 if(iExeVsE32ImageMap.find(exeName) != iExeVsE32ImageMap.end()) |
|
228 { |
|
229 cout << "Warning: "<< "Duplicate entry '" << finder.name << " '"<< endl; |
|
230 retVal = _findnext(handle, &finder); |
|
231 continue; |
|
232 } |
|
233 iExeVsE32ImageMap.insert(std::make_pair(exeName, e32Image)); |
|
234 iExecutableList.push_back(exeName); |
|
235 } |
|
236 else |
|
237 { |
|
238 cout << "Warning: "<< finder.name << " is not a valid E32 executable" << endl; |
|
239 } |
|
240 } |
|
241 retVal = _findnext(handle,&finder); |
|
242 } |
|
243 #endif |
|
244 } |
|
245 |
|
246 /** |
|
247 Function to traverse through ExeVsE32ImageMap and prepare ExeVsIdData map. |
|
248 |
|
249 @internalComponent |
|
250 @released |
|
251 */ |
|
252 void DirReader::PrepareExeVsIdMap(void) |
|
253 { |
|
254 ExeVsE32ImageMap::iterator begin = iExeVsE32ImageMap.begin(); |
|
255 ExeVsE32ImageMap::iterator end = iExeVsE32ImageMap.end(); |
|
256 String exeName; |
|
257 E32Image* e32Image = KNull; |
|
258 IdData* id = KNull; |
|
259 if(iExeVsIdData.size() == 0) //Is not already prepared |
|
260 { |
|
261 while(begin != end) |
|
262 { |
|
263 exeName = begin->first; |
|
264 e32Image = begin->second; |
|
265 id = new IdData; |
|
266 id->iUid = e32Image->iOrigHdr->iUid1; |
|
267 id->iDbgFlag = (e32Image->iOrigHdr->iFlags & KImageDebuggable)? true : false; |
|
268 TUint aHeaderFmt = E32ImageHeader::HdrFmtFromFlags(e32Image->iOrigHdr->iFlags); |
|
269 if (aHeaderFmt >= KImageHdrFmt_V) |
|
270 { |
|
271 E32ImageHeaderV* v = e32Image->iHdr; |
|
272 id->iSid = v->iS.iSecureId; |
|
273 id->iVid = v->iS.iVendorId; |
|
274 id->iFileOffset = 0;//Entry read from directory input, has no offset. |
|
275 } |
|
276 iExeVsIdData[exeName] = id; |
|
277 ++begin; |
|
278 } |
|
279 } |
|
280 id = KNull; |
|
281 } |
|
282 |
|
283 /** |
|
284 Function to return ExeVsIdData map. |
|
285 |
|
286 @internalComponent |
|
287 @released |
|
288 |
|
289 @return returns iExeVsIdData. |
|
290 */ |
|
291 const ExeVsIdDataMap& DirReader::GetExeVsIdMap() const |
|
292 { |
|
293 return iExeVsIdData; |
|
294 } |
|
295 |
|
296 /** |
|
297 Function responsible to gather dependencies for all the executables using the container iExeVsE32ImageMap. |
|
298 |
|
299 @internalComponent |
|
300 @released |
|
301 |
|
302 @return iImageVsDepList - returns all executable's dependencies |
|
303 */ |
|
304 ExeNamesVsDepListMap& DirReader::GatherDependencies() |
|
305 { |
|
306 ExeVsE32ImageMap::iterator begin = iExeVsE32ImageMap.begin(); |
|
307 ExeVsE32ImageMap::iterator end = iExeVsE32ImageMap.end(); |
|
308 |
|
309 StringList executableList; |
|
310 while(begin != end) |
|
311 { |
|
312 PrepareExeDependencyList((*begin).second, executableList); |
|
313 iImageVsDepList.insert(std::make_pair((*begin).first, executableList)); |
|
314 executableList.clear(); |
|
315 ++begin; |
|
316 } |
|
317 return iImageVsDepList; |
|
318 } |
|
319 |
|
320 /** |
|
321 Function responsible to prepare the dependency list. |
|
322 |
|
323 @internalComponent |
|
324 @released |
|
325 |
|
326 @param - aE32Image, Using this, can get all the information about the executable |
|
327 @param - aExecutableList, Excutables placed into this list |
|
328 */ |
|
329 void DirReader::PrepareExeDependencyList(E32Image* aE32Image, StringList& aExecutableList) |
|
330 { |
|
331 int count = 0; |
|
332 char** nameList = aE32Image->GetImportExecutableNames(count); |
|
333 int i = 0; |
|
334 String dependency; |
|
335 for(; i < count; ++i) |
|
336 { |
|
337 dependency.assign(nameList[i]); |
|
338 aExecutableList.push_back(ReaderUtil::ToLower(dependency)); |
|
339 } |
|
340 DELETE(nameList); |
|
341 } |
|
342 |
|
343 /** |
|
344 Function to identify the given path as file or directory |
|
345 |
|
346 @internalComponent |
|
347 @released |
|
348 |
|
349 @param - aStr, path name |
|
350 @return - retuns the either Directory, file or Unknown. |
|
351 */ |
|
352 EImageType DirReader::EntryType(char* aStr) |
|
353 { |
|
354 int strLength = strlen(aStr); |
|
355 if(aStr[strLength - 1] == '\\' || aStr[strLength - 1] == '/') |
|
356 { |
|
357 aStr[strLength - 1] = KNull; |
|
358 } |
|
359 int retVal = 0; |
|
360 #ifdef __LINUX__ |
|
361 struct stat fileEntrybuf; |
|
362 retVal = stat(aStr, &fileEntrybuf); |
|
363 if(retVal >= 0) |
|
364 { |
|
365 if(S_ISDIR(fileEntrybuf.st_mode)) |
|
366 { |
|
367 #else |
|
368 struct _finddata_t finder; |
|
369 retVal = _findfirst(aStr, &finder); |
|
370 if(retVal > 0) //No error |
|
371 { |
|
372 if(finder.attrib & _A_SUBDIR) |
|
373 { |
|
374 #endif |
|
375 return EE32Directoy; |
|
376 } |
|
377 else |
|
378 { |
|
379 if(E32Reader::IsE32Image(aStr) == true) |
|
380 { |
|
381 return EE32File; |
|
382 } |
|
383 } |
|
384 } |
|
385 |
|
386 return EE32InputNotExist; |
|
387 } |