|
1 /* |
|
2 * Copyright (c) 2004-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 * Definition of the Swi::Sis::CParser |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include <apadef.h> |
|
21 #include "sisinstallerrors.h" |
|
22 #include "sisdataprovider.h" |
|
23 #include "sisparser.h" |
|
24 #include "siscontents.h" |
|
25 #include "swicommon.h" |
|
26 |
|
27 using namespace Swi; |
|
28 using namespace Swi::Sis; |
|
29 |
|
30 EXPORT_C /*static*/ CContents* Parser::ContentsL(MSisDataProvider& aDataProvider) |
|
31 { |
|
32 TInt32 uid1; |
|
33 TInt32 uid2; |
|
34 TInt32 uid3; |
|
35 TUint32 uidCrc; |
|
36 |
|
37 // Check Uids and header Crc |
|
38 ReadSymbianHeaderL(aDataProvider, uid1, uid2, uid3, uidCrc); |
|
39 |
|
40 // Create CContents (delegate the parsing to CContents) |
|
41 TInt64 bytesRead=0; |
|
42 CContents* ret = CContents::NewL(aDataProvider, bytesRead); |
|
43 return ret; |
|
44 } |
|
45 |
|
46 void Parser::ReadSymbianHeaderL(MSisDataProvider& aDataProvider, TInt32& aUid1, TInt32& aUid2, TInt32& aUid3, TUint32& aUidCrc) |
|
47 { |
|
48 // Parse the SISX header, that's 4*4 bytes (UID1, UID2, UID3, UID Checksum) |
|
49 TPckg<TInt32> uid1pkg(aUid1); |
|
50 TInt err = aDataProvider.Read(uid1pkg, sizeof(TInt32)); // UID1 |
|
51 if ((err != KErrNone) || (uid1pkg.Length() != sizeof(TInt32))) |
|
52 { |
|
53 User::Leave(KErrSISFieldBufferTooShort); |
|
54 } |
|
55 |
|
56 if (aUid1 != KUidSisxFile.iUid) // The first UID *must* be KUidSisxFile |
|
57 { |
|
58 |
|
59 // We could have errored out here because we |
|
60 // have a legacy SIS file, check that. |
|
61 // consume UID 2 and 3 to do the check. |
|
62 // ignore error here, we'll just leave |
|
63 // with KErrCorrupt. |
|
64 |
|
65 TPckg<TInt32> uid2pkg(aUid2); |
|
66 aDataProvider.Read(uid2pkg, sizeof(TInt32)); |
|
67 TPckg<TInt32> uid3pkg(aUid3); |
|
68 aDataProvider.Read(uid3pkg, sizeof(TInt32)); |
|
69 |
|
70 if (aUid3 == KUidLegacySisFile.iUid) |
|
71 { |
|
72 User::Leave(KErrLegacySisFile); |
|
73 } |
|
74 else |
|
75 { |
|
76 User::Leave(KErrCorrupt); |
|
77 } |
|
78 } |
|
79 |
|
80 TPckg<TInt32> uid2pkg(aUid2); |
|
81 err = aDataProvider.Read(uid2pkg, sizeof(TInt32)); // UID2 |
|
82 if ((err != KErrNone) || (uid2pkg.Length() != sizeof(TInt32))) |
|
83 { |
|
84 User::Leave(KErrSISFieldBufferTooShort); |
|
85 } |
|
86 |
|
87 TPckg<TInt32> uid3pkg(aUid3); |
|
88 err = aDataProvider.Read(uid3pkg, sizeof(TInt32)); // UID3 |
|
89 if ((err != KErrNone) || (uid3pkg.Length() != sizeof(TInt32))) |
|
90 { |
|
91 User::Leave(KErrSISFieldBufferTooShort); |
|
92 } |
|
93 |
|
94 |
|
95 TPckg<TUint32> uidcrcpkg(aUidCrc); |
|
96 err = aDataProvider.Read(uidcrcpkg, sizeof(TInt32)); // Checksum |
|
97 if ((err != KErrNone) || (uidcrcpkg.Length() != sizeof(TInt32))) |
|
98 { |
|
99 User::Leave(KErrSISFieldBufferTooShort); |
|
100 } |
|
101 |
|
102 User::LeaveIfError(Parser::CheckUidCrc(aUidCrc, uid1pkg, uid2pkg, uid3pkg)); |
|
103 } |
|
104 |
|
105 |
|
106 TInt Parser::CheckUidCrc(TUint32 aCrc, const TDesC8& aUid1, const TDesC8& aUid2, const TDesC8& aUid3) |
|
107 { |
|
108 /* _LIT8(KCrcTest, "123456789"); |
|
109 TBuf8 <12> buffer(KCrcTest); |
|
110 TUint16 tcrc=0; |
|
111 Mem::Crc(tcrc, buffer.PtrZ(), 9); |
|
112 */ |
|
113 TBuf8<12> uidBits; |
|
114 uidBits.Append(aUid1); |
|
115 uidBits.Append(aUid2); |
|
116 uidBits.Append(aUid3); |
|
117 |
|
118 TBuf8<7> evenBits; // 1 more byte for zero terminator |
|
119 TBuf8<7> oddBits; // 1 more byte for zero terminator |
|
120 evenBits.SetLength(6); |
|
121 oddBits.SetLength(6); |
|
122 |
|
123 for (TInt k = 0; k < 6; k++) |
|
124 { |
|
125 evenBits[k] = uidBits[k*2]; |
|
126 oddBits[k] = uidBits[(k*2)+1]; |
|
127 } |
|
128 |
|
129 TUint16 crcHigh(0); |
|
130 TUint16 crcLow(0); |
|
131 Mem::Crc(crcHigh, oddBits.PtrZ(), 6); |
|
132 Mem::Crc(crcLow, evenBits.PtrZ(), 6); |
|
133 TUint32 crc = (crcHigh << 16) + crcLow; |
|
134 if (aCrc != crc) |
|
135 { |
|
136 return KErrCorrupt; |
|
137 } |
|
138 return KErrNone; |
|
139 } |
|
140 |
|
141 |
|
142 EXPORT_C void Parser::CreateSisStubL(RFile& aFile, MSisDataProvider& aDataProvider) |
|
143 { |
|
144 TInt32 uid1; |
|
145 TInt32 uid2; |
|
146 TInt32 uid3; |
|
147 TUint32 uidCrc; |
|
148 |
|
149 // Read the SisX header from the data provider and write it to the file |
|
150 ReadSymbianHeaderL(aDataProvider, uid1, uid2, uid3, uidCrc); |
|
151 WriteSymbianHeaderL(aFile, uid1, uid2, uid3, uidCrc); |
|
152 |
|
153 // Write the rest of the stub (SISX format) to the file |
|
154 CContents::WriteStubFieldsL(aFile, aDataProvider); |
|
155 } |
|
156 |
|
157 void Parser::WriteSymbianHeaderL(RFile& aFile, TInt32& aUid1, TInt32& aUid2, TInt32& aUid3, TUint32& aUidCrc) |
|
158 { |
|
159 TPckg<TInt32> uid1Pckg(aUid1); |
|
160 User::LeaveIfError(aFile.Write(uid1Pckg)); |
|
161 TPckg<TInt32> uid2Pckg(aUid2); |
|
162 User::LeaveIfError(aFile.Write(uid2Pckg)); |
|
163 TPckg<TInt32> uid3Pckg(aUid3); |
|
164 User::LeaveIfError(aFile.Write(uid3Pckg)); |
|
165 TPckg<TUint32> uidCrcPckg(aUidCrc); |
|
166 User::LeaveIfError(aFile.Write(uidCrcPckg)); |
|
167 } |