|
1 /* |
|
2 * Copyright (c) 2008-2010 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 the License "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: |
|
15 * This file implements Reference Install tasks for getting ComponentInfo, installation, uninstallation and activation/deactivation. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include "sifrefinstallertask.h" |
|
21 #include "sifrefbinpkgextractor.h" |
|
22 #include "usiflog.h" |
|
23 #include <usif/usiferror.h> |
|
24 |
|
25 using namespace Usif; |
|
26 |
|
27 _LIT(KRefInstPrivateDir, "c:\\private\\1028634e\\"); |
|
28 |
|
29 /** |
|
30 A set of helper functions for Reference Installer tasks. |
|
31 */ |
|
32 namespace InstallHelper |
|
33 { |
|
34 _LIT(KSifReferenceSoftwareType, "reference"); |
|
35 _LIT(KUiConfirmationQuestion, "Are you sure you want to %S component: %S, vendor: %S"); |
|
36 _LIT(KParamNameErrDesc, "Error Description"); |
|
37 _LIT(KErrFileAlreadyExists, "File already exists: "); |
|
38 _LIT(KUiConfirmationTypeInstall, "install"); |
|
39 _LIT(KUiConfirmationTypeUpgrade, "upgrade"); |
|
40 _LIT(KUiConfirmationTypeUninstall, "uninstall"); |
|
41 _LIT(KUiParserErrorDesc, "Installer encountered a problem when parsing a package file."); |
|
42 const TInt KMaxConfirmationTypeLengh = KUiConfirmationTypeUninstall.iTypeLength; |
|
43 |
|
44 // This Reference Installer uses Component Name and Vendor Name in order to |
|
45 // identify a component in the SCR database. This identification scheme doesn't provide |
|
46 // unique ids and its results depend on the current language. Hence, a real installer |
|
47 // must use the Unique Id mechanism provided by the SCR. |
|
48 void FindComponentL(RSoftwareComponentRegistry& aScr, TComponentSearchData& aCompSearchData, const CSifRefPkgParser& aParser) |
|
49 { |
|
50 DEBUG_PRINTF(_L8("InstallHelper::FindComponentL()")); |
|
51 |
|
52 // Get the index of the current language |
|
53 const TLanguage curLang = User::Language(); |
|
54 TInt langIndex = aParser.GetLanguageIndex(curLang); |
|
55 if (langIndex == KErrNotFound) |
|
56 { |
|
57 ASSERT(aParser.Languages().Count() > 0); // The parser should have already rejected packages without languages |
|
58 langIndex = 0; |
|
59 } |
|
60 |
|
61 // Data for CComponentInfo |
|
62 aCompSearchData.iName = aParser.ComponentNames()[langIndex]; |
|
63 aCompSearchData.iVersion = aParser.Version().Name(); |
|
64 aCompSearchData.iVendor = aParser.VendorNames()[langIndex]; |
|
65 aCompSearchData.iScomoState = EDeactivated; |
|
66 aCompSearchData.iInstallStatus = ENewComponent; |
|
67 aCompSearchData.iComponentId = 0; |
|
68 |
|
69 RSoftwareComponentRegistryView scrView; |
|
70 CComponentFilter* filter = CComponentFilter::NewLC(); |
|
71 filter->SetNameL(*aCompSearchData.iName); |
|
72 filter->SetVendorL(*aCompSearchData.iVendor); |
|
73 filter->SetSoftwareTypeL(KSifReferenceSoftwareType); |
|
74 |
|
75 scrView.OpenViewL(aScr, filter); |
|
76 CleanupClosePushL(scrView); |
|
77 |
|
78 // Iterate over matching components in order to determine the status of the package being processed. |
|
79 CComponentEntry* component = NULL; |
|
80 while ((component = scrView.NextComponentL()) != NULL) |
|
81 { |
|
82 const TDesC& installedVersion = component->Version(); |
|
83 const TInt cmp = RSoftwareComponentRegistry::CompareVersionsL(installedVersion, aCompSearchData.iVersion); |
|
84 if (cmp > 0) |
|
85 { |
|
86 aCompSearchData.iInstallStatus = ENewerVersionAlreadyInstalled; |
|
87 aCompSearchData.iScomoState = component->ScomoState(); |
|
88 aCompSearchData.iComponentId = component->ComponentId(); |
|
89 delete component; |
|
90 break; |
|
91 } |
|
92 else if (cmp == 0 && aCompSearchData.iInstallStatus < EAlreadyInstalled) |
|
93 { |
|
94 aCompSearchData.iInstallStatus = EAlreadyInstalled; |
|
95 aCompSearchData.iScomoState = component->ScomoState(); |
|
96 aCompSearchData.iComponentId = component->ComponentId(); |
|
97 } |
|
98 else if (cmp < 0 && aCompSearchData.iInstallStatus < EUpgrade) |
|
99 { |
|
100 aCompSearchData.iInstallStatus = EUpgrade; |
|
101 aCompSearchData.iScomoState = component->ScomoState(); |
|
102 aCompSearchData.iComponentId = component->ComponentId(); |
|
103 } |
|
104 delete component; |
|
105 } |
|
106 CleanupStack::PopAndDestroy(2, filter); |
|
107 } |
|
108 |
|
109 TBool UnregisterAndDeleteFileL(RSoftwareComponentRegistry& aScr, RSoftwareComponentRegistryFilesList& aFileList, RStsSession& aSts, TComponentId aComponentId) |
|
110 { |
|
111 DEBUG_PRINTF(_L8("InstallHelper::UnregisterAndDeleteFileL()")); |
|
112 |
|
113 // Get next file |
|
114 HBufC* file = aFileList.NextFileL(); |
|
115 if (file != NULL) |
|
116 { |
|
117 // and remove it from the file system |
|
118 CleanupStack::PushL(file); |
|
119 aSts.RemoveL(*file); |
|
120 CleanupStack::PopAndDestroy(file); |
|
121 } |
|
122 else |
|
123 { |
|
124 // Remove the component from the SCR if there are no files left |
|
125 aFileList.Close(); |
|
126 aScr.DeleteComponentL(aComponentId); |
|
127 |
|
128 // Copying complete |
|
129 return ETrue; |
|
130 } |
|
131 |
|
132 // Copying in progress |
|
133 return EFalse; |
|
134 } |
|
135 |
|
136 MInstallerUIHandler* CreateUiHandlerL(const COpaqueNamedParams* aCustomArguments, TInstallerUIHandlerFactory aUiHandlerFactory) |
|
137 { |
|
138 DEBUG_PRINTF(_L8("InstallHelper::CreateUiHandlerL()")); |
|
139 |
|
140 // Instantiate a UI handler for non-silent requests |
|
141 if (aCustomArguments != NULL) |
|
142 { |
|
143 TInt silent = EFalse; |
|
144 aCustomArguments->GetIntByNameL(_L("Silent"), silent); |
|
145 if (silent) |
|
146 { |
|
147 return NULL; |
|
148 } |
|
149 } |
|
150 |
|
151 return aUiHandlerFactory(); |
|
152 } |
|
153 |
|
154 enum TConfirmationType |
|
155 { |
|
156 EConfirmationInstall, |
|
157 EConfirmationUpgrade, |
|
158 EConfirmationUninstall |
|
159 }; |
|
160 |
|
161 void userConfirmationL(TConfirmationType aType, MInstallerUIHandler& uiHandler, const TDesC& aComponent, const TDesC& aVendor) |
|
162 { |
|
163 DEBUG_PRINTF(_L8("InstallHelper::userConfirmationL()")); |
|
164 |
|
165 const TInt maxLen = KUiConfirmationQuestion.iTypeLength + KMaxConfirmationTypeLengh + aComponent.Length() + aVendor.Length(); |
|
166 HBufC* info = HBufC::NewLC(maxLen); |
|
167 TPtr bufInfo(info->Des()); |
|
168 |
|
169 switch (aType) |
|
170 { |
|
171 case EConfirmationInstall: |
|
172 bufInfo.Format(KUiConfirmationQuestion, &KUiConfirmationTypeInstall, &aComponent, &aVendor); |
|
173 break; |
|
174 |
|
175 case EConfirmationUpgrade: |
|
176 bufInfo.Format(KUiConfirmationQuestion, &KUiConfirmationTypeUpgrade, &aComponent, &aVendor); |
|
177 break; |
|
178 |
|
179 case EConfirmationUninstall: |
|
180 bufInfo.Format(KUiConfirmationQuestion, &KUiConfirmationTypeUninstall, &aComponent, &aVendor); |
|
181 break; |
|
182 |
|
183 default: |
|
184 User::Leave(KErrArgument); |
|
185 } |
|
186 |
|
187 if (!uiHandler.ConfirmationUIHandler(*info)) |
|
188 { |
|
189 User::Leave(KErrCancel); |
|
190 } |
|
191 |
|
192 CleanupStack::PopAndDestroy(info); |
|
193 } |
|
194 } |
|
195 |
|
196 // ============================================================================================================= |
|
197 |
|
198 CSifRefGetComponentInfoTask* CSifRefGetComponentInfoTask::NewL(TTransportTaskParams& aParams) |
|
199 { |
|
200 DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::NewL()")); |
|
201 |
|
202 // Validate the arguments first. |
|
203 if ((aParams.iFileName == NULL && aParams.iFileHandle == NULL) || aParams.iComponentInfo == NULL) |
|
204 { |
|
205 User::Leave(KErrArgument); |
|
206 } |
|
207 |
|
208 CSifRefGetComponentInfoTask* self = new (ELeave) CSifRefGetComponentInfoTask(aParams); |
|
209 return self; |
|
210 } |
|
211 |
|
212 CSifRefGetComponentInfoTask::CSifRefGetComponentInfoTask(TTransportTaskParams& aParams) |
|
213 : CSifTransportTask(aParams, EFalse), iStep(EExtractEmbeddedPkgs) |
|
214 { |
|
215 } |
|
216 |
|
217 CSifRefGetComponentInfoTask::~CSifRefGetComponentInfoTask() |
|
218 { |
|
219 DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::~CSifRefGetComponentInfoTask()")); |
|
220 |
|
221 iFile.Close(); |
|
222 iFs.Close(); |
|
223 iScr.Close(); |
|
224 iSts.Close(); |
|
225 iEmbeddedComponents.Close(); |
|
226 if (iSifRequestInProgress) |
|
227 { |
|
228 iSif.CancelOperation(); |
|
229 } |
|
230 iSif.Close(); |
|
231 delete iParser; |
|
232 delete iComponentInfo; |
|
233 } |
|
234 |
|
235 TBool CSifRefGetComponentInfoTask::ExecuteImplL() |
|
236 { |
|
237 DEBUG_PRINTF2(_L8("Exiting from CSifRefGetComponentInfoTask::ExecuteImplL(), iStep = %d"), iStep); |
|
238 |
|
239 TBool done = EFalse; |
|
240 |
|
241 switch (iStep) |
|
242 { |
|
243 case EExtractEmbeddedPkgs: |
|
244 ExtractEmbeddedPkgsL(); |
|
245 ++iStep; |
|
246 break; |
|
247 |
|
248 case EParsePkgFile: |
|
249 iStep = ParsePkgFileL(); |
|
250 break; |
|
251 |
|
252 case EFindComponent: |
|
253 InstallHelper::FindComponentL(iScr, iCompSearchData, *iParser); |
|
254 ++iStep; |
|
255 break; |
|
256 |
|
257 case ECreateComponentInfoNode: |
|
258 iStep = CreateComponentInfoNodeL(); |
|
259 break; |
|
260 |
|
261 case ESetComponentInfo: |
|
262 SetComponentInfoL(); |
|
263 done = ETrue; |
|
264 break; |
|
265 |
|
266 default: |
|
267 User::Leave(KErrGeneral); |
|
268 } |
|
269 |
|
270 if (!iSifRequestInProgress) |
|
271 { |
|
272 TRequestStatus* status(RequestStatus()); |
|
273 User::RequestComplete(status, KErrNone); |
|
274 } |
|
275 |
|
276 DEBUG_PRINTF3(_L8("Exiting from CSifRefGetComponentInfoTask::ExecuteImplL(), done = %d, iStep = %d"), done, iStep); |
|
277 |
|
278 return done; |
|
279 } |
|
280 |
|
281 void CSifRefGetComponentInfoTask::ExtractEmbeddedPkgsL() |
|
282 { |
|
283 DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::ExtractEmbeddedPkgsL()")); |
|
284 |
|
285 // Start an STS transaction. The extraction of a package requires creation of temporary |
|
286 // files that must be deleted when the GetComponentInfo requiest is complete. This is why |
|
287 // we need this STS transaction here. |
|
288 iSts.CreateTransactionL(); |
|
289 |
|
290 if (FileName()) |
|
291 { |
|
292 SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileName(), KRefInstPrivateDir, iEmbeddedComponents); |
|
293 } |
|
294 else if (FileHandle()) |
|
295 { |
|
296 SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileHandle(), KRefInstPrivateDir, iEmbeddedComponents); |
|
297 } |
|
298 else |
|
299 { |
|
300 ASSERT(0); |
|
301 } |
|
302 |
|
303 // Connect to the SCR. The installer needs this session to check if a component being queried |
|
304 // is already installed and, if yes, obtain its detials. |
|
305 User::LeaveIfError(iScr.Connect()); |
|
306 } |
|
307 |
|
308 TInt CSifRefGetComponentInfoTask::ParsePkgFileL() |
|
309 { |
|
310 DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::ParsePkgFileL()")); |
|
311 |
|
312 delete iParser; |
|
313 iParser = NULL; |
|
314 |
|
315 // Check if the next component is of the type our installer supports. If yes, add it to the list of |
|
316 // the components to be processed. If not, use the SIF API to obtain its details. |
|
317 const SifRefBinPkgExtractor::CAuxNode& node = *iEmbeddedComponents[iCurrentComponent]; |
|
318 if (node.Foreign()) |
|
319 { |
|
320 // Connect to the SIF server |
|
321 iComponentInfo = CComponentInfo::NewL(); |
|
322 User::LeaveIfError(iSif.Connect()); |
|
323 |
|
324 // Our installer keeps temporary files under its private folder and therefore we have to |
|
325 // pass a file handle to the SIF API. |
|
326 User::LeaveIfError(iFs.Connect()); |
|
327 iFs.ShareProtected(); |
|
328 User::LeaveIfError(iFile.Open(iFs, node.FileNameL(), EFileShareReadersOnly)); |
|
329 |
|
330 // Submit a SIF request |
|
331 iSif.GetComponentInfo(iFile, *iComponentInfo, *RequestStatus()); |
|
332 |
|
333 iSifRequestInProgress = ETrue; |
|
334 |
|
335 return ECreateComponentInfoNode; |
|
336 } |
|
337 else |
|
338 { |
|
339 iParser = CSifRefPkgParser::NewL(node.FileNameL()); |
|
340 return EFindComponent; |
|
341 } |
|
342 } |
|
343 |
|
344 TInt CSifRefGetComponentInfoTask::CreateComponentInfoNodeL() |
|
345 { |
|
346 DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::CreateComponentInfoNodeL()")); |
|
347 |
|
348 SifRefBinPkgExtractor::CAuxNode& auxNode = *iEmbeddedComponents[iCurrentComponent]; |
|
349 |
|
350 if (iSifRequestInProgress) |
|
351 { |
|
352 iSif.Close(); |
|
353 iFile.Close(); |
|
354 iFs.Close(); |
|
355 |
|
356 iSifRequestInProgress = EFalse; |
|
357 |
|
358 // Add the root node of iComponentInfo to the tree |
|
359 User::LeaveIfError(RequestStatus()->Int()); |
|
360 auxNode.SetCompInfoL(iComponentInfo); |
|
361 iComponentInfo = NULL; |
|
362 } |
|
363 else |
|
364 { |
|
365 // This reference installer uses the KExampleFileSize const value to calculate the maximum size of the installed |
|
366 // component on a phone. This is because the reference package file carries only the list of the files to be installed |
|
367 // without the files themselves. A real installer should use the size of the files to be installed. |
|
368 const TInt KExampleFileSize = 1024; |
|
369 const TInt maxInstalledSize = iParser->Files().Count() * KExampleFileSize; |
|
370 const TBool hasExe = EFalse; |
|
371 const TBool driveSelectionRequired = EFalse; |
|
372 RPointerArray<Usif::CComponentInfo::CApplicationInfo>* applications = NULL; |
|
373 // The example capabilities below are hardcoded due to the same reason. The reference package file doesn't contain |
|
374 // user grantable capabilities but a real package file should provide them. |
|
375 TCapabilitySet userGrantableCaps(ECapabilityReadUserData, ECapabilityWriteUserData); |
|
376 |
|
377 // Create a ComponentInfo node and set it as a root node. |
|
378 CComponentInfo::CNode* compInfoNode = CComponentInfo::CNode::NewLC(InstallHelper::KSifReferenceSoftwareType, |
|
379 *iCompSearchData.iName, iCompSearchData.iVersion, *iCompSearchData.iVendor, |
|
380 iCompSearchData.iScomoState, iCompSearchData.iInstallStatus, iCompSearchData.iComponentId, |
|
381 *iCompSearchData.iName, ENotAuthenticated, userGrantableCaps, maxInstalledSize, hasExe, driveSelectionRequired, applications); |
|
382 |
|
383 auxNode.SetNodeL(compInfoNode); |
|
384 CleanupStack::Pop(compInfoNode); |
|
385 } |
|
386 |
|
387 return (++iCurrentComponent < iEmbeddedComponents.Count()) ? EParsePkgFile : ESetComponentInfo; |
|
388 } |
|
389 |
|
390 void CSifRefGetComponentInfoTask::SetComponentInfoL() |
|
391 { |
|
392 DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::SetComponentInfoL()")); |
|
393 |
|
394 // At least one node must exist, otherwise we can't reach this point. |
|
395 ASSERT (iEmbeddedComponents.Count() > 0); |
|
396 |
|
397 // Build a real tree of the nodes from iEmbeddedComponents which is a flat list |
|
398 for (TInt i=iEmbeddedComponents.Count()-1; i>=1; --i) |
|
399 { |
|
400 iEmbeddedComponents[i]->RegisterChildToParentL(); |
|
401 } |
|
402 |
|
403 // Set the tree built above as the root node of ComponentInfo(). |
|
404 iEmbeddedComponents[0]->SetAsRootNodeL(*ComponentInfo()); |
|
405 } |
|
406 |
|
407 // ============================================================================================================= |
|
408 |
|
409 CSifRefInstallTask* CSifRefInstallTask::NewL(TTransportTaskParams& aParams, TInstallerUIHandlerFactory aUiHandlerFactory) |
|
410 { |
|
411 DEBUG_PRINTF(_L8("CSifRefInstallTask::NewL()")); |
|
412 |
|
413 CSifRefInstallTask* self = new (ELeave) CSifRefInstallTask(aParams); |
|
414 CleanupStack::PushL(self); |
|
415 self->ConstructL(aUiHandlerFactory); |
|
416 CleanupStack::Pop(self); |
|
417 return self; |
|
418 } |
|
419 |
|
420 CSifRefInstallTask::CSifRefInstallTask(TTransportTaskParams& aParams) |
|
421 : CSifTransportTask(aParams, EFalse), iStep(EExtractEmbeddedPkgs) |
|
422 { |
|
423 } |
|
424 |
|
425 CSifRefInstallTask::~CSifRefInstallTask() |
|
426 { |
|
427 DEBUG_PRINTF(_L8("CSifRefInstallTask::~CSifRefInstallTask()")); |
|
428 |
|
429 iFileList.Close(); |
|
430 iFile.Close(); |
|
431 iFs.Close(); |
|
432 iScr.Close(); |
|
433 iSts.Close(); |
|
434 iEmbeddedComponents.Close(); |
|
435 if (iSifRequestInProgress) |
|
436 { |
|
437 iSif.CancelOperation(); |
|
438 } |
|
439 iSif.Close(); |
|
440 delete iParser; |
|
441 delete iUiHandler; |
|
442 delete iOpaqueArguments; |
|
443 delete iOpaqueResults; |
|
444 } |
|
445 |
|
446 void CSifRefInstallTask::ConstructL(TInstallerUIHandlerFactory aUiHandlerFactory) |
|
447 { |
|
448 if ((FileName() == NULL && FileHandle() == NULL) || |
|
449 CustomArguments() == NULL || |
|
450 CustomResults() == NULL) |
|
451 { |
|
452 User::Leave(KErrArgument); |
|
453 } |
|
454 |
|
455 iUiHandler = InstallHelper::CreateUiHandlerL(CustomArguments(), aUiHandlerFactory); |
|
456 } |
|
457 |
|
458 TBool CSifRefInstallTask::ExecuteImplL() |
|
459 { |
|
460 DEBUG_PRINTF2(_L8("Exiting from CSifRefInstallTask::ExecuteImplL(), iStep = %d"), iStep); |
|
461 |
|
462 TBool done = EFalse; |
|
463 |
|
464 switch (iStep) |
|
465 { |
|
466 case EExtractEmbeddedPkgs: |
|
467 ExtractEmbeddedPkgsL(); |
|
468 ++iStep; |
|
469 break; |
|
470 |
|
471 case EParsePkgFile: |
|
472 iStep = ParsePkgFileL(); |
|
473 break; |
|
474 |
|
475 case ELaunchForeignInstall: |
|
476 LaunchForeignInstallL(); |
|
477 ++iStep; |
|
478 break; |
|
479 |
|
480 case EFinishForeignInstall: |
|
481 FinishForeignInstallL(); |
|
482 iStep = EParsePkgFile; |
|
483 break; |
|
484 |
|
485 case EFindAndCheckComponent: |
|
486 // Next step differs for ENewComponent and EUpgrade |
|
487 iStep = FindAndCheckComponentL(); |
|
488 break; |
|
489 |
|
490 case EGetInstalledFileList: |
|
491 GetInstalledFileListL(); |
|
492 ++iStep; |
|
493 break; |
|
494 |
|
495 case EUnregisterAndDeleteFile: |
|
496 if (UnregisterAndDeleteFileL()) |
|
497 { |
|
498 ++iStep; |
|
499 } |
|
500 break; |
|
501 |
|
502 case ERegisterComponent: |
|
503 RegisterComponentL(); |
|
504 ++iStep; |
|
505 break; |
|
506 |
|
507 case ECopyFile: |
|
508 if (CopyFileL()) |
|
509 { |
|
510 ++iStep; |
|
511 } |
|
512 break; |
|
513 |
|
514 case ESetScomoState: |
|
515 iStep = SetScomoStateL(); |
|
516 break; |
|
517 |
|
518 case ECommit: |
|
519 CommitL(); |
|
520 done = ETrue; |
|
521 break; |
|
522 |
|
523 default: |
|
524 User::Leave(KErrGeneral); |
|
525 } |
|
526 |
|
527 if (!iSifRequestInProgress) |
|
528 { |
|
529 TRequestStatus* status(RequestStatus()); |
|
530 User::RequestComplete(status, KErrNone); |
|
531 } |
|
532 |
|
533 DEBUG_PRINTF3(_L8("Exiting from CSifRefInstallTask::ExecuteImplL(), done = %d, iStep = %d"), done, iStep); |
|
534 |
|
535 return done; |
|
536 } |
|
537 |
|
538 namespace |
|
539 { |
|
540 TInt AuxNodeSorter(const SifRefBinPkgExtractor::CAuxNode& aLeft, const SifRefBinPkgExtractor::CAuxNode& aRight) |
|
541 { |
|
542 const TBool l = aLeft.Foreign(); |
|
543 const TBool r = aRight.Foreign(); |
|
544 if (l == r) |
|
545 { |
|
546 return 0; |
|
547 } |
|
548 else if (!l && r) |
|
549 { |
|
550 return 1; |
|
551 } |
|
552 else |
|
553 { |
|
554 return -1; |
|
555 } |
|
556 } |
|
557 } |
|
558 |
|
559 void CSifRefInstallTask::ExtractEmbeddedPkgsL() |
|
560 { |
|
561 DEBUG_PRINTF(_L8("CSifRefInstallTask::ExtractEmbeddedPkgsL()")); |
|
562 |
|
563 // Start an STS transaction |
|
564 iSts.CreateTransactionL(); |
|
565 |
|
566 if (FileName()) |
|
567 { |
|
568 SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileName(), KRefInstPrivateDir, iEmbeddedComponents); |
|
569 } |
|
570 else if (FileHandle()) |
|
571 { |
|
572 SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileHandle(), KRefInstPrivateDir, iEmbeddedComponents); |
|
573 } |
|
574 else |
|
575 { |
|
576 ASSERT(0); |
|
577 } |
|
578 |
|
579 // Sort the list of the embedded components in order to install foreign packages first |
|
580 const TLinearOrder<SifRefBinPkgExtractor::CAuxNode> sortOrder(AuxNodeSorter); |
|
581 iEmbeddedComponents.Sort(sortOrder); |
|
582 } |
|
583 |
|
584 TInt CSifRefInstallTask::ParsePkgFileL() |
|
585 { |
|
586 DEBUG_PRINTF(_L8("CSifRefInstallTask::ParsePkgFileL()")); |
|
587 |
|
588 TInt nextStep = -1; |
|
589 TRAPD(err, nextStep = ParsePkgFileImplL()); |
|
590 if (err != KErrNone) |
|
591 { |
|
592 if (iUiHandler) |
|
593 { |
|
594 iUiHandler->ErrorDescriptionUIHandler(InstallHelper::KUiParserErrorDesc); |
|
595 } |
|
596 User::Leave(err); |
|
597 } |
|
598 |
|
599 return nextStep; |
|
600 } |
|
601 |
|
602 TInt CSifRefInstallTask::ParsePkgFileImplL() |
|
603 { |
|
604 DEBUG_PRINTF(_L8("CSifRefInstallTask::ParsePkgFileImplL()")); |
|
605 |
|
606 delete iParser; |
|
607 iParser = NULL; |
|
608 |
|
609 // Check if the next component is of the type our installer supports. If yes, add it to the list of |
|
610 // the components to be processed. If not, use the SIF API to install it. |
|
611 const SifRefBinPkgExtractor::CAuxNode& node = *iEmbeddedComponents[iCurrentComponent]; |
|
612 if (node.Foreign()) |
|
613 { |
|
614 return ELaunchForeignInstall; |
|
615 } |
|
616 else |
|
617 { |
|
618 iParser = CSifRefPkgParser::NewL(node.FileNameL()); |
|
619 return EFindAndCheckComponent; |
|
620 } |
|
621 } |
|
622 |
|
623 void CSifRefInstallTask::LaunchForeignInstallL() |
|
624 { |
|
625 DEBUG_PRINTF(_L8("CSifRefInstallTask::LaunchForeignInstallL()")); |
|
626 |
|
627 const SifRefBinPkgExtractor::CAuxNode& node = *iEmbeddedComponents[iCurrentComponent]; |
|
628 |
|
629 // Connect to the SIF server |
|
630 User::LeaveIfError(iSif.Connect()); |
|
631 |
|
632 // Our installer keeps temporary files under its private folder and therefore we have to |
|
633 // pass a file handle to the SIF API. |
|
634 User::LeaveIfError(iFs.Connect()); |
|
635 iFs.ShareProtected(); |
|
636 User::LeaveIfError(iFile.Open(iFs, node.FileNameL(), EFileShareReadersOnly)); |
|
637 |
|
638 // Submit a SIF request |
|
639 iOpaqueArguments = COpaqueNamedParams::NewL(); |
|
640 iOpaqueResults = COpaqueNamedParams::NewL(); |
|
641 iSif.Install(iFile, *iOpaqueArguments, *iOpaqueResults, *RequestStatus(), EFalse); |
|
642 |
|
643 iSifRequestInProgress = ETrue; |
|
644 } |
|
645 |
|
646 void CSifRefInstallTask::FinishForeignInstallL() |
|
647 { |
|
648 DEBUG_PRINTF(_L8("CSifRefInstallTask::FinishForeignInstallL()")); |
|
649 |
|
650 iSif.Close(); |
|
651 iFile.Close(); |
|
652 iFs.Close(); |
|
653 delete iOpaqueArguments; |
|
654 iOpaqueArguments = NULL; |
|
655 delete iOpaqueResults; |
|
656 iOpaqueResults = NULL; |
|
657 |
|
658 // Check the result of the concurrent installation |
|
659 iSifRequestInProgress = EFalse; |
|
660 User::LeaveIfError(RequestStatus()->Int()); |
|
661 |
|
662 // There must be at least one component left because we install foreign components first |
|
663 ++iCurrentComponent; |
|
664 } |
|
665 |
|
666 TInt CSifRefInstallTask::FindAndCheckComponentL() |
|
667 { |
|
668 DEBUG_PRINTF(_L8("CSifRefInstallTask::FindAndCheckComponentL()")); |
|
669 |
|
670 // Connect to the SCR and create a new transaction to continue the installation of our own type |
|
671 if (!iScrTransaction) |
|
672 { |
|
673 User::LeaveIfError(iScr.Connect()); |
|
674 iScr.CreateTransactionL(); |
|
675 iScrTransaction = ETrue; |
|
676 } |
|
677 |
|
678 // Exit code |
|
679 TInt nextStep = ERegisterComponent; |
|
680 |
|
681 // Check if already installed |
|
682 InstallHelper::FindComponentL(iScr, iCompSearchData, *iParser); |
|
683 switch (iCompSearchData.iInstallStatus) |
|
684 { |
|
685 case ENewComponent: |
|
686 // nextStep already set to ERegisterComponent |
|
687 break; |
|
688 |
|
689 case EUpgrade: |
|
690 // Uninstall the previous version |
|
691 nextStep = EGetInstalledFileList; |
|
692 break; |
|
693 |
|
694 case EAlreadyInstalled: |
|
695 User::Leave(KErrSifSameVersionAlreadyInstalled); |
|
696 break; |
|
697 |
|
698 case ENewerVersionAlreadyInstalled: |
|
699 User::Leave(KErrSifNewerVersionAlreadyInstalled); |
|
700 break; |
|
701 |
|
702 default: |
|
703 ASSERT(0); |
|
704 } |
|
705 |
|
706 // Ask the user for the confirmation |
|
707 if (iUiHandler != NULL) |
|
708 { |
|
709 userConfirmationL(iCompSearchData.iInstallStatus == ENewComponent ? InstallHelper::EConfirmationInstall : InstallHelper::EConfirmationUpgrade, *iUiHandler, *iCompSearchData.iName, *iCompSearchData.iVendor); |
|
710 } |
|
711 |
|
712 return nextStep; |
|
713 } |
|
714 |
|
715 void CSifRefInstallTask::GetInstalledFileListL() |
|
716 { |
|
717 DEBUG_PRINTF(_L8("CSifRefInstallTask::GetInstalledFileListL()")); |
|
718 |
|
719 // Get a list of files to be deleted |
|
720 iFileList.OpenListL(iScr, iCompSearchData.iComponentId); |
|
721 } |
|
722 |
|
723 TBool CSifRefInstallTask::UnregisterAndDeleteFileL() |
|
724 { |
|
725 DEBUG_PRINTF(_L8("CSifRefInstallTask::UnregisterAndDeleteFileL()")); |
|
726 |
|
727 return InstallHelper::UnregisterAndDeleteFileL(iScr, iFileList, iSts, iCompSearchData.iComponentId); |
|
728 } |
|
729 |
|
730 void CSifRefInstallTask::RegisterComponentL() |
|
731 { |
|
732 DEBUG_PRINTF(_L8("CSifRefInstallTask::RegisterComponentL()")); |
|
733 |
|
734 // Register a new component in the SCR |
|
735 RCPointerArray<CLocalizableComponentInfo> componentInfoArray; |
|
736 CleanupClosePushL(componentInfoArray); |
|
737 |
|
738 // ...for each language |
|
739 const RLanguageArray& languages = iParser->Languages(); |
|
740 const TInt langCount = languages.Count(); |
|
741 for (TInt i=0; i<langCount; ++i) |
|
742 { |
|
743 const TDesC& locName = *iParser->ComponentNames()[i]; |
|
744 const TDesC& locVendor = *iParser->VendorNames()[i]; |
|
745 CLocalizableComponentInfo* componentInfo = CLocalizableComponentInfo::NewLC(locName, locVendor, languages[i]); |
|
746 componentInfoArray.AppendL(componentInfo); |
|
747 CleanupStack::Pop(componentInfo); |
|
748 } |
|
749 iCompSearchData.iComponentId = iScr.AddComponentL(componentInfoArray, InstallHelper::KSifReferenceSoftwareType); |
|
750 |
|
751 // Set the version of a new component |
|
752 iScr.SetComponentVersionL(iCompSearchData.iComponentId, iCompSearchData.iVersion); |
|
753 |
|
754 CleanupStack::PopAndDestroy(&componentInfoArray); |
|
755 |
|
756 iCopyFileIndex = 0; |
|
757 iComponentSize = 0; |
|
758 |
|
759 // Send the id if the installed component to the client. If this is a compound package we send the id of the root component only. |
|
760 if (iEmbeddedComponents[iCurrentComponent]->Root()) |
|
761 { |
|
762 CustomResults()->AddIntL(KSifOutParam_ComponentId, iCompSearchData.iComponentId); |
|
763 } |
|
764 } |
|
765 |
|
766 namespace |
|
767 { |
|
768 TBool CheckPathExistenceL(const TDesC& filePath) |
|
769 { |
|
770 TBool exists = EFalse; |
|
771 |
|
772 RFs fs; |
|
773 User::LeaveIfError(fs.Connect()); |
|
774 CleanupClosePushL(fs); |
|
775 TEntry entry; |
|
776 TInt error = fs.Entry(filePath, entry); |
|
777 if (error == KErrNone) |
|
778 { |
|
779 exists = ETrue; |
|
780 } |
|
781 else if (error != KErrPathNotFound && error != KErrNotFound) |
|
782 { |
|
783 User::Leave(error); |
|
784 } |
|
785 |
|
786 CleanupStack::PopAndDestroy(&fs); |
|
787 |
|
788 return exists; |
|
789 } |
|
790 } |
|
791 |
|
792 TBool CSifRefInstallTask::CopyFileL() |
|
793 { |
|
794 DEBUG_PRINTF(_L8("CSifRefInstallTask::CopyFileL()")); |
|
795 |
|
796 // List of files to be copied from a package file |
|
797 const RCHBufCArray& files = iParser->Files(); |
|
798 |
|
799 // Register and copy a file if any left |
|
800 if (iCopyFileIndex < files.Count()) |
|
801 { |
|
802 // The name of the current file |
|
803 const TDesC& filePath = *files[iCopyFileIndex]; |
|
804 |
|
805 // Check if filePath already exists |
|
806 if (CheckPathExistenceL(filePath)) |
|
807 { |
|
808 // Add a custom result describing the error |
|
809 HBufC* desc = HBufC::NewLC(InstallHelper::KErrFileAlreadyExists.iTypeLength + filePath.Length()); |
|
810 TPtr bufDesc = desc->Des(); |
|
811 bufDesc.Copy(InstallHelper::KErrFileAlreadyExists); |
|
812 bufDesc.Copy(filePath); |
|
813 CustomResults()->AddStringL(InstallHelper::KParamNameErrDesc, *desc); |
|
814 CleanupStack::PopAndDestroy(desc); |
|
815 } |
|
816 |
|
817 // Register the file in the SCR |
|
818 iScr.RegisterComponentFileL(iCompSearchData.iComponentId, filePath); |
|
819 |
|
820 // Copy the current file |
|
821 RFile file; |
|
822 iSts.CreateNewL(filePath, file, TFileMode(EFileShareExclusive |EFileWrite)); |
|
823 _LIT8(KReferenceFootprint, "This file belongs to the SIF reference component.\n"); |
|
824 const TInt numLines = 100; // The operation must take a while to simulate real copying |
|
825 for (TInt i=0; i<numLines; ++i) |
|
826 { |
|
827 User::LeaveIfError(file.Write(KReferenceFootprint)); |
|
828 } |
|
829 iComponentSize += KReferenceFootprint.iTypeLength*numLines; |
|
830 file.Close(); |
|
831 |
|
832 ++iCopyFileIndex; |
|
833 } |
|
834 else |
|
835 { |
|
836 // Set the size of the component in the SCR |
|
837 iScr.SetComponentSizeL(iCompSearchData.iComponentId, iComponentSize); |
|
838 |
|
839 // Step complete, all the files have been copied |
|
840 return ETrue; |
|
841 } |
|
842 |
|
843 // Step not complete, there are still files left |
|
844 |
|
845 DEBUG_PRINTF(_L8("Exiting from CSifRefInstallTask::CopyFileL()")); |
|
846 |
|
847 return EFalse; |
|
848 } |
|
849 |
|
850 TInt CSifRefInstallTask::SetScomoStateL() |
|
851 { |
|
852 DEBUG_PRINTF(_L8("CSifRefInstallTask::SetScomoStateL()")); |
|
853 |
|
854 // Activate the newly added component |
|
855 TInt inactive = EFalse; |
|
856 if (!CustomArguments()->GetIntByNameL(_L("InstallInactive"), inactive) || !inactive) |
|
857 { |
|
858 iScr.SetScomoStateL(iCompSearchData.iComponentId, EActivated); |
|
859 } |
|
860 |
|
861 // Check if there are any components to be installed left |
|
862 return (++iCurrentComponent < iEmbeddedComponents.Count()) ? EParsePkgFile : ECommit; |
|
863 } |
|
864 |
|
865 void CSifRefInstallTask::CommitL() |
|
866 { |
|
867 DEBUG_PRINTF(_L8("CSifRefInstallTask::CommitL()")); |
|
868 |
|
869 // Commit the STS & SCR transactions |
|
870 iSts.CommitL(); |
|
871 iScr.CommitTransactionL(); |
|
872 } |
|
873 |
|
874 // ============================================================================================================= |
|
875 |
|
876 CSifRefUninstallTask* CSifRefUninstallTask::NewL(TTransportTaskParams& aParams, TInstallerUIHandlerFactory aUiHandlerFactory) |
|
877 { |
|
878 DEBUG_PRINTF(_L8("CSifRefUninstallTask::NewL()")); |
|
879 |
|
880 CSifRefUninstallTask* self = new (ELeave) CSifRefUninstallTask(aParams); |
|
881 CleanupStack::PushL(self); |
|
882 self->ConstructL(aUiHandlerFactory); |
|
883 CleanupStack::Pop(self); |
|
884 return self; |
|
885 } |
|
886 |
|
887 CSifRefUninstallTask::CSifRefUninstallTask(TTransportTaskParams& aParams) |
|
888 : CSifTransportTask(aParams), iStep(EGetFileList) |
|
889 { |
|
890 } |
|
891 |
|
892 void CSifRefUninstallTask::ConstructL(TInstallerUIHandlerFactory aUiHandlerFactory) |
|
893 { |
|
894 if (ComponentId() == NULL || CustomArguments() == NULL || CustomResults() == NULL) |
|
895 { |
|
896 User::Leave(KErrArgument); |
|
897 } |
|
898 |
|
899 iUiHandler = InstallHelper::CreateUiHandlerL(CustomArguments(), aUiHandlerFactory); |
|
900 } |
|
901 |
|
902 CSifRefUninstallTask::~CSifRefUninstallTask() |
|
903 { |
|
904 DEBUG_PRINTF(_L8("CSifRefUninstallTask::~CSifRefUninstallTask()")); |
|
905 |
|
906 // Make sure to close sub-session before the session |
|
907 iFileList.Close(); |
|
908 iScr.Close(); |
|
909 iSts.Close(); |
|
910 delete iUiHandler; |
|
911 } |
|
912 |
|
913 TBool CSifRefUninstallTask::ExecuteImplL() |
|
914 { |
|
915 DEBUG_PRINTF2(_L8("CSifRefInstallTask::ExecuteImplL(), iStep = %d"), iStep); |
|
916 |
|
917 switch (iStep) |
|
918 { |
|
919 case EGetFileList: |
|
920 GetFileListL(); |
|
921 break; |
|
922 |
|
923 case EUnregisterAndDeleteFile: |
|
924 if (!UnregisterAndDeleteFileL()) |
|
925 { |
|
926 return EFalse; |
|
927 } |
|
928 break; |
|
929 |
|
930 case ECommit: |
|
931 CommitL(); |
|
932 return ETrue; |
|
933 |
|
934 default: |
|
935 User::Leave(KErrGeneral); |
|
936 } |
|
937 |
|
938 ++iStep; |
|
939 |
|
940 DEBUG_PRINTF2(_L8("Exiting from CSifRefInstallTask::ExecuteImplL(), iStep = %d"), iStep); |
|
941 |
|
942 return EFalse; |
|
943 } |
|
944 |
|
945 void CSifRefUninstallTask::GetFileListL() |
|
946 { |
|
947 DEBUG_PRINTF(_L8("CSifRefUninstallTask::GetFileListL()")); |
|
948 |
|
949 // Connect to the SCR and start a transaction |
|
950 User::LeaveIfError(iScr.Connect()); |
|
951 iScr.CreateTransactionL(); |
|
952 |
|
953 // Ask the user for confirmation |
|
954 if (iUiHandler != NULL) |
|
955 { |
|
956 CComponentEntry* entry = CComponentEntry::NewLC(); |
|
957 if (!iScr.GetComponentL(ComponentId(), *entry)) |
|
958 { |
|
959 User::Leave(KErrNotFound); |
|
960 } |
|
961 userConfirmationL(InstallHelper::EConfirmationUninstall, *iUiHandler, entry->Name(), entry->Vendor()); |
|
962 CleanupStack::PopAndDestroy(entry); |
|
963 } |
|
964 |
|
965 // Get a list of files to be deleted |
|
966 iFileList.OpenListL(iScr, ComponentId()); |
|
967 |
|
968 // Start an STS transaction |
|
969 iSts.CreateTransactionL(); |
|
970 } |
|
971 |
|
972 TBool CSifRefUninstallTask::UnregisterAndDeleteFileL() |
|
973 { |
|
974 DEBUG_PRINTF(_L8("CSifRefUninstallTask::UnregisterAndDeleteFileL()")); |
|
975 |
|
976 return InstallHelper::UnregisterAndDeleteFileL(iScr, iFileList, iSts, ComponentId()); |
|
977 } |
|
978 |
|
979 void CSifRefUninstallTask::CommitL() |
|
980 { |
|
981 DEBUG_PRINTF(_L8("CSifRefUninstallTask::CommitL()")); |
|
982 |
|
983 // Commit the STS & SCR transactions |
|
984 iSts.CommitL(); |
|
985 iScr.CommitTransactionL(); |
|
986 } |
|
987 |
|
988 // ============================================================================================================= |
|
989 |
|
990 CSifRefActivateDeactivateTask::CSifRefActivateDeactivateTask(TTransportTaskParams& aParams, TScomoState aScomoState) |
|
991 : CSifTransportTask(aParams), iScomoState(aScomoState) |
|
992 { |
|
993 DEBUG_PRINTF(_L8("CSifRefActivateDeactivateTask::CSifRefActivateDeactivateTask()")); |
|
994 } |
|
995 |
|
996 CSifRefActivateDeactivateTask::~CSifRefActivateDeactivateTask() |
|
997 { |
|
998 DEBUG_PRINTF(_L8("CSifRefActivateDeactivateTask::~CSifRefActivateDeactivateTask()")); |
|
999 |
|
1000 iScr.Close(); |
|
1001 } |
|
1002 |
|
1003 TBool CSifRefActivateDeactivateTask::ExecuteImplL() |
|
1004 { |
|
1005 DEBUG_PRINTF(_L8("CSifRefActivateDeactivateTask::ExecuteImplL()")); |
|
1006 |
|
1007 if (ComponentId() == NULL) |
|
1008 { |
|
1009 User::Leave(KErrArgument); |
|
1010 } |
|
1011 |
|
1012 // Connect to SCR and activate/deactivate component |
|
1013 User::LeaveIfError(iScr.Connect()); |
|
1014 iScr.SetScomoStateL(ComponentId(), iScomoState); |
|
1015 |
|
1016 return ETrue; |
|
1017 } |