|
1 // Copyright (c) 1998-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 the License "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 // f32\sfat\sl_check.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include "sl_std.h" |
|
19 #include "sl_scandrv.h" |
|
20 |
|
21 const TInt KMaxBufferSize=8192; |
|
22 |
|
23 |
|
24 TBool CCheckFatTable::IsEof16Bit(TInt aCluster) const |
|
25 { |
|
26 return(aCluster>=0xFFF8 && aCluster<=0xFFFF); |
|
27 } |
|
28 |
|
29 TBool CCheckFatTable::IsEof12Bit(TInt aCluster) const |
|
30 { |
|
31 return(aCluster>=0xFF8 && aCluster<=0xFFF); |
|
32 } |
|
33 |
|
34 TInt CCheckFatTable::MaxFatIndex() const |
|
35 { |
|
36 __ASSERT_DEBUG((TUint)iMaxFatIndex>=KFatFirstSearchCluster, Fault(ECheckFatIndexZero)); |
|
37 return(iMaxFatIndex); |
|
38 } |
|
39 |
|
40 |
|
41 CCheckFatTable* CCheckFatTable::NewL(CFatMountCB* aOwner) |
|
42 // |
|
43 // Create a CCheckFatTable |
|
44 // |
|
45 { |
|
46 CCheckFatTable* fatTable; |
|
47 fatTable=new(ELeave) CCheckFatTable(aOwner); |
|
48 return(fatTable); |
|
49 } |
|
50 |
|
51 |
|
52 CCheckFatTable::CCheckFatTable(CFatMountCB* aOwner) |
|
53 // |
|
54 // Constructor |
|
55 // |
|
56 { |
|
57 iOwner=aOwner; |
|
58 } |
|
59 |
|
60 CCheckFatTable::~CCheckFatTable() |
|
61 // |
|
62 // Destructor |
|
63 // |
|
64 { |
|
65 User::Free(iCheckFat); |
|
66 } |
|
67 |
|
68 |
|
69 void CCheckFatTable::InitializeL() |
|
70 // |
|
71 // Initialize the check fat table |
|
72 // |
|
73 { |
|
74 __PRINT(_L("CCheckFatTable::InitializeL")); |
|
75 |
|
76 TInt fatSize=iOwner->FatSizeInBytes(); |
|
77 |
|
78 if(iCheckFat==NULL) |
|
79 iCheckFat=(TUint8*)User::AllocL(fatSize); |
|
80 else |
|
81 iCheckFat=(TUint8*)User::ReAllocL(iCheckFat,fatSize); |
|
82 Mem::FillZ(iCheckFat,fatSize); |
|
83 iMaxFatIndex=iOwner->UsableClusters()+1; |
|
84 if(iOwner->Is16BitFat()) |
|
85 { |
|
86 __ASSERT_ALWAYS(iMaxFatIndex>0 && iMaxFatIndex<EOF_16Bit && !IsEof16Bit(iMaxFatIndex),User::Leave(KErrCorrupt)); |
|
87 } |
|
88 else |
|
89 { |
|
90 __ASSERT_ALWAYS(iMaxFatIndex>0 && iMaxFatIndex<EOF_12Bit && !IsEof12Bit(iMaxFatIndex),User::Leave(KErrCorrupt)); |
|
91 } |
|
92 WriteMediaDescriptor(); |
|
93 |
|
94 __PRINT2(_L("fatSize=%d,iCheckFat=0x%x"),fatSize,iCheckFat); |
|
95 } |
|
96 |
|
97 |
|
98 /** |
|
99 @return ETrue if found errors in FAT |
|
100 */ |
|
101 TBool CCheckFatTable::FlushL() |
|
102 // |
|
103 // Flush iCheckFat to the media, comparing each sector to corresponding |
|
104 // sector in all fats (cf.CFixedCache::FlushL) |
|
105 // |
|
106 { |
|
107 TBool bErrFound = EFalse; |
|
108 |
|
109 __PRINT(_L("CCheckFatTable::FlushL()")); |
|
110 HBufC8* hBuf=HBufC8::New(KMaxBufferSize); |
|
111 if (hBuf==NULL) |
|
112 hBuf=HBufC8::NewL(KMaxBufferSize/4); |
|
113 CleanupStack::PushL(hBuf); |
|
114 |
|
115 TUint8* ptr=(TUint8*)hBuf->Ptr(); |
|
116 TInt maxSize=hBuf->Des().MaxSize(); |
|
117 |
|
118 TPtr8 fatBuffer(ptr,maxSize); |
|
119 TInt fatSize=iOwner->FatSizeInBytes(); |
|
120 TInt remainder=fatSize; |
|
121 TInt offset=iOwner->StartOfFatInBytes(); |
|
122 TUint8* dataPtr=iCheckFat; |
|
123 TFatDriveInterface& drive = iOwner->DriveInterface(); |
|
124 TInt fatNumber=iOwner->NumberOfFats(); |
|
125 |
|
126 while(remainder) |
|
127 { |
|
128 TInt s=Min(fatBuffer.MaxSize(),remainder); |
|
129 TInt fatCount=fatNumber; |
|
130 TInt fatPos=0; |
|
131 while(fatCount) |
|
132 { |
|
133 TInt fatOffset=offset+fatPos; |
|
134 User::LeaveIfError(drive.ReadCritical(fatOffset,s,fatBuffer)); |
|
135 TInt rem2=s; |
|
136 TInt offset2=fatOffset; |
|
137 TUint8* dataPtr2=dataPtr; |
|
138 TInt bufOffset=0; |
|
139 while(rem2) |
|
140 { |
|
141 TInt s2=Min(rem2,512); |
|
142 TInt r=Mem::Compare(dataPtr2,s2,fatBuffer.Ptr()+bufOffset,s2); |
|
143 if (r!=0) |
|
144 { |
|
145 bErrFound = ETrue; |
|
146 TPtrC8 dataBuf(dataPtr2,s2); |
|
147 User::LeaveIfError(drive.WriteCritical(offset2,dataBuf)); |
|
148 } |
|
149 rem2-=s2; |
|
150 offset2+=s2; |
|
151 dataPtr2+=s2; |
|
152 bufOffset+=s2; |
|
153 } |
|
154 --fatCount; |
|
155 fatPos+=fatSize; |
|
156 } |
|
157 offset+=s; |
|
158 dataPtr+=s; |
|
159 remainder-=s; |
|
160 } |
|
161 |
|
162 CleanupStack::PopAndDestroy(); |
|
163 |
|
164 return bErrFound; |
|
165 } |
|
166 |
|
167 void CCheckFatTable::WriteMediaDescriptor() |
|
168 // |
|
169 // Write media descriptor to first byte and 0xFF to |
|
170 // remaining bytes of first two entries |
|
171 // |
|
172 { |
|
173 __PRINT(_L("CCheckFatTable::WriteMediaDescriptor")); |
|
174 iCheckFat[0]=KBootSectorMediaDescriptor; |
|
175 iCheckFat[1]=0xFF; |
|
176 iCheckFat[2]=0xFF; |
|
177 if (iOwner->Is16BitFat()) |
|
178 iCheckFat[3]=0xFF; |
|
179 } |
|
180 |
|
181 TInt CCheckFatTable::PosInBytes(TInt aFatIndex) const |
|
182 // |
|
183 // Return number of bytes into the fat |
|
184 // |
|
185 { |
|
186 TInt fatPosInBytes; |
|
187 if (iOwner->Is16BitFat()) |
|
188 fatPosInBytes=aFatIndex<<1; |
|
189 else |
|
190 // this is used since 8-bit access will be used for reading/writing |
|
191 fatPosInBytes=(aFatIndex*3>>1); |
|
192 return(fatPosInBytes); |
|
193 } |
|
194 |
|
195 |
|
196 TInt CCheckFatTable::PosInIndex(TInt aBytePos) const |
|
197 // |
|
198 // Return index given byte position in fat |
|
199 // |
|
200 { |
|
201 if(iOwner->Is16BitFat()) |
|
202 return(aBytePos>>1); |
|
203 else |
|
204 return((aBytePos<<1)/3); |
|
205 } |
|
206 |
|
207 |
|
208 TInt CCheckFatTable::ReadL(TInt aFatIndex) const |
|
209 // |
|
210 // Read a value from the check fat |
|
211 // |
|
212 { |
|
213 __ASSERT_ALWAYS((TUint32)aFatIndex >=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex(),User::Leave(KErrCorrupt)); |
|
214 TUint clusterVal; |
|
215 if(iOwner->Is16BitFat()) |
|
216 clusterVal=*(TUint16*)(iCheckFat+PosInBytes(aFatIndex)); |
|
217 else |
|
218 { |
|
219 TUint8* pCluster=iCheckFat+PosInBytes(aFatIndex); |
|
220 clusterVal=pCluster[0]|(pCluster[1]<<8); |
|
221 TBool oddCluster=(aFatIndex)&1; |
|
222 if(oddCluster) |
|
223 clusterVal>>=4; |
|
224 clusterVal&=0xFFF; |
|
225 } |
|
226 return(clusterVal); |
|
227 } |
|
228 |
|
229 |
|
230 void CCheckFatTable::WriteL(TInt aFatIndex,TInt aValue) |
|
231 // |
|
232 // Write a value to the check fat |
|
233 // |
|
234 { |
|
235 if(iOwner->Is16BitFat()) |
|
236 __ASSERT_ALWAYS((TUint32)aFatIndex>=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex() && aValue>=0 && aValue<=0xFFFF,User::Leave(KErrCorrupt)); |
|
237 else |
|
238 __ASSERT_ALWAYS((TUint32)aFatIndex>=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex() && aValue>=0 && aValue<=0xFFF,User::Leave(KErrCorrupt)); |
|
239 TUint8* p=(TUint8*)(iCheckFat+PosInBytes(aFatIndex)); |
|
240 if (iOwner->Is16BitFat()) |
|
241 { |
|
242 *(TUint16*)p=(TUint16)aValue; |
|
243 return; |
|
244 } |
|
245 TUint8 mask=0x0F; |
|
246 TBool odd=(aFatIndex)&1; |
|
247 TUint8 fatVal; |
|
248 if(odd) |
|
249 { |
|
250 mask<<=4; |
|
251 aValue<<=4; |
|
252 fatVal=p[0]; |
|
253 fatVal&=~mask; |
|
254 fatVal|=(TUint8)(aValue&0xFF); |
|
255 p[0]=fatVal; |
|
256 p[1]=(TUint8)(aValue>>8); |
|
257 } |
|
258 else |
|
259 { |
|
260 p[0]=(TUint8)(aValue&0xFF); |
|
261 fatVal=p[1]; |
|
262 fatVal&=~mask; |
|
263 fatVal|=(TUint8)(aValue>>8); |
|
264 p[1]=fatVal; |
|
265 } |
|
266 return; |
|
267 } |
|
268 |
|
269 |
|
270 TBool CCheckFatTable::GetNextClusterL(TInt& aCluster) const |
|
271 // |
|
272 // Get the next cluster in the chain from the check fat. |
|
273 // |
|
274 { |
|
275 __PRINT(_L("CCheckFatTable::GetNextClusterL")); |
|
276 TBool ret; |
|
277 TInt nextCluster=ReadL(aCluster); |
|
278 if (iOwner->Is16BitFat()) |
|
279 ret=!IsEof16Bit(nextCluster); |
|
280 else |
|
281 ret=!IsEof12Bit(nextCluster); |
|
282 if (ret) |
|
283 aCluster=nextCluster; |
|
284 return(ret); |
|
285 } |
|
286 |
|
287 void CCheckFatTable::WriteFatEntryEofFL(TInt aCluster) |
|
288 // |
|
289 // Write EOF to aCluster |
|
290 // |
|
291 { |
|
292 __PRINT(_L("CCheckFatTable::WriteFatEntryEofF")); |
|
293 if (iOwner->Is16BitFat()) |
|
294 WriteL(aCluster,EOF_16Bit); |
|
295 else |
|
296 WriteL(aCluster,EOF_12Bit); |
|
297 } |
|
298 |
|
299 |