|
1 /* |
|
2 * Copyright (c) 2006-2009 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 * |
|
16 */ |
|
17 |
|
18 |
|
19 #ifdef _MSC_VER |
|
20 #pragma warning (disable: 4786) |
|
21 #endif |
|
22 |
|
23 // System Includes |
|
24 #include <openssl/sha.h> |
|
25 #include <iostream> |
|
26 |
|
27 // User Includes |
|
28 #include "is_utils.h" |
|
29 #include "errors.h" |
|
30 #include "sisfile.h" |
|
31 #include "controllerinfo.h" |
|
32 #include "hashcontainer.h" |
|
33 #include "expressionevaluator.h" |
|
34 |
|
35 // SisX Library Includes |
|
36 #include "sisfiledescription.h" |
|
37 #include "sisfiledata.h" |
|
38 #include "siscontents.h" |
|
39 #include "siscontroller.h" |
|
40 #include "sisinfo.h" |
|
41 #include "sisinstallblock.h" |
|
42 #include "sisarray.h" |
|
43 #include "sissupportedlanguages.h" |
|
44 #include "sissupportedoptions.h" |
|
45 #include "sissupportedoption.h" |
|
46 #include "sislanguage.h" |
|
47 #include "sisdataunit.h" |
|
48 #include "sisdata.h" |
|
49 #include "sisstring.h" |
|
50 |
|
51 const std::string Type2String(CSISInfo::TSISInstallationType aType) |
|
52 { |
|
53 switch (aType) |
|
54 { |
|
55 case CSISInfo::EInstInstallation : |
|
56 return "SA"; |
|
57 case CSISInfo::EInstAugmentation : |
|
58 return "SP"; |
|
59 case CSISInfo::EInstPartialUpgrade : |
|
60 return "PU"; |
|
61 case CSISInfo::EInstPreInstalledApp : |
|
62 return "PA"; |
|
63 break; |
|
64 case CSISInfo::EInstPreInstalledPatch : |
|
65 return "PP"; |
|
66 default: |
|
67 return "Invalid/Unknown Type"; |
|
68 } |
|
69 } |
|
70 |
|
71 |
|
72 SisFile::~SisFile() |
|
73 { |
|
74 } |
|
75 |
|
76 SisFile::SisFile(const std::wstring& aFilename) |
|
77 { |
|
78 iContents.Load(aFilename); |
|
79 } |
|
80 |
|
81 |
|
82 TUint32 SisFile::GetPackageUid() const |
|
83 { |
|
84 return iContents.UID1(); |
|
85 } |
|
86 |
|
87 |
|
88 const CSISPrerequisites* SisFile::GetDependencies() const |
|
89 { |
|
90 return &iContents.Controller().Prerequisites(); |
|
91 } |
|
92 |
|
93 |
|
94 const CSISProperties* SisFile::GetProperties() const |
|
95 { |
|
96 return &iContents.Controller().Properties(); |
|
97 } |
|
98 |
|
99 std::wstring SisFile::GetVendorLocalName() const |
|
100 { |
|
101 return iContents.Controller().SISInfo().VendorName(); |
|
102 } |
|
103 |
|
104 |
|
105 void SisFile::GetControllerData(const char*& aData, int& aLen) const |
|
106 { |
|
107 aData = (char*)iContents.Controller().RawBuffer(); |
|
108 aLen = iContents.Controller().RawBufferSize(); |
|
109 } |
|
110 |
|
111 const CSISController& SisFile::GetController() |
|
112 { |
|
113 return iContents.Controller(); |
|
114 } |
|
115 |
|
116 bool SisFile::GetInstallableFiles(InstallableFiles& aFiles, |
|
117 ExpressionEvaluator& aEvaluator, |
|
118 const std::wstring& aDrivePath, |
|
119 int aInstallingDrive) const |
|
120 { |
|
121 bool success = true; |
|
122 |
|
123 CSISInfo::TSISInstallationType installType = iContents.Controller().SISInfo().InstallationType(); |
|
124 int count = iContents.SisData().DataUnitCount(); |
|
125 const CSISDataUnit* dataUnit = NULL; |
|
126 |
|
127 if (installType == CSISInfo::EInstInstallation || installType == CSISInfo::EInstAugmentation || installType == CSISInfo::EInstPartialUpgrade) |
|
128 { |
|
129 dataUnit = &(iContents.DataUnit(0)); |
|
130 } |
|
131 |
|
132 // Logo |
|
133 if (!iContents.Controller().SISLogo().WasteOfSpace()) |
|
134 { |
|
135 const CSISFileDescription& fileDes = iContents.Controller().SISLogo().FileDesc(); |
|
136 |
|
137 // FT or empty target file names are not installed |
|
138 if(fileDes.Operation() != CSISFileDescription::EOpText && fileDes.Target().size() > 0) |
|
139 { |
|
140 // for PA stub sis files no file data present, |
|
141 // aFiles will be filled with only file descriptions of files, empty file data |
|
142 if (NULL != dataUnit && fileDes.Operation() != CSISFileDescription::EOpNull) |
|
143 { |
|
144 aFiles.push_back(new InstallableFile(fileDes, new CSISFileData(dataUnit->FileData(fileDes.FileIndex())), aDrivePath, aInstallingDrive)); |
|
145 } |
|
146 else |
|
147 { |
|
148 // SIS files will not be present in PA stubs |
|
149 aFiles.push_back( new InstallableFile(fileDes,aDrivePath,aInstallingDrive)); |
|
150 } |
|
151 } |
|
152 } |
|
153 |
|
154 // process main controller - data unit 0 |
|
155 const CSISInstallBlock& installBlock = iContents.Controller().InstallBlock(); |
|
156 |
|
157 ProcessInstallBlock(installBlock, aFiles, aEvaluator, aDrivePath, aInstallingDrive); |
|
158 |
|
159 return success; |
|
160 } |
|
161 |
|
162 bool SisFile::HasEmbedded() const |
|
163 { |
|
164 const CSISInstallBlock& blk = iContents.Controller().InstallBlock(); |
|
165 TControllerMap embeddedCtls; |
|
166 iContents.Controller().InstallBlock().GetEmbeddedControllers(embeddedCtls, false); |
|
167 |
|
168 return (embeddedCtls.size() != 0); |
|
169 } |
|
170 |
|
171 void SisFile::CheckValid() const |
|
172 { |
|
173 std::string error; |
|
174 |
|
175 CSISInfo::TSISInstallationType installType = iContents.Controller().SISInfo().InstallationType(); |
|
176 // Allow SA, SP, PU and PA(stub) installations only |
|
177 bool success = (installType == CSISInfo::EInstInstallation) || |
|
178 (installType == CSISInfo::EInstPreInstalledApp) || |
|
179 (installType == CSISInfo::EInstAugmentation) || |
|
180 (installType == CSISInfo::EInstPartialUpgrade); |
|
181 |
|
182 if (installType == CSISInfo::EInstPreInstalledApp) |
|
183 { |
|
184 LWARN(L"Installation of PA type SIS files may cause problems on upgrade and/or restoration. Please see the documentation for details." ); |
|
185 } |
|
186 |
|
187 if (!success) |
|
188 { |
|
189 std::string type = Type2String(installType); |
|
190 error = "Invalid package type (" + type + ")"; |
|
191 } |
|
192 bool failed = !success; |
|
193 |
|
194 |
|
195 success = iContents.Controller().SupportedOptionCount() == 0; |
|
196 if (!success) |
|
197 error += "SIS File contains user options"; |
|
198 failed = failed || !success; |
|
199 |
|
200 const CSISInstallBlock& blk = iContents.Controller().InstallBlock(); |
|
201 |
|
202 int fileCount = blk.FileCount(); |
|
203 for(int i = 0; i < fileCount; ++i) |
|
204 { |
|
205 const CSISFileDescription& fD = blk.FileDescription(i); |
|
206 const CSISFileDescription::TSISFileOperation operation = fD.Operation(); |
|
207 std::wstring target(fD.Target().GetString()); |
|
208 // |
|
209 switch( operation ) |
|
210 { |
|
211 case CSISFileDescription::EOpInstall: |
|
212 success = true; |
|
213 break; |
|
214 case CSISFileDescription::EOpRun: |
|
215 { |
|
216 const CSISFileDescription::TSISInstOption operationOptions = fD.OperationOptions(); |
|
217 if(operationOptions & CSISFileDescription::EInstFileRunOptionByMimeType) |
|
218 { |
|
219 LWARN(L"File " << target << L" contains \"Run-Using-MIME\" option that will be ignored."); |
|
220 } |
|
221 if((operationOptions & CSISFileDescription::EInstFileRunOptionInstall) \ |
|
222 && (operationOptions & CSISFileDescription::EInstFileRunOptionUninstall)) |
|
223 { |
|
224 LWARN(L"File " << target << L" contains \"RUN-BOTH\" option that will be ignored."); |
|
225 } |
|
226 else if(operationOptions & CSISFileDescription::EInstFileRunOptionInstall) |
|
227 { |
|
228 LWARN(L"File " << target << L" contains \"Run-On-Install\" option that will be ignored."); |
|
229 } |
|
230 else if(operationOptions & CSISFileDescription::EInstFileRunOptionUninstall) |
|
231 { |
|
232 LWARN(L"File " << target << L" contains \"Run-On-Uninstall\" option that will be ignored."); |
|
233 } |
|
234 if(operationOptions & CSISFileDescription::EInstFileRunOptionBeforeShutdown) |
|
235 { |
|
236 LWARN(L"File " << target << L" contains \"Run-Before-Shutdown\" option that will be ignored."); |
|
237 } |
|
238 if(operationOptions & CSISFileDescription::EInstFileRunOptionAfterInstall) |
|
239 { |
|
240 LWARN(L"File " << target << L" contains \"Run-After-Install\" option that will be ignored."); |
|
241 } |
|
242 LWARN(L"File " << target << L" contains \"File-Run\" option that will be ignored."); |
|
243 } |
|
244 success = true; |
|
245 break; |
|
246 case CSISFileDescription::EOpText: |
|
247 LWARN(L"File " << target << L" contains \"Display Text\" option that will be ignored." ); |
|
248 success = true; |
|
249 break; |
|
250 case CSISFileDescription::EOpNull: |
|
251 success = true; |
|
252 break; |
|
253 default: |
|
254 success = false; |
|
255 break; |
|
256 } |
|
257 // |
|
258 if (!success) |
|
259 { |
|
260 error += "SIS File contains install options : "+operation; |
|
261 break; |
|
262 } |
|
263 } |
|
264 failed = failed || !success; |
|
265 |
|
266 if (failed) |
|
267 { |
|
268 std::string x; |
|
269 throw InvalidSis(Ucs2ToUtf8(this->GetPackageName(),x), |
|
270 error, SIS_NOT_SUPPORTED); |
|
271 } |
|
272 } |
|
273 |
|
274 std::wstring SisFile::GetVendorName() const |
|
275 { |
|
276 return iContents.Controller().SISInfo().UniqueVendorName(); |
|
277 } |
|
278 |
|
279 std::wstring SisFile::GetPackageName() const |
|
280 { |
|
281 return iContents.Controller().SISInfo().PackageName(0); |
|
282 } |
|
283 |
|
284 TUint32 SisFile::GetIndex() const |
|
285 { |
|
286 return iContents.Controller().DataIndex(); |
|
287 } |
|
288 |
|
289 TUint32 SisFile::GetSigned() const |
|
290 { |
|
291 return true; |
|
292 } |
|
293 |
|
294 TUint32 SisFile::GetInstallType() const |
|
295 { |
|
296 return iContents.Controller().SISInfo().InstallationType(); |
|
297 } |
|
298 |
|
299 TUint32 SisFile::GetInstallFlags() const |
|
300 { |
|
301 return iContents.Controller().SISInfo().InstallationFlag(); |
|
302 } |
|
303 |
|
304 TUint32 SisFile::GetLanguage() const |
|
305 { |
|
306 return iContents.Controller().Language(0); |
|
307 } |
|
308 |
|
309 Version SisFile::GetVersion() const |
|
310 { |
|
311 const CSISVersion& v = iContents.Controller().SISInfo().SISVersion(); |
|
312 return Version(v.Major(), v.Minor(), v.Build()); |
|
313 } |
|
314 |
|
315 const Controllers SisFile::GetControllerInfo(const TUint16 aRegistryFileMajorVersion, |
|
316 const TUint16 aRegistryFileMinorVersion) const |
|
317 { |
|
318 ControllerInfo* ci = new ControllerInfo(); |
|
319 ci->SetVersion(GetVersion()); |
|
320 ci->CalculateAndSetHash(iContents.Controller(),aRegistryFileMajorVersion,aRegistryFileMinorVersion); |
|
321 ci->SetOffset(0); |
|
322 Controllers c; |
|
323 |
|
324 c.push_back(ci); |
|
325 |
|
326 // Embedded controllers |
|
327 |
|
328 TControllerMap embeddedCtls; |
|
329 iContents.Controller().InstallBlock().GetEmbeddedControllers(embeddedCtls, false); |
|
330 for (TControllerMapConstIter iter = embeddedCtls.begin(); iter != embeddedCtls.end(); ++iter) |
|
331 { |
|
332 const CSISController& ctrl = *iter->second; |
|
333 ControllerInfo* ci = new ControllerInfo(); |
|
334 |
|
335 ci->SetVersion(GetVersion()); |
|
336 ci->CalculateAndSetHash(ctrl,aRegistryFileMajorVersion,aRegistryFileMinorVersion); |
|
337 ci->SetOffset(0); |
|
338 c.push_back(ci); |
|
339 } |
|
340 |
|
341 return c; |
|
342 } |
|
343 |
|
344 |
|
345 std::vector<TInt> SisFile::GetAllInstallChainIndices() const |
|
346 { |
|
347 int signatureCount = iContents.Controller().SignatureCount(); |
|
348 |
|
349 std::vector<TInt> result; |
|
350 for(int index = 0; index < signatureCount; ++index) |
|
351 { |
|
352 result.push_back(index); |
|
353 } |
|
354 return result; |
|
355 } |
|
356 |
|
357 void SisFile::GetInstallableFiles( InstallableFiles& aFiles, |
|
358 const CSISInstallBlock& aInstallBlock, |
|
359 const std::wstring& aDrivePath, |
|
360 int aInstallingDrive) const |
|
361 { |
|
362 CSISInfo::TSISInstallationType installType = iContents.Controller().SISInfo().InstallationType(); |
|
363 const CSISDataUnit* dataUnit = NULL; |
|
364 |
|
365 if (installType == CSISInfo::EInstInstallation || installType == CSISInfo::EInstAugmentation || installType == CSISInfo::EInstPartialUpgrade) |
|
366 { |
|
367 dataUnit = &(iContents.DataUnit(0)); |
|
368 } |
|
369 |
|
370 int fileCount = aInstallBlock.FileCount(); |
|
371 |
|
372 for (int i = 0; i < fileCount; ++i) |
|
373 { |
|
374 const CSISFileDescription& fileDes = aInstallBlock.FileDescription(i); |
|
375 |
|
376 // FT or empty target file names are not installed |
|
377 if(fileDes.Operation() == CSISFileDescription::EOpText && fileDes.Target().size() == 0) |
|
378 { |
|
379 continue; |
|
380 } |
|
381 |
|
382 // for PA stub sis files no file data present, |
|
383 // aFiles will be filled with only file descriptions of files, empty file data |
|
384 if (NULL != dataUnit && fileDes.Operation() != CSISFileDescription::EOpNull) |
|
385 { |
|
386 const CSISFileData& filedataref = dataUnit->FileData(fileDes.FileIndex()); |
|
387 aFiles.push_back(new InstallableFile(fileDes, new CSISFileData(dataUnit->FileData(fileDes.FileIndex())), aDrivePath, aInstallingDrive)); |
|
388 } |
|
389 else // for stubs, no file data |
|
390 { |
|
391 aFiles.push_back(new InstallableFile(fileDes, aDrivePath, aInstallingDrive)); |
|
392 } |
|
393 } |
|
394 } |
|
395 |
|
396 void SisFile::ProcessInstallBlock(const CSISInstallBlock& aInstallBlock, |
|
397 InstallableFiles& aFiles, |
|
398 ExpressionEvaluator& aEvaluator, |
|
399 const std::wstring& aDrivePath, |
|
400 int aInstallingDrive) const |
|
401 { |
|
402 GetInstallableFiles(aFiles, aInstallBlock, aDrivePath, aInstallingDrive); |
|
403 |
|
404 const CSISArray<CSISIf, CSISFieldRoot::ESISIf>& ifs = aInstallBlock.Ifs(); |
|
405 for (int i = 0; i < ifs.size(); ++i) |
|
406 { |
|
407 const CSISIf& ifBlock = ifs[i]; |
|
408 |
|
409 if (ifBlock.WasteOfSpace()) |
|
410 { |
|
411 std::string x; |
|
412 std::string error = "corrupt SIS file"; |
|
413 throw InvalidSis(Ucs2ToUtf8(this->GetPackageName(),x), error, INVALID_SIS); |
|
414 } |
|
415 |
|
416 // Main expression |
|
417 const ExpressionResult expressionResult = aEvaluator.Evaluate( ifBlock.Expression() ); |
|
418 const bool processBlock = expressionResult.BoolValue(); |
|
419 if ( processBlock ) |
|
420 { |
|
421 ProcessInstallBlock(ifBlock.InstallBlock(), aFiles, aEvaluator, aDrivePath, aInstallingDrive); |
|
422 continue; |
|
423 } |
|
424 |
|
425 int elseCount = ifBlock.ElseIfCount(); |
|
426 for (int i = 0; i < elseCount; ++i) |
|
427 { |
|
428 const CSISElseIf& ifElseBlock = ifBlock.ElseIf(i) ; |
|
429 if ( aEvaluator.Evaluate(ifElseBlock.Expression()).BoolValue()) |
|
430 { |
|
431 ProcessInstallBlock(ifElseBlock.InstallBlock(), aFiles, aEvaluator, aDrivePath, aInstallingDrive); |
|
432 break; // Stop processing else if blocks |
|
433 } |
|
434 // Process the rest of the files |
|
435 GetInstallableFiles(aFiles, ifElseBlock.InstallBlock(), aDrivePath, aInstallingDrive); |
|
436 } |
|
437 } |
|
438 } |
|
439 |
|
440 PackageUids SisFile::GetEmbeddedPackageUids() const |
|
441 { |
|
442 // Embedded controllers |
|
443 PackageUids pkgs; |
|
444 TControllerMap embeddedCtls; |
|
445 iContents.Controller().InstallBlock().GetEmbeddedControllers(embeddedCtls, false); |
|
446 for (TControllerMapConstIter iter = embeddedCtls.begin(); iter != embeddedCtls.end(); ++iter) |
|
447 { |
|
448 const CSISController* ctrl = iter->second; |
|
449 const CSISInfo& info = ctrl->SISInfo(); |
|
450 TUint32 uid = info.UID1(); |
|
451 pkgs.push_back(uid); |
|
452 } |
|
453 return pkgs; |
|
454 } |
|
455 |
|
456 bool SisFile::IsSupportedLanguage(TUint32 aLanguage) const |
|
457 { |
|
458 bool result = false; |
|
459 int langCount = iContents.Controller().LanguageCount(); |
|
460 for (int i = 0; i < langCount; ++i) |
|
461 { |
|
462 if (iContents.Controller().Language(i) == aLanguage) |
|
463 { |
|
464 result = true; |
|
465 break; |
|
466 } |
|
467 } |
|
468 return result; |
|
469 } |
|
470 |
|
471 void SisFile::MakeSISStub(std::wstring& aFileName) |
|
472 { |
|
473 CSISContents contents = iContents; |
|
474 contents.SetStub(CSISContents::EStubPreInstalled); |
|
475 contents.WriteSIS(aFileName); |
|
476 } |
|
477 |