1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_prel.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,360 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// f32\sfile\sf_prel.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "sf_std.h"
1.22 +#include "u32std.h"
1.23 +#include <e32hal.h>
1.24 +#include "sf_cache_man.h"
1.25 +
1.26 +_LIT(KLitInitCompleteThread,"InitCompleteThread");
1.27 +
1.28 +#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1.29 +_LIT(KCorruptFileNamesList,"CorruptFileNames.lst");
1.30 +_LIT(KSysData,"\\sys\\data\\");
1.31 +_LIT(KSystemData,"\\system\\data\\");
1.32 +/**
1.33 +ASCII text file reader constructor
1.34 +This code is more or less lifted directly from estart.cpp
1.35 +*/
1.36 +TText8FileReader::TText8FileReader()
1.37 + {
1.38 +
1.39 + iBufPos=-1;
1.40 + iFileDataBuf=NULL;
1.41 + iFileSize=0;
1.42 + }
1.43 +
1.44 +/**
1.45 +ASCII text file reader destructor
1.46 +*/
1.47 +TText8FileReader::~TText8FileReader()
1.48 + {
1.49 +
1.50 + delete[] iFileDataBuf;
1.51 + }
1.52 +
1.53 +/**
1.54 +Supply an ASCII text file for the file reader.
1.55 +This function reads the entire contents of this file into a buffer, converting to
1.56 +unicode / folding each character. Subsequent parsing of the file data is all done from this
1.57 +buffer.
1.58 +@param aFile The file to be read. Must already be opened for read access in EFileStreamText mode.
1.59 +@return KErrNone if no error.
1.60 +*/
1.61 +TInt TText8FileReader::Set(RFile& aFile)
1.62 + {
1.63 +
1.64 + iFile=aFile;
1.65 + iBuf.Zero();
1.66 + iBufPos=0;
1.67 +
1.68 + // Read the size of the file
1.69 + TInt r=iFile.Size(iFileSize);
1.70 + if (r!=KErrNone || !iFileSize)
1.71 + return(KErrGeneral);
1.72 +
1.73 + // Allocate a buffer to read in the
1.74 + iFileDataBuf=new TText[iFileSize+1]; // +1 in case need to NULL terminate the end of the last string
1.75 + if (iFileDataBuf==NULL)
1.76 + return(KErrNoMemory);
1.77 +
1.78 + // Read the entire contents of the file into the buffer
1.79 + TPtr fdata(NULL,0);
1.80 + TInt pos=0;
1.81 + r=iFile.Seek(ESeekStart,pos);
1.82 + while (pos<iFileSize)
1.83 + {
1.84 + if ((r=iFile.Read(iBuf))!=KErrNone)
1.85 + return(r);
1.86 + fdata.Set((iFileDataBuf+pos),0,iBuf.Length());
1.87 + fdata.Copy(iBuf);
1.88 + fdata.Fold();
1.89 + pos+=iBuf.Length();
1.90 + }
1.91 + return(KErrNone);
1.92 + }
1.93 +
1.94 +/**
1.95 +Return the next record from the text file.
1.96 +@param aPtr A TPtr which is setup with the address and length of the next record, referencing
1.97 +the data in the reader's buffer.
1.98 +@return KErrNone if a record is successfully loaded into the buffer, KErrEof if the end of the
1.99 +file is encountered, KErrGeneral if a file hasn't been set.
1.100 +*/
1.101 +TInt TText8FileReader::Read(TPtr& aPtr)
1.102 + {
1.103 +
1.104 + // Check that Set() has been called.
1.105 + if (iBufPos<0)
1.106 + return(KErrGeneral);
1.107 +
1.108 + // Check if we have run into the end of the file
1.109 + TInt bufRemainder=(iFileSize-iBufPos);
1.110 + if (!bufRemainder)
1.111 + return(KErrEof);
1.112 +
1.113 + // Setup the descriptor passed with the next record - don't include the record terminator
1.114 + // The line terminators are CR + LF for DOS
1.115 + // whereas only LF for Unix line endings
1.116 + aPtr.Set((iFileDataBuf+iBufPos),bufRemainder,bufRemainder);
1.117 + TInt len=aPtr.Locate('\n');
1.118 + if (len != KErrNotFound)
1.119 + {
1.120 + iBufPos += len;
1.121 + // Check for DOS line ending to support both DOS and Unix formats
1.122 + if ((len != 0) && (iFileDataBuf[iBufPos-1] == '\r'))
1.123 + {
1.124 + len--;
1.125 + }
1.126 + aPtr.SetLength(len);
1.127 + }
1.128 + else
1.129 + iBufPos=iFileSize;
1.130 +
1.131 + // Point iBufPos to the next non-empty line
1.132 + while (iBufPos<iFileSize && (iFileDataBuf[iBufPos]=='\n' || iFileDataBuf[iBufPos]=='\r'))
1.133 + iBufPos++;
1.134 + return(KErrNone);
1.135 + }
1.136 +
1.137 +/**
1.138 +Parse a record and split it into filename, error code & use once flag
1.139 +@param aLine, this a a record from read from the file
1.140 +@param aName, this is the parsed filename component of the record
1.141 +@param aReturnCode, the error code that will be returned when an attempt is made to open the file
1.142 +@param aUseOnce, flag which states whether the error should persist over more than one open attempt
1.143 +@return error code, if the record is malformed return KErrCorrupt (ironic, what?) else KErrNone
1.144 +*/
1.145 +TInt ParseCorruptNamesRecord(TPtr aLine, TPtr& aName, TInt& aReturnCode, TBool& aUseOnce)
1.146 + {
1.147 + aName.Set(NULL,0,0);
1.148 + // Remove leading spaces
1.149 + aLine.TrimLeft();
1.150 + TPtr remainderPtr(aLine);
1.151 +
1.152 + // collect pathname
1.153 + TInt lenFileName=remainderPtr.Locate(',');
1.154 + if(lenFileName<1)
1.155 + return KErrCorrupt;
1.156 + TPtr pathNamePtr(remainderPtr.LeftTPtr(lenFileName));
1.157 + // Remove trailing spaces
1.158 + pathNamePtr.TrimRight();
1.159 + // Parse the pathname to see if it could be valid, do not allow wild cards
1.160 + TParse fileParse;
1.161 + TInt r=fileParse.SetNoWild(pathNamePtr,NULL,NULL);
1.162 + if(r!=KErrNone)
1.163 + return KErrCorrupt;
1.164 +
1.165 + // move over delimiter to collect the user supplied return code
1.166 + // see first if sufficient length in the record
1.167 + TInt lenRemainder=remainderPtr.Length();
1.168 + if(lenRemainder<lenFileName+2)
1.169 + return KErrCorrupt;
1.170 +
1.171 + remainderPtr.Set(remainderPtr.MidTPtr(lenFileName+1));
1.172 + remainderPtr.TrimLeft();
1.173 + TInt lenReturnCode=remainderPtr.Locate(',');
1.174 + if(lenReturnCode<1)
1.175 + return KErrCorrupt;
1.176 +
1.177 + TPtr returnCodePtr(remainderPtr.LeftTPtr(lenReturnCode));
1.178 + TLex lexLine(returnCodePtr);
1.179 + TInt returnCode;
1.180 + if(lexLine.Val(returnCode)!=KErrNone)
1.181 + return KErrCorrupt;
1.182 +
1.183 + lenRemainder=remainderPtr.Length();
1.184 + if(lenRemainder<lenReturnCode+2)
1.185 + return KErrCorrupt;
1.186 +
1.187 + // collect the useOnce flag value
1.188 + remainderPtr.Set(remainderPtr.MidTPtr(lenReturnCode+1));
1.189 + remainderPtr.Trim();
1.190 + TBool useOnce;
1.191 + // This must either be "EVERY" or "ONCE"
1.192 + if (remainderPtr.MatchF(_L("EVERY"))!=KErrNotFound)
1.193 + useOnce=EFalse;
1.194 + else if(remainderPtr.MatchF(_L("ONCE"))!=KErrNotFound)
1.195 + useOnce=ETrue;
1.196 + else
1.197 + return KErrCorrupt;
1.198 +
1.199 + // Everything has worked out, so set up output args
1.200 +
1.201 + aName.Set(pathNamePtr);
1.202 + aReturnCode=returnCode;
1.203 + aUseOnce=useOnce;
1.204 + return KErrNone;
1.205 + }
1.206 +
1.207 +/**
1.208 +Open c:\CorruptFileNames.lst
1.209 +File contains a set of text records
1.210 +Each record has comma delimited fields and has the form:
1.211 + <filename>, <errorCode>, <[ONCE,EVERY]>
1.212 +e.g.
1.213 +c:\system\bin\bt.lst, -6,EVERY
1.214 +the filename should be fully qualified,
1.215 +errorCode should be a literal not a symbol
1.216 +EVERY means that every attempt to open the file will be failed
1.217 +ONCE means that only the first access to the file will be failed
1.218 +*/
1.219 +
1.220 +TInt FindHitListFile(RFs aFs)
1.221 + {
1.222 + TFindFile finder(aFs);
1.223 + TInt r=finder.FindByDir(KCorruptFileNamesList,_L("\\"));
1.224 + if(r!=KErrNone)
1.225 + {
1.226 + r=finder.FindByDir(KCorruptFileNamesList,KSysData);
1.227 + }
1.228 +
1.229 + if(r!=KErrNone)
1.230 + {
1.231 + r=finder.FindByDir(KCorruptFileNamesList,KSystemData);
1.232 + }
1.233 +
1.234 + if(r==KErrNone)
1.235 + { // This is stored as a global because the name can be retrieved by a user api
1.236 + gCorruptFileNamesListFile=finder.File().Alloc();
1.237 + if(gCorruptFileNamesListFile==NULL)
1.238 + {
1.239 + r=KErrNoMemory;
1.240 + }
1.241 + }
1.242 + return r;
1.243 + }
1.244 +
1.245 +void CreateCorruptFileNamesList()
1.246 + {
1.247 + RFs fs;
1.248 + fs.Connect();
1.249 + TInt r=FindHitListFile(fs);
1.250 + if(r!=KErrNone)
1.251 + return;
1.252 + RFile f;
1.253 + r=f.Open(fs,*gCorruptFileNamesListFile,EFileShareExclusive|EFileStreamText|EFileRead);
1.254 + if(r!=KErrNone)
1.255 + {
1.256 + return;
1.257 + }
1.258 + // Create a corrupt filenames file reader and pass it the file object. This will also result in the copying of the contents of
1.259 + // the file into reader's buffer. Filename information read from the file will include pointers to text strings in
1.260 + // this buffer and so the reader object must not be deleted until processing is complete.
1.261 + __PRINT1(_L("@@@@ Using Corrupt names file %S"),gCorruptFileNamesListFile);
1.262 +
1.263 + TText8FileReader* namesFile=new TText8FileReader;
1.264 + if (!namesFile)
1.265 + {
1.266 + f.Close();
1.267 + return;
1.268 + }
1.269 +
1.270 + r=namesFile->Set(f);
1.271 + f.Close();
1.272 + fs.Close();
1.273 + if(r==KErrNone)
1.274 + {
1.275 + // Parse each drive mapping record in turn, saving the information in an array of mapping structures - one for
1.276 + // each valid record.
1.277 + TPtr linePtr(NULL,0);
1.278 + while ((r=namesFile->Read(linePtr))==KErrNone)
1.279 + {
1.280 + TInt returnCode;
1.281 + TBool useOnce;
1.282 + TPtr namePtr(NULL,0);
1.283 + if (ParseCorruptNamesRecord(linePtr,namePtr,returnCode,useOnce)==KErrNone)
1.284 + {
1.285 + // Valid corrupt filename record found
1.286 + TCorruptNameRec* newRec=new TCorruptNameRec;
1.287 + if(!newRec)
1.288 + {
1.289 + break;
1.290 + }
1.291 + if(newRec->Construct(&namePtr,returnCode,useOnce,gCorruptFileNameList)!=KErrNone)
1.292 + {
1.293 + delete newRec;
1.294 + newRec=NULL;
1.295 + break;
1.296 + }
1.297 +
1.298 + gCorruptFileNameList=newRec;
1.299 + }
1.300 + else
1.301 + {
1.302 + __PRINT1(_L("@@@@@ Bad Parse corrupt file name record %S\n"),&linePtr);
1.303 + }
1.304 + }
1.305 + }
1.306 +
1.307 + delete namesFile;
1.308 + }
1.309 +#endif
1.310 +
1.311 +TInt InitCompleteThread(TAny* aPtr)
1.312 + {
1.313 + __PRINT(KLitInitCompleteThread);
1.314 + RMessagePtr2 message=*(RMessagePtr2*)aPtr;
1.315 + RThread::Rendezvous(0);
1.316 +
1.317 +
1.318 + //
1.319 +#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1.320 + CreateCorruptFileNamesList();
1.321 +#endif
1.322 +
1.323 + TInt r = KErrNone;
1.324 + message.Complete(r);
1.325 + return(KErrNone);
1.326 + }
1.327 +
1.328 +
1.329 +TInt TFsStartupInitComplete::DoRequestL(CFsRequest *aRequest)
1.330 +//
1.331 +// do further initialisation once necessary startup init complete outside file server
1.332 +//
1.333 + {
1.334 + if(StartupInitCompleted)
1.335 + return(KErrAlreadyExists);
1.336 +
1.337 +
1.338 + StartupInitCompleted=ETrue;
1.339 + RMessagePtr2 msg=aRequest->Message();
1.340 + RThread thread;
1.341 + TInt r=thread.Create(KLitInitCompleteThread,InitCompleteThread,KDefaultStackSize,NULL,&msg);
1.342 + if (KErrNone == r)
1.343 + {
1.344 + TRequestStatus s;
1.345 + thread.Rendezvous(s);
1.346 + if (s==KRequestPending)
1.347 + thread.Resume();
1.348 + else
1.349 + thread.Kill(0);
1.350 + thread.Close();
1.351 + User::WaitForRequest(s);
1.352 + r = s.Int();
1.353 + }
1.354 + return(KErrNone);
1.355 + }
1.356 +
1.357 +TInt TFsStartupInitComplete::Initialise(CFsRequest* /*aRequest*/)
1.358 +//
1.359 +//
1.360 +//
1.361 + {
1.362 + return KErrNone;
1.363 + }