os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_prel.cpp
changeset 0 bde4ae8d615e
     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 +	}