os/ossrv/genericservices/systemagent/src/halsettings/halfiles.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Initialise / Persist HAL Implementation of HALSettings
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
/**
sl@0
    19
 @file
sl@0
    20
 @internalComponent
sl@0
    21
*/
sl@0
    22
sl@0
    23
#include "halfiles.h"
sl@0
    24
#include "halpatchdata.h"
sl@0
    25
#include "haldebug.h"
sl@0
    26
sl@0
    27
sl@0
    28
/**
sl@0
    29
Constructor of THalFileHeader class
sl@0
    30
@param aMachineUid Machine Uid
sl@0
    31
@param aTypePrefix header 'h' 'a' 'l' and version no.
sl@0
    32
*/
sl@0
    33
THalFileHeader::THalFileHeader(TUint32 aMachineUid, TUint32 aTypePrefix)
sl@0
    34
: iMachineUid (aMachineUid), iTypePrefix(aTypePrefix){}
sl@0
    35
		
sl@0
    36
/**
sl@0
    37
Validate header of the hal.dat file.
sl@0
    38
@return KErrNone if successful otherwise KErrCorrupt.
sl@0
    39
*/
sl@0
    40
TInt THalFileHeader::ValidateHeader() 
sl@0
    41
	{
sl@0
    42
	TInt result;
sl@0
    43
	TInt machineUID;
sl@0
    44
	result = HAL::Get(HAL::EMachineUid,machineUID);	
sl@0
    45
	if (result != KErrNone)
sl@0
    46
		return result;	
sl@0
    47
	if(iTypePrefix != typePrefix && machineUID != iMachineUid)
sl@0
    48
		return KErrCorrupt;
sl@0
    49
	return result;
sl@0
    50
	}
sl@0
    51
sl@0
    52
/**
sl@0
    53
Get the path (drive & folder path) of the HAL data file.
sl@0
    54
@param aPathName On completion this will contain the result.
sl@0
    55
*/	
sl@0
    56
static void GetSystemDrivePath(THalFileName& aPathName)
sl@0
    57
	{
sl@0
    58
	aPathName.Copy(KHalFilePath);
sl@0
    59
	aPathName[0] = 'A' + static_cast<TInt>(RFs::GetSystemDrive());
sl@0
    60
	}
sl@0
    61
sl@0
    62
/**
sl@0
    63
Initialise the HAL.
sl@0
    64
Read the saved HAL file - containing a series of saved HAL attributes. If present, initialise
sl@0
    65
each attribute saved.
sl@0
    66
@return KErrNone if successful, otherwise any system wide error code.
sl@0
    67
*/
sl@0
    68
