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