|
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 // |
|
15 |
|
16 |
|
17 |
|
18 // INCLUDE FILES |
|
19 #include "sysutil.h" |
|
20 #include <f32file.h> |
|
21 #include <bsul/ccacheddriveinfo.h> |
|
22 #include "sysutildomaincrkeys.h" // for disc space |
|
23 #include "sysutilinternalpskeys.h" // for disc space |
|
24 #include "sysutildebug.h" // debug helper |
|
25 #include "sysutilpatchdata.h" // patchable data defining the MMC drive integer identifer |
|
26 #include <baflpan.h> |
|
27 #include <e32property.h> |
|
28 #include <e32capability.h> |
|
29 #include <bsul/inifile.h> |
|
30 #include <bautils.h> |
|
31 #include "sysutilsetup.h" |
|
32 #include "sysutilplugindef.h" |
|
33 |
|
34 // File names of the files which store version and device type information. |
|
35 _LIT( KSWVersionFileName, "sw.txt" ); |
|
36 _LIT( KLangSWVersionFileName, "langsw.txt" ); |
|
37 _LIT( KLangVersionFileName, "lang.txt" ); |
|
38 _LIT( KDeviceAttributesFileName, "deviceattributes.ini" ); |
|
39 _LIT( KPRInformationFileName, "purpose.txt" ); |
|
40 |
|
41 // UID of sysutilsetup.exe. |
|
42 const TUid KSysUtilSetupUid = {0x10285B3B}; |
|
43 |
|
44 // Publish and Subscribe keys. |
|
45 const TUid KTestFilePathsUid = {0x10285B40}; |
|
46 const TUid KSWVersionUid = {0x10285B3C}; |
|
47 const TUid KLangSWVersionUid = {0x10285B3D}; |
|
48 const TUid KLangVersionUid = {0x10285B3E}; |
|
49 const TUid KDeviceTypeInfoUid = {0x10285B3F}; |
|
50 const TUid KPRInformationUid = {0x20027BC4}; |
|
51 |
|
52 // Device Type Information attribute UIDs. |
|
53 const TUid KManufacturerNameUid = {0x10286358}; |
|
54 const TUid KModelNameUid = {0x10286359}; |
|
55 const TUid KModelCodeUid = {0x1028635A}; |
|
56 const TUid KRevisionIDUid = {0x1028635B}; |
|
57 const TUid KDefaultDeviceNameUid = {0x1028635C}; |
|
58 const TUid KUIPlatformNameUid = {0x1028635D}; |
|
59 const TUid KUIPlatformVersionMajorUid = {0x1028635E}; |
|
60 const TUid KUIPlatformVersionMinorUid = {0x1028635F}; |
|
61 const TUid KUIPlatformVersionUid = {0x10286360}; |
|
62 const TUid KOSVersionMajorUid = {0x10286361}; |
|
63 const TUid KOSVersionMinorUid = {0x10286362}; |
|
64 const TUid KOSVersionUid = {0x10286363}; |
|
65 |
|
66 // This is the maximum number of Device Type Information attributes that can be |
|
67 // stored in the Device Type Information Publish and Subscribe property. |
|
68 const TUint16 KAttributeLimit = 450; |
|
69 |
|
70 // Default values that will be used if no plugin is provided, the |
|
71 // deviceattributes.ini file is missing or if a device attribute is not |
|
72 // specified by a licensee. |
|
73 _LIT16( KDefaultManufacturer, "Symbian" ); |
|
74 _LIT16( KDefaultModelName, "Symbian" ); |
|
75 _LIT16( KDefaultModelCode, "Symbian" ); |
|
76 _LIT16( KDefaultRevisionID, "00.00" ); |
|
77 _LIT16( KDefaultDeviceName, "Symbian" ); |
|
78 _LIT16( KDefaultUIPlatform, "Symbian" ); |
|
79 _LIT16( KDefaultUIPlatformVersionMajor, "0" ); |
|
80 _LIT16( KDefaultUIPlatformVersionMinor, "0" ); |
|
81 _LIT16( KDefaultUIPlatformVersion, "0.0" ); |
|
82 _LIT16( KDefaultOSVersionMajor, "0" ); |
|
83 _LIT16( KDefaultOSVersionMinor, "0" ); |
|
84 _LIT16( KDefaultOSVersion, "0.0" ); |
|
85 |
|
86 |
|
87 // Security policies for the Publish and Subscribe properties. |
|
88 _LIT_SECURITY_POLICY_C1( KSecurityPolicyNone, ECapability_None ); |
|
89 _LIT_SECURITY_POLICY_S1( KSecurityPolicyWriteDeviceData, 0x10285B3B, ECapabilityWriteDeviceData ); |
|
90 |
|
91 _LIT( KNewLinePattern, "\\n" ); |
|
92 _LIT( KNewline, "\n" ); |
|
93 |
|
94 |
|
95 /** |
|
96 Dummy sysutil implementation object - never instantiated. |
|
97 @internalComponent |
|
98 */ |
|
99 class CDeviceTypeInformation::TImpl |
|
100 { |
|
101 TUint32 iDummy; |
|
102 }; |
|
103 |
|
104 /** |
|
105 Stores a copy of the device type information attributes. For details of the |
|
106 memory layout see SGL.TS0017.201 BAFL Component Design Document.doc. |
|
107 @internalComponent |
|
108 */ |
|
109 typedef struct _SDeviceAttributes |
|
110 { |
|
111 TUint16 Length() const; |
|
112 TUint16 Count() const; |
|
113 TInt32 Uid( const TInt aAttributeIndex ) const; |
|
114 TInt16 Error( const TInt aAttributeIndex ) const; |
|
115 TInt AttributeLength( const TInt aAttributeIndex ) const; |
|
116 TUint16* AttributePtr( const TInt aAttributeIndex ) const; |
|
117 TUint16* iDeviceAttributes; |
|
118 } SDeviceAttributes; |
|
119 |
|
120 /** |
|
121 @return TInt16 The number of elements in the memory block. |
|
122 */ |
|
123 inline TUint16 SDeviceAttributes::Length() const |
|
124 { |
|
125 return iDeviceAttributes[0]; |
|
126 } |
|
127 |
|
128 /** |
|
129 @return TInt16 The number of device type information attributes. |
|
130 */ |
|
131 inline TUint16 SDeviceAttributes::Count() const |
|
132 { |
|
133 return iDeviceAttributes[1]; |
|
134 } |
|
135 |
|
136 /** |
|
137 Returns the UID which matches the attribute with the given index. |
|
138 |
|
139 @param aAttribIndex The index of the attribute in iDeviceAttributes. |
|
140 @return TInt32 The UID of the attribute with the given index. |
|
141 */ |
|
142 inline TInt32 SDeviceAttributes::Uid( const TInt aAttribIndex ) const |
|
143 { |
|
144 return (iDeviceAttributes[2 + (2 * aAttribIndex)] << 16) + iDeviceAttributes[2 + (2 * aAttribIndex) + 1]; |
|
145 } |
|
146 |
|
147 /** |
|
148 Returns an error code associated with the device type information attribute with |
|
149 the given index. This error code is generated when the attribute is retrieved |
|
150 from a plugin/deviceattributes.ini. It indicates if a value was successfully |
|
151 read, no value was provided or if an error occured. |
|
152 |
|
153 @param aAttribIndex The index of the attribute in iDeviceAttributes. |
|
154 @return TInt16 The error of the attribute with the given index. |
|
155 */ |
|
156 inline TInt16 SDeviceAttributes::Error( const TInt aAttribIndex) const |
|
157 { |
|
158 return static_cast<TInt16>(iDeviceAttributes[2 + (3 * Count()) + 1 + aAttribIndex]); |
|
159 } |
|
160 |
|
161 /** |
|
162 Returns the length of the attribute with the given index. |
|
163 |
|
164 @param aAttribIndex The index of the attribute in iDeviceAttributes. |
|
165 @return TInt The length of the attribute with the given index. |
|
166 */ |
|
167 inline TInt SDeviceAttributes::AttributeLength( const TInt aAttribIndex ) const |
|
168 { |
|
169 return iDeviceAttributes[2 + (2 * Count()) + aAttribIndex + 1] - iDeviceAttributes[2 + (2 * Count()) + aAttribIndex]; |
|
170 } |
|
171 |
|
172 /** |
|
173 Returns a pointer to the attribute value in iDeviceAttributes with the given |
|
174 index. |
|
175 |
|
176 @param aAttribIndex The index of the attribute in iDeviceAttributes. |
|
177 @return TUint16* A pointer to the attribute value with the given index. |
|
178 */ |
|
179 inline TUint16* SDeviceAttributes::AttributePtr( const TInt aAttribIndex ) const |
|
180 { |
|
181 return iDeviceAttributes + iDeviceAttributes[2 + (2 * Count()) + aAttribIndex]; |
|
182 } |
|
183 |
|
184 // ======== LOCAL FUNCTIONS ======== |
|
185 |
|
186 /** |
|
187 Returns the total length of all the device type information attribute values stored |
|
188 in aValues. |
|
189 |
|
190 @param aKeys An array which contains a list of device type information attribute |
|
191 UIDs. The UIDs corrospond to the values in aValues. |
|
192 @param aValues An array which contains a list of device type information attribute |
|
193 values. The values corrospond to the UIDs in aKeys. |
|
194 @return TInt The total length of all the device type information attribute values |
|
195 stored in aValues. |
|
196 @internalComponent |
|
197 */ |
|
198 static TInt AttributesTotalLength( RArray<TInt32>&, CDesC16ArraySeg& aValues ) |
|
199 { |
|
200 TUint attributesTotalLength = 0; |
|
201 TInt numAttributes = aValues.Count(); |
|
202 for( TInt attributeIndex = 0; attributeIndex < numAttributes; attributeIndex++ ) |
|
203 { |
|
204 TInt attributeLength = aValues[attributeIndex].Length(); |
|
205 if( attributeLength < CDeviceTypeInformation::KMaxAttributeLength ) |
|
206 { |
|
207 attributesTotalLength += attributeLength; |
|
208 } |
|
209 else |
|
210 { |
|
211 attributesTotalLength += CDeviceTypeInformation::KMaxAttributeLength; |
|
212 } |
|
213 } |
|
214 |
|
215 return attributesTotalLength; |
|
216 } |
|
217 |
|
218 /** |
|
219 Returns a pointer to some memory which contains the device type information attribute |
|
220 UIDs and values (these are contained in aKeys and aValues) in a compact format. The |
|
221 layout of the memory can be found in the Design Document |
|
222 (SGL.TS0017.201 BAFL Component Design Document.doc). |
|
223 |
|
224 @param aKeys An array which contains a list of device type information |
|
225 attribute UIDs. The UIDs corrospond to the values in aValues. |
|
226 @param aValues An array which contains a list of device type information |
|
227 attribute values. The values corrospond to the UIDs in aKeys. |
|
228 @leave - One of the system-wide error codes. |
|
229 @return TUint16* A pointer to the memory which contains the device type |
|
230 information attribute UIDs and values in a compact format. |
|
231 @internalComponent |
|
232 */ |
|
233 static TUint16* CreateDeviceTypeInfoPSDataL( RArray<TInt32>& aKeys, CDesC16ArraySeg& aValues ) |
|
234 { |
|
235 // See SGL.TS0017.201 BAFL Component Design Document.doc for more information on the |
|
236 // memory requirements and layout. |
|
237 TInt memoryElements = 3 + (4 * aKeys.Count()) + AttributesTotalLength( aKeys, aValues ); |
|
238 |
|
239 // Allocate memory to store the device type information attribute keys and values |
|
240 TUint16* deviceAttributes = static_cast<TUint16*>( User::AllocL( sizeof(TUint16) * memoryElements ) ); |
|
241 CleanupStack::PushL( deviceAttributes ); |
|
242 |
|
243 // Store the attributes length and count |
|
244 deviceAttributes[0] = memoryElements; |
|
245 deviceAttributes[1] = aKeys.Count(); |
|
246 |
|
247 // Store the attribute UIDs, offsets of the attributes in the memory, error codes and attribute values. |
|
248 if( deviceAttributes[1] > 0 ) |
|
249 { |
|
250 // Set the first offset to point to the start of the attributes |
|
251 deviceAttributes[2 + (2 * deviceAttributes[1])] = 2 + 1 + (4 * deviceAttributes[1]); |
|
252 |
|
253 for( TInt attributeNumber = 0; attributeNumber < deviceAttributes[1]; attributeNumber++ ) |
|
254 { |
|
255 // Store the UID as two TUint16s |
|
256 deviceAttributes[2 + (2 * attributeNumber)] = static_cast<TUint16>(aKeys[attributeNumber] >> 16); |
|
257 deviceAttributes[2 + (2 * attributeNumber) + 1] = static_cast<TUint16>(aKeys[attributeNumber]); |
|
258 |
|
259 if( KUIPlatformVersionMajorUid.iUid == aKeys[attributeNumber] || KUIPlatformVersionMinorUid.iUid == aKeys[attributeNumber] |
|
260 || KOSVersionMajorUid.iUid == aKeys[attributeNumber] || KOSVersionMinorUid.iUid == aKeys[attributeNumber] ) |
|
261 { |
|
262 // If the values were present in the INI/plugin (as we have the attribute keys) and the values |
|
263 // are KNullDesC16 then the values were corrupt. |
|
264 if( aValues[attributeNumber].Compare( KNullDesC16 ) == 0 ) |
|
265 { |
|
266 deviceAttributes[2 + (2 * deviceAttributes[1]) + 1 + attributeNumber] = deviceAttributes[2 + (2 * deviceAttributes[1]) + 1 + attributeNumber - 1]; |
|
267 deviceAttributes[2 + (3 * deviceAttributes[1]) + 1 + attributeNumber] = static_cast<TUint16>(KErrCorrupt); |
|
268 continue; |
|
269 } |
|
270 } |
|
271 |
|
272 // If the attribute value is too long we need to truncate it and set the error as KErrOverflow. |
|
273 if( aValues[attributeNumber].Length() > CDeviceTypeInformation::KMaxAttributeLength ) |
|
274 { |
|
275 deviceAttributes[2 + (2 * deviceAttributes[1]) + 1 + attributeNumber] = deviceAttributes[2 + (2 * deviceAttributes[1]) + attributeNumber] + CDeviceTypeInformation::KMaxAttributeLength; |
|
276 deviceAttributes[2 + (3 * deviceAttributes[1]) + 1 + attributeNumber] = static_cast<TUint16>(KErrOverflow); |
|
277 Mem::Copy( deviceAttributes + deviceAttributes[2 + (2 * deviceAttributes[1]) + attributeNumber], aValues[attributeNumber].Ptr(), CDeviceTypeInformation::KMaxAttributeLength * 2 ); |
|
278 } |
|
279 else |
|
280 { |
|
281 deviceAttributes[2 + (2 * deviceAttributes[1]) + 1 + attributeNumber] = deviceAttributes[2 + (2 * deviceAttributes[1]) + attributeNumber] + aValues[attributeNumber].Length(); |
|
282 deviceAttributes[2 + (3 * deviceAttributes[1]) + 1 + attributeNumber] = KErrNone; |
|
283 Mem::Copy( deviceAttributes + deviceAttributes[2 + (2 * deviceAttributes[1]) + attributeNumber], aValues[attributeNumber].Ptr(), aValues[attributeNumber].Size() ); |
|
284 } |
|
285 } |
|
286 } |
|
287 CleanupStack::Pop( 1 ); |
|
288 |
|
289 return deviceAttributes; |
|
290 } |
|
291 |
|
292 /** |
|
293 Helper function which deletes the Version and Device Type Information Publish and |
|
294 Subscribe properties. This is meant for testing purposes only and requires the |
|
295 KSysUtilTestModeEnabled constant to be patched to ETrue. |
|
296 |
|
297 @leave - One of the system-wide error codes. |
|
298 @internalComponent |
|
299 */ |
|
300 EXPORT_C void DeletePSPropertiesL() |
|
301 { |
|
302 if( KSysUtilTestModeEnabled ) |
|
303 { |
|
304 TInt err = RProperty::Delete(KSWVersionUid.iUid); |
|
305 if(err != KErrNotFound) |
|
306 { |
|
307 User::LeaveIfError(err); |
|
308 } |
|
309 |
|
310 err = RProperty::Delete(KLangSWVersionUid.iUid); |
|
311 if(err != KErrNotFound) |
|
312 { |
|
313 User::LeaveIfError(err); |
|
314 } |
|
315 |
|
316 err = RProperty::Delete(KLangVersionUid.iUid); |
|
317 if(err != KErrNotFound) |
|
318 { |
|
319 User::LeaveIfError(err); |
|
320 } |
|
321 |
|
322 err = RProperty::Delete(KDeviceTypeInfoUid.iUid); |
|
323 if(err != KErrNotFound) |
|
324 { |
|
325 User::LeaveIfError(err); |
|
326 } |
|
327 |
|
328 err = RProperty::Delete(KPRInformationUid.iUid); |
|
329 if(err != KErrNotFound) |
|
330 { |
|
331 User::LeaveIfError(err); |
|
332 } |
|
333 } |
|
334 } |
|
335 |
|
336 /** |
|
337 Finds and returns the device type information attribute number in aAttr. This |
|
338 number is used as an index in a populated instance of SDeviceAttributes. |
|
339 |
|
340 @param aAttr A reference to SDeviceAttributes which contains a copy of the device type information attributes. |
|
341 @param aKey The UID of the device type information attribute which needs to be found. |
|
342 @return The attribute index number (position) in aAttr. |
|
343 @return KErrNotFound aKey is not present in aAttr. |
|
344 @internalComponent |
|
345 */ |
|
346 static TInt FindAttributeNumber( const SDeviceAttributes& aAttr, const TUid& aKey ) |
|
347 { |
|
348 TInt bottom = 0; |
|
349 TInt top = aAttr.Count() - 1; |
|
350 |
|
351 while( bottom <= top ) |
|
352 { |
|
353 TUint middle = bottom + ( top - bottom ) / 2; |
|
354 if( static_cast<TUint32>(aKey.iUid) < aAttr.Uid( middle ) ) |
|
355 { |
|
356 top = middle - 1; |
|
357 } |
|
358 else if( static_cast<TUint32>(aKey.iUid) > aAttr.Uid( middle ) ) |
|
359 { |
|
360 bottom = middle + 1; |
|
361 } |
|
362 else |
|
363 { |
|
364 return middle; |
|
365 } |
|
366 } |
|
367 return KErrNotFound; |
|
368 } |
|
369 |
|
370 /** |
|
371 Find a value from the patchable data. If that fails try Publish&Subscribe, |
|
372 or if that fails, from Central Repository. |
|
373 |
|
374 @internalComponent |
|
375 @param aPCKey identifies the value to get from P&S. |
|
376 @param aCRKey identifies the value to get from Centrep |
|
377 @param aPatchableData patchable data set at compile time, may have been patched via rom patching |
|
378 @return Disk level threshold |
|
379 */ |
|
380 static TInt FindValueL( |
|
381 const TUint aPCKey, |
|
382 const TUint aCRKey, |
|
383 const TInt aPatchableData ) |
|
384 { |
|
385 TInt val( 0 ); |
|
386 |
|
387 if (aPatchableData != -1) |
|
388 { |
|
389 __SYSUTIL_TRACE1("SysUtil: CL treshold value found from patchable data %d",aPatchableData); |
|
390 return aPatchableData; |
|
391 } |
|
392 |
|
393 // Patchable data not set, try to get it from P & S Keys. |
|
394 TInt errorCode = RProperty::Get( KPSUidDiskLevel, aPCKey, val ); |
|
395 if ( errorCode != KErrNone ) |
|
396 { |
|
397 __SYSUTIL_TRACE1("SysUtil: CL treshold value not found from PS: %d, trying CR",errorCode); |
|
398 |
|
399 CRepository* repository = CRepository::NewLC(KCRUidDiskLevel); |
|
400 User::LeaveIfError(repository->Get(aCRKey,val)); |
|
401 CleanupStack::PopAndDestroy( repository ); |
|
402 } |
|
403 |
|
404 return val; |
|
405 } |
|
406 |
|
407 /** |
|
408 Find out the critical level treashold (in bytes) for disk drives of type |
|
409 aMediaType. Different media types may have different tresholds. If adding |
|
410 a non-default treshold for some media type, implementation should go here. |
|
411 |
|
412 @internalComponent |
|
413 @param aMediaType identifies the media type of the drive |
|
414 @return Disk level threshold |
|
415 */ |
|
416 static TInt64 FindCriticalLevelTresholdL( const TMediaType aMediaType ) |
|
417 { |
|
418 if ( aMediaType == EMediaRam ) // RAM drives have different critical level than others |
|
419 { |
|
420 return (TInt64) FindValueL(KRamDiskCriticalThreshold, KRamDiskCriticalLevel, KSysUtilRamDiskCriticalThreshold ); |
|
421 } |
|
422 else // Some other media type |
|
423 { |
|
424 return (TInt64) FindValueL(KOtherDiskCriticalThreshold, KDiskCriticalThreshold, KSysUtilOtherDiskCriticalThreshold ); |
|
425 } |
|
426 } |
|
427 |
|
428 /** |
|
429 Retrieves a string containing the location of sysutilplugin.dll. The location |
|
430 which is retrieved is dependent upon two things. The first is a patchable constant |
|
431 KSysUtilTestModeEnabled. This must be set to ETrue in order to use the test location instead |
|
432 of the standard path. This is set to EFalse by default for hardware builds. |
|
433 |
|
434 The second is a Publish and Subscribe property, which has a UID of |
|
435 0x10285B40. If KSysUtilTestModeEnabled is set to ETrue then this property will be defined |
|
436 and set to ETrue. This means that the test location is being used instead of the |
|
437 standard location. If the client wishes to switch to the standard location they |
|
438 can set this property to EFalse. |
|
439 |
|
440 It may be the case that the standard location needs to be used before the property |
|
441 is defined. If this is needed then the client can define and set the property. |
|
442 Alternatively, a call can be made to SysUtil::GetSWVersion, |
|
443 SysUtil::GetLangSWVersion, SysUtil::GetLangVersion or SysUtil::GetDeviceTypeInfoL. |
|
444 It can then call RProperty::Set with a value of EFalse. |
|
445 |
|
446 @param aLocation On return contains the location of sysutilplugin.dll. |
|
447 @leave - One of the system-wide error codes. |
|
448 @internalComponent |
|
449 */ |
|
450 static void GetDllLocationL( TDes& aLocation ) |
|
451 { |
|
452 _LIT( KDeviceAttributeDll, "Z:\\sys\\bin\\sysutilplugin.dll" ); |
|
453 |
|
454 if( KSysUtilTestModeEnabled ) |
|
455 { |
|
456 TBool testPaths = EFalse; |
|
457 TInt err = RProperty::Get( KUidSystemCategory, KTestFilePathsUid.iUid, testPaths ); |
|
458 if( KErrNone != err ) |
|
459 testPaths = EFalse; |
|
460 |
|
461 if( testPaths ) |
|
462 { |
|
463 TDriveUnit systemDrive( static_cast<TUint>(RFs::GetSystemDrive()) ); |
|
464 TParse path; |
|
465 path.Set( systemDrive.Name(), &KDeviceAttributeDll, NULL ); |
|
466 |
|
467 aLocation = path.FullName(); |
|
468 __SYSUTIL_TRACE1("DLL Location: %S", &aLocation); |
|
469 return; |
|
470 } |
|
471 } |
|
472 |
|
473 __SYSUTIL_TRACE1("DLL Location: %S", &KDeviceAttributeDll); |
|
474 aLocation = KDeviceAttributeDll; |
|
475 } |
|
476 |
|
477 /** |
|
478 Retrieves a string containing the path to deviceattributes.ini. The path which |
|
479 is retrieved is dependent upon two things. The first is a patchable constant |
|
480 KSysUtilTestModeEnabled. This must be set to ETrue in order to use the test path instead |
|
481 of the standard path. This is set to EFalse by default for hardware builds. |
|
482 |
|
483 The second is a Publish and Subscribe property, which has a UID of |
|
484 0x10285B40. If KSysUtilTestModeEnabled is set to ETrue then this property will be defined |
|
485 and set to ETrue. This means that the test path is being used instead of the |
|
486 standard path. If the client wishes to switch to the standard path they can set |
|
487 this property to EFalse. |
|
488 |
|
489 It may be the case that the standard path needs to be used before the property |
|
490 is defined. If this is needed then the client can define and set the property. |
|
491 Alternatively, a call can be made to SysUtil::GetSWVersion, |
|
492 SysUtil::GetLangSWVersion, SysUtil::GetLangVersion SysUtil::GetDeviceTypeInfoL or SysUtil::GetPRInformation. |
|
493 It can then call RProperty::Set with a value of EFalse. |
|
494 |
|
495 @param aPath On return contains the path to deviceattributes.ini. |
|
496 @return - One of the system-wide error codes. |
|
497 @internalComponent |
|
498 */ |
|
499 static TInt GetFilePath( TDes& aPath ) |
|
500 { |
|
501 _LIT( KDebugPath, "Z:\\versions\\" ); |
|
502 _LIT( KPath, "Z:\\resource\\versions\\" ); |
|
503 |
|
504 if( KSysUtilTestModeEnabled ) |
|
505 { |
|
506 TBool testPaths = EFalse; |
|
507 |
|
508 TInt err = RProperty::Get( KUidSystemCategory, KTestFilePathsUid.iUid, testPaths ); |
|
509 if( KErrNone != err ) |
|
510 testPaths = EFalse; |
|
511 |
|
512 if( testPaths ) |
|
513 { |
|
514 TDriveUnit systemDrive( static_cast<TUint>(RFs::GetSystemDrive()) ); |
|
515 TParse path; |
|
516 path.Set( systemDrive.Name(), &KDebugPath, NULL ); |
|
517 |
|
518 aPath = path.DriveAndPath(); |
|
519 __SYSUTIL_TRACE1("File Location: %S", &aPath); |
|
520 return KErrNone; |
|
521 } |
|
522 } |
|
523 |
|
524 __SYSUTIL_TRACE1("File Location: %S", &KPath); |
|
525 aPath = KPath; |
|
526 return KErrNone; |
|
527 } |
|
528 |
|
529 /** |
|
530 Fetch text from specified files. The algorithm first reads the file and puts |
|
531 the string into a buffer. Then it searches for these "\n" sequences in |
|
532 the buffer. To search for "\n" in a string the search string is specified as "\\n" |
|
533 with the extra slash in front to mean that we are really searching for "\n" and not |
|
534 the newline character - 0x000A. Once the "\n" is found in the buffer it is replaced |
|
535 with the newline character - 0x000A. So since this input string is unicode, it is |
|
536 actually searching for the byte sequence of 0x005C, 0x006E. These 4 bytes are |
|
537 replaced by the two byte sequence of 0x000A. |
|
538 |
|
539 @internalComponent |
|
540 @param aFilename File name to fetch string from. |
|
541 @param aValue On return, contains the requested version string. If the buffer is |
|
542 insufficient the descriptor is filled to its maximum length. If a buffer is provided |
|
543 that is longer than 64 characters, and the file content is larger than 64 characters, |
|
544 the returned buffer is truncated at 64 characters (see error codes below). |
|
545 @param aRemoveNewLines Replaces new line patterns if set to ETrue |
|
546 @return KErrNone on success. |
|
547 KErrTooBig if the maximum length of the descriptor is insufficient |
|
548 to hold the file content, or has been truncated (see above). In both cases new-line processing |
|
549 is done on the buffers if needed. If the file is empty KErrEof is returned, and the length of the |
|
550 buffer is set to zero. If none of these cases apply then one of the Symbian error codes is |
|
551 returned if reading the version string fails. |
|
552 */ |
|
553 static TInt GetTextFromFile( |
|
554 const TDesC& aFilename, |
|
555 TDes& aValue, |
|
556 TBool aRemoveNewLines ) |
|
557 { |
|
558 RFs fs; |
|
559 TInt err; |
|
560 err = fs.Connect(); |
|
561 if (err != KErrNone) |
|
562 return err; |
|
563 |
|
564 RFile file; |
|
565 err = file.Open( fs, aFilename, |
|
566 EFileRead | EFileStreamText | EFileShareReadersOnly ); |
|
567 if (err != KErrNone) |
|
568 { |
|
569 fs.Close(); |
|
570 return err; |
|
571 } |
|
572 |
|
573 TBuf8<2> characters; |
|
574 err = file.Read(characters); |
|
575 |
|
576 if (err == KErrNone || err == KErrTooBig) |
|
577 { |
|
578 // This means that we have an ANSI file (without the header bytes) |
|
579 if( characters.Length() == 0 || characters.Length() == 1 ) |
|
580 { |
|
581 file.Close(); |
|
582 fs.Close(); |
|
583 return KErrCorrupt; |
|
584 } |
|
585 else |
|
586 { |
|
587 TUint8 firstByte = characters[0]; |
|
588 TUint8 secondByte = characters[1]; |
|
589 |
|
590 // Heading byte values for unicode files |
|
591 const TInt KFFByte = 255; |
|
592 const TInt KFEByte = 254; |
|
593 |
|
594 // If file isn't unicode KErrCorrupt is returned |
|
595 if( (firstByte!=KFFByte && secondByte!=KFEByte) && (secondByte!=KFFByte && firstByte!=KFEByte) ) |
|
596 { |
|
597 file.Close(); |
|
598 fs.Close(); |
|
599 return KErrCorrupt; |
|
600 } |
|
601 } |
|
602 } |
|
603 |
|
604 TFileText tf; |
|
605 tf.Set(file); |
|
606 err = tf.Read(aValue); |
|
607 // If the maximum length of the descriptor is insufficient to hold the record, |
|
608 // the Read() function returns KErrTooBig and the descriptor is filled to its maximum length. |
|
609 // |
|
610 // If Read() is called when the current position is the end of the file (that is, after |
|
611 // the last line delimiter in the file), KErrEof is returned, and the length of the buffer |
|
612 // is set to zero. In this case, this would mean an empty file, as this code always reads |
|
613 // from the beginning of the file. |
|
614 |
|
615 if (err == KErrNone || err == KErrTooBig) |
|
616 { |
|
617 if (aValue.Length() > KSysUtilVersionTextLength) |
|
618 { |
|
619 // File content is larger than 64 characters. Truncate to 64 characters. |
|
620 aValue.Delete(KSysUtilVersionTextLength,aValue.Length() - KSysUtilVersionTextLength); |
|
621 err = KErrTooBig; |
|
622 } |
|
623 if (aRemoveNewLines) |
|
624 { |
|
625 // Replace new-line patterns with real ones |
|
626 TInt error = aValue.Find(KNewLinePattern); |
|
627 while (error != KErrNotFound) |
|
628 { |
|
629 // error is a position |
|
630 aValue.Replace(error, KNewLinePattern().Length(), KNewline ); |
|
631 error = aValue.Find(KNewLinePattern); |
|
632 } |
|
633 } |
|
634 } |
|
635 |
|
636 file.Close(); |
|
637 fs.Close(); |
|
638 |
|
639 return err; |
|
640 } |
|
641 |
|
642 /** |
|
643 Launches sysutilsetup.exe which is a helper executable. It should be launched |
|
644 when the current client does not have the correct capabilities to define Publish |
|
645 and Subscribe properties. |
|
646 |
|
647 Flags are used to determine which Publish and Subscribe properties are defined |
|
648 and set. The supported flags can be found in sysutilsetup.h. |
|
649 |
|
650 @param aFlags Used to determine which Publish and Subscribe properties |
|
651 should be defined and set. See sysutilsetup.h for |
|
652 supported flags. |
|
653 @return KErrNotReady The excutable has panicked or was not found. |
|
654 @return - Otherwise, one of the other system-wide error codes. |
|
655 @internalComponent |
|
656 */ |
|
657 static TInt LaunchSetupExecutable( const TDesC& aFlags ) |
|
658 { |
|
659 _LIT( KSysUtilSetupExeName, "Z:\\sys\\bin\\sysutilsetup.exe" ); |
|
660 const TUidType KSetupUid( KNullUid, KNullUid, KSysUtilSetupUid ); |
|
661 |
|
662 RProcess setupProcess; |
|
663 TInt err = setupProcess.Create( KSysUtilSetupExeName, aFlags, KSetupUid ); |
|
664 if( KErrNone != err ) |
|
665 { |
|
666 return KErrNotFound == err ? KErrNotReady : err; |
|
667 } |
|
668 |
|
669 TRequestStatus status; |
|
670 setupProcess.Rendezvous( status ); |
|
671 if( KRequestPending != status.Int() ) |
|
672 { |
|
673 setupProcess.Kill( 0 ); // Abort startup |
|
674 } |
|
675 else |
|
676 { |
|
677 setupProcess.Resume(); // Logon OK - start the server |
|
678 } |
|
679 |
|
680 User::WaitForRequest( status ); // Wait for start or death |
|
681 |
|
682 // We can't use the 'exit reason' if the server panicked as this |
|
683 // is the panic 'reason' and may be '0' which cannot be distinguished |
|
684 // from KErrNone |
|
685 err = setupProcess.ExitType() == EExitPanic ? KErrNotReady : status.Int(); |
|
686 setupProcess.Close(); |
|
687 |
|
688 return err; |
|
689 } |
|
690 |
|
691 /** |
|
692 Retrieves a string containing the version information for the given UID. |
|
693 |
|
694 @param aVersionUid The UID that corresponds to the version information which is required. |
|
695 @param aValue On return, contains the version string for the given aVersionUid. |
|
696 @return - One of the system-wide error codes. |
|
697 @internalComponent |
|
698 */ |
|
699 static TInt GetVersionPropertyData( const TUid& aVersionUid, TDes& aValue ) |
|
700 { |
|
701 // The P&S property contains the version data (max length 64) and the error code |
|
702 TBuf16<KSysUtilVersionTextLength + 1> temp; |
|
703 TInt16 err = RProperty::Get( KSysUtilSetupUid, aVersionUid.iUid, temp ); |
|
704 |
|
705 // If the P&S properties are not set we need to set them |
|
706 if ( KErrNotFound == err ) |
|
707 { |
|
708 __SYSUTIL_TRACE("Launching sysutilsetup.exe"); |
|
709 err = LaunchSetupExecutable( KSetVersionPropertiesFlag ); |
|
710 __SYSUTIL_TRACE("sysutilsetup.exe terminated"); |
|
711 if( KErrNone != err ) |
|
712 { |
|
713 return err; |
|
714 } |
|
715 |
|
716 err = RProperty::Get( KSysUtilSetupUid, aVersionUid.iUid, temp ); |
|
717 if( KErrNone != err ) |
|
718 { |
|
719 return err; |
|
720 } |
|
721 } |
|
722 |
|
723 if( aValue.MaxLength() < temp.Length() - 1 ) |
|
724 { |
|
725 aValue = temp.MidTPtr( 1, aValue.MaxLength() ); |
|
726 return KErrTooBig; |
|
727 } |
|
728 aValue = temp.MidTPtr( 1, temp.Length() - 1 ); |
|
729 |
|
730 return static_cast<TInt16>( temp[0] ); |
|
731 } |
|
732 |
|
733 /** |
|
734 Retrieves the version information from aFileName and stores it in a Publish and |
|
735 Subscribe property which has a key of aKey. |
|
736 |
|
737 @param aFileName The name of the file which contains the version information. |
|
738 @param aKey The key to be used for the Publish and Subscribe property. |
|
739 @leave - One of the system-wide error codes. |
|
740 @internalComponent |
|
741 */ |
|
742 static void SetVersionPropertyL( const TDesC& aFileName, const TUid& aKey ) |
|
743 { |
|
744 TFileName filePath; |
|
745 User::LeaveIfError( GetFilePath( filePath ) ); |
|
746 filePath.Append( aFileName ); |
|
747 |
|
748 // The P&S property must store the version data (max length 64) and the error code. |
|
749 TUint16* versionData = static_cast<TUint16*>( User::AllocL( sizeof(TUint16) * (KSysUtilVersionTextLength + 1) ) ); |
|
750 CleanupDeletePushL( versionData ); |
|
751 |
|
752 // The error code is store in the first TUint16 and the rest is for data. |
|
753 TPtr16 versionDataPtr( versionData + 1, KSysUtilVersionTextLength ); |
|
754 TInt err = GetTextFromFile( filePath, versionDataPtr, ETrue ); |
|
755 if ( err != KErrNone ) |
|
756 { |
|
757 __SYSUTIL_TRACE2( "Error: %d, while processing: %S", err, &filePath ); |
|
758 } |
|
759 |
|
760 // Store the error code from GetTextFromFile in the first TUint16. |
|
761 versionData[0] = static_cast<TUint16>( err ); |
|
762 |
|
763 err = RProperty::Define( aKey.iUid, RProperty::EByteArray, KSecurityPolicyNone, |
|
764 KSecurityPolicyWriteDeviceData, KSysUtilVersionTextLength + 1 ); |
|
765 if ( KErrAlreadyExists != err ) |
|
766 { |
|
767 User::LeaveIfError( err ); |
|
768 } |
|
769 |
|
770 versionDataPtr.Set( versionData, versionDataPtr.Length() + 1, versionDataPtr.Length() + 1 ); |
|
771 User::LeaveIfError( RProperty::Set( KSysUtilSetupUid, aKey.iUid, versionDataPtr ) ); |
|
772 CleanupStack::PopAndDestroy( 1 ); |
|
773 } |
|
774 |
|
775 /** |
|
776 Sets the version information Publish and Subscribe properties. |
|
777 |
|
778 @leave - One of the system-wide error codes. |
|
779 @internalComponent |
|
780 */ |
|
781 EXPORT_C void SetVersionPropertiesL() |
|
782 { |
|
783 SetVersionPropertyL( KSWVersionFileName, KSWVersionUid ); |
|
784 SetVersionPropertyL( KLangSWVersionFileName, KLangSWVersionUid ); |
|
785 SetVersionPropertyL( KLangVersionFileName, KLangVersionUid); |
|
786 SetVersionPropertyL( KPRInformationFileName, KPRInformationUid ); |
|
787 } |
|
788 |
|
789 /** |
|
790 Compares two UIDs. |
|
791 |
|
792 @param aLeft The first of two UIDs to compare. |
|
793 @param aRight The second of two UIDs to compare. |
|
794 @return TInt Zero if both UIDs are the same. Positive if aLeft is greater |
|
795 than aRight. Negative if aLeft is less than aRight. |
|
796 @leave - One of the system-wide error codes. |
|
797 @internalComponent |
|
798 */ |
|
799 static TInt CompareUids( const TInt32& aLeft, const TInt32& aRight ) |
|
800 { |
|
801 TUint32 left = static_cast<TUint32>(aLeft); |
|
802 TUint32 right = static_cast<TUint32>(aRight); |
|
803 if( left == right ) |
|
804 { |
|
805 return 0; |
|
806 } |
|
807 else if ( left < right ) |
|
808 { |
|
809 return -1; |
|
810 } |
|
811 return 1; |
|
812 } |
|
813 |
|
814 /** |
|
815 Finds the deviceattributes.ini file which best match the current locale. If more |
|
816 than one INI file is found for the current locale (this is a result of having |
|
817 different versions of the INI file in different ROFS sections) then the contents |
|
818 of the INI file are merged. If a attribute appears more than once then the most |
|
819 recent value is taken. On return akeys and aValues will contain the merged |
|
820 results. |
|
821 |
|
822 Note: The keys and values are in UID order from low to high. |
|
823 |
|
824 @param aKeys On return, contains the attribute UIDs. |
|
825 @param aValues On return, contains the attribute values. |
|
826 @leave KErrGeneral A UID in the INI file is missing the '0x' hex prefix. |
|
827 @leave - Otherwise, one of the other system-wide error codes. |
|
828 @internalComponent |
|
829 */ |
|
830 static void ReadDeviceAttribFilesAsArraysL( |
|
831 RArray<TInt32>& aKeys, |
|
832 CDesC16ArraySeg& aValues ) |
|
833 { |
|
834 _LIT( KWildCardChar, "*" ); |
|
835 |
|
836 RFs fs; |
|
837 fs.Connect(); |
|
838 CleanupClosePushL( fs ); |
|
839 |
|
840 // Get the localised version of deviceattributes.ini, if available, and use |
|
841 // it to create a search pattern which will be used to find versions of the |
|
842 // file that may be available in additional ROFS sections. |
|
843 TFileName matchPattern; |
|
844 User::LeaveIfError( GetFilePath( matchPattern ) ); |
|
845 matchPattern.Append( KDeviceAttributesFileName ); |
|
846 BaflUtils::NearestLanguageFile( fs, matchPattern ); |
|
847 matchPattern.Append( KWildCardChar ); |
|
848 |
|
849 // Get a list of all the versions of the localised deviceattributes.ini |
|
850 // that may be available in additional ROFS sections. If an error occurs |
|
851 // the default values will be used. |
|
852 CDir* iniFileList = NULL; |
|
853 TInt err = fs.GetDir( matchPattern, KEntryAttReadOnly | KEntryAttHidden | |
|
854 KEntryAttSystem | KEntryAttArchive, ESortByName, iniFileList ); |
|
855 |
|
856 __SYSUTIL_TRACE1( "Error: %d, while getting a list of deviceattribute.ini files", err ); |
|
857 |
|
858 if( err == KErrNone ) |
|
859 { |
|
860 CleanupStack::PushL( iniFileList ); |
|
861 // Go through each INI file (starting with the last file first) extracting |
|
862 // the keys and values which are then stored in the two provided arrays. |
|
863 // This keys and values are stored in key order from low to high. Only the |
|
864 // most recent version of each value is stored i.e. the value in the INI |
|
865 // file which is stored in the newest ROFS section. |
|
866 TLinearOrder<TInt32> orderer( CompareUids ); |
|
867 for( TInt iniNumber = iniFileList->Count() - 1; iniNumber >= 0; iniNumber-- ) |
|
868 { |
|
869 // Get next INI file |
|
870 TFileName iniPath; |
|
871 User::LeaveIfError( GetFilePath( iniPath ) ); |
|
872 iniPath.Append( (*iniFileList)[iniNumber].iName ); |
|
873 |
|
874 BSUL::CIniDocument16* iniFile = NULL; |
|
875 TRAPD( err, iniFile = BSUL::CIniDocument16::NewL( fs, iniPath ) ); |
|
876 __SYSUTIL_TRACE1("BSUL::CIniDocument16::NewL error = %d", err); |
|
877 if( err == KErrNone ) |
|
878 { |
|
879 CleanupStack::PushL( iniFile ); |
|
880 |
|
881 RArray<TPtrC16> iniFileSections; |
|
882 iniFile->GetSectionList( iniFileSections ); |
|
883 CleanupClosePushL( iniFileSections ); |
|
884 |
|
885 // For each section get the key/value pairs and insert in order to |
|
886 // the provided arrays. If a key already exists do not insert the |
|
887 // value in aValue. |
|
888 TInt numIniFileSections = iniFileSections.Count(); |
|
889 for( TInt sectionNum = 0; sectionNum < numIniFileSections; sectionNum++ ) |
|
890 { |
|
891 BSUL::CIniSecIter16* sectionIter = BSUL::CIniSecIter16::NewL( iniFileSections[sectionNum], iniFile ); |
|
892 CleanupStack::PushL( sectionIter ); |
|
893 |
|
894 TPtrC16 key; |
|
895 TPtrC16 value; |
|
896 while( sectionIter->Next( key, value ) ) |
|
897 { |
|
898 const TChar char0('0'); |
|
899 const TChar charX('x'); |
|
900 |
|
901 TUint32 tempUid; |
|
902 TLex16 lex( key ); |
|
903 |
|
904 // Skip over the '0' and 'x' hex number prefix |
|
905 if( lex.Get() != char0 || lex.Get() != charX ) |
|
906 { |
|
907 User::Leave(KErrGeneral); |
|
908 } |
|
909 User::LeaveIfError( lex.Val( tempUid, EHex ) ); |
|
910 |
|
911 TInt err = aKeys.InsertInOrder( static_cast<TInt32>(tempUid), orderer ); |
|
912 if( KErrAlreadyExists != err ) |
|
913 { |
|
914 User::LeaveIfError( err ); |
|
915 |
|
916 TInt index = aKeys.FindInOrder( static_cast<TInt32>(tempUid), orderer ); |
|
917 aValues.InsertL( index, value ); |
|
918 } |
|
919 } |
|
920 CleanupStack::PopAndDestroy( 1 ); // sectionIter |
|
921 } |
|
922 CleanupStack::PopAndDestroy( 2 ); // iniFile and iniFileSections |
|
923 } |
|
924 } |
|
925 CleanupStack::PopAndDestroy( 1 ); // iniFileList |
|
926 } |
|
927 CleanupStack::PopAndDestroy( 1 ); // fs |
|
928 } |
|
929 |
|
930 /** |
|
931 Retrieves the provisioned device type information attribute key/value pairs |
|
932 which are stored in aKeys and aValues. |
|
933 |
|
934 Note: The keys and values are in UID order from low to high. |
|
935 |
|
936 @param aKeys On return, contains the attribute UIDs. |
|
937 @param aValues On return, contains the attribute values. |
|
938 @leave KErrCorrupt There is a mismatch between the number of keys and values or |
|
939 an invalid key has been provided. |
|
940 @leave - Otherwise, one of the other system-wide error codes. |
|
941 @panic KErrTooBig More than 450 attributes where provisioned. |
|
942 @internalComponent |
|
943 */ |
|
944 static void GetDeviceAttributesL( RArray<TInt32>& aKeys, CDesC16ArraySeg& aValues ) |
|
945 { |
|
946 RArray<TInt32> iniKeys; |
|
947 CleanupClosePushL( iniKeys ); |
|
948 |
|
949 CDesC16ArraySeg* iniValues = new (ELeave) CDesC16ArraySeg( 8 ); |
|
950 CleanupStack::PushL( iniValues ); |
|
951 |
|
952 // First try to get the device type information attributes from the INI file/s. |
|
953 ReadDeviceAttribFilesAsArraysL( iniKeys, *iniValues ); |
|
954 |
|
955 if( !KSysUtilDisableDeviceTypeInfoSetupExe ) |
|
956 { |
|
957 // Now try to get the device type information attributes from a DLL. |
|
958 TFileName deviceAttributeDllLocation; |
|
959 GetDllLocationL(deviceAttributeDllLocation); |
|
960 |
|
961 RLibrary deviceAttributeDll; |
|
962 TInt err = deviceAttributeDll.Load( deviceAttributeDllLocation ); |
|
963 CleanupClosePushL( deviceAttributeDll ); |
|
964 |
|
965 if( KErrNone == err ) |
|
966 { |
|
967 SysUtilPlugin::GetDeviceAttributesAsArraysFuncL GetDeviceAttributesAsArraysL = reinterpret_cast<SysUtilPlugin::GetDeviceAttributesAsArraysFuncL>( deviceAttributeDll.Lookup( SysUtilPlugin::EGetDeviceAttributesAsArraysLOrdinal ) ); |
|
968 User::LeaveIfNull( &GetDeviceAttributesAsArraysL ); |
|
969 GetDeviceAttributesAsArraysL( aKeys, aValues ); |
|
970 } |
|
971 else |
|
972 { |
|
973 __SYSUTIL_TRACE1("Could not load sysutilplug.dll with error: %d ", err); |
|
974 } |
|
975 CleanupStack::PopAndDestroy( 1 ); |
|
976 } |
|
977 |
|
978 // Merge results with the INI taking lowest priority i.e. if the value already |
|
979 // exists in aKeys/aValues then ignore the one in iniKeys/iniValues. |
|
980 TLinearOrder<TInt32> orderer( CompareUids ); |
|
981 TInt numIniAttribs = iniKeys.Count(); |
|
982 for( TInt keyNum = 0; keyNum < numIniAttribs; keyNum++ ) |
|
983 { |
|
984 TInt err = aKeys.InsertInOrder( iniKeys[keyNum], orderer ); |
|
985 if( KErrAlreadyExists != err ) |
|
986 { |
|
987 User::LeaveIfError( err ); |
|
988 |
|
989 TInt index = aKeys.FindInOrder( iniKeys[keyNum], orderer ); |
|
990 aValues.InsertL( index, (*iniValues)[keyNum] ); |
|
991 } |
|
992 } |
|
993 CleanupStack::PopAndDestroy( 2 ); |
|
994 |
|
995 // Check we have the same number of keys and values and that we don't have too many keys |
|
996 if( aKeys.Count() != aValues.Count() ) |
|
997 { |
|
998 User::Leave( KErrCorrupt ); |
|
999 } |
|
1000 else if( aKeys.Count() > KAttributeLimit ) |
|
1001 { |
|
1002 _LIT( KPanicReason, "KAttributeLimit exceeded" ); |
|
1003 User::Panic( KPanicReason, KErrTooBig ); |
|
1004 } |
|
1005 } |
|
1006 |
|
1007 /** |
|
1008 Validates major and minor version numbers. This means both values must be |
|
1009 within the range 0 to KMaxTUint16. If the major, minor or both numbers are |
|
1010 invalid their values will be replaced by KNullDesC16. |
|
1011 |
|
1012 @param aKeys An array which contains a list of device type information attribute |
|
1013 UIDs. The UIDs corrospond to the values in aValues. |
|
1014 @param aValues An array which contains a list of device type information attribute |
|
1015 values. The values corrospond to the UIDs in aKeys. |
|
1016 @internalComponent |
|
1017 */ |
|
1018 static void ValidateVersionNumbersL( RArray<TInt32>& aKeys, CDesC16ArraySeg& aValues, const TUid& aMajorVersionUid, const TUid& aMinorVersionUid) |
|
1019 { |
|
1020 TLinearOrder<TInt32> orderer( CompareUids ); |
|
1021 TInt pos = aKeys.FindInOrder( aMajorVersionUid.iUid, orderer ); |
|
1022 if( KErrNotFound != pos ) |
|
1023 { |
|
1024 if( aKeys[pos + 1] == aMinorVersionUid.iUid ) |
|
1025 { |
|
1026 TInt32 value; |
|
1027 TLex16 lex( aValues[pos] ); |
|
1028 TInt err = lex.Val( value ); |
|
1029 |
|
1030 if( KErrNone == err && value >= 0 && value <= KMaxTUint16 ) |
|
1031 { |
|
1032 lex = aValues[pos+ 1]; |
|
1033 err = lex.Val( value ); |
|
1034 |
|
1035 if( KErrNone == err && value >= 0 && value <= KMaxTUint16 ) |
|
1036 { |
|
1037 return; |
|
1038 } |
|
1039 } |
|
1040 aValues.Delete( pos + 1 ); |
|
1041 aValues.InsertL( pos + 1, KNullDesC16 ); |
|
1042 } |
|
1043 aValues.Delete( pos ); |
|
1044 aValues.InsertL( pos, KNullDesC16 ); |
|
1045 return; |
|
1046 } |
|
1047 |
|
1048 pos = aKeys.FindInOrder( aMinorVersionUid.iUid, orderer ); |
|
1049 if( KErrNotFound != pos ) |
|
1050 { |
|
1051 aValues.Delete( pos ); |
|
1052 aValues.InsertL( pos, KNullDesC16 ); |
|
1053 } |
|
1054 } |
|
1055 |
|
1056 /** |
|
1057 Gets the device type information attributes and stores them in their formatted form. |
|
1058 |
|
1059 @return TUint16* Formatted device type information attributes. |
|
1060 @internalComponent |
|
1061 */ |
|
1062 static TUint16* FormattedDeviceTypeInfoL() |
|
1063 { |
|
1064 RArray<TInt32> keys; |
|
1065 CleanupClosePushL( keys ); |
|
1066 |
|
1067 CDesC16ArraySeg* values = new (ELeave) CDesC16ArraySeg( 8 ); |
|
1068 CleanupStack::PushL( values ); |
|
1069 |
|
1070 GetDeviceAttributesL( keys, *values ); |
|
1071 |
|
1072 // Validate the major and minor UI and OS version numbers. This should be done now to avoid repeated processing |
|
1073 // later on when the client calls either of the GetUIPlatformVersion APIs. An added advantage of doing |
|
1074 // this now is that we save memory space if the version numbers are corrupt. |
|
1075 ValidateVersionNumbersL( keys, *values, KUIPlatformVersionMajorUid, KUIPlatformVersionMinorUid ); |
|
1076 ValidateVersionNumbersL( keys, *values, KOSVersionMajorUid, KOSVersionMinorUid ); |
|
1077 |
|
1078 TUint16* deviceAttributes = CreateDeviceTypeInfoPSDataL( keys, *values ); |
|
1079 |
|
1080 CleanupStack::PopAndDestroy( 2 ); |
|
1081 |
|
1082 return deviceAttributes; |
|
1083 } |
|
1084 |
|
1085 /** |
|
1086 Sets the Device Type Information attributes Publish and Subscribe property |
|
1087 value. If the property does not already exist it will define it. Otherwise, it |
|
1088 will set the value again. |
|
1089 |
|
1090 @leave - One of the system-wide error codes. |
|
1091 @internalComponent |
|
1092 */ |
|
1093 EXPORT_C void SetDeviceTypeInfoPropertyL() |
|
1094 { |
|
1095 TUint16* deviceAttributes = FormattedDeviceTypeInfoL(); |
|
1096 CleanupStack::PushL( deviceAttributes ); |
|
1097 |
|
1098 // Set the Publish and Subscribe property |
|
1099 TPtrC16 deviceAttributesTPtrC( deviceAttributes, deviceAttributes[0] ); |
|
1100 TInt propertyType = deviceAttributesTPtrC.Size() < 512 ? RProperty::EByteArray : RProperty::ELargeByteArray; |
|
1101 |
|
1102 TInt err = RProperty::Define( KDeviceTypeInfoUid.iUid, propertyType, KSecurityPolicyNone, |
|
1103 KSecurityPolicyWriteDeviceData, deviceAttributesTPtrC.Size() ); |
|
1104 if ( KErrAlreadyExists != err ) |
|
1105 { |
|
1106 User::LeaveIfError( err ); |
|
1107 } |
|
1108 User::LeaveIfError( RProperty::Set( KSysUtilSetupUid, KDeviceTypeInfoUid.iUid, deviceAttributesTPtrC ) ); |
|
1109 |
|
1110 CleanupStack::PopAndDestroy( 1 ); |
|
1111 } |
|
1112 |
|
1113 // ========================= SysUtil MEMBER FUNCTIONS ========================== |
|
1114 |
|
1115 /** |
|
1116 Obtains the displayable software version string. |
|
1117 |
|
1118 Usage example: |
|
1119 @code |
|
1120 TBuf<KSysUtilVersionTextLength> version; |
|
1121 if ( SysUtil::GetSWVersion( version ) == KErrNone ) |
|
1122 { |
|
1123 // Use the version string. |
|
1124 ... |
|
1125 } |
|
1126 @endcode |
|
1127 The software version is provisioned by the device creator into the ROM |
|
1128 as a Unicode UTF16 format displayable string, for example: |
|
1129 |
|
1130 <code>V 1.0\\n29-07-07\\nBuild12345\\n(c) Symbian Software</code> |
|
1131 |
|
1132 This provisioned text string contains only one line of text with "\n" sequences |
|
1133 in the text which indicate a new line. This API will parse the |
|
1134 text and remove any "\n" sequences that it finds and replace it with the |
|
1135 Unicode newline sequence - 0x000A. The resulting |
|
1136 buffer is then a unicode string with newline sequences built in. This |
|
1137 then can for example, allow the buffer to be displayed directly to the |
|
1138 screen already formatted on multiple lines. |
|
1139 |
|
1140 @param aValue On return, contains the software version string. The buffer should |
|
1141 have space for KSysUtilVersionTextLength characters. If the buffer is |
|
1142 insufficient the descriptor is filled to its maximum length. If a buffer is |
|
1143 provided that is longer than 64 characters, and the provisioned text is larger |
|
1144 than 64 characters, the returned buffer is truncated at 64 characters (see error |
|
1145 codes below). |
|
1146 @return KErrNone on success, KErrTooBig if the maximum length of the descriptor |
|
1147 is insufficient to hold the provisioned text, or has been truncated (see above). |
|
1148 In both cases new-line processing is done on the buffers. If a zero length |
|
1149 text string has been provisioned KErrEof is returned, and the length of the |
|
1150 buffer is set to zero. If none of these cases apply then one of the Symbian |
|
1151 error codes is returned if reading the version string fails. |
|
1152 */ |
|
1153 EXPORT_C TInt SysUtil::GetSWVersion( TDes& aValue ) |
|
1154 { |
|
1155 if( KSysUtilDisableVersionSetupExe ) |
|
1156 { |
|
1157 __SYSUTIL_TRACE("GetSWVersion caching disabled"); |
|
1158 |
|
1159 TFileName filePath; |
|
1160 TInt err = GetFilePath( filePath ); |
|
1161 if( KErrNone != err) |
|
1162 { |
|
1163 return err; |
|
1164 } |
|
1165 |
|
1166 filePath.Append( KSWVersionFileName ); |
|
1167 |
|
1168 err = GetTextFromFile( filePath, aValue, ETrue ); |
|
1169 if ( err != KErrNone ) |
|
1170 { |
|
1171 __SYSUTIL_TRACE2("Error: %d, while processing: %S",err, &filePath); |
|
1172 } |
|
1173 |
|
1174 return err; |
|
1175 } |
|
1176 else |
|
1177 { |
|
1178 __SYSUTIL_TRACE("GetSWVersion caching enabled"); |
|
1179 return GetVersionPropertyData( KSWVersionUid, aValue ); |
|
1180 } |
|
1181 } |
|
1182 |
|
1183 /** |
|
1184 Returns displayable software version which the currently installed language |
|
1185 package is compatible with. |
|
1186 |
|
1187 This version text is provisioned by the device creator into the ROM |
|
1188 as a Unicode UTF16 format displayable string, for example: |
|
1189 |
|
1190 <code>V 1.0\\n29-07-07\\nBuild12345\\n(c) Symbian Software</code> |
|
1191 |
|
1192 This provisioned text string contains only one line of text with "\n" sequences |
|
1193 in the text which indicate a new line. This API will parse the |
|
1194 text and remove any "\n" sequences that it finds and replace it with the |
|
1195 Unicode newline sequence - 0x000A. The resulting |
|
1196 buffer is then a unicode string with newline sequences built in. This |
|
1197 then can for example, allow the buffer to be displayed directly to the |
|
1198 screen already formatted on multiple lines. |
|
1199 |
|
1200 @param aValue On return, contains the software version string. The buffer should |
|
1201 have space for KSysUtilVersionTextLength characters. If the buffer is |
|
1202 insufficient the descriptor is filled to its maximum length. If a buffer is |
|
1203 provided that is longer than 64 characters, and the provisioned text is larger |
|
1204 than 64 characters, the returned buffer is truncated at 64 characters (see error |
|
1205 codes below). |
|
1206 @return KErrNone on success, KErrTooBig if the maximum length of the descriptor |
|
1207 is insufficient to hold the provisioned text, or has been truncated (see above). |
|
1208 In both cases new-line processing is done on the buffers. If a zero length |
|
1209 text string has been provisioned KErrEof is returned, and the length of the |
|
1210 buffer is set to zero. If none of these cases apply then one of the Symbian |
|
1211 error codes is returned if reading the version string fails. |
|
1212 */ |
|
1213 EXPORT_C TInt SysUtil::GetLangSWVersion( TDes& aValue ) |
|
1214 { |
|
1215 if( KSysUtilDisableVersionSetupExe ) |
|
1216 { |
|
1217 __SYSUTIL_TRACE("GetLangSWVersion caching disabled"); |
|
1218 |
|
1219 TFileName filePath; |
|
1220 TInt err = GetFilePath( filePath ); |
|
1221 if( KErrNone != err) |
|
1222 { |
|
1223 return err; |
|
1224 } |
|
1225 |
|
1226 filePath.Append( KLangSWVersionFileName ); |
|
1227 |
|
1228 err = GetTextFromFile( filePath, aValue, ETrue ); |
|
1229 if ( err != KErrNone ) |
|
1230 { |
|
1231 __SYSUTIL_TRACE2("Error: %d, while processing: %S",err, &filePath); |
|
1232 } |
|
1233 |
|
1234 return err; |
|
1235 } |
|
1236 else |
|
1237 { |
|
1238 __SYSUTIL_TRACE("GetLangSWVersion caching enabled"); |
|
1239 return GetVersionPropertyData( KLangSWVersionUid, aValue ); |
|
1240 } |
|
1241 } |
|
1242 |
|
1243 /** |
|
1244 Obtains the displayable version of the currently installed language package. |
|
1245 This does NOT do any newline processing on the version text. |
|
1246 (unlike, for example GetLangSWVersion() or GetSWVersion()). |
|
1247 |
|
1248 This version text is provisioned by the device creator into the ROM |
|
1249 as a Unicode UTF16 format displayable string. |
|
1250 |
|
1251 @param aValue On return, contains the software version string. The buffer should |
|
1252 have space for KSysUtilVersionTextLength characters. If the buffer is |
|
1253 insufficient the descriptor is filled to its maximum length. If a buffer is |
|
1254 provided that is longer than 64 characters, and the provisioned text is larger |
|
1255 than 64 characters, the returned buffer is truncated at 64 characters (see error |
|
1256 codes below). |
|
1257 @return KErrNone on success, KErrTooBig if the maximum length of the descriptor |
|
1258 is insufficient to hold the provisioned text, or has been truncated (see above). |
|
1259 In both cases new-line processing is done on the buffers. If a zero length |
|
1260 text string has been provisioned KErrEof is returned, and the length of the |
|
1261 buffer is set to zero. If none of these cases apply then one of the Symbian |
|
1262 error codes is returned if reading the version string fails. |
|
1263 */ |
|
1264 EXPORT_C TInt SysUtil::GetLangVersion( TDes& aValue ) |
|
1265 { |
|
1266 if( KSysUtilDisableVersionSetupExe ) |
|
1267 { |
|
1268 __SYSUTIL_TRACE("GetLangVersion caching disabled"); |
|
1269 |
|
1270 TFileName filePath; |
|
1271 TInt err = GetFilePath( filePath ); |
|
1272 if( KErrNone != err) |
|
1273 { |
|
1274 return err; |
|
1275 } |
|
1276 |
|
1277 filePath.Append( KLangVersionFileName ); |
|
1278 |
|
1279 err = GetTextFromFile( filePath, aValue, ETrue ); |
|
1280 if ( err != KErrNone ) |
|
1281 { |
|
1282 __SYSUTIL_TRACE2("Error: %d, while processing: %S",err, &filePath); |
|
1283 } |
|
1284 |
|
1285 return err; |
|
1286 } |
|
1287 else |
|
1288 { |
|
1289 __SYSUTIL_TRACE("GetLangVersion caching enabled"); |
|
1290 return GetVersionPropertyData( KLangVersionUid, aValue ); |
|
1291 } |
|
1292 } |
|
1293 |
|
1294 /** |
|
1295 Obtains the displayable product release information string. |
|
1296 |
|
1297 Usage example: |
|
1298 @code |
|
1299 TBuf<KSysUtilVersionTextLength> prInfo; |
|
1300 if ( SysUtil::GetPRInformation( prInfo ) == KErrNone ) |
|
1301 { |
|
1302 // Use the version string. |
|
1303 ... |
|
1304 } |
|
1305 @endcode |
|
1306 The product release information is provisioned by the device creator into the ROM |
|
1307 as a Unicode UTF16 format displayable string, for example: |
|
1308 |
|
1309 <code>custom build\n20090626\nusb fix xyz</code> |
|
1310 or |
|
1311 <code>PR1.0</code> |
|
1312 or |
|
1313 <code>PR1.1</code> |
|
1314 |
|
1315 This provisioned text string contains only one line of text with "\n" sequences |
|
1316 in the text which indicate a new line. This API will parse the |
|
1317 text and remove any "\n" sequences that it finds and replace it with the |
|
1318 Unicode newline sequence - 0x000A. The resulting |
|
1319 buffer is then a unicode string with newline sequences built in. This |
|
1320 then can for example, allow the buffer to be displayed directly to the |
|
1321 screen already formatted on multiple lines. |
|
1322 |
|
1323 @param aValue On return, contains the product release information string. The buffer should |
|
1324 have space for KSysUtilVersionTextLength characters. If the buffer is |
|
1325 insufficient the descriptor is filled to its maximum length. If a buffer is |
|
1326 provided that is longer than 64 characters, and the provisioned text is larger |
|
1327 than 64 characters, the returned buffer is truncated at 64 characters. |
|
1328 @return KErrNone on success, KErrTooBig if the maximum length of the descriptor |
|
1329 is insufficient to hold the provisioned text, or has been truncated. |
|
1330 In both cases new-line processing is done on the buffers. If a zero length |
|
1331 text string has been provisioned KErrEof is returned, and the length of the |
|
1332 buffer is set to zero. If none of these cases apply then one of the Symbian |
|
1333 error codes is returned if reading the product release string fails. |
|
1334 */ |
|
1335 EXPORT_C TInt SysUtil::GetPRInformation( TDes& aValue ) |
|
1336 { |
|
1337 TInt err = KErrNone; |
|
1338 if( KSysUtilDisableVersionSetupExe ) |
|
1339 { |
|
1340 __SYSUTIL_TRACE("GetPRInformation caching disabled"); |
|
1341 TFileName filePath; |
|
1342 GetFilePath( filePath ); |
|
1343 filePath.Append( KPRInformationFileName ); |
|
1344 err = GetTextFromFile( filePath, aValue, ETrue ); |
|
1345 if ( err != KErrNone ) |
|
1346 { |
|
1347 __SYSUTIL_TRACE2("Error: %d, while processing: %S",err, &filePath); |
|
1348 } |
|
1349 } |
|
1350 else |
|
1351 { |
|
1352 __SYSUTIL_TRACE("GetPRInformation caching enabled"); |
|
1353 err = GetVersionPropertyData( KPRInformationUid, aValue ); |
|
1354 } |
|
1355 return err; |
|
1356 } |
|
1357 |
|
1358 /** |
|
1359 Checks if free system drive storage space is or will fall below critical level. |
|
1360 The system drive (internal, read/write, persistent drive) is also known |
|
1361 as the FFS (internal flash file system). |
|
1362 |
|
1363 To calculate if a critical level has been reached the critical level threshold |
|
1364 setting will be used. This setting is available in the patchable data. |
|
1365 |
|
1366 RAM drives and non-RAM drives have different threshold levels, so the corresponding |
|
1367 setting will be used for the calculation depending on the drive type. |
|
1368 |
|
1369 RAM drives are defined to be drives that have the media type of EMediaRam |
|
1370 as returned by RFs. @see RFs::Drive |
|
1371 |
|
1372 To set the patchdata for the RAM drive threshold set the MACRO |
|
1373 SYMBIAN_BAFL_SYSUTIL_RAM_DRIVE_CRITICAL_THRESHOLD at ROM build time to an |
|
1374 appropriate level. To set the patchdata for the non-RAM drive threshold |
|
1375 set the MACRO SYMBIAN_BAFL_SYSUTIL_OTHER_DISK_CRITICAL_THRESHOLD at ROM |
|
1376 build time to an appropriate level. |
|
1377 |
|
1378 This method also needs to determine which drive is the FFS drive. To do |
|
1379 this patchable data has been provided. If the patchable data has not been |
|
1380 set, then RFs::GetSystemDrive() will be used to determine the FFS drive. |
|
1381 |
|
1382 To set the patchdata to the FFS drive set the MACRO |
|
1383 SYMBIAN_BAFL_SYSUTIL_DEFAULT_FFS_DRIVE to the appropriate drive letter. |
|
1384 @see TDriveNumber |
|
1385 |
|
1386 This function exists here to maintain binary compatibility . |
|
1387 @see SysUtil::FFSSpaceBelowCriticalLevelL |
|
1388 |
|
1389 @param aFs File server session. Must be given if available, e.g. from |
|
1390 EIKON environment. If NULL, this method will create a temporary session, |
|
1391 which causes the method to consume more time and system resources. |
|
1392 @param aBytesToWrite Number of bytes the caller is about to write to the |
|
1393 system drive. If value 0 is given, this method checks if the current system |
|
1394 drive space is already below critical level. |
|
1395 @return ETrue if system drive space would go below critical level after writing |
|
1396 aBytesToWrite more data, EFalse otherwise. |
|
1397 @leave System wide error codes |
|
1398 */ |
|
1399 EXPORT_C TBool SysUtil::FFSSpaceBelowCriticalLevel_OldL( |
|
1400 RFs* aFs, |
|
1401 TInt aBytesToWrite ) |
|
1402 { |
|
1403 __SYSUTIL_TRACE("SysUtil::FFSSpaceBelowCriticalLevel_OldL"); |
|
1404 TBool retVal( EFalse ); |
|
1405 |
|
1406 RFs fs; |
|
1407 if ( !aFs ) |
|
1408 { |
|
1409 User::LeaveIfError( fs.Connect() ); // Create temp session. |
|
1410 CleanupClosePushL( fs ); |
|
1411 } |
|
1412 else |
|
1413 { |
|
1414 if( aFs->Handle() == KNullHandle ) |
|
1415 { |
|
1416 User::Panic(_L("BAFL"), EBafPanicRFsConnectArg ); |
|
1417 } |
|
1418 fs = *aFs; |
|
1419 } |
|
1420 |
|
1421 TInt ffsDrive = GetFFSDriveLetter( fs ); |
|
1422 retVal = DiskSpaceBelowCriticalLevel_OldL(&fs, aBytesToWrite, ffsDrive ); |
|
1423 |
|
1424 if ( !aFs ) |
|
1425 { |
|
1426 CleanupStack::PopAndDestroy(); // Close temp session |
|
1427 } |
|
1428 |
|
1429 return retVal; |
|
1430 } |
|
1431 |
|
1432 /** |
|
1433 Checks if free disk drive storage space is or will fall below critical |
|
1434 level. |
|
1435 |
|
1436 To calculate if a critical level has been reached the critical level threshold |
|
1437 setting will be used. This setting is available in the patchable data. |
|
1438 |
|
1439 RAM drives and non-RAM drives have different threshold levels, so the corresponding |
|
1440 setting will be used for the calculation depending on the drive type. |
|
1441 |
|
1442 RAM drives are defined to be drives that have the media type of EMediaRam |
|
1443 as returned by RFs. @see RFs::Drive |
|
1444 |
|
1445 To set the patchdata for the RAM drive threshold set the MACRO |
|
1446 SYMBIAN_BAFL_SYSUTIL_RAM_DRIVE_CRITICAL_THRESHOLD at ROM build time to an |
|
1447 appropriate level. To set the patchdata for the non-RAM drive threshold |
|
1448 set the MACRO SYMBIAN_BAFL_SYSUTIL_OTHER_DISK_CRITICAL_THRESHOLD at ROM |
|
1449 build time to an appropriate level. |
|
1450 |
|
1451 This function exists here to maintain binary compatibility . |
|
1452 @see SysUtil::DiskSpaceBelowCriticalLevelL |
|
1453 |
|
1454 @param aFs File server session. Must be given if available, e.g. from |
|
1455 EIKON environment. If NULL, this method will create a temporary session, |
|
1456 which causes the method to consume more time and system resources. |
|
1457 @param aBytesToWrite Number of bytes the caller is about to write to |
|
1458 disk. If value 0 is given, this method checks if the current disk space |
|
1459 is already below critical level. |
|
1460 @param aDrive Identifies the disk drive to be checked. Numeric values |
|
1461 for identifying disk drives are defined in TDriveNumber enumeration. |
|
1462 @see TDriveNumber in f32file.h. |
|
1463 @return ETrue if disk space would go below critical level after writing |
|
1464 aBytesToWrite more data, EFalse otherwise. |
|
1465 @leave System wide error codes |
|
1466 */ |
|
1467 EXPORT_C TBool SysUtil::DiskSpaceBelowCriticalLevel_OldL( |
|
1468 RFs* aFs, |
|
1469 TInt aBytesToWrite, |
|
1470 TInt aDrive ) |
|
1471 { |
|
1472 __SYSUTIL_TRACE1("SysUtil::DiskSpaceBelowCriticalLevel_OldL( %d )",aDrive); |
|
1473 |
|
1474 RFs fs; |
|
1475 if ( !aFs ) |
|
1476 { |
|
1477 User::LeaveIfError( fs.Connect() ); // Create temp session. |
|
1478 CleanupClosePushL( fs ); |
|
1479 } |
|
1480 else |
|
1481 { |
|
1482 if( aFs->Handle() == KNullHandle ) |
|
1483 { |
|
1484 User::Panic(_L("BAFL"), EBafPanicRFsConnectArg ); |
|
1485 } |
|
1486 fs = *aFs; |
|
1487 } |
|
1488 |
|
1489 TVolumeInfo vinfo; |
|
1490 // This may leave e.g. KErrNotReady if no drive |
|
1491 TInt errorCode = fs.Volume( vinfo, aDrive ); |
|
1492 |
|
1493 if ( !aFs ) |
|
1494 { |
|
1495 CleanupStack::PopAndDestroy(); // Close temp session |
|
1496 } |
|
1497 |
|
1498 __SYSUTIL_TRACE1("SysUtil::DiskSpaceBelowCriticalLevel_OldL RFs::Volume returned error code %d.",errorCode); |
|
1499 User::LeaveIfError( errorCode ); |
|
1500 |
|
1501 const TInt64 criticalLevel = FindCriticalLevelTresholdL( vinfo.iDrive.iType ); |
|
1502 __SYSUTIL_TRACE3("SysUtil: CL treshold value: %Ld, Free: %Ld, Size: %Ld",criticalLevel,vinfo.iFree,vinfo.iSize); |
|
1503 |
|
1504 return ( vinfo.iFree - (TInt64)aBytesToWrite ) <= criticalLevel; |
|
1505 } |
|
1506 |
|
1507 /** |
|
1508 Checks if free MMC storage space is or will fall below critical |
|
1509 level. |
|
1510 |
|
1511 To calculate if a critical level has been reached the critical level threshold |
|
1512 setting will be used. This setting is available in the patchable data. |
|
1513 |
|
1514 RAM drives and non-RAM drives have different threshold levels, so the corresponding |
|
1515 setting will be used for the calculation depending on the drive type. |
|
1516 |
|
1517 RAM drives are defined to be drives that have the media type of EMediaRam |
|
1518 as returned by RFs. @see RFs::Drive |
|
1519 |
|
1520 This method also needs to determine which drive is the MMC drive. To do |
|
1521 this a patchable data has been provided. If the patchable data |
|
1522 has not been set, then the drive will be fetched using BSUL. |
|
1523 @see CCachedDriveInfo |
|
1524 |
|
1525 To set the patchdata for the RAM drive threshold set the MACRO |
|
1526 SYMBIAN_BAFL_SYSUTIL_RAM_DRIVE_CRITICAL_THRESHOLD at ROM build time to an |
|
1527 appropriate level. To set the patchdata for the non-RAM drive threshold |
|
1528 set the MACRO SYMBIAN_BAFL_SYSUTIL_OTHER_DISK_CRITICAL_THRESHOLD at ROM |
|
1529 build time to an appropriate level. |
|
1530 |
|
1531 To set the patchdata to the MMC drive set the MACRO |
|
1532 SYMBIAN_BAFL_SYSUTIL_DEFAULT_MMC_DRIVE to the appropriate drive letter. |
|
1533 @see TDriveNumber |
|
1534 |
|
1535 This function exists here to maintain binary compatibility . |
|
1536 @see SysUtil::MMCSpaceBelowCriticalLevelL |
|
1537 |
|
1538 @param aFs File server session. Must be given if available, e.g. from |
|
1539 EIKON environment. If NULL, this method will create a temporary session, |
|
1540 which causes the method to consume more time and system resources. |
|
1541 @param aBytesToWrite Number of bytes the caller is about to write to |
|
1542 MMC. If value 0 is given, this method checks if the current MMC space |
|
1543 is already below critical level. |
|
1544 @return ETrue if MMC space would go below critical level after writing |
|
1545 aBytesToWrite more data, EFalse otherwise. |
|
1546 @leave KErrNotFound if the MMC drive cannot be found, otherwise one of the |
|
1547 system-wide error codes. |
|
1548 */ |
|
1549 EXPORT_C TBool SysUtil::MMCSpaceBelowCriticalLevel_OldL(RFs* aFs, TInt aBytesToWrite) |
|
1550 { |
|
1551 __SYSUTIL_TRACE("SysUtil::MMCSpaceBelowCriticalLevel_OldL"); |
|
1552 TBool retVal(EFalse); |
|
1553 |
|
1554 RFs fs; |
|
1555 if ( !aFs ) |
|
1556 { |
|
1557 User::LeaveIfError( fs.Connect() ); // Create temp session. |
|
1558 CleanupClosePushL( fs ); |
|
1559 } |
|
1560 else |
|
1561 { |
|
1562 if( aFs->Handle() == KNullHandle ) |
|
1563 { |
|
1564 User::Panic(_L("BAFL"), EBafPanicRFsConnectArg ); |
|
1565 } |
|
1566 fs = *aFs; |
|
1567 } |
|
1568 |
|
1569 TInt mmcDrive = GetMMCDriveLetter( fs ); |
|
1570 retVal = DiskSpaceBelowCriticalLevel_OldL(&fs, aBytesToWrite, mmcDrive ); |
|
1571 |
|
1572 if ( !aFs ) |
|
1573 { |
|
1574 CleanupStack::PopAndDestroy(); // Close temp session |
|
1575 } |
|
1576 |
|
1577 return retVal; |
|
1578 } |
|
1579 |
|
1580 /** |
|
1581 Checks if free system drive storage space is or will fall below critical level. |
|
1582 The system drive (internal, read/write, persistent drive) is also known |
|
1583 as the FFS (internal flash file system). |
|
1584 |
|
1585 To calculate if a critical level has been reached the critical level threshold |
|
1586 setting will be used. This setting is available in the patchable data. |
|
1587 |
|
1588 RAM drives and non-RAM drives have different threshold levels, so the corresponding |
|
1589 setting will be used for the calculation depending on the drive type. |
|
1590 |
|
1591 RAM drives are defined to be drives that have the media type of EMediaRam |
|
1592 as returned by RFs. @see RFs::Drive |
|
1593 |
|
1594 To set the patchdata for the RAM drive threshold set the MACRO |
|
1595 SYMBIAN_BAFL_SYSUTIL_RAM_DRIVE_CRITICAL_THRESHOLD at ROM build time to an |
|
1596 appropriate level. To set the patchdata for the non-RAM drive threshold |
|
1597 set the MACRO SYMBIAN_BAFL_SYSUTIL_OTHER_DISK_CRITICAL_THRESHOLD at ROM |
|
1598 build time to an appropriate level. |
|
1599 |
|
1600 This method also needs to determine which drive is the FFS drive. To do |
|
1601 this patchable data has been provided. If the patchable data has not been |
|
1602 set, then RFs::GetSystemDrive() will be used to determine the FFS drive. |
|
1603 |
|
1604 To set the patchdata to the FFS drive set the MACRO |
|
1605 SYMBIAN_BAFL_SYSUTIL_DEFAULT_FFS_DRIVE to the appropriate drive letter. |
|
1606 @see TDriveNumber |
|
1607 |
|
1608 @param aFs File server session. Must be given if available, e.g. from |
|
1609 EIKON environment. If NULL, this method will create a temporary session, |
|
1610 which causes the method to consume more time and system resources. |
|
1611 @param aBytesToWrite Number of bytes the caller is about to write to the |
|
1612 system drive. If value 0 is given, this method checks if the current system |
|
1613 drive space is already below critical level. |
|
1614 @return ETrue if system drive space would go below critical level after writing |
|
1615 aBytesToWrite more data, EFalse otherwise. |
|
1616 @leave System wide error codes |
|
1617 */ |
|
1618 |
|
1619 EXPORT_C TBool SysUtil::FFSSpaceBelowCriticalLevelL( |
|
1620 RFs* aFs, |
|
1621 TInt64 aBytesToWrite ) |
|
1622 { |
|
1623 __SYSUTIL_TRACE("SysUtil::FFSSpaceBelowCriticalLevelL"); |
|
1624 TBool retVal( EFalse ); |
|
1625 |
|
1626 RFs fs; |
|
1627 if ( !aFs ) |
|
1628 { |
|
1629 User::LeaveIfError( fs.Connect() ); // Create temp session. |
|
1630 CleanupClosePushL( fs ); |
|
1631 } |
|
1632 else |
|
1633 { |
|
1634 if( aFs->Handle() == KNullHandle ) |
|
1635 { |
|
1636 User::Panic(_L("BAFL"), EBafPanicRFsConnectArg ); |
|
1637 } |
|
1638 fs = *aFs; |
|
1639 } |
|
1640 |
|
1641 TInt ffsDrive = GetFFSDriveLetter( fs ); |
|
1642 retVal = DiskSpaceBelowCriticalLevelL(&fs, aBytesToWrite, ffsDrive ); |
|
1643 |
|
1644 if ( !aFs ) |
|
1645 { |
|
1646 CleanupStack::PopAndDestroy(); // Close temp session |
|
1647 } |
|
1648 |
|
1649 return retVal; |
|
1650 } |
|
1651 |
|
1652 /** |
|
1653 Checks if free disk drive storage space is or will fall below critical |
|
1654 level. |
|
1655 |
|
1656 To calculate if a critical level has been reached the critical level threshold |
|
1657 setting will be used. This setting is available in the patchable data. |
|
1658 |
|
1659 RAM drives and non-RAM drives have different threshold levels, so the corresponding |
|
1660 setting will be used for the calculation depending on the drive type. |
|
1661 |
|
1662 RAM drives are defined to be drives that have the media type of EMediaRam |
|
1663 as returned by RFs. @see RFs::Drive |
|
1664 |
|
1665 To set the patchdata for the RAM drive threshold set the MACRO |
|
1666 SYMBIAN_BAFL_SYSUTIL_RAM_DRIVE_CRITICAL_THRESHOLD at ROM build time to an |
|
1667 appropriate level. To set the patchdata for the non-RAM drive threshold |
|
1668 set the MACRO SYMBIAN_BAFL_SYSUTIL_OTHER_DISK_CRITICAL_THRESHOLD at ROM |
|
1669 build time to an appropriate level. |
|
1670 |
|
1671 Usage example: |
|
1672 @code |
|
1673 TInt64 dataSize = 500000000; |
|
1674 if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFsSession, dataSize, EDriveC ) ) |
|
1675 { |
|
1676 // Can not write the data, there's not enough free space on disk. |
|
1677 ... |
|
1678 } |
|
1679 else |
|
1680 { |
|
1681 // It's ok to actually write the data. |
|
1682 ... |
|
1683 } |
|
1684 @endcode |
|
1685 @param aFs File server session. Must be given if available, e.g. from |
|
1686 EIKON environment. If NULL, this method will create a temporary session, |
|
1687 which causes the method to consume more time and system resources. |
|
1688 @param aBytesToWrite Number of bytes the caller is about to write to |
|
1689 disk. If value 0 is given, this method checks if the current disk space |
|
1690 is already below critical level. |
|
1691 @param aDrive Identifies the disk drive to be checked. Numeric values |
|
1692 for identifying disk drives are defined in TDriveNumber enumeration. |
|
1693 @see TDriveNumber in f32file.h. |
|
1694 @return ETrue if disk space would go below critical level after writing |
|
1695 aBytesToWrite more data, EFalse otherwise. |
|
1696 @leave System wide error codes |
|
1697 */ |
|
1698 |
|
1699 EXPORT_C TBool SysUtil::DiskSpaceBelowCriticalLevelL( |
|
1700 RFs* aFs, |
|
1701 TInt64 aBytesToWrite, |
|
1702 TInt aDrive ) |
|
1703 { |
|
1704 __SYSUTIL_TRACE1("SysUtil::DiskSpaceBelowCriticalLevelL( %d )",aDrive); |
|
1705 |
|
1706 RFs fs; |
|
1707 if ( !aFs ) |
|
1708 { |
|
1709 User::LeaveIfError( fs.Connect() ); // Create temp session. |
|
1710 CleanupClosePushL( fs ); |
|
1711 } |
|
1712 else |
|
1713 { |
|
1714 if( aFs->Handle() == KNullHandle ) |
|
1715 { |
|
1716 User::Panic(_L("BAFL"), EBafPanicRFsConnectArg ); |
|
1717 } |
|
1718 fs = *aFs; |
|
1719 } |
|
1720 |
|
1721 TVolumeInfo vinfo; |
|
1722 // This may leave e.g. KErrNotReady if no drive |
|
1723 TInt errorCode = fs.Volume( vinfo, aDrive ); |
|
1724 |
|
1725 if ( !aFs ) |
|
1726 { |
|
1727 CleanupStack::PopAndDestroy(); // Close temp session |
|
1728 } |
|
1729 |
|
1730 __SYSUTIL_TRACE1("SysUtil::DiskSpaceBelowCriticalLevelL RFs::Volume returned error code %d.",errorCode); |
|
1731 User::LeaveIfError( errorCode ); |
|
1732 |
|
1733 const TInt64 criticalLevel = FindCriticalLevelTresholdL( vinfo.iDrive.iType ); |
|
1734 __SYSUTIL_TRACE3("SysUtil: CL treshold value: %Ld, Free: %Ld, Size: %Ld",criticalLevel,vinfo.iFree,vinfo.iSize); |
|
1735 |
|
1736 return ( vinfo.iFree - aBytesToWrite ) <= criticalLevel; |
|
1737 } |
|
1738 |
|
1739 /** |
|
1740 Checks if free MMC storage space is or will fall below critical |
|
1741 level. |
|
1742 |
|
1743 To calculate if a critical level has been reached the critical level threshold |
|
1744 setting will be used. This setting is available in the patchable data. |
|
1745 |
|
1746 RAM drives and non-RAM drives have different threshold levels, so the corresponding |
|
1747 setting will be used for the calculation depending on the drive type. |
|
1748 |
|
1749 RAM drives are defined to be drives that have the media type of EMediaRam |
|
1750 as returned by RFs. @see RFs::Drive |
|
1751 |
|
1752 This method also needs to determine which drive is the MMC drive. To do |
|
1753 this a patchable data has been provided. If the patchable data |
|
1754 has not been set, then the drive will be fetched using BSUL. |
|
1755 @see CCachedDriveInfo |
|
1756 |
|
1757 To set the patchdata for the RAM drive threshold set the MACRO |
|
1758 SYMBIAN_BAFL_SYSUTIL_RAM_DRIVE_CRITICAL_THRESHOLD at ROM build time to an |
|
1759 appropriate level. To set the patchdata for the non-RAM drive threshold |
|
1760 set the MACRO SYMBIAN_BAFL_SYSUTIL_OTHER_DISK_CRITICAL_THRESHOLD at ROM |
|
1761 build time to an appropriate level. |
|
1762 |
|
1763 To set the patchdata to the MMC drive set the MACRO |
|
1764 SYMBIAN_BAFL_SYSUTIL_DEFAULT_MMC_DRIVE to the appropriate drive letter. |
|
1765 @see TDriveNumber |
|
1766 |
|
1767 @param aFs File server session. Must be given if available, e.g. from |
|
1768 EIKON environment. If NULL, this method will create a temporary session, |
|
1769 which causes the method to consume more time and system resources. |
|
1770 @param aBytesToWrite Number of bytes the caller is about to write to |
|
1771 MMC. If value 0 is given, this method checks if the current MMC space |
|
1772 is already below critical level. |
|
1773 @return ETrue if MMC space would go below critical level after writing |
|
1774 aBytesToWrite more data, EFalse otherwise. |
|
1775 @leave KErrNotFound if the MMC drive cannot be found, otherwise one of the |
|
1776 system-wide error codes. |
|
1777 */ |
|
1778 EXPORT_C TBool SysUtil::MMCSpaceBelowCriticalLevelL(RFs* aFs, TInt64 aBytesToWrite) |
|
1779 { |
|
1780 __SYSUTIL_TRACE("SysUtil::MMCSpaceBelowCriticalLevelL"); |
|
1781 TBool retVal(EFalse); |
|
1782 |
|
1783 RFs fs; |
|
1784 if ( !aFs ) |
|
1785 { |
|
1786 User::LeaveIfError( fs.Connect() ); // Create temp session. |
|
1787 CleanupClosePushL( fs ); |
|
1788 } |
|
1789 else |
|
1790 { |
|
1791 if( aFs->Handle() == KNullHandle ) |
|
1792 { |
|
1793 User::Panic(_L("BAFL"), EBafPanicRFsConnectArg ); |
|
1794 } |
|
1795 fs = *aFs; |
|
1796 } |
|
1797 |
|
1798 TInt mmcDrive = GetMMCDriveLetter( fs ); |
|
1799 retVal = DiskSpaceBelowCriticalLevelL(&fs, aBytesToWrite, mmcDrive ); |
|
1800 |
|
1801 if ( !aFs ) |
|
1802 { |
|
1803 CleanupStack::PopAndDestroy(); // Close temp session |
|
1804 } |
|
1805 |
|
1806 return retVal; |
|
1807 } |
|
1808 |
|
1809 |
|
1810 /** |
|
1811 Returns the FFS drive letter |
|
1812 |
|
1813 This method determines which drive is the FFS drive. To do |
|
1814 this a patchable data has been provided. If the patchable data |
|
1815 has not been set, then the drive will be fetched via a call to |
|
1816 GetSystemDrive(). |
|
1817 |
|
1818 To set the patchdata to the FFS drive set the MACRO |
|
1819 SYMBIAN_BAFL_SYSUTIL_DEFAULT_FFS_DRIVE to the appropriate drive letter. |
|
1820 @see TDriveNumber |
|
1821 |
|
1822 @return TInt the integer value equivalent of the TDriveNumber |
|
1823 */ |
|
1824 EXPORT_C TInt SysUtil::GetFFSDriveLetter( RFs & aFs ) |
|
1825 { |
|
1826 // Check the argument, and panic if necessary |
|
1827 if( aFs.Handle() == KNullHandle ) |
|
1828 { |
|
1829 User::Panic(_L("KERN-EXEC"), 0); |
|
1830 } |
|
1831 |
|
1832 // Check to see if FFS drive is set in patchable data |
|
1833 TInt ffsDrive = KSysUtilDefaultFFSDrive; |
|
1834 if( !(ffsDrive >= EDriveA && ffsDrive <= EDriveZ) ) |
|
1835 { |
|
1836 ffsDrive = aFs.GetSystemDrive(); |
|
1837 } |
|
1838 |
|
1839 return ffsDrive; |
|
1840 } |
|
1841 |
|
1842 /** |
|
1843 Returns the MMC drive letter |
|
1844 |
|
1845 This method determines which drive is the MMC drive. To do |
|
1846 this a patchable data has been provided. |
|
1847 |
|
1848 To set the patchdata to the MMC drive set the MACRO |
|
1849 SYMBIAN_BAFL_SYSUTIL_DEFAULT_MMC_DRIVE to the appropriate drive letter. |
|
1850 @see TDriveNumber |
|
1851 |
|
1852 @return TInt the integer value equivalent of the TDriveNumber |
|
1853 */ |
|
1854 |
|
1855 EXPORT_C TInt SysUtil::GetMMCDriveLetter( RFs & aFs ) |
|
1856 { |
|
1857 // Check the argument, and panic if necessary |
|
1858 if( aFs.Handle() == KNullHandle ) |
|
1859 { |
|
1860 User::Panic(_L("KERN-EXEC"), 0); |
|
1861 } |
|
1862 |
|
1863 // Check to see if MMC drive is set in patchable data |
|
1864 TInt mmcDrive = KSysUtilDefaultMMCDrive; |
|
1865 |
|
1866 // If a valid mmcDrive is not currently found in patchable data, then search for one. |
|
1867 if( !(mmcDrive >= EDriveA && mmcDrive <= EDriveZ) ) |
|
1868 { |
|
1869 __SYSUTIL_TRACE("SysUtil::MMCSpaceBelowCriticalLevelL - searching for MMC drive"); |
|
1870 // If mmcDrive is not set in patchable data, then fetch the MMC drive from BSUL. |
|
1871 BSUL::CCachedDriveInfo *cachedDriveInfo = BSUL::CCachedDriveInfo::NewLC( aFs ); |
|
1872 // This will find valid MMC drive, leave if none available |
|
1873 mmcDrive = cachedDriveInfo->GetDefaultRemovableMemoryCardDriveL(); |
|
1874 __SYSUTIL_TRACE1("SysUtil::MMCSpaceBelowCriticalLevelL, Selected MMC drive %d.",mmcDrive); |
|
1875 CleanupStack::PopAndDestroy(cachedDriveInfo); |
|
1876 } |
|
1877 |
|
1878 return mmcDrive; |
|
1879 } |
|
1880 |
|
1881 /** |
|
1882 Creates and returns a populated CDeviceTypeInformation object which is used |
|
1883 to access the device type information attributes. |
|
1884 |
|
1885 All the attributes are provisioned by the device creator. |
|
1886 |
|
1887 The returned object is owned by the calling code and so it is the calling |
|
1888 codes responsibility to delete this object when it no longer requires it. |
|
1889 |
|
1890 @return CDeviceTypeInformation* A pointer to an instance of CDeviceTypeInformation. |
|
1891 @leave KErrNoMemory If there is not enough memory to create the object. |
|
1892 @leave KErrNotReady If there was a problem retrieving the device type |
|
1893 information attributes. |
|
1894 @leave - Otherwise one of the other system-wide error codes. |
|
1895 @see CDeviceTypeInformation |
|
1896 */ |
|
1897 EXPORT_C CDeviceTypeInformation* SysUtil::GetDeviceTypeInfoL() |
|
1898 { |
|
1899 __SYSUTIL_TRACE("SysUtil::GetDeviceTypeInfoL"); |
|
1900 return CDeviceTypeInformation::NewL(); |
|
1901 } |
|
1902 |
|
1903 // ================= CDeviceTypeInformation MEMBER FUNCTIONS =================== |
|
1904 |
|
1905 /** |
|
1906 Class destructor. |
|
1907 |
|
1908 Performs any clean up such as deleting memory on the heap. |
|
1909 */ |
|
1910 EXPORT_C CDeviceTypeInformation::~CDeviceTypeInformation() |
|
1911 { |
|
1912 SDeviceAttributes* attr = reinterpret_cast<SDeviceAttributes*>( iImpl ); |
|
1913 if( attr != NULL ) |
|
1914 { |
|
1915 delete attr->iDeviceAttributes; |
|
1916 delete attr; |
|
1917 } |
|
1918 } |
|
1919 |
|
1920 /** |
|
1921 Allocates and constructs an instance of CDeviceTypeInformation. |
|
1922 |
|
1923 @return A pointer to an instance of CDeviceTypeInformation. |
|
1924 @leave KErrNoMemory, if there is not enough memory to create the object. |
|
1925 @leave - Otherwise one of the other system-wide error codes. |
|
1926 */ |
|
1927 CDeviceTypeInformation* CDeviceTypeInformation::NewL() |
|
1928 { |
|
1929 CDeviceTypeInformation* self = new (ELeave) CDeviceTypeInformation(); |
|
1930 CleanupStack::PushL( self ); |
|
1931 self->ConstructL(); |
|
1932 CleanupStack::Pop( self ); |
|
1933 return self; |
|
1934 } |
|
1935 |
|
1936 /** |
|
1937 Class constructor. |
|
1938 |
|
1939 Performs any class construction tasks that will not cause a leave. |
|
1940 */ |
|
1941 CDeviceTypeInformation::CDeviceTypeInformation() : iImpl( NULL ) |
|
1942 { |
|
1943 } |
|
1944 |
|
1945 /** |
|
1946 Performs class creation tasks as part of two phase construction. |
|
1947 |
|
1948 Performs any class construction tasks that will cause a leave. |
|
1949 */ |
|
1950 void CDeviceTypeInformation::ConstructL() |
|
1951 { |
|
1952 SDeviceAttributes* attr = new (ELeave) SDeviceAttributes; |
|
1953 attr->iDeviceAttributes = NULL; |
|
1954 iImpl = reinterpret_cast<TImpl*>( attr ); |
|
1955 |
|
1956 if( !KSysUtilDisableDeviceTypeInfoSetupExe ) |
|
1957 { |
|
1958 __SYSUTIL_TRACE("GetDeviceTypeInfoL caching enabled"); |
|
1959 |
|
1960 // Check if the P&S property is already set. If it isn't then define and set it. If it |
|
1961 // is we will most likely get KErrOverflow as we are only providing enough space to |
|
1962 // get the first TUint16. This stores the length of the attribute. |
|
1963 TUint16 attributesLength; |
|
1964 TPtr16 attributesLengthTPtr( &attributesLength, 1 ); |
|
1965 TInt err = RProperty::Get( KSysUtilSetupUid, KDeviceTypeInfoUid.iUid, attributesLengthTPtr ); |
|
1966 if ( KErrNotFound == err ) |
|
1967 { |
|
1968 __SYSUTIL_TRACE("Launching sysutilsetup.exe"); |
|
1969 User::LeaveIfError( LaunchSetupExecutable( KSetDeviceTypeInfoPropertyFlag ) ); |
|
1970 __SYSUTIL_TRACE("sysutilsetup.exe terminated"); |
|
1971 |
|
1972 err = RProperty::Get( KSysUtilSetupUid, KDeviceTypeInfoUid.iUid, attributesLengthTPtr ); |
|
1973 if( KErrOverflow != err ) |
|
1974 { |
|
1975 User::LeaveIfError( err ); |
|
1976 } |
|
1977 } |
|
1978 else if( KErrOverflow != err ) |
|
1979 { |
|
1980 User::LeaveIfError( err ); |
|
1981 } |
|
1982 |
|
1983 attr->iDeviceAttributes = static_cast<TUint16*>( User::AllocL( sizeof(TUint16) * attributesLength ) ); |
|
1984 TPtr16 deviceAttributesTPtr( attr->iDeviceAttributes, attributesLength ); |
|
1985 User::LeaveIfError( RProperty::Get( KSysUtilSetupUid, KDeviceTypeInfoUid.iUid, deviceAttributesTPtr ) ); |
|
1986 } |
|
1987 else |
|
1988 { |
|
1989 __SYSUTIL_TRACE("GetDeviceTypeInfoL caching disabled"); |
|
1990 attr->iDeviceAttributes = FormattedDeviceTypeInfoL(); |
|
1991 } |
|
1992 } |
|
1993 |
|
1994 /** |
|
1995 Retrieves a reference to the attribute string which matches the provided |
|
1996 UID. The attribute has a maximum length of KMaxAttributeLength UTF-16 |
|
1997 characters. |
|
1998 |
|
1999 The attribute is provisioned by the device creator. If the device creator |
|
2000 does not provide an attribute value for the given UID then KNullDesC16 |
|
2001 will be supplied and KErrNotFound will be returned. If the device creator |
|
2002 has supplied an attribute value which is longer than KMaxAttributeLength |
|
2003 then the supplied value will be truncated. In this case KErrKErrOverflow |
|
2004 will be returned. |
|
2005 |
|
2006 @param aAttributeUid The UID of the required attribute. |
|
2007 @param aValue On return, contains the attribute value if successful |
|
2008 and KNullDesC16 otherwise. |
|
2009 @return KErrNone Successful, the provisioned value has been returned. |
|
2010 @return KErrNotFound A value for the given UID was not provisioned. |
|
2011 @return KErrOverflow The provisioned attribute value has been truncated. |
|
2012 @return - Otherwise, one of the other system-wide error codes. |
|
2013 @publishedPartner |
|
2014 @released |
|
2015 */ |
|
2016 EXPORT_C TInt CDeviceTypeInformation::GetAttribute( const TUid& aAttributeUid, TPtrC16& aValue ) const |
|
2017 { |
|
2018 SDeviceAttributes* attr = reinterpret_cast<SDeviceAttributes*>( this->iImpl ); |
|
2019 |
|
2020 TInt attributeNumber = FindAttributeNumber( *attr, aAttributeUid ); |
|
2021 if( KErrNotFound != attributeNumber ) |
|
2022 { |
|
2023 aValue.Set( attr->AttributePtr( attributeNumber ), attr->AttributeLength( attributeNumber ) ); |
|
2024 return attr->Error( attributeNumber ); |
|
2025 } |
|
2026 |
|
2027 aValue.Set( KNullDesC16 ); |
|
2028 return KErrNotFound; |
|
2029 } |
|
2030 |
|
2031 /** |
|
2032 Retrieves a reference to the Manufacturer Name string. This value conveys |
|
2033 the name of the device manufacturer. The Manufacturer Name has a maximum |
|
2034 length of KMaxAttributeLength UTF-16 characters. |
|
2035 |
|
2036 This is a standard device type information attribute (it is common to all |
|
2037 device creators) as such it can be assumed that an attribute value will |
|
2038 always be retrieved. |
|
2039 |
|
2040 The Manufacturer Name is provisioned by the device creator. If the device |
|
2041 creator does not provide a value for this attribute then a default value |
|
2042 will be supplied instead and KDefaultValue will be returned. If the device |
|
2043 creator has supplied a value and it is longer than KMaxAttributeLength |
|
2044 then the provisioned value will be truncated. In this case KErrOverflow |
|
2045 will be returned. |
|
2046 |
|
2047 Note: This attribute is represented by a UID of 0x10286358. |
|
2048 |
|
2049 @param aValue On return, contains the Manufacturer Name UTF-16 string. |
|
2050 @return KErrNone Successful, the provisioned value has been returned. |
|
2051 @return KDefaultValue Successful, the default value has been returned. |
|
2052 @return KErrOverflow The provisioned attribute value has been truncated |
|
2053 @return - Otherwise one of the other system-wide error codes. |
|
2054 */ |
|
2055 EXPORT_C TInt CDeviceTypeInformation::GetManufacturerName( TPtrC16& aValue ) const |
|
2056 { |
|
2057 TInt err = GetAttribute( KManufacturerNameUid, aValue ); |
|
2058 if( KErrNotFound == err ) |
|
2059 { |
|
2060 aValue.Set( KDefaultManufacturer ); |
|
2061 return CDeviceTypeInformation::KDefaultValue; |
|
2062 } |
|
2063 |
|
2064 return err; |
|
2065 } |
|
2066 |
|
2067 /** |
|
2068 Retrieves a reference to the Model Name string. This value conveys the |
|
2069 model name of the device as recognisable by the end-user i.e. the consumer. |
|
2070 The Model Name has a maximum length of KMaxAttributeLength UTF-16 |
|
2071 characters. |
|
2072 |
|
2073 This is a standard device type information attribute (it is common to all |
|
2074 device creators) as such it can be assumed that an attribute value will |
|
2075 always be retrieved. |
|
2076 |
|
2077 The Model Name is provisioned by the device creator. If the device creator |
|
2078 does not provide a value for this attribute then a default value will be |
|
2079 supplied instead and KDefaultValue will be returned. If the device creator |
|
2080 has supplied a value and it is longer than KMaxAttributeLength then the |
|
2081 provisioned value will be truncated. In this case KErrKErrOverflow will be |
|
2082 returned. |
|
2083 |
|
2084 Note: This attribute is represented by a UID of 0x10286359. |
|
2085 |
|
2086 @param aValue On return, contains the Model Name. |
|
2087 @return KErrNone Successful, the provisioned value has been returned. |
|
2088 @return KDefaultValue Successful, the default value has been returned. |
|
2089 @return KErrOverflow The provisioned attribute value has been truncated. |
|
2090 @return - Otherwise, one of the other system-wide error codes. |
|
2091 */ |
|
2092 EXPORT_C TInt CDeviceTypeInformation::GetModelName( TPtrC16& aValue ) const |
|
2093 { |
|
2094 TInt err = GetAttribute( KModelNameUid, aValue ); |
|
2095 if( KErrNotFound == err ) |
|
2096 { |
|
2097 aValue.Set( KDefaultModelName ); |
|
2098 return CDeviceTypeInformation::KDefaultValue; |
|
2099 } |
|
2100 |
|
2101 return err; |
|
2102 } |
|
2103 |
|
2104 /** |
|
2105 Retrieves a reference to the Model Code string. This value conveys the |
|
2106 internal model name or part number by which this model is known to the |
|
2107 manufacturer. The Model Code has a maximum length of KMaxAttributeLength |
|
2108 UTF-16 characters. |
|
2109 |
|
2110 This is a standard device type information attribute (it is common to all |
|
2111 device creators) as such it can be assumed that an attribute value will |
|
2112 always be retrieved. |
|
2113 |
|
2114 The Model Code is provisioned by the device creator. If the device creator |
|
2115 does not provide a value for this attribute then a default value will be |
|
2116 supplied instead and KDefaultValue will be returned. If the device creator |
|
2117 has supplied a value and it is longer than KMaxAttributeLength then the |
|
2118 provisioned value will be truncated. In this case KErrKErrOverflow will be |
|
2119 returned. |
|
2120 |
|
2121 Note: This attribute is represented by a UID of 0x1028635A. |
|
2122 |
|
2123 @param aValue On return, contains the Model Code. |
|
2124 @return KErrNone Successful, the provisioned value has been returned. |
|
2125 @return KDefaultValue Successful, the default value has been returned. |
|
2126 @return KErrOverflow The provisioned attribute value has been truncated. |
|
2127 @return - Otherwise, one of the other system-wide error codes. |
|
2128 */ |
|
2129 EXPORT_C TInt CDeviceTypeInformation::GetModelCode( TPtrC16& aValue ) const |
|
2130 { |
|
2131 TInt err = GetAttribute( KModelCodeUid, aValue ); |
|
2132 if( KErrNotFound == err ) |
|
2133 { |
|
2134 aValue.Set( KDefaultModelCode ); |
|
2135 return CDeviceTypeInformation::KDefaultValue; |
|
2136 } |
|
2137 |
|
2138 return err; |
|
2139 } |
|
2140 |
|
2141 /** |
|
2142 Retrieves a reference to the Revision ID string. This value contains the |
|
2143 device revision and/or variant identification string and conveys the |
|
2144 specific version of the hardware and software used in the device. The |
|
2145 Revision ID has a maximum length of KMaxAttributeLength UTF-16 |
|
2146 characters. |
|
2147 |
|
2148 This is a standard device type information attribute (it is common to all |
|
2149 device creators) as such it can be assumed that an attribute value will |
|
2150 always be retrieved. |
|
2151 |
|
2152 The Revision ID is provisioned by the device creator. If the device |
|
2153 creator does not provide a value for this attribute then a default value |
|
2154 will be supplied instead and KDefaultValue will be returned. If the device |
|
2155 creator has supplied a value and it is longer than KMaxAttributeLength |
|
2156 then the provisioned value will be truncated. In this case |
|
2157 KErrKErrOverflow will be returned. |
|
2158 |
|
2159 Note: This attribute is represented by a UID of 0x1028635B. |
|
2160 |
|
2161 @param aValue On return, contains the Revision ID (this also |
|
2162 includes the Variant ID). |
|
2163 @return KErrNone Successful, the provisioned value has been returned. |
|
2164 @return KDefaultValue Successful, the default value has been returned. |
|
2165 @return KErrOverflow The provisioned attribute value has been truncated. |
|
2166 @return - Otherwise, one of the other system-wide error codes. |
|
2167 */ |
|
2168 EXPORT_C TInt CDeviceTypeInformation::GetRevisionID( TPtrC16& aValue ) const |
|
2169 { |
|
2170 TInt err = GetAttribute( KRevisionIDUid, aValue ); |
|
2171 if( KErrNotFound == err ) |
|
2172 { |
|
2173 aValue.Set( KDefaultRevisionID ); |
|
2174 return CDeviceTypeInformation::KDefaultValue; |
|
2175 } |
|
2176 |
|
2177 return err; |
|
2178 } |
|
2179 |
|
2180 /** |
|
2181 Retrieves a copy of the default Device Name string. This value conveys |
|
2182 the default name for the device as might be used for network identification |
|
2183 e.g. Bluetooth nickname. The Device Name has a maximum length of |
|
2184 KMaxAttributeLength UTF-16 characters. |
|
2185 |
|
2186 This is a standard device type information attribute (it is common to all |
|
2187 device creators) as such it can be assumed that an attribute value will |
|
2188 always be retrieved. |
|
2189 |
|
2190 The Default Device Name is provisioned by the device creator. If the device |
|
2191 creator does not provide a value for this attribute then a default value |
|
2192 will be supplied instead and KDefaultValue will be returned. If the device |
|
2193 creator has supplied a value and it is longer than KMaxAttributeLength or |
|
2194 the user supplied descriptors length is less than KMaxAttributeLength then |
|
2195 the provioned value will be truncated. In this case KErrKErrOverflow will |
|
2196 be returned. |
|
2197 |
|
2198 Note: This attribute is represented by a UID of 0x1028635C. |
|
2199 |
|
2200 @param aValue On return, contains the Default Device Name. |
|
2201 @return KErrNone Successful, the provisioned value has been returned. |
|
2202 @return KDefaultValue Successful, the default value has been returned. |
|
2203 @return KErrOverflow The provisioned attribute value has been truncated. |
|
2204 @return - Otherwise, one of the other system-wide error codes. |
|
2205 */ |
|
2206 EXPORT_C TInt CDeviceTypeInformation::GetDefaultDeviceName( TPtrC16& aValue ) const |
|
2207 { |
|
2208 TInt err = GetAttribute( KDefaultDeviceNameUid, aValue ); |
|
2209 if( KErrNotFound == err ) |
|
2210 { |
|
2211 aValue.Set( KDefaultDeviceName ); |
|
2212 return CDeviceTypeInformation::KDefaultValue; |
|
2213 } |
|
2214 |
|
2215 return err; |
|
2216 } |
|
2217 |
|
2218 /** |
|
2219 Retrieves a reference to the name of the UI Platform software used |
|
2220 in the device. The UI Platform name has a maximum length of |
|
2221 KMaxAttributeLength UTF-16 characters. |
|
2222 |
|
2223 This is a standard device type information attribute (it is common to all |
|
2224 device creators) as such it can be assumed that an attribute value will |
|
2225 always be retrieved. |
|
2226 |
|
2227 The UI Platform is provisioned by the device creator. If the device |
|
2228 creator does not provide a value for this attribute then a default value |
|
2229 will be supplied instead and KDefaultValue will be returned. If the device |
|
2230 creator has supplied a value and it is longer than KMaxAttributeLength |
|
2231 then the provisioned value will be truncated. In this case |
|
2232 KErrKErrOverflow will be returned. |
|
2233 |
|
2234 Note: This attribute is represented by a UID of 0x1028635D. |
|
2235 |
|
2236 @param aValue On return, contains the UI Platform. |
|
2237 @return KErrNone Successful, the provisioned value has been returned. |
|
2238 @return KDefaultValue Successful, the default value has been returned. |
|
2239 @return KErrOverflow The provisioned attribute value has been truncated. |
|
2240 @return - Otherwise, one of the other system-wide error codes. |
|
2241 */ |
|
2242 EXPORT_C TInt CDeviceTypeInformation::GetUIPlatformName( TPtrC16& aValue ) const |
|
2243 { |
|
2244 TInt err = GetAttribute( KUIPlatformNameUid, aValue ); |
|
2245 if( KErrNotFound == err ) |
|
2246 { |
|
2247 aValue.Set( KDefaultUIPlatform ); |
|
2248 return CDeviceTypeInformation::KDefaultValue; |
|
2249 } |
|
2250 |
|
2251 return err; |
|
2252 } |
|
2253 |
|
2254 /** |
|
2255 Retrieves a reference to the UI Platform version used in the device for |
|
2256 display, transmission or tagging purposes. The UI Platform version has a maximum |
|
2257 length of KMaxAttributeLength UTF-16 characters. |
|
2258 |
|
2259 The string should never be used for programmatic decisions based on assumed |
|
2260 functionality present in the device as device creators can vary the content of |
|
2261 the device firmware. Instead Feature Manager should be used to query the |
|
2262 functional capabilities of a device. @see CFeatureDiscovery |
|
2263 |
|
2264 The UI Platform version is provisioned by the device creator. If the device |
|
2265 creator does not provide a value for this attribute then a default value |
|
2266 indicating unknown version will be supplied instead and KDefaultValue will |
|
2267 be returned. If the device creator has supplied a value and it is longer than |
|
2268 KMaxAttributeLength then the provisioned value will be truncated. In this case |
|
2269 KErrOverflow will be returned. The format of the string is device dependent. |
|
2270 |
|
2271 Note: This attribute is represented by a UID of 0x10286360. |
|
2272 |
|
2273 @param aValue On return, contains the UI version number of the |
|
2274 current UI platform. |
|
2275 @return KErrNone Successful, the provisioned value has been returned. |
|
2276 @return KDefaultValue Successful, the default value has been returned. |
|
2277 @return KErrOverflow The provisioned attribute value has been truncated |
|
2278 due to the provided descriptor being too small. |
|
2279 @return - Otherwise, one of the other system-wide error codes. |
|
2280 */ |
|
2281 EXPORT_C TInt CDeviceTypeInformation::GetUIPlatformVersion( TPtrC16& aValue ) const |
|
2282 { |
|
2283 TInt err = GetAttribute( KUIPlatformVersionUid, aValue ); |
|
2284 if( KErrNotFound == err ) |
|
2285 { |
|
2286 aValue.Set( KDefaultUIPlatformVersion ); |
|
2287 return CDeviceTypeInformation::KDefaultValue; |
|
2288 } |
|
2289 |
|
2290 return err; |
|
2291 } |
|
2292 |
|
2293 /** |
|
2294 Retrieves the UI platform major and minor version numbers as TUint16s. |
|
2295 |
|
2296 The retrieved values are both standard device type information attributes |
|
2297 (they are common to all device creators) as such it can be assumed that |
|
2298 values will always be retrieved. |
|
2299 |
|
2300 The UI version is provisioned by the device creator. If the device creator |
|
2301 provides invalid major and minor UI version numbers the default version |
|
2302 numbers will be supplied and KErrCorrupt will be returned. If the device |
|
2303 creator does not provide values for these attributes then default values |
|
2304 will be supplied and KDefaultValue will be returned. |
|
2305 |
|
2306 Note: The major UI version number attribute is represented by a UID of |
|
2307 0x1028635E and minor UI version number is represented by a UID of |
|
2308 0x1028635F. |
|
2309 |
|
2310 @param aMajor On return, contains the UI major version number. |
|
2311 @param aMinor On return, contains the UI minor version number. |
|
2312 @return KErrNone Successful, the provisioned value has been returned. |
|
2313 @return KDefaultValue Successful, the default value has been returned. |
|
2314 @return KErrCorrupt The provisioned attribute value is invalid. The |
|
2315 default value has been returned. |
|
2316 @return - Otherwise, one of the other system-wide error codes. |
|
2317 */ |
|
2318 EXPORT_C TInt CDeviceTypeInformation::GetUIPlatformVersion( |
|
2319 TUint16& aMajor, |
|
2320 TUint16& aMinor ) const |
|
2321 { |
|
2322 SDeviceAttributes* attr = reinterpret_cast<SDeviceAttributes*>( this->iImpl ); |
|
2323 TPtrC16 majorVersionNum( KDefaultUIPlatformVersionMajor ); |
|
2324 TPtrC16 minorVersionNum( KDefaultUIPlatformVersionMinor ); |
|
2325 |
|
2326 // If we have valid major and minor numbers use these instead of the default values. |
|
2327 // Otherwise check to see if the minor version number exists. If it does the error |
|
2328 // number associated with this should be used instead of KDefaultValue as the |
|
2329 // version number (in major/minor form) is corrupt. |
|
2330 TInt attributeNumber = FindAttributeNumber( *attr, KUIPlatformVersionMajorUid ); |
|
2331 if( KErrNotFound != attributeNumber ) |
|
2332 { |
|
2333 if( attr->Uid( attributeNumber + 1 ) == KUIPlatformVersionMinorUid.iUid ) |
|
2334 { |
|
2335 if( KErrNone == attr->Error( attributeNumber ) && KErrNone == attr->Error( attributeNumber + 1 ) ) |
|
2336 { |
|
2337 majorVersionNum.Set( attr->AttributePtr( attributeNumber ), attr->AttributeLength( attributeNumber ) ); |
|
2338 minorVersionNum.Set( attr->AttributePtr( attributeNumber + 1 ), attr->AttributeLength( attributeNumber + 1 ) ); |
|
2339 } |
|
2340 } |
|
2341 } |
|
2342 else |
|
2343 { |
|
2344 attributeNumber = FindAttributeNumber( *attr, KUIPlatformVersionMinorUid ); |
|
2345 } |
|
2346 |
|
2347 TLex16 lex( majorVersionNum ); |
|
2348 lex.Val( aMajor, EDecimal ); |
|
2349 |
|
2350 lex.Assign( minorVersionNum ); |
|
2351 lex.Val( aMinor, EDecimal ); |
|
2352 |
|
2353 return attributeNumber == KErrNotFound ? KDefaultValue : attr->Error( attributeNumber ); |
|
2354 } |
|
2355 |
|
2356 /** |
|
2357 Retrieves a reference to the Symbian OS version used in the device for |
|
2358 display, transmission or tagging purposes. The Symbian OS version has a maximum |
|
2359 length of KMaxAttributeLength UTF-16 characters. |
|
2360 |
|
2361 The string should never be used for programmatic decisions based on assumed |
|
2362 functionality present in the device as device creators can very the content of |
|
2363 the device firmware. Instead Feature Manager should be used to query the |
|
2364 functional capabilities of a device. @see CFeatureDiscovery |
|
2365 |
|
2366 This is a standard device type information attribute (it is common to all |
|
2367 devices) as such it can be assumed that an attribute value will |
|
2368 always be retrieved. |
|
2369 |
|
2370 The Symbian OS version is provisioned by the device creator. If the device |
|
2371 creator does not provide a value for this attribute then a default value |
|
2372 indicating unknown version will be supplied instead and KDefaultValue will |
|
2373 be returned. If the device creator has supplied a value and it is longer than |
|
2374 KMaxAttributeLength then the provisioned value will be truncated. In this case |
|
2375 KErrOverflow will be returned. The format of the string is device dependent. |
|
2376 |
|
2377 Note: This attribute is represented by a UID of 0x10286363. |
|
2378 |
|
2379 @param aValue On return, contains the Symbian OS version number. |
|
2380 @return KErrNone Successful, the provisioned value has been returned. |
|
2381 @return KDefaultValue Successful, the default value has been returned. |
|
2382 @return KErrOverflow The provisioned attribute value has been truncated |
|
2383 due to the provided descriptor being too small. |
|
2384 @return - Otherwise one of the other system-wide error codes. |
|
2385 */ |
|
2386 EXPORT_C TInt CDeviceTypeInformation::GetOSVersion( TPtrC16& aValue ) const |
|
2387 { |
|
2388 TInt err = GetAttribute( KOSVersionUid, aValue ); |
|
2389 if( KErrNotFound == err ) |
|
2390 { |
|
2391 aValue.Set( KDefaultOSVersion ); |
|
2392 return CDeviceTypeInformation::KDefaultValue; |
|
2393 } |
|
2394 |
|
2395 return err; |
|
2396 } |
|
2397 |
|
2398 /** |
|
2399 Retrieves the Symbian OS major and minor version numbers as TUint16s. |
|
2400 |
|
2401 The retrieved values are both standard device type information attributes |
|
2402 (they are common to all device creators) as such it can be assumed that |
|
2403 values will always be retrieved. |
|
2404 |
|
2405 The OS version is provisioned by the device creator. If the device creator |
|
2406 provides invalid major and minor UI version numbers the default version |
|
2407 numbers will be supplied and KErrCorrupt will be returned. If the device |
|
2408 creator does not provide values for these attributes then default values |
|
2409 will be supplied and KDefaultValue will be returned. |
|
2410 |
|
2411 Note: The major UI version number attribute is represented by a UID of |
|
2412 0x10286361 and minor UI version number is represented by a UID of |
|
2413 0x10286362. |
|
2414 |
|
2415 @param aMajor On return, contains the OS major version number. |
|
2416 @param aMinor On return, contains the OS minor version number. |
|
2417 @return KErrNone Successful, the provisioned value has been returned. |
|
2418 @return KDefaultValue Successful, the default value has been returned. |
|
2419 @return KErrCorrupt The provisioned attribute value is invalid. The |
|
2420 default value has been returned. |
|
2421 @return - Otherwise, one of the other system-wide error codes. |
|
2422 */ |
|
2423 EXPORT_C TInt CDeviceTypeInformation::GetOSVersion( TUint16& aMajor, |
|
2424 TUint16& aMinor ) const |
|
2425 { |
|
2426 SDeviceAttributes* attr = reinterpret_cast<SDeviceAttributes*>( this->iImpl ); |
|
2427 TPtrC16 majorVersionNum( KDefaultOSVersionMajor ); |
|
2428 TPtrC16 minorVersionNum( KDefaultOSVersionMinor ); |
|
2429 |
|
2430 // If we have valid major and minor numbers use these instead of the default values. |
|
2431 // Otherwise check to see if the minor version number exists. If it does the error |
|
2432 // number associated with this should be used instead of KDefaultValue as the |
|
2433 // version number (in major/minor form) is corrupt. |
|
2434 TInt attributeNumber = FindAttributeNumber( *attr, KOSVersionMajorUid ); |
|
2435 if( KErrNotFound != attributeNumber ) |
|
2436 { |
|
2437 if( attr->Uid( attributeNumber + 1 ) == KOSVersionMinorUid.iUid ) |
|
2438 { |
|
2439 if( KErrNone == attr->Error( attributeNumber ) && KErrNone == attr->Error( attributeNumber + 1 ) ) |
|
2440 { |
|
2441 majorVersionNum.Set( attr->AttributePtr( attributeNumber ), attr->AttributeLength( attributeNumber ) ); |
|
2442 minorVersionNum.Set( attr->AttributePtr( attributeNumber + 1 ), attr->AttributeLength( attributeNumber + 1 ) ); |
|
2443 } |
|
2444 } |
|
2445 } |
|
2446 else |
|
2447 { |
|
2448 attributeNumber = FindAttributeNumber( *attr, KOSVersionMinorUid ); |
|
2449 } |
|
2450 |
|
2451 TLex16 lex( majorVersionNum ); |
|
2452 lex.Val( aMajor, EDecimal ); |
|
2453 |
|
2454 lex.Assign( minorVersionNum ); |
|
2455 lex.Val( aMinor, EDecimal ); |
|
2456 |
|
2457 return attributeNumber == KErrNotFound ? KDefaultValue : attr->Error( attributeNumber ); |
|
2458 } |