TInt InitialiseHAL()
sl@0
    69
	{
sl@0
    70
    __HS_TRACE("HalSettings: InitialiseHAL");
sl@0
    71
    
sl@0
    72
	//File server to open the HAL.DAT file
sl@0
    73
	RFs fs;
sl@0
    74
	TInt result = fs.Connect(); 
sl@0
    75
	if (result != KErrNone)
sl@0
    76
		{
sl@0
    77
		return result;
sl@0
    78
		}
sl@0
    79
	//Get the system drive path
sl@0
    80
	THalFileName halFileName;
sl@0
    81
	GetSystemDrivePath(halFileName);
sl@0
    82
	halFileName.Append(KHalFileName);
sl@0
    83
	
sl@0
    84
	//Open the hal.dat file with EFileShare Exclusive mode to read HAL attributes
sl@0
    85
	RFile file;
sl@0
    86
	result = file.Open(fs,halFileName,EFileRead | EFileShareExclusive);
sl@0
    87
	if (result != KErrNone)
sl@0
    88
		{
sl@0
    89
		fs.Close();
sl@0
    90
		return result;		
sl@0
    91
		}
sl@0
    92
		
sl@0
    93
	//Checking the file integrity (total size should always be multiples of 8) 	
sl@0
    94
	TInt size=0;
sl@0
    95
	result = file.Size(size);
sl@0
    96
	if (result != KErrNone || size <= sizeof(THalFileHeader) || (size&7) != 0)
sl@0
    97
		{
sl@0
    98
		file.Close();
sl@0
    99
		fs.Close();
sl@0
   100
		return KErrCorrupt;	
sl@0
   101
		}
sl@0
   102
		
sl@0
   103
	//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
   104
	TInt maxDevices = 1;
sl@0
   105
	HAL::Get(HALData::EDisplayNumberOfScreens,maxDevices);
sl@0
   106
	TInt maxSize = (maxDevices * (TInt)HALData::ENumHalAttributes * (sizeof(HALData::TAttribute) + sizeof(TInt)) + sizeof(THalFileHeader));
sl@0
   107
	if (size > maxSize)
sl@0
   108
		//devices * number of attributes * (attribute + value) + header
sl@0
   109
		{
sl@0
   110
		file.Close();
sl@0
   111
		fs.Close();
sl@0
   112
		return KErrCorrupt;
sl@0
   113
		}
sl@0
   114
		
sl@0
   115
	//Allocate a buffer to read all HAL.DAT file
sl@0
   116
	TInt* pBuf=(TInt*)User::Alloc(size);
sl@0
   117
	if (!pBuf)
sl@0
   118
		{
sl@0
   119
		file.Close();
sl@0
   120
		fs.Close();
sl@0
   121
		return  KErrNoMemory;		
sl@0
   122
		}
sl@0
   123
	TPtr8 bptr((TUint8*)pBuf,size);
sl@0
   124
	
sl@0
   125
	//Read HAL.DAT to the allocated buffer	
sl@0
   126
	result = file.Read(bptr);
sl@0
   127
	if ( result == KErrNone)
sl@0
   128
		{
sl@0
   129
		const TInt* pD = pBuf;
sl@0
   130
		const TInt* pE = pD + size/sizeof(TInt);
sl@0
   131
		THalFileHeader header (*pD, *(pD+1));
sl@0
   132
		pD += 2; //first 8 bytes are header  
sl@0
   133
		
sl@0
   134
		//Checking the validity of the file header and if valid set all HAL attributes
sl@0
   135
		if ((result = header.ValidateHeader()) == KErrNone)
sl@0
   136
			{
sl@0
   137
			while (pD < pE)
sl@0
   138
				{
sl@0
   139
				TInt attrib = *pD++;
sl@0
   140
				//the top 8 bits contain the device number
sl@0
   141
				HAL::Set(((TUint)attrib)>>24, (HAL::TAttribute)(attrib & 0xFFFFFF), *pD++);
sl@0
   142
				}
sl@0
   143
			}
sl@0
   144
		}
sl@0
   145
	User::Free(pBuf);
sl@0
   146
	file.Close();
sl@0
   147
	fs.Close();
sl@0
   148
	return(result);	
sl@0
   149
	}
sl@0
   150
sl@0
   151
/**
sl@0
   152
Persist the HAL.
sl@0
   153
Gets all HAL attributes, and their properties 
sl@0
   154
then save attributes (which are meaningful and modifiable on this device) to hal.dat
sl@0
   155
@return KErrNone if successful, otherwise any system wide error code.
sl@0
   156
*/
sl@0
   157
