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 the License "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: // sl@0: sl@0: #include "hal.h" sl@0: #include sl@0: sl@0: /** HAL attributes data folder */ sl@0: _LIT(KHalFilePath,"_:\\private\\102825B1\\"); sl@0: /** HAL attributes data file name */ sl@0: _LIT(KHalFileName,"HAL.DAT"); sl@0: /** Buffer descriptor for holding complete HAL data file path and name. */ sl@0: typedef TBuf<28> THalFileName; sl@0: sl@0: /**First 4 bytes in the HAL.DAT ('h' 'a' 'l' and version '0') sl@0: */ sl@0: const TUint32 typePrefix = 0x006C6168; sl@0: sl@0: /** sl@0: HALSettings HAL.DAT header class sl@0: This class is used to validate HAL.DAT file header sl@0: */ sl@0: class THalFileHeader sl@0: { sl@0: TUint32 iMachineUid; //Machine UID sl@0: TUint32 iTypePrefix; //HAL.DAT first 4 bytes 'h' 'a' 'l' and version '0' sl@0: public: sl@0: THalFileHeader(TUint32 aMachineUid, TUint32 aTypePrefix); sl@0: TInt ValidateHeader(); sl@0: }; sl@0: sl@0: /** Function to manage command line sl@0: */ sl@0: TInt HALSettingsManager(); sl@0: sl@0: /** Function to Initialise HAL attribute sl@0: */ sl@0: TInt InitialiseHAL(); sl@0: /** Function to Persist HAL attribute sl@0: */ sl@0: TInt PersistHAL(); 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 && (TUint32)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: void GetSystemDrivePath(THalFileName& aPathName) sl@0: { sl@0: aPathName.Copy(KHalFilePath); sl@0: aPathName[0] = static_cast('A' + (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: //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: if ( result == KErrPathNotFound ) sl@0: result = KErrNone; 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 <= (TInt)sizeof(THalFileHeader) || (size&7) != 0) sl@0: { sl@0: file.Close(); sl@0: fs.Close(); sl@0: return KErrCorrupt; 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: 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: HAL::Set(HALData::EPersistStartupModeKernel, *pD); 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: TInt value; sl@0: TInt result = HAL::Get(HALData::EPersistStartupModeKernel, value); sl@0: if ( result != KErrNone ) sl@0: { sl@0: return result; sl@0: } sl@0: RFs fs; sl@0: result=fs.Connect(); sl@0: if ( result != KErrNone ) sl@0: { 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: fs.Close(); 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: fs.Close(); 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) + 8); sl@0: if(result != KErrNone) sl@0: { sl@0: fs.Close(); 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*)&value, 8); 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: } sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: TInt result = HALSettingsManager(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: return result; sl@0: }