--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/power/halsettings.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,282 @@
+// 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 the License "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:
+//
+
+#include "hal.h"
+#include <f32file.h>
+
+/** HAL attributes data folder */
+_LIT(KHalFilePath,"_:\\private\\102825B1\\");
+/** HAL attributes data file name */
+_LIT(KHalFileName,"HAL.DAT");
+/** Buffer descriptor for holding complete HAL data file path and name. */
+typedef TBuf<28> THalFileName;
+
+/**First 4 bytes in the HAL.DAT ('h' 'a' 'l' and version '0')
+*/
+const TUint32 typePrefix = 0x006C6168;
+
+/**
+HALSettings HAL.DAT header class
+This class is used to validate HAL.DAT file header
+*/
+class THalFileHeader
+ {
+ TUint32 iMachineUid; //Machine UID
+ TUint32 iTypePrefix; //HAL.DAT first 4 bytes 'h' 'a' 'l' and version '0'
+ public:
+ THalFileHeader(TUint32 aMachineUid, TUint32 aTypePrefix);
+ TInt ValidateHeader();
+ };
+
+/** Function to manage command line
+*/
+TInt HALSettingsManager();
+
+/** Function to Initialise HAL attribute
+*/
+TInt InitialiseHAL();
+/** Function to Persist HAL attribute
+*/
+TInt PersistHAL();
+
+/**
+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 && (TUint32)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.
+*/
+void GetSystemDrivePath(THalFileName& aPathName)
+ {
+ aPathName.Copy(KHalFilePath);
+ aPathName[0] = static_cast<TUint16>('A' + (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()
+ {
+ //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();
+ if ( result == KErrPathNotFound )
+ result = KErrNone;
+ 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 <= (TInt)sizeof(THalFileHeader) || (size&7) != 0)
+ {
+ 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;
+ 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)
+ {
+ HAL::Set(HALData::EPersistStartupModeKernel, *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()
+ {
+ TInt value;
+ TInt result = HAL::Get(HALData::EPersistStartupModeKernel, value);
+ if ( result != KErrNone )
+ {
+ return result;
+ }
+ RFs fs;
+ result=fs.Connect();
+ if ( result != KErrNone )
+ {
+ return result;
+ }
+ THalFileName halFile;
+ GetSystemDrivePath(halFile);
+
+ // Ensure directory \private\SID exists in target drive
+ result = fs.MkDirAll(halFile);
+ if (result != KErrNone )
+ if(result != KErrAlreadyExists )
+ {
+ fs.Close();
+ return result;
+ }
+ TInt muid=0;
+
+ // Gets the machine's unique ID
+ result=HAL::Get(HAL::EMachineUid, muid);
+ if ( result != KErrNone )
+ {
+ fs.Close();
+ return result;
+ }
+
+ //Allocating a buffer with size of header and data (HAL attributes)
+ RBuf8 buf;
+ result = buf.ReAlloc(sizeof(THalFileHeader) + 8);
+ if(result != KErrNone)
+ {
+ fs.Close();
+ 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*)&value, 8);
+
+ //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;
+ }
+
+GLDEF_C TInt E32Main()
+ {
+ __UHEAP_MARK;
+
+ TInt result = HALSettingsManager();
+
+ __UHEAP_MARKEND;
+
+ return result;
+ }