author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Thu, 02 Sep 2010 21:54:16 +0300 | |
changeset 259 | 57b9594f5772 |
parent 201 | 43365a9b78a3 |
child 257 | 3e88ff8f41d5 |
permissions | -rw-r--r-- |
0 | 1 |
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). |
2 |
// All rights reserved. |
|
3 |
// This component and the accompanying materials are made available |
|
4 |
// under the terms of the License "Eclipse Public License v1.0" |
|
5 |
// which accompanies this distribution, and is available |
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 |
// |
|
8 |
// Initial Contributors: |
|
9 |
// Nokia Corporation - initial contribution. |
|
10 |
// |
|
11 |
// Contributors: |
|
12 |
// |
|
13 |
// Description: |
|
14 |
// f32\sfile\sf_prel.cpp |
|
15 |
// |
|
16 |
// |
|
17 |
||
18 |
#include "sf_std.h" |
|
19 |
#include "u32std.h" |
|
20 |
#include <e32hal.h> |
|
21 |
#include "sf_cache_man.h" |
|
22 |
||
23 |
_LIT(KLitInitCompleteThread,"InitCompleteThread"); |
|
24 |
||
25 |
#if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
26 |
_LIT(KCorruptFileNamesList,"CorruptFileNames.lst"); |
|
27 |
_LIT(KSysData,"\\sys\\data\\"); |
|
28 |
_LIT(KSystemData,"\\system\\data\\"); |
|
29 |
/** |
|
30 |
ASCII text file reader constructor |
|
31 |
This code is more or less lifted directly from estart.cpp |
|
32 |
*/ |
|
33 |
TText8FileReader::TText8FileReader() |
|
34 |
{ |
|
35 |
||
36 |
iBufPos=-1; |
|
37 |
iFileDataBuf=NULL; |
|
38 |
iFileSize=0; |
|
39 |
} |
|
40 |
||
41 |
/** |
|
42 |
ASCII text file reader destructor |
|
43 |
*/ |
|
44 |
TText8FileReader::~TText8FileReader() |
|
45 |
{ |
|
46 |
||
47 |
delete[] iFileDataBuf; |
|
48 |
} |
|
49 |
||
50 |
/** |
|
51 |
Supply an ASCII text file for the file reader. |
|
52 |
This function reads the entire contents of this file into a buffer, converting to |
|
53 |
unicode / folding each character. Subsequent parsing of the file data is all done from this |
|
54 |
buffer. |
|
55 |
@param aFile The file to be read. Must already be opened for read access in EFileStreamText mode. |
|
56 |
@return KErrNone if no error. |
|
57 |
*/ |
|
58 |
TInt TText8FileReader::Set(RFile& aFile) |
|
59 |
{ |
|
60 |
||
61 |
iFile=aFile; |
|
62 |
iBuf.Zero(); |
|
63 |
iBufPos=0; |
|
64 |
||
65 |
// Read the size of the file |
|
66 |
TInt r=iFile.Size(iFileSize); |
|
67 |
if (r!=KErrNone || !iFileSize) |
|
68 |
return(KErrGeneral); |
|
69 |
||
70 |
// Allocate a buffer to read in the |
|
71 |
iFileDataBuf=new TText[iFileSize+1]; // +1 in case need to NULL terminate the end of the last string |
|
72 |
if (iFileDataBuf==NULL) |
|
73 |
return(KErrNoMemory); |
|
74 |
||
75 |
// Read the entire contents of the file into the buffer |
|
76 |
TPtr fdata(NULL,0); |
|
77 |
TInt pos=0; |
|
78 |
r=iFile.Seek(ESeekStart,pos); |
|
79 |
while (pos<iFileSize) |
|
80 |
{ |
|
81 |
if ((r=iFile.Read(iBuf))!=KErrNone) |
|
82 |
return(r); |
|
83 |
fdata.Set((iFileDataBuf+pos),0,iBuf.Length()); |
|
84 |
fdata.Copy(iBuf); |
|
85 |
fdata.Fold(); |
|
86 |
pos+=iBuf.Length(); |
|
87 |
} |
|
88 |
return(KErrNone); |
|
89 |
} |
|
90 |
||
91 |
/** |
|
92 |
Return the next record from the text file. |
|
93 |
@param aPtr A TPtr which is setup with the address and length of the next record, referencing |
|
94 |
the data in the reader's buffer. |
|
95 |
@return KErrNone if a record is successfully loaded into the buffer, KErrEof if the end of the |
|
96 |
file is encountered, KErrGeneral if a file hasn't been set. |
|
97 |
*/ |
|
98 |
TInt TText8FileReader::Read(TPtr& aPtr) |
|
99 |
{ |
|
100 |
||
101 |
// Check that Set() has been called. |
|
102 |
if (iBufPos<0) |
|
103 |
return(KErrGeneral); |
|
104 |
||
105 |
// Check if we have run into the end of the file |
|
106 |
TInt bufRemainder=(iFileSize-iBufPos); |
|
107 |
if (!bufRemainder) |
|
108 |
return(KErrEof); |
|
109 |
||
110 |
// Setup the descriptor passed with the next record - don't include the record terminator |
|
111 |
// The line terminators are CR + LF for DOS |
|
112 |
// whereas only LF for Unix line endings |
|
113 |
aPtr.Set((iFileDataBuf+iBufPos),bufRemainder,bufRemainder); |
|
114 |
TInt len=aPtr.Locate('\n'); |
|
115 |
if (len != KErrNotFound) |
|
116 |
{ |
|
117 |
iBufPos += len; |
|
118 |
// Check for DOS line ending to support both DOS and Unix formats |
|
119 |
if ((len != 0) && (iFileDataBuf[iBufPos-1] == '\r')) |
|
120 |
{ |
|
121 |
len--; |
|
122 |
} |
|
123 |
aPtr.SetLength(len); |
|
124 |
} |
|
125 |
else |
|
126 |
iBufPos=iFileSize; |
|
127 |
||
128 |
// Point iBufPos to the next non-empty line |
|
129 |
while (iBufPos<iFileSize && (iFileDataBuf[iBufPos]=='\n' || iFileDataBuf[iBufPos]=='\r')) |
|
130 |
iBufPos++; |
|
131 |
return(KErrNone); |
|
132 |
} |
|
133 |
||
134 |
/** |
|
135 |
Parse a record and split it into filename, error code & use once flag |
|
136 |
@param aLine, this a a record from read from the file |
|
137 |
@param aName, this is the parsed filename component of the record |
|
138 |
@param aReturnCode, the error code that will be returned when an attempt is made to open the file |
|
139 |
@param aUseOnce, flag which states whether the error should persist over more than one open attempt |
|
140 |
@return error code, if the record is malformed return KErrCorrupt (ironic, what?) else KErrNone |
|
141 |
*/ |
|
142 |
TInt ParseCorruptNamesRecord(TPtr aLine, TPtr& aName, TInt& aReturnCode, TBool& aUseOnce) |
|
143 |
{ |
|
144 |
aName.Set(NULL,0,0); |
|
145 |
// Remove leading spaces |
|
146 |
aLine.TrimLeft(); |
|
147 |
TPtr remainderPtr(aLine); |
|
148 |
||
149 |
// collect pathname |
|
150 |
TInt lenFileName=remainderPtr.Locate(','); |
|
151 |
if(lenFileName<1) |
|
152 |
return KErrCorrupt; |
|
153 |
TPtr pathNamePtr(remainderPtr.LeftTPtr(lenFileName)); |
|
154 |
// Remove trailing spaces |
|
155 |
pathNamePtr.TrimRight(); |
|
156 |
// Parse the pathname to see if it could be valid, do not allow wild cards |
|
157 |
TParse fileParse; |
|
158 |
TInt r=fileParse.SetNoWild(pathNamePtr,NULL,NULL); |
|
159 |
if(r!=KErrNone) |
|
160 |
return KErrCorrupt; |
|
161 |
||
162 |
// move over delimiter to collect the user supplied return code |
|
163 |
// see first if sufficient length in the record |
|
164 |
TInt lenRemainder=remainderPtr.Length(); |
|
165 |
if(lenRemainder<lenFileName+2) |
|
166 |
return KErrCorrupt; |
|
167 |
||
168 |
remainderPtr.Set(remainderPtr.MidTPtr(lenFileName+1)); |
|
169 |
remainderPtr.TrimLeft(); |
|
170 |
TInt lenReturnCode=remainderPtr.Locate(','); |
|
171 |
if(lenReturnCode<1) |
|
172 |
return KErrCorrupt; |
|
173 |
||
174 |
TPtr returnCodePtr(remainderPtr.LeftTPtr(lenReturnCode)); |
|
175 |
TLex lexLine(returnCodePtr); |
|
176 |
TInt returnCode; |
|
177 |
if(lexLine.Val(returnCode)!=KErrNone) |
|
178 |
return KErrCorrupt; |
|
179 |
||
180 |
lenRemainder=remainderPtr.Length(); |
|
181 |
if(lenRemainder<lenReturnCode+2) |
|
182 |
return KErrCorrupt; |
|
183 |
||
184 |
// collect the useOnce flag value |
|
185 |
remainderPtr.Set(remainderPtr.MidTPtr(lenReturnCode+1)); |
|
186 |
remainderPtr.Trim(); |
|
187 |
TBool useOnce; |
|
188 |
// This must either be "EVERY" or "ONCE" |
|
189 |
if (remainderPtr.MatchF(_L("EVERY"))!=KErrNotFound) |
|
190 |
useOnce=EFalse; |
|
191 |
else if(remainderPtr.MatchF(_L("ONCE"))!=KErrNotFound) |
|
192 |
useOnce=ETrue; |
|
193 |
else |
|
194 |
return KErrCorrupt; |
|
195 |
||
196 |
// Everything has worked out, so set up output args |
|
197 |
||
198 |
aName.Set(pathNamePtr); |
|
199 |
aReturnCode=returnCode; |
|
200 |
aUseOnce=useOnce; |
|
201 |
return KErrNone; |
|
202 |
} |
|
203 |
||
204 |
/** |
|
205 |
Open c:\CorruptFileNames.lst |
|
206 |
File contains a set of text records |
|
207 |
Each record has comma delimited fields and has the form: |
|
208 |
<filename>, <errorCode>, <[ONCE,EVERY]> |
|
209 |
e.g. |
|
210 |
c:\system\bin\bt.lst, -6,EVERY |
|
211 |
the filename should be fully qualified, |
|
212 |
errorCode should be a literal not a symbol |
|
213 |
EVERY means that every attempt to open the file will be failed |
|
214 |
ONCE means that only the first access to the file will be failed |
|
215 |
*/ |
|
216 |
||
217 |
TInt FindHitListFile(RFs aFs) |
|
218 |
{ |
|
219 |
TFindFile finder(aFs); |
|
220 |
TInt r=finder.FindByDir(KCorruptFileNamesList,_L("\\")); |
|
221 |
if(r!=KErrNone) |
|
222 |
{ |
|
223 |
r=finder.FindByDir(KCorruptFileNamesList,KSysData); |
|
224 |
} |
|
225 |
||
226 |
if(r!=KErrNone) |
|
227 |
{ |
|
228 |
r=finder.FindByDir(KCorruptFileNamesList,KSystemData); |
|
229 |
} |
|
230 |
||
231 |
if(r==KErrNone) |
|
232 |
{ // This is stored as a global because the name can be retrieved by a user api |
|
233 |
gCorruptFileNamesListFile=finder.File().Alloc(); |
|
234 |
if(gCorruptFileNamesListFile==NULL) |
|
235 |
{ |
|
236 |
r=KErrNoMemory; |
|
237 |
} |
|
238 |
} |
|
239 |
return r; |
|
240 |
} |
|
241 |
||
242 |
void CreateCorruptFileNamesList() |
|
243 |
{ |
|
244 |
RFs fs; |
|
201
43365a9b78a3
Revision: 201027
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
245 |
|
43365a9b78a3
Revision: 201027
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
246 |
TInt r = fs.Connect(); |
0 | 247 |
if(r!=KErrNone) |
248 |
return; |
|
201
43365a9b78a3
Revision: 201027
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
249 |
|
43365a9b78a3
Revision: 201027
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
250 |
r=FindHitListFile(fs); |
43365a9b78a3
Revision: 201027
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
251 |
if(r!=KErrNone) |
43365a9b78a3
Revision: 201027
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
252 |
return; |
43365a9b78a3
Revision: 201027
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
253 |
|
0 | 254 |
RFile f; |
255 |
r=f.Open(fs,*gCorruptFileNamesListFile,EFileShareExclusive|EFileStreamText|EFileRead); |
|
256 |
if(r!=KErrNone) |
|
257 |
{ |
|
258 |
return; |
|
259 |
} |
|
260 |
// Create a corrupt filenames file reader and pass it the file object. This will also result in the copying of the contents of |
|
261 |
// the file into reader's buffer. Filename information read from the file will include pointers to text strings in |
|
262 |
// this buffer and so the reader object must not be deleted until processing is complete. |
|
263 |
__PRINT1(_L("@@@@ Using Corrupt names file %S"),gCorruptFileNamesListFile); |
|
264 |
||
265 |
TText8FileReader* namesFile=new TText8FileReader; |
|
266 |
if (!namesFile) |
|
267 |
{ |
|
268 |
f.Close(); |
|
269 |
return; |
|
270 |
} |
|
271 |
||
272 |
r=namesFile->Set(f); |
|
273 |
f.Close(); |
|
274 |
fs.Close(); |
|
275 |
if(r==KErrNone) |
|
276 |
{ |
|
277 |
// Parse each drive mapping record in turn, saving the information in an array of mapping structures - one for |
|
278 |
// each valid record. |
|
279 |
TPtr linePtr(NULL,0); |
|
280 |
while ((r=namesFile->Read(linePtr))==KErrNone) |
|
281 |
{ |
|
282 |
TInt returnCode; |
|
283 |
TBool useOnce; |
|
284 |
TPtr namePtr(NULL,0); |
|
285 |
if (ParseCorruptNamesRecord(linePtr,namePtr,returnCode,useOnce)==KErrNone) |
|
286 |
{ |
|
287 |
// Valid corrupt filename record found |
|
288 |
TCorruptNameRec* newRec=new TCorruptNameRec; |
|
289 |
if(!newRec) |
|
290 |
{ |
|
291 |
break; |
|
292 |
} |
|
293 |
if(newRec->Construct(&namePtr,returnCode,useOnce,gCorruptFileNameList)!=KErrNone) |
|
294 |
{ |
|
295 |
delete newRec; |
|
296 |
newRec=NULL; |
|
297 |
break; |
|
298 |
} |
|
299 |
||
300 |
gCorruptFileNameList=newRec; |
|
301 |
} |
|
302 |
else |
|
303 |
{ |
|
304 |
__PRINT1(_L("@@@@@ Bad Parse corrupt file name record %S\n"),&linePtr); |
|
305 |
} |
|
306 |
} |
|
307 |
} |
|
308 |
||
309 |
delete namesFile; |
|
310 |
} |
|
311 |
#endif |
|
312 |
||
313 |
TInt InitCompleteThread(TAny* aPtr) |
|
314 |
{ |
|
315 |
__PRINT(KLitInitCompleteThread); |
|
316 |
RMessagePtr2 message=*(RMessagePtr2*)aPtr; |
|
317 |
RThread::Rendezvous(0); |
|
318 |
||
319 |
||
320 |
// |
|
321 |
#if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
322 |
CreateCorruptFileNamesList(); |
|
323 |
#endif |
|
324 |
||
325 |
TInt r = KErrNone; |
|
326 |
message.Complete(r); |
|
327 |
return(KErrNone); |
|
328 |
} |
|
329 |
||
330 |
||
331 |
TInt TFsStartupInitComplete::DoRequestL(CFsRequest *aRequest) |
|
332 |
// |
|
333 |
// do further initialisation once necessary startup init complete outside file server |
|
334 |
// |
|
335 |
{ |
|
336 |
if(StartupInitCompleted) |
|
337 |
return(KErrAlreadyExists); |
|
338 |
||
339 |
||
340 |
StartupInitCompleted=ETrue; |
|
341 |
RMessagePtr2 msg=aRequest->Message(); |
|
342 |
RThread thread; |
|
343 |
TInt r=thread.Create(KLitInitCompleteThread,InitCompleteThread,KDefaultStackSize,NULL,&msg); |
|
344 |
if (KErrNone == r) |
|
345 |
{ |
|
346 |
TRequestStatus s; |
|
347 |
thread.Rendezvous(s); |
|
348 |
if (s==KRequestPending) |
|
349 |
thread.Resume(); |
|
350 |
else |
|
351 |
thread.Kill(0); |
|
352 |
thread.Close(); |
|
353 |
User::WaitForRequest(s); |
|
354 |
r = s.Int(); |
|
355 |
} |
|
356 |
return(KErrNone); |
|
357 |
} |
|
358 |
||
359 |
TInt TFsStartupInitComplete::Initialise(CFsRequest* /*aRequest*/) |
|
360 |
// |
|
361 |
// |
|
362 |
// |
|
363 |
{ |
|
364 |
return KErrNone; |
|
365 |
} |