|
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 the License "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 // |
|
15 |
|
16 #include "hal.h" |
|
17 #include <f32file.h> |
|
18 |
|
19 /** HAL attributes data folder */ |
|
20 _LIT(KHalFilePath,"_:\\private\\102825B1\\"); |
|
21 /** HAL attributes data file name */ |
|
22 _LIT(KHalFileName,"HAL.DAT"); |
|
23 /** Buffer descriptor for holding complete HAL data file path and name. */ |
|
24 typedef TBuf<28> THalFileName; |
|
25 |
|
26 /**First 4 bytes in the HAL.DAT ('h' 'a' 'l' and version '0') |
|
27 */ |
|
28 const TUint32 typePrefix = 0x006C6168; |
|
29 |
|
30 /** |
|
31 HALSettings HAL.DAT header class |
|
32 This class is used to validate HAL.DAT file header |
|
33 */ |
|
34 class THalFileHeader |
|
35 { |
|
36 TUint32 iMachineUid; //Machine UID |
|
37 TUint32 iTypePrefix; //HAL.DAT first 4 bytes 'h' 'a' 'l' and version '0' |
|
38 public: |
|
39 THalFileHeader(TUint32 aMachineUid, TUint32 aTypePrefix); |
|
40 TInt ValidateHeader(); |
|
41 }; |
|
42 |
|
43 /** Function to manage command line |
|
44 */ |
|
45 TInt HALSettingsManager(); |
|
46 |
|
47 /** Function to Initialise HAL attribute |
|
48 */ |
|
49 TInt InitialiseHAL(); |
|
50 /** Function to Persist HAL attribute |
|
51 */ |
|
52 TInt PersistHAL(); |
|
53 |
|
54 /** |
|
55 Constructor of THalFileHeader class |
|
56 @param aMachineUid Machine Uid |
|
57 @param aTypePrefix header 'h' 'a' 'l' and version no. |
|
58 */ |
|
59 THalFileHeader::THalFileHeader(TUint32 aMachineUid, TUint32 aTypePrefix) |
|
60 : iMachineUid (aMachineUid), iTypePrefix(aTypePrefix){} |
|
61 |
|
62 /** |
|
63 Validate header of the hal.dat file. |
|
64 @return KErrNone if successful otherwise KErrCorrupt. |
|
65 */ |
|
66 TInt THalFileHeader::ValidateHeader() |
|
67 { |
|
68 TInt result; |
|
69 TInt machineUID; |
|
70 result = HAL::Get(HAL::EMachineUid,machineUID); |
|
71 if (result != KErrNone) |
|
72 return result; |
|
73 if(iTypePrefix != typePrefix && (TUint32)machineUID != iMachineUid) |
|
74 return KErrCorrupt; |
|
75 return result; |
|
76 } |
|
77 |
|
78 /** |
|
79 Get the path (drive & folder path) of the HAL data file. |
|
80 @param aPathName On completion this will contain the result. |
|
81 */ |
|
82 void GetSystemDrivePath(THalFileName& aPathName) |
|
83 { |
|
84 aPathName.Copy(KHalFilePath); |
|
85 aPathName[0] = static_cast<TUint16>('A' + (RFs::GetSystemDrive())); |
|
86 } |
|
87 |
|
88 /** |
|
89 Initialise the HAL. |
|
90 Read the saved HAL file - containing a series of saved HAL attributes. If present, initialise |
|
91 each attribute saved. |
|
92 @return KErrNone if successful, otherwise any system wide error code. |
|
93 */ |
|
94 TInt InitialiseHAL() |
|
95 { |
|
96 //File server to open the HAL.DAT file |
|
97 RFs fs; |
|
98 TInt result = fs.Connect(); |
|
99 if (result != KErrNone) |
|
100 { |
|
101 return result; |
|
102 } |
|
103 //Get the system drive path |
|
104 THalFileName halFileName; |
|
105 GetSystemDrivePath(halFileName); |
|
106 halFileName.Append(KHalFileName); |
|
107 |
|
108 //Open the hal.dat file with EFileShare Exclusive mode to read HAL attributes |
|
109 RFile file; |
|
110 result = file.Open(fs,halFileName,EFileRead | EFileShareExclusive); |
|
111 if (result != KErrNone) |
|
112 { |
|
113 fs.Close(); |
|
114 if ( result == KErrPathNotFound ) |
|
115 result = KErrNone; |
|
116 return result; |
|
117 } |
|
118 |
|
119 //Checking the file integrity (total size should always be multiples of 8) |
|
120 TInt size=0; |
|
121 result = file.Size(size); |
|
122 if (result != KErrNone || size <= (TInt)sizeof(THalFileHeader) || (size&7) != 0) |
|
123 { |
|
124 file.Close(); |
|
125 fs.Close(); |
|
126 return KErrCorrupt; |
|
127 } |
|
128 //Allocate a buffer to read all HAL.DAT file |
|
129 TInt* pBuf=(TInt*)User::Alloc(size); |
|
130 if (!pBuf) |
|
131 { |
|
132 file.Close(); |
|
133 fs.Close(); |
|
134 return KErrNoMemory; |
|
135 } |
|
136 TPtr8 bptr((TUint8*)pBuf,size); |
|
137 |
|
138 //Read HAL.DAT to the allocated buffer |
|
139 result = file.Read(bptr); |
|
140 if ( result == KErrNone) |
|
141 { |
|
142 const TInt* pD = pBuf; |
|
143 THalFileHeader header (*pD, *(pD+1)); |
|
144 pD += 2; //first 8 bytes are header |
|
145 |
|
146 //Checking the validity of the file header and if valid set all HAL attributes |
|
147 if ((result = header.ValidateHeader()) == KErrNone) |
|
148 { |
|
149 HAL::Set(HALData::EPersistStartupModeKernel, *pD); |
|
150 } |
|
151 } |
|
152 User::Free(pBuf); |
|
153 file.Close(); |
|
154 fs.Close(); |
|
155 return(result); |
|
156 } |
|
157 |
|
158 /** |
|
159 Persist the HAL. |
|
160 Gets all HAL attributes, and their properties |
|
161 then save attributes (which are meaningful and modifiable on this device) to hal.dat |
|
162 @return KErrNone if successful, otherwise any system wide error code. |
|
163 */ |
|
164 TInt PersistHAL() |
|
165 { |
|
166 TInt value; |
|
167 TInt result = HAL::Get(HALData::EPersistStartupModeKernel, value); |
|
168 if ( result != KErrNone ) |
|
169 { |
|
170 return result; |
|
171 } |
|
172 RFs fs; |
|
173 result=fs.Connect(); |
|
174 if ( result != KErrNone ) |
|
175 { |
|
176 return result; |
|
177 } |
|
178 THalFileName halFile; |
|
179 GetSystemDrivePath(halFile); |
|
180 |
|
181 // Ensure directory \private\SID exists in target drive |
|
182 result = fs.MkDirAll(halFile); |
|
183 if (result != KErrNone ) |
|
184 if(result != KErrAlreadyExists ) |
|
185 { |
|
186 fs.Close(); |
|
187 return result; |
|
188 } |
|
189 TInt muid=0; |
|
190 |
|
191 // Gets the machine's unique ID |
|
192 result=HAL::Get(HAL::EMachineUid, muid); |
|
193 if ( result != KErrNone ) |
|
194 { |
|
195 fs.Close(); |
|
196 return result; |
|
197 } |
|
198 |
|
199 //Allocating a buffer with size of header and data (HAL attributes) |
|
200 RBuf8 buf; |
|
201 result = buf.ReAlloc(sizeof(THalFileHeader) + 8); |
|
202 if(result != KErrNone) |
|
203 { |
|
204 fs.Close(); |
|
205 return result; |
|
206 } |
|
207 |
|
208 //Appending header and hal attributes to the allocated buffer |
|
209 THalFileHeader header (muid,typePrefix); |
|
210 buf.Append((const TUint8*)&header,sizeof(THalFileHeader)); |
|
211 buf.Append((const TUint8*)&value, 8); |
|
212 |
|
213 //Saving HAL setting to a temp file after that rename it to HAL.DAT |
|
214 RFile file; |
|
215 TFileName tempFile; |
|
216 result = file.Temp(fs,halFile,tempFile,EFileWrite|EFileShareExclusive); |
|
217 |
|
218 if ( result == KErrNone ) |
|
219 { |
|
220 result = file.Write(buf); |
|
221 if ( result == KErrNone ) |
|
222 { |
|
223 halFile.Append(KHalFileName); |
|
224 fs.Delete(halFile); // ignore if error |
|
225 result = file.Rename(halFile); |
|
226 } |
|
227 file.Close(); |
|
228 } |
|
229 buf.Close(); |
|
230 fs.Close(); |
|
231 return result; |
|
232 } |
|
233 |
|
234 /** |
|
235 HAL Settings Manager. |
|
236 Manages the request for initialise and persist hal settings through command line |
|
237 For initialise it checks SID of the process send the request and command line parameter. |
|
238 If the SID = SID of EStart and command line is "INITIALISE" it initialise hal settings. |
|
239 For persistence it only checks the command line = "PERSIST" |
|
240 @return KErrNone if successful, otherwise any system wide error code. |
|
241 */ |
|
242 TInt HALSettingsManager() |
|
243 { |
|
244 const TInt KMaxArgumentLength = 10; |
|
245 const TInt KEStartSID = 0x10272C04; //SID of EStart |
|
246 _LIT(KHalInitialise,"INITIALISE"); |
|
247 _LIT(KHalPersist,"PERSIST"); |
|
248 |
|
249 if (User::CommandLineLength() > KMaxArgumentLength) |
|
250 return KErrArgument; |
|
251 TBuf<KMaxArgumentLength> args; |
|
252 User::CommandLine(args); |
|
253 TInt result; |
|
254 |
|
255 //Initialise or Persist HAL depending on command line arguments |
|
256 if (args.CompareF(KHalInitialise) == 0) |
|
257 { |
|
258 if(User::CreatorSecureId() != KEStartSID) |
|
259 return KErrPermissionDenied; |
|
260 result = InitialiseHAL(); |
|
261 } |
|
262 else if (args.CompareF(KHalPersist) == 0) |
|
263 { |
|
264 result = PersistHAL(); |
|
265 } |
|
266 else |
|
267 { |
|
268 return KErrArgument; |
|
269 } |
|
270 return result; |
|
271 } |
|
272 |
|
273 GLDEF_C TInt E32Main() |
|
274 { |
|
275 __UHEAP_MARK; |
|
276 |
|
277 TInt result = HALSettingsManager(); |
|
278 |
|
279 __UHEAP_MARKEND; |
|
280 |
|
281 return result; |
|
282 } |