genericservices/systemagent/src/halsettings/halfiles.cpp
changeset 0 e4d67989cc36
child 20 a2e897c5c62b
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2007-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 // Initialise / Persist HAL Implementation of HALSettings
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include "halfiles.h"
       
    24 #include "halpatchdata.h"
       
    25 #include "haldebug.h"
       
    26 
       
    27 
       
    28 /**
       
    29 Constructor of THalFileHeader class
       
    30 @param aMachineUid Machine Uid
       
    31 @param aTypePrefix header 'h' 'a' 'l' and version no.
       
    32 */
       
    33 THalFileHeader::THalFileHeader(TUint32 aMachineUid, TUint32 aTypePrefix)
       
    34 : iMachineUid (aMachineUid), iTypePrefix(aTypePrefix){}
       
    35 		
       
    36 /**
       
    37 Validate header of the hal.dat file.
       
    38 @return KErrNone if successful otherwise KErrCorrupt.
       
    39 */
       
    40 TInt THalFileHeader::ValidateHeader() 
       
    41 	{
       
    42 	TInt result;
       
    43 	TInt machineUID;
       
    44 	result = HAL::Get(HAL::EMachineUid,machineUID);	
       
    45 	if (result != KErrNone)
       
    46 		return result;	
       
    47 	if(iTypePrefix != typePrefix && machineUID != iMachineUid)
       
    48 		return KErrCorrupt;
       
    49 	return result;
       
    50 	}
       
    51 
       
    52 /**
       
    53 Get the path (drive & folder path) of the HAL data file.
       
    54 @param aPathName On completion this will contain the result.
       
    55 */	
       
    56 static void GetSystemDrivePath(THalFileName& aPathName)
       
    57 	{
       
    58 	aPathName.Copy(KHalFilePath);
       
    59 	aPathName[0] = 'A' + static_cast<TInt>(RFs::GetSystemDrive());
       
    60 	}
       
    61 
       
    62 /**
       
    63 Initialise the HAL.
       
    64 Read the saved HAL file - containing a series of saved HAL attributes. If present, initialise
       
    65 each attribute saved.
       
    66 @return KErrNone if successful, otherwise any system wide error code.
       
    67 */
       
    68 TInt InitialiseHAL()
       
    69 	{
       
    70     __HS_TRACE("HalSettings: InitialiseHAL");
       
    71     
       
    72 	//File server to open the HAL.DAT file
       
    73 	RFs fs;
       
    74 	TInt result = fs.Connect(); 
       
    75 	if (result != KErrNone)
       
    76 		{
       
    77 		return result;
       
    78 		}
       
    79 	//Get the system drive path
       
    80 	THalFileName halFileName;
       
    81 	GetSystemDrivePath(halFileName);
       
    82 	halFileName.Append(KHalFileName);
       
    83 	
       
    84 	//Open the hal.dat file with EFileShare Exclusive mode to read HAL attributes
       
    85 	RFile file;
       
    86 	result = file.Open(fs,halFileName,EFileRead | EFileShareExclusive);
       
    87 	if (result != KErrNone)
       
    88 		{
       
    89 		fs.Close();
       
    90 		return result;		
       
    91 		}
       
    92 		
       
    93 	//Checking the file integrity (total size should always be multiples of 8) 	
       
    94 	TInt size=0;
       
    95 	result = file.Size(size);
       
    96 	if (result != KErrNone || size <= sizeof(THalFileHeader) || (size&7) != 0)
       
    97 		{
       
    98 		file.Close();
       
    99 		fs.Close();
       
   100 		return KErrCorrupt;	
       
   101 		}
       
   102 		
       
   103 	//Check to see that the filesize of HAL.DAT is not greater than if it contained entries for the max number of attributes
       
   104 	TInt maxDevices = 1;
       
   105 	HAL::Get(HALData::EDisplayNumberOfScreens,maxDevices);
       
   106 	TInt maxSize = (maxDevices * (TInt)HALData::ENumHalAttributes * (sizeof(HALData::TAttribute) + sizeof(TInt)) + sizeof(THalFileHeader));
       
   107 	if (size > maxSize)
       
   108 		//devices * number of attributes * (attribute + value) + header
       
   109 		{
       
   110 		file.Close();
       
   111 		fs.Close();
       
   112 		return KErrCorrupt;
       
   113 		}
       
   114 		
       
   115 	//Allocate a buffer to read all HAL.DAT file
       
   116 	TInt* pBuf=(TInt*)User::Alloc(size);
       
   117 	if (!pBuf)
       
   118 		{
       
   119 		file.Close();
       
   120 		fs.Close();
       
   121 		return  KErrNoMemory;		
       
   122 		}
       
   123 	TPtr8 bptr((TUint8*)pBuf,size);
       
   124 	
       
   125 	//Read HAL.DAT to the allocated buffer	
       
   126 	result = file.Read(bptr);
       
   127 	if ( result == KErrNone)
       
   128 		{
       
   129 		const TInt* pD = pBuf;
       
   130 		const TInt* pE = pD + size/sizeof(TInt);
       
   131 		THalFileHeader header (*pD, *(pD+1));
       
   132 		pD += 2; //first 8 bytes are header  
       
   133 		
       
   134 		//Checking the validity of the file header and if valid set all HAL attributes
       
   135 		if ((result = header.ValidateHeader()) == KErrNone)
       
   136 			{
       
   137 			while (pD < pE)
       
   138 				{
       
   139 				TInt attrib = *pD++;
       
   140 				//the top 8 bits contain the device number
       
   141 				HAL::Set(((TUint)attrib)>>24, (HAL::TAttribute)(attrib & 0xFFFFFF), *pD++);
       
   142 				}
       
   143 			}
       
   144 		}
       
   145 	User::Free(pBuf);
       
   146 	file.Close();
       
   147 	fs.Close();
       
   148 	return(result);	
       
   149 	}
       
   150 
       
   151 /**
       
   152 Persist the HAL.
       
   153 Gets all HAL attributes, and their properties 
       
   154 then save attributes (which are meaningful and modifiable on this device) to hal.dat
       
   155 @return KErrNone if successful, otherwise any system wide error code.
       
   156 */
       
   157 TInt PersistHAL()
       
   158 	{
       
   159     __HS_TRACE("HalSettings: PersistHAL");
       
   160     
       
   161 	const TInt KHalProperties=HAL::EEntryDynamic|HAL::EEntryValid;
       
   162 	//Get all HAL attributes
       
   163 	HAL::SEntry* pE;
       
   164 	TInt nEntries;
       
   165 	TInt result = HAL::GetAll(nEntries, pE);
       
   166 	if ( result != KErrNone )
       
   167 		{
       
   168 		return result;
       
   169 		}
       
   170 	const HAL::SEntry* pS=pE;
       
   171 	const HAL::SEntry* pEnd=pS + nEntries;
       
   172 	TInt* pD = (TInt*)pE;
       
   173 		
       
   174     __HS_TRACE1("HalSettings: ENumHalAttributes == %d", HALData::ENumHalAttributes );
       
   175     __HS_TRACE1("HalSettings: KHalPenStatePersistenceDisabled == %d", KHalPenStatePersistenceDisabled );
       
   176 	
       
   177 	for (TInt s = 0; pS<pEnd; ++pS, ++s)
       
   178 		{
       
   179 		
       
   180 		__HS_TRACE3("HalSettings: Attr: %d; Prop: %x; Value: %x", s, pS->iProperties, pS->iValue );
       
   181  
       
   182 		if ((s%HAL::ENumHalAttributes) == HALData::EDisplayMemoryHandle)
       
   183 		    {		    
       
   184 		    if( pS->iValue >= KErrNone )
       
   185 		        {
       
   186 		        RHandleBase handle;
       
   187 		        handle.SetHandle(pS->iValue);
       
   188 		        handle.Close();
       
   189 		        }
       
   190 		    }
       
   191 				
       
   192 		// HAL::GetAll() will return all HAL attributes 
       
   193 		// But only need to save the attribute value which are valid and dynamic
       
   194 		if ((pS->iProperties & KHalProperties) != KHalProperties)
       
   195 			continue;
       
   196 			
       
   197 		// Do NOT save the EDisplayState as this could be off when system 
       
   198 		// shutdown and then when system startup occurs the display will never 
       
   199 		// be turned on
       
   200 		if ((s%HAL::ENumHalAttributes) == HALData::EDisplayState)
       
   201             continue;
       
   202 		
       
   203 		// Do NOT save the EPenState as if this is 0 on save it could disable 
       
   204 		// the touch screen on a reboot of the device on some platforms.
       
   205 		if ((KHalPenStatePersistenceDisabled==1) && 
       
   206 			(s%HAL::ENumHalAttributes) == HALData::EPenState )
       
   207             continue;
       
   208 			
       
   209 		// At this point we know this atribute must be saved to persitent store
       
   210 		__HS_TRACE1("HalSettings: Attribute %d saved", s%HAL::ENumHalAttributes);
       
   211 		
       
   212 		TInt v=pS->iValue;		
       
   213 		if((KHalNonSecureOffsetPersistenceDisabled == 1) &&
       
   214 		   (s%HAL::ENumHalAttributes) == HALData::ETimeNonSecureOffset)
       
   215 		   {
       
   216 		   // If product so wants, save the nonsecure offset always as zero (so during boot user time == secure time)
       
   217 		   v = 0;
       
   218 		   }
       
   219 		//top 8 bits are used to store device number next 3 is for the Hal attributes ENum value
       
   220 		*pD++=((s/HAL::ENumHalAttributes)<<24) + (s%HAL::ENumHalAttributes);
       
   221 		*pD++=v;
       
   222 		}
       
   223 	TUint nSaved=(pD-(TInt*)pE)>>1;
       
   224 	RFs fs;
       
   225 	//coverity[cleanup_stack]
       
   226 	/* pE is just a local pointer here and goes out of scope after the execution of the function
       
   227 	* This error is possibly thrown due to pE not made NULL in GetAll( ) but ,it should not be an issue here
       
   228 	* as Connect() is not a leaving function
       
   229 	*/
       
   230 	result=fs.Connect(); //
       
   231 	if ( result != KErrNone )
       
   232 		{
       
   233 		User::Free(pE);
       
   234 		return result;	
       
   235 		}
       
   236 	THalFileName halFile;
       
   237 	GetSystemDrivePath(halFile);
       
   238 	
       
   239 	// Ensure directory \private\SID exists in target drive
       
   240 	result = fs.MkDirAll(halFile);
       
   241 	if (result != KErrNone )
       
   242 		if(result != KErrAlreadyExists )
       
   243 			{
       
   244 			//coverity[cleanup_stack]
       
   245 			// Close() is not a leaving function
       
   246 			fs.Close();
       
   247 			User::Free(pE);
       
   248 			return 	result;
       
   249 			}
       
   250 	TInt muid=0;
       
   251 	
       
   252 	// Gets the machine's unique ID
       
   253 	result=HAL::Get(HAL::EMachineUid, muid);
       
   254 	if ( result != KErrNone )
       
   255 		{
       
   256 		//coverity[cleanup_stack]
       
   257 		// Close() is not a leaving function
       
   258 		fs.Close();
       
   259 		User::Free(pE);
       
   260 		return 	result;	
       
   261 		}
       
   262 		
       
   263 	//Allocating a buffer with size of header and data (HAL attributes)	
       
   264 	RBuf8 buf;
       
   265 	result = buf.ReAlloc(sizeof(THalFileHeader) + (nSaved*8));
       
   266 	if(result != KErrNone)
       
   267 		{
       
   268 		//coverity[cleanup_stack]
       
   269 		// Close() is not a leaving function
       
   270 		fs.Close();
       
   271 		User::Free(pE);
       
   272 		return 	result;		
       
   273 		}
       
   274 		
       
   275 	//Appending header and hal attributes to the allocated buffer		
       
   276 	THalFileHeader header (muid,typePrefix);
       
   277 	buf.Append((const TUint8*)&header,sizeof(THalFileHeader));
       
   278 	buf.Append((const TUint8*)pE, nSaved*8);
       
   279 	User::Free(pE);
       
   280 	
       
   281 	//Saving HAL setting to a temp file after that rename it to HAL.DAT
       
   282 	RFile file;
       
   283 	TFileName  tempFile;
       
   284 	result = file.Temp(fs,halFile,tempFile,EFileWrite|EFileShareExclusive);
       
   285 
       
   286 	if ( result == KErrNone )
       
   287 		{
       
   288 		result = file.Write(buf);
       
   289 		if ( result == KErrNone )
       
   290 			{
       
   291 			halFile.Append(KHalFileName); 
       
   292 			fs.Delete(halFile); // ignore if error 
       
   293 			result = file.Rename(halFile);
       
   294 			}
       
   295 		file.Close();	
       
   296 		}	
       
   297 	buf.Close();
       
   298 	fs.Close();
       
   299 	return result;
       
   300 	}
       
   301 	
       
   302 /**
       
   303 HAL Settings Manager.
       
   304 Manages the request for initialise and persist hal settings through command line
       
   305 For initialise it checks SID of the process send the request and command line parameter.
       
   306 If the SID = SID of EStart and command line is "INITIALISE" it initialise hal settings.
       
   307 For persistence it only checks the command line = "PERSIST"
       
   308 @return KErrNone if successful, otherwise any system wide error code.
       
   309 */
       
   310 TInt HALSettingsManager()
       
   311 	{
       
   312 	const TInt KMaxArgumentLength = 10;
       
   313 	const TInt KEStartSID = 0x10272C04; //SID of EStart
       
   314 	_LIT(KHalInitialise,"INITIALISE");
       
   315 	_LIT(KHalPersist,"PERSIST");
       
   316 
       
   317 	if (User::CommandLineLength() >  KMaxArgumentLength)
       
   318 		return KErrArgument;
       
   319 	TBuf<KMaxArgumentLength> args;
       
   320 	User::CommandLine(args);
       
   321 	TInt result;
       
   322 	
       
   323 	//Initialise or Persist HAL depending on command line arguments
       
   324 	if (args.CompareF(KHalInitialise) == 0)
       
   325 		{
       
   326 		if(User::CreatorSecureId() != KEStartSID)
       
   327 				return KErrPermissionDenied;	
       
   328 		result = InitialiseHAL();	
       
   329 		}
       
   330 	else if (args.CompareF(KHalPersist) == 0)
       
   331 		{
       
   332 		result = PersistHAL();
       
   333 		}
       
   334 	else
       
   335 		{
       
   336 		return KErrArgument;
       
   337 		}
       
   338 	return result;
       
   339 	}