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