--- /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<TInt>(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; pS<pEnd; ++pS, ++s)
+ {
+
+ __HS_TRACE3("HalSettings: Attr: %d; Prop: %x; Value: %x", s, pS->iProperties, 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<KMaxArgumentLength> 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;
+ }