genericservices/systemagent/src/halsettings/halfiles.cpp
changeset 31 ce057bb09d0b
child 45 4b03adbd26ca
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     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 				// We will not persisit the closed handle
       
   190 				continue;
       
   191 		        }
       
   192 		    }
       
   193 				
       
   194 		// HAL::GetAll() will return all HAL attributes 
       
   195 		// But only need to save the attribute value which are valid and dynamic
       
   196 		if ((pS->iProperties & KHalProperties) != KHalProperties)
       
   197 			continue;
       
   198 			
       
   199 		// Do NOT save the EDisplayState as this could be off when system 
       
   200 		// shutdown and then when system startup occurs the display will never 
       
   201 		// be turned on
       
   202 		if ((s%HAL::ENumHalAttributes) == HALData::EDisplayState)
       
   203             continue;
       
   204 		
       
   205 		// Do NOT save the EPenState as if this is 0 on save it could disable 
       
   206 		// the touch screen on a reboot of the device on some platforms.
       
   207 		if ((KHalPenStatePersistenceDisabled==1) && 
       
   208 			(s%HAL::ENumHalAttributes) == HALData::EPenState )
       
   209             continue;
       
   210 			
       
   211 		// At this point we know this atribute must be saved to persitent store
       
   212 		__HS_TRACE1("HalSettings: Attribute %d saved", s%HAL::ENumHalAttributes);
       
   213 		
       
   214 		TInt v=pS->iValue;		
       
   215 		if((KHalNonSecureOffsetPersistenceDisabled == 1) &&
       
   216 		   (s%HAL::ENumHalAttributes) == HALData::ETimeNonSecureOffset)
       
   217 		   {
       
   218 		   // If product so wants, save the nonsecure offset always as zero (so during boot user time == secure time)
       
   219 		   v = 0;
       
   220 		   }
       
   221 		//top 8 bits are used to store device number next 3 is for the Hal attributes ENum value
       
   222 		*pD++=((s/HAL::ENumHalAttributes)<<24) + (s%HAL::ENumHalAttributes);
       
   223 		*pD++=v;
       
   224 		}
       
   225 	TUint nSaved=(pD-(TInt*)pE)>>1;
       
   226 	RFs fs;
       
   227 	//coverity[cleanup_stack]
       
   228 	/* pE is just a local pointer here and goes out of scope after the execution of the function
       
   229 	* This error is possibly thrown due to pE not made NULL in GetAll( ) but ,it should not be an issue here
       
   230 	* as Connect() is not a leaving function
       
   231 	*/
       
   232 	result=fs.Connect(); //
       
   233 	if ( result != KErrNone )
       
   234 		{
       
   235 		User::Free(pE);
       
   236 		return result;	
       
   237 		}
       
   238 	THalFileName halFile;
       
   239 	GetSystemDrivePath(halFile);
       
   240 	
       
   241 	// Ensure directory \private\SID exists in target drive
       
   242 	result = fs.MkDirAll(halFile);
       
   243 	if (result != KErrNone )
       
   244 		if(result != KErrAlreadyExists )
       
   245 			{
       
   246 			//coverity[cleanup_stack]
       
   247 			// Close() is not a leaving function
       
   248 			fs.Close();
       
   249 			User::Free(pE);
       
   250 			return 	result;
       
   251 			}
       
   252 	TInt muid=0;
       
   253 	
       
   254 	// Gets the machine's unique ID
       
   255 	result=HAL::Get(HAL::EMachineUid, muid);
       
   256 	if ( result != KErrNone )
       
   257 		{
       
   258 		//coverity[cleanup_stack]
       
   259 		// Close() is not a leaving function
       
   260 		fs.Close();
       
   261 		User::Free(pE);
       
   262 		return 	result;	
       
   263 		}
       
   264 		
       
   265 	//Allocating a buffer with size of header and data (HAL attributes)	
       
   266 	RBuf8 buf;
       
   267 	result = buf.ReAlloc(sizeof(THalFileHeader) + (nSaved*8));
       
   268 	if(result != KErrNone)
       
   269 		{
       
   270 		//coverity[cleanup_stack]
       
   271 		// Close() is not a leaving function
       
   272 		fs.Close();
       
   273 		User::Free(pE);
       
   274 		return 	result;		
       
   275 		}
       
   276 		
       
   277 	//Appending header and hal attributes to the allocated buffer		
       
   278 	THalFileHeader header (muid,typePrefix);
       
   279 	buf.Append((const TUint8*)&header,sizeof(THalFileHeader));
       
   280 	buf.Append((const TUint8*)pE, nSaved*8);
       
   281 	User::Free(pE);
       
   282 	
       
   283 	//Saving HAL setting to a temp file after that rename it to HAL.DAT
       
   284 	RFile file;
       
   285 	TFileName  tempFile;
       
   286 	result = file.Temp(fs,halFile,tempFile,EFileWrite|EFileShareExclusive);
       
   287 
       
   288 	if ( result == KErrNone )
       
   289 		{
       
   290 		result = file.Write(buf);
       
   291 		if ( result == KErrNone )
       
   292 			{
       
   293 			halFile.Append(KHalFileName); 
       
   294 			fs.Delete(halFile); // ignore if error 
       
   295 			result = file.Rename(halFile);
       
   296 			}
       
   297 		file.Close();	
       
   298 		}	
       
   299 	buf.Close();
       
   300 	fs.Close();
       
   301 	return result;
       
   302 	}
       
   303 	
       
   304 /**
       
   305 HAL Settings Manager.
       
   306 Manages the request for initialise and persist hal settings through command line
       
   307 For initialise it checks SID of the process send the request and command line parameter.
       
   308 If the SID = SID of EStart and command line is "INITIALISE" it initialise hal settings.
       
   309 For persistence it only checks the command line = "PERSIST"
       
   310 @return KErrNone if successful, otherwise any system wide error code.
       
   311 */
       
   312 TInt HALSettingsManager()
       
   313 	{
       
   314 	const TInt KMaxArgumentLength = 10;
       
   315 	const TInt KEStartSID = 0x10272C04; //SID of EStart
       
   316 	_LIT(KHalInitialise,"INITIALISE");
       
   317 	_LIT(KHalPersist,"PERSIST");
       
   318 
       
   319 	if (User::CommandLineLength() >  KMaxArgumentLength)
       
   320 		return KErrArgument;
       
   321 	TBuf<KMaxArgumentLength> args;
       
   322 	User::CommandLine(args);
       
   323 	TInt result;
       
   324 	
       
   325 	//Initialise or Persist HAL depending on command line arguments
       
   326 	if (args.CompareF(KHalInitialise) == 0)
       
   327 		{
       
   328 		if(User::CreatorSecureId() != KEStartSID)
       
   329 				return KErrPermissionDenied;	
       
   330 		result = InitialiseHAL();	
       
   331 		}
       
   332 	else if (args.CompareF(KHalPersist) == 0)
       
   333 		{
       
   334 		result = PersistHAL();
       
   335 		}
       
   336 	else
       
   337 		{
       
   338 		return KErrArgument;
       
   339 		}
       
   340 	return result;
       
   341 	}