Subversion Repositories NaviCtrl

Rev

Rev 378 | Rev 380 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 378 Rev 379
Line 52... Line 52...
52
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
52
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
53
// + #### END OF LICENSING TERMS ####
53
// + #### END OF LICENSING TERMS ####
54
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
54
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56
#include <stdio.h>
56
#include <stdio.h>
-
 
57
#include <string.h>
57
#include "91x_lib.h"
58
#include "91x_lib.h"
58
#include "timer1.h"
59
#include "timer1.h"
59
#include "fat16.h"
60
#include "fat16.h"
60
#include "sdc.h"
61
#include "sdc.h"
61
#include "uart1.h"
62
#include "uart1.h"
62
#include "logging.h"
-
 
63
#include "led.h"
63
#include "main.h"
-
 
64
 
64
//________________________________________________________________________________________________________________________________________
65
//________________________________________________________________________________________________________________________________________
65
// Module name:                 fat16.c
66
// Module name:                 fat16.c
66
// Compiler used:               avr-gcc 3.4.5
67
// Compiler used:               avr-gcc 3.4.5
67
// Last Modifikation:   20.03.2010
68
// Last Modifikation:   20.03.2010
68
// Version:                             2.10
69
// Version:                             2.10
Line 104... Line 105...
104
Root Directory Entry                            Start + # of Reserved + (# of Sectors Per FAT * 2)
105
Root Directory Entry                            Start + # of Reserved + (# of Sectors Per FAT * 2)
105
Data Area (Starts with Cluster #2)      Start + # of Reserved + (# of Sectors Per FAT * 2) + ((Maximum Root Directory Entries * 32) / Bytes per Sector)
106
Data Area (Starts with Cluster #2)      Start + # of Reserved + (# of Sectors Per FAT * 2) + ((Maximum Root Directory Entries * 32) / Bytes per Sector)
106
*/
107
*/
Line -... Line 108...
-
 
108
 
107
 
109
 
108
 
110
 
Line 109... Line 111...
109
/*
111
/*
110
________________________________________________________________________________________________________________________________________
112
________________________________________________________________________________________________________________________________________
Line 124... Line 126...
124
        u16     EndCylSec;                                      // End of Partition - Cylinder/Sector
126
        u16     EndCylSec;                                      // End of Partition - Cylinder/Sector
125
        u32     NoSectorsBeforePartition;       // Number of Sectors between the MBR and the First Sector in the Partition
127
        u32     NoSectorsBeforePartition;       // Number of Sectors between the MBR and the First Sector in the Partition
126
        u32     NoSectorsPartition      ;               // Number of Sectors in the Partition
128
        u32     NoSectorsPartition      ;               // Number of Sectors in the Partition
127
} __attribute__((packed)) PartitionEntry_t;
129
} __attribute__((packed)) PartitionEntry_t;
Line -... Line 130...
-
 
130
 
-
 
131
 
128
 
132
 
129
/*
133
/*
Line 130... Line 134...
130
Coding of Cylinder/Sector words
134
Coding of Cylinder/Sector words
131
 
135
 
Line 307... Line 311...
307
        u16     SectorsPerFat;                  // how many sectors does a fat16 contain?
311
        u16     SectorsPerFat;                  // how many sectors does a fat16 contain?
308
        u32 FirstFatSector;                     // sector of the start of the fat
312
        u32 FirstFatSector;                     // sector of the start of the fat
309
        u32 FirstRootDirSector;         // sector of the rootdirectory
313
        u32 FirstRootDirSector;         // sector of the rootdirectory
310
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
314
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
311
        u32 LastDataSector;                     // the last data sector of the partition
315
        u32 LastDataSector;                     // the last data sector of the partition
312
        u8 VolumeLabel[12];                     // the volume label
316
        u8  VolumeLabel[12];        // the volume label
-
 
317
        u32     CurrentWorkingDirectory;// A pointer to the directory we are actual using 
-
 
318
        s8      PathToCwd[256];                 // a string containing the complete path to the current working directory                               
313
} Partition_t;
319
}   __attribute__((packed)) Partition_t;
Line 314... Line 320...
314
 
320
 
Line 315... Line 321...
315
Partition_t     Partition;                                      // Structure holds partition information
321
Partition_t     Partition;              // Structure holds partition information
Line -... Line 322...
-
 
322
 
-
 
323
File_t FilePointer[FILE_MAX_OPEN];      // Allocate Memmoryspace for each filepointer used.
316
 
324
 
317
File_t FilePointer[FILE_MAX_OPEN];      // Allocate Memmoryspace for each filepointer used.
325
 
318
 
326
 
319
 
327
 
320
/****************************************************************************************************************************************/
328
/****************************************************************************************************************************************/
Line 442... Line 450...
442
        }
450
        }
Line 443... Line 451...
443
 
451
 
444
        // clear dirname with spaces
452
        // clear dirname with spaces
445
        dirname[11] = 0; // terminate dirname
453
        dirname[11] = 0; // terminate dirname
-
 
454
        for(writepointer = 0; writepointer < 11; writepointer++) dirname[writepointer] = ' ';
-
 
455
 
-
 
456
        // handle the special dirnames "." and ".." seperately
-
 
457
        readpointer = 0;
-
 
458
        if(filepath[0] == '/') readpointer++;
-
 
459
        // if we are trying to enter directories "." or ".." 
-
 
460
        if(filepath[readpointer] == '.')
-
 
461
        {
-
 
462
                // directory '.'
-
 
463
                if(filepath[readpointer+1] == 0)
-
 
464
                {
-
 
465
                        dirname[0] = '.';
-
 
466
                        return((s8*)&filepath[readpointer]);
-
 
467
                }
-
 
468
                // directory '..'               
-
 
469
                if((filepath[readpointer+1] == '.') &&  (filepath[readpointer+2] == 0))
-
 
470
                {
-
 
471
                        dirname[0] = '.';
-
 
472
                        dirname[1] = '.';
-
 
473
                        return((s8*)&filepath[readpointer]);
-
 
474
                }
-
 
475
        }
446
        for(writepointer = 0; writepointer < 11; writepointer++) dirname[writepointer] = ' ';
476
 
447
        writepointer = 0;
477
        writepointer = 0;
448
        // start seperating the dirname from the filepath.
478
        // start seperating the dirname from the filepath.
449
        readpointer = 0;
479
        readpointer = 0;
450
        if(filepath[0] == '/') readpointer = 1; // ignore first '/'
480
        if(filepath[0] == '/') readpointer = 1; // ignore first '/'
Line 547... Line 577...
547
        }
577
        }
548
        returnvalue = SDC_Deinit();                     // uninitialize interface to sd-card
578
        returnvalue = SDC_Deinit();                     // uninitialize interface to sd-card
549
        Partition.IsValid = 0;  // mark data in partition structure as invalid
579
        Partition.IsValid = 0;  // mark data in partition structure as invalid
550
        Partition.VolumeLabel[0]='\0';
580
        Partition.VolumeLabel[0]='\0';
551
        UART1_PutString("ok");
581
        UART1_PutString("ok");
552
        SD_LoggingError = 100;
582
SD_WatchDog = 0;
553
        return(returnvalue);
583
        return(returnvalue);
554
}
584
}
Line 555... Line 585...
555
 
585
 
556
/****************************************************************************************************************************************/
586
/****************************************************************************************************************************************/
Line 570... Line 600...
570
        File_t *file;
600
        File_t *file;
571
        u8 result = 0;
601
        u8 result = 0;
Line 572... Line 602...
572
 
602
 
573
        UART1_PutString("\r\n FAT16 init...");
603
        UART1_PutString("\r\n FAT16 init...");
574
        Partition.IsValid = 0;
-
 
575
 
604
        Partition.IsValid = 0;
576
        // declare the filepointers as unused.
605
        // declare the filepointers as unused.
577
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
606
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
578
        {
607
        {
579
                UnlockFilePointer(&FilePointer[cnt]);
608
                UnlockFilePointer(&FilePointer[cnt]);
Line 653... Line 682...
653
                UART1_PutString("VBR: Partition ist not FAT16 type.");
682
                UART1_PutString("VBR: Partition ist not FAT16 type.");
654
                result = 6;
683
                result = 6;
655
                goto end;
684
                goto end;
656
        }
685
        }
657
        Partition.IsValid = 1; // mark data in partition structure as valid
686
        Partition.IsValid = 1; // mark data in partition structure as valid
-
 
687
        Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
-
 
688
        strcpy(Partition.PathToCwd,"/");       
658
        result = 0;
689
        result = 0;
659
        end:
690
        end:
660
        if(result != 0) Fat16_Deinit();
691
        if(result != 0) Fat16_Deinit();
661
        else UART1_PutString("ok");
692
        else UART1_PutString("ok");
662
        return(result);
693
        return(result);
Line 684... Line 715...
684
        {
715
        {
685
                file->SectorInCache = file->FirstSectorOfCurrCluster + i;
716
                file->SectorInCache = file->FirstSectorOfCurrCluster + i;
686
                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
717
                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
687
                {
718
                {
688
                        Fat16_Deinit();
719
                        Fat16_Deinit();
689
                        retvalue = 0;
-
 
690
                        return(retvalue);
720
                        return(0);
691
                }
721
                }
692
        }
722
        }
693
        return(retvalue);
723
        return(retvalue);
694
}
724
}
Line 724... Line 754...
724
                {
754
                {
725
                        file->SectorInCache = sector;                                           // update sector stored in buffer
755
                        file->SectorInCache = sector;                                           // update sector stored in buffer
726
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))       // read sector from sd-card
756
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))       // read sector from sd-card
727
                        {
757
                        {
728
                                Fat16_Deinit();
758
                                Fat16_Deinit();
729
                                return (cluster);
759
                                return (CLUSTER_UNDEFINED);
730
                        }
760
                        }
731
                }
761
                }
732
                // read the next cluster from cache
762
                // read the next cluster from cache
733
                fat = (Fat16Entry_t *)(&(file->Cache[byte]));
763
                fat = (Fat16Entry_t *)(&(file->Cache[byte]));
734
                cluster = fat->NextCluster;
764
                cluster = fat->NextCluster;
Line 746... Line 776...
746
        }
776
        }
747
        return(cluster);
777
        return(cluster);
748
}
778
}
Line -... Line 779...
-
 
779
 
749
 
780
 
750
 
781
 
751
/****************************************************************************************************************************************/
782
/****************************************************************************************************************************************/
752
/* Function:    FindNextFreeCluster(File_t *);                                                                                                                                                                          */
783
/* Function:    FindNextFreeCluster(File_t *);                                                                                                                                                                          */
753
/*                                                                                                                                                                                                                                                                              */
784
/*                                                                                                                                                                                                                                                                              */
Line 772... Line 803...
772
                curr_sector = Partition.FirstFatSector + fat_sector;    // calculate sector to read
803
                curr_sector = Partition.FirstFatSector + fat_sector;    // calculate sector to read
773
                file->SectorInCache = curr_sector;                                              // upate the sector number of file cache.
804
                file->SectorInCache = curr_sector;                                              // upate the sector number of file cache.
774
                if( SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))              // read sector of fat from sd-card.
805
                if( SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))              // read sector of fat from sd-card.
775
                {
806
                {
776
                        Fat16_Deinit();
807
                        Fat16_Deinit();
777
                        return(free_cluster);
808
                        return(CLUSTER_UNDEFINED);
778
                }
809
                }
Line 779... Line 810...
779
 
810
 
Line 780... Line 811...
780
                fat = (Fat16Entry_t *)file->Cache;                                              // set fat pointer to file cache
811
                fat = (Fat16Entry_t *)file->Cache;                                              // set fat pointer to file cache
Line 785... Line 816...
785
                        {
816
                        {
786
                                fat[fat_entry].NextCluster = FAT16_CLUSTER_LAST_MAX;    // mark this fat-entry as used
817
                                fat[fat_entry].NextCluster = FAT16_CLUSTER_LAST_MAX;    // mark this fat-entry as used
787
                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // and save the sector at the sd-card.
818
                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // and save the sector at the sd-card.
788
                                {
819
                                {
789
                                        Fat16_Deinit();
820
                                        Fat16_Deinit();
790
                                        return(free_cluster);
821
                                        return(CLUSTER_UNDEFINED);
791
                                }
822
                                }
792
                                free_cluster = (u16)(fat_sector * FAT16_ENTRIES_PER_SECTOR + (u32)fat_entry);
823
                                free_cluster = (u16)(fat_sector * FAT16_ENTRIES_PER_SECTOR + (u32)fat_entry);
793
                                fat_entry = FAT16_ENTRIES_PER_SECTOR;                                   // terminate the search for a free cluster in this sector.
824
                                fat_entry = FAT16_ENTRIES_PER_SECTOR;                                   // terminate the search for a free cluster in this sector.
794
                        }
825
                        }
795
                }
826
                }
Line 1036... Line 1067...
1036
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return(direntry_exist);
1067
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return(direntry_exist);
Line 1037... Line 1068...
1037
 
1068
 
1038
        // dir entries can be searched only in filesclusters that have
1069
        // dir entries can be searched only in filesclusters that have
1039
        // a corresponding dir entry with adir-flag set in its attribute
1070
        // a corresponding dir entry with adir-flag set in its attribute
1040
        // or direct within the root directory area
-
 
1041
 
1071
        // or direct within the root directory area
1042
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1072
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1043
        // no current directory exist therefore assume searching in the root
1073
        // no current directory exist therefore assume searching in the root
1044
        if(file->DirectorySector == SECTOR_UNDEFINED)
1074
        if(file->DirectorySector == SECTOR_UNDEFINED)
1045
        {
1075
        {
Line 1063... Line 1093...
1063
                // check if the directory entry of current file is existent and has the dir-flag set
1093
                // check if the directory entry of current file is existent and has the dir-flag set
1064
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1094
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1065
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1095
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1066
                {
1096
                {
1067
                        Fat16_Deinit();
1097
                        Fat16_Deinit();
1068
                        return(direntry_exist);
1098
                        return(0);
1069
                }
1099
                }
1070
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1100
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1071
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1101
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1072
                {
1102
                {
1073
                        case SLOT_EMPTY:
1103
                        case SLOT_EMPTY:
Line 1091... Line 1121...
1091
        file->SectorOfCurrCluster               = 0;
1121
        file->SectorOfCurrCluster               = 0;
1092
        file->ByteOfCurrSector                  = 0;
1122
        file->ByteOfCurrSector                  = 0;
Line 1093... Line 1123...
1093
 
1123
 
1094
        do // loop over all data clusters of the current directory entry
1124
        do // loop over all data clusters of the current directory entry
1095
        {
1125
        {
1096
                dir_sector = 0; // reset sector counter within a new cluster
1126
                dir_sector = 0;
1097
                do // loop over all sectors of a cluster or all sectors of the root directory
1127
                do // loop over all sectors of a cluster or all sectors of the root directory
1098
                {
1128
                {
1099
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1129
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1100
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1130
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1101
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
1131
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
1102
                        {
1132
                        {
1103
                                Fat16_Deinit();
1133
                                Fat16_Deinit();
1104
                                return(direntry_exist);
1134
                                return(0);
1105
                        }
1135
                        }
1106
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1136
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1107
                        // search all directory entries within that sector
1137
                        // search all directory entries within that sector
1108
                        for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
1138
                        for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
Line 1196... Line 1226...
1196
            // check if the directory entry of current file is existent and has the dir-flag set
1226
            // check if the directory entry of current file is existent and has the dir-flag set
1197
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1227
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1198
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1228
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1199
                {
1229
                {
1200
                        Fat16_Deinit();
1230
                        Fat16_Deinit();
1201
                        return(retvalue);
1231
                        return(0);
1202
                }
1232
                }
1203
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1233
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1204
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1234
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1205
                {
1235
                {
1206
                        case SLOT_EMPTY:
1236
                        case SLOT_EMPTY:
Line 1238... Line 1268...
1238
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1268
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1239
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1269
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1240
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1270
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1241
                        {
1271
                        {
1242
                                Fat16_Deinit();
1272
                                Fat16_Deinit();
1243
                                return(retvalue);
1273
                                return(0);
1244
                        }
1274
                        }
Line 1245... Line 1275...
1245
 
1275
 
1246
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1276
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1247
                        // search all directory entries of a sector
1277
                        // search all directory entries of a sector
Line 1264... Line 1294...
1264
                                        dir[dir_entry].StartCluster = subdircluster;                                            // copy the location of the first datacluster to the directoryentry.
1294
                                        dir[dir_entry].StartCluster = subdircluster;                                            // copy the location of the first datacluster to the directoryentry.
1265
                                        dir[dir_entry].Size             = 0;                                                                    // the new createted file has no content yet.
1295
                                        dir[dir_entry].Size             = 0;                                                                    // the new createted file has no content yet.
1266
                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to card
1296
                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to card
1267
                                        {
1297
                                        {
1268
                                                Fat16_Deinit();
1298
                                                Fat16_Deinit();
1269
                                                return(retvalue);
1299
                                                return(0);
1270
                                        }
1300
                                        }
1271
                                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(subdircluster);  // Calculate absolute sectorposition of first datacluster.
1301
                                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(subdircluster);  // Calculate absolute sectorposition of first datacluster.
1272
                                        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;      // Start reading the file with the first sector of the first datacluster.
1302
                                        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;      // Start reading the file with the first sector of the first datacluster.
1273
                                        file->SectorOfCurrCluster               = 0;                                                            // reset sector of cureen cluster
1303
                                        file->SectorOfCurrCluster               = 0;                                                            // reset sector of cureen cluster
1274
                                        file->ByteOfCurrSector                  = 0;                                                            // reset the byte location within the current sector
1304
                                        file->ByteOfCurrSector                  = 0;                                                            // reset the byte location within the current sector
Line 1282... Line 1312...
1282
                                                ClearCurrCluster(file); // fill cluster with zeros
1312
                                                ClearCurrCluster(file); // fill cluster with zeros
1283
                                                file->SectorInCache = file->FirstSectorOfFirstCluster;
1313
                                                file->SectorInCache = file->FirstSectorOfFirstCluster;
1284
                                                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1314
                                                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1285
                                                {
1315
                                                {
1286
                                                        Fat16_Deinit();
1316
                                                        Fat16_Deinit();
1287
                                                        return(retvalue);
1317
                                                        return(0);
1288
                                                }
1318
                                                }
1289
                                                dir = (DirEntry_t *)file->Cache;
1319
                                                dir = (DirEntry_t *)file->Cache;
1290
                                                // create direntry "." to current dir
1320
                                                // create direntry "." to current dir
1291
                                                dir[0].Name[0] = 0x2E;
1321
                                                dir[0].Name[0] = 0x2E;
1292
                                                for(i = 1; i < 11; i++) dir[0].Name[i] = ' ';
1322
                                                for(i = 1; i < 11; i++) dir[0].Name[i] = ' ';
Line 1301... Line 1331...
1301
                                                dir[1].StartCluster = dircluster;
1331
                                                dir[1].StartCluster = dircluster;
1302
                                                dir[1].Size = 0;
1332
                                                dir[1].Size = 0;
1303
                                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))// read in the sector.
1333
                                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))// read in the sector.
1304
                                                {
1334
                                                {
1305
                                                        Fat16_Deinit();
1335
                                                        Fat16_Deinit();
1306
                                                        return(retvalue);
1336
                                                        return(0);
1307
                                                }
1337
                                                }
1308
                                        }
1338
                                        }
1309
                                        retvalue = 1;
1339
                                        retvalue = 1;
1310
                                        dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
1340
                                        dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
1311
                                }
1341
                                }
Line 1349... Line 1379...
1349
 
1379
 
1350
        // trace along the filepath
1380
        // trace along the filepath
1351
        path = (s8*)filename;                                                           // start a the beginning of the filename string
1381
        path = (s8*)filename;                                                           // start a the beginning of the filename string
1352
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
1382
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
-
 
1383
        file->DirectoryIndex = 0;
-
 
1384
        /* if a path begins with a '/' at index 0 the search starts at the rootdirectory otherwise we will start relative to the cwd */
-
 
1385
        if(path[0] != '/')
-
 
1386
        {
-
 
1387
                /* is the current working directory the rootdirectory? */
-
 
1388
                if(Partition.CurrentWorkingDirectory == Partition.FirstRootDirSector) file->DirectorySector = 0;
-
 
1389
                /* otherwise we are working in an subdirectory */
-
 
1390
                else file->DirectorySector = Partition.CurrentWorkingDirectory;
1353
        file->DirectoryIndex = 0;
1391
        }
1354
        // as long as the file was not found and the remaining path is not empty
1392
        // as long as the file was not found and the remaining path is not empty
1355
        while((*path != 0) && !file_exist)
1393
        while((*path != 0) && !file_exist)
1356
        {       // separate dirname and subpath from filepath string
1394
        {       // separate dirname and subpath from filepath string
1357
                subpath = SeperateDirName(path, dirname);
1395
                subpath = SeperateDirName(path, dirname);
Line 1459... Line 1497...
1459
/*      Returnvalue:    The filepointer to the file or 0 if faild.                                                                                                                                                              */
1497
/*      Returnvalue:    The filepointer to the file or 0 if faild.                                                                                                                                                              */
1460
/********************************************************************************************************************************************/
1498
/********************************************************************************************************************************************/
1461
File_t * fopen_(s8 * const filename, const s8 mode)
1499
File_t * fopen_(s8 * const filename, const s8 mode)
1462
{
1500
{
1463
        File_t *file    = 0;
1501
        File_t *file    = 0;
-
 
1502
        s8 *cptr;
Line 1464... Line 1503...
1464
 
1503
 
Line 1465... Line 1504...
1465
        if((!Partition.IsValid) || (filename == 0)) return(file);
1504
        if((!Partition.IsValid) || (filename == 0)) return(file);
1466
 
1505
 
Line 1481... Line 1520...
1481
        file->SectorInCache                             = SECTOR_UNDEFINED;             // the last sector read, wich is still in the sectorbuffer.
1520
        file->SectorInCache                             = SECTOR_UNDEFINED;             // the last sector read, wich is still in the sectorbuffer.
1482
        file->DirectorySector                   = SECTOR_UNDEFINED;             // the sectorposition where the directoryentry has been made.
1521
        file->DirectorySector                   = SECTOR_UNDEFINED;             // the sectorposition where the directoryentry has been made.
1483
        file->DirectoryIndex                    = 0;            // the index to the directoryentry within the specified sector.
1522
        file->DirectoryIndex                    = 0;            // the index to the directoryentry within the specified sector.
1484
        file->Attribute                                 = 0;            // the attribute of the file opened.
1523
        file->Attribute                                 = 0;            // the attribute of the file opened.
Line -... Line 1524...
-
 
1524
 
-
 
1525
        // bring the path into the correct syntax 
-
 
1526
        cptr = filename;
-
 
1527
        // search the whole string 
-
 
1528
        while(*cptr != 0)
-
 
1529
        {
-
 
1530
                // replace all '\' by '/'
-
 
1531
                if(*cptr == '\\') *cptr = '/';
-
 
1532
                cptr++;
1485
 
1533
        }
1486
        // check if a real file (no directory) to the given filename exist
1534
        // check if a real file (no directory) to the given filename exist
1487
        if(FileExist(filename, ATTR_NONE, ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL, file))
1535
        if(FileExist(filename, ATTR_NONE, ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL, file))
1488
        {  // file exist
1536
        {  // file exist
1489
                switch(mode)  // check mode
1537
                switch(mode)  // check mode
Line 1558... Line 1606...
1558
                                // try to create the file
1606
                                // try to create the file
1559
                                if(!FileCreate(filename, ATTR_ARCHIVE, file))
1607
                                if(!FileCreate(filename, ATTR_ARCHIVE, file))
1560
                                { // if it could not be created
1608
                                { // if it could not be created
1561
                                        fclose_(file);
1609
                                        fclose_(file);
1562
                                        file = NULL;
1610
                                        file = NULL;
1563
                                }
1611
                                }
1564
                                break;
1612
                                break;
1565
                        case 'r': // else opened for 'r'
1613
                        case 'r': // else opened for 'r'
1566
                        default:  // if unsupported mode
1614
                        default:  // if unsupported mode
1567
                                fclose_(file);
1615
                                fclose_(file);
1568
                                file = NULL;
1616
                                file = NULL;
Line 1661... Line 1709...
1661
        s16 c = EOF;
1709
        s16 c = EOF;
1662
        u32 curr_sector;
1710
        u32 curr_sector;
Line 1663... Line 1711...
1663
 
1711
 
1664
        if( (!Partition.IsValid) || (file == NULL)) return(c);
1712
        if( (!Partition.IsValid) || (file == NULL)) return(c);
1665
        // if the end of the file is not reached, get the next character.
1713
        // if the end of the file is not reached, get the next character.
1666
        if((0 < file->Size) && ((file->Position+1) < file->Size) )
1714
        if((0 < file->Size) && ((file->Position) < file->Size) )
1667
        {
1715
        {
1668
                curr_sector  = file->FirstSectorOfCurrCluster;          // calculate the sector of the next character to be read.
1716
                curr_sector  = file->FirstSectorOfCurrCluster;          // calculate the sector of the next character to be read.
Line 1669... Line 1717...
1669
                curr_sector += file->SectorOfCurrCluster;
1717
                curr_sector += file->SectorOfCurrCluster;
1670
 
1718
 
1671
                if(file->SectorInCache != curr_sector)
1719
                if(file->SectorInCache != curr_sector)
1672
                {
1720
                {
1673
                        file->SectorInCache = curr_sector;
1721
                        file->SectorInCache = curr_sector;
1674
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache,file->Cache))
1722
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache,file->Cache))
1675
                        {
1723
                        {
1676
                                Fat16_Deinit();
1724
                                Fat16_Deinit();
1677
                                return(c);
1725
                                return(EOF);
1678
                        }
1726
                        }
1679
                }
1727
                }
1680
                c = (s16) file->Cache[file->ByteOfCurrSector];
1728
                c = (s16) file->Cache[file->ByteOfCurrSector];
Line 1738... Line 1786...
1738
                                {
1786
                                {
1739
                                        Fat16_Deinit();
1787
                                        Fat16_Deinit();
1740
                                        return(EOF);
1788
                                        return(EOF);
1741
                                }
1789
                                }
1742
                        }
1790
                        }
1743
       
-
 
1744
 
1791
               
-
 
1792
                        file->Cache[file->ByteOfCurrSector] = (u8)c;            // write databyte into the buffer. The byte will be written to the device at once
1745
                        if(file->Size == file->Position) file->Size++;          // a character has been written to the file so the size is incremented only when the character has been added at the end of the file.
1793
                        if(file->Size == file->Position) file->Size++;          // a character has been written to the file so the size is incremented only when the character has been added at the end of the file.
1746
                        file->Position++;                                                                       // the actual positon within the file.
1794
                        file->Position++;                                                                       // the actual positon within the file.
1747
                        file->ByteOfCurrSector++;                                                       // goto next byte in sector
1795
                        file->ByteOfCurrSector++;                                                       // goto next byte in sector
1748
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)          // if the end of this sector is reached yet
1796
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)          // if the end of this sector is reached yet
1749
                        {       // save the sector to the sd-card
1797
                        {       // save the sector to the sd-card
Line 2003... Line 2051...
2003
                curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
2051
                curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
2004
                file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
2052
                file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
2005
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
2053
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
2006
                {
2054
                {
2007
                        Fat16_Deinit();
2055
                        Fat16_Deinit();
2008
                        return(pVolumeLabel);
2056
                        return(NULL);
2009
                }
2057
                }
2010
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
2058
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
2011
                // search all directory entries within that sector
2059
                // search all directory entries within that sector
2012
                for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
2060
                for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
2013
                {   // check for existing dir entry
2061
                {   // check for existing dir entry
Line 2040... Line 2088...
2040
        }while((dir_sector < max_dir_sector) && (!pVolumeLabel));
2088
        }while((dir_sector < max_dir_sector) && (!pVolumeLabel));
Line 2041... Line 2089...
2041
 
2089
 
2042
        UnlockFilePointer(file);
2090
        UnlockFilePointer(file);
2043
        return(pVolumeLabel);
2091
        return(pVolumeLabel);
-
 
2092
}
-
 
2093
 
-
 
2094
 
-
 
2095
 
-
 
2096
#define ATTR_NONE               0x00    // normal file
-
 
2097
#define ATTR_READONLY           0x01    // file is readonly
-
 
2098
#define ATTR_HIDDEN                     0x02    // file is hidden
-
 
2099
#define ATTR_SYSTEM                     0x04    // file is a system file
-
 
2100
#define ATTR_VOLUMELABEL        0x08    // entry is a volume label
-
 
2101
#define ATTR_LONG_FILENAME      0x0F    // this is a long filename entry
-
 
2102
#define ATTR_SUBDIRECTORY       0x10    // entry is a directory name
-
 
2103
#define ATTR_ARCHIVE            0x20    // file is new or modified
-
 
2104
 
-
 
2105
 
-
 
2106
/********************************************************************************************************************************************/
-
 
2107
/*      Function:               u8 FindItem(Find_t);                                                                                                                                                                                                                    */
-
 
2108
/*                                                                                                                                                                                                                                                                                      */
-
 
2109
/*      Description:    This function looks for the item specified by global structure FindElement in the actual directory                                      */
-
 
2110
/*                                                                                                                                                                                                                                                              */
-
 
2111
/*                                                                                                                                                                                                                                                                                      */
-
 
2112
/*      Returnvalue:    TRUE if an matching element was found                                                                                                                                                                           */
-
 
2113
/********************************************************************************************************************************************/
-
 
2114
 
-
 
2115
u8 FindItem(Find_t *findelement)
-
 
2116
{
-
 
2117
        u16             index = 0;
-
 
2118
        u16             max_dir_sector = 0;
-
 
2119
        u16     end_of_directory_not_reached = 1;                                                                               // the directory has been read completely without a result.
-
 
2120
        u8              i = 0;
-
 
2121
        u8              readpointer = 0;
-
 
2122
        u8              writepointer = 0;
-
 
2123
        u8              retvalue = 0;
-
 
2124
        DirEntry_t      *DirectoryEntry;
-
 
2125
        File_t  file;
-
 
2126
 
-
 
2127
        file.FirstSectorOfCurrCluster   = findelement->fp.FirstSectorOfCurrCluster;
-
 
2128
        file.SectorOfCurrCluster        = findelement->fp.SectorOfCurrCluster;
-
 
2129
        index                                                   = findelement->fp.DirectoryIndex;
-
 
2130
 
-
 
2131
        // within the root directory area we can read sectors sequentially until the end of this area
-
 
2132
        if((Partition.FirstRootDirSector <= file.FirstSectorOfCurrCluster) && (file.FirstSectorOfCurrCluster < Partition.FirstDataSector))
-
 
2133
        {
-
 
2134
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
-
 
2135
        }
-
 
2136
        // within the data clusters we can read sectors sequentially only within the cluster
-
 
2137
        else if((Partition.FirstDataSector <= file.FirstSectorOfCurrCluster) && (file.FirstSectorOfCurrCluster <= Partition.LastDataSector))
-
 
2138
        {
-
 
2139
                max_dir_sector = Partition.SectorsPerCluster;                           // limit max secters before next cluster
-
 
2140
        }
-
 
2141
 
-
 
2142
        do
-
 
2143
        {                                                                                                                                                               // search the next 16 rootentries in this sector of the roordirectory.          
-
 
2144
                if(SD_SUCCESS != SDC_GetSector(((u32) file.FirstSectorOfCurrCluster + (u32)file.SectorOfCurrCluster), file.Cache));                                             // Read the Rootdirectory.
-
 
2145
                {
-
 
2146
                        Fat16_Deinit();
-
 
2147
                        return(0);
-
 
2148
                }
-
 
2149
               
-
 
2150
                DirectoryEntry = (DirEntry_t *)file.Cache;
-
 
2151
 
-
 
2152
                while((!retvalue)&&(index<16))
-
 
2153
                {
-
 
2154
                        i=0;                   
-
 
2155
                        if((u8) DirectoryEntry[index].Name[0] != 0xe5)                                                          // ignore deleted items.
-
 
2156
                        {
-
 
2157
                                while((i<=10)&&((DirectoryEntry[index].Name[i] == findelement->searchstring[i]) || (findelement->searchstring[i]=='*') || findelement->searchstring[i]=='?'))
-
 
2158
                                {
-
 
2159
                                        i++;
-
 
2160
                                }
-
 
2161
                        }
-
 
2162
                        if((DirectoryEntry[index].Attribute <= 0x30) && (DirectoryEntry[index].Attribute & findelement->attribmask) && (i==11))
-
 
2163
                        {
-
 
2164
                for(readpointer=0;readpointer<=10;readpointer++)
-
 
2165
                                {
-
 
2166
                                        if((DirectoryEntry[index].Name[readpointer] != ' ') && (readpointer!=8))
-
 
2167
                                        {
-
 
2168
                                                findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
-
 
2169
                                                writepointer++;
-
 
2170
                                        }
-
 
2171
                                        else  
-
 
2172
                                        {
-
 
2173
                                                if(DirectoryEntry[index].Attribute == ATTR_ARCHIVE)                                            
-
 
2174
                                                {
-
 
2175
                                        if(readpointer < 8) readpointer=8;
-
 
2176
                                        if(DirectoryEntry[index].Name[readpointer] != ' ')
-
 
2177
                                        {
-
 
2178
                                        findelement->name[writepointer] = '.';                                                  // then seperate the name and the extension by a '.' at index 8.                                                
-
 
2179
                                        writepointer++;
-
 
2180
                                        findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
-
 
2181
                                        writepointer++;
-
 
2182
                                        }
-
 
2183
                                            else break;
-
 
2184
                                                }
-
 
2185
                            else break;
-
 
2186
                        }
-
 
2187
                        /* terminate the namestring with 0 for debugpurposes*/
-
 
2188
                        findelement->name[12] = 0;
-
 
2189
                                }
-
 
2190
                                findelement->fp.FirstSectorOfFirstCluster = (u32) DirectoryEntry[index].StartCluster;                                                  
-
 
2191
                                findelement->fp.DirectoryIndex   = index;              
-
 
2192
                                findelement->fp.FirstSectorOfCurrCluster   = file.FirstSectorOfCurrCluster;
-
 
2193
                                findelement->fp.DirectorySector  = (file.FirstSectorOfCurrCluster + file.SectorOfCurrCluster);
-
 
2194
                                findelement->fp.SectorOfCurrCluster      = file.SectorOfCurrCluster;
-
 
2195
                findelement->fp.Size            = DirectoryEntry[index].Size;
-
 
2196
                                findelement->fp.Attribute               = DirectoryEntry[index].Attribute;
-
 
2197
                retvalue = 1;
-
 
2198
                        }                      
-
 
2199
                        /* search the next sector */
-
 
2200
                        index++;
-
 
2201
                }
-
 
2202
                /* this sector has been searched but we havn't found what we are looking for. Therefore we have to find the next sector */
-
 
2203
                if(!retvalue)                                                                                                                           // file not found in this sector so take next sector.
-
 
2204
                {
-
 
2205
                        /* in the next sector we start looking for the specified entry beginning at index 0 */
-
 
2206
                        index = 0;
-
 
2207
                        /* there are still sectors to be read within the cluster or within the linear addresspace of the rootdirectory */
-
 
2208
                        if(file.SectorOfCurrCluster < max_dir_sector-1)  file.SectorOfCurrCluster++; else end_of_directory_not_reached = 0;
-
 
2209
                        /* if we are looking for an directoryentry outside the rootdirectory and have reached the end of the cluster we have to get the next one */
-
 
2210
                        if(Partition.FirstDataSector <= file.FirstSectorOfCurrCluster)
-
 
2211
                        {
-
 
2212
                                end_of_directory_not_reached = GetNextCluster(&file);
-
 
2213
                        }
-
 
2214
                }
-
 
2215
        }
-
 
2216
        while((end_of_directory_not_reached) && (!retvalue) );
-
 
2217
 
-
 
2218
        return(retvalue);      
-
 
2219
}
-
 
2220
 
-
 
2221
 
-
 
2222
 
-
 
2223
 
-
 
2224
/********************************************************************************************************************************************/
-
 
2225
/*      Function:               findnext_(Find_t *);                                                                                                                                                                                                                    */
-
 
2226
/*                                                                                                                                                                                                                                                                                      */
-
 
2227
/*      Description:    This function looks for the next item in the specified directory with a matching filename and fileattributes specified  */
-
 
2228
/*                  by function findfirst()                                                                                                                                                                                                     */
-
 
2229
/*                                                                                                                                                                                                                                                                                      */
-
 
2230
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2231
/********************************************************************************************************************************************/
-
 
2232
u8 findnext_(Find_t * findelement)
-
 
2233
{
-
 
2234
        u8 itemfound = 0;
-
 
2235
        u8 index = 0;
-
 
2236
 
-
 
2237
        findelement->fp.DirectoryIndex++;
-
 
2238
 
-
 
2239
        /* before we start searching an element we clear the complete namestring within the structure FindElement */
-
 
2240
        for(index=0;index<11;index++) findelement->name[index] = 0;
-
 
2241
 
-
 
2242
        if(FindItem(findelement))
-
 
2243
        {
-
 
2244
                itemfound = 1;         
-
 
2245
        }
-
 
2246
 
-
 
2247
        return(itemfound);
-
 
2248
}
-
 
2249
 
-
 
2250
 
-
 
2251
 
-
 
2252
/********************************************************************************************************************************************/
-
 
2253
/*      Function:               findfirst_(s8* filename, u8 attribmask, Find_t *);                                                                                                                                              */
-
 
2254
/*                                                                                                                                                                                                                                                                                      */
-
 
2255
/*      Description:    This function looks for the first item in the specified directory with a matching filename and fileattributes                   */
-
 
2256
/*                                      The filename of the element found is transformed from 8.3 to a string                                                                                                   */
-
 
2257
/*                                                                                                                                                                                                                                                                                      */
-
 
2258
/*                                                                                                                                                                                                                                                                                      */
-
 
2259
/*      Returnvalue:    (1) if Element was found. (0) if no valid element was found                                                                                                                     */
-
 
2260
/********************************************************************************************************************************************/
-
 
2261
u8 findfirst_(const s8* name, u8 attribmask, Find_t *findelement)
-
 
2262
{
-
 
2263
        u8 itemfound = 0;
-
 
2264
        u8 index = 0;  
-
 
2265
 
-
 
2266
        /* initialize the FindElement structure */
-
 
2267
        findelement->fp.FirstSectorOfFirstCluster = 0;  // First sector of the first cluster of the file.
-
 
2268
        findelement->fp.FirstSectorOfCurrCluster = Partition.CurrentWorkingDirectory;                                   // First sector of the cluster which is edited at the moment.
-
 
2269
        findelement->fp.SectorOfCurrCluster = 0;                                                        // The sector within the current cluster.
-
 
2270
        findelement->fp.ByteOfCurrSector = 0;                                                   // The byte location within the current sector.
-
 
2271
        findelement->fp.Size = 0;                                                                               // The size of the opend file in bytes.
-
 
2272
        findelement->fp.Position = 0;                                                                   // Pointer to a character within the file 0 < fileposition < filesize
-
 
2273
        findelement->fp.DirectorySector = 0;                                                            // the sectorposition where the directoryentry has been made.
-
 
2274
        findelement->fp.DirectoryIndex = 0;                                                             // The index to the directoryentry within the specified sector.
-
 
2275
        findelement->attribfilter = 0;
-
 
2276
        findelement->attribmask = attribmask;
-
 
2277
        findelement->searchstring[0]=0;
-
 
2278
 
-
 
2279
        /* seperate the name of the element to be found from the filepath and bring it to the 8.3*/
-
 
2280
        SeperateDirName(name, findelement->searchstring);
-
 
2281
        /* after the name of the element is in 8.3 we process the wildcards (*). After an * all following character are wildcards to */
-
 
2282
        for(index=0;index<8;index++)
-
 
2283
        {
-
 
2284
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
-
 
2285
                if(findelement->searchstring[index] == '*')
-
 
2286
                {
-
 
2287
                        /*  */
-
 
2288
                        while(++index <8) findelement->searchstring[index] = '*';
-
 
2289
                }
-
 
2290
        }
-
 
2291
        for(index=8;index<11;index++)
-
 
2292
        {                                                                                                                                                                                                                                        
-
 
2293
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
-
 
2294
                if(findelement->searchstring[index] == '*')
-
 
2295
                {
-
 
2296
                        /*  */
-
 
2297
                        while(++index <11) findelement->searchstring[index] = '*';
-
 
2298
                }
-
 
2299
        }
-
 
2300
       
-
 
2301
        /* the value of ...DirectoryIndex will be incremented in findnext_() thererfore it has to be decremented in findfirst_() */
-
 
2302
        findelement->fp.DirectoryIndex--;
-
 
2303
        /* now lets search for the item within the direcory */
-
 
2304
        itemfound = findnext_(findelement);
-
 
2305
 
-
 
2306
        return(itemfound);
-
 
2307
}
-
 
2308
 
-
 
2309
 
-
 
2310
/********************************************************************************************************************************************/
-
 
2311
/*      Function:               u8 GetDirCount(s8* filepath);                                                                                                                                                                                   */
-
 
2312
/*                                                                                                                                                                                                                                                                                      */
-
 
2313
/*      Description:    This function counts the number of subdirectories the dirpath contains                                                                                                  */
-
 
2314
/*                                                                                                                                                                                                                                                              */
-
 
2315
/*                                                                                                                                                                                                                                                                                      */
-
 
2316
/*      Returnvalue:    then number of subdirectories within the specified path                                                                                                                                 */
-
 
2317
/********************************************************************************************************************************************/
-
 
2318
u8 GetDirCount(u8 *dirpath)
-
 
2319
{
-
 
2320
   u8 i=0;
-
 
2321
   u8 cnt=0;
-
 
2322
 
-
 
2323
   while(dirpath[i] != 0 )
-
 
2324
   {
-
 
2325
      if(dirpath[i]=='/')
-
 
2326
      {  
-
 
2327
         if(dirpath[i+1]!=0) cnt++;                                            // ignore last'/'
-
 
2328
      }
-
 
2329
      i++;  
-
 
2330
   }
-
 
2331
   i=0;  
-
 
2332
   return(cnt);
-
 
2333
}
-
 
2334
 
-
 
2335
 
-
 
2336
/********************************************************************************************************************************************/
-
 
2337
/* Funtion:     char *GetSubDirectory (char *dirpath, char *directory)                                                                                                                                          */
-
 
2338
/*                                                                                                                                                                                                                                                                                      */
-
 
2339
/* Description: this function returns a pointer to the beginning of the next subdirectory or NULL                                                                                       */
-
 
2340
/*                                                                                                                                                                                                                                                                                      */
-
 
2341
/*                                                                                                                                                                                                                                                                                      */
-
 
2342
/* returnvalue:   number of subdirectories in the filepath                                                                                                                                                                      */
-
 
2343
/********************************************************************************************************************************************/
-
 
2344
u8 * GetSubDirectory(u8 *dirpath, u8 *directory)
-
 
2345
{
-
 
2346
   u8 *cptr = dirpath;
-
 
2347
   u8 *dptr = directory;
-
 
2348
   u8 *retvalue = NULL;
-
 
2349
       
-
 
2350
   /* if the first character of the path is an '/' we go to the next character */
-
 
2351
   if(*cptr == '/') cptr++;
-
 
2352
   /* search end of path or subdirectory*/
-
 
2353
   while((*cptr != 0) && (*cptr != '/'))
-
 
2354
   {
-
 
2355
      *dptr = *cptr;
-
 
2356
       dptr++;
-
 
2357
       cptr++;
-
 
2358
   }  
-
 
2359
   if(*cptr!=0) retvalue = ++cptr;
-
 
2360
   *dptr = 0;
-
 
2361
 
-
 
2362
   return(retvalue);
-
 
2363
}
-
 
2364
 
-
 
2365
/********************************************************************************************************************************************/
-
 
2366
/*      Function:               s8 *GetPath(void);                                                                                                                                                                                                              */
-
 
2367
/*                                                                                                                                                                                                                                                                                      */
-
 
2368
/*      Description:    This function function returns a pointer to the absolute path of the active partition                                                                   */
-
 
2369
/*                                                                                                                                                                                                                                      */
-
 
2370
/*                                                                                                                                                                                                                                                                                      */
-
 
2371
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2372
/********************************************************************************************************************************************/
-
 
2373
 
-
 
2374
s8 *GetPath(void)
-
 
2375
{
-
 
2376
        return(Partition.PathToCwd);
-
 
2377
}
-
 
2378
 
-
 
2379
/********************************************************************************************************************************************/
-
 
2380
/*      Function:               void SetPathToRoot(void);                                                                                                                                                                                                       */
-
 
2381
/*                                                                                                                                                                                                                                                                                      */
-
 
2382
/*      Description:    This function sets the path to the rootdirectory                                                                                                                                                */
-
 
2383
/*                                                                                                                                                                                                                                      */
-
 
2384
/*                                                                                                                                                                                                                                                                                      */
-
 
2385
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2386
/********************************************************************************************************************************************/
-
 
2387
 
-
 
2388
void SetPathToRoot(void)
-
 
2389
{
-
 
2390
        /* lets point to the rootdirectory */
-
 
2391
        strcpy(Partition.PathToCwd, "/");      
-
 
2392
}
-
 
2393
 
-
 
2394
/********************************************************************************************************************************************/
-
 
2395
/*      Function:               void AppendDirToPath(s8* directory);                                                                                                                                                                                    */
-
 
2396
/*                                                                                                                                                                                                                                                                                      */
-
 
2397
/*      Description:    This function function appends the name of an directory to the Path to the CWD                                                                                  */
-
 
2398
/*                                                                                                                                                                                                                                      */
-
 
2399
/*                                                                                                                                                                                                                                                                                      */
-
 
2400
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2401
/********************************************************************************************************************************************/
-
 
2402
 
-
 
2403
void AppendDirToPath(s8* directory)
-
 
2404
{
-
 
2405
        /* append the name of the directory to the path */
-
 
2406
        strcat(Partition.PathToCwd, directory);
-
 
2407
        /* append a '/' after the directoryname */
-
 
2408
        strcat(Partition.PathToCwd, "/");
-
 
2409
}
-
 
2410
 
-
 
2411
/********************************************************************************************************************************************/
-
 
2412
/*      Function:               RemoveLastDirFromPath(void);                                                                                                                                                                                    */
-
 
2413
/*                                                                                                                                                                                                                                                                                      */
-
 
2414
/*      Description:    This function removes the last directory from the path to the cwd                                                                                                               */
-
 
2415
/*                                                                                                                                                                                                                                      */
-
 
2416
/*                                                                                                                                                                                                                                                                                      */
-
 
2417
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2418
/********************************************************************************************************************************************/
-
 
2419
 
-
 
2420
void RemoveLastDirFromPath(void)
-
 
2421
{
-
 
2422
        /* a pointer to the beginning of the absolute path to the cwd */
-
 
2423
        s8 * cptr = Partition.PathToCwd;
-
 
2424
        /* lets find the end of the path to the cwd */
-
 
2425
        while(*cptr != 0 ) cptr++;
-
 
2426
        /* if the path is terminated with an '/' */
-
 
2427
        if((*(cptr-1)) == '/') *(cptr-1)=0;    
-
 
2428
        /* now lets find the beginning of the last directorientry */
-
 
2429
        while((*cptr != '/' ) && cptr > Partition.PathToCwd) cptr--;
-
 
2430
        /* is there one subdirectory left within the path? */
-
 
2431
        if(cptr > Partition.PathToCwd)
-
 
2432
        {
-
 
2433
                /* we delete the direntry by terminating the path with 0 */
-
 
2434
                *cptr = 0;
-
 
2435
        }
-
 
2436
        /* there is no subdirectory left within the path. Therefore we create the root instead. */
-
 
2437
        else
-
 
2438
        {
-
 
2439
                *cptr = '/';
-
 
2440
                *(cptr+1) = 0;
-
 
2441
        }
-
 
2442
}
-
 
2443
 
-
 
2444
/********************************************************************************************************************************************/
-
 
2445
/*      Function:               chdir_(s8* filepath);                                                                                                                                                                                                   */
-
 
2446
/*                                                                                                                                                                                                                                                                                      */
-
 
2447
/*      Description:    This function changed the current working directory to the directory specified by the filepath                                                  */
-
 
2448
/*                  by function findfirst()                                                                                                                                                                                                     */
-
 
2449
/*                                                                                                                                                                                                                                                                                      */
-
 
2450
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2451
/********************************************************************************************************************************************/
-
 
2452
/*                                                                         
-
 
2453
#define ATTR_NONE               0x00    // normal file
-
 
2454
#define ATTR_READONLY           0x01    // file is readonly
-
 
2455
#define ATTR_HIDDEN                     0x02    // file is hidden
-
 
2456
#define ATTR_SYSTEM                     0x04    // file is a system file
-
 
2457
#define ATTR_VOLUMELABEL        0x08    // entry is a volume label
-
 
2458
#define ATTR_LONG_FILENAME      0x0F    // this is a long filename entry
-
 
2459
#define ATTR_SUBDIRECTORY       0x10    // entry is a directory name
-
 
2460
#define ATTR_ARCHIVE            0x20    // file is new or modified
-
 
2461
*/
-
 
2462
 
-
 
2463
u8 chdir_(s8 *path)
-
 
2464
{
-
 
2465
        u8              retvalue = 0;                                   // the value returned by this function
-
 
2466
        u32     ultemp = 0;                                             // temp. variable
-
 
2467
        u8     *directory = path;                               // pointer to a directoryname within the path
-
 
2468
        u8      dircount = 0;                                   // the number of subdirectoryentries within the path
-
 
2469
        u8      cache[64];                                              // a buffer containing the name of the subdirectory we are actually looking for
-
 
2470
        Find_t  fe;                                                             // The findelement needed for function findfirst to find the subdirectoryentry
-
 
2471
        s8              tp[256];                                                // temporarily we remember the actual path until the operation has finished successfully
-
 
2472
        u32     cwdt = 0;
-
 
2473
        s8     *cptr;
-
 
2474
 
-
 
2475
        /* bring the path into the correct syntax */
-
 
2476
        cptr = path;
-
 
2477
        /* search the whole string */
-
 
2478
        while(*cptr != 0 )
-
 
2479
        {
-
 
2480
                if(*cptr == '\\') *cptr = '/';
-
 
2481
                cptr++;
-
 
2482
        }
-
 
2483
        /* lets remember the actual path */
-
 
2484
        strcpy(tp, Partition.PathToCwd);
-
 
2485
        cwdt = Partition.CurrentWorkingDirectory;
-
 
2486
        /* how many subdirectories are there within the path? */
-
 
2487
        dircount = GetDirCount(path);  
-
 
2488
        /* if the path is absolute we begin at the rootdirectory */
-
 
2489
        if(path[0] == '/')
-
 
2490
        {
-
 
2491
                strcpy(Partition.PathToCwd, "/");
-
 
2492
                Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
-
 
2493
                /* if there is no other pathinformation we only switch to the rootdirectory. So theres nothing left todo.*/
-
 
2494
                if(!dircount) return(1);
-
 
2495
        }
-
 
2496
        /* now we parse through all the subdirectories within the path */
-
 
2497
        do
-
 
2498
        {  
-
 
2499
                /* until all the subdirectories within the path have been processed */
-
 
2500
        if(dircount) dircount--;
-
 
2501
                /* this is the name of the next subdirectory we are looking for */             
-
 
2502
            directory = GetSubDirectory(directory, cache);  
-
 
2503
                /* search for the next subdirectory within the path */
-
 
2504
                if(findfirst_(cache, ATTR_SUBDIRECTORY, &fe))
-
 
2505
                {
-
 
2506
                        /* we try to change into the directory "..". Now we have to delete the last direntry from the path */
-
 
2507
                        if(strcmp(cache,"..") == 0) RemoveLastDirFromPath();
-
 
2508
                        /* we try to change into the actual directory so there's nothing todo */
-
 
2509
                        else if(cache[0] == '.') return(1);
-
 
2510
                        /* otherwise we append the name of the directory we are changing in to the path */
-
 
2511
                        else AppendDirToPath(cache);
-
 
2512
                        /* The startcluster within an directoryentry specifies the position within the fat where the file or directory starts */
-
 
2513
                        ultemp = (u32) fe.fp.FirstSectorOfFirstCluster;
-
 
2514
                        /* the first 2 entries are reserved for '.' and '..' */
-
 
2515
                        ultemp -= 2;
-
 
2516
                        /* now we have to transform the position within the fat into the corrosponding sectoraddress relative to the beginning of the datasection of the active partition*/
-
 
2517
                        ultemp *= Partition.SectorsPerCluster;
-
 
2518
                        /* at least we make the sectoraddress absolute by adding the relative address to the beginning of the datasection of the active partition */
-
 
2519
                        ultemp += Partition.FirstDataSector;
-
 
2520
                        /* the cwd now points to the specified directory */
-
 
2521
                        Partition.CurrentWorkingDirectory = ultemp;
-
 
2522
                        /* we found the folder specified by the foldername */
-
 
2523
                        retvalue = 1;
-
 
2524
                }
-
 
2525
        }
-
 
2526
        /* do this until all subdirectories have been found or a subdirectory is missing */
-
 
2527
        while(dircount && retvalue );
-
 
2528
 
-
 
2529
        /* if we could not change to the specified directory we restore the actual path */
-
 
2530
        if(!retvalue)
-
 
2531
        {
-
 
2532
                Partition.CurrentWorkingDirectory = cwdt;                                                  
-
 
2533
                strcpy(Partition.PathToCwd, tp);
-
 
2534
        }
-
 
2535
        return(retvalue);