datacommsserver/esockserver/ssock/INIFILE.CPP
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 1997-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 "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 //
       
    15 
       
    16 #include <es_ini.h>
       
    17 #include <f32file.h>
       
    18 #include <cfextras.h>
       
    19 
       
    20 
       
    21 /**
       
    22 @internalComponent
       
    23 */
       
    24 class TFileListIter
       
    25 	{
       
    26 public:
       
    27 	TFileListIter()
       
    28 		{
       
    29 		iList = 0;
       
    30 		iIsCDir = EFalse;
       
    31 		iIdx = 0;
       
    32 		}
       
    33 	void Set(const CDir* aList)
       
    34 		{
       
    35 		iList = static_cast<const void*>(aList);
       
    36 	    iIdx = 0;
       
    37 		iIsCDir = ETrue;
       
    38 		}
       
    39 	void Set(const CommsFW::COwnEntryList* aList)
       
    40 		{
       
    41 		iList = static_cast<const void*>(aList);
       
    42 	    iIdx = 0;
       
    43 		iIsCDir = EFalse;
       
    44 		}
       
    45 	const TEntry* operator++(TInt)
       
    46 		{
       
    47 		const TEntry* entry = NULL;
       
    48 		if(iIsCDir)
       
    49 			{
       
    50 			const CDir* list = reinterpret_cast<const CDir*>(iList);
       
    51 			if(list != NULL && iIdx < list->Count())
       
    52 				{
       
    53 				entry = &(*list)[iIdx++];
       
    54 				}
       
    55 			}
       
    56 		else
       
    57 			{
       
    58 			const CommsFW::COwnEntryList* list = reinterpret_cast<const CommsFW::COwnEntryList*>(iList);
       
    59 			if(list != NULL && iIdx < list->Count())
       
    60 				{
       
    61 				entry = &(*list)[iIdx++];
       
    62 				}
       
    63 			}
       
    64 		return entry;
       
    65 		}
       
    66 private:
       
    67 	const void* iList;
       
    68 	TBool iIsCDir;
       
    69 	TInt iIdx;
       
    70 	};
       
    71 
       
    72 const TInt KTokenSize=32;
       
    73 
       
    74 // Warning !! redifinition required
       
    75 const TInt32 KUidCommsProcess = 0x101F7989;
       
    76 
       
    77 /*
       
    78 @internalComponent
       
    79 */
       
    80 enum TIniPanic
       
    81 	{
       
    82 	ESectionNameTooBig,
       
    83 	EVarNameTooBig,
       
    84 	};
       
    85 
       
    86 /**
       
    87 @internalComponent
       
    88 */
       
    89 void Panic(TIniPanic aPanic)
       
    90 	{
       
    91 	_LIT(cESockIniData,"CESockIniData");
       
    92 	User::Panic(cESockIniData,aPanic);
       
    93 	}
       
    94 
       
    95 
       
    96 EXPORT_C CESockIniData::CESockIniData() 
       
    97 : iPtr(NULL,0)
       
    98 	{
       
    99 	}
       
   100 
       
   101 EXPORT_C CESockIniData::CESockIniData(const CommsFW::COwnEntryList* aFileList) 
       
   102 : iPtr(NULL,0),
       
   103   iFileList(aFileList)
       
   104   	{
       
   105 	}
       
   106 
       
   107 EXPORT_C CESockIniData::~CESockIniData()
       
   108 	{
       
   109 	delete (TText*)iPtr.Ptr();
       
   110 	delete iToken;
       
   111 	delete iName;
       
   112 	}
       
   113 
       
   114 EXPORT_C CESockIniData* CESockIniData::NewL(const TDesC& aName)
       
   115 	{
       
   116 	CESockIniData* p=new(ELeave) CESockIniData;
       
   117 	CleanupStack::PushL(p);
       
   118 	p->ConstructL(aName);
       
   119 	CleanupStack::Pop();
       
   120 	return p;
       
   121 	}
       
   122 
       
   123 EXPORT_C CESockIniData* CESockIniData::NewL(const CommsFW::COwnEntryList* aFileList)
       
   124 	{
       
   125 	CESockIniData* p=new(ELeave) CESockIniData(aFileList);
       
   126 	CleanupStack::PushL(p);
       
   127 	p->ConstructL(KNullDesC);
       
   128 	CleanupStack::Pop();
       
   129 	return p;
       
   130 	}
       
   131 
       
   132 EXPORT_C void CESockIniData::ConstructL(const TDesC& aName)
       
   133 /**
       
   134 Allocate a buffer and Read file's contents into iPtr
       
   135 */
       
   136 	{
       
   137 	
       
   138     iToken=HBufC::NewL(KTokenSize+2);	// 2 extra chars for [tokenName]
       
   139 	
       
   140 	// protocol_buf is used to holf the protocol list
       
   141 	// and then the whole collated .ini file
       
   142 	CBufFlat* protocol_buf=CBufFlat::NewL(4);
       
   143 	CleanupStack::PushL(protocol_buf);
       
   144 	TInt protocol_pos = 0;
       
   145 	
       
   146 	//data_buf is used to temporarily hold the .esk files'bodies
       
   147 	CBufFlat* data_buf=CBufFlat::NewL(4);
       
   148 	CleanupStack::PushL(data_buf);
       
   149 	TInt data_pos = 0;
       
   150 	
       
   151 	TInt data_size =0;
       
   152 	
       
   153 	TAutoClose<RFs> fs;
       
   154 	User::LeaveIfError(fs.iObj.Connect());
       
   155 	fs.PushL();
       
   156 
       
   157 	TBuf<100> privatePath;
       
   158 	TBool isC32Exe = (RThread().SecureId() == KUidCommsProcess);
       
   159  	if(isC32Exe)	// If it is C32Exe, uppend private path with ESock
       
   160         {
       
   161 		privatePath = KEsockIniFileDir;
       
   162         }
       
   163 	else
       
   164         {
       
   165 		fs.iObj.PrivatePath(privatePath);
       
   166         }
       
   167 	
       
   168 	TFindFile ff(fs.iObj);
       
   169 	TFileListIter iter;
       
   170 	
       
   171 	if(aName == ESOCK_INI_DATA || aName.Length() == 0) 
       
   172 		{
       
   173 		CDir* ownedFileList = NULL;
       
   174 		if(iFileList)
       
   175 			{
       
   176 			iter.Set(iFileList);
       
   177 			}
       
   178 		else
       
   179 			{
       
   180 			// Have to build own file list
       
   181 			if(ff.FindWildByDir(KEsockWildCard, privatePath, ownedFileList) == KErrNone)
       
   182 				{
       
   183 				CleanupStack::PushL(ownedFileList);
       
   184 				iter.Set(ownedFileList);
       
   185 				}
       
   186 			}
       
   187 		_LIT(KSockManMainSectionName,"sockman");
       
   188 		_LIT(KProtocolListItemName,"protocols");
       
   189 		TPtrC protocols;
       
   190 		TInt err = KErrNone;
       
   191 		
       
   192 		_LIT(KTxtComma,",");
       
   193 		_LIT(KNewLine,"\r\n");
       
   194 		_LIT(KTxtIniFileStart,"[sockman] protocols= ");
       
   195 		
       
   196 		protocol_buf->InsertL(protocol_pos, (TAny*)(&KTxtIniFileStart)->Ptr(), (&KTxtIniFileStart)->Size());
       
   197 		protocol_pos+= (&KTxtIniFileStart)->Size();
       
   198 
       
   199 		TBool noBackupDirSearched(EFalse);
       
   200 		while (err==KErrNone)                
       
   201 			{
       
   202 			TBool firstEntry = ETrue;
       
   203 			while(const TEntry* entry = iter++)	//for (TInt i=0; i < iFileList->Count(); i++)    
       
   204 				{
       
   205 				TParse fullentry;
       
   206 				fullentry.Set(entry->iName,& ff.File(),NULL);      
       
   207 				TAutoClose<RFile> file;
       
   208 				User::LeaveIfError(file.iObj.Open(fs.iObj,fullentry.FullName(),EFileStreamText|EFileRead));
       
   209 				file.PushL();
       
   210 				User::LeaveIfError(file.iObj.Size(data_size));
       
   211 
       
   212 				// Following BR1123 we presume that all files are narrow-char only and widen them here
       
   213 				__ASSERT_COMPILE(sizeof(TText) == 2);
       
   214 				TUint8* rawBuff = (TUint8*) User::AllocLC(data_size * sizeof(TText));
       
   215 				TPtr8 rawTPtr(rawBuff, data_size * sizeof(TText));
       
   216 				User::LeaveIfError(file.iObj.Read(rawTPtr));
       
   217 
       
   218 				TText* dstPtr = (TText*) rawBuff;
       
   219 				for(TInt i = data_size - 1; i >= 0; --i)
       
   220 					{
       
   221 					dstPtr[i] = rawBuff[i];
       
   222 					}
       
   223 				iPtr.Set((TText*) rawBuff, data_size, data_size);
       
   224 				CleanupStack::Pop();  // Get data off; destructor takes care of freeing iPtr
       
   225 				
       
   226 				if(FindVar(KSockManMainSectionName,KProtocolListItemName,protocols))
       
   227 					{
       
   228 					//Store the protocol in the protocol dynamic buffer
       
   229 					if(firstEntry)
       
   230 						{
       
   231 						firstEntry = EFalse;
       
   232 						}
       
   233 					else
       
   234 						{
       
   235 						protocol_buf->ExpandL(protocol_pos, (&KTxtComma)->Size());
       
   236 						protocol_buf->Write(protocol_pos,(TAny*)(&KTxtComma)->Ptr(), (&KTxtComma)->Size());
       
   237 						protocol_pos+=(&KTxtComma)->Size();
       
   238 						}
       
   239 					protocol_buf->ExpandL(protocol_pos, protocols.Size());
       
   240 					protocol_buf->Write(protocol_pos, protocols.Ptr(), protocols.Size());
       
   241 					protocol_pos+=protocols.Size();
       
   242 					}
       
   243 				else
       
   244 					{
       
   245 					// Protocols line absent; whole of text is "trailer"
       
   246 					protocols.Set(iPtr.Ptr(), 0);
       
   247 					data_buf->ExpandL(data_pos, (&KNewLine)->Size());
       
   248 					data_buf->Write(data_pos, (TAny*)(&KNewLine)->Ptr(), (&KNewLine)->Size());
       
   249 					data_pos+=(&KNewLine)->Size();
       
   250 					}
       
   251 				
       
   252 				TInt dif = (protocols.Ptr()+protocols.Length()) - iPtr.Ptr();
       
   253 				
       
   254 				//Store the rest of the file in the data dynamic buffer
       
   255 				data_buf->ExpandL(data_pos, (data_size-dif)*sizeof(TText));
       
   256 				data_buf->Write(data_pos, (protocols.Ptr()+protocols.Length()), (data_size-dif)*sizeof(TText));
       
   257 				data_pos+= (data_size - dif)*sizeof(TText);
       
   258 				
       
   259 				//Delete temporary buffer
       
   260 				delete (TText*)iPtr.Ptr();
       
   261 				iPtr.Set(NULL,0,0);
       
   262 				file.Pop();
       
   263 				}
       
   264 			
       
   265 			if(ownedFileList)
       
   266 				{
       
   267 				CleanupStack::PopAndDestroy(ownedFileList);
       
   268 
       
   269 				//Continue the search in the next drive in the search sequence
       
   270 				err=ff.FindWild(ownedFileList); 
       
   271 				
       
   272 				if (err==KErrNone)
       
   273 					{
       
   274 					CleanupStack::PushL(ownedFileList);
       
   275 					iter.Set(ownedFileList);
       
   276 					protocol_buf->ExpandL(protocol_pos, (&KTxtComma)->Size());
       
   277 					protocol_buf->Write(protocol_pos,(TAny*)(&KTxtComma)->Ptr(), (&KTxtComma)->Size());
       
   278 					protocol_pos+=(&KTxtComma)->Size();
       
   279 					}
       
   280 				else if (err==KErrNoMemory)
       
   281 					{
       
   282 					User::Leave(err);
       
   283 					}
       
   284 				else if(err==KErrNotFound && !noBackupDirSearched)
       
   285 					{
       
   286  					//It's time to look into nobackup directory
       
   287  					noBackupDirSearched = ETrue;
       
   288  					if(isC32Exe)	// If it is C32Exe, uppend private path with ESock
       
   289          				{
       
   290  						privatePath = KEsockNoBackupDir;
       
   291  						err = ff.FindWildByDir(KEsockWildCard, privatePath, ownedFileList);
       
   292  						if(err == KErrNone)
       
   293  							{
       
   294  							CleanupStack::PushL(ownedFileList);
       
   295  							iter.Set(ownedFileList);
       
   296  							}
       
   297          				}
       
   298  					}
       
   299 				}
       
   300 			else
       
   301 			    {
       
   302 			    err=KErrNotFound; // Break out of while loop
       
   303 			    }
       
   304 			}
       
   305 		
       
   306 		//Copy all the collated esk bodies into the protocol_buf after the protocol list
       
   307 		protocol_buf->ExpandL(protocol_pos, data_buf->Size());
       
   308 		protocol_buf->Write(protocol_pos, data_buf->Ptr(0), data_buf->Size());
       
   309 		
       
   310 		//Copy the all collated initialisation information into its final destination
       
   311 		TText* newinifile = (TText*)User::AllocL(protocol_buf->Size());
       
   312 		protocol_buf->Read(0, newinifile, protocol_buf->Size());
       
   313 		
       
   314 		data_size = protocol_buf->Size() / (TInt) sizeof(TText);
       
   315 		iPtr.Set(newinifile, data_size, data_size);
       
   316 		
       
   317 		fs.Pop();
       
   318 		}
       
   319 	else
       
   320 	// Deals with standard .ini file
       
   321 		{
       
   322 		
       
   323  		TInt err = KErrNone;
       
   324  		err = ff.FindByDir(aName, privatePath);
       
   325  		if(err!=KErrNone && isC32Exe)
       
   326  			{
       
   327  			privatePath = KEsockNoBackupDir;
       
   328  			User::LeaveIfError(ff.FindByDir(aName, privatePath));	
       
   329  			}
       
   330  				
       
   331 		iName=ff.File().AllocL();
       
   332 		
       
   333 		TAutoClose<RFile> file;
       
   334 		TInt size;
       
   335 		User::LeaveIfError(file.iObj.Open(fs.iObj,*iName,EFileStreamText|EFileRead));
       
   336 		file.PushL();
       
   337 		
       
   338 		User::LeaveIfError(file.iObj.Size(size));
       
   339 		TText* data=(TText*)User::AllocL(size);
       
   340 		iPtr.Set(data, size/(TInt)sizeof(TText), size/(TInt)sizeof(TText));
       
   341 		TPtr8 dest((TUint8*)data, 0, size);
       
   342 		User::LeaveIfError(file.iObj.Read(dest));
       
   343 		
       
   344 		TUint8* ptr = (TUint8*)data;
       
   345 		//
       
   346 		// This is orderred as FEFF assuming the processor is Little Endian
       
   347 		// The data in the file is FFFE.		PRR 28/9/98
       
   348 		//
       
   349 		if(size>=(TInt)sizeof(TText) && iPtr[0]==0xFEFF)
       
   350 			{
       
   351 			// UNICODE Text file so lose the FFFE
       
   352 			Mem::Copy(ptr, ptr+sizeof(TText), size-sizeof(TText));
       
   353 			iPtr.Set(data, size/(TInt)sizeof(TText)-1, size/(TInt)sizeof(TText)-1);
       
   354 			}
       
   355 		else if(size)
       
   356 			{
       
   357 			// NON-UNICODE so convert to UNICODE
       
   358 			TText* newdata = (TText*)User::AllocL(size*sizeof(TText));
       
   359 			iPtr.Set(newdata, size, size);
       
   360 			TInt i;
       
   361 			for(i=0 ; i<size ; ++i)
       
   362 				iPtr[i]=ptr[i];
       
   363 			delete data;
       
   364 			}
       
   365 		
       
   366 		file.Pop();
       
   367 		fs.Pop();
       
   368 		
       
   369 		}
       
   370 	CleanupStack::PopAndDestroy(2); // remove protocol_buf - data_buf
       
   371 	}
       
   372 
       
   373 EXPORT_C TBool CESockIniData::FindVar(const TDesC &aVarName, TPtrC &aResult) const
       
   374 	{
       
   375 	TInt pos=iPtr.Find(aVarName);
       
   376 	if (pos==KErrNotFound)
       
   377 		return(EFalse);
       
   378 	TLex lex(iPtr.Mid(pos));
       
   379 	lex.SkipCharacters();
       
   380 	lex.SkipSpaceAndMark();		// Should be at the start of the data
       
   381 	lex.SkipCharacters();
       
   382 	aResult.Set(lex.MarkedToken().Ptr(),lex.MarkedToken().Length());
       
   383 	return(ETrue);
       
   384 	}
       
   385 
       
   386 EXPORT_C TBool CESockIniData::FindVar(const TDesC &aVarName, TInt &aResult) const
       
   387 	{
       
   388 	TPtrC ptr(NULL,0);
       
   389 	if (FindVar(aVarName,ptr))
       
   390 		{
       
   391 		TLex lex(ptr);
       
   392 		if (lex.Val(aResult)==KErrNone)
       
   393 			return(ETrue);
       
   394 		}
       
   395 	return(EFalse);
       
   396 	}
       
   397 
       
   398 EXPORT_C TBool CESockIniData::FindVar(const TDesC &aSection,const TDesC &aVarName,TPtrC &aResult) const
       
   399 /**
       
   400 Find a variable's value given a section name and a var name
       
   401 */
       
   402 	{
       
   403 	__ASSERT_DEBUG(aSection.Length()<=KTokenSize,Panic(ESectionNameTooBig));
       
   404 	__ASSERT_DEBUG(aVarName.Length()<=KTokenSize,Panic(EVarNameTooBig));
       
   405 
       
   406 	TPtr sectionToken=iToken->Des();
       
   407 	_LIT(sectionTokenString,"[%S]");
       
   408 	sectionToken.Format(sectionTokenString,&aSection);
       
   409 	TInt sectionStart=iPtr.Find(sectionToken);
       
   410 	if (sectionStart==KErrNotFound)
       
   411 		return EFalse;
       
   412 	TPtrC section=iPtr.Mid(sectionStart);
       
   413 	sectionStart+=section.Find(TPtrC(_S("]")));
       
   414 	if (sectionStart==KErrNotFound)
       
   415 		return EFalse;
       
   416 	sectionStart++;
       
   417 	section.Set(iPtr.Mid(sectionStart));
       
   418 	
       
   419 	TInt sectionEnd=section.Find(TPtrC(_S("[")));
       
   420 	if (sectionEnd==KErrNotFound)
       
   421 		sectionEnd=iPtr.Length()-sectionStart;
       
   422 	
       
   423 	section.Set(iPtr.Mid(sectionStart,sectionEnd));
       
   424 	TPtr varToken=iToken->Des();
       
   425 	_LIT(varTokenString,"%S=");
       
   426 	varToken.Format(varTokenString,&aVarName);
       
   427 	TInt pos=section.Find(varToken);
       
   428 	if (pos==KErrNotFound)
       
   429 		return EFalse;
       
   430 	TLex lex(section.Mid(pos));
       
   431 	lex.SkipCharacters();
       
   432 	lex.SkipSpaceAndMark();		// Should be at the start of the data
       
   433 	lex.SkipCharacters();
       
   434 	aResult.Set(lex.MarkedToken().Ptr(),lex.MarkedToken().Length());
       
   435 	return(ETrue);
       
   436 
       
   437 	}
       
   438 
       
   439 EXPORT_C TBool CESockIniData::FindVar(const TDesC &aSection,const TDesC &aVarName,TInt &aResult) const
       
   440 	{
       
   441 	TPtrC ptr(NULL,0);
       
   442 	if (FindVar(aSection,aVarName,ptr))
       
   443 		{
       
   444 		TLex lex(ptr);
       
   445 		if (lex.Val(aResult)==KErrNone)
       
   446 			return(ETrue);
       
   447 		}
       
   448 	return(EFalse);
       
   449 }
       
   450 
       
   451 EXPORT_C TInt CESockIniData::WriteVar(const TDesC& aSection,const TDesC& aVarName,TInt aValue)
       
   452 /**
       
   453 Changes the string associated with a token
       
   454 */
       
   455 	{
       
   456 	TBuf<32> buf;
       
   457 	buf.Num(aValue);
       
   458 	return WriteVar(aSection, aVarName, buf);
       
   459 	}
       
   460 
       
   461 EXPORT_C TInt CESockIniData::WriteVar(const TDesC& aSection,const TDesC& aVarName,const TDesC& aValue)
       
   462 /**
       
   463 Changes the string associated with a token
       
   464 */
       
   465 	{
       
   466 	// First find the variable - this gives us a descriptor into the
       
   467 	// ini data giving the bound of the item that has gto be replaced.
       
   468 	TPtrC ptr;
       
   469 	
       
   470 	if (!FindVar(aSection, aVarName, ptr))
       
   471 		return KErrNotFound;
       
   472 	
       
   473 	TInt pos = ptr.Ptr()-iPtr.Ptr();
       
   474 	TInt size = (iPtr.Length()+aValue.Length()-ptr.Length())*sizeof(TText);
       
   475 
       
   476 	if (size>iPtr.MaxLength())
       
   477 		{
       
   478 		TText* newdata = (TText*)User::ReAlloc((TUint8*)iPtr.Ptr(), size); 
       
   479 		if (newdata == 0)
       
   480 			return KErrNoMemory;
       
   481 
       
   482 		iPtr.Set(newdata, iPtr.Length(), size/(TInt)sizeof(TText));
       
   483 		}
       
   484 	
       
   485 	iPtr.Replace(pos, ptr.Length(), aValue);
       
   486 	return KErrNone;
       
   487 	}
       
   488 
       
   489 EXPORT_C void CESockIniData::CommitL()
       
   490 	{
       
   491 	TAutoClose<RFs> fs;
       
   492 	User::LeaveIfError(fs.iObj.Connect());
       
   493 	fs.PushL();
       
   494 
       
   495 	TAutoClose<RFile> file;
       
   496 	User::LeaveIfError(file.iObj.Replace(fs.iObj,*iName,EFileStreamText|EFileWrite));
       
   497 	file.PushL();
       
   498 
       
   499 	TPtrC8 ptrc8((TUint8*)iPtr.Ptr(), iPtr.Size());
       
   500 	User::LeaveIfError(file.iObj.Write(ptrc8));
       
   501 
       
   502 	file.Pop();
       
   503 	fs.Pop();
       
   504 	}
       
   505