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 #include "conf_explorer.h"
00043 #include "fs_com.h"
00044 #include "fat.h"
00045 #include LIB_MEM
00046 #include LIB_CTRLACCESS
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 Bool fat_select_filesystem ( U8 u8_fat_type , Bool b_MBR );
00057 Bool fat_write_MBR ( void );
00058 Bool fat_write_PBR ( Bool b_MBR );
00059 Bool fat_clean_zone ( Bool b_MBR );
00060 Bool fat_initialize_fat ( void );
00061
00062
00065 void fat_translatedate_number_to_ascii ( FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms );
00066 void fat_translate_number_to_ascii ( FS_STRING sz_ascii_number, U8 u8_size_number_ascii, U8 u8_nb_increment );
00067 void fat_translatedate_ascii_to_number ( const FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms );
00068 U16 fat_translate_ascii_to_number ( const FS_STRING sz_ascii_number, U8 u8_size_number_ascii );
00070
00073 void fat_create_long_name_entry ( FS_STRING sz_name , U8 u8_crc , U8 u8_id );
00074 U8 fat_create_short_entry_name ( FS_STRING sz_name , FS_STRING short_name , U8 nb , Bool mode );
00075 U8 fat_find_short_entry_name ( FS_STRING sz_name );
00076 Bool fat_entry_shortname_compare ( FS_STRING short_name );
00077 U8 fat_check_name ( FS_STRING sz_name );
00078 U8 fat_translate_char_shortname ( U8 character );
00079 Bool fat_alloc_entry_free ( U8 u8_nb_entry );
00080 Bool fat_garbage_collector_entry ( void );
00082
00083
00084
00085
00102 Bool fat_mount( void )
00103 {
00104 U8 u8_sector_size;
00105 U8 u8_tmp;
00106 U16 u16_tmp;
00107 U32 u32_tmp;
00108
00109
00110 fs_g_nav.u32_cluster_sel_dir = 0;
00111
00112 fat_clear_entry_info_and_ptr();
00113
00114 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM;
00115 fs_gu32_addrsector = 0;
00116
00117
00118 if( !fat_check_device() )
00119 return FALSE;
00120
00121 while( 1 )
00122 {
00123
00124 if( !fat_cache_read_sector( TRUE ))
00125 return FALSE;
00126
00127
00128 if ( (fs_g_sector[510] != FS_BR_SIGNATURE_LOW )
00129 && (fs_g_sector[511] != FS_BR_SIGNATURE_HIGH ) )
00130 {
00131 fs_g_status = FS_ERR_NO_FORMAT;
00132 return FALSE;
00133 }
00134
00135 if ( 0 == fs_gu32_addrsector )
00136 {
00137
00138
00139 #if (FS_MULTI_PARTITION == ENABLED)
00140 u16_tmp=0;
00141 #endif
00142 for( u8_tmp=0 ; u8_tmp!=4 ; u8_tmp++ )
00143 {
00144
00145 if ( ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+0] == FS_PART_BOOTABLE )||
00146 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+0] == FS_PART_NO_BOOTABLE ) )
00147 && ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT12 )||
00148 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_INF32M )||
00149 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_SUP32M )||
00150 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_SUP32M_BIS)||
00151 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT32 )||
00152 (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT32_BIS )) )
00153 {
00154
00155 #if (FS_MULTI_PARTITION == ENABLED)
00156 if( u16_tmp == fs_g_nav.u8_partition )
00157 break;
00158 u16_tmp++;
00159 #else
00160 break;
00161 #endif
00162 }
00163 }
00164 if( u8_tmp != 4 )
00165 {
00166
00167 LSB0(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+8];
00168 LSB1(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+9];
00169 LSB2(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+10];
00170 LSB3(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+11];
00171 fs_gu32_addrsector *= mem_sector_size( fs_g_nav.u8_lun );
00172 continue;
00173 }
00174
00175
00176 #if (FS_MULTI_PARTITION == ENABLED)
00177
00178 if ( 0 != fs_g_nav.u8_partition )
00179 {
00180 fs_g_status = FS_ERR_NO_PART;
00181 return FALSE;
00182 }
00183 #endif
00184 }
00185
00186
00187 if ( (fs_g_sector[0] == 0xEB) &&
00188 (fs_g_sector[2] == 0x90) &&
00189 ((fs_g_sector[21] & 0xF0) == 0xF0) )
00190 {
00191 break;
00192 }
00193
00194 fs_g_status = FS_ERR_NO_PART;
00195 return FALSE;
00196 }
00197
00198 fs_g_status = FS_ERR_NO_SUPPORT_PART;
00199
00200
00201
00202 u8_sector_size = HIGH_16_BPB_BytsPerSec/2;
00203
00204
00205 fs_g_nav.u8_BPB_SecPerClus = U8_BPB_SecPerClus * u8_sector_size;
00206
00207
00208
00209 LSB( u16_tmp ) = LOW_16_BPB_FATSz16;
00210 MSB( u16_tmp ) = HIGH_16_BPB_FATSz16;
00211 if ( 0==u16_tmp )
00212 {
00213 LSB( u16_tmp ) = LOW0_32_BPB_FATSz32;
00214 MSB( u16_tmp ) = LOW1_32_BPB_FATSz32;
00215
00216 if( (0 != LOW2_32_BPB_FATSz32 )
00217 || (0 != LOW3_32_BPB_FATSz32 ) )
00218 {
00219 return FALSE;
00220 }
00221 }
00222 fs_g_nav.u16_fat_size = u16_tmp * u8_sector_size;
00223
00224
00225 if ( (0==LOW_16_BPB_TotSec16) && (0==HIGH_16_BPB_TotSec16) )
00226 {
00227 LSB0( u32_tmp ) = LOW0_32_BPB_TotSec32;
00228 LSB1( u32_tmp ) = LOW1_32_BPB_TotSec32;
00229 LSB2( u32_tmp ) = LOW2_32_BPB_TotSec32;
00230 LSB3( u32_tmp ) = LOW3_32_BPB_TotSec32;
00231 }
00232 else
00233 {
00234 LSB0( u32_tmp ) = LOW_16_BPB_TotSec16;
00235 LSB1( u32_tmp ) = HIGH_16_BPB_TotSec16;
00236 LSB2( u32_tmp ) = 0;
00237 LSB3( u32_tmp ) = 0;
00238 }
00239 u32_tmp *= u8_sector_size;
00240
00241
00242 fs_g_nav.rootdir.seg.u16_pos = FS_NB_FAT * fs_g_nav.u16_fat_size;
00243
00244
00245 LSB( u16_tmp ) = LOW_16_BPB_RootEntCnt;
00246 MSB( u16_tmp ) = HIGH_16_BPB_RootEntCnt;
00247 fs_g_nav.rootdir.seg.u16_size = ((u16_tmp * FS_SIZE_FILE_ENTRY) + ((FS_512B*u8_sector_size)-1)) / (FS_512B*u8_sector_size);
00248 fs_g_nav.rootdir.seg.u16_size *= u8_sector_size;
00249
00250
00251 LSB( u16_tmp ) = LOW_16_BPB_ResvSecCnt;
00252 MSB( u16_tmp ) = HIGH_16_BPB_ResvSecCnt;
00253
00254 fs_g_nav.u16_offset_FSInfo = (u16_tmp-LOW_16_BPB_FSInfo)*u8_sector_size;
00255 u16_tmp *= u8_sector_size;
00256
00257
00258 fs_g_nav.u32_ptr_fat = fs_gu32_addrsector + u16_tmp;
00259
00260
00261 fs_g_nav.u32_offset_data = (FS_NB_FAT * (U32)fs_g_nav.u16_fat_size) + (U32)fs_g_nav.rootdir.seg.u16_size;
00262
00263
00264 u32_tmp -= ((U32)u16_tmp + fs_g_nav.u32_offset_data);
00265
00266
00267
00268 for( u8_tmp = fs_g_nav.u8_BPB_SecPerClus; u8_tmp!=1 ; u8_tmp >>= 1 )
00269 {
00270 u32_tmp >>= 1;
00271 }
00272 fs_g_nav.u32_CountofCluster = u32_tmp+2;
00273
00274
00275 if (u32_tmp < FS_FAT12_MAX_CLUSTERS)
00276 {
00277
00278 #if (FS_FAT_12 == DISABLED)
00279 return FALSE;
00280 #endif
00281 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_12;
00282 } else {
00283 if (u32_tmp < FS_FAT16_MAX_CLUSTERS)
00284 {
00285
00286 #if (FS_FAT_16 == DISABLED)
00287 return FS_NO_SUPPORT_PART;
00288 #endif
00289 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_16;
00290 } else {
00291
00292 #if (FS_FAT_32 == DISABLED)
00293 return FALSE;
00294 #endif
00295 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_32;
00296
00297
00298 LSB0( fs_g_nav.rootdir.u32_cluster ) = LOW0_32_BPB_RootClus;
00299 LSB1( fs_g_nav.rootdir.u32_cluster ) = LOW1_32_BPB_RootClus;
00300 LSB2( fs_g_nav.rootdir.u32_cluster ) = LOW2_32_BPB_RootClus;
00301 LSB3( fs_g_nav.rootdir.u32_cluster ) = LOW3_32_BPB_RootClus;
00302 }
00303 }
00304
00305 return TRUE;
00306 }
00307
00308
00309
00310 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) )
00311
00313 _MEM_TYPE_SLOW_ U32 fs_s_u32_size_partition;
00314
00335 Bool fat_format( U8 u8_fat_type )
00336 {
00337 Bool b_MBR;
00338 #if (FS_MULTI_PARTITION == ENABLED)
00339 #error NOT SUPPORTED
00340 fs_g_nav.u8_partition = 0;
00341 #endif
00342
00343
00344
00345 mem_read_capacity( fs_g_nav.u8_lun , &fs_s_u32_size_partition );
00346
00347 if( u8_fat_type & FS_FORMAT_NOMBR_FLAG )
00348 {
00349 b_MBR = FALSE;
00350 u8_fat_type &= ~FS_FORMAT_NOMBR_FLAG;
00351
00352 fs_s_u32_size_partition++;
00353 }else{
00354 b_MBR = TRUE;
00355
00356 }
00357
00358
00359 if( !fat_select_filesystem( u8_fat_type , b_MBR ))
00360 return FALSE;
00361
00362
00363 if( b_MBR )
00364 if( !fat_write_MBR())
00365 return FALSE;
00366
00367
00368 if( !fat_write_PBR( b_MBR ))
00369 return FALSE;
00370
00371
00372
00373 if( !fat_clean_zone( b_MBR ))
00374 return FALSE;
00375
00376
00377 if( !fat_initialize_fat())
00378 return FALSE;
00379
00380 return fat_cache_flush();
00381 }
00382
00383
00384
00386 typedef struct st_fs_format_table {
00387 U32 u32_disk_size;
00388 U8 u8_SecPerClusVal;
00389 } Fs_format_table;
00390
00391
00393 _CONST_TYPE_ Fs_format_table TableFAT12[] = {
00394 { 4096, 1},
00395 { 8192, 2},
00396 { 16384, 4},
00397 { 32680, 8},
00398 };
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00412 _CONST_TYPE_ Fs_format_table TableFAT16[] = {
00413 { 8400, 0},
00414 { 32680, 2},
00415 { 262144, 4},
00416 { 524288, 8},
00417 { 1048576, 16},
00418
00419 { 2097152, 32},
00420 { 4194304, 64},
00421 { 0xFFFFFFFF, 0}
00422 };
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00438 _CONST_TYPE_ Fs_format_table TableFAT32[] = {
00439 { 66600, 0},
00440 { 532480, 1},
00441 { 16777216, 8},
00442 { 33554432, 16},
00443 { 67108864, 32},
00444 { 0xFFFFFFFF, 64}
00445 };
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00462
00478 Bool fat_select_filesystem( U8 u8_fat_type , Bool b_MBR )
00479 {
00480 U8 u8_i;
00481 U8 u8_tmp = 0;
00482 U16 u16_tmp, u16_tmp2;
00483 Fs_format_table _CONST_TYPE_ *ptr_table;
00484
00485 if( (FS_FORMAT_FAT != u8_fat_type )
00486 && (FS_FORMAT_FAT32 != u8_fat_type ) )
00487 {
00488
00489 if( (((U32)512*1024*1024)/FS_512B) >= fs_s_u32_size_partition )
00490 {
00491 u8_fat_type = FS_FORMAT_FAT;
00492 } else {
00493 u8_fat_type = FS_FORMAT_FAT32;
00494 }
00495 }
00496
00497
00498 if(FS_FORMAT_FAT == u8_fat_type )
00499 {
00500 if( (((U32)15*1024*1024)/FS_512B) >= fs_s_u32_size_partition )
00501 {
00502
00503 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_12;
00504 u8_i = sizeof(TableFAT12);
00505 ptr_table = TableFAT12;
00506 }else{
00507
00508 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_16;
00509 u8_i = sizeof(TableFAT16);
00510 ptr_table = TableFAT16;
00511 }
00512 }
00513 else
00514 {
00515 fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_32;
00516 u8_i = sizeof(TableFAT32);
00517 ptr_table = TableFAT32;
00518 }
00519 for( ; u8_i!=0 ; u8_i-- )
00520 {
00521 if( fs_s_u32_size_partition <= ptr_table->u32_disk_size )
00522 {
00523
00524 fs_g_nav.u8_BPB_SecPerClus = ptr_table->u8_SecPerClusVal;
00525 break;
00526 }
00527 ptr_table++;
00528 }
00529 if(0 == fs_g_nav.u8_BPB_SecPerClus)
00530 {
00531 fs_g_status = FS_ERR_BAD_SIZE_FAT;
00532 return FALSE;
00533 }
00534
00535
00536
00537 if( b_MBR )
00538 fs_g_nav.u32_ptr_fat = 1;
00539 else
00540 fs_g_nav.u32_ptr_fat = 0;
00541
00542 if( Is_fat12 )
00543 {
00544 fs_g_nav.u32_ptr_fat += 1;
00545
00546 fs_g_nav.u16_fat_size=1;
00547 while(1)
00548 {
00549 if( 12 < fs_g_nav.u16_fat_size)
00550 {
00551 fs_g_status = FS_ERR_BAD_SIZE_FAT;
00552 return FALSE;
00553 }
00554
00555
00556 u16_tmp = ((fs_s_u32_size_partition -1 - (fs_g_nav.u16_fat_size *2)) / fs_g_nav.u8_BPB_SecPerClus)+2;
00557 u16_tmp2 = (fs_g_nav.u16_fat_size *FS_512B *2) / 3;
00558 if( u16_tmp <= u16_tmp2 )
00559 break;
00560
00561 fs_g_nav.u16_fat_size++;
00562 }
00563 }
00564 else
00565 {
00566 if( Is_fat32 )
00567 {
00568 fs_g_nav.u32_ptr_fat += 32;
00569
00570
00571
00572
00573
00574 u8_tmp = 32;
00575
00576
00577
00578
00579 u16_tmp = (((U16)fs_g_nav.u8_BPB_SecPerClus)<<7) + 1;
00580
00581
00582 }
00583 if( Is_fat16 )
00584 {
00585 fs_g_nav.u32_ptr_fat += 1;
00586
00587
00588
00589
00590
00591
00592 u8_tmp = 33;
00593
00594
00595
00596 MSB(u16_tmp) = fs_g_nav.u8_BPB_SecPerClus;
00597 LSB(u16_tmp) = 2;
00598 }
00599
00600 fs_g_nav.u16_fat_size = (fs_s_u32_size_partition -u8_tmp +u16_tmp -1) / u16_tmp;
00601 }
00602
00603 return TRUE;
00604 }
00605
00606
00612 Bool fat_write_MBR( void )
00613 {
00614 U8 u8_i = 0;
00615
00616
00617 fs_gu32_addrsector = 0;
00618 if( !fat_cache_read_sector( FALSE ))
00619 return FALSE;
00620 fat_cache_mark_sector_as_dirty();
00621 fat_cache_clear();
00622
00623
00624 fs_g_sector[510] = FS_BR_SIGNATURE_LOW;
00625 fs_g_sector[511] = FS_BR_SIGNATURE_HIGH;
00626
00627
00628 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +0] = FS_PART_NO_BOOTABLE;
00629
00630
00631 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +2] = 2;
00632
00633
00634
00635 if( Is_fat32 )
00636 {
00637 u8_i = FS_PART_TYPE_FAT32;
00638 }
00639 if( Is_fat16 )
00640 {
00641 if( fs_s_u32_size_partition < (32L*1024*(1024/FS_512B)) )
00642 {
00643 u8_i = FS_PART_TYPE_FAT16_INF32M;
00644 }else{
00645 u8_i = FS_PART_TYPE_FAT16_SUP32M;
00646 }
00647 }
00648 if( Is_fat12 )
00649 {
00650 u8_i = FS_PART_TYPE_FAT12;
00651 }
00652
00653 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +4] = u8_i;
00654
00655
00656 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +5] = (LSB1(fs_s_u32_size_partition)<<2) + (LSB0(fs_s_u32_size_partition)>>6);
00657
00658 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +6] = (LSB1(fs_s_u32_size_partition)&0xC0) + (LSB0(fs_s_u32_size_partition)&0x3F);
00659 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +7] = LSB2(fs_s_u32_size_partition);
00660
00661
00662 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+ 8] = 0x01;
00663
00664
00665
00666
00667 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+12] = LSB0(fs_s_u32_size_partition);
00668 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+13] = LSB1(fs_s_u32_size_partition);
00669 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+14] = LSB2(fs_s_u32_size_partition);
00670 fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+15] = LSB3(fs_s_u32_size_partition);
00671
00672 return TRUE;
00673 }
00674
00676 _CONST_TYPE_ U8 const_header_pbr[] = {
00677 0xEB,0,0x90,
00678 'M','S','W','I','N','4','.','1',
00679 FS_512B & 0xFF, FS_512B >>8,
00680 0,
00681 0,0,
00682 2,
00683 0,0,
00684 0,0,
00685 FS_PART_NO_REMOVE_MEDIA,
00686 0,0,
00687 0x3F,0,
00688 0,0,
00689 1
00690 };
00691 _CONST_TYPE_ U8 const_tail_pbr[] = {
00692 FS_PART_HARD_DISK,
00693 0,
00694 FS_BOOT_SIGN,
00695 0,0,0,0,
00696 'N','O',' ','N','A','M','E',' ',' ',' ',' ',
00697 'F','A','T',' ',' ',' ',' ',' ',
00698 };
00699
00700
00703 _CONST_TYPE_ U8 const_FSI_LeadSig[] = {
00704 0x52,0x52,0x61,0x41
00705 };
00706 _CONST_TYPE_ U8 const_FSI_StrucSig[] = {
00707 0x72,0x72,0x41,0x61
00708 };
00710
00711
00719 Bool fat_write_PBR( Bool b_MBR )
00720 {
00721 U16 u16_tmp;
00722
00723
00724 if( b_MBR )
00725 fs_gu32_addrsector = 1;
00726 else
00727 fs_gu32_addrsector = 0;
00728
00729 if( !fat_cache_read_sector( FALSE ))
00730 return FALSE;
00731 fat_cache_mark_sector_as_dirty();
00732 fat_cache_clear();
00733
00734
00735 memcpy_code2ram( fs_g_sector, const_header_pbr , sizeof(const_header_pbr) );
00736
00737 fs_g_sector[510] = FS_BR_SIGNATURE_LOW;
00738 fs_g_sector[511] = FS_BR_SIGNATURE_HIGH;
00739
00740
00741 fs_g_sector[13] = fs_g_nav.u8_BPB_SecPerClus;
00742
00743 fs_g_sector[26] = (LSB1(fs_s_u32_size_partition)<<2) + (LSB0(fs_s_u32_size_partition)>>6);
00744
00745
00746
00747
00748
00749
00750 if( Is_fat32 )
00751 {
00752 memcpy_code2ram( &fs_g_sector[64], const_tail_pbr, sizeof(const_tail_pbr) );
00753 }else{
00754 memcpy_code2ram( &fs_g_sector[36], const_tail_pbr, sizeof(const_tail_pbr) );
00755 }
00756
00757 u16_tmp = fs_g_nav.u16_fat_size;
00758 if( Is_fat32 )
00759 {
00760
00761 fs_g_sector[14] = 32;
00762
00763
00764 LOW0_32_BPB_FATSz32 = LSB(u16_tmp);
00765 LOW1_32_BPB_FATSz32 = MSB(u16_tmp);
00766
00767
00768
00769 fs_g_sector[44]= 2;
00770
00771
00772
00773
00774
00775
00776 fs_g_sector[85]='3';
00777 fs_g_sector[86]='2';
00778 }
00779 else
00780 {
00781
00782
00783 fs_g_sector[14] = 1;
00784
00785
00786 fs_g_sector[18] = 512>>8;
00787
00788
00789 LOW_16_BPB_FATSz16 = LSB(u16_tmp);
00790 HIGH_16_BPB_FATSz16 = MSB(u16_tmp);
00791
00792 fs_g_sector[57]='1';
00793 if( Is_fat12 )
00794 {
00795 fs_g_sector[58]='2';
00796 }else{
00797 fs_g_sector[58]='6';
00798 }
00799 }
00800
00801
00802 if( ( Is_fat32 )
00803 || ((0x10000-1) <= fs_s_u32_size_partition) )
00804 {
00805
00806
00807 fs_g_sector[32] = LSB0(fs_s_u32_size_partition);
00808 fs_g_sector[33] = LSB1(fs_s_u32_size_partition);
00809 fs_g_sector[34] = LSB2(fs_s_u32_size_partition);
00810 fs_g_sector[35] = LSB3(fs_s_u32_size_partition);
00811 }
00812 else
00813 {
00814
00815 fs_g_sector[19] = LSB0(fs_s_u32_size_partition);
00816 fs_g_sector[20] = LSB1(fs_s_u32_size_partition);
00817 }
00818
00819 if( Is_fat32 )
00820 {
00821
00822 if( !fat_write_fat32_FSInfo( 0xFFFFFFFF ))
00823 return FALSE;
00824 }
00825 return TRUE;
00826 }
00828
00829 #ifdef FS_FAT_32
00840 Bool fat_write_fat32_FSInfo( U32 u32_nb_free_cluster )
00841 {
00842
00843 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat - fs_g_nav.u16_offset_FSInfo;
00844
00845 if( !fat_cache_read_sector( FALSE ))
00846 return FALSE;
00847 fat_cache_mark_sector_as_dirty();
00848 fat_cache_clear();
00849
00850
00851
00852 memcpy_code2ram( &fs_g_sector[0], const_FSI_LeadSig, sizeof(const_FSI_LeadSig) );
00853
00854
00855 memcpy_code2ram( &fs_g_sector[484], const_FSI_StrucSig, sizeof(const_FSI_StrucSig) );
00856
00857 fs_g_sector[488] = LSB0(u32_nb_free_cluster);
00858 fs_g_sector[489] = LSB1(u32_nb_free_cluster);
00859 fs_g_sector[490] = LSB2(u32_nb_free_cluster);
00860 fs_g_sector[491] = LSB3(u32_nb_free_cluster);
00861
00862 memset( &fs_g_sector[492] , 0xFF , 4 );
00863
00864
00865 fs_g_sector[510] = FS_BR_SIGNATURE_LOW;
00866 fs_g_sector[511] = FS_BR_SIGNATURE_HIGH;
00867 return TRUE;
00868 }
00869
00870
00875 U32 fat_read_fat32_FSInfo( void )
00876 {
00877 U32 u32_nb_free_cluster;
00878
00879
00880 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat - fs_g_nav.u16_offset_FSInfo;
00881 if( !fat_cache_read_sector( TRUE ))
00882 return 0xFFFFFFFF;
00883
00884
00885
00886 if( fs_g_sector[510] != FS_BR_SIGNATURE_LOW )
00887 return 0xFFFFFFFF;
00888 if( fs_g_sector[511] != FS_BR_SIGNATURE_HIGH)
00889 return 0xFFFFFFFF;
00890
00891 if( 0 != memcmp_code2ram( &fs_g_sector[0], const_FSI_LeadSig, sizeof(const_FSI_LeadSig) ))
00892 return 0xFFFFFFFF;
00893
00894
00895 if( 0 != memcmp_code2ram( &fs_g_sector[484], const_FSI_StrucSig, sizeof(const_FSI_StrucSig)) )
00896 return 0xFFFFFFFF;
00897
00898
00899
00900 LSB0(u32_nb_free_cluster) = fs_g_sector[488];
00901 LSB1(u32_nb_free_cluster) = fs_g_sector[489];
00902 LSB2(u32_nb_free_cluster) = fs_g_sector[490];
00903 LSB3(u32_nb_free_cluster) = fs_g_sector[491];
00904 return u32_nb_free_cluster;
00905 }
00906 #endif // FS_FAT_32
00907
00908
00916 Bool fat_clean_zone( Bool b_MBR )
00917 {
00918 U16 u16_nb_sector_clean;
00919
00920
00921 if( !fat_cache_flush())
00922 return FALSE;
00923 fat_cache_clear();
00924
00925
00926
00927 if( b_MBR )
00928 {
00929 fs_gu32_addrsector = 2;
00930 }else{
00931 fs_gu32_addrsector = 1;
00932 }
00933
00934
00935 if( Is_fat32 )
00936 {
00937 fs_gu32_addrsector++;
00938
00939 u16_nb_sector_clean = fs_g_nav.u8_BPB_SecPerClus + 30;
00940 }
00941 else
00942 {
00943
00944 u16_nb_sector_clean = 32;
00945 }
00946 u16_nb_sector_clean += (fs_g_nav.u16_fat_size*2);
00947
00948
00949 for( ; u16_nb_sector_clean!=0; u16_nb_sector_clean-- )
00950 {
00951 if( !fat_cache_read_sector( FALSE ))
00952 return FALSE;
00953 fat_cache_mark_sector_as_dirty();
00954 fs_gu32_addrsector++;
00955 }
00956 return TRUE;
00957 }
00958
00959
00962 _CONST_TYPE_ U8 const_header_fat12[] = {
00963 0xF8,0xFF,0xFF
00964 };
00965 _CONST_TYPE_ U8 const_header_fat16[] = {
00966 0xF8,0xFF,0xFF,0xFF
00967 };
00968 _CONST_TYPE_ U8 const_header_fat32[] = {
00969 0xF8,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0x0F
00970 ,0xFF,0xFF,0xFF,0x0F
00971 };
00973
00974
00980 Bool fat_initialize_fat( void )
00981 {
00982
00983 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat;
00984 if( !fat_cache_read_sector( FALSE ))
00985 return FALSE;
00986 fat_cache_mark_sector_as_dirty();
00987
00988 if( Is_fat32 )
00989 {
00990 memcpy_code2ram( fs_g_sector, const_header_fat32, sizeof(const_header_fat32) );
00991 }
00992 if( Is_fat16 )
00993 {
00994 memcpy_code2ram( fs_g_sector, const_header_fat16, sizeof(const_header_fat16) );
00995 }
00996 if( Is_fat12 )
00997 {
00998 memcpy_code2ram( fs_g_sector, const_header_fat12, sizeof(const_header_fat12) );
00999 }
01000
01001
01002 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + fs_g_nav.u16_fat_size;
01003 if( !fat_cache_read_sector( FALSE ))
01004 return FALSE;
01005 fat_cache_mark_sector_as_dirty();
01006 return TRUE;
01007 }
01008
01009
01018 Bool fat_serialnumber( Bool b_action , U8 _MEM_TYPE_SLOW_ *a_u8_sn )
01019 {
01020
01021 if ( Is_fat12 || Is_fat16 )
01022 {
01023 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat-1;
01024 }
01025 else
01026 {
01027 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat-32;
01028 }
01029
01030 if( !fat_cache_read_sector( TRUE ))
01031 return FALSE;
01032
01033
01034 if( b_action == FS_SN_READ )
01035 {
01036
01037 a_u8_sn[0] = fs_g_sector[42];
01038 a_u8_sn[1] = fs_g_sector[41];
01039 a_u8_sn[2] = fs_g_sector[40];
01040 a_u8_sn[3] = fs_g_sector[39];
01041 return TRUE;
01042 }else{
01043
01044 fs_g_sector[42] = a_u8_sn[0];
01045 fs_g_sector[41] = a_u8_sn[1];
01046 fs_g_sector[40] = a_u8_sn[2];
01047 fs_g_sector[39] = a_u8_sn[3];
01048 fat_cache_mark_sector_as_dirty();
01049 return fat_cache_flush();
01050 }
01051 }
01052
01053
01062 Bool fat_entry_label( Bool b_action , FS_STRING sz_label )
01063 {
01064 PTR_CACHE ptr_entry;
01065 U8 u8_pos_name;
01066 U8 u8_char;
01067
01068 ptr_entry = fat_get_ptr_entry();
01069
01070 if( FS_LABEL_READ == b_action)
01071 {
01072 if( FS_ENTRY_END == ptr_entry[0] )
01073 {
01074 fs_g_status = FS_ERR_ENTRY_EMPTY;
01075 return FALSE;
01076 }
01077 if( FS_ATTR_VOLUME_ID != ptr_entry[11])
01078 {
01079 fs_g_status = FS_ERR_ENTRY_BAD;
01080 return FALSE;
01081 }
01082 if( NULL == sz_label )
01083 return TRUE;
01084 for( u8_pos_name=0; u8_pos_name<11; u8_pos_name++ )
01085 {
01086 u8_char = *ptr_entry;
01087 if( 0x20 == u8_char )
01088 u8_char = 0;
01089 *sz_label = u8_char;
01090 if( 0 == u8_char )
01091 return TRUE;
01092 ptr_entry++;
01093 sz_label++;
01094 }
01095 *sz_label = 0;
01096 return TRUE;
01097 }
01098
01099 if( FS_LABEL_WRITE == b_action)
01100 {
01101
01102 if( FS_ENTRY_END != ptr_entry[0] )
01103 {
01104 if( FS_ATTR_VOLUME_ID != ptr_entry[11])
01105 {
01106 fs_g_status = FS_ERR_ENTRY_BAD;
01107 return FALSE;
01108 }
01109 }
01110 if( 0 == *sz_label )
01111 {
01112 fs_g_status = FS_ERR_NAME_INCORRECT;
01113 return FALSE;
01114 }
01115 ptr_entry[11] = FS_ATTR_VOLUME_ID;
01116 for( u8_pos_name=0; u8_pos_name<11; u8_pos_name++ )
01117 {
01118 u8_char = *sz_label;
01119 if( ('a'<=u8_char) && (u8_char<='z') )
01120 {
01121 u8_char -= ('a'-'A');
01122 }
01123 if( 0 == u8_char )
01124 {
01125 u8_char = 0x20;
01126 }
01127 *ptr_entry = u8_char;
01128 ptr_entry++;
01129 if( 0x20 == u8_char )
01130 continue;
01131 sz_label++;
01132 }
01133 fat_cache_mark_sector_as_dirty();
01134 return fat_cache_flush();
01135 }
01136 return FALSE;
01137 }
01138 #endif // FS_LEVEL_FEATURES
01139
01140
01141 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET))
01155 Bool fat_initialize_dir( void )
01156 {
01157 U8 u8_i;
01158
01159
01160 if( !fat_clear_cluster())
01161 return FALSE;
01162 fat_cache_mark_sector_as_dirty();
01163
01164
01165
01166 fs_g_sector[0]='.';
01167 for( u8_i=1 ; u8_i<11 ; u8_i++ )
01168 fs_g_sector[u8_i]=' ';
01169 fs_g_sector[11]=FS_ATTR_DIRECTORY;
01170 fs_g_sector[26]= LSB0( fs_g_nav_entry.u32_cluster );
01171 fs_g_sector[27]= LSB1( fs_g_nav_entry.u32_cluster );
01172 fs_g_sector[20]= LSB2( fs_g_nav_entry.u32_cluster );
01173 fs_g_sector[21]= LSB3( fs_g_nav_entry.u32_cluster );
01174
01175 fs_g_sector[FS_SIZE_FILE_ENTRY+0]='.';
01176 fs_g_sector[FS_SIZE_FILE_ENTRY+1]='.';
01177 for( u8_i=2 ; u8_i<11 ; u8_i++ )
01178 fs_g_sector[FS_SIZE_FILE_ENTRY+u8_i]=' ';
01179 fs_g_sector[FS_SIZE_FILE_ENTRY+11]=FS_ATTR_DIRECTORY;
01180 fs_g_sector[FS_SIZE_FILE_ENTRY+26]= LSB0( fs_g_nav.u32_cluster_sel_dir );
01181 fs_g_sector[FS_SIZE_FILE_ENTRY+27]= LSB1( fs_g_nav.u32_cluster_sel_dir );
01182 fs_g_sector[FS_SIZE_FILE_ENTRY+20]= LSB2( fs_g_nav.u32_cluster_sel_dir );
01183 fs_g_sector[FS_SIZE_FILE_ENTRY+21]= LSB3( fs_g_nav.u32_cluster_sel_dir );
01184
01185 return TRUE;
01186 }
01187 #endif // FS_LEVEL_FEATURES
01188
01189
01196 void fat_get_date( FS_STRING sz_date , Bool type_date )
01197 {
01198 PTR_CACHE ptr_entry;
01199
01200 ptr_entry = fat_get_ptr_entry();
01201 if( FS_DATE_LAST_WRITE == type_date )
01202 {
01203 fat_translatedate_number_to_ascii( sz_date , &ptr_entry[22] , FALSE );
01204 }
01205 else
01206 {
01207 fat_translatedate_number_to_ascii( sz_date , &ptr_entry[13] , TRUE );
01208 }
01209 }
01210
01211
01219 void fat_translatedate_number_to_ascii( FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms )
01220 {
01221 FS_STRING ptr_string_date;
01222 U8 u8_i;
01223 U8 msb_date, lsb_date, msb_time, lsb_time, u8_ms = 0;
01224
01225
01226 if( enable_ms )
01227 {
01228 u8_ms = *ptr_date;
01229 ptr_date++;
01230 }
01231 lsb_time = *ptr_date;
01232 ptr_date++;
01233 msb_time = *ptr_date;
01234 ptr_date++;
01235 lsb_date = *ptr_date;
01236 ptr_date++;
01237 msb_date = *ptr_date;
01238
01239
01240 ptr_string_date = sz_date;
01241 *ptr_string_date = '1';
01242 ptr_string_date++;
01243 *ptr_string_date = '9';
01244 ptr_string_date++;
01245 *ptr_string_date = '8';
01246 ptr_string_date++;
01247 for( u8_i=(15-2) ; u8_i!=0 ; u8_i-- )
01248 {
01249 *ptr_string_date = '0';
01250 ptr_string_date++;
01251 }
01252
01253
01254 fat_translate_number_to_ascii( sz_date, 4 , msb_date>>1 );
01255
01256
01257 fat_translate_number_to_ascii( &sz_date[4] , 2 , ((msb_date & 0x01)<<3) + (lsb_date>>5) );
01258
01259
01260 fat_translate_number_to_ascii( &sz_date[6] , 2 , lsb_date & 0x1F );
01261
01262
01263 fat_translate_number_to_ascii( &sz_date[8] , 2 , msb_time >> (11-8) );
01264
01265
01266 fat_translate_number_to_ascii( &sz_date[10] , 2 , ((msb_time & 0x07)<<3) + (lsb_time>>5) );
01267
01268
01269 fat_translate_number_to_ascii( &sz_date[12] , 2 , (lsb_time & 0x1F)<<1 );
01270 if( 99 < u8_ms )
01271 {
01272
01273 fat_translate_number_to_ascii( &sz_date[12] , 2 , 1 );
01274 u8_ms -= 100;
01275 }
01276
01277
01278 fat_translate_number_to_ascii( &sz_date[14] , 2 , u8_ms );
01279 }
01280
01281
01292 void fat_translate_number_to_ascii( FS_STRING sz_ascii_number, U8 u8_size_number_ascii, U8 u8_nb_increment )
01293 {
01294 FS_STRING ptr_sz_ascii_number;
01295
01296 u8_size_number_ascii--;
01297
01298 for( ; u8_nb_increment != 0 ; u8_nb_increment-- )
01299 {
01300 ptr_sz_ascii_number = sz_ascii_number + u8_size_number_ascii;
01301 ptr_sz_ascii_number[0]++;
01302 while( ('9'+1) == *ptr_sz_ascii_number )
01303 {
01304 *ptr_sz_ascii_number = '0';
01305 ptr_sz_ascii_number--;
01306 ptr_sz_ascii_number[0]++;
01307 }
01308 }
01309 }
01310
01311
01312 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET))
01323 void fat_set_date( const FS_STRING sz_date , Bool type_date )
01324 {
01325 PTR_CACHE ptr_entry;
01326
01327 fat_cache_mark_sector_as_dirty();
01328 ptr_entry = fat_get_ptr_entry();
01329
01330 if( FS_DATE_LAST_WRITE == type_date )
01331 {
01332 fat_translatedate_ascii_to_number( sz_date , &ptr_entry[22] , FALSE );
01333 }
01334 else
01335 {
01336 fat_translatedate_ascii_to_number( sz_date , &ptr_entry[13] , TRUE );
01337 }
01338 }
01339
01340
01352 void fat_translatedate_ascii_to_number( const FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms )
01353 {
01354 U8 u8_tmp;
01355 U8 msb_date, lsb_date, msb_time, lsb_time;
01356
01357
01358 msb_date = ((U8)(fat_translate_ascii_to_number( sz_date , 4 )-1980))<<1;
01359
01360
01361 u8_tmp = (U8)fat_translate_ascii_to_number( &sz_date[4] , 2 );
01362 msb_date |= (u8_tmp >> 3);
01363 lsb_date = (u8_tmp << 5);
01364
01365
01366 lsb_date |= (U8)fat_translate_ascii_to_number( &sz_date[6] , 2 );
01367
01368
01369 msb_time = ((U8)fat_translate_ascii_to_number( &sz_date[8] , 2 )) << (11-8);
01370
01371
01372 u8_tmp = (U8)fat_translate_ascii_to_number( &sz_date[10] , 2 );
01373 msb_time |= (u8_tmp >> 3);
01374 lsb_time = (u8_tmp << 5);
01375
01376
01377 u8_tmp = (U8)fat_translate_ascii_to_number( &sz_date[12] , 2 );
01378 lsb_time |= (u8_tmp >> 1);
01379
01380
01381 if( enable_ms )
01382 {
01383
01384 if( u8_tmp & 0x01 )
01385 {
01386 u8_tmp = 100;
01387 }
01388 else
01389 {
01390 u8_tmp = 0;
01391 }
01392 *ptr_date = u8_tmp + (U8)fat_translate_ascii_to_number( &sz_date[14] , 2 );
01393 ptr_date++;
01394 }
01395
01396
01397 ptr_date[0] = lsb_time;
01398 ptr_date[1] = msb_time;
01399 ptr_date[2] = lsb_date;
01400 ptr_date[3] = msb_date;
01401 }
01402
01403
01415 U16 fat_translate_ascii_to_number( const FS_STRING sz_ascii_number, U8 u8_size_number_ascii )
01416 {
01417 U8 sz_ascii_number_copy[4];
01418 U8 _MEM_TYPE_FAST_ *ptr_sz_ascii_number;
01419 U8 u8_i;
01420 U16 u16_number;
01421
01422 for( u8_i=0; u8_i < u8_size_number_ascii; u8_i++ )
01423 {
01424 sz_ascii_number_copy[u8_i] = sz_ascii_number[u8_i];
01425 }
01426
01427 u16_number=0;
01428
01429 while( 1 )
01430 {
01431
01432 ptr_sz_ascii_number = sz_ascii_number_copy;
01433 for( u8_i = u8_size_number_ascii; u8_i !=0; u8_i-- )
01434 {
01435 if( '0' != *ptr_sz_ascii_number )
01436 {
01437 break;
01438 }
01439 ptr_sz_ascii_number++;
01440 }
01441 if( 0 == u8_i)
01442 return u16_number;
01443
01444
01445 ptr_sz_ascii_number = sz_ascii_number_copy + u8_size_number_ascii -1;
01446 u16_number++;
01447 ptr_sz_ascii_number[0]--;
01448 while( ('0'-1) == ptr_sz_ascii_number[0] )
01449 {
01450 *ptr_sz_ascii_number = '9';
01451 ptr_sz_ascii_number--;
01452 ptr_sz_ascii_number[0]--;
01453 }
01454 }
01455 }
01456 #endif // FS_LEVEL_FEATURES
01457
01458
01459
01460 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
01474 Bool fat_create_entry_file_name( FS_STRING sz_name )
01475 {
01476 U8 u8_i, u8_nb;
01477 U8 u8_crc, u8_nb_entry;
01478
01479
01480 u8_nb_entry = fat_check_name( sz_name );
01481 if( 0 == u8_nb_entry )
01482 return FALSE;
01483
01484
01485 u8_nb = fat_find_short_entry_name( sz_name );
01486 if( 0 == u8_nb )
01487 {
01488 fs_g_status = FS_ERR_FILE_EXIST;
01489 return FALSE;
01490 }
01491
01492
01493 if( !fat_alloc_entry_free( u8_nb_entry ))
01494 return FALSE;
01495
01496
01497
01498 u8_crc = fat_create_short_entry_name( sz_name , 0 , u8_nb, FALSE );
01499 u8_nb_entry--;
01500
01501
01502 for( u8_i=1 ; u8_i<=u8_nb_entry ; u8_i++ )
01503 {
01504
01505 fs_g_nav_fast.u16_entry_pos_sel_file--;
01506 if( !fat_read_dir())
01507 return FALSE;
01508
01509 if( u8_i == u8_nb_entry )
01510 {
01511 u8_i += FS_ENTRY_LFN_LAST;
01512 }
01513 fat_create_long_name_entry( sz_name , u8_crc , u8_i );
01514 sz_name += FS_SIZE_LFN_ENTRY*(Is_unicode? 2 : 1 );
01515 }
01516
01517 fs_g_nav_fast.u16_entry_pos_sel_file += u8_nb_entry;
01518 return TRUE;
01519 }
01520
01521
01532 void fat_create_long_name_entry( FS_STRING sz_name , U8 u8_crc , U8 u8_id )
01533 {
01534 PTR_CACHE ptr_entry;
01535 Bool b_end_of_name = FALSE;
01536
01537 fat_cache_mark_sector_as_dirty();
01538 ptr_entry = fat_get_ptr_entry();
01539 *ptr_entry = u8_id;
01540 ptr_entry++;
01541
01542 for( u8_id=1; u8_id<FS_SIZE_FILE_ENTRY ; u8_id++ , ptr_entry++ )
01543 {
01544
01545 if( 11 == u8_id)
01546 {
01547 *ptr_entry = FS_ATTR_LFN_ENTRY;
01548 continue;
01549 }
01550 if( (12 == u8_id)
01551 || (26 == u8_id)
01552 || (27 == u8_id) )
01553 {
01554
01555
01556 continue;
01557 }
01558 if( 13 == u8_id)
01559 {
01560 *ptr_entry = u8_crc;
01561 continue;
01562 }
01563
01564
01565 if( !b_end_of_name )
01566 {
01567 U16 u16_tmp;
01568 if( Is_unicode )
01569 {
01570 u16_tmp = ((FS_STR_UNICODE)sz_name)[0];
01571 }else{
01572 u16_tmp = sz_name[0];
01573 }
01574 if(('\\' == u16_tmp )
01575 || ('/' == u16_tmp ) )
01576 {
01577 u16_tmp = 0;
01578 }
01579 if( 0 == u16_tmp )
01580 {
01581 b_end_of_name = TRUE;
01582 }
01583 *ptr_entry = LSB(u16_tmp);
01584 ptr_entry++;
01585 *ptr_entry = MSB(u16_tmp);
01586 u8_id++;
01587 sz_name += (Is_unicode? 2 : 1 );
01588 }
01589 else
01590 {
01591 *ptr_entry = 0xFF;
01592 }
01593 }
01594 }
01595
01596
01607 U8 fat_create_short_entry_name( FS_STRING sz_name , FS_STRING short_name , U8 nb , Bool mode )
01608 {
01609 PTR_CACHE ptr_entry = 0;
01610 U8 u8_i, u8_step, character;
01611 U8 crc;
01612 U8 nb_digit;
01613
01614 if( !mode )
01615 {
01616
01617 fat_cache_mark_sector_as_dirty();
01618
01619 ptr_entry = fat_get_ptr_entry();
01620 }
01621
01622
01623 if( nb < 10 ) nb_digit = 1;
01624 else if( nb < 100 ) nb_digit = 2;
01625 else nb_digit = 3;
01626
01627 crc = u8_i = 0;
01628 u8_step = 1;
01629 while( 1 )
01630 {
01631 if( Is_unicode )
01632 {
01633 character = ((FS_STR_UNICODE)sz_name)[0];
01634 }else{
01635 character = sz_name[0];
01636 }
01637
01638 if( 1 == u8_step )
01639 {
01640 if( ((FS_SIZE_SFNAME_WITHOUT_EXT-(1+nb_digit)) == u8_i)
01641 || ('.' == character)
01642 || fat_check_eof_name(character) )
01643 {
01644 u8_step++;
01645 continue;
01646 }
01647 }
01648 if( 8 == u8_step )
01649 {
01650 if( (u8_i == FS_SIZE_SFNAME)
01651 || fat_check_eof_name(character) )
01652 {
01653 u8_step++;
01654 continue;
01655 }
01656 }
01657 if( (1==u8_step) || (8==u8_step) )
01658 {
01659 character = fat_translate_char_shortname( character );
01660 sz_name += (Is_unicode? 2 : 1 );
01661 if( 0 == character )
01662 {
01663 continue;
01664 }
01665 }
01666 if( 7 == u8_step )
01667 {
01668 if( ('.' == character)
01669 || fat_check_eof_name(character) )
01670 {
01671 u8_step++;
01672 } else {
01673 sz_name += (Is_unicode? 2 : 1 );
01674 }
01675 continue;
01676 }
01677 if( 6 == u8_step )
01678 {
01679 if( u8_i == FS_SIZE_SFNAME_WITHOUT_EXT )
01680 {
01681 u8_step++;
01682 continue;
01683 }
01684 character = ' ';
01685 }
01686 if( 9 == u8_step )
01687 {
01688 if( u8_i == FS_SIZE_SFNAME )
01689 {
01690 break;
01691 }
01692 character = ' ';
01693 }
01694 if( 5 == u8_step )
01695 {
01696 character = '0'+(nb%10);
01697 u8_step++;
01698 }
01699 if( 4 == u8_step )
01700 {
01701 character = '0'+((nb%100)/10);
01702 u8_step++;
01703 }
01704 if( 3 == u8_step )
01705 {
01706 character = '0'+(nb/100);
01707 u8_step++;
01708 }
01709 if( 2 == u8_step )
01710 {
01711 character = '~';
01712 u8_step+=(4-nb_digit);
01713 }
01714
01715 if( mode )
01716 {
01717
01718 *short_name = character;
01719 short_name++;
01720 }else{
01721
01722 *ptr_entry = character;
01723 ptr_entry++;
01724 }
01725 u8_i++;
01726
01727
01728 crc = (crc >> 1) + ((crc & 1) << 7);
01729 crc += character;
01730 }
01731 return crc;
01732 }
01733
01734
01742 U8 fat_find_short_entry_name( FS_STRING sz_name )
01743 {
01744 char _MEM_TYPE_SLOW_ short_name[11];
01745 U8 u8_nb;
01746
01747 u8_nb = 0;
01748 while(1)
01749 {
01750 if( 0xFF == u8_nb )
01751 return 0;
01752
01753 u8_nb++;
01754 fat_create_short_entry_name( sz_name , short_name , u8_nb , TRUE );
01755 fs_g_nav_fast.u16_entry_pos_sel_file = 0;
01756
01757 while(1)
01758 {
01759 if ( !fat_read_dir())
01760 {
01761 if( FS_ERR_OUT_LIST == fs_g_status )
01762 return u8_nb;
01763 return 0;
01764 }
01765 if( fat_entry_shortname_compare( short_name ) )
01766 break;
01767 if( FS_ERR_ENTRY_EMPTY == fs_g_status )
01768 return u8_nb;
01769 fs_g_nav_fast.u16_entry_pos_sel_file++;
01770 }
01771 }
01772 }
01773
01774
01782 Bool fat_entry_shortname_compare( FS_STRING short_name )
01783 {
01784 PTR_CACHE ptr_entry;
01785
01786 ptr_entry = fat_get_ptr_entry();
01787 if( FS_ENTRY_END == *ptr_entry )
01788 {
01789 fs_g_status = FS_ERR_ENTRY_EMPTY;
01790 return FALSE;
01791 }
01792 if( (FS_ENTRY_DEL == *ptr_entry )
01793 || (FS_ATTR_LFN_ENTRY == ptr_entry[11]) )
01794 {
01795 fs_g_status = FS_ERR_ENTRY_BAD;
01796 return FALSE;
01797 }
01798 fs_g_status = FS_ERR_ENTRY_BAD;
01799 return (0==memcmp_ram2ram(ptr_entry , short_name , 8+3 ));
01800 }
01801
01803 _CONST_TYPE_ U8 fs_s_tab_incorrect_char[]={':','*','?','"','<','>','|'};
01804
01812 U8 fat_check_name( FS_STRING sz_name )
01813 {
01814 U8 u8_nb_entry, u8_i, u8_j;
01815 U16 u16_character;
01816
01817 u8_nb_entry = 2;
01818 u8_i = FS_SIZE_LFN_ENTRY;
01819 while( 1 )
01820 {
01821 if( Is_unicode )
01822 {
01823 u16_character = ((FS_STR_UNICODE)sz_name)[0];
01824 }else{
01825 u16_character = sz_name[0];
01826 }
01827 if( fat_check_eof_name( u16_character ) )
01828 break;
01829
01830 for( u8_j = 0 ; u8_j < sizeof(fs_s_tab_incorrect_char) ; u8_j++ )
01831 {
01832 if( u16_character == fs_s_tab_incorrect_char[u8_j] )
01833 {
01834 fs_g_status = FS_ERR_INCORRECT_NAME;
01835 return 0;
01836 }
01837 }
01838 if( 0 == u8_i )
01839 {
01840 u8_nb_entry++;
01841 u8_i = FS_SIZE_LFN_ENTRY;
01842 }
01843 u8_i--;
01844 sz_name += (Is_unicode? 2 : 1 );
01845 }
01846 if( 0x14 < u8_nb_entry )
01847 {
01848 fs_g_status = FS_ERR_NAME_TOO_LARGE;
01849 return 0;
01850 }
01851 return u8_nb_entry;
01852 }
01853
01854
01856 _CONST_TYPE_ U8 fs_s_execption_char[]={'+',',','.',';','=','[',']'};
01857
01865 U8 fat_translate_char_shortname( U8 character )
01866 {
01867 U8 u8_j;
01868
01869 if( (character<=' ') || ('~'<character) )
01870 return 0;
01871 if( ('a'<=character) && (character<='z') )
01872 {
01873 return (character - ('a'-'A'));
01874 }
01875 for( u8_j = 0 ; u8_j < sizeof(fs_s_execption_char) ; u8_j++ )
01876 {
01877 if( character == fs_s_execption_char[u8_j] )
01878 return 0;
01879 }
01880 return character;
01881 }
01882
01883
01895 Bool fat_alloc_entry_free( U8 u8_nb_entry )
01896 {
01897 PTR_CACHE ptr_entry;
01898 Bool b_garbage_collector_used = FALSE;
01899 U8 u8_nb_entry_save;
01900
01901 u8_nb_entry_save = u8_nb_entry;
01902
01903
01904 fs_g_nav_fast.u16_entry_pos_sel_file=0;
01905
01906 while( 1 )
01907 {
01908
01909 if( !fat_read_dir() )
01910 {
01911 if( FS_ERR_OUT_LIST != fs_g_status )
01912 return FALSE;
01913
01914
01915
01916
01917 fs_g_seg.u32_size_or_pos = 1;
01918 if( !fat_allocfreespace())
01919 {
01920
01921 if( b_garbage_collector_used )
01922 return FALSE;
01923 if( !fat_garbage_collector_entry())
01924 return FALSE;
01925 b_garbage_collector_used = TRUE;
01926 fs_g_nav_fast.u16_entry_pos_sel_file=0;
01927 u8_nb_entry = u8_nb_entry_save;
01928 continue;
01929 }
01930
01931
01932
01933 if( !fat_clear_cluster())
01934 return FALSE;
01935
01936 continue;
01937 }
01938
01939
01940 ptr_entry = fat_get_ptr_entry();
01941 if ( FS_ENTRY_END == *ptr_entry )
01942 {
01943 u8_nb_entry--;
01944 if( 0 == u8_nb_entry )
01945 {
01946 return TRUE;
01947 }
01948 }
01949
01950
01951 fs_g_nav_fast.u16_entry_pos_sel_file++;
01952 if( 0 == fs_g_nav_fast.u16_entry_pos_sel_file )
01953 {
01954
01955
01956 if( b_garbage_collector_used )
01957 {
01958
01959 fs_g_status = FS_ERR_NO_FREE_SPACE;
01960 return FALSE;
01961 }
01962 if( !fat_garbage_collector_entry())
01963 return FALSE;
01964 b_garbage_collector_used = TRUE;
01965 fs_g_nav_fast.u16_entry_pos_sel_file=0;
01966 u8_nb_entry = u8_nb_entry_save;
01967 continue;
01968 }
01969 }
01970 }
01971
01972
01978 Bool fat_garbage_collector_entry( void )
01979 {
01980 _MEM_TYPE_SLOW_ U8 entry[ FS_SIZE_FILE_ENTRY ];
01981 PTR_CACHE ptr_entry;
01982 U16 u16_pos_old = 0;
01983 U16 u16_pos_new = 0;
01984
01985
01986 while( 1 )
01987 {
01988
01989 fs_g_nav_fast.u16_entry_pos_sel_file=u16_pos_old;
01990
01991 if( !fat_read_dir() )
01992 {
01993 if( FS_ERR_OUT_LIST != fs_g_status )
01994 return FALSE;
01995 goto fat_garbage_collector_entry_endofdir;
01996 }
01997
01998
01999 ptr_entry = fat_get_ptr_entry();
02000
02001 if ( FS_ENTRY_END == *ptr_entry )
02002 {
02003
02004 fat_garbage_collector_entry_endofdir:
02005
02006 fs_g_nav_fast.u16_entry_pos_sel_file=u16_pos_new;
02007 while( fs_g_nav_fast.u16_entry_pos_sel_file != u16_pos_old )
02008 {
02009
02010 if( !fat_read_dir() )
02011 return FALSE;
02012 memset( fat_get_ptr_entry() , 0 , 32 );
02013 fat_cache_mark_sector_as_dirty();
02014 fs_g_nav_fast.u16_entry_pos_sel_file++;
02015 }
02016 return TRUE;
02017 }
02018
02019 if ( FS_ENTRY_DEL != *ptr_entry )
02020 {
02021
02022 if( u16_pos_old != u16_pos_new )
02023 {
02024
02025 memcpy_ram2ram( entry, ptr_entry, FS_SIZE_FILE_ENTRY );
02026 fs_g_nav_fast.u16_entry_pos_sel_file=u16_pos_new;
02027
02028 if( !fat_read_dir() )
02029 return FALSE;
02030 memcpy_ram2ram( fat_get_ptr_entry(), entry, FS_SIZE_FILE_ENTRY );
02031 fat_cache_mark_sector_as_dirty();
02032 }
02033 u16_pos_new++;
02034 }
02035 u16_pos_old++;
02036 }
02037 }
02038
02039
02048 Bool fat_delete_file( Bool b_cluster_list )
02049 {
02050 PTR_CACHE ptr_entry;
02051 U8 u8_tmp;
02052 Bool b_short_del = FALSE;
02053
02054
02055 while( 1 )
02056 {
02057
02058 if( !fat_read_dir() )
02059 return FALSE;
02060
02061
02062 ptr_entry = fat_get_ptr_entry();
02063 u8_tmp = ptr_entry[0];
02064
02065 if( (FS_ATTR_LFN_ENTRY != ptr_entry[11])
02066 && (b_short_del) )
02067 {
02068
02069 break;
02070 }
02071
02072
02073 b_short_del = TRUE;
02074 ptr_entry[0] = FS_ENTRY_DEL;
02075 fat_cache_mark_sector_as_dirty();
02076
02077 if( (FS_ATTR_LFN_ENTRY == ptr_entry[11])
02078 && ( 0 != (FS_ENTRY_LFN_LAST & u8_tmp)) )
02079 {
02080
02081 break;
02082 }
02083
02084
02085 fs_g_nav_fast.u16_entry_pos_sel_file--;
02086 }
02087
02088 if( b_cluster_list )
02089 {
02090
02091 fs_g_nav_entry.u32_pos_in_file=0;
02092 if( !fat_read_file( FS_CLUST_ACT_CLR ))
02093 return FALSE;
02094 }
02095
02096 return TRUE;
02097 }
02098 #endif // FS_LEVEL_FEATURES
02099
02100
02101
02107 U32 fat_getfreespace( void )
02108 {
02109 U32 u32_nb_free_cluster = 0;
02110
02111
02112 fs_g_cluster.u32_pos = 2;
02113
02114 if( Is_fat12 )
02115 {
02116 for(
02117 ; fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02118 ; fs_g_cluster.u32_pos++ )
02119 {
02120
02121 if ( !fat_cluster_val( FS_CLUST_VAL_READ ) )
02122 return 0;
02123
02124 if ( 0 == fs_g_cluster.u32_val )
02125 u32_nb_free_cluster++;
02126 }
02127 }
02128 else
02129 {
02130 if( Is_fat32 )
02131 {
02132 u32_nb_free_cluster = fat_read_fat32_FSInfo();
02133 if( 0xFFFFFFFF != u32_nb_free_cluster )
02134 goto endof_fat_getfreespace;
02135 u32_nb_free_cluster = 0;
02136 }
02137
02138
02139 if( !fat_cluster_val( FS_CLUST_VAL_READ ))
02140 return FALSE;
02141 for(
02142 ; fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02143 ; fs_g_cluster.u32_pos++ )
02144 {
02145 if ( 0 == fs_g_cluster.u32_val )
02146 u32_nb_free_cluster++;
02147 if( !fat_cluster_readnext() )
02148 return FALSE;
02149 }
02150 #if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) )
02151 if( Is_fat32 )
02152 {
02153
02154 fat_write_fat32_FSInfo( u32_nb_free_cluster );
02155 }
02156 #endif
02157 }
02158 endof_fat_getfreespace:
02159 return (u32_nb_free_cluster * fs_g_nav.u8_BPB_SecPerClus);
02160 }
02161
02162
02172 U8 fat_getfreespace_percent( void )
02173 {
02174 U32 u32_nb_free_cluster = 0;
02175 U16 u16_tmp, u16_pos;
02176
02177 if( Is_fat12 )
02178 {
02179 return (((fat_getfreespace()/fs_g_nav.u8_BPB_SecPerClus)*100) / fs_g_nav.u32_CountofCluster);
02180 }
02181
02182
02183 fs_g_cluster.u32_pos = 2;
02184
02185 if( !fat_cluster_val( FS_CLUST_VAL_READ ))
02186 return FALSE;
02187
02188
02189
02190
02191 if( Is_fat32 )
02192 {
02193 u32_nb_free_cluster = fat_read_fat32_FSInfo();
02194 if( 0xFFFFFFFF != u32_nb_free_cluster )
02195 goto endof_fat_getfreespace_percent;
02196 u32_nb_free_cluster = 0;
02197
02198 u16_pos = 2*4;
02199 for( u16_tmp = fs_g_nav.u16_fat_size
02200 ; u16_tmp!=0
02201 ; u16_tmp-- )
02202 {
02203 for( ; u16_pos < 512 ; u16_pos += (2*4) )
02204 {
02205 if( 0 == fs_g_sector[u16_pos] )
02206 u32_nb_free_cluster+=2;
02207 }
02208
02209 u16_pos = 0;
02210 fs_gu32_addrsector++;
02211 if( !fat_cache_read_sector( TRUE ))
02212 return 0;
02213 }
02214 }
02215
02216 if ( Is_fat16 )
02217 {
02218 u16_pos = 2*2;
02219
02220 for( u16_tmp = fs_g_nav.u16_fat_size
02221 ; u16_tmp!=0
02222 ; u16_tmp-- )
02223 {
02224 for( ; u16_pos < 512 ; u16_pos += (2*2) )
02225 {
02226 if( 0 == fs_g_sector[u16_pos] )
02227 u32_nb_free_cluster+=2;
02228 }
02229
02230 u16_pos = 0;
02231 fs_gu32_addrsector++;
02232 if( !fat_cache_read_sector( TRUE ))
02233 return 0;
02234 }
02235 }
02236
02237
02238 if( u32_nb_free_cluster > fs_g_nav.u32_CountofCluster )
02239 return 100;
02240 if( u32_nb_free_cluster > ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256) )
02241 {
02242
02243 u32_nb_free_cluster -= ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256);
02244 }
02245 endof_fat_getfreespace_percent:
02246 return ((u32_nb_free_cluster * 100) / fs_g_nav.u32_CountofCluster);
02247 }
02248
02249
02250
02251 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
02268 Bool fat_allocfreespace( void )
02269 {
02270
02271 Bool first_cluster_free_is_found = FALSE;
02272
02273 Bool b_quick_find = TRUE;
02274
02275 if( Is_fat32 )
02276 {
02277
02278 if( !fat_write_fat32_FSInfo( 0xFFFFFFFF ))
02279 return FALSE;
02280 }
02281
02282 if( 0xFF == MSB0(fs_g_seg.u32_addr) )
02283 {
02284 fat_allocfreespace_start:
02285
02286 fs_g_cluster.u32_pos = 2;
02287 }else{
02288
02289 fs_g_cluster.u32_pos = fs_g_seg.u32_addr+1;
02290 }
02291
02292 fat_clear_info_fat_mod();
02293
02294
02295 for(
02296 ; fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster
02297 ; fs_g_cluster.u32_pos++ )
02298 {
02299
02300 if ( !fat_cluster_val( FS_CLUST_VAL_READ ) )
02301 return FALSE;
02302
02303 if ( 0 == fs_g_cluster.u32_val )
02304 {
02305
02306 fs_g_cluster.u32_val = fs_g_cluster.u32_pos;
02307 if( TRUE == first_cluster_free_is_found )
02308 {
02309
02310 fs_g_cluster.u32_pos--;
02311 if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) )
02312 return FALSE;
02313 }
02314 else
02315 {
02316
02317 first_cluster_free_is_found = TRUE;
02318
02319 if( 0xFF != MSB0(fs_g_seg.u32_addr) )
02320 {
02321
02322
02323 if( 0 == fs_g_seg.u32_addr )
02324 {
02325 if( FS_TYPE_FAT_32 != fs_g_nav_fast.u8_type_fat )
02326 {
02327
02328 fs_g_status = FS_ERR_NO_FREE_SPACE;
02329 return FALSE;
02330 }
02331 fs_g_cluster.u32_pos = fs_g_nav.rootdir.u32_cluster;
02332 }
02333 else
02334 {
02335 fs_g_cluster.u32_pos = fs_g_seg.u32_addr;
02336 }
02337 if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) )
02338 return FALSE;
02339 }
02340 fs_g_seg.u32_addr = fs_g_cluster.u32_val;
02341 }
02342
02343
02344 fs_g_cluster.u32_pos = fs_g_cluster.u32_val;
02345 fs_g_cluster.u32_val = FS_CLUST_VAL_EOL;
02346 if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) )
02347 return FALSE;
02348
02349
02350 if ( fs_g_seg.u32_size_or_pos <= fs_g_nav.u8_BPB_SecPerClus )
02351 {
02352 fs_g_seg.u32_size_or_pos = 0;
02353 break;
02354 }
02355 fs_g_seg.u32_size_or_pos -= fs_g_nav.u8_BPB_SecPerClus;
02356 }
02357 else
02358 {
02359
02360 if( TRUE == first_cluster_free_is_found )
02361 {
02362
02363
02364 break;
02365 }
02366 else
02367 {
02368
02369
02370 if( b_quick_find )
02371 {
02372 fs_g_cluster.u32_pos += 500;
02373 }
02374 }
02375 }
02376 }
02377
02378
02379 if( FALSE == first_cluster_free_is_found )
02380 {
02381 if( b_quick_find )
02382 {
02383
02384 b_quick_find = FALSE;
02385 goto fat_allocfreespace_start;
02386 }
02387 fs_g_status = FS_ERR_NO_FREE_SPACE;
02388 return FALSE;
02389 }
02390
02391 return fat_update_fat2();
02392 }
02393 #endif // FS_LEVEL_FEATURES
02394
02395
02396 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
02399 void fat_clear_info_fat_mod( void )
02400 {
02401 fs_g_u16_first_mod_fat = 0xFFFF;
02402 fs_g_u16_last_mod_fat = 0;
02403 }
02404 #endif // FS_LEVEL_FEATURES
02405
02406
02407 #if (FS_LEVEL_FEATURES > FSFEATURE_READ)
02413 Bool fat_update_fat2( void )
02414 {
02415 while( fs_g_u16_first_mod_fat <= fs_g_u16_last_mod_fat )
02416 {
02417
02418 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + fs_g_u16_first_mod_fat;
02419
02420 if( !fat_cache_read_sector( TRUE ))
02421 return FALSE;
02422
02423 fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + ((U32)fs_g_u16_first_mod_fat + fs_g_nav.u16_fat_size);
02424
02425 if( !fat_cache_read_sector( FALSE ))
02426 return FALSE;
02427
02428 fat_cache_mark_sector_as_dirty();
02429 fs_g_u16_first_mod_fat++;
02430 }
02431 return TRUE;
02432 }
02433 #endif // FS_LEVEL_FEATURES
02434
02435
02436 #if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE))
02448 Bool fat_clear_cluster( void )
02449 {
02450 U8 u8_loop;
02451
02452
02453 fs_g_seg.u32_size_or_pos = 0;
02454 if( !fat_cluster_list( FS_CLUST_ACT_ONE, FALSE ))
02455 return FALSE;
02456
02457
02458 fs_gu32_addrsector = fs_g_seg.u32_addr + (fs_g_nav.u8_BPB_SecPerClus -1);
02459 for( u8_loop = 0
02460 ; fs_g_nav.u8_BPB_SecPerClus != u8_loop
02461 ; u8_loop++ )
02462 {
02463
02464 if( !fat_cache_read_sector( FALSE ))
02465 return FALSE;
02466
02467 if(0 == u8_loop)
02468 {
02469 fat_cache_clear();
02470 }
02471 fat_cache_mark_sector_as_dirty();
02472 fs_gu32_addrsector--;
02473 }
02474 return TRUE;
02475 }
02476 #endif // FS_LEVEL_FEATURES