os/ossrv/genericservices/systemagent/src/halsettings/halfiles.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericservices/systemagent/src/halsettings/halfiles.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,341 @@
     1.4 +// Copyright (c) 2007-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 "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 +// Initialise / Persist HAL Implementation of HALSettings
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +/**
    1.22 + @file
    1.23 + @internalComponent
    1.24 +*/
    1.25 +
    1.26 +#include "halfiles.h"
    1.27 +#include "halpatchdata.h"
    1.28 +#include "haldebug.h"
    1.29 +
    1.30 +
    1.31 +/**
    1.32 +Constructor of THalFileHeader class
    1.33 +@param aMachineUid Machine Uid
    1.34 +@param aTypePrefix header 'h' 'a' 'l' and version no.
    1.35 +*/
    1.36 +THalFileHeader::THalFileHeader(TUint32 aMachineUid, TUint32 aTypePrefix)
    1.37 +: iMachineUid (aMachineUid), iTypePrefix(aTypePrefix){}
    1.38 +		
    1.39 +/**
    1.40 +Validate header of the hal.dat file.
    1.41 +@return KErrNone if successful otherwise KErrCorrupt.
    1.42 +*/
    1.43 +TInt THalFileHeader::ValidateHeader() 
    1.44 +	{
    1.45 +	TInt result;
    1.46 +	TInt machineUID;
    1.47 +	result = HAL::Get(HAL::EMachineUid,machineUID);	
    1.48 +	if (result != KErrNone)
    1.49 +		return result;	
    1.50 +	if(iTypePrefix != typePrefix && machineUID != iMachineUid)
    1.51 +		return KErrCorrupt;
    1.52 +	return result;
    1.53 +	}
    1.54 +
    1.55 +/**
    1.56 +Get the path (drive & folder path) of the HAL data file.
    1.57 +@param aPathName On completion this will contain the result.
    1.58 +*/	
    1.59 +static void GetSystemDrivePath(THalFileName& aPathName)
    1.60 +	{
    1.61 +	aPathName.Copy(KHalFilePath);
    1.62 +	aPathName[0] = 'A' + static_cast<TInt>(RFs::GetSystemDrive());
    1.63 +	}
    1.64 +
    1.65 +/**
    1.66 +Initialise the HAL.
    1.67 +Read the saved HAL file - containing a series of saved HAL attributes. If present, initialise
    1.68 +each attribute saved.
    1.69 +@return KErrNone if successful, otherwise any system wide error code.
    1.70 +*/
    1.71 +TInt InitialiseHAL()
    1.72 +	{
    1.73 +    __HS_TRACE("HalSettings: InitialiseHAL");
    1.74 +    
    1.75 +	//File server to open the HAL.DAT file
    1.76 +	RFs fs;
    1.77 +	TInt result = fs.Connect(); 
    1.78 +	if (result != KErrNone)
    1.79 +		{
    1.80 +		return result;
    1.81 +		}
    1.82 +	//Get the system drive path
    1.83 +	THalFileName halFileName;
    1.84 +	GetSystemDrivePath(halFileName);
    1.85 +	halFileName.Append(KHalFileName);
    1.86 +	
    1.87 +	//Open the hal.dat file with EFileShare Exclusive mode to read HAL attributes
    1.88 +	RFile file;
    1.89 +	result = file.Open(fs,halFileName,EFileRead | EFileShareExclusive);
    1.90 +	if (result != KErrNone)
    1.91 +		{
    1.92 +		fs.Close();
    1.93 +		return result;		
    1.94 +		}
    1.95 +		
    1.96 +	//Checking the file integrity (total size should always be multiples of 8) 	
    1.97 +	TInt size=0;
    1.98 +	result = file.Size(size);
    1.99 +	if (result != KErrNone || size <= sizeof(THalFileHeader) || (size&7) != 0)
   1.100 +		{
   1.101 +		file.Close();
   1.102 +		fs.Close();
   1.103 +		return KErrCorrupt;	
   1.104 +		}
   1.105 +		
   1.106 +	//Check to see that the filesize of HAL.DAT is not greater than if it contained entries for the max number of attributes
   1.107 +	TInt maxDevices = 1;
   1.108 +	HAL::Get(HALData::EDisplayNumberOfScreens,maxDevices);
   1.109 +	TInt maxSize = (maxDevices * (TInt)HALData::ENumHalAttributes * (sizeof(HALData::TAttribute) + sizeof(TInt)) + sizeof(THalFileHeader));
   1.110 +	if (size > maxSize)
   1.111 +		//devices * number of attributes * (attribute + value) + header
   1.112 +		{
   1.113 +		file.Close();
   1.114 +		fs.Close();
   1.115 +		return KErrCorrupt;
   1.116 +		}
   1.117 +		
   1.118 +	//Allocate a buffer to read all HAL.DAT file
   1.119 +	TInt* pBuf=(TInt*)User::Alloc(size);
   1.120 +	if (!pBuf)
   1.121 +		{
   1.122 +		file.Close();
   1.123 +		fs.Close();
   1.124 +		return  KErrNoMemory;		
   1.125 +		}
   1.126 +	TPtr8 bptr((TUint8*)pBuf,size);
   1.127 +	
   1.128 +	//Read HAL.DAT to the allocated buffer	
   1.129 +	result = file.Read(bptr);
   1.130 +	if ( result == KErrNone)
   1.131 +		{
   1.132 +		const TInt* pD = pBuf;
   1.133 +		const TInt* pE = pD + size/sizeof(TInt);
   1.134 +		THalFileHeader header (*pD, *(pD+1));
   1.135 +		pD += 2; //first 8 bytes are header  
   1.136 +		
   1.137 +		//Checking the validity of the file header and if valid set all HAL attributes
   1.138 +		if ((result = header.ValidateHeader()) == KErrNone)
   1.139 +			{
   1.140 +			while (pD < pE)
   1.141 +				{
   1.142 +				TInt attrib = *pD++;
   1.143 +				//the top 8 bits contain the device number
   1.144 +				HAL::Set(((TUint)attrib)>>24, (HAL::TAttribute)(attrib & 0xFFFFFF), *pD++);
   1.145 +				}
   1.146 +			}
   1.147 +		}
   1.148 +	User::Free(pBuf);
   1.149 +	file.Close();
   1.150 +	fs.Close();
   1.151 +	return(result);	
   1.152 +	}
   1.153 +
   1.154 +/**
   1.155 +Persist the HAL.
   1.156 +Gets all HAL attributes, and their properties 
   1.157 +then save attributes (which are meaningful and modifiable on this device) to hal.dat
   1.158 +@return KErrNone if successful, otherwise any system wide error code.
   1.159 +*/
   1.160 +TInt PersistHAL()
   1.161 +	{
   1.162 +    __HS_TRACE("HalSettings: PersistHAL");
   1.163 +    
   1.164 +	const TInt KHalProperties=HAL::EEntryDynamic|HAL::EEntryValid;
   1.165 +	//Get all HAL attributes
   1.166 +	HAL::SEntry* pE;
   1.167 +	TInt nEntries;
   1.168 +	TInt result = HAL::GetAll(nEntries, pE);
   1.169 +	if ( result != KErrNone )
   1.170 +		{
   1.171 +		return result;
   1.172 +		}
   1.173 +	const HAL::SEntry* pS=pE;
   1.174 +	const HAL::SEntry* pEnd=pS + nEntries;
   1.175 +	TInt* pD = (TInt*)pE;
   1.176 +		
   1.177 +    __HS_TRACE1("HalSettings: ENumHalAttributes == %d", HALData::ENumHalAttributes );
   1.178 +    __HS_TRACE1("HalSettings: KHalPenStatePersistenceDisabled == %d", KHalPenStatePersistenceDisabled );
   1.179 +	
   1.180 +	for (TInt s = 0; pS<pEnd; ++pS, ++s)
   1.181 +		{
   1.182 +		
   1.183 +		__HS_TRACE3("HalSettings: Attr: %d; Prop: %x; Value: %x", s, pS->iProperties, pS->iValue );
   1.184 + 
   1.185 +		if ((s%HAL::ENumHalAttributes) == HALData::EDisplayMemoryHandle)
   1.186 +		    {		    
   1.187 +		    if( pS->iValue >= KErrNone )
   1.188 +		        {
   1.189 +		        RHandleBase handle;
   1.190 +		        handle.SetHandle(pS->iValue);
   1.191 +		        handle.Close();
   1.192 +				// We will not persisit the closed handle
   1.193 +				continue;
   1.194 +		        }
   1.195 +		    }
   1.196 +				
   1.197 +		// HAL::GetAll() will return all HAL attributes 
   1.198 +		// But only need to save the attribute value which are valid and dynamic
   1.199 +		if ((pS->iProperties & KHalProperties) != KHalProperties)
   1.200 +			continue;
   1.201 +			
   1.202 +		// Do NOT save the EDisplayState as this could be off when system 
   1.203 +		// shutdown and then when system startup occurs the display will never 
   1.204 +		// be turned on
   1.205 +		if ((s%HAL::ENumHalAttributes) == HALData::EDisplayState)
   1.206 +            continue;
   1.207 +		
   1.208 +		// Do NOT save the EPenState as if this is 0 on save it could disable 
   1.209 +		// the touch screen on a reboot of the device on some platforms.
   1.210 +		if ((KHalPenStatePersistenceDisabled==1) && 
   1.211 +			(s%HAL::ENumHalAttributes) == HALData::EPenState )
   1.212 +            continue;
   1.213 +			
   1.214 +		// At this point we know this atribute must be saved to persitent store
   1.215 +		__HS_TRACE1("HalSettings: Attribute %d saved", s%HAL::ENumHalAttributes);
   1.216 +		
   1.217 +		TInt v=pS->iValue;		
   1.218 +		if((KHalNonSecureOffsetPersistenceDisabled == 1) &&
   1.219 +		   (s%HAL::ENumHalAttributes) == HALData::ETimeNonSecureOffset)
   1.220 +		   {
   1.221 +		   // If product so wants, save the nonsecure offset always as zero (so during boot user time == secure time)
   1.222 +		   v = 0;
   1.223 +		   }
   1.224 +		//top 8 bits are used to store device number next 3 is for the Hal attributes ENum value
   1.225 +		*pD++=((s/HAL::ENumHalAttributes)<<24) + (s%HAL::ENumHalAttributes);
   1.226 +		*pD++=v;
   1.227 +		}
   1.228 +	TUint nSaved=(pD-(TInt*)pE)>>1;
   1.229 +	RFs fs;
   1.230 +	//coverity[cleanup_stack]
   1.231 +	/* pE is just a local pointer here and goes out of scope after the execution of the function
   1.232 +	* This error is possibly thrown due to pE not made NULL in GetAll( ) but ,it should not be an issue here
   1.233 +	* as Connect() is not a leaving function
   1.234 +	*/
   1.235 +	result=fs.Connect(); //
   1.236 +	if ( result != KErrNone )
   1.237 +		{
   1.238 +		User::Free(pE);
   1.239 +		return result;	
   1.240 +		}
   1.241 +	THalFileName halFile;
   1.242 +	GetSystemDrivePath(halFile);
   1.243 +	
   1.244 +	// Ensure directory \private\SID exists in target drive
   1.245 +	result = fs.MkDirAll(halFile);
   1.246 +	if (result != KErrNone )
   1.247 +		if(result != KErrAlreadyExists )
   1.248 +			{
   1.249 +			//coverity[cleanup_stack]
   1.250 +			// Close() is not a leaving function
   1.251 +			fs.Close();
   1.252 +			User::Free(pE);
   1.253 +			return 	result;
   1.254 +			}
   1.255 +	TInt muid=0;
   1.256 +	
   1.257 +	// Gets the machine's unique ID
   1.258 +	result=HAL::Get(HAL::EMachineUid, muid);
   1.259 +	if ( result != KErrNone )
   1.260 +		{
   1.261 +		//coverity[cleanup_stack]
   1.262 +		// Close() is not a leaving function
   1.263 +		fs.Close();
   1.264 +		User::Free(pE);
   1.265 +		return 	result;	
   1.266 +		}
   1.267 +		
   1.268 +	//Allocating a buffer with size of header and data (HAL attributes)	
   1.269 +	RBuf8 buf;
   1.270 +	result = buf.ReAlloc(sizeof(THalFileHeader) + (nSaved*8));
   1.271 +	if(result != KErrNone)
   1.272 +		{
   1.273 +		//coverity[cleanup_stack]
   1.274 +		// Close() is not a leaving function
   1.275 +		fs.Close();
   1.276 +		User::Free(pE);
   1.277 +		return 	result;		
   1.278 +		}
   1.279 +		
   1.280 +	//Appending header and hal attributes to the allocated buffer		
   1.281 +	THalFileHeader header (muid,typePrefix);
   1.282 +	buf.Append((const TUint8*)&header,sizeof(THalFileHeader));
   1.283 +	buf.Append((const TUint8*)pE, nSaved*8);
   1.284 +	User::Free(pE);
   1.285 +	
   1.286 +	//Saving HAL setting to a temp file after that rename it to HAL.DAT
   1.287 +	RFile file;
   1.288 +	TFileName  tempFile;
   1.289 +	result = file.Temp(fs,halFile,tempFile,EFileWrite|EFileShareExclusive);
   1.290 +
   1.291 +	if ( result == KErrNone )
   1.292 +		{
   1.293 +		result = file.Write(buf);
   1.294 +		if ( result == KErrNone )
   1.295 +			{
   1.296 +			halFile.Append(KHalFileName); 
   1.297 +			fs.Delete(halFile); // ignore if error 
   1.298 +			result = file.Rename(halFile);
   1.299 +			}
   1.300 +		file.Close();	
   1.301 +		}	
   1.302 +	buf.Close();
   1.303 +	fs.Close();
   1.304 +	return result;
   1.305 +	}
   1.306 +	
   1.307 +/**
   1.308 +HAL Settings Manager.
   1.309 +Manages the request for initialise and persist hal settings through command line
   1.310 +For initialise it checks SID of the process send the request and command line parameter.
   1.311 +If the SID = SID of EStart and command line is "INITIALISE" it initialise hal settings.
   1.312 +For persistence it only checks the command line = "PERSIST"
   1.313 +@return KErrNone if successful, otherwise any system wide error code.
   1.314 +*/
   1.315 +TInt HALSettingsManager()
   1.316 +	{
   1.317 +	const TInt KMaxArgumentLength = 10;
   1.318 +	const TInt KEStartSID = 0x10272C04; //SID of EStart
   1.319 +	_LIT(KHalInitialise,"INITIALISE");
   1.320 +	_LIT(KHalPersist,"PERSIST");
   1.321 +
   1.322 +	if (User::CommandLineLength() >  KMaxArgumentLength)
   1.323 +		return KErrArgument;
   1.324 +	TBuf<KMaxArgumentLength> args;
   1.325 +	User::CommandLine(args);
   1.326 +	TInt result;
   1.327 +	
   1.328 +	//Initialise or Persist HAL depending on command line arguments
   1.329 +	if (args.CompareF(KHalInitialise) == 0)
   1.330 +		{
   1.331 +		if(User::CreatorSecureId() != KEStartSID)
   1.332 +				return KErrPermissionDenied;	
   1.333 +		result = InitialiseHAL();	
   1.334 +		}
   1.335 +	else if (args.CompareF(KHalPersist) == 0)
   1.336 +		{
   1.337 +		result = PersistHAL();
   1.338 +		}
   1.339 +	else
   1.340 +		{
   1.341 +		return KErrArgument;
   1.342 +		}
   1.343 +	return result;
   1.344 +	}