TInt PersistHAL()
sl@0
   158
	{
sl@0
   159
    __HS_TRACE("HalSettings: PersistHAL");
sl@0
   160
    
sl@0
   161
	const TInt KHalProperties=HAL::EEntryDynamic|HAL::EEntryValid;
sl@0
   162
	//Get all HAL attributes
sl@0
   163
	HAL::SEntry* pE;
sl@0
   164
	TInt nEntries;
sl@0
   165
	TInt result = HAL::GetAll(nEntries, pE);
sl@0
   166
	if ( result != KErrNone )
sl@0
   167
		{
sl@0
   168
		return result;
sl@0
   169
		}
sl@0
   170
	const HAL::SEntry* pS=pE;
sl@0
   171
	const HAL::SEntry* pEnd=pS + nEntries;
sl@0
   172
	TInt* pD = (TInt*)pE;
sl@0
   173
		
sl@0
   174
    __HS_TRACE1("HalSettings: ENumHalAttributes == %d", HALData::ENumHalAttributes );
sl@0
   175
    __HS_TRACE1("HalSettings: KHalPenStatePersistenceDisabled == %d", KHalPenStatePersistenceDisabled );
sl@0
   176
	
sl@0
   177
	for (TInt s = 0; pS<pEnd; ++pS, ++s)
sl@0
   178
		{
sl@0
   179
		
sl@0
   180
		__HS_TRACE3("HalSettings: Attr: %d; Prop: %x; Value: %x", s, pS->iProperties, pS->iValue );
sl@0
   181
 
sl@0
   182
		if ((s%HAL::ENumHalAttributes) == HALData::EDisplayMemoryHandle)
sl@0
   183
		    {		    
sl@0
   184
		    if( pS->iValue >= KErrNone )
sl@0
   185
		        {
sl@0
   186
		        RHandleBase handle;
sl@0
   187
		        handle.SetHandle(pS->iValue);
sl@0
   188
		        handle.Close();
sl@0
   189
				// We will not persisit the closed handle
sl@0
   190
				continue;
sl@0
   191
		        }
sl@0
   192
		    }
sl@0
   193
				
sl@0
   194
		// HAL::GetAll() will return all HAL attributes 
sl@0
   195
		// But only need to save the attribute value which are valid and dynamic
sl@0
   196
		if ((pS->iProperties & KHalProperties) != KHalProperties)
sl@0
   197
			continue;
sl@0
   198
			
sl@0
   199
		// Do NOT save the EDisplayState as this could be off when system 
sl@0
   200
		// shutdown and then when system startup occurs the display will never 
sl@0
   201
		// be turned on
sl@0
   202
		if ((s%HAL::ENumHalAttributes) == HALData::EDisplayState)
sl@0
   203
            continue;
sl@0
   204
		
sl@0
   205
		// Do NOT save the EPenState as if this is 0 on save it could disable 
sl@0
   206
		// the touch screen on a reboot of the device on some platforms.
sl@0
   207
		if ((KHalPenStatePersistenceDisabled==1) && 
sl@0
   208
			(s%HAL::ENumHalAttributes) == HALData::EPenState )
sl@0
   209
            continue;
sl@0
   210
			
sl@0
   211
		// At this point we know this atribute must be saved to persitent store
sl@0
   212
		__HS_TRACE1("HalSettings: Attribute %d saved", s%HAL::ENumHalAttributes);
sl@0
   213
		
sl@0
   214
		TInt v=pS->iValue;		
sl@0
   215
		if((KHalNonSecureOffsetPersistenceDisabled == 1) &&
sl@0
   216
		   (s%HAL::ENumHalAttributes) == HALData::ETimeNonSecureOffset)
sl@0
   217
		   {
sl@0
   218
		   // If product so wants, save the nonsecure offset always as zero (so during boot user time == secure time)
sl@0
   219
		   v = 0;
sl@0
   220
		   }
sl@0
   221
		//top 8 bits are used to store device number next 3 is for the Hal attributes ENum value
sl@0
   222
		*pD++=((s/HAL::ENumHalAttributes)<<24) + (s%HAL::ENumHalAttributes);
sl@0
   223
		*pD++=v;
sl@0
   224
		}
sl@0
   225
	TUint nSaved=(pD-(TInt*)pE)>>1;
sl@0
   226
	RFs fs;
sl@0
   227
	//coverity[cleanup_stack]
sl@0
   228
	/* pE is just a local pointer here and goes out of scope after the execution of the function
sl@0
   229
	* This error is possibly thrown due to pE not made NULL in GetAll( ) but ,it should not be an issue here
sl@0
   230
	* as Connect() is not a leaving function
sl@0
   231
	*/
sl@0
   232
	result=fs.Connect(); //
sl@0
   233
	if ( result != KErrNone )
sl@0
   234
		{
sl@0
   235
		User::Free(pE);
sl@0
   236
		return result;	
sl@0
   237
		}
sl@0
   238
	THalFileName halFile;
sl@0
   239
	GetSystemDrivePath(halFile);
sl@0
   240
	
sl@0
   241
	// Ensure directory \private\SID exists in target drive
sl@0
   242
	result = fs.MkDirAll(halFile);
sl@0
   243
	if (result != KErrNone )
sl@0
   244
		if(result != KErrAlreadyExists )
sl@0
   245
			{
sl@0
   246
			//coverity[cleanup_stack]
sl@0
   247
			// Close() is not a leaving function
sl@0
   248
			fs.Close();
sl@0
   249
			User::Free(pE);
sl@0
   250
			return 	result;
sl@0
   251
			}
sl@0
   252
	TInt muid=0;
sl@0
   253
	
sl@0
   254
	// Gets the machine's unique ID
sl@0
   255
	result=HAL::Get(HAL::EMachineUid, muid);
sl@0
   256
	if ( result != KErrNone )
sl@0
   257
		{
sl@0
   258
		//coverity[cleanup_stack]
sl@0
   259
		// Close() is not a leaving function
sl@0
   260
		fs.Close();
sl@0
   261
		User::Free(pE);
sl@0
   262
		return 	result;	
sl@0
   263
		}
sl@0
   264
		
sl@0
   265
	//Allocating a buffer with size of header and data (HAL attributes)	
sl@0
   266
	RBuf8 buf;
sl@0
   267
	result = buf.ReAlloc(sizeof(THalFileHeader) + (nSaved*8));
sl@0
   268
	if(result != KErrNone)
sl@0
   269
		{
sl@0
   270
		//coverity[cleanup_stack]
sl@0
   271
		// Close() is not a leaving function
sl@0
   272
		fs.Close();
sl@0
   273
		User::Free(pE);
sl@0
   274
		return 	result;		
sl@0
   275
		}
sl@0
   276
		
sl@0
   277
	//Appending header and hal attributes to the allocated buffer		
sl@0
   278
	THalFileHeader header (muid,typePrefix);
sl@0
   279
	buf.Append((const TUint8*)&header,sizeof(THalFileHeader));
sl@0
   280
	buf.Append((const TUint8*)pE, nSaved*8);
sl@0
   281
	User::Free(pE);
sl@0
   282
	
sl@0
   283
	//Saving HAL setting to a temp file after that rename it to HAL.DAT
sl@0
   284
	RFile file;
sl@0
   285
	TFileName  tempFile;
sl@0
   286
	result = file.Temp(fs,halFile,tempFile,EFileWrite|EFileShareExclusive);
sl@0
   287
sl@0
   288
	if ( result == KErrNone )
sl@0
   289
		{
sl@0
   290
		result = file.Write(buf);
sl@0
   291
		if ( result == KErrNone )
sl@0
   292
			{
sl@0
   293
			halFile.Append(KHalFileName); 
sl@0
   294
			fs.Delete(halFile); // ignore if error 
sl@0
   295
			result = file.Rename(halFile);
sl@0
   296
			}
sl@0
   297
		file.Close();	
sl@0
   298
		}	
sl@0
   299
	buf.Close();
sl@0
   300
	fs.Close();
sl@0
   301
	return result;
sl@0
   302
	}
