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