00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include "circle_platform.h"
00064
00065 #if SDCARD_SDIO
00066 #include "sdio_sd.h"
00067 #else
00068 #include "spi_sd.h"
00069 #endif
00070
00071 #include "dosfs.h"
00072
00073
00074
00075 __IO SD_CardInfo SDCardInfo;
00076 __IO SD_Error Status = SD_OK;
00077
00078
00079
00080
00081
00082 typedef struct
00083 {
00084 long int quot;
00085 long int rem;
00086 } ldiv_t;
00087
00088
00089
00090 NODEBUG ldiv_t DFS_ldiv( s32 numer, s32 denom )
00091 {
00092 static ldiv_t ld;
00093
00094 ld.quot = numer / denom;
00095 ld.rem = numer % denom;
00096
00097 return ld;
00098 }
00099
00100 #define DFS_div(x,y) DFS_ldiv(x,y)
00101
00102
00103 NODEBUG void* DFS_memset( void* dest, u8 c, s32 count )
00104 {
00105 u32 i;
00106
00107 u8* val = ( u8* ) dest;
00108
00109 for ( i = 0; i < count; i++ )
00110 {
00111 *val = c;
00112 val++;
00113 }
00114
00115 return dest;
00116 }
00117
00118
00119 NODEBUG void* DFS_memcpy( void* dest, void* src, s32 count )
00120 {
00121
00122 u8* d = ( u8* )dest;
00123 u8* s = ( u8* )src;
00124
00125 while ( count-- > 0 )
00126 *d++ = *s++;
00127 return dest;
00128 }
00129
00130
00131 NODEBUG s32 DFS_memcmp( const void* s1, const void* s2, u32 n )
00132 {
00133 u8 u1, u2;
00134 u8* c1 = ( u8* ) s1;
00135 u8* c2 = ( u8* ) s2;
00136
00137 for ( ; n-- ; c1++, c2++ )
00138 {
00139 u1 = * ( u8* ) c1;
00140 u2 = * ( u8* ) c2;
00141 if ( u1 != u2 )
00142 {
00143 return ( u1 - u2 );
00144 }
00145 }
00146 return 0;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 NODEBUG void DFS_strcpy( u8* Dest , u8* Src )
00164 {
00165
00166
00167 while ( *Src )
00168 {
00169
00170 *Dest++ = *Src++;
00171 }
00172 }
00173
00174
00175
00176 NODEBUG u8* DFS_strncpy( u8* s1, const u8* s2, s32 n )
00177 {
00178 u8 c;
00179 u8* s = s1;
00180
00181 --s1;
00182
00183 if ( n >= 4 )
00184 {
00185 s32 n4 = n >> 2;
00186
00187 for ( ;; )
00188 {
00189 c = *s2++;
00190 *++s1 = c;
00191 if ( c == '\0' )
00192 break;
00193 c = *s2++;
00194 *++s1 = c;
00195 if ( c == '\0' )
00196 break;
00197 c = *s2++;
00198 *++s1 = c;
00199 if ( c == '\0' )
00200 break;
00201 c = *s2++;
00202 *++s1 = c;
00203 if ( c == '\0' )
00204 break;
00205 if ( --n4 == 0 )
00206 goto last_chars;
00207 }
00208 n = n - ( s1 - s ) - 1;
00209 if ( n == 0 )
00210 return s;
00211 goto zero_fill;
00212 }
00213
00214 last_chars:
00215 n &= 3;
00216 if ( n == 0 )
00217 return s;
00218
00219 do
00220 {
00221 c = *s2++;
00222 *++s1 = c;
00223 if ( --n == 0 )
00224 return s;
00225 }
00226 while ( c != '\0' );
00227
00228 zero_fill:
00229 do
00230 *++s1 = '\0';
00231 while ( --n > 0 );
00232
00233 return s;
00234 }
00235
00236 NODEBUG s32 DFS_strcmp( u8* s1, u8* s2 )
00237 {
00238 while ( *s1 == *s2 && *s1 != '\0' )
00239 {
00240 s1++;
00241 s2++;
00242 }
00243
00244
00245
00246 return *s1 - *s2;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255 NODEBUG uint32_t DFS_ReadSector( uint8_t unit, uint8_t* buffer, uint32_t sector, uint32_t count )
00256 {
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 if (SD_ReadBlock( buffer, sector << 9, SECTOR_SIZE ) != SD_OK)
00269 return 1;
00270
00271 #if SDCARD_SDIO
00272
00273 if ( SD_WaitReadOperation() == SD_OK )
00274 {
00275
00276 do
00277 {
00278 Status = SD_GetStatus();
00279 }
00280 while ( Status == SD_TRANSFER_BUSY );
00281
00282 if ( Status == SD_TRANSFER_OK )
00283 return 0;
00284 else
00285 return 1;
00286 }
00287 else
00288 return 1;
00289 #endif
00290
00291
00292
00293 }
00294
00295
00296 NODEBUG uint32_t DFS_WriteSector( uint8_t unit, uint8_t* buffer, uint32_t sector, uint32_t count )
00297 {
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 if (SD_WriteBlock( buffer, sector << 9, SECTOR_SIZE ) != SD_OK)
00311 return 1;
00312
00313 #if SDCARD_SDIO
00314
00315 if ( SD_WaitWriteOperation() == SD_OK )
00316 {
00317
00318 do
00319 {
00320 Status = SD_GetStatus();
00321 }
00322 while ( Status == SD_TRANSFER_BUSY );
00323
00324 if ( Status == SD_TRANSFER_OK )
00325 return 0;
00326 else
00327 return 1;
00328 }
00329 else
00330 return 1;
00331 #endif
00332
00333
00334
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 NODEBUG uint32_t DFS_GetPtnStart( uint8_t unit, uint8_t* scratchsector, uint8_t pnum, uint8_t* pactive, uint8_t* pptype, uint32_t* psize )
00353 {
00354 uint32_t result;
00355 PMBR mbr = ( PMBR ) scratchsector;
00356
00357
00358 if ( pnum > 3 )
00359 return DFS_ERRMISC;
00360
00361
00362 if ( DFS_ReadSector( unit, scratchsector, 0, 1 ) )
00363 {
00364 return DFS_ERRMISC;
00365 }
00366
00367 result = ( uint32_t ) mbr->ptable[pnum].start_0 |
00368 ( ( ( uint32_t ) mbr->ptable[pnum].start_1 ) << 8 ) |
00369 ( ( ( uint32_t ) mbr->ptable[pnum].start_2 ) << 16 ) |
00370 ( ( ( uint32_t ) mbr->ptable[pnum].start_3 ) << 24 );
00371
00372 if ( pactive )
00373 *pactive = mbr->ptable[pnum].active;
00374
00375 if ( pptype )
00376 *pptype = mbr->ptable[pnum].type;
00377
00378 if ( psize )
00379 *psize = ( uint32_t ) mbr->ptable[pnum].size_0 |
00380 ( ( ( uint32_t ) mbr->ptable[pnum].size_1 ) << 8 ) |
00381 ( ( ( uint32_t ) mbr->ptable[pnum].size_2 ) << 16 ) |
00382 ( ( ( uint32_t ) mbr->ptable[pnum].size_3 ) << 24 );
00383
00384 return result;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 NODEBUG uint32_t DFS_GetVolInfo( uint8_t unit, uint8_t* scratchsector, uint32_t startsector, PVOLINFO volinfo )
00396 {
00397 PLBR lbr = ( PLBR ) scratchsector;
00398 volinfo->unit = unit;
00399 volinfo->startsector = startsector;
00400
00401 if ( DFS_ReadSector( unit, scratchsector, startsector, 1 ) )
00402 return DFS_ERRMISC;
00403
00404
00405
00406
00407
00408 volinfo->secperclus = lbr->bpb.secperclus;
00409 volinfo->reservedsecs = ( uint16_t ) lbr->bpb.reserved_l |
00410 ( ( ( uint16_t ) lbr->bpb.reserved_h ) << 8 );
00411
00412 volinfo->numsecs = ( uint16_t ) lbr->bpb.sectors_s_l |
00413 ( ( ( uint16_t ) lbr->bpb.sectors_s_h ) << 8 );
00414
00415 if ( !volinfo->numsecs )
00416 volinfo->numsecs = ( uint32_t ) lbr->bpb.sectors_l_0 |
00417 ( ( ( uint32_t ) lbr->bpb.sectors_l_1 ) << 8 ) |
00418 ( ( ( uint32_t ) lbr->bpb.sectors_l_2 ) << 16 ) |
00419 ( ( ( uint32_t ) lbr->bpb.sectors_l_3 ) << 24 );
00420
00421
00422
00423
00424 volinfo->secperfat = ( uint16_t ) lbr->bpb.secperfat_l |
00425 ( ( ( uint16_t ) lbr->bpb.secperfat_h ) << 8 );
00426 if ( !volinfo->secperfat )
00427 {
00428 volinfo->secperfat = ( uint32_t ) lbr->ebpb.ebpb32.fatsize_0 |
00429 ( ( ( uint32_t ) lbr->ebpb.ebpb32.fatsize_1 ) << 8 ) |
00430 ( ( ( uint32_t ) lbr->ebpb.ebpb32.fatsize_2 ) << 16 ) |
00431 ( ( ( uint32_t ) lbr->ebpb.ebpb32.fatsize_3 ) << 24 );
00432
00433 DFS_memcpy( volinfo->label, lbr->ebpb.ebpb32.label, 11 );
00434 volinfo->label[11] = 0;
00435
00436
00437
00438
00439 }
00440 else
00441 {
00442 DFS_memcpy( volinfo->label, lbr->ebpb.ebpb.label, 11 );
00443 volinfo->label[11] = 0;
00444
00445
00446
00447
00448 }
00449
00450
00451 volinfo->rootentries = ( uint16_t ) lbr->bpb.rootentries_l |
00452 ( ( ( uint16_t ) lbr->bpb.rootentries_h ) << 8 );
00453
00454
00455 volinfo->fat1 = startsector + volinfo->reservedsecs;
00456
00457
00458
00459
00460 if ( volinfo->rootentries )
00461 {
00462 volinfo->rootdir = volinfo->fat1 + ( volinfo->secperfat * 2 );
00463 volinfo->dataarea = volinfo->rootdir + ( ( ( volinfo->rootentries * 32 ) + ( SECTOR_SIZE - 1 ) ) / SECTOR_SIZE );
00464 }
00465 else
00466 {
00467 volinfo->dataarea = volinfo->fat1 + ( volinfo->secperfat * 2 );
00468 volinfo->rootdir = ( uint32_t ) lbr->ebpb.ebpb32.root_0 |
00469 ( ( ( uint32_t ) lbr->ebpb.ebpb32.root_1 ) << 8 ) |
00470 ( ( ( uint32_t ) lbr->ebpb.ebpb32.root_2 ) << 16 ) |
00471 ( ( ( uint32_t ) lbr->ebpb.ebpb32.root_3 ) << 24 );
00472 }
00473
00474
00475 volinfo->numclusters = ( volinfo->numsecs - volinfo->dataarea ) / volinfo->secperclus;
00476 if ( volinfo->numclusters < 4085 )
00477 volinfo->filesystem = FAT12;
00478 else if ( volinfo->numclusters < 65525 )
00479 volinfo->filesystem = FAT16;
00480 else
00481 volinfo->filesystem = FAT32;
00482
00483 return DFS_OK;
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 NODEBUG uint32_t DFS_GetFAT( PVOLINFO volinfo, uint8_t* scratch, uint32_t* scratchcache, uint32_t cluster )
00495 {
00496 uint32_t offset, sector, result;
00497
00498 if ( volinfo->filesystem == FAT12 )
00499 {
00500 offset = cluster + ( cluster >> 2 );
00501 }
00502 else if ( volinfo->filesystem == FAT16 )
00503 {
00504 offset = cluster * 2;
00505 }
00506 else if ( volinfo->filesystem == FAT32 )
00507 {
00508 offset = cluster * 4;
00509 }
00510 else
00511 return 0x0ffffff7;
00512
00513
00514
00515 sector = DFS_ldiv( offset, SECTOR_SIZE ).quot + volinfo->fat1;
00516
00517
00518 if ( sector != *scratchcache )
00519 {
00520 if ( DFS_ReadSector( volinfo->unit, scratch, sector, 1 ) )
00521 {
00522
00523
00524 *scratchcache = 0;
00525 return 0x0ffffff7;
00526 }
00527 *scratchcache = sector;
00528 }
00529
00530
00531
00532
00533
00534 offset = DFS_ldiv( offset, SECTOR_SIZE ).rem;
00535
00536 if ( volinfo->filesystem == FAT12 )
00537 {
00538
00539
00540
00541 if ( offset == SECTOR_SIZE - 1 )
00542 {
00543 result = ( uint32_t ) scratch[offset];
00544 sector++;
00545 if ( DFS_ReadSector( volinfo->unit, scratch, sector, 1 ) )
00546 {
00547
00548
00549 *scratchcache = 0;
00550 return 0x0ffffff7;
00551 }
00552 *scratchcache = sector;
00553
00554 result |= ( ( uint32_t ) scratch[0] ) << 8;
00555 }
00556 else
00557 {
00558 result = ( uint32_t ) scratch[offset] |
00559 ( ( uint32_t ) scratch[offset + 1] ) << 8;
00560 }
00561 if ( cluster & 1 )
00562 result = result >> 4;
00563 else
00564 result = result & 0xfff;
00565 }
00566 else if ( volinfo->filesystem == FAT16 )
00567 {
00568 result = ( uint32_t ) scratch[offset] |
00569 ( ( uint32_t ) scratch[offset + 1] ) << 8;
00570 }
00571 else if ( volinfo->filesystem == FAT32 )
00572 {
00573 result = ( ( uint32_t ) scratch[offset] |
00574 ( ( uint32_t ) scratch[offset + 1] ) << 8 |
00575 ( ( uint32_t ) scratch[offset + 2] ) << 16 |
00576 ( ( uint32_t ) scratch[offset + 3] ) << 24 ) & 0x0fffffff;
00577 }
00578 else
00579 result = 0x0ffffff7;
00580 return result;
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 NODEBUG uint32_t DFS_SetFAT( PVOLINFO volinfo, uint8_t* scratch, uint32_t* scratchcache, uint32_t cluster, uint32_t new_contents )
00601 {
00602 uint32_t offset, sector, result;
00603 if ( volinfo->filesystem == FAT12 )
00604 {
00605 offset = cluster + ( cluster / 2 );
00606 new_contents &= 0xfff;
00607 }
00608 else if ( volinfo->filesystem == FAT16 )
00609 {
00610 offset = cluster * 2;
00611 new_contents &= 0xffff;
00612 }
00613 else if ( volinfo->filesystem == FAT32 )
00614 {
00615 offset = cluster * 4;
00616 new_contents &= 0x0fffffff;
00617 }
00618 else
00619 return DFS_ERRMISC;
00620
00621
00622
00623 sector = DFS_ldiv( offset, SECTOR_SIZE ).quot + volinfo->fat1;
00624
00625
00626 if ( sector != *scratchcache )
00627 {
00628 if ( DFS_ReadSector( volinfo->unit, scratch, sector, 1 ) )
00629 {
00630
00631
00632 *scratchcache = 0;
00633 return DFS_ERRMISC;
00634 }
00635 *scratchcache = sector;
00636 }
00637
00638
00639
00640
00641
00642 offset = DFS_ldiv( offset, SECTOR_SIZE ).rem;
00643
00644 if ( volinfo->filesystem == FAT12 )
00645 {
00646
00647
00648
00649 if ( cluster & 1 )
00650 new_contents = new_contents << 4;
00651
00652
00653 if ( offset == SECTOR_SIZE - 1 )
00654 {
00655
00656
00657 if ( cluster & 1 )
00658 {
00659 scratch[offset] = ( scratch[offset] & 0x0f ) | new_contents & 0xf0;
00660 }
00661
00662 else
00663 {
00664 scratch[offset] = new_contents & 0xff;
00665 }
00666 result = DFS_WriteSector( volinfo->unit, scratch, *scratchcache, 1 );
00667
00668 if ( DFS_OK == result )
00669 result = DFS_WriteSector( volinfo->unit, scratch, ( *scratchcache ) + volinfo->secperfat, 1 );
00670
00671
00672
00673 if ( DFS_OK == result )
00674 {
00675 *scratchcache++;
00676 result = DFS_ReadSector( volinfo->unit, scratch, *scratchcache, 1 );
00677 if ( DFS_OK == result )
00678 {
00679
00680 if ( cluster & 1 )
00681 {
00682 scratch[0] = new_contents & 0xff00;
00683 }
00684
00685 else
00686 {
00687 scratch[0] = ( scratch[0] & 0xf0 ) | new_contents & 0x0f;
00688 }
00689 result = DFS_WriteSector( volinfo->unit, scratch, *scratchcache, 1 );
00690
00691 if ( DFS_OK == result )
00692 result = DFS_WriteSector( volinfo->unit, scratch, ( *scratchcache ) + volinfo->secperfat, 1 );
00693 }
00694 else
00695 {
00696
00697
00698 *scratchcache = 0;
00699 }
00700 }
00701 }
00702
00703
00704
00705 else
00706 {
00707
00708 if ( cluster & 1 )
00709 {
00710 scratch[offset] = ( scratch[offset] & 0x0f ) | new_contents & 0xf0;
00711 scratch[offset + 1] = new_contents & 0xff00;
00712 }
00713
00714 else
00715 {
00716 scratch[offset] = new_contents & 0xff;
00717 scratch[offset + 1] = ( scratch[offset + 1] & 0xf0 ) | new_contents & 0x0f;
00718 }
00719 result = DFS_WriteSector( volinfo->unit, scratch, *scratchcache, 1 );
00720
00721 if ( DFS_OK == result )
00722 result = DFS_WriteSector( volinfo->unit, scratch, ( *scratchcache ) + volinfo->secperfat, 1 );
00723 }
00724 }
00725 else if ( volinfo->filesystem == FAT16 )
00726 {
00727 scratch[offset] = ( new_contents & 0xff );
00728 scratch[offset + 1] = ( new_contents & 0xff00 ) >> 8;
00729 result = DFS_WriteSector( volinfo->unit, scratch, *scratchcache, 1 );
00730
00731 if ( DFS_OK == result )
00732 result = DFS_WriteSector( volinfo->unit, scratch, ( *scratchcache ) + volinfo->secperfat, 1 );
00733 }
00734 else if ( volinfo->filesystem == FAT32 )
00735 {
00736 scratch[offset] = ( new_contents & 0xff );
00737 scratch[offset + 1] = ( new_contents & 0xff00 ) >> 8;
00738 scratch[offset + 2] = ( new_contents & 0xff0000 ) >> 16;
00739 scratch[offset + 3] = ( scratch[offset + 3] & 0xf0 ) | ( ( new_contents & 0x0f000000 ) >> 24 );
00740
00741
00742
00743 result = DFS_WriteSector( volinfo->unit, scratch, *scratchcache, 1 );
00744
00745 if ( DFS_OK == result )
00746 result = DFS_WriteSector( volinfo->unit, scratch, ( *scratchcache ) + volinfo->secperfat, 1 );
00747 }
00748 else
00749 result = DFS_ERRMISC;
00750
00751 return result;
00752 }
00753
00754
00755
00756
00757
00758
00759 NODEBUG uint8_t* DFS_CanonicalToDir( uint8_t* dest, uint8_t* src )
00760 {
00761 uint8_t* destptr = dest;
00762 vs32 c = '5';
00763
00764 c = *src;
00765
00766 DFS_memset( dest, ' ', 11 );
00767 dest[11] = 0;
00768
00769 while ( *src && ( *src != DIR_SEPARATOR ) && ( destptr - dest < 11 ) )
00770 {
00771 if ( *src >= 'a' && *src <= 'z' )
00772 {
00773 *destptr++ = c = ( *src - 'a' ) + 'A';
00774 src++;
00775 }
00776 else if ( *src == '.' )
00777 {
00778 src++;
00779 destptr = dest + 8;
00780 }
00781 else
00782 {
00783 *destptr = c;
00784 *destptr++ = *src++;
00785 }
00786 }
00787
00788 return dest;
00789 }
00790
00791
00792
00793
00794
00795
00796
00797
00798 NODEBUG uint32_t DFS_GetFreeFAT( PVOLINFO volinfo, uint8_t* scratch )
00799 {
00800 uint32_t i, result = 0xffffffff, scratchcache = 0;
00801
00802
00803
00804
00805 for ( i = 2; i < volinfo->numclusters; i++ )
00806 {
00807 result = DFS_GetFAT( volinfo, scratch, &scratchcache, i );
00808 if ( !result )
00809 {
00810 return i;
00811 }
00812 }
00813 return 0x0ffffff7;
00814 }
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 NODEBUG uint32_t DFS_OpenDir( PVOLINFO volinfo, uint8_t* dirname, PDIRINFO dirinfo )
00825 {
00826
00827 dirinfo->flags = 0;
00828 u8 c = *dirname;
00829
00830
00831 if ( !my_strlen( ( u8* ) dirname ) || ( my_strlen( ( u8* ) dirname ) == 1 && dirname[0] == DIR_SEPARATOR ) )
00832 {
00833 if ( volinfo->filesystem == FAT32 )
00834 {
00835 dirinfo->currentcluster = volinfo->rootdir;
00836 dirinfo->currentsector = 0;
00837 dirinfo->currententry = 0;
00838
00839
00840 return DFS_ReadSector( volinfo->unit, dirinfo->scratch, volinfo->dataarea + ( ( volinfo->rootdir - 2 ) * volinfo->secperclus ), 1 );
00841 }
00842 else
00843 {
00844 dirinfo->currentcluster = 0;
00845 dirinfo->currentsector = 0;
00846 dirinfo->currententry = 0;
00847
00848
00849 return DFS_ReadSector( volinfo->unit, dirinfo->scratch, volinfo->rootdir, 1 );
00850 }
00851 }
00852
00853
00854
00855 else
00856 {
00857 uint8_t tmpfn[12];
00858 uint8_t* ptr = dirname;
00859 uint32_t result;
00860 DIRENT de;
00861
00862 if ( volinfo->filesystem == FAT32 )
00863 {
00864 dirinfo->currentcluster = volinfo->rootdir;
00865 dirinfo->currentsector = 0;
00866 dirinfo->currententry = 0;
00867
00868
00869 if ( DFS_ReadSector( volinfo->unit, dirinfo->scratch, volinfo->dataarea + ( ( volinfo->rootdir - 2 ) * volinfo->secperclus ), 1 ) )
00870 return DFS_ERRMISC;
00871 }
00872 else
00873 {
00874 dirinfo->currentcluster = 0;
00875 dirinfo->currentsector = 0;
00876 dirinfo->currententry = 0;
00877
00878
00879 if ( DFS_ReadSector( volinfo->unit, dirinfo->scratch, volinfo->rootdir, 1 ) )
00880 return DFS_ERRMISC;
00881 }
00882
00883
00884 while ( *ptr == DIR_SEPARATOR && *ptr )
00885 ptr++;
00886
00887
00888
00889 while ( *ptr )
00890 {
00891
00892 DFS_CanonicalToDir( tmpfn, ptr );
00893
00894 de.name[0] = 0;
00895
00896 do
00897 {
00898 result = DFS_GetNext( volinfo, dirinfo, &de );
00899 }
00900 while ( !result && DFS_memcmp( de.name, tmpfn, 11 ) );
00901
00902 if ( !DFS_memcmp( de.name, tmpfn, 11 ) && ( ( de.attr & ATTR_DIRECTORY ) == ATTR_DIRECTORY ) )
00903 {
00904 if ( volinfo->filesystem == FAT32 )
00905 {
00906 dirinfo->currentcluster = ( uint32_t ) de.startclus_l_l |
00907 ( ( uint32_t ) de.startclus_l_h ) << 8 |
00908 ( ( uint32_t ) de.startclus_h_l ) << 16 |
00909 ( ( uint32_t ) de.startclus_h_h ) << 24;
00910 }
00911 else
00912 {
00913 dirinfo->currentcluster = ( uint32_t ) de.startclus_l_l |
00914 ( ( uint32_t ) de.startclus_l_h ) << 8;
00915 }
00916 dirinfo->currentsector = 0;
00917 dirinfo->currententry = 0;
00918
00919 if ( DFS_ReadSector( volinfo->unit, dirinfo->scratch, volinfo->dataarea + ( ( dirinfo->currentcluster - 2 ) * volinfo->secperclus ), 1 ) )
00920 return DFS_ERRMISC;
00921 }
00922 else if ( !DFS_memcmp( de.name, tmpfn, 11 ) && !( de.attr & ATTR_DIRECTORY ) )
00923 return DFS_NOTFOUND;
00924
00925
00926 while ( *ptr != DIR_SEPARATOR && *ptr )
00927 ptr++;
00928 if ( *ptr == DIR_SEPARATOR )
00929 ptr++;
00930 }
00931
00932 if ( !dirinfo->currentcluster )
00933 return DFS_NOTFOUND;
00934 }
00935 return DFS_OK;
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 NODEBUG uint32_t DFS_GetNext( PVOLINFO volinfo, PDIRINFO dirinfo, PDIRENT dirent )
00949 {
00950 uint32_t tempint;
00951
00952
00953 if ( dirinfo->currententry >= SECTOR_SIZE / sizeof( DIRENT ) )
00954 {
00955 dirinfo->currententry = 0;
00956 dirinfo->currentsector++;
00957
00958
00959
00960
00961
00962 if ( dirinfo->currentcluster == 0 )
00963 {
00964
00965 if ( dirinfo->currentsector * ( SECTOR_SIZE / sizeof( DIRENT ) ) >= volinfo->rootentries )
00966 return DFS_EOF;
00967
00968
00969 if ( DFS_ReadSector( volinfo->unit, dirinfo->scratch, volinfo->rootdir + dirinfo->currentsector, 1 ) )
00970 return DFS_ERRMISC;
00971 }
00972
00973
00974 else
00975 {
00976 if ( dirinfo->currentsector >= volinfo->secperclus )
00977 {
00978 dirinfo->currentsector = 0;
00979 if ( ( dirinfo->currentcluster >= 0xff7 && volinfo->filesystem == FAT12 ) ||
00980 ( dirinfo->currentcluster >= 0xfff7 && volinfo->filesystem == FAT16 ) ||
00981 ( dirinfo->currentcluster >= 0x0ffffff7 && volinfo->filesystem == FAT32 ) )
00982 {
00983
00984
00985
00986
00987 if ( !( dirinfo->flags & DFS_DI_BLANKENT ) )
00988 return DFS_EOF;
00989
00990
00991
00992 else
00993 return DFS_ALLOCNEW;
00994 }
00995 dirinfo->currentcluster = DFS_GetFAT( volinfo, dirinfo->scratch, &tempint, dirinfo->currentcluster );
00996 }
00997 if ( DFS_ReadSector( volinfo->unit, dirinfo->scratch, volinfo->dataarea + ( ( dirinfo->currentcluster - 2 ) * volinfo->secperclus ) + dirinfo->currentsector, 1 ) )
00998 return DFS_ERRMISC;
00999 }
01000 }
01001
01002 DFS_memcpy( dirent, &( ( ( PDIRENT ) dirinfo->scratch )[dirinfo->currententry] ), sizeof( DIRENT ) );
01003
01004 if ( dirent->name[0] == 0 )
01005 {
01006
01007 if ( dirinfo->flags & DFS_DI_BLANKENT )
01008 {
01009
01010 dirinfo->currententry++;
01011 return DFS_OK;
01012 }
01013 else
01014 return DFS_EOF;
01015 }
01016
01017 if ( dirent->name[0] == 0xe5 )
01018 dirent->name[0] = 0;
01019 else if ( ( ( dirent->attr & ATTR_LONG_NAME ) == ATTR_LONG_NAME ) &&
01020 !( dirinfo->flags & DFS_DI_BLANKENT ) )
01021 dirent->name[0] = 0;
01022 else if ( dirent->name[0] == 0x05 )
01023 dirent->name[0] = 0xe5;
01024
01025 dirinfo->currententry++;
01026
01027 return DFS_OK;
01028 }
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040 NODEBUG uint32_t DFS_GetFreeDirEnt( PVOLINFO volinfo, uint8_t* path, PDIRINFO di, PDIRENT de )
01041 {
01042 uint32_t tempclus, i;
01043
01044 if ( DFS_OpenDir( volinfo, path, di ) )
01045 return DFS_NOTFOUND;
01046
01047
01048 di->flags |= DFS_DI_BLANKENT;
01049
01050
01051
01052 tempclus = 0;
01053 do
01054 {
01055 tempclus = DFS_GetNext( volinfo, di, de );
01056
01057
01058 if ( tempclus == DFS_OK && ( !de->name[0] ) )
01059 {
01060 return DFS_OK;
01061 }
01062
01063
01064 else if ( tempclus == DFS_EOF )
01065 return DFS_ERRMISC;
01066
01067 else if ( tempclus == DFS_ALLOCNEW )
01068 {
01069 tempclus = DFS_GetFreeFAT( volinfo, di->scratch );
01070 if ( tempclus == 0x0ffffff7 )
01071 return DFS_ERRMISC;
01072
01073
01074 DFS_memset( di->scratch, 0, SECTOR_SIZE );
01075 for ( i = 0; i < volinfo->secperclus; i++ )
01076 {
01077 if ( DFS_WriteSector( volinfo->unit, di->scratch, volinfo->dataarea + ( ( tempclus - 2 ) * volinfo->secperclus ) + i, 1 ) )
01078 return DFS_ERRMISC;
01079 }
01080
01081 i = 0;
01082 DFS_SetFAT( volinfo, di->scratch, &i, di->currentcluster, tempclus );
01083
01084
01085 di->currentcluster = tempclus;
01086 di->currentsector = 0;
01087 di->currententry = 1;
01088
01089
01090 switch ( volinfo->filesystem )
01091 {
01092 case FAT12: tempclus = 0xff8; break;
01093 case FAT16: tempclus = 0xfff8; break;
01094 case FAT32: tempclus = 0x0ffffff8; break;
01095 default: return DFS_ERRMISC;
01096 }
01097 DFS_SetFAT( volinfo, di->scratch, &i, di->currentcluster, tempclus );
01098 }
01099 }
01100 while ( !tempclus );
01101
01102
01103 return DFS_ERRMISC;
01104 }
01105
01106
01107
01108
01109
01110
01111
01112
01113 NODEBUG uint32_t DFS_OpenFile( PVOLINFO volinfo, uint8_t* path, uint8_t mode, uint8_t* scratch, PFILEINFO fileinfo )
01114 {
01115 uint8_t tmppath[MAX_PATH];
01116 uint8_t filename[12];
01117 uint8_t* p;
01118 DIRINFO di;
01119 DIRENT de;
01120 uint32_t dircluster;
01121
01122
01123 DFS_memset( fileinfo, 0, sizeof( FILEINFO ) );
01124
01125
01126 fileinfo->mode = mode;
01127
01128
01129 DFS_strncpy( ( u8* ) tmppath, ( u8* ) path, MAX_PATH );
01130 tmppath[MAX_PATH - 1] = 0;
01131 if ( DFS_strcmp( ( u8* ) path, ( u8* ) tmppath ) )
01132 {
01133 return DFS_PATHLEN;
01134 }
01135
01136
01137 while ( tmppath[0] == DIR_SEPARATOR )
01138 DFS_strcpy( ( u8* ) tmppath, ( u8* ) tmppath + 1 );
01139
01140
01141 p = tmppath;
01142 while ( *( p++ ) );
01143
01144 p--;
01145 while ( p > tmppath && *p != DIR_SEPARATOR )
01146 p--;
01147 if ( *p == DIR_SEPARATOR )
01148 p++;
01149
01150 DFS_CanonicalToDir( filename, p );
01151
01152 if ( p > tmppath )
01153 p--;
01154 if ( *p == DIR_SEPARATOR || p == tmppath )
01155 *p = 0;
01156
01157
01158
01159 di.scratch = scratch;
01160 dircluster = di.currentcluster;
01161
01162 if ( DFS_OpenDir( volinfo, tmppath, &di ) )
01163 return DFS_NOTFOUND;
01164
01165 while ( !DFS_GetNext( volinfo, &di, &de ) )
01166 {
01167 if ( !DFS_memcmp( de.name, filename, 11 ) )
01168 {
01169
01170
01171 if ( ( de.attr & ATTR_DIRECTORY ) && ( mode != DFS_CREATEDIR ) )
01172 return DFS_NOTFOUND;
01173
01174 fileinfo->volinfo = volinfo;
01175 fileinfo->pointer = 0;
01176
01177
01178
01179 if ( di.currentcluster == 0 )
01180 fileinfo->dirsector = volinfo->rootdir + di.currentsector;
01181 else
01182 fileinfo->dirsector = volinfo->dataarea + ( ( di.currentcluster - 2 ) * volinfo->secperclus ) + di.currentsector;
01183 fileinfo->diroffset = di.currententry - 1;
01184 if ( volinfo->filesystem == FAT32 )
01185 {
01186 fileinfo->cluster = ( uint32_t ) de.startclus_l_l |
01187 ( ( uint32_t ) de.startclus_l_h ) << 8 |
01188 ( ( uint32_t ) de.startclus_h_l ) << 16 |
01189 ( ( uint32_t ) de.startclus_h_h ) << 24;
01190 }
01191 else
01192 {
01193 fileinfo->cluster = ( uint32_t ) de.startclus_l_l |
01194 ( ( uint32_t ) de.startclus_l_h ) << 8;
01195 }
01196 fileinfo->firstcluster = fileinfo->cluster;
01197 fileinfo->filelen = ( uint32_t ) de.filesize_0 |
01198 ( ( uint32_t ) de.filesize_1 ) << 8 |
01199 ( ( uint32_t ) de.filesize_2 ) << 16 |
01200 ( ( uint32_t ) de.filesize_3 ) << 24;
01201
01202 return DFS_OK;
01203 }
01204 }
01205
01206
01207
01208 if ( mode & DFS_WRITE )
01209 {
01210 uint32_t cluster, temp;
01211
01212
01213 if ( DFS_OK != DFS_GetFreeDirEnt( volinfo, tmppath, &di, &de ) )
01214 return DFS_ERRMISC;
01215
01216
01217 DFS_memset( &de, 0, sizeof( de ) );
01218 DFS_memcpy( de.name, filename, 11 );
01219 de.crttime_l = 0x20;
01220 de.crttime_h = 0x08;
01221 de.crtdate_l = 0x11;
01222 de.crtdate_h = 0x34;
01223 de.lstaccdate_l = 0x11;
01224 de.lstaccdate_h = 0x34;
01225 de.wrttime_l = 0x20;
01226 de.wrttime_h = 0x08;
01227 de.wrtdate_l = 0x11;
01228 de.wrtdate_h = 0x34;
01229
01230
01231 if ( mode == DFS_CREATEDIR ) de.attr |= ATTR_DIRECTORY;
01232
01233
01234 cluster = DFS_GetFreeFAT( volinfo, scratch );
01235
01236 de.startclus_l_l = cluster & 0xff;
01237 de.startclus_l_h = ( cluster & 0xff00 ) >> 8;
01238 de.startclus_h_l = ( cluster & 0xff0000 ) >> 16;
01239 de.startclus_h_h = ( cluster & 0xff000000 ) >> 24;
01240
01241
01242 fileinfo->volinfo = volinfo;
01243 fileinfo->pointer = 0;
01244
01245
01246
01247 if ( di.currentcluster == 0 )
01248 fileinfo->dirsector = volinfo->rootdir + di.currentsector;
01249 else
01250 fileinfo->dirsector = volinfo->dataarea + ( ( di.currentcluster - 2 ) * volinfo->secperclus ) + di.currentsector;
01251 fileinfo->diroffset = di.currententry - 1;
01252 fileinfo->cluster = cluster;
01253 fileinfo->firstcluster = cluster;
01254 fileinfo->filelen = 0;
01255
01256
01257
01258
01259 if ( DFS_ReadSector( volinfo->unit, scratch, fileinfo->dirsector, 1 ) )
01260 return DFS_ERRMISC;
01261 DFS_memcpy( &( ( ( PDIRENT ) scratch )[di.currententry - 1] ), &de, sizeof( DIRENT ) );
01262 if ( DFS_WriteSector( volinfo->unit, scratch, fileinfo->dirsector, 1 ) )
01263 return DFS_ERRMISC;
01264
01265
01266 switch ( volinfo->filesystem )
01267 {
01268 case FAT12: cluster = 0xff8; break;
01269 case FAT16: cluster = 0xfff8; break;
01270 case FAT32: cluster = 0x0ffffff8; break;
01271 default: return DFS_ERRMISC;
01272 }
01273 temp = 0;
01274 DFS_SetFAT( volinfo, scratch, &temp, fileinfo->cluster, cluster );
01275
01276
01277 if ( mode == DFS_CREATEDIR )
01278 {
01279 if ( dircluster <= 2 )
01280 dircluster = 0;
01281
01282 uint32_t startsector = volinfo->dataarea + ( ( fileinfo->cluster - 2 ) * volinfo->secperclus );
01283 uint32_t endsector = startsector + volinfo->secperclus - 1;
01284
01285 DFS_memset( scratch, 0, SECTOR_SIZE );
01286
01287 for ( ; endsector > startsector; endsector -= 1 )
01288 DFS_WriteSector( volinfo->unit, scratch, endsector, 1 );
01289
01290 DFS_memcpy( &( de.name ), ". ", 11 );
01291 de.filesize_0 = 0;
01292 de.filesize_1 = 0;
01293 de.filesize_2 = 0;
01294 de.filesize_3 = 0;
01295 DFS_memcpy( scratch, &de, sizeof( DIRENT ) );
01296
01297 DFS_memcpy( &( de.name ), ".. ", 11 );
01298 de.startclus_l_l = dircluster & 0xff;
01299 de.startclus_l_h = ( dircluster & 0xff00 ) >> 8;
01300 de.startclus_h_l = ( dircluster & 0xff0000 ) >> 16;
01301 de.startclus_h_h = ( dircluster & 0xff000000 ) >> 24;
01302
01303 DFS_memcpy( scratch + sizeof( DIRENT ), &de, sizeof( DIRENT ) );
01304
01305 DFS_WriteSector( volinfo->unit, scratch, startsector, 1 );
01306 }
01307
01308 return DFS_OK;
01309 }
01310
01311 return DFS_NOTFOUND;
01312 }
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 NODEBUG uint32_t DFS_ReadFile( PFILEINFO fileinfo, uint8_t* scratch, uint8_t* buffer, uint32_t* successcount, uint32_t len )
01323 {
01324 uint32_t remain;
01325 uint32_t result = DFS_OK;
01326 uint32_t sector;
01327 uint32_t bytesread;
01328
01329
01330 if ( len > fileinfo->filelen - fileinfo->pointer )
01331 len = fileinfo->filelen - fileinfo->pointer;
01332
01333 remain = len;
01334 *successcount = 0;
01335
01336 while ( remain && result == DFS_OK )
01337 {
01338
01339
01340
01341 sector = fileinfo->volinfo->dataarea +
01342 ( ( fileinfo->cluster - 2 ) * fileinfo->volinfo->secperclus ) +
01343 DFS_div( DFS_div( fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE ).rem, SECTOR_SIZE ).quot;
01344
01345
01346 if ( DFS_div( fileinfo->pointer, SECTOR_SIZE ).rem )
01347 {
01348 uint16_t tempreadsize;
01349
01350
01351 result = DFS_ReadSector( fileinfo->volinfo->unit, scratch, sector, 1 );
01352
01353
01354
01355 tempreadsize = SECTOR_SIZE - ( DFS_div( fileinfo->pointer, SECTOR_SIZE ).rem );
01356
01357
01358
01359
01360 if ( remain >= tempreadsize )
01361 {
01362 DFS_memcpy( buffer, scratch + ( SECTOR_SIZE - tempreadsize ), tempreadsize );
01363 bytesread = tempreadsize;
01364 buffer += tempreadsize;
01365 fileinfo->pointer += tempreadsize;
01366 remain -= tempreadsize;
01367 }
01368
01369 else
01370 {
01371 DFS_memcpy( buffer, scratch + ( SECTOR_SIZE - tempreadsize ), remain );
01372
01373 buffer += remain;
01374 fileinfo->pointer += remain;
01375 bytesread = remain;
01376 remain = 0;
01377 }
01378 }
01379
01380 else
01381 {
01382
01383
01384
01385
01386
01387
01388
01389 if ( remain >= SECTOR_SIZE )
01390 {
01391 result = DFS_ReadSector( fileinfo->volinfo->unit, buffer, sector, 1 );
01392 remain -= SECTOR_SIZE;
01393 buffer += SECTOR_SIZE;
01394 fileinfo->pointer += SECTOR_SIZE;
01395 bytesread = SECTOR_SIZE;
01396 }
01397
01398 else
01399 {
01400 result = DFS_ReadSector( fileinfo->volinfo->unit, scratch, sector, 1 );
01401 DFS_memcpy( buffer, scratch, remain );
01402 buffer += remain;
01403 fileinfo->pointer += remain;
01404 bytesread = remain;
01405 remain = 0;
01406 }
01407 }
01408
01409 *successcount += bytesread;
01410
01411
01412 if ( DFS_div( fileinfo->pointer - bytesread, fileinfo->volinfo->secperclus * SECTOR_SIZE ).quot !=
01413 DFS_div( fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE ).quot )
01414 {
01415
01416
01417 bytesread = 0;
01418 if ( ( ( fileinfo->volinfo->filesystem == FAT12 ) && ( fileinfo->cluster >= 0xff8 ) ) ||
01419 ( ( fileinfo->volinfo->filesystem == FAT16 ) && ( fileinfo->cluster >= 0xfff8 ) ) ||
01420 ( ( fileinfo->volinfo->filesystem == FAT32 ) && ( fileinfo->cluster >= 0x0ffffff8 ) ) )
01421 result = DFS_EOF;
01422 else
01423 fileinfo->cluster = DFS_GetFAT( fileinfo->volinfo, scratch, &bytesread, fileinfo->cluster );
01424 }
01425 }
01426
01427 return result;
01428 }
01429
01430
01431
01432
01433
01434
01435
01436 NODEBUG void DFS_Seek( PFILEINFO fileinfo, uint32_t offset, uint8_t* scratch )
01437 {
01438 uint32_t tempint;
01439
01440
01441
01442 if ( offset == fileinfo->pointer )
01443 {
01444 return;
01445 }
01446
01447
01448 if ( offset > fileinfo->filelen )
01449 {
01450 offset = fileinfo->filelen;
01451
01452 }
01453
01454
01455
01456 if ( offset == 0 )
01457 {
01458 fileinfo->cluster = fileinfo->firstcluster;
01459 fileinfo->pointer = 0;
01460 return;
01461 }
01462
01463 else if ( offset < fileinfo->pointer )
01464 {
01465 fileinfo->cluster = fileinfo->firstcluster;
01466 fileinfo->pointer = 0;
01467
01468 }
01469
01470
01471
01472
01473
01474
01475
01476 if ( DFS_div( fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE ).quot ==
01477 DFS_div( fileinfo->pointer + offset, fileinfo->volinfo->secperclus * SECTOR_SIZE ).quot )
01478 {
01479 fileinfo->pointer = offset;
01480 }
01481
01482 else
01483 {
01484
01485 fileinfo->pointer = DFS_div( fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE ).quot *
01486 fileinfo->volinfo->secperclus * SECTOR_SIZE;
01487
01488
01489
01490 while ( DFS_div( fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE ).quot !=
01491 DFS_div( offset, fileinfo->volinfo->secperclus * SECTOR_SIZE ).quot )
01492 {
01493
01494
01495
01496
01497
01498 fileinfo->cluster = DFS_GetFAT( fileinfo->volinfo, scratch, &tempint, fileinfo->cluster );
01499
01500 if ( fileinfo->cluster == 0x0ffffff7 )
01501 {
01502 fileinfo->pointer = 0;
01503 fileinfo->cluster = fileinfo->firstcluster;
01504 return;
01505 }
01506 fileinfo->pointer += SECTOR_SIZE * fileinfo->volinfo->secperclus;
01507 }
01508
01509
01510 fileinfo->pointer = offset;
01511 }
01512 }
01513
01514
01515
01516
01517
01518 NODEBUG uint32_t DFS_UnlinkFile( PVOLINFO volinfo, uint8_t* path, uint8_t* scratch )
01519 {
01520 PDIRENT de = ( PDIRENT ) scratch;
01521 FILEINFO fi;
01522 uint32_t cache = 0;
01523 uint32_t tempclus;
01524
01525
01526 if ( DFS_OK != DFS_OpenFile( volinfo, path, DFS_READ, scratch, &fi ) )
01527 return DFS_NOTFOUND;
01528
01529
01530 if ( DFS_ReadSector( volinfo->unit, scratch, fi.dirsector, 1 ) )
01531 return DFS_ERRMISC;
01532 ( ( PDIRENT ) scratch )[fi.diroffset].name[0] = 0xe5;
01533 if ( DFS_WriteSector( volinfo->unit, scratch, fi.dirsector, 1 ) )
01534 return DFS_ERRMISC;
01535
01536
01537 while ( !( ( volinfo->filesystem == FAT12 && fi.firstcluster >= 0x0ff7 ) ||
01538 ( volinfo->filesystem == FAT16 && fi.firstcluster >= 0xfff7 ) ||
01539 ( volinfo->filesystem == FAT32 && fi.firstcluster >= 0x0ffffff7 ) ) )
01540 {
01541 tempclus = fi.firstcluster;
01542
01543 fi.firstcluster = DFS_GetFAT( volinfo, scratch, &cache, fi.firstcluster );
01544 DFS_SetFAT( volinfo, scratch, &cache, tempclus, 0 );
01545
01546 }
01547 return DFS_OK;
01548 }
01549
01550
01551
01552
01553
01554
01555
01556
01557 NODEBUG uint32_t DFS_WriteFile( PFILEINFO fileinfo, uint8_t* scratch, uint8_t* buffer, uint32_t* successcount, uint32_t len )
01558 {
01559 uint32_t remain;
01560 uint32_t result = DFS_OK;
01561 uint32_t sector;
01562 uint32_t byteswritten;
01563
01564
01565 if ( !( fileinfo->mode & DFS_WRITE ) )
01566 return DFS_ERRMISC;
01567
01568 remain = len;
01569 *successcount = 0;
01570
01571 while ( remain && result == DFS_OK )
01572 {
01573
01574
01575
01576 sector = fileinfo->volinfo->dataarea +
01577 ( ( fileinfo->cluster - 2 ) * fileinfo->volinfo->secperclus ) +
01578 DFS_div( DFS_div( fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE ).rem, SECTOR_SIZE ).quot;
01579
01580
01581 if ( DFS_div( fileinfo->pointer, SECTOR_SIZE ).rem )
01582 {
01583 uint16_t tempsize;
01584
01585
01586 result = DFS_ReadSector( fileinfo->volinfo->unit, scratch, sector, 1 );
01587
01588
01589
01590 tempsize = DFS_div( fileinfo->pointer, SECTOR_SIZE ).rem;
01591
01592
01593
01594
01595
01596 if ( remain >= SECTOR_SIZE - tempsize )
01597 {
01598 DFS_memcpy( scratch + tempsize, buffer, SECTOR_SIZE - tempsize );
01599 if ( !result )
01600 result = DFS_WriteSector( fileinfo->volinfo->unit, scratch, sector, 1 );
01601
01602 byteswritten = SECTOR_SIZE - tempsize;
01603 buffer += SECTOR_SIZE - tempsize;
01604 fileinfo->pointer += SECTOR_SIZE - tempsize;
01605 if ( fileinfo->filelen < fileinfo->pointer )
01606 {
01607 fileinfo->filelen = fileinfo->pointer;
01608 }
01609 remain -= SECTOR_SIZE - tempsize;
01610 }
01611
01612 else
01613 {
01614 DFS_memcpy( scratch + tempsize, buffer, remain );
01615 if ( !result )
01616 result = DFS_WriteSector( fileinfo->volinfo->unit, scratch, sector, 1 );
01617
01618 buffer += remain;
01619 fileinfo->pointer += remain;
01620 if ( fileinfo->filelen < fileinfo->pointer )
01621 {
01622 fileinfo->filelen = fileinfo->pointer;
01623 }
01624 byteswritten = remain;
01625 remain = 0;
01626 }
01627 }
01628
01629 else
01630 {
01631
01632
01633
01634
01635 if ( remain >= SECTOR_SIZE )
01636 {
01637 result = DFS_WriteSector( fileinfo->volinfo->unit, buffer, sector, 1 );
01638 remain -= SECTOR_SIZE;
01639 buffer += SECTOR_SIZE;
01640 fileinfo->pointer += SECTOR_SIZE;
01641 if ( fileinfo->filelen < fileinfo->pointer )
01642 {
01643 fileinfo->filelen = fileinfo->pointer;
01644 }
01645 byteswritten = SECTOR_SIZE;
01646 }
01647
01648
01649 else
01650 {
01651
01652
01653
01654 if ( fileinfo->pointer < fileinfo->filelen )
01655 {
01656 result = DFS_ReadSector( fileinfo->volinfo->unit, scratch, sector, 1 );
01657 if ( !result )
01658 {
01659 DFS_memcpy( scratch, buffer, remain );
01660 result = DFS_WriteSector( fileinfo->volinfo->unit, scratch, sector, 1 );
01661 }
01662 }
01663 else
01664 {
01665 result = DFS_WriteSector( fileinfo->volinfo->unit, buffer, sector, 1 );
01666 }
01667
01668 buffer += remain;
01669 fileinfo->pointer += remain;
01670 if ( fileinfo->filelen < fileinfo->pointer )
01671 {
01672 fileinfo->filelen = fileinfo->pointer;
01673 }
01674 byteswritten = remain;
01675 remain = 0;
01676 }
01677 }
01678
01679 *successcount += byteswritten;
01680
01681
01682 if ( DFS_div( fileinfo->pointer - byteswritten, fileinfo->volinfo->secperclus * SECTOR_SIZE ).quot !=
01683 DFS_div( fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE ).quot )
01684 {
01685 uint32_t lastcluster;
01686
01687
01688
01689
01690
01691 byteswritten = 0;
01692
01693 lastcluster = fileinfo->cluster;
01694 fileinfo->cluster = DFS_GetFAT( fileinfo->volinfo, scratch, &byteswritten, fileinfo->cluster );
01695
01696
01697 if ( ( ( fileinfo->volinfo->filesystem == FAT12 ) && ( fileinfo->cluster >= 0xff8 ) ) ||
01698 ( ( fileinfo->volinfo->filesystem == FAT16 ) && ( fileinfo->cluster >= 0xfff8 ) ) ||
01699 ( ( fileinfo->volinfo->filesystem == FAT32 ) && ( fileinfo->cluster >= 0x0ffffff8 ) ) )
01700 {
01701 uint32_t tempclus;
01702
01703 tempclus = DFS_GetFreeFAT( fileinfo->volinfo, scratch );
01704 byteswritten = 0;
01705 if ( tempclus == 0x0ffffff7 )
01706 return DFS_ERRMISC;
01707
01708
01709 DFS_SetFAT( fileinfo->volinfo, scratch, &byteswritten, lastcluster, tempclus );
01710 fileinfo->cluster = tempclus;
01711
01712
01713 switch ( fileinfo->volinfo->filesystem )
01714 {
01715 case FAT12: tempclus = 0xff8; break;
01716 case FAT16: tempclus = 0xfff8; break;
01717 case FAT32: tempclus = 0x0ffffff8; break;
01718 default: return DFS_ERRMISC;
01719 }
01720 DFS_SetFAT( fileinfo->volinfo, scratch, &byteswritten, fileinfo->cluster, tempclus );
01721
01722 result = DFS_OK;
01723 }
01724
01725 }
01726 }
01727
01728
01729 if ( DFS_ReadSector( fileinfo->volinfo->unit, scratch, fileinfo->dirsector, 1 ) )
01730 return DFS_ERRMISC;
01731 ( ( PDIRENT ) scratch )[fileinfo->diroffset].filesize_0 = fileinfo->filelen & 0xff;
01732 ( ( PDIRENT ) scratch )[fileinfo->diroffset].filesize_1 = ( fileinfo->filelen & 0xff00 ) >> 8;
01733 ( ( PDIRENT ) scratch )[fileinfo->diroffset].filesize_2 = ( fileinfo->filelen & 0xff0000 ) >> 16;
01734 ( ( PDIRENT ) scratch )[fileinfo->diroffset].filesize_3 = ( fileinfo->filelen & 0xff000000 ) >> 24;
01735 if ( DFS_WriteSector( fileinfo->volinfo->unit, scratch, fileinfo->dirsector, 1 ) )
01736 return DFS_ERRMISC;
01737 return result;
01738 }
01739
01740 NODEBUG u32 DFS_UnMount( enum STORAGE_device device )
01741 {
01742 #if SDCARD_SDIO
01743 SDIO_SetPowerState( SDIO_PowerState_OFF );
01744 #endif
01745 SD_DeInit();
01746 }
01747
01748 NODEBUG u32 DFS_Mount( enum STORAGE_device device )
01749 {
01750 uint8_t sector[SECTOR_SIZE];
01751 uint32_t pstart, psize;
01752 uint8_t pactive, ptype;
01753
01754 switch ( device )
01755 {
01756 case MMCSD_SDIO:
01757 {
01758
01759
01760
01761
01762
01763 Status = SD_Init();
01764
01765 if ( Status != SD_OK )
01766 return -1;
01767
01768 if ( DFS_ReadSector( 0, sector, 0, 1 ) )
01769 {
01770
01771 return -1;
01772 }
01773
01774 if ( ( sector[0x1FE] == 0x55 ) & ( sector[0x1FF] == 0xAA ) )
01775 {
01776
01777 if ( ( sector[0x36] == 'F' ) & ( sector[0x37] == 'A' ) & ( sector[0x38] == 'T' ) )
01778 {
01779
01780 pstart = 0;
01781 pactive = 0x80;
01782 ptype = 0x06;
01783 psize = 0xFFFFFFFF;
01784 }
01785 else if ( ( sector[0x52] == 'F' ) & ( sector[0x53] == 'A' ) & ( sector[0x54] == 'T' ) )
01786 {
01787
01788 pstart = 0;
01789 pactive = 0x80;
01790 ptype = 0x06;
01791 psize = 0xFFFFFFFF;
01792 }
01793 else
01794 {
01795 pstart = DFS_GetPtnStart( 0, sector, 0, &pactive, &ptype, &psize );
01796 if ( pstart == 0xffffffff )
01797 {
01798
01799 return -1;
01800 }
01801 }
01802 return pstart;
01803 }
01804 }
01805 default:
01806 break;
01807 }
01808 }