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 + }