|
1 /* |
|
2 * Copyright (c) 2000 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Implementation of applicationmanagement components |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <bautils.h> |
|
19 #include <DRMLicenseManager.h> |
|
20 #include <pathinfo.h> |
|
21 #include <zipfilemember.h> |
|
22 #include "amdeploymentcomponentdata.h" |
|
23 #include "debug.h" |
|
24 |
|
25 _LIT8( KSisxMimeType, "x-epoc/x-sisx-app" ); |
|
26 _LIT( KTempDir, "piptemp\\" ); |
|
27 _LIT8( KPipMimeType, "application/x-pip" ); |
|
28 _LIT8( KDrmMessageMimeType, "application/vnd.oma.drm.message" ); |
|
29 _LIT8( KDrmContentMimeType, "application/vnd.oma.drm.content" ); |
|
30 _LIT8( KSisMimeType, "application/vnd.symbian.install"); |
|
31 _LIT8( KJadMIMEType, "text/vnd.sun.j2me.app-descriptor" ); |
|
32 _LIT8( KJarMIMEType, "application/java-archive" ); |
|
33 _LIT8( KJavaMIMEType, "application/java" ); |
|
34 |
|
35 using namespace NApplicationManagement; |
|
36 |
|
37 /** |
|
38 * Data class to Data access |
|
39 */ |
|
40 CDeploymentComponentData::CDeploymentComponentData() |
|
41 { |
|
42 } |
|
43 |
|
44 CDeploymentComponentData::CDeploymentComponentData(TType aType, |
|
45 const TDesC8 &aDataFile) : |
|
46 iDataFileName(aDataFile), iType(aType) |
|
47 { |
|
48 } |
|
49 |
|
50 void CDeploymentComponentData::ConstructL(const TDesC8 &aData, |
|
51 const TDesC8 &aMime) |
|
52 { |
|
53 SetDataL(aData, aMime); |
|
54 } |
|
55 |
|
56 CDeploymentComponentData &CDeploymentComponentData::operator=( |
|
57 const CDeploymentComponentData &aData ) |
|
58 { |
|
59 if( &aData != this ) |
|
60 { |
|
61 SetDataL( aData.Data(), aData.MimeType() ); |
|
62 iType = aData.iType; |
|
63 iDataFileName = aData.iDataFileName; |
|
64 } |
|
65 return *this; |
|
66 } |
|
67 |
|
68 void CDeploymentComponentData::ConstructLoadL(RReadStream &aStream) |
|
69 { |
|
70 TUint32 len(aStream.ReadUint32L() ); |
|
71 aStream.ReadL(iDataFileName, len); |
|
72 |
|
73 len = aStream.ReadUint32L(); |
|
74 aStream.ReadL(iMimeType, len); |
|
75 } |
|
76 |
|
77 CDeploymentComponentData* CDeploymentComponentData::NewL(TType aType, |
|
78 const TDesC8 &aData, const TDesC8 &aMime, const TDesC8 &aDataFile) |
|
79 { |
|
80 CDeploymentComponentData *self = CDeploymentComponentData::NewLC(aType, |
|
81 aData, aMime, aDataFile); |
|
82 CleanupStack::Pop(); |
|
83 return self; |
|
84 } |
|
85 |
|
86 CDeploymentComponentData* CDeploymentComponentData::NewLC(TType aType, |
|
87 const TDesC8 &aData, const TDesC8 &aMime, const TDesC8 &aDataFile) |
|
88 { |
|
89 CDeploymentComponentData *self = new ( ELeave ) CDeploymentComponentData( aType, aDataFile); |
|
90 CleanupStack::PushL(self) ; |
|
91 self->ConstructL(aData, aMime); |
|
92 return self; |
|
93 } |
|
94 |
|
95 CDeploymentComponentData* CDeploymentComponentData::LoadL( |
|
96 RReadStream &aBuffer) |
|
97 { |
|
98 CDeploymentComponentData *self = |
|
99 CDeploymentComponentData::LoadLC(aBuffer); |
|
100 CleanupStack::Pop(); |
|
101 return self; |
|
102 } |
|
103 |
|
104 CDeploymentComponentData* CDeploymentComponentData::LoadLC( |
|
105 RReadStream &aBuffer) |
|
106 { |
|
107 CDeploymentComponentData *self = new ( ELeave ) CDeploymentComponentData(); |
|
108 CleanupStack::PushL(self) ; |
|
109 self->ConstructLoadL(aBuffer); |
|
110 return self; |
|
111 } |
|
112 |
|
113 CDeploymentComponentData::~CDeploymentComponentData() |
|
114 { |
|
115 RDEBUG8_3("CDeploymentComponentData::~CDeploymentComponentData 0x%X - 0x%X", reinterpret_cast<TUint>(this), |
|
116 reinterpret_cast<TUint>(this)+sizeof( CDeploymentComponentData ) ); |
|
117 |
|
118 delete iData; |
|
119 iData = NULL; |
|
120 } |
|
121 |
|
122 TInt CDeploymentComponentData::DataLengthL() const |
|
123 { |
|
124 TInt ret( 0); |
|
125 if (iData == NULL) |
|
126 { |
|
127 if (iDataFileName.Length() > 0) |
|
128 { |
|
129 RFs fs; |
|
130 User::LeaveIfError(fs.Connect() ); |
|
131 CleanupClosePushL(fs); // 1 |
|
132 TEntry entry; |
|
133 TFileName fileName; |
|
134 fileName.Copy(iDataFileName); |
|
135 User::LeaveIfError(fs.Entry(fileName, entry) ); |
|
136 ret = entry.iSize; |
|
137 CleanupStack::PopAndDestroy( &fs); |
|
138 } |
|
139 } |
|
140 else |
|
141 { |
|
142 ret = iData->Length(); |
|
143 } |
|
144 return ret; |
|
145 } |
|
146 |
|
147 const TDesC8 &CDeploymentComponentData::Data() const |
|
148 { |
|
149 if (iData == NULL) |
|
150 { |
|
151 TRAPD( err, LoadDataL() ) |
|
152 ; |
|
153 if (err != KErrNone) |
|
154 { |
|
155 return KNullDesC8(); |
|
156 } |
|
157 } |
|
158 if (iData != NULL) |
|
159 { |
|
160 return *iData; |
|
161 } |
|
162 else |
|
163 { |
|
164 return KNullDesC8(); |
|
165 } |
|
166 } |
|
167 |
|
168 void CDeploymentComponentData::LoadDataL() const |
|
169 { |
|
170 |
|
171 if (iDataFileName.Length() > 0) |
|
172 { |
|
173 RFs fs; |
|
174 User::LeaveIfError(fs.Connect() ); |
|
175 CleanupClosePushL(fs); // 1 |
|
176 RFile file; |
|
177 TFileName fileName; |
|
178 fileName.Copy(iDataFileName); |
|
179 TInt err(file.Open(fs, fileName, EFileRead) ); |
|
180 if (err == KErrNone) |
|
181 { |
|
182 CleanupClosePushL(file); // 2 |
|
183 TInt fsize; |
|
184 User::LeaveIfError(file.Size(fsize) ); |
|
185 iData = HBufC8::NewL(fsize); |
|
186 TPtr8 ptr(iData->Des() ); |
|
187 User::LeaveIfError(file.Read(ptr) ); |
|
188 CleanupStack::PopAndDestroy( &file); |
|
189 } |
|
190 else |
|
191 { |
|
192 RDEBUG_3( "ERROR Leaving CDeploymentComponentData::Data - SEVERE Could not open data file '%S': %d!", |
|
193 &fileName, err ); |
|
194 User::Leave(KErrNotFound) ; |
|
195 } |
|
196 CleanupStack::PopAndDestroy( &fs); |
|
197 } |
|
198 else |
|
199 { |
|
200 RDEBUG( "ERROR Leaving CDeploymentComponentData::LoadDataL() - No file to load!" ); |
|
201 User::Leave(KErrNotFound) ; |
|
202 } |
|
203 } |
|
204 |
|
205 TUid CDeploymentComponentData::SetDataL(const TDesC8& aMimeType) |
|
206 { |
|
207 RDEBUG8_2("CDeploymentComponentData::SetDataL() aMimeType: (%S)", &aMimeType); |
|
208 |
|
209 TUid ret(TUid::Null()); |
|
210 iMimeType = aMimeType.Left(KMaxMimeLength); |
|
211 |
|
212 if (aMimeType.Length()!=NULL) |
|
213 { |
|
214 TUid ret(TUid::Null()); |
|
215 RFs fs; |
|
216 User::LeaveIfError(fs.Connect()); |
|
217 CleanupClosePushL(fs); |
|
218 CFileMan *fm = CFileMan::NewL(fs); |
|
219 CleanupStack::PushL(fm); |
|
220 TFileName oldfilepath; |
|
221 oldfilepath.Copy(iDataFileName); |
|
222 |
|
223 |
|
224 RDEBUG("App Mgmt before copy start"); |
|
225 TInt maxLength = iDataFileName.Length(); |
|
226 TChar charvaldot = '.'; |
|
227 TChar charvalslash = '\\'; |
|
228 //TFileName oldfilepath; |
|
229 TInt pos = iDataFileName.LocateReverse(charvaldot); |
|
230 |
|
231 TInt lengthDeleted = maxLength - pos; |
|
232 |
|
233 iDataFileName.Delete(pos, lengthDeleted); |
|
234 |
|
235 if (iMimeType == KSisxMimeType) |
|
236 { |
|
237 _LIT16(KExt,".sisx"); |
|
238 iExtn.Append(KExt); |
|
239 } |
|
240 if(iMimeType==KSisMimeType) |
|
241 { |
|
242 _LIT16(KExt,".sis"); |
|
243 iExtn.Append(KExt); |
|
244 } |
|
245 if(iMimeType==KPipMimeType) |
|
246 { |
|
247 _LIT16(KExt,".pip"); |
|
248 iExtn.Append(KExt); |
|
249 } |
|
250 if(iMimeType==KJadMIMEType) |
|
251 { |
|
252 _LIT16(KExt,".jad"); |
|
253 iExtn.Append(KExt); |
|
254 } |
|
255 if(iMimeType==KJarMIMEType) |
|
256 { |
|
257 _LIT16(KExt,".jar"); |
|
258 iExtn.Append(KExt); |
|
259 } |
|
260 if(iMimeType==KJavaMIMEType) |
|
261 { |
|
262 _LIT16(KExt,".jar"); |
|
263 iExtn.Append(KExt); |
|
264 } |
|
265 iDataFileName.Append(iExtn);//file name with sisx extension |
|
266 TFileName newfilepath; |
|
267 newfilepath.Copy(iDataFileName); |
|
268 User::LeaveIfError(fm->Rename(oldfilepath, newfilepath)); |
|
269 CleanupStack::PopAndDestroy(fm); |
|
270 CleanupStack::PopAndDestroy( &fs); |
|
271 //RDEBUG_2(" filename: %S", iDataFileName ); |
|
272 } |
|
273 if (IsSISInstallFile(aMimeType) ) |
|
274 { |
|
275 RFs fs; |
|
276 User::LeaveIfError(fs.Connect() ); |
|
277 CleanupClosePushL(fs); |
|
278 ret = ResolveUidL(fs); |
|
279 CleanupStack::PopAndDestroy( &fs); |
|
280 } |
|
281 RDEBUG8_2("CDeploymentComponentData::SetDataL() UID: (0x%x)", ret.iUid); |
|
282 return ret; |
|
283 } |
|
284 |
|
285 TUid CDeploymentComponentData::SetDataL(const TFileName &aData, |
|
286 const TDesC8& aMimeType) |
|
287 { |
|
288 RDEBUG_2("CDeploymentComponentData::SetDataL() TFileName: (%S)", &aData); |
|
289 |
|
290 _LIT(KNewPath, "c:\\private\\200267FB\\"); |
|
291 |
|
292 TUid ret(TUid::Null()); |
|
293 iMimeType = aMimeType.Left(KMaxMimeLength) ; |
|
294 RFs fs; |
|
295 User::LeaveIfError(fs.Connect() ); |
|
296 CleanupClosePushL(fs); |
|
297 CFileMan *fm = CFileMan::NewL(fs); |
|
298 CleanupStack::PushL(fm); |
|
299 TFileName fn; |
|
300 fn.Copy(iDataFileName); |
|
301 |
|
302 RDEBUG("App Mgmt before copy start"); |
|
303 |
|
304 |
|
305 TInt maxLength = iDataFileName.Length(); |
|
306 TChar charvaldot = '.'; |
|
307 TChar charvalslash = '\\'; |
|
308 |
|
309 TInt pos = iDataFileName.LocateReverse(charvaldot); |
|
310 |
|
311 TInt lengthDeleted = maxLength-pos; |
|
312 |
|
313 iDataFileName.Delete(pos, lengthDeleted); |
|
314 |
|
315 TInt srcpos = aData.LocateReverse(charvaldot); |
|
316 |
|
317 TBuf<15> extn(aData.Mid(srcpos)); |
|
318 |
|
319 iDataFileName.Append(extn); |
|
320 |
|
321 TFileName newfilepath; |
|
322 newfilepath.Copy(iDataFileName); |
|
323 |
|
324 User::LeaveIfError(fm->Move(aData,KNewPath())); |
|
325 |
|
326 TFileName oldfilepath(KNewPath()); |
|
327 oldfilepath.Append(aData.Mid(aData.LocateReverse(charvalslash))); |
|
328 |
|
329 User::LeaveIfError(fm->Rename(oldfilepath, newfilepath)); |
|
330 |
|
331 |
|
332 //User::LeaveIfError(fm->Copy(aData, fn) ); |
|
333 |
|
334 RDEBUG("App Mgmt before copy End"); |
|
335 |
|
336 |
|
337 if (IsSISInstallFile(aMimeType) ) |
|
338 { |
|
339 ret = ResolveUidL(fs); |
|
340 } |
|
341 |
|
342 CleanupStack::PopAndDestroy(fm); |
|
343 CleanupStack::PopAndDestroy( &fs); |
|
344 RDEBUG_2("CDeploymentComponentData::SetDataL() (%d)", ret.iUid); |
|
345 |
|
346 return ret; |
|
347 } |
|
348 |
|
349 TUid CDeploymentComponentData::SetDataL(const TDesC8 &aData, |
|
350 const TDesC8 &aMimeType) |
|
351 { |
|
352 TUid ret(TUid::Null()); |
|
353 if (iData) |
|
354 { |
|
355 delete iData; |
|
356 iData = NULL; |
|
357 } |
|
358 iData = aData.AllocL(); |
|
359 ret = SetDataL(aMimeType); |
|
360 return ret; |
|
361 } |
|
362 |
|
363 TBool CDeploymentComponentData::IsSISInstallFile(const TDesC8 &aMimeType) |
|
364 { |
|
365 TBool isSIS(EFalse); |
|
366 |
|
367 if (aMimeType == KSisxMimeType || aMimeType == KPipMimeType || aMimeType |
|
368 == KDrmMessageMimeType || aMimeType == KDrmContentMimeType || aMimeType == KSisMimeType) |
|
369 { |
|
370 isSIS = ETrue; |
|
371 } |
|
372 |
|
373 return isSIS; |
|
374 } |
|
375 |
|
376 TUid CDeploymentComponentData::ResolveUidL(RFs& aFs) |
|
377 { |
|
378 RDEBUG("CDeploymentComponentData::ResolveUidL()"); |
|
379 |
|
380 TUid ret(TUid::Null() ); |
|
381 HBufC* buf = HBufC::NewLC(KMaxFileName); |
|
382 TPtr16 ptr = buf->Des(); |
|
383 ptr.Copy(iDataFileName); |
|
384 |
|
385 // if PIP/DRM package, we need to use license manager to extract the sis file |
|
386 if (iMimeType == KPipMimeType || iMimeType == KDrmMessageMimeType |
|
387 || iMimeType == KDrmContentMimeType) |
|
388 { |
|
389 RDEBUG8_2(" -> mime: %S", &iMimeType ); |
|
390 |
|
391 RFile originalFile; |
|
392 RFile decryptedFile; |
|
393 TFileName decryptedTempFileName; |
|
394 |
|
395 RDEBUG_2(" -> opening original file: %S", &ptr ); |
|
396 // leave if can not open the original file |
|
397 User::LeaveIfError(originalFile.Open(aFs, ptr, EFileWrite) ); |
|
398 RDEBUG(" -> done"); |
|
399 |
|
400 // First construct the temp path |
|
401 User::LeaveIfError(aFs.PrivatePath(decryptedTempFileName) ); |
|
402 // set drive letter into the path |
|
403 decryptedTempFileName.Insert( 0, TParsePtrC( PathInfo::PhoneMemoryRootPath() ).Drive() ); |
|
404 // append "piptemp\\" |
|
405 decryptedTempFileName.Append(KTempDir); |
|
406 // create the folder |
|
407 aFs.MkDir(decryptedTempFileName); |
|
408 |
|
409 // Use license manager to extract files from the pip package |
|
410 CDRMLicenseManager* licenseMgr = CDRMLicenseManager::NewL(); |
|
411 CleanupStack::PushL(licenseMgr); |
|
412 // decryp from the original file into the temp file |
|
413 RDEBUG_2(" -> extracting SIS file into: %S", &decryptedTempFileName); |
|
414 User::LeaveIfError(licenseMgr->ExtractSISFileL(originalFile, |
|
415 decryptedTempFileName) ); |
|
416 RDEBUG(" -> done"); |
|
417 |
|
418 // Get the sis file name |
|
419 decryptedTempFileName.Append( *(licenseMgr->GetSISMemberL()->Name() )); |
|
420 // open temporary handle to it. |
|
421 RDEBUG_2(" -> opening decrypted file: %S", &decryptedTempFileName ); |
|
422 User::LeaveIfError(decryptedFile.Open(aFs, decryptedTempFileName, |
|
423 EFileShareAny) ); |
|
424 RDEBUG(" -> done"); |
|
425 // parse the uid from the file |
|
426 ret = ParseUidFromSisFileL(decryptedFile); |
|
427 |
|
428 // no use anymore for the decrypted file |
|
429 decryptedFile.Close(); |
|
430 // delete the temp file |
|
431 TInt err = aFs.Delete(decryptedTempFileName); |
|
432 if (err != KErrNone) |
|
433 { |
|
434 RDEBUG_2("**** ERROR, unable to delete temporary file: %S", &decryptedTempFileName ); |
|
435 } |
|
436 |
|
437 CleanupStack::PopAndDestroy(licenseMgr); |
|
438 decryptedFile.Close(); |
|
439 originalFile.Close(); |
|
440 } |
|
441 else |
|
442 if (iMimeType == KSisxMimeType || iMimeType == KSisMimeType ) |
|
443 { |
|
444 RDEBUG(" -> mime: x-epoc/x-sisx-app"); |
|
445 RFile originalFile; |
|
446 RDEBUG_2(" -> opening file: %S", &ptr ); |
|
447 User::LeaveIfError(originalFile.Open(aFs, ptr, EFileRead) ); |
|
448 RDEBUG(" -> opened ok"); |
|
449 ret = ParseUidFromSisFileL(originalFile); |
|
450 originalFile.Close(); |
|
451 } |
|
452 |
|
453 else |
|
454 { |
|
455 RDEBUG8_2( "**** ERROR - CDeploymentComponentData::ResolveUidL( ) - cannot get uid from mime type: %S", &iMimeType ); |
|
456 } |
|
457 |
|
458 CleanupStack::PopAndDestroy(buf); |
|
459 return ret; |
|
460 } |
|
461 |
|
462 void CDeploymentComponentData::SerializedFormL(RWriteStream &aBuffer) const |
|
463 { |
|
464 aBuffer.WriteUint32L(iDataFileName.Length() ); |
|
465 aBuffer.WriteL(iDataFileName); |
|
466 |
|
467 aBuffer.WriteUint32L(iMimeType.Length() ); |
|
468 aBuffer.WriteL(iMimeType); |
|
469 |
|
470 } |
|
471 |
|
472 void CDeploymentComponentData::DestroyL(RFs &aFs) const |
|
473 { |
|
474 TFileName fn; |
|
475 fn.Copy(iDataFileName); |
|
476 aFs.Delete(fn) ; |
|
477 } |
|
478 |
|
479 const TDesC8 &CDeploymentComponentData::DataFileName() const |
|
480 { |
|
481 return iDataFileName; |
|
482 } |
|
483 |
|
484 void CDeploymentComponentData::PersistL(RFs &aFs) |
|
485 { |
|
486 if (iData) |
|
487 { |
|
488 RFile file; |
|
489 TFileName aFile; |
|
490 aFile.Copy(iDataFileName) ; |
|
491 RDEBUG_3( "CDeploymentComponentData::PersistL() - Saving '%S', dataLenght %d", &aFile, (iData ? iData->Length() : 0) ); |
|
492 User::LeaveIfError(file.Replace(aFs, aFile, EFileWrite) ); |
|
493 CleanupClosePushL(file) ; |
|
494 |
|
495 file.Write( *iData) ; |
|
496 file.Flush(); |
|
497 delete iData; |
|
498 iData = NULL; |
|
499 CleanupStack::PopAndDestroy( &file) ; // file |
|
500 } |
|
501 else |
|
502 { |
|
503 RDEBUG( "CDeploymentComponentData::PersistL() - Already persisted" ); |
|
504 } |
|
505 RDEBUG( "CDeploymentComponentData::PersistL() - Done" ); |
|
506 } |
|
507 |
|
508 TInt CDeploymentComponentData::SerializedFormLength() const |
|
509 { |
|
510 return iDataFileName.Length() + (2 * 4) + iMimeType.Length(); |
|
511 } |
|
512 |
|
513 void CDeploymentComponentData::SetDataFileNameL(const TDesC8 &aNewFileName) |
|
514 { |
|
515 if (aNewFileName.Length() > 0) |
|
516 { |
|
517 RFs fs; |
|
518 User::LeaveIfError(fs.Connect() ); |
|
519 CleanupClosePushL(fs); |
|
520 TFileName newfile; |
|
521 newfile.Copy(aNewFileName); |
|
522 TFileName oldfile; |
|
523 oldfile.Copy(iDataFileName); |
|
524 User::LeaveIfError(BaflUtils::RenameFile(fs, oldfile, newfile) ); |
|
525 CleanupStack::PopAndDestroy( &fs); |
|
526 iDataFileName = aNewFileName; |
|
527 } |
|
528 else |
|
529 { |
|
530 RDEBUG( "CDeploymentComponentData::SetDataFileNameL - ERROR Cannot set empty filename!" ); |
|
531 User::Leave(KErrArgument); |
|
532 } |
|
533 } |
|
534 void CDeploymentComponentData::SetMimeTypeL(const TDesC8 &aMimeType) |
|
535 { |
|
536 iMimeType = aMimeType.Left(KMaxMimeLength) ; |
|
537 } |
|
538 void CDeploymentComponentData::ResetData(RFs &aFs) |
|
539 { |
|
540 TRAP_IGNORE(DestroyL( aFs )); |
|
541 iDataFileName = KNullDesC8(); |
|
542 delete iData; |
|
543 iData = NULL; |
|
544 } |
|
545 |
|
546 TUid CDeploymentComponentData::ParseUidFromSisFileL(RFile& aHandleToFile) |
|
547 { |
|
548 RDEBUG("CDeploymentComponentData::ParseUidFromSisFileL"); |
|
549 |
|
550 TUid appUid; |
|
551 TInt uidLen = sizeof(TInt32); |
|
552 TInt seekLen = sizeof(TInt32) + sizeof(TInt32); |
|
553 User::LeaveIfError(aHandleToFile.Seek(ESeekStart, seekLen)); |
|
554 TPckg<TInt32> uid1(appUid.iUid); |
|
555 User::LeaveIfError(aHandleToFile.Read(uid1, uidLen)); |
|
556 |
|
557 if (uid1.Length() != uidLen) |
|
558 { |
|
559 RDEBUG("**** ERROR - uid length inconsistency - underflow"); |
|
560 User::Leave(KErrUnderflow); |
|
561 } |
|
562 |
|
563 RDEBUG_2(" -> returning SIS UID: %d", appUid.iUid ); |
|
564 return appUid; |
|
565 } |
|
566 |
|
567 // End of File |