sl@0
   303
	
sl@0
   304
/**
sl@0
   305
HAL Settings Manager.
sl@0
   306
Manages the request for initialise and persist hal settings through command line
sl@0
   307
For initialise it checks SID of the process send the request and command line parameter.
sl@0
   308
If the SID = SID of EStart and command line is "INITIALISE" it initialise hal settings.
sl@0
   309
For persistence it only checks the command line = "PERSIST"
sl@0
   310
@return KErrNone if successful, otherwise any system wide error code.
sl@0
   311
*/
sl@0
   312
TInt HALSettingsManager()
sl@0
   313
	{
sl@0
   314
	const TInt KMaxArgumentLength = 10;
sl@0
   315
	const TInt KEStartSID = 0x10272C04; //SID of EStart
sl@0
   316
	_LIT(KHalInitialise,"INITIALISE");
sl@0
   317
	_LIT(KHalPersist,"PERSIST");
sl@0
   318
sl@0
   319
	if (User::CommandLineLength() >  KMaxArgumentLength)
sl@0
   320
		return KErrArgument;
sl@0
   321
	TBuf<KMaxArgumentLength> args;
sl@0
   322
	User::CommandLine(args);
sl@0
   323
	TInt result;
sl@0
   324
	
sl@0
   325
	//Initialise or Persist HAL depending on command line arguments
sl@0
   326
	if (args.CompareF(KHalInitialise) == 0)
sl@0
   327
		{
sl@0
   328
		if(User::CreatorSecureId() != KEStartSID)
sl@0
   329
				return KErrPermissionDenied;	
sl@0
   330
		result = InitialiseHAL();	
sl@0
   331
		}
sl@0
   332
	else if (args.CompareF(KHalPersist) == 0)
sl@0
   333
		{
sl@0
   334
		result = PersistHAL();
sl@0
   335
		}
sl@0
   336
	else
sl@0
   337
		{
sl@0
   338
		return KErrArgument;
sl@0
   339
		}
sl@0
   340
	return result;
sl@0
   341
	}