00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "conf_explorer.h"
00046 #include "fs_com.h"
00047 #include "fat.h"
00048 #include LIB_MEM
00049 #include LIB_CTRLACCESS
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 Bool fat_select_filesystem ( U8 u8_fat_type , Bool b_MBR );
00060 Bool fat_write_MBR ( void );
00061 Bool fat_write_PBR ( Bool b_MBR );
00062 Bool fat_clean_zone ( Bool b_MBR );
00063 Bool fat_initialize_fat ( void );
00064
00065
00068 void fat_translatedate_number_to_ascii ( FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms );
00069 void fat_translate_number_to_ascii ( FS_STRING sz_ascii_number, U8 u8_size_number_ascii, U8 u8_nb_increment );
00070 void fat_translatedate_ascii_to_number ( const FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms );
00071 U16 fat_translate_ascii_to_number ( const FS_STRING sz_ascii_number, U8 u8_size_number_ascii );
00073
00076 void fat_create_long_name_entry ( FS_STRING sz_name , U8 u8_crc , U8 u8_id );
00077 U8 fat_create_short_entry_name ( FS_STRING sz_name , FS_STRING short_name , U8 nb , Bool mode );
00078 U8 fat_find_short_entry_name ( FS_STRING sz_name );
00079 Bool fat_entry_shortname_compare ( FS_STRING short_name );
00080 U8 fat_check_name ( FS_STRING sz_name );
00081 U8 fat_translate_char_shortname ( U8 character );
00082 Bool fat_alloc_entry_free ( U8 u8_nb_entry );
00083 Bool fat_garbage_collector_entry ( void );
00085
00086
00087
00088
00105 Bool fat_mount( void )
00106 {
00107 U8 u8_sector_size;
00108 U8 u8_tmp;
00109 U16 u16_tmp;
00110 U32 u32_tmp;
00111
00112
00113 fs_g_nav.u32_cluster_sel_dir = 0;
00114
00115 fat_clear_entry_info_and_ptr();
00116
00117 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM;
00118 fs_gu32_addrsector = 0;
00119
00120
00121 if( !fat_check_device() )
00122 return FALSE;
00123
00124 while( 1 )
00125 {
00126
00127 if( !fat_cache_read_sector( TRUE ))
00128 return FALSE;
00129
00130
00131 if ( (fs_g_sector[510] != FS_BR_SIGNATURE_LOW )
00132 && (fs_g_sector[511] != FS_BR_SIGNATURE_HIGH ) )
00133 {
00134 fs_g_status = FS_ERR_NO_FORMAT;
00135 return FALSE;
00136 }
00137
00138 if ( 0 == fs_gu32_addrsector )
00139 {
00140
00141
00142 #if (FS_MULTI_PARTITION == ENABLED)
00143 u16_tmp=0;
00144 #endif
00145 for( u8_tmp=0 ; u8_tmp!=4 ; u8_tmp++ )
00146 {
00147
00148 if ( ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+0] == FS_PART_BOOTABLE )||
00149 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+0] == FS_PART_NO_BOOTABLE ) )
00150 && ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT12 )||
00151 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_INF32M )||
00152 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_SUP32M )||
00153 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_SUP32M_BIS)||
00154 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT32 )||
00155 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT32_BIS )) )
00156 {
00157
00158 #if (FS_MULTI_PARTITION == ENABLED)
00159 if( u16_tmp == fs_g_nav.u8_partition )
00160 break;
00161 u16_tmp++;
00162 #else
00163 break;
00164 #endif
00165 }
00166 }
00167 if( u8_tmp != 4 )
00168 {
00169
00170 LSB0(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+8];
00171 LSB1(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+9];
00172 LSB2(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+10];
00173 LSB3(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+11];
00174 fs_gu32_addrsector *= mem_sector_size( fs_g_nav.u8_lun );
00175 continue;
00176 }
00177
00178
00179 #if (FS_MULTI_PARTITION == ENABLED)
00180
00181 if ( 0 != fs_g_nav.u8_partition )
00182 {
00183 fs_g_status = FS_ERR_NO_PART;
00184 return FALSE;
00185 }
00186 #endif
00187 }
00188
00189
00190 if ( (fs_g_sector[0] == 0xEB) &&
00191 (fs_g_sector[2] == 0x90) &&
00192 ((fs_g_sector[21] & 0xF0) == 0xF0) )
00193 {
00194 break;
00195 }
00196
00197 fs_g_status = FS_ERR_NO_PART;
00198 return FALSE;
00199 }
00200
00201 fs_g_status = FS_ERR_NO_SUPPORT_PART;
00202
00203
00204
00205 u8_sector_size = HIGH_16_BPB_BytsPerSec/2;
00206
00207
00208 fs_g_nav.u8_BPB_SecPerClus = U8_BPB_SecPerClus * u8_sector_size;
00209
00210
00211
00212 LSB( u16_tmp ) = LOW_16_BPB_FATSz16;
00213 MSB( u16_tmp ) = HIGH_16_BPB_FATSz16;
00214 if ( 0==u16_tmp )
00215 {
00216 LSB( u16_tmp ) = LOW0_32_BPB_FATSz32;
00217 MSB( u16_tmp ) = LOW1_32_BPB_FATSz32;
00218
00219 if( (0 != LOW2_32_BPB_FATSz32 )
00220 || (0 != LOW3_32_BPB_FATSz32 ) )
00221 {
00222 return FALSE;
00223 }
00224 }
00225 fs_g_nav.u16_fat_size = u16_tmp * u8_sector_size;
00226
00227
00228 if ( (0==LOW_16_BPB_TotSec16) && (0==HIGH_16_BPB_TotSec16) )
00229 {
00230 LSB0( u32_tmp ) = LOW0_32_BPB_TotSec32;
00231 LSB1( u32_tmp ) = LOW1_32_BPB_TotSec32;
00232 LSB2( u32_tmp ) = LOW2_32_BPB_TotSec32;
00233 LSB3( u32_tmp ) = LOW3_32_BPB_TotSec32;
00234 }
00235 else
00236 {
00237 LSB0( u32_tmp ) = LOW_16_BPB_TotSec16;
00238 LSB1( u32_tmp ) = HIGH_16_BPB_TotSec16;
00239 LSB2( u32_tmp ) = 0;
00240 LSB3( u32_tmp ) = 0;
00241 }
00242 u32_tmp *= u8_sector_size;
00243
00244
00245 fs_g_nav.rootdir.seg.u16_pos = FS_NB_FAT * fs_g_nav.u16_fat_size;
00246
00247
00248 LSB( u16_tmp ) = LOW_16_BPB_RootEntCnt;
00249 MSB( u16_tmp ) = HIGH_16_BPB_RootEntCnt;
00250 fs_g_nav.rootdir.seg.u16_size = ((u16_tmp * FS_SIZE_FILE_ENTRY) + ((FS_512B*u8_sector_size)-1)) / (FS_512B*u8_sector_size);
00251 fs_g_nav.rootdir.seg.u16_size *= u8_sector_size;
00252
00253
00254 LSB( u16_tmp ) = LOW_16_BPB_ResvSecCnt;
00255 MSB( u16_tmp ) = HIGH_16_BPB_ResvSecCnt;
00256
00257 fs_g_nav.u16_offset_FSInfo = (u16_tmp-LOW_16_BPB_FSInfo)*u8_sector_size;
00258 u16_tmp *= u8_sector_size;
00259
00260
00261 fs_g_nav.u32_ptr_fat = fs_gu32_addrsector + u16_tmp;
00262
00263
00264 fs_g_nav.u32_offset_data = (FS_NB_FAT * (U32)fs_g_nav.u16_fat_size) + (U32)fs_g_nav.rootdir.seg.u16_size;
00265
00266
00267 u32_tmp -= ((U32)u16_tmp + fs_g_nav.u32_offset_data);
00268
00269
00270
00271 if (!fs_g_nav.u8_BPB_SecPerClus)
00272 return FALSE;
00273 for( u8_tmp = fs_g_nav.u8_BPB_SecPerClus; u8_tmp!=1 ; u8_tmp >>= 1 )
00274 {
00275 u32_tmp >>= 1;
00276 }
00277 fs_g_nav.u32_CountofCluster = u32_tmp+2;
00278
00279
00280 if (u32_tmp < FS_FAT12_MAX_CLUSTERS)
00281 {
00282
00283 #if (FS_FAT_12 == DISABLED)
00284 return FALSE;
00285 #endif
00286 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_12;
00287 } else {
00288 if (u32_tmp < FS_FAT16_MAX_CLUSTERS)
00289 {
00290
00291 #if (FS_FAT_16 == DISABLED)
00292 return FS_NO_SUPPORT_PART;
00293 #endif
00294 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_16;
00295 } else {
00296
00297 #if (FS_FAT_32 == DISABLED)
00298 return FALSE;
00299 #endif
00300 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_32;
00301
00302
00303 LSB0( fs_g_nav.rootdir.u32_cluster ) = LOW0_32_BPB_RootClus;
00304 LSB1( fs_g_nav.rootdir.u32_cluster ) = LOW1_32_BPB_RootClus;
00305 LSB2( fs_g_nav.rootdir.u32_cluster ) = LOW2_32_BPB_RootClus;
00306 LSB3( fs_g_nav.rootdir.u32_cluster ) = LOW3_32_BPB_RootClus;
00307 }
00308 }
00309
00310 return TRUE;
00311 }
00312
00313
00314
00315 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) )
00316
00318 _MEM_TYPE_SLOW_ U32 fs_s_u32_size_partition;
00319
00340 Bool fat_format( U8 u8_fat_type )
00341 {
00342 Bool b_MBR;
00343 #if (FS_MULTI_PARTITION == ENABLED)
00344 #error NOT SUPPORTED
00345 fs_g_nav.u8_partition = 0;
00346 #endif
00347
00348
00349
00350 mem_read_capacity( fs_g_nav.u8_lun , &fs_s_u32_size_partition );
00351
00352 if( u8_fat_type & FS_FORMAT_NOMBR_FLAG )
00353 {
00354 b_MBR = FALSE;
00355 u8_fat_type &= ~FS_FORMAT_NOMBR_FLAG;
00356
00357 fs_s_u32_size_partition++;
00358 }else{
00359 b_MBR = TRUE;
00360
00361 }
00362
00363
00364 if( !fat_select_filesystem( u8_fat_type , b_MBR ))
00365 return FALSE;
00366
00367
00368 if( b_MBR )
00369 if( !fat_write_MBR())
00370 return FALSE;
00371
00372
00373 if( !fat_write_PBR( b_MBR ))
00374 return FALSE;
00375
00376
00377
00378 if( !fat_clean_zone( b_MBR ))
00379 return FALSE;
00380
00381
00382 if( !fat_initialize_fat())
00383 return FALSE;
00384
00385 return fat_cache_flush();
00386 }
00387
00388
00389
00391 typedef struct st_fs_format_table {
00392 U32 u32_disk_size;
00393 U8 u8_SecPerClusVal;
00394 } Fs_format_table;
00395
00396
00398 _CONST_TYPE_ Fs_format_table TableFAT12[] = {
00399 { 4096, 1},
00400 { 8192, 2},
00401 { 16384, 4},
00402 { 32680, 8},
00403 };
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00417 _CONST_TYPE_ Fs_format_table TableFAT16[] = {
00418 { 8400, 0},
00419 { 32680, 2},
00420 { 262144, 4},
00421 { 524288, 8},
00422 { 1048576, 16},
00423
00424 { 2097152, 32},
00425 { 4194304, 64},
00426 { 0xFFFFFFFF, 0}
00427 };
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00443 _CONST_TYPE_ Fs_format_table TableFAT32[] = {
00444 { 66600, 0},
00445 { 532480, 1},
00446 { 16777216, 8},
00447 { 33554432, 16},
00448 { 67108864, 32},
00449 { 0xFFFFFFFF, 64}
00450 };
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00467
00483 Bool fat_select_filesystem( U8 u8_fat_type , Bool b_MBR )
00484 {
00485 U8 u8_i;
00486 U8 u8_tmp = 0;
00487 U16 u16_tmp, u16_tmp2;
00488 Fs_format_table _CONST_TYPE_ *ptr_table;
00489
00490 if( (FS_FORMAT_FAT != u8_fat_type )
00491 && (FS_FORMAT_FAT32 != u8_fat_type ) )
00492 {
00493
00494 if( (((U32)512*1024*1024)/FS_512B) >= fs_s_u32_size_partition )
00495 {
00496 u8_fat_type = FS_FORMAT_FAT;
00497 } else {
00498 u8_fat_type = FS_FORMAT_FAT32;
00499 }
00500 }
00501
00502
00503 if(FS_FORMAT_FAT == u8_fat_type )
00504 {
00505 if( (((U32)2*1024*1024)/FS_512B) >= fs_s_u32_size_partition )
00506 {
00507 fs_g_status = FS_ERR_DEVICE_TOO_SMALL;
00508 return FALSE;
00509 }
00510 if( (((U32)15*1024*1024)/FS_512B) >= fs_s_u32_size_partition )
00511 {
00512
00513 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_12;
00514 u8_i = sizeof(TableFAT12);
00515 ptr_table = TableFAT12;
00516 }else{
00517
00518 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_16;
00519 u8_i = sizeof(TableFAT16);
00520 ptr_table = TableFAT16;
00521 }
00522 }
00523 else
00524 {
00525 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_32;
00526 u8_i = sizeof(TableFAT32);
00527 ptr_table = TableFAT32;
00528 }
00529 for( ; u8_i!=0 ; u8_i-- )
00530 {
00531 if( fs_s_u32_size_partition <= ptr_table->u32_disk_size )
00532 {
00533
00534 fs_g_nav.u8_BPB_SecPerClus = ptr_table->u8_SecPerClusVal;
00535 break;
00536 }
00537 ptr_table++;
00538 }
00539 if(0 == fs_g_nav.u8_BPB_SecPerClus)
00540 {
00541 fs_g_status = FS_ERR_BAD_SIZE_FAT;
00542 return FALSE;
00543 }
00544
00545
00546
00547 if( b_MBR )
00548 fs_g_nav.u32_ptr_fat = 1;
00549 else
00550 fs_g_nav.u32_ptr_fat = 0;
00551
00552 if( Is_fat12 )
00553 {
00554 fs_g_nav.u32_ptr_fat += 1;
00555
00556 fs_g_nav.u16_fat_size=1;
00557 while(1)
00558 {
00559 if( 12 < fs_g_nav.u16_fat_size)
00560 {
00561 fs_g_status = FS_ERR_BAD_SIZE_FAT;
00562 return FALSE;
00563 }
00564
00565
00566 u16_tmp = ((fs_s_u32_size_partition -1 - (fs_g_nav.u16_fat_size *2)) / fs_g_nav.u8_BPB_SecPerClus)+2;
00567 u16_tmp2 = (fs_g_nav.u16_fat_size *FS_512B *2) / 3;
00568 if( u16_tmp <= u16_tmp2 )
00569 break;
00570
00571 fs_g_nav.u16_fat_size++;
00572 }
00573 }
00574 else
00575 {
00576 if( Is_fat32 )
00577 {
00578 fs_g_nav.u32_ptr_fat += 32;
00579
00580
00581
00582
00583
00584 u8_tmp = 32;
00585
00586
00587
00588
00589 u16_tmp = (((U16)fs_g_nav.u8_BPB_SecPerClus)<<7) + 1;
00590
00591
00592 }
00593 if( Is_fat16 )
00594 {
00595 fs_g_nav.u32_ptr_fat += 1;
00596
00597
00598
00599
00600
00601
00602 u8_tmp = 33;
00603
00604
00605
00606 MSB(u16_tmp) = fs_g_nav.u8_BPB_SecPerClus;
00607 LSB(u16_tmp) = 2;
00608 }
00609
00610 fs_g_nav.u16_fat_size = (fs_s_u32_size_partition -u8_tmp +u16_tmp -1) / u16_tmp;
00611 }
00612
00613 return TRUE;
00614 }
00615
00616
00622 Bool fat_write_MBR( void )
00623 {
00624 U8 u8_i = 0;
00625
00626
00627 fs_gu32_addrsector = 0;
00628 if( !fat_cache_read_sector( FALSE ))
00629 return FALSE;
00630 fat_cache_mark_sector_as_dirty();
00631 fat_cache_clear();
00632
00633
00634 fs_g_sector[510] = FS_BR_SIGNATURE_LOW;
00635 fs_g_sector[511] = FS_BR_SIGNATURE_HIGH;
00636
00637
00638 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +0] = FS_PART_NO_BOOTABLE;
00639
00640
00641 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +2] = 2;
00642
00643
00644
00645 if( Is_fat32 )
00646 {
00647 u8_i = FS_PART_TYPE_FAT32;
00648 }
00649 if( Is_fat16 )
00650 {
00651 if( fs_s_u32_size_partition < (32L*1024*(1024/FS_512B)) )
00652 {
00653 u8_i = FS_PART_TYPE_FAT16_INF32M;
00654 }else{
00655 u8_i = FS_PART_TYPE_FAT16_SUP32M;
00656 }
00657 }
00658 if( Is_fat12 )
00659 {
00660 u8_i = FS_PART_TYPE_FAT12;
00661 }
00662
00663 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +4] = u8_i;
00664
00665
00666 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +5] = (LSB1(fs_s_u32_size_partition)<<2) + (LSB0(fs_s_u32_size_partition)>>6);
00667
00668 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +6] = (LSB1(fs_s_u32_size_partition)&0xC0) + (LSB0(fs_s_u32_size_partition)&0x3F);
00669 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +7] = LSB2(fs_s_u32_size_partition);
00670
00671
00672 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+ 8] = 0x01;
00673
00674
00675
00676
00677 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+12] = LSB0(fs_s_u32_size_partition);
00678 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+13] = LSB1(fs_s_u32_size_partition);
00679 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+14] = LSB2(fs_s_u32_size_partition);
00680 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+15] = LSB3(fs_s_u32_size_partition);
00681
00682 return TRUE;
00683 }
00684
00686 _CONST_TYPE_ U8 const_header_pbr[] = {
00687 0xEB,0,0x90,
00688 'M','S','W','I','N','4','.','1',
00689 FS_512B & 0xFF, FS_512B >>8,
00690 0,
00691 0,0,
00692 2,
00693 0,0,
00694 0,0,
00695 FS_PART_NO_REMOVE_MEDIA,
00696 0,0,
00697 0x3F,0,
00698 0,0,
00699 1
00700 };
00701 _CONST_TYPE_ U8 const_tail_pbr[] = {
00702 FS_PART_HARD_DISK,
00703 0,
00704 FS_BOOT_SIGN,
00705 0,0,0,0,
00706 'N','O',' ','N','A','M','E',' ',' ',' ',' ',
00707 'F','A','T',' ',' ',' ',' ',' ',
00708 };
00709
00710
00713 _CONST_TYPE_ U8 const_FSI_LeadSig[] = {
00714 0x52,0x52,0x61,0x41
00715 };
00716 _CONST_TYPE_ U8 const_FSI_StrucSig[] = {
00717 0x72,0x72,0x41,0x61
00718 };
00720
00721
00729 Bool fat_write_PBR( Bool b_MBR )
00730 {
00731 U16 u16_tmp;
00732
00733
00734 if( b_MBR )
00735 fs_gu32_addrsector = 1;
00736 else
00737 fs_gu32_addrsector = 0;
00738
00739 if( !fat_cache_read_sector( FALSE ))
00740 return FALSE;
00741 fat_cache_mark_sector_as_dirty();
00742 fat_cache_clear();
00743
00744
00745 memcpy_code2ram( fs_g_sector, const_header_pbr , sizeof(const_header_pbr) );
00746
00747 fs_g_sector[510] = FS_BR_SIGNATURE_LOW;
00748 fs_g_sector[511] = FS_BR_SIGNATURE_HIGH;
00749
00750
00751 fs_g_sector[13] = fs_g_nav.u8_BPB_SecPerClus;
00752
00753 fs_g_sector[26] = (LSB1(fs_s_u32_size_partition)<<2) + (LSB0(fs_s_u32_size_partition)>>6);
00754
00755
00756
00757
00758
00759
00760 if( Is_fat32 )
00761 {
00762 memcpy_code2ram( &fs_g_sector[64], const_tail_pbr, sizeof(const_tail_pbr) );
00763 }else{
00764 memcpy_code2ram( &fs_g_sector[36], const_tail_pbr, sizeof(const_tail_pbr) );
00765 }
00766
00767 u16_tmp = fs_g_nav.u16_fat_size;
00768 if( Is_fat32 )
00769 {
00770
00771 fs_g_sector[14] = 32;
00772
00773
00774 LOW0_32_BPB_FATSz32 = LSB(u16_tmp);
00775 LOW1_32_BPB_FATSz32 = MSB(u16_tmp);
00776
00777
00778
00779 fs_g_sector[44]= 2;
00780
00781 fs_g_sector[48]= 1;
00782
00783
00784
00785
00786 fs_g_sector[85]='3';
00787 fs_g_sector[86]='2';
00788
00789 fs_g_nav.u16_offset_FSInfo = (32-1);
00790 }
00791 else
00792 {
00793
00794
00795 fs_g_sector[14] = 1;
00796
00797
00798 fs_g_sector[18] = 512>>8;
00799
00800
00801 LOW_16_BPB_FATSz16 = LSB(u16_tmp);
00802 HIGH_16_BPB_FATSz16 = MSB(u16_tmp);
00803
00804 fs_g_sector[57]='1';
00805 if( Is_fat12 )
00806 {
00807 fs_g_sector[58]='2';
00808 }else{
00809 fs_g_sector[58]='6';
00810 }
00811 }
00812
00813
00814 if( ( Is_fat32 )
00815 || ((0x10000-1) <= fs_s_u32_size_partition) )
00816 {
00817
00818
00819 fs_g_sector[32] = LSB0(fs_s_u32_size_partition);
00820 fs_g_sector[33] = LSB1(fs_s_u32_size_partition);
00821 fs_g_sector[34] = LSB2(fs_s_u32_size_partition);
00822 fs_g_sector[35] = LSB3(fs_s_u32_size_partition);
00823 }
00824 else
00825 {
00826
00827 fs_g_sector[19] = LSB0(fs_s_u32_size_partition);
00828 fs_g_sector[20] = LSB1(fs_s_u32_size_partition);
00829 }
00830
00831 if( Is_fat32 )
00832 {
00833
00834 if( !fat_write_fat32_FSInfo( 0xFFFFFFFF ))
00835 return FALSE;
00836 }
00837 return TRUE;
00838 }
00840
00841 #ifdef FS_FAT_32
00852 Bool fat_write_fat32_FSInfo( U32 u32_nb_free_cluster )
00853 {
00854
00855 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat - fs_g_nav.u16_offset_FSInfo;
00856
00857 if( !fat_cache_read_sector( FALSE ))
00858 return FALSE;
00859 fat_cache_mark_sector_as_dirty();
00860 fat_cache_clear();
00861
00862
00863
00864 memcpy_code2ram( &fs_g_sector[0], const_FSI_LeadSig, sizeof(const_FSI_LeadSig) );
00865
00866
00867 memcpy_code2ram( &fs_g_sector[484], const_FSI_StrucSig, sizeof(const_FSI_StrucSig) );
00868
00869 fs_g_sector[488] = LSB0(u32_nb_free_cluster);
00870 fs_g_sector[489] = LSB1(u32_nb_free_cluster);
00871 fs_g_sector[490] = LSB2(u32_nb_free_cluster);
00872 fs_g_sector[491] = LSB3(u32_nb_free_cluster);
00873
00874 memset( &fs_g_sector[492] , 0xFF , 4 );
00875
00876
00877 fs_g_sector[510] = FS_BR_SIGNATURE_LOW;
00878 fs_g_sector[511] = FS_BR_SIGNATURE_HIGH;
00879 return TRUE;
00880 }
00881
00882
00887 U32 fat_read_fat32_FSInfo( void )
00888 {
00889 U32 u32_nb_free_cluster;
00890
00891
00892 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat - fs_g_nav.u16_offset_FSInfo;
00893 if( !fat_cache_read_sector( TRUE ))
00894 return 0xFFFFFFFF;
00895
00896
00897
00898 if( fs_g_sector[510] != FS_BR_SIGNATURE_LOW )
00899 return 0xFFFFFFFF;
00900 if( fs_g_sector[511] != FS_BR_SIGNATURE_HIGH)
00901 return 0xFFFFFFFF;
00902
00903 if( 0 != memcmp_code2ram( &fs_g_sector[0], const_FSI_LeadSig, sizeof(const_FSI_LeadSig) ))
00904 return 0xFFFFFFFF;
00905
00906
00907 if( 0 != memcmp_code2ram( &fs_g_sector[484], const_FSI_StrucSig, sizeof(const_FSI_StrucSig)) )
00908 return 0xFFFFFFFF;
00909
00910
00911
00912 LSB0(u32_nb_free_cluster) = fs_g_sector[488];
00913 LSB1(u32_nb_free_cluster) = fs_g_sector[489];
00914 LSB2(u32_nb_free_cluster) = fs_g_sector[490];
00915 LSB3(u32_nb_free_cluster) = fs_g_sector[491];
00916 return u32_nb_free_cluster;
00917 }
00918 #endif // FS_FAT_32
00919
00920
00928 Bool fat_clean_zone( Bool b_MBR )
00929 {
00930 U16 u16_nb_sector_clean, u16_i;
00931 _MEM_TYPE_SLOW_ U8 *ptr;
00932
00933
00934 if( !fat_cache_flush())
00935 return FALSE;
00936 fat_cache_clear();
00937
00938
00939
00940 if( b_MBR )
00941 {
00942 fs_gu32_addrsector = 2;
00943 }else{
00944 fs_gu32_addrsector = 1;
00945 }
00946
00947
00948 if( Is_fat32 )
00949 {
00950 fs_gu32_addrsector++;
00951
00952 u16_nb_sector_clean = fs_g_nav.u8_BPB_SecPerClus + 30;
00953 }
00954 else
00955 {
00956
00957 u16_nb_sector_clean = 32;
00958 }
00959 u16_nb_sector_clean += (fs_g_nav.u16_fat_size*2);
00960
00961
00962 for( ; u16_nb_sector_clean!=0; u16_nb_sector_clean-- )
00963 {
00964
00965
00966 if( !fat_cache_read_sector( TRUE ))
00967 return FALSE;
00968 ptr = fs_g_sector;
00969 for( u16_i=0; u16_i<FS_CACHE_SIZE; u16_i++,ptr++ )
00970 {
00971 if( 0x00 != *ptr )
00972 {
00973
00974 fat_cache_clear();
00975 fat_cache_mark_sector_as_dirty();
00976 break;
00977 }
00978 }
00979 fs_gu32_addrsector++;
00980 }
00981 return TRUE;
00982 }
00983
00984
00987 _CONST_TYPE_ U8 const_header_fat12[] = {
00988 0xF8,0xFF,0xFF
00989 };
00990 _CONST_TYPE_ U8 const_header_fat16[] = {
00991 0xF8,0xFF,0xFF,0xFF
00992 };
00993 _CONST_TYPE_ U8 const_header_fat32[] = {
00994 0xF8,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0x0F
00995 ,0xFF,0xFF,0xFF,0x0F
00996 };
00998
00999
01005 Bool fat_initialize_fat( void )
01006 {
01007
01008 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat;
01009 if( !fat_cache_read_sector( FALSE ))
01010 return FALSE;
01011 fat_cache_mark_sector_as_dirty();
01012
01013 if( Is_fat32 )
01014 {
01015 memcpy_code2ram( fs_g_sector, const_header_fat32, sizeof(const_header_fat32) );
01016 }
01017 if( Is_fat16 )
01018 {
01019 memcpy_code2ram( fs_g_sector, const_header_fat16, sizeof(const_header_fat16) );
01020 }
01021 if( Is_fat12 )
01022 {
01023 memcpy_code2ram( fs_g_sector, const_header_fat12, sizeof(const_header_fat12) );
01024 }
01025
01026
01027 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + fs_g_nav.u16_fat_size;
01028 if( !fat_cache_read_sector( FALSE ))
01029 return FALSE;
01030 fat_cache_mark_sector_as_dirty();
01031 return TRUE;
01032 }
01033
01034
01043 Bool fat_serialnumber( Bool b_action , U8 _MEM_TYPE_SLOW_ *a_u8_sn )
01044 {
01045
01046 if ( Is_fat12 || Is_fat16 )
01047 {
01048 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat-1;
01049 }
01050 else
01051 {
01052 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat-32;
01053 }
01054
01055 if( !fat_cache_read_sector( TRUE ))
01056 return FALSE;
01057
01058
01059 if( b_action == FS_SN_READ )
01060 {
01061
01062 a_u8_sn[0] = fs_g_sector[42];
01063 a_u8_sn[1] = fs_g_sector[41];
01064 a_u8_sn[2] = fs_g_sector[40];
01065 a_u8_sn[3] = fs_g_sector[39];
01066 return TRUE;
01067 }else{
01068
01069 fs_g_sector[42] = a_u8_sn[0];
01070 fs_g_sector[41] = a_u8_sn[1];
01071 fs_g_sector[40] = a_u8_sn[2];
01072 fs_g_sector[39] = a_u8_sn[3];
01073 fat_cache_mark_sector_as_dirty();
01074 return fat_cache_flush();
01075 }
01076 }
01077
01078
01087 Bool fat_entry_label( Bool b_action , FS_STRING sz_label )
01088 {
01089 PTR_CACHE ptr_entry;
01090 U8 u8_pos_name;
01091 U8 u8_char;
01092
01093 ptr_entry = fat_get_ptr_entry();
01094
01095 if( FS_LABEL_READ == b_action)
01096 {
01097 if( FS_ENTRY_END == ptr_entry[0] )
01098 {
01099 fs_g_status = FS_ERR_ENTRY_EMPTY;
01100 return FALSE;
01101 }
01102 if( FS_ATTR_VOLUME_ID != ptr_entry[11])
01103 {
01104 fs_g_status = FS_ERR_ENTRY_BAD;
01105 return FALSE;
01106 }
01107 if( NULL == sz_label )
01108 return TRUE;
01109 for( u8_pos_name=0; u8_pos_name<11; u8_pos_name++ )
01110 {
01111 u8_char = *ptr_entry;
01112 if( 0x20 == u8_char )
01113 u8_char = 0;
01114 *sz_label = u8_char;
01115 if( 0 == u8_char )
01116 return TRUE;
01117 ptr_entry++;
01118 sz_label++;
01119 }
01120 *sz_label = 0;
01121 return TRUE;
01122 }
01123
01124 if( FS_LABEL_WRITE == b_action)
01125 {
01126
01127 if( FS_ENTRY_END != ptr_entry[0] )
01128 {
01129 if( FS_ATTR_VOLUME_ID != ptr_entry[11])
01130 {
01131 fs_g_status = FS_ERR_ENTRY_BAD;
01132 return FALSE;
01133 }
01134 }
01135 if( 0 == *sz_label )
01136 {
01137 fs_g_status = FS_ERR_NAME_INCORRECT;
01138 return FALSE;
01139 }
01140 ptr_entry[11] = FS_ATTR_VOLUME_ID;
01141 for( u8_pos_name=0; u8_pos_name<11; u8_pos_name++ )
01142 {
01143 u8_char = *sz_label;
01144 if( ('a'<=u8_char) && (u8_char<='z') )
01145 {
01146 u8_char -= ('a'-'A');
01147 }
01148 if( 0 == u8_char )
01149 {
01150 u8_char = 0x20;
01151 }
01152 *ptr_entry = u8_char;
01153 ptr_entry++;
01154 if( 0x20 == u8_char )
01155 continue;
01156 sz_label++;
01157 }
01158 fat_cache_mark_sector_as_dirty();
01159 return fat_cache_flush();
01160 }
01161 return FALSE;
01162 }
01163 #endif // FS_LEVEL_FEATURES
01164
01165
01166 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET))
01180 Bool fat_initialize_dir( void )
01181 {
01182 U8 u8_i;
01183
01184
01185 if( !fat_clear_cluster())
01186 return FALSE;
01187 fat_cache_mark_sector_as_dirty();
01188
01189
01190
01191 fs_g_sector[0]='.';
01192 for( u8_i=1 ; u8_i<11 ; u8_i++ )
01193 fs_g_sector[u8_i]=' ';
01194 fs_g_sector[11]=FS_ATTR_DIRECTORY;
01195 fs_g_sector[26]= LSB0( fs_g_nav_entry.u32_cluster );
01196 fs_g_sector[27]= LSB1( fs_g_nav_entry.u32_cluster );
01197 fs_g_sector[20]= LSB2( fs_g_nav_entry.u32_cluster );
01198 fs_g_sector[21]= LSB3( fs_g_nav_entry.u32_cluster );
01199
01200 fs_g_sector[FS_SIZE_FILE_ENTRY+0]='.';
01201 fs_g_sector[FS_SIZE_FILE_ENTRY+1]='.';
01202 for( u8_i=2 ; u8_i<11 ; u8_i++ )
01203 fs_g_sector[FS_SIZE_FILE_ENTRY+u8_i]=' ';
01204 fs_g_sector[FS_SIZE_FILE_ENTRY+11]=FS_ATTR_DIRECTORY;
01205 fs_g_sector[FS_SIZE_FILE_ENTRY+26]= LSB0( fs_g_nav.u32_cluster_sel_dir );
01206 fs_g_sector[FS_SIZE_FILE_ENTRY+27]= LSB1( fs_g_nav.u32_cluster_sel_dir );
01207 fs_g_sector[FS_SIZE_FILE_ENTRY+20]= LSB2( fs_g_nav.u32_cluster_sel_dir );
01208 fs_g_sector[FS_SIZE_FILE_ENTRY+21]= LSB3( fs_g_nav.u32_cluster_sel_dir );
01209
01210 return TRUE;
01211 }
01212 #endif // FS_LEVEL_FEATURES
01213
01214
01221 void fat_get_date( FS_STRING sz_date , Bool type_date )
01222 {
01223 PTR_CACHE ptr_entry;
01224
01225 ptr_entry = fat_get_ptr_entry();
01226 if( FS_DATE_LAST_WRITE == type_date )
01227 {
01228 fat_translatedate_number_to_ascii( sz_date , &ptr_entry[22] , FALSE );
01229 }
01230 else
01231 {
01232 fat_translatedate_number_to_ascii( sz_date , &ptr_entry[13] , TRUE );
01233 }
01234 }
01235
01236
01244 void fat_translatedate_number_to_ascii( FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms )
01245 {
01246 FS_STRING ptr_string_date;
01247 U8 u8_i;
01248 U8 msb_date, lsb_date, msb_time, lsb_time, u8_ms = 0;
01249
01250
01251 if( enable_ms )
01252 {
01253 u8_ms = *ptr_date;
01254 ptr_date++;
01255 }
01256 lsb_time = *ptr_date;
01257 ptr_date++;
01258 msb_time = *ptr_date;
01259 ptr_date++;
01260 lsb_date = *ptr_date;
01261 ptr_date++;
01262 msb_date = *ptr_date;
01263
01264
01265 ptr_string_date = sz_date;
01266 *ptr_string_date = '1';
01267 ptr_string_date++;
01268 *ptr_string_date = '9';
01269 ptr_string_date++;
01270 *ptr_string_date = '8';
01271 ptr_string_date++;
01272 for( u8_i=(15-2) ; u8_i!=0 ; u8_i-- )
01273 {
01274 *ptr_string_date = '0';
01275 ptr_string_date++;
01276 }
01277
01278
01279 fat_translate_number_to_ascii( sz_date, 4 , msb_date>>1 );
01280
01281
01282 fat_translate_number_to_ascii( &sz_date[4] , 2 , ((msb_date & 0x01)<<3) + (lsb_date>>5) );
01283
01284
01285 fat_translate_number_to_ascii( &sz_date[6] , 2 , lsb_date & 0x1F );
01286
01287
01288 fat_translate_number_to_ascii( &sz_date[8] , 2 , msb_time >> (11-8) );
01289
01290
01291 fat_translate_number_to_ascii( &sz_date[10] , 2 , ((msb_time & 0x07)<<3) + (lsb_time>>5) );
01292
01293
01294 fat_translate_number_to_ascii( &sz_date[12] , 2 , (lsb_time & 0x1F)<<1 );
01295 if( 99 < u8_ms )
01296 {
01297
01298 fat_translate_number_to_ascii( &sz_date[12] , 2 , 1 );
01299 u8_ms -= 100;
01300 }
01301
01302
01303 fat_translate_number_to_ascii( &sz_date[14] , 2 , u8_ms );
01304 }
01305
01306
01317 void fat_translate_number_to_ascii( FS_STRING sz_ascii_number, U8 u8_size_number_ascii, U8 u8_nb_increment )
01318 {
01319 FS_STRING ptr_sz_ascii_number;
01320
01321 u8_size_number_ascii--;
01322
01323 for( ; u8_nb_increment != 0 ; u8_nb_increment-- )
01324 {
01325 ptr_sz_ascii_number = sz_ascii_number + u8_size_number_ascii;
01326 ptr_sz_ascii_number[0]++;
01327 while( ('9'+1) == *ptr_sz_ascii_number )
01328 {
01329 *ptr_sz_ascii_number = '0';
01330 ptr_sz_ascii_number--;
01331 ptr_sz_ascii_number[0]++;
01332 }
01333 }
01334 }
01335
01336
01337 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET))
01348 void fat_set_date( const FS_STRING sz_date , Bool type_date )
01349 {
01350 PTR_CACHE ptr_entry;
01351
01352 fat_cache_mark_sector_as_dirty();
01353 ptr_entry = fat_get_ptr_entry();
01354
01355 if( FS_DATE_LAST_WRITE == type_date )
01356 {
01357 fat_translatedate_ascii_to_number( sz_date , &ptr_entry[22] , FALSE );
01358 }
01359 else
01360 {
01361 fat_translatedate_ascii_to_number( sz_date , &ptr_entry[13] , TRUE );
01362 }
01363 }
01364
01365
01377 void fat_translatedate_ascii_to_number( const FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms )
01378 {
01379 U8 u8_tmp;
01380 U8 msb_date, lsb_date, msb_time, lsb_time;
01381
01382
01383 msb_date = ((U8)(fat_translate_ascii_to_number( sz_date , 4 )-1980))<<1;
01384
01385
01386 u8_tmp = (U8)fat_translate_ascii_to_number( &sz_date[4] , 2 );
01387 msb_date |= (u8_tmp >> 3);
01388 lsb_date = (u8_tmp << 5);
01389
01390
01391 lsb_date |= (U8)fat_translate_ascii_to_number( &sz_date[6] , 2 );
01392
01393
01394 msb_time = ((U8)fat_translate_ascii_to_number( &sz_date[8] , 2 )) << (11-8);
01395
01396
01397 u8_tmp = (U8)fat_translate_ascii_to_number( &sz_date[10] , 2 );
01398 msb_time |= (u8_tmp >> 3);
01399 lsb_time = (u8_tmp << 5);
01400
01401
01402 u8_tmp = (U8)fat_translate_ascii_to_number( &sz_date[12] , 2 );
01403 lsb_time |= (u8_tmp >> 1);
01404
01405
01406 if( enable_ms )
01407 {
01408
01409 if( u8_tmp & 0x01 )
01410 {
01411 u8_tmp = 100;
01412 }
01413 else
01414 {
01415 u8_tmp = 0;
01416 }
01417 *ptr_date = u8_tmp + (U8)fat_translate_ascii_to_number( &sz_date[14] , 2 );
01418 ptr_date++;
01419 }
01420
01421
01422 ptr_date[0] = lsb_time;
01423 ptr_date[1] = msb_time;
01424 ptr_date[2] = lsb_date;
01425 ptr_date[3] = msb_date;
01426 }
01427
01428
01440 U16 fat_translate_ascii_to_number( const FS_STRING sz_ascii_number, U8 u8_size_number_ascii )
01441 {
01442 U8 sz_ascii_number_copy[4];
01443 U8 _MEM_TYPE_FAST_ *ptr_sz_ascii_number;
01444 U8 u8_i;
01445 U16 u16_number;
01446
01447 for( u8_i=0; u8_i < u8_size_number_ascii; u8_i++ )
01448 {
01449 sz_ascii_number_copy[u8_i] = sz_ascii_number[u8_i];
01450 }
01451
01452 u16_number=0;
01453
01454 while( 1 )
01455 {
01456
01457 ptr_sz_ascii_number = sz_ascii_number_copy;
01458 for( u8_i = u8_size_number_ascii; u8_i !=0; u8_i-- )
01459 {
01460 if( '0' != *ptr_sz_ascii_number )
01461 {
01462 break;
01463 }
01464 ptr_sz_ascii_number++;
01465 }
01466 if( 0 == u8_i)
01467 return u16_number;
01468
01469
01470 ptr_sz_ascii_number = sz_ascii_number_copy + u8_size_number_ascii -1;
01471 u16_number++;
01472 ptr_sz_ascii_number[0]--;
01473 while( ('0'-1) == ptr_sz_ascii_number[0] )
01474 {
01475 *ptr_sz_ascii_number = '9';
01476 ptr_sz_ascii_number--;
01477 ptr_sz_ascii_number[0]--;
01478 }
01479 }
01480 }
01481 #endif // FS_LEVEL_FEATURES
01482
01483
01484
01485 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
01499 Bool fat_create_entry_file_name( FS_STRING sz_name )
01500 {
01501 U8 u8_i, u8_nb;
01502 U8 u8_crc, u8_nb_entry;
01503
01504
01505 u8_nb_entry = fat_check_name( sz_name );
01506 if( 0 == u8_nb_entry )
01507 return FALSE;
01508
01509
01510 u8_nb = fat_find_short_entry_name( sz_name );
01511 if( 0 == u8_nb )
01512 {
01513 fs_g_status = FS_ERR_FILE_EXIST;
01514 return FALSE;
01515 }
01516
01517
01518 if( !fat_alloc_entry_free( u8_nb_entry ))
01519 return FALSE;
01520
01521
01522
01523 u8_crc = fat_create_short_entry_name( sz_name , 0 , u8_nb, FALSE );
01524 u8_nb_entry--;
01525
01526
01527 for( u8_i=1 ; u8_i<=u8_nb_entry ; u8_i++ )
01528 {
01529
01530 fs_g_nav_fast.u16_entry_pos_sel_file--;
01531 if( !fat_read_dir())
01532 return FALSE;
01533
01534 if( u8_i == u8_nb_entry )
01535 {
01536 u8_i += FS_ENTRY_LFN_LAST;
01537 }
01538 fat_create_long_name_entry( sz_name , u8_crc , u8_i );
01539 sz_name += FS_SIZE_LFN_ENTRY*(Is_unicode? 2 : 1 );
01540 }
01541
01542 fs_g_nav_fast.u16_entry_pos_sel_file += u8_nb_entry;
01543 return TRUE;
01544 }
01545
01546
01557 void fat_create_long_name_entry( FS_STRING sz_name , U8 u8_crc , U8 u8_id )
01558 {
01559 PTR_CACHE ptr_entry;
01560 Bool b_end_of_name = FALSE;
01561
01562 fat_cache_mark_sector_as_dirty();
01563 ptr_entry = fat_get_ptr_entry();
01564 *ptr_entry = u8_id;
01565 ptr_entry++;
01566
01567 for( u8_id=1; u8_id<FS_SIZE_FILE_ENTRY ; u8_id++ , ptr_entry++ )
01568 {
01569
01570 if( 11 == u8_id)
01571 {
01572 *ptr_entry = FS_ATTR_LFN_ENTRY;
01573 continue;
01574 }
01575 if( (12 == u8_id)
01576 || (26 == u8_id)
01577 || (27 == u8_id) )
01578 {
01579
01580
01581 continue;
01582 }
01583 if( 13 == u8_id)
01584 {
01585 *ptr_entry = u8_crc;
01586 continue;
01587 }
01588
01589
01590 if( !b_end_of_name )
01591 {
01592 U16 u16_tmp;
01593 if( Is_unicode )
01594 {
01595 u16_tmp = ((FS_STR_UNICODE)sz_name)[0];
01596 }else{
01597 u16_tmp = sz_name[0];
01598 }
01599 if(('\\' == u16_tmp )
01600 || ('/' == u16_tmp ) )
01601 {
01602 u16_tmp = 0;
01603 }
01604 if( 0 == u16_tmp )
01605 {
01606 b_end_of_name = TRUE;
01607 }
01608 *ptr_entry = LSB(u16_tmp);
01609 ptr_entry++;
01610 *ptr_entry = MSB(u16_tmp);
01611 u8_id++;
01612 sz_name += (Is_unicode? 2 : 1 );
01613 }
01614 else
01615 {
01616 *ptr_entry = 0xFF;
01617 }
01618 }
01619 }
01620
01621
01632 U8 fat_create_short_entry_name( FS_STRING sz_name , FS_STRING short_name , U8 nb , Bool mode )
01633 {
01634 PTR_CACHE ptr_entry = 0;
01635 U8 u8_i, u8_step, character;
01636 U8 crc;
01637 U8 nb_digit;
01638
01639 if( !mode )
01640 {
01641
01642 fat_cache_mark_sector_as_dirty();
01643
01644 ptr_entry = fat_get_ptr_entry();
01645 }
01646
01647
01648 if( nb < 10 ) nb_digit = 1;
01649 else if( nb < 100 ) nb_digit = 2;
01650 else nb_digit = 3;
01651
01652 crc = u8_i = 0;
01653 u8_step = 1;
01654 while( 1 )
01655 {
01656 if( Is_unicode )
01657 {
01658 character = ((FS_STR_UNICODE)sz_name)[0];
01659 }else{
01660 character = sz_name[0];
01661 }
01662
01663 if( 1 == u8_step )
01664 {
01665 if( ((FS_SIZE_SFNAME_WITHOUT_EXT-(1+nb_digit)) == u8_i)
01666 || ('.' == character)
01667 || fat_check_eof_name(character) )
01668 {
01669 u8_step++;
01670 continue;
01671 }
01672 }
01673 if( 8 == u8_step )
01674 {
01675 if( (u8_i == FS_SIZE_SFNAME)
01676 || fat_check_eof_name(character) )
01677 {
01678 u8_step++;
01679 continue;
01680 }
01681 }
01682 if( (1==u8_step) || (8==u8_step) )
01683 {
01684 character = fat_translate_char_shortname( character );
01685 sz_name += (Is_unicode? 2 : 1 );
01686 if( 0 == character )
01687 {
01688 continue;
01689 }
01690 }
01691 if( 7 == u8_step )
01692 {
01693 if( ('.' == character)
01694 || fat_check_eof_name(character) )
01695 {
01696 u8_step++;
01697 } else {
01698 sz_name += (Is_unicode? 2 : 1 );
01699 }
01700 continue;
01701 }
01702 if( 6 == u8_step )
01703 {
01704 if( u8_i == FS_SIZE_SFNAME_WITHOUT_EXT )
01705 {
01706 u8_step++;
01707 continue;
01708 }
01709 character = ' ';
01710 }
01711 if( 9 == u8_step )
01712 {
01713 if( u8_i == FS_SIZE_SFNAME )
01714 {
01715 break;
01716 }
01717 character = ' ';
01718 }
01719 if( 5 == u8_step )
01720 {
01721 character = '0'+(nb%10);
01722 u8_step++;
01723 }
01724 if( 4 == u8_step )
01725 {
01726 character = '0'+((nb%100)/10);
01727 u8_step++;
01728 }
01729 if( 3 == u8_step )
01730 {
01731 character = '0'+(nb/100);
01732 u8_step++;
01733 }
01734 if( 2 == u8_step )
01735 {
01736 character = '~';
01737 u8_step+=(4-nb_digit);
01738 }
01739
01740 if( mode )
01741 {
01742
01743 *short_name = character;
01744 short_name++;
01745 }else{
01746
01747 *ptr_entry = character;
01748 ptr_entry++;
01749 }
01750 u8_i++;
01751
01752
01753 crc = (crc >> 1) + ((crc & 1) << 7);
01754 crc += character;
01755 }
01756 return crc;
01757 }
01758
01759
01767 U8 fat_find_short_entry_name( FS_STRING sz_name )
01768 {
01769 char _MEM_TYPE_SLOW_ short_name[11];
01770 U8 u8_nb;
01771
01772 u8_nb = 0;
01773 while(1)
01774 {
01775 if( 0xFF == u8_nb )
01776 return 0;
01777
01778 u8_nb++;
01779 fat_create_short_entry_name( sz_name , short_name , u8_nb , TRUE );
01780 fs_g_nav_fast.u16_entry_pos_sel_file = 0;
01781
01782 while(1)
01783 {
01784 if ( !fat_read_dir())
01785 {
01786 if( FS_ERR_OUT_LIST == fs_g_status )
01787 return u8_nb;
01788 return 0;
01789 }
01790 if( fat_entry_shortname_compare( short_name ) )
01791 break;
01792 if( FS_ERR_ENTRY_EMPTY == fs_g_status )
01793 return u8_nb;
01794 fs_g_nav_fast.u16_entry_pos_sel_file++;
01795 }
01796 }
01797 }
01798
01799
01807 Bool fat_entry_shortname_compare( FS_STRING short_name )
01808 {
01809 PTR_CACHE ptr_entry;
01810
01811 ptr_entry = fat_get_ptr_entry();
01812 if( FS_ENTRY_END == *ptr_entry )
01813 {
01814 fs_g_status = FS_ERR_ENTRY_EMPTY;
01815 return FALSE;
01816 }
01817 if( (FS_ENTRY_DEL == *ptr_entry )
01818 || (FS_ATTR_LFN_ENTRY == ptr_entry[11]) )
01819 {
01820 fs_g_status = FS_ERR_ENTRY_BAD;
01821 return FALSE;
01822 }
01823 fs_g_status = FS_ERR_ENTRY_BAD;
01824 return (0==memcmp_ram2ram(ptr_entry , short_name , 8+3 ));
01825 }
01826
01828 _CONST_TYPE_ U8 fs_s_tab_incorrect_char[]={':','*','?','"','<','>','|'};
01829
01837 U8 fat_check_name( FS_STRING sz_name )
01838 {
01839 U8 u8_nb_entry, u8_i, u8_j;
01840 U16 u16_character;
01841
01842 u8_nb_entry = 2;
01843 u8_i = FS_SIZE_LFN_ENTRY;
01844 while( 1 )
01845 {
01846 if( Is_unicode )
01847 {
01848 u16_character = ((FS_STR_UNICODE)sz_name)[0];
01849 }else{
01850 u16_character = sz_name[0];
01851 }
01852 if( fat_check_eof_name( u16_character ) )
01853 break;
01854
01855 for( u8_j = 0 ; u8_j < sizeof(fs_s_tab_incorrect_char) ; u8_j++ )
01856 {
01857 if( u16_character == fs_s_tab_incorrect_char[u8_j] )
01858 {
01859 fs_g_status = FS_ERR_INCORRECT_NAME;
01860 return 0;
01861 }
01862 }
01863 if( 0 == u8_i )
01864 {
01865 u8_nb_entry++;
01866 u8_i = FS_SIZE_LFN_ENTRY;
01867 }
01868 u8_i--;
01869 sz_name += (Is_unicode? 2 : 1 );
01870 }
01871 if( 0x14 < u8_nb_entry )
01872 {
01873 fs_g_status = FS_ERR_NAME_TOO_LARGE;
01874 return 0;
01875 }
01876 return u8_nb_entry;
01877 }
01878
01879
01881 _CONST_TYPE_ U8 fs_s_execption_char[]={'+',',','.',';','=','[',']'};
01882
01890 U8 fat_translate_char_shortname( U8 character )
01891 {
01892 U8 u8_j;
01893
01894 if( (character<=' ') || ('~'<character) )
01895 return 0;
01896 if( ('a'<=character) && (character<='z') )
01897 {
01898 return (character - ('a'-'A'));
01899 }
01900 for( u8_j = 0 ; u8_j < sizeof(fs_s_execption_char) ; u8_j++ )
01901 {
01902 if( character == fs_s_execption_char[u8_j] )
01903 return 0;
01904 }
01905 return character;
01906 }
01907
01908
01920 Bool fat_alloc_entry_free( U8 u8_nb_entry )
01921 {
01922 PTR_CACHE ptr_entry;
01923 Bool b_garbage_collector_used = FALSE;
01924 U8 u8_nb_entry_save;
01925
01926 u8_nb_entry_save = u8_nb_entry;
01927
01928
01929 fs_g_nav_fast.u16_entry_pos_sel_file=0;
01930
01931 while( 1 )
01932 {
01933
01934 if( !fat_read_dir() )
01935 {
01936 if( FS_ERR_OUT_LIST != fs_g_status )
01937 return FALSE;
01938
01939
01940
01941
01942 fs_g_seg.u32_size_or_pos = 1;
01943 if( !fat_allocfreespace())
01944 {
01945
01946 if( b_garbage_collector_used )
01947 return FALSE;
01948 if( !fat_garbage_collector_entry())
01949 return FALSE;
01950 b_garbage_collector_used = TRUE;
01951 fs_g_nav_fast.u16_entry_pos_sel_file=0;
01952 u8_nb_entry = u8_nb_entry_save;
01953 continue;
01954 }
01955
01956
01957
01958 if( !fat_clear_cluster())
01959 return FALSE;
01960
01961 continue;
01962 }
01963
01964
01965 ptr_entry = fat_get_ptr_entry();
01966 if ( FS_ENTRY_END == *ptr_entry )
01967 {
01968 u8_nb_entry--;
01969 if( 0 == u8_nb_entry )
01970 {
01971 return TRUE;
01972 }
01973 }
01974
01975
01976 fs_g_nav_fast.u16_entry_pos_sel_file++;
01977 if( 0 == fs_g_nav_fast.u16_entry_pos_sel_file )
01978 {
01979
01980
01981 if( b_garbage_collector_used )
01982 {
01983
01984 fs_g_status = FS_ERR_NO_FREE_SPACE;
01985 return FALSE;
01986 }
01987 if( !fat_garbage_collector_entry())
01988 return FALSE;
01989 b_garbage_collector_used = TRUE;
01990 fs_g_nav_fast.u16_entry_pos_sel_file=0;
01991 u8_nb_entry = u8_nb_entry_save;
01992 continue;
01993 }
01994 }
01995 }
01996
01997
02003 Bool fat_garbage_collector_entry( void )
02004 {
02005 _MEM_TYPE_SLOW_ U8 entry[ FS_SIZE_FILE_ENTRY ];
02006 PTR_CACHE ptr_entry;
02007 U16 u16_pos_old = 0;
02008 U16 u16_pos_new = 0;
02009
02010
02011 while( 1 )
02012 {
02013
02014 fs_g_nav_fast.u16_entry_pos_sel_file=u16_pos_old;
02015
02016 if( !fat_read_dir() )
02017 {
02018 if( FS_ERR_OUT_LIST != fs_g_status )
02019 return FALSE;
02020 goto fat_garbage_collector_entry_endofdir;
02021 }
02022
02023
02024 ptr_entry = fat_get_ptr_entry();
02025
02026 if ( FS_ENTRY_END == *ptr_entry )
02027 {
02028
02029 fat_garbage_collector_entry_endofdir:
02030
02031 fs_g_nav_fast.u16_entry_pos_sel_file=u16_pos_new;
02032 while( fs_g_nav_fast.u16_entry_pos_sel_file != u16_pos_old )
02033 {
02034
02035 if( !fat_read_dir() )
02036 return FALSE;
02037 memset( fat_get_ptr_entry() , 0 , 32 );
02038 fat_cache_mark_sector_as_dirty();
02039 fs_g_nav_fast.u16_entry_pos_sel_file++;
02040 }
02041 return TRUE;
02042 }
02043
02044 if ( FS_ENTRY_DEL != *ptr_entry )
02045 {
02046
02047 if( u16_pos_old != u16_pos_new )
02048 {
02049
02050 memcpy_ram2ram( entry, ptr_entry, FS_SIZE_FILE_ENTRY );
02051 fs_g_nav_fast.u16_entry_pos_sel_file=u16_pos_new;
02052
02053 if( !fat_read_dir() )
02054 return FALSE;
02055 memcpy_ram2ram( fat_get_ptr_entry(), entry, FS_SIZE_FILE_ENTRY );
02056 fat_cache_mark_sector_as_dirty();
02057 }
02058 u16_pos_new++;
02059 }
02060 u16_pos_old++;
02061 }
02062 }
02063
02064
02073 Bool fat_delete_file( Bool b_cluster_list )
02074 {
02075 PTR_CACHE ptr_entry;
02076 U8 u8_tmp;
02077 Bool b_short_del = FALSE;
02078
02079
02080 while( 1 )
02081 {
02082
02083 if( !fat_read_dir() )
02084 return FALSE;
02085
02086
02087 ptr_entry = fat_get_ptr_entry();
02088 u8_tmp = ptr_entry[0];
02089
02090 if( (FS_ATTR_LFN_ENTRY != ptr_entry[11])
02091 && (b_short_del) )
02092 {
02093
02094 break;
02095 }
02096
02097
02098 b_short_del = TRUE;
02099 ptr_entry[0] = FS_ENTRY_DEL;
02100 fat_cache_mark_sector_as_dirty();
02101
02102 if( (FS_ATTR_LFN_ENTRY == ptr_entry[11])
02103 && ( 0 != (FS_ENTRY_LFN_LAST & u8_tmp)) )
02104 {
02105
02106 break;
02107 }
02108
02109
02110 fs_g_nav_fast.u16_entry_pos_sel_file--;
02111 }
02112
02113 if( b_cluster_list )
02114 {
02115
02116 fs_g_nav_entry.u32_pos_in_file=0;
02117 if( !fat_read_file( FS_CLUST_ACT_CLR ))
02118 return FALSE;
02119 }
02120
02121 return TRUE;
02122 }
02123 #endif // FS_LEVEL_FEATURES
02124
02125
02126
02132 U32 fat_getfreespace( void )
02133 {
02134 U32 u32_nb_free_cluster = 0;
02135
02136
02137 fs_g_cluster.u32_pos = 2;
02138
02139 if( Is_fat12 )
02140 {
02141 for(
02142 ; fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02143 ; fs_g_cluster.u32_pos++ )
02144 {
02145
02146 if ( !fat_cluster_val( FS_CLUST_VAL_READ ) )
02147 return 0;
02148
02149 if ( 0 == fs_g_cluster.u32_val )
02150 u32_nb_free_cluster++;
02151 }
02152 }
02153 else
02154 {
02155 if( Is_fat32 )
02156 {
02157 u32_nb_free_cluster = fat_read_fat32_FSInfo();
02158 if( 0xFFFFFFFF != u32_nb_free_cluster )
02159 goto endof_fat_getfreespace;
02160 u32_nb_free_cluster = 0;
02161 }
02162
02163
02164 if( !fat_cluster_val( FS_CLUST_VAL_READ ))
02165 return FALSE;
02166 for(
02167 ; fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02168 ; fs_g_cluster.u32_pos++ )
02169 {
02170 if ( 0 == fs_g_cluster.u32_val )
02171 u32_nb_free_cluster++;
02172 if( !fat_cluster_readnext() )
02173 return FALSE;
02174 }
02175 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) )
02176 if( Is_fat32 )
02177 {
02178
02179 fat_write_fat32_FSInfo( u32_nb_free_cluster );
02180 }
02181 #endif
02182 }
02183 endof_fat_getfreespace:
02184 return (u32_nb_free_cluster * fs_g_nav.u8_BPB_SecPerClus);
02185 }
02186
02187
02197 U8 fat_getfreespace_percent( void )
02198 {
02199 U32 u32_nb_free_cluster = 0;
02200 U16 u16_tmp, u16_pos;
02201
02202 if( Is_fat12 )
02203 {
02204 return (((fat_getfreespace()/fs_g_nav.u8_BPB_SecPerClus)*100) / fs_g_nav.u32_CountofCluster);
02205 }
02206
02207
02208 fs_g_cluster.u32_pos = 2;
02209
02210 if( !fat_cluster_val( FS_CLUST_VAL_READ ))
02211 return FALSE;
02212
02213
02214
02215
02216 if( Is_fat32 )
02217 {
02218 u32_nb_free_cluster = fat_read_fat32_FSInfo();
02219 if( 0xFFFFFFFF != u32_nb_free_cluster )
02220 goto endof_fat_getfreespace_percent;
02221 u32_nb_free_cluster = 0;
02222
02223 u16_pos = 2*4;
02224 for( u16_tmp = fs_g_nav.u16_fat_size
02225 ; u16_tmp!=0
02226 ; u16_tmp-- )
02227 {
02228 for( ; u16_pos < 512 ; u16_pos += (2*4) )
02229 {
02230 if( 0 == fs_g_sector[u16_pos] )
02231 u32_nb_free_cluster+=2;
02232 }
02233
02234 u16_pos = 0;
02235 fs_gu32_addrsector++;
02236 if( !fat_cache_read_sector( TRUE ))
02237 return 0;
02238 }
02239 }
02240
02241 if ( Is_fat16 )
02242 {
02243 u16_pos = 2*2;
02244
02245 for( u16_tmp = fs_g_nav.u16_fat_size
02246 ; u16_tmp!=0
02247 ; u16_tmp-- )
02248 {
02249 for( ; u16_pos < 512 ; u16_pos += (2*2) )
02250 {
02251 if( 0 == fs_g_sector[u16_pos] )
02252 u32_nb_free_cluster+=2;
02253 }
02254
02255 u16_pos = 0;
02256 fs_gu32_addrsector++;
02257 if( !fat_cache_read_sector( TRUE ))
02258 return 0;
02259 }
02260 }
02261
02262
02263 if( u32_nb_free_cluster > fs_g_nav.u32_CountofCluster )
02264 return 100;
02265 if( u32_nb_free_cluster > ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256) )
02266 {
02267
02268 u32_nb_free_cluster -= ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256);
02269 }
02270 endof_fat_getfreespace_percent:
02271 return ((u32_nb_free_cluster * 100) / fs_g_nav.u32_CountofCluster);
02272 }
02273
02274
02275
02276 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
02293 Bool fat_allocfreespace( void )
02294 {
02295
02296 Bool first_cluster_free_is_found = FALSE;
02297
02298 Bool b_quick_find = TRUE;
02299
02300 if( Is_fat32 )
02301 {
02302
02303 if( !fat_write_fat32_FSInfo( 0xFFFFFFFF ))
02304 return FALSE;
02305 }
02306
02307 if( 0xFF == MSB0(fs_g_seg.u32_addr) )
02308 {
02309 fat_allocfreespace_start:
02310
02311 fs_g_cluster.u32_pos = 2;
02312 }else{
02313
02314 fs_g_cluster.u32_pos = fs_g_seg.u32_addr+1;
02315 }
02316
02317 fat_clear_info_fat_mod();
02318
02319
02320 for(
02321 ; fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02322 ; fs_g_cluster.u32_pos++ )
02323 {
02324
02325 if ( !fat_cluster_val( FS_CLUST_VAL_READ ) )
02326 return FALSE;
02327
02328 if ( 0 == fs_g_cluster.u32_val )
02329 {
02330
02331 fs_g_cluster.u32_val = fs_g_cluster.u32_pos;
02332 if( TRUE == first_cluster_free_is_found )
02333 {
02334
02335 fs_g_cluster.u32_pos--;
02336 if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) )
02337 return FALSE;
02338 }
02339 else
02340 {
02341
02342 first_cluster_free_is_found = TRUE;
02343
02344 if( 0xFF != MSB0(fs_g_seg.u32_addr) )
02345 {
02346
02347
02348 if( 0 == fs_g_seg.u32_addr )
02349 {
02350 if( FS_TYPE_FAT_32 != fs_g_nav_fast.u8_type_fat )
02351 {
02352
02353 fs_g_status = FS_ERR_NO_FREE_SPACE;
02354 return FALSE;
02355 }
02356 fs_g_cluster.u32_pos = fs_g_nav.rootdir.u32_cluster;
02357 }
02358 else
02359 {
02360 fs_g_cluster.u32_pos = fs_g_seg.u32_addr;
02361 }
02362 if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) )
02363 return FALSE;
02364 }
02365 fs_g_seg.u32_addr = fs_g_cluster.u32_val;
02366 }
02367
02368
02369 fs_g_cluster.u32_pos = fs_g_cluster.u32_val;
02370 fs_g_cluster.u32_val = FS_CLUST_VAL_EOL;
02371 if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) )
02372 return FALSE;
02373
02374
02375 if ( fs_g_seg.u32_size_or_pos <= fs_g_nav.u8_BPB_SecPerClus )
02376 {
02377 fs_g_seg.u32_size_or_pos = 0;
02378 break;
02379 }
02380 fs_g_seg.u32_size_or_pos -= fs_g_nav.u8_BPB_SecPerClus;
02381 }
02382 else
02383 {
02384
02385 if( TRUE == first_cluster_free_is_found )
02386 {
02387
02388
02389 break;
02390 }
02391 else
02392 {
02393
02394
02395 if( b_quick_find )
02396 {
02397 fs_g_cluster.u32_pos += 500;
02398 }
02399 }
02400 }
02401 }
02402
02403
02404 if( FALSE == first_cluster_free_is_found )
02405 {
02406 if( b_quick_find )
02407 {
02408
02409 b_quick_find = FALSE;
02410 goto fat_allocfreespace_start;
02411 }
02412 fs_g_status = FS_ERR_NO_FREE_SPACE;
02413 return FALSE;
02414 }
02415
02416 return fat_update_fat2();
02417 }
02418 #endif // FS_LEVEL_FEATURES
02419
02420
02421 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
02424 void fat_clear_info_fat_mod( void )
02425 {
02426 fs_g_u16_first_mod_fat = 0xFFFF;
02427 fs_g_u16_last_mod_fat = 0;
02428 }
02429 #endif // FS_LEVEL_FEATURES
02430
02431
02432 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
02438 Bool fat_update_fat2( void )
02439 {
02440 while( fs_g_u16_first_mod_fat <= fs_g_u16_last_mod_fat )
02441 {
02442
02443 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + fs_g_u16_first_mod_fat;
02444
02445 if( !fat_cache_read_sector( TRUE ))
02446 return FALSE;
02447
02448 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + ((U32)fs_g_u16_first_mod_fat + fs_g_nav.u16_fat_size);
02449
02450 if( !fat_cache_read_sector( FALSE ))
02451 return FALSE;
02452
02453 fat_cache_mark_sector_as_dirty();
02454 fs_g_u16_first_mod_fat++;
02455 }
02456 return TRUE;
02457 }
02458 #endif // FS_LEVEL_FEATURES
02459
02460
02461 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
02473 Bool fat_clear_cluster( void )
02474 {
02475 U8 u8_loop;
02476
02477
02478 fs_g_seg.u32_size_or_pos = 0;
02479 if( !fat_cluster_list( FS_CLUST_ACT_ONE, FALSE ))
02480 return FALSE;
02481
02482
02483 fs_gu32_addrsector = fs_g_seg.u32_addr + (fs_g_nav.u8_BPB_SecPerClus -1);
02484 for( u8_loop = 0
02485 ; fs_g_nav.u8_BPB_SecPerClus != u8_loop
02486 ; u8_loop++ )
02487 {
02488
02489 if( !fat_cache_read_sector( FALSE ))
02490 return FALSE;
02491
02492 if(0 == u8_loop)
02493 {
02494 fat_cache_clear();
02495 }
02496 fat_cache_mark_sector_as_dirty();
02497 fs_gu32_addrsector--;
02498 }
02499 return TRUE;
02500 }
02501 #endif // FS_LEVEL_FEATURES