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