📄 fat.lst
字号:
254 1 euint8 hb,lb;
255 1 euint16 offset;
ARM COMPILER V2.42, fat 27/03/06 10:45:49 PAGE 5
256 1 euint32 nextcluster=0;
257 1
258 1 switch(fs->type)
259 1 {
260 2 case FAT12:
261 2 offset = ((cluster_addr%1024)*3/2)%512;
262 2 hb = buf[offset];
263 2 if(offset == 511){
264 3 buf2=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cluster_addr)+1,IOM_MODE_READONLY);
265 3 lb = buf2[0];
266 3 part_relSect(fs->part,buf2);
267 3 }else{
268 3 lb = buf[offset + 1];
269 3 }
270 2 if(cluster_addr%2==0){
271 3 nextcluster = ( ((lb&0x0F)<<8) + (hb) );
272 3 }else{
273 3 nextcluster = ( (lb<<4) + (hb>>4) );
274 3 }
275 2 break;
276 2 case FAT16:
277 2 offset=cluster_addr%256;
278 2 nextcluster = *((euint16*)buf + offset);
279 2 break;
280 2 case FAT32:
281 2 offset=cluster_addr%128;
282 2 nextcluster = *((euint32*)buf + offset);
283 2 break;
284 2 }
285 1 return(nextcluster);
286 1 }
287 /*****************************************************************************/
288
289 /* ****************************************************************************
290 * void fat_setNextClusterAddressWBuf(FileSystem *fs,euint32 cluster_addr,euint32 next_cluster_addr,euint
-8* buf)
291 * Description: This function fills in a fat entry. The entry is cluster_addr and the
292 * data entered is next_cluster_addr. This function is also given a *buf, so it does
293 * not write the data itself, except in the case of FAT 12 cross sector data, where
294 * the second sector is handled by this function.
295 * Return value:
296 */
297 void fat_setNextClusterAddressWBuf(FileSystem *fs,euint32 cluster_addr,euint32 next_cluster_addr,euint8*
-buf)
298 {
299 1 euint16 offset;
300 1 euint8 *buf2;
301 1
302 1 switch(fs->type)
303 1 {
304 2 case FAT12:
305 2 offset = ((cluster_addr%1024)*3/2)%512;
306 2 if(offset == 511){
307 3 if(cluster_addr%2==0){
308 4 buf[offset]=next_cluster_addr&0xFF;
309 4 }else{
310 4 buf[offset]=(buf[offset]&0xF)+((next_cluster_addr<<4)&0xF0);
311 4 }
312 3 buf2=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cluster_addr)+1,IOM_MODE_READWRITE);
313 3 if(cluster_addr%2==0){
314 4 buf2[0]=(buf2[0]&0xF0)+((next_cluster_addr>>8)&0xF);
315 4 }else{
316 4 buf2[0]=(next_cluster_addr>>4)&0xFF;
317 4 }
318 3 part_relSect(fs->part,buf2);
319 3 }else{
ARM COMPILER V2.42, fat 27/03/06 10:45:49 PAGE 6
320 3 if(cluster_addr%2==0){
321 4 buf[offset]=next_cluster_addr&0xFF;
322 4 buf[offset+1]=(buf[offset+1]&0xF0)+((next_cluster_addr>>8)&0xF);
323 4 }else{
324 4 buf[offset]=(buf[offset]&0xF)+((next_cluster_addr<<4)&0xF0);
325 4 buf[offset+1]=(next_cluster_addr>>4)&0xFF;
326 4 }
327 3 }
328 2 break;
329 2 case FAT16:
330 2 offset=cluster_addr%256;
331 2 *((euint16*)buf+offset)=next_cluster_addr;
332 2 break;
333 2 case FAT32:
334 2 offset=cluster_addr%128;
335 2 *((euint32*)buf+offset)=next_cluster_addr;
336 2 break;
337 2 }
338 1 }
339 /*****************************************************************************/
340
341 /* ****************************************************************************
342 * esint16 fat_getNextClusterChain(FileSystem *fs, ClusterChain *Cache)
343 * Description: This function is to advance the clusterchain of a Cache.
344 * First, the function verifies if the Cache is valid. It could correct it if it
345 * is not, but this is not done at the time. If the cachen is valid, the next step is
346 * to see what the next cluster is, if this is the End of Clustermark, the cache is
347 * updated to know the lastcluster but will remain untouched otherwise. -1 is returned.
348 * If there are more clusters the function scans the rest of the chain until the next
349 * cluster is no longer lineair, or until it has run out of fat data (only 1 sector) is
350 * examined, namely the one fetched to check for EoC.
351 * With lineair is meant that logical cluster n+1 should be 1 more than logical cluster n
352 * at the disc level.
353 * Return value: 0 on success, or -1 when EoC.
354 */
355 esint16 fat_getNextClusterChain(FileSystem *fs, ClusterChain *Cache)
356 {
357 1 euint32 sect,lr,nlr,dc;
358 1 esint16 lin=0;
359 1 euint8 *buf;
360 1
361 1 if(Cache->DiscCluster==0)
362 1 {
363 2 return(-1);
364 2 }
365 1
366 1 sect=fat_getSectorAddressFatEntry(fs,Cache->DiscCluster);
367 1 buf=part_getSect(fs->part,sect,IOM_MODE_READONLY);
368 1 dc=fat_getNextClusterAddressWBuf(fs,Cache->DiscCluster,buf);
369 1 if(fat_isEocMarker(fs,dc))
370 1 {
371 2 Cache->LastCluster=Cache->DiscCluster;
372 2 part_relSect(fs->part,buf);
373 2 return(-1);
374 2 }
375 1
376 1 Cache->DiscCluster=dc;
377 1 Cache->LogicCluster++;
378 1
379 1 lr=Cache->DiscCluster-1;
380 1 nlr=lr+1;
381 1
382 1 while(nlr-1==lr && fat_getSectorAddressFatEntry(fs,nlr)==sect)
383 1 {
384 2 lr=nlr;
385 2 nlr=fat_getNextClusterAddressWBuf(fs,lr,buf);
ARM COMPILER V2.42, fat 27/03/06 10:45:49 PAGE 7
386 2 lin++;
387 2 }
388 1
389 1 Cache->Linear=lin-1<0?0:lin-1;
390 1
391 1 part_relSect(fs->part,buf);
392 1 return(0);
393 1 }
394 /*****************************************************************************/
395
396
397 /* ****************************************************************************
398 * esint16 fat_LogicToDiscCluster(FileSystem *fs, ClusterChain *Cache,euint32 logiccluster)
399 * Description: This function is used to follow clusterchains. When called it will convert
400 * a logical cluster, to a disc cluster, using a Cache object. All it does is call
401 * getNextClusterChain in the proper manner, and rewind clusterchains if required.
402 * It is NOT recommended to go backwards in clusterchains, since this will require
403 * scanning the entire chain every time.
404 * Return value: 0 on success and -1 on failure (meaning out of bounds).
405 */
406 esint16 fat_LogicToDiscCluster(FileSystem *fs, ClusterChain *Cache,euint32 logiccluster)
407 {
408 1 if(logiccluster<Cache->LogicCluster || Cache->DiscCluster==0){
409 2 Cache->LogicCluster=0;
410 2 Cache->DiscCluster=Cache->FirstCluster;
411 2 Cache->Linear=0;
412 2 }
413 1
414 1 if(Cache->LogicCluster==logiccluster){
415 2 return(0);
416 2 }
417 1
418 1 while(Cache->LogicCluster!=logiccluster)
419 1 {
420 2 if(Cache->Linear!=0)
421 2 {
422 3 Cache->Linear--;
423 3 Cache->LogicCluster++;
424 3 Cache->DiscCluster++;
425 3 }
426 2 else
427 2 {
428 3 if((fat_getNextClusterChain(fs,Cache))!=0){
429 4 return(-1);
430 4 }
431 3 }
432 2 }
433 1 return(0);
434 1 }
435 /*****************************************************************************/
436
437 /* ****************************************************************************
438 * eint16 fat_allocClusterChain(FileSystem *fs,ClusterChain *Cache,euint32 num_clusters)
439 * Description: This function extends a clusterchain by num_clusters. It returns the
440 * number of clusters it *failed* to allocate.
441 * Return value: 0 on success, all other values are the number of clusters it could
442 * not allocate.
443 */
444 eint16 fat_allocClusterChain(FileSystem *fs,ClusterChain *Cache,euint32 num_clusters)
445 {
446 1 euint32 cc,ncl=num_clusters,lc;
447 1 euint8 *bufa=0,*bufb=0;
448 1 euint8 overflow=0;
449 1
450 1 if(Cache->FirstCluster<=1)return(num_clusters);
451 1
ARM COMPILER V2.42, fat 27/03/06 10:45:49 PAGE 8
452 1 lc=fs_getLastCluster(fs,Cache);
453 1 cc=lc;
454 1
455 1 while(ncl > 0){
456 2 cc++;
457 2 if(cc>=fs->DataClusterCount+1){
458 3 if(overflow){
459 4 bufa=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,lc),IOM_MODE_READWRITE);
460 4 fat_setNextClusterAddressWBuf(fs,lc,fat_giveEocMarker(fs),bufa);
461 4 Cache->LastCluster=lc;
462 4 part_relSect(fs->part,bufa);
463 4 fs->FreeClusterCount-=num_clusters-ncl;
464 4 return(num_clusters-ncl);
465 4 }
466 3 cc=2;
467 3 overflow++;
468 3 }
469 2 bufa=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cc),IOM_MODE_READONLY);
470 2 if(fat_getNextClusterAddressWBuf(fs,cc,bufa)==0){
471 3 bufb=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,lc),IOM_MODE_READWRITE);
472 3 fat_setNextClusterAddressWBuf(fs,lc,cc,bufb);
473 3 part_relSect(fs->part,bufb);
474 3 ncl--;
475 3 lc=cc;
476 3 }
477 2 part_relSect(fs->part,bufa);
478 2 if(ncl==0){
479 3 bufa=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,lc),IOM_MODE_READWRITE);
480 3 fat_setNextClusterAddressWBuf(fs,lc,fat_giveEocMarker(fs),bufa);
481 3 Cache->LastCluster=lc;
482 3 part_relSect(fs->part,bufa);
483 3 }
484 2 }
485 1 if(Cache->ClusterCount)Cache->ClusterCount+=num_clusters;
486 1 return(0);
487 1 }
488
489 /* ****************************************************************************
490 * eint16 fat_unlinkClusterChain(FileSystem *fs,ClusterChain *Cache)
491 * Description: This function removes a clusterchain. Starting at FirstCluster
492 * it follows the chain until the end, resetting all values to 0.
493 * Return value: 0 on success.
494 */
495 eint16 fat_unlinkClusterChain(FileSystem *fs,ClusterChain *Cache)
496 {
497 1 euint32 c,tbd=0;
498 1
499 1 Cache->LogicCluster=0;
500 1 Cache->DiscCluster=Cache->FirstCluster;
501 1
502 1 c=0;
503 1
504 1 while(!fat_LogicToDiscCluster(fs,Cache,c++)){
505 2 if(tbd!=0){
506 3 fat_setNextClusterAddress(fs,tbd,0);
507 3 }
508 2 tbd=Cache->DiscCluster;
509 2 }
510 1 fat_setNextClusterAddress(fs,Cache->DiscCluster,0);
511 1 fs->FreeClusterCount+=c;
512 1 return(0);
513 1 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -