diff -r 000000000000 -r e4d67989cc36 genericservices/systemagent/src/halsettings/halfiles.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericservices/systemagent/src/halsettings/halfiles.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,339 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Initialise / Persist HAL Implementation of HALSettings +// +// + +/** + @file + @internalComponent +*/ + +#include "halfiles.h" +#include "halpatchdata.h" +#include "haldebug.h" + + +/** +Constructor of THalFileHeader class +@param aMachineUid Machine Uid +@param aTypePrefix header 'h' 'a' 'l' and version no. +*/ +THalFileHeader::THalFileHeader(TUint32 aMachineUid, TUint32 aTypePrefix) +: iMachineUid (aMachineUid), iTypePrefix(aTypePrefix){} + +/** +Validate header of the hal.dat file. +@return KErrNone if successful otherwise KErrCorrupt. +*/ +TInt THalFileHeader::ValidateHeader() + { + TInt result; + TInt machineUID; + result = HAL::Get(HAL::EMachineUid,machineUID); + if (result != KErrNone) + return result; + if(iTypePrefix != typePrefix && machineUID != iMachineUid) + return KErrCorrupt; + return result; + } + +/** +Get the path (drive & folder path) of the HAL data file. +@param aPathName On completion this will contain the result. +*/ +static void GetSystemDrivePath(THalFileName& aPathName) + { + aPathName.Copy(KHalFilePath); + aPathName[0] = 'A' + static_cast(RFs::GetSystemDrive()); + } + +/** +Initialise the HAL. +Read the saved HAL file - containing a series of saved HAL attributes. If present, initialise +each attribute saved. +@return KErrNone if successful, otherwise any system wide error code. +*/ +TInt InitialiseHAL() + { + __HS_TRACE("HalSettings: InitialiseHAL"); + + //File server to open the HAL.DAT file + RFs fs; + TInt result = fs.Connect(); + if (result != KErrNone) + { + return result; + } + //Get the system drive path + THalFileName halFileName; + GetSystemDrivePath(halFileName); + halFileName.Append(KHalFileName); + + //Open the hal.dat file with EFileShare Exclusive mode to read HAL attributes + RFile file; + result = file.Open(fs,halFileName,EFileRead | EFileShareExclusive); + if (result != KErrNone) + { + fs.Close(); + return result; + } + + //Checking the file integrity (total size should always be multiples of 8) + TInt size=0; + result = file.Size(size); + if (result != KErrNone || size <= sizeof(THalFileHeader) || (size&7) != 0) + { + file.Close(); + fs.Close(); + return KErrCorrupt; + } + + //Check to see that the filesize of HAL.DAT is not greater than if it contained entries for the max number of attributes + TInt maxDevices = 1; + HAL::Get(HALData::EDisplayNumberOfScreens,maxDevices); + TInt maxSize = (maxDevices * (TInt)HALData::ENumHalAttributes * (sizeof(HALData::TAttribute) + sizeof(TInt)) + sizeof(THalFileHeader)); + if (size > maxSize) + //devices * number of attributes * (attribute + value) + header + { + file.Close(); + fs.Close(); + return KErrCorrupt; + } + + //Allocate a buffer to read all HAL.DAT file + TInt* pBuf=(TInt*)User::Alloc(size); + if (!pBuf) + { + file.Close(); + fs.Close(); + return KErrNoMemory; + } + TPtr8 bptr((TUint8*)pBuf,size); + + //Read HAL.DAT to the allocated buffer + result = file.Read(bptr); + if ( result == KErrNone) + { + const TInt* pD = pBuf; + const TInt* pE = pD + size/sizeof(TInt); + THalFileHeader header (*pD, *(pD+1)); + pD += 2; //first 8 bytes are header + + //Checking the validity of the file header and if valid set all HAL attributes + if ((result = header.ValidateHeader()) == KErrNone) + { + while (pD < pE) + { + TInt attrib = *pD++; + //the top 8 bits contain the device number + HAL::Set(((TUint)attrib)>>24, (HAL::TAttribute)(attrib & 0xFFFFFF), *pD++); + } + } + } + User::Free(pBuf); + file.Close(); + fs.Close(); + return(result); + } + +/** +Persist the HAL. +Gets all HAL attributes, and their properties +then save attributes (which are meaningful and modifiable on this device) to hal.dat +@return KErrNone if successful, otherwise any system wide error code. +*/ +TInt PersistHAL() + { + __HS_TRACE("HalSettings: PersistHAL"); + + const TInt KHalProperties=HAL::EEntryDynamic|HAL::EEntryValid; + //Get all HAL attributes + HAL::SEntry* pE; + TInt nEntries; + TInt result = HAL::GetAll(nEntries, pE); + if ( result != KErrNone ) + { + return result; + } + const HAL::SEntry* pS=pE; + const HAL::SEntry* pEnd=pS + nEntries; + TInt* pD = (TInt*)pE; + + __HS_TRACE1("HalSettings: ENumHalAttributes == %d", HALData::ENumHalAttributes ); + __HS_TRACE1("HalSettings: KHalPenStatePersistenceDisabled == %d", KHalPenStatePersistenceDisabled ); + + for (TInt s = 0; pSiProperties, pS->iValue ); + + if ((s%HAL::ENumHalAttributes) == HALData::EDisplayMemoryHandle) + { + if( pS->iValue >= KErrNone ) + { + RHandleBase handle; + handle.SetHandle(pS->iValue); + handle.Close(); + } + } + + // HAL::GetAll() will return all HAL attributes + // But only need to save the attribute value which are valid and dynamic + if ((pS->iProperties & KHalProperties) != KHalProperties) + continue; + + // Do NOT save the EDisplayState as this could be off when system + // shutdown and then when system startup occurs the display will never + // be turned on + if ((s%HAL::ENumHalAttributes) == HALData::EDisplayState) + continue; + + // Do NOT save the EPenState as if this is 0 on save it could disable + // the touch screen on a reboot of the device on some platforms. + if ((KHalPenStatePersistenceDisabled==1) && + (s%HAL::ENumHalAttributes) == HALData::EPenState ) + continue; + + // At this point we know this atribute must be saved to persitent store + __HS_TRACE1("HalSettings: Attribute %d saved", s%HAL::ENumHalAttributes); + + TInt v=pS->iValue; + if((KHalNonSecureOffsetPersistenceDisabled == 1) && + (s%HAL::ENumHalAttributes) == HALData::ETimeNonSecureOffset) + { + // If product so wants, save the nonsecure offset always as zero (so during boot user time == secure time) + v = 0; + } + //top 8 bits are used to store device number next 3 is for the Hal attributes ENum value + *pD++=((s/HAL::ENumHalAttributes)<<24) + (s%HAL::ENumHalAttributes); + *pD++=v; + } + TUint nSaved=(pD-(TInt*)pE)>>1; + RFs fs; + //coverity[cleanup_stack] + /* pE is just a local pointer here and goes out of scope after the execution of the function + * This error is possibly thrown due to pE not made NULL in GetAll( ) but ,it should not be an issue here + * as Connect() is not a leaving function + */ + result=fs.Connect(); // + if ( result != KErrNone ) + { + User::Free(pE); + return result; + } + THalFileName halFile; + GetSystemDrivePath(halFile); + + // Ensure directory \private\SID exists in target drive + result = fs.MkDirAll(halFile); + if (result != KErrNone ) + if(result != KErrAlreadyExists ) + { + //coverity[cleanup_stack] + // Close() is not a leaving function + fs.Close(); + User::Free(pE); + return result; + } + TInt muid=0; + + // Gets the machine's unique ID + result=HAL::Get(HAL::EMachineUid, muid); + if ( result != KErrNone ) + { + //coverity[cleanup_stack] + // Close() is not a leaving function + fs.Close(); + User::Free(pE); + return result; + } + + //Allocating a buffer with size of header and data (HAL attributes) + RBuf8 buf; + result = buf.ReAlloc(sizeof(THalFileHeader) + (nSaved*8)); + if(result != KErrNone) + { + //coverity[cleanup_stack] + // Close() is not a leaving function + fs.Close(); + User::Free(pE); + return result; + } + + //Appending header and hal attributes to the allocated buffer + THalFileHeader header (muid,typePrefix); + buf.Append((const TUint8*)&header,sizeof(THalFileHeader)); + buf.Append((const TUint8*)pE, nSaved*8); + User::Free(pE); + + //Saving HAL setting to a temp file after that rename it to HAL.DAT + RFile file; + TFileName tempFile; + result = file.Temp(fs,halFile,tempFile,EFileWrite|EFileShareExclusive); + + if ( result == KErrNone ) + { + result = file.Write(buf); + if ( result == KErrNone ) + { + halFile.Append(KHalFileName); + fs.Delete(halFile); // ignore if error + result = file.Rename(halFile); + } + file.Close(); + } + buf.Close(); + fs.Close(); + return result; + } + +/** +HAL Settings Manager. +Manages the request for initialise and persist hal settings through command line +For initialise it checks SID of the process send the request and command line parameter. +If the SID = SID of EStart and command line is "INITIALISE" it initialise hal settings. +For persistence it only checks the command line = "PERSIST" +@return KErrNone if successful, otherwise any system wide error code. +*/ +TInt HALSettingsManager() + { + const TInt KMaxArgumentLength = 10; + const TInt KEStartSID = 0x10272C04; //SID of EStart + _LIT(KHalInitialise,"INITIALISE"); + _LIT(KHalPersist,"PERSIST"); + + if (User::CommandLineLength() > KMaxArgumentLength) + return KErrArgument; + TBuf args; + User::CommandLine(args); + TInt result; + + //Initialise or Persist HAL depending on command line arguments + if (args.CompareF(KHalInitialise) == 0) + { + if(User::CreatorSecureId() != KEStartSID) + return KErrPermissionDenied; + result = InitialiseHAL(); + } + else if (args.CompareF(KHalPersist) == 0) + { + result = PersistHAL(); + } + else + { + return KErrArgument; + } + return result